upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/tests/common/sync_helpers.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/common/sync_helpers.rs')
-rw-r--r--tests/common/sync_helpers.rs101
1 files changed, 90 insertions, 11 deletions
diff --git a/tests/common/sync_helpers.rs b/tests/common/sync_helpers.rs
index 5fc2ad7..daa684b 100644
--- a/tests/common/sync_helpers.rs
+++ b/tests/common/sync_helpers.rs
@@ -1071,12 +1071,16 @@ pub struct SyncTestResult {
1071 pub syncing_relay: TestRelay, 1071 pub syncing_relay: TestRelay,
1072 pub maintainer_keys: Keys, 1072 pub maintainer_keys: Keys,
1073 pub repo_coord: String, 1073 pub repo_coord: String,
1074 // Keep SmartGitServer alive for the test duration
1075 _git_server: Option<super::git_server::SmartGitServer>,
1076 // Keep temp dir alive for the test duration
1077 _git_temp_dir: Option<tempfile::TempDir>,
1074} 1078}
1075 1079
1076/// Helper to send an event to a relay 1080/// Helper to send an event to a relay
1077/// 1081///
1078/// Creates a temporary client, sends the event, and disconnects. 1082/// Creates a temporary client, sends the event, and disconnects.
1079async fn send_to_relay(relay: &TestRelay, event: &Event) -> Result<(), String> { 1083pub async fn send_to_relay(relay: &TestRelay, event: &Event) -> Result<(), String> {
1080 let temp_keys = Keys::generate(); 1084 let temp_keys = Keys::generate();
1081 let client = TestClient::new(relay.url(), temp_keys).await?; 1085 let client = TestClient::new(relay.url(), temp_keys).await?;
1082 client.send_event(event).await?; 1086 client.send_event(event).await?;
@@ -1084,6 +1088,17 @@ async fn send_to_relay(relay: &TestRelay, event: &Event) -> Result<(), String> {
1084 Ok(()) 1088 Ok(())
1085} 1089}
1086 1090
1091/// Helper to send an event to a relay by URL
1092///
1093/// Creates a temporary client, sends the event, and disconnects.
1094pub async fn send_to_relay_url(relay_url: &str, event: &Event) -> Result<(), String> {
1095 let temp_keys = Keys::generate();
1096 let client = TestClient::new(relay_url, temp_keys).await?;
1097 client.send_event(event).await?;
1098 client.disconnect().await;
1099 Ok(())
1100}
1101
1087/// Unified sync test helper that automatically determines sync mode. 1102/// Unified sync test helper that automatically determines sync mode.
1088/// 1103///
1089/// This function sets up a complete sync test environment by determining whether 1104/// This function sets up a complete sync test environment by determining whether
@@ -1119,6 +1134,10 @@ async fn send_to_relay(relay: &TestRelay, event: &Event) -> Result<(), String> {
1119/// // Assert comment synced to result.syncing_relay 1134/// // Assert comment synced to result.syncing_relay
1120/// ``` 1135/// ```
1121pub async fn run_sync_test(historic_events: &[Event], live_events: &[Event]) -> SyncTestResult { 1136pub async fn run_sync_test(historic_events: &[Event], live_events: &[Event]) -> SyncTestResult {
1137 use super::purgatory_helpers::{
1138 create_state_event, create_test_repo_with_commit, push_to_relay, CommitVariant,
1139 };
1140
1122 // Validate usage - cannot provide events in both slices 1141 // Validate usage - cannot provide events in both slices
1123 let historic_mode = !historic_events.is_empty(); 1142 let historic_mode = !historic_events.is_empty();
1124 let live_mode = !live_events.is_empty(); 1143 let live_mode = !live_events.is_empty();
@@ -1137,39 +1156,97 @@ pub async fn run_sync_test(historic_events: &[Event], live_events: &[Event]) ->
1137 // 2. Start source relay 1156 // 2. Start source relay
1138 let source = TestRelay::start().await; 1157 let source = TestRelay::start().await;
1139 1158
1140 // 3. Create keys and announcement listing both relays 1159 // 3. Create local git repo with a commit
1160 let git_temp_dir = tempfile::tempdir().expect("Failed to create temp dir for git repo");
1161 let commit_hash =
1162 create_test_repo_with_commit(git_temp_dir.path(), CommitVariant::StateTest)
1163 .expect("Failed to create test git repo");
1164
1165 // 4. Create keys and build URLs
1141 let keys = Keys::generate(); 1166 let keys = Keys::generate();
1142 let announcement = 1167 let npub = keys
1143 create_repo_announcement(&keys, &[&source.domain(), &syncing_domain], "test-repo"); 1168 .public_key()
1169 .to_bech32()
1170 .expect("Failed to convert public key to npub");
1171
1172 // Clone URLs: source relay HTTP endpoint is where git data lives
1173 // The syncing relay's purgatory will fetch from source's clone URL
1174 let clone_url_source = format!("http://{}/{}/{}.git", source.domain(), npub, "test-repo");
1175 let clone_url_syncing = format!(
1176 "http://{}/{}/{}.git",
1177 syncing_domain, npub, "test-repo"
1178 );
1179
1180 let clone_urls = vec![clone_url_source.clone(), clone_url_syncing.clone()];
1181 let relay_urls = vec![
1182 format!("ws://{}", source.domain()),
1183 format!("ws://{}", syncing_domain),
1184 ];
1144 1185
1145 // 4. Send announcement + historic events to source BEFORE syncing relay starts 1186 let announcement = EventBuilder::new(Kind::GitRepoAnnouncement, "Repository state")
1187 .tags(vec![
1188 Tag::identifier("test-repo"),
1189 Tag::custom(TagKind::custom("clone"), clone_urls.clone()),
1190 Tag::custom(TagKind::custom("relays"), relay_urls.clone()),
1191 ])
1192 .sign_with_keys(&keys)
1193 .expect("Failed to sign repo announcement");
1194
1195 // 5. Create state event referencing the commit
1196 let state_event = create_state_event(
1197 &keys,
1198 "test-repo",
1199 &[("main", &commit_hash)],
1200 &[],
1201 &clone_urls.iter().map(|s| s.as_str()).collect::<Vec<_>>(),
1202 &relay_urls.iter().map(|s| s.as_str()).collect::<Vec<_>>(),
1203 )
1204 .expect("Failed to create state event");
1205
1206 // 6. Send announcement + state event to source (both go to purgatory)
1146 send_to_relay(&source, &announcement) 1207 send_to_relay(&source, &announcement)
1147 .await 1208 .await
1148 .expect("Failed to send announcement"); 1209 .expect("Failed to send announcement");
1210 send_to_relay(&source, &state_event)
1211 .await
1212 .expect("Failed to send state event");
1213
1214 // 7. Git push to source relay → releases both announcement and state event from purgatory
1215 push_to_relay(git_temp_dir.path(), &source.domain(), &npub, "test-repo")
1216 .expect("Failed to push git data to source relay");
1217
1218 // 8. Wait for source relay to process the push and release events from purgatory
1219 tokio::time::sleep(Duration::from_secs(2)).await;
1220
1221 // 9. Send historic events to source BEFORE syncing relay starts
1149 for event in historic_events { 1222 for event in historic_events {
1150 send_to_relay(&source, event) 1223 send_to_relay(&source, event)
1151 .await 1224 .await
1152 .expect("Failed to send historic event"); 1225 .expect("Failed to send historic event");
1153 } 1226 }
1154 1227
1155 // 5. Start syncing relay (connects to source) 1228 // 10. Start syncing relay (connects to source)
1156 let syncing = 1229 let syncing =
1157 TestRelay::start_on_port_with_options(syncing_port, Some(source.url().into()), false).await; 1230 TestRelay::start_on_port_with_options(syncing_port, Some(source.url().into()), false).await;
1158 1231
1159 // 6. Wait for sync connection to establish 1232 // 11. Wait for sync connection to establish
1160 let _ = wait_for_sync_connection(syncing.url(), 1, Duration::from_secs(5)).await; 1233 let _ = wait_for_sync_connection(syncing.url(), 1, Duration::from_secs(5)).await;
1161 1234
1162 // 7. Send live events AFTER connection established 1235 // 12. Send live events AFTER connection established
1163 for event in live_events { 1236 for event in live_events {
1164 send_to_relay(&source, event) 1237 send_to_relay(&source, event)
1165 .await 1238 .await
1166 .expect("Failed to send live event"); 1239 .expect("Failed to send live event");
1167 } 1240 }
1168 1241
1169 // 8. Allow sync to complete 1242 // 13. Allow sync + purgatory promotion to complete on the syncing relay.
1170 tokio::time::sleep(Duration::from_millis(100)).await; 1243 // The syncing relay receives the announcement (goes to purgatory) and state event.
1244 // The purgatory sync loop (1s interval) fetches git data from source's clone URL
1245 // (http://source-domain/npub/test-repo.git) and releases the announcement.
1246 // We wait up to 8s to allow time for this.
1247 tokio::time::sleep(Duration::from_secs(8)).await;
1171 1248
1172 // 9. Compute repo coordinate before moving keys 1249 // 14. Compute repo coordinate before moving keys
1173 let coordinate = repo_coord(&keys, "test-repo"); 1250 let coordinate = repo_coord(&keys, "test-repo");
1174 1251
1175 SyncTestResult { 1252 SyncTestResult {
@@ -1177,6 +1254,8 @@ pub async fn run_sync_test(historic_events: &[Event], live_events: &[Event]) ->
1177 syncing_relay: syncing, 1254 syncing_relay: syncing,
1178 maintainer_keys: keys, 1255 maintainer_keys: keys,
1179 repo_coord: coordinate, 1256 repo_coord: coordinate,
1257 _git_server: None,
1258 _git_temp_dir: Some(git_temp_dir),
1180 } 1259 }
1181} 1260}
1182 1261