From 63865548b07e44d69321af3b03ca2c29aa60d74d Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Wed, 18 Feb 2026 22:56:13 +0000 Subject: test: update run_sync_test to use push_to_relay for purgatory flow Previously run_sync_test used a SmartGitServer external to the relay, but never pushed to the source relay itself. With the announcement purgatory feature, announcements stay in purgatory until git data arrives. By using push_to_relay to the source relay, both the announcement and state event are released from purgatory before the syncing relay starts, allowing the announcement to be synced. --- tests/common/sync_helpers.rs | 101 ++++++++++++++++++++++++++++++++++++++----- 1 file 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 { pub syncing_relay: TestRelay, pub maintainer_keys: Keys, pub repo_coord: String, + // Keep SmartGitServer alive for the test duration + _git_server: Option, + // Keep temp dir alive for the test duration + _git_temp_dir: Option, } /// Helper to send an event to a relay /// /// Creates a temporary client, sends the event, and disconnects. -async fn send_to_relay(relay: &TestRelay, event: &Event) -> Result<(), String> { +pub async fn send_to_relay(relay: &TestRelay, event: &Event) -> Result<(), String> { let temp_keys = Keys::generate(); let client = TestClient::new(relay.url(), temp_keys).await?; client.send_event(event).await?; @@ -1084,6 +1088,17 @@ async fn send_to_relay(relay: &TestRelay, event: &Event) -> Result<(), String> { Ok(()) } +/// Helper to send an event to a relay by URL +/// +/// Creates a temporary client, sends the event, and disconnects. +pub async fn send_to_relay_url(relay_url: &str, event: &Event) -> Result<(), String> { + let temp_keys = Keys::generate(); + let client = TestClient::new(relay_url, temp_keys).await?; + client.send_event(event).await?; + client.disconnect().await; + Ok(()) +} + /// Unified sync test helper that automatically determines sync mode. /// /// 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> { /// // Assert comment synced to result.syncing_relay /// ``` pub async fn run_sync_test(historic_events: &[Event], live_events: &[Event]) -> SyncTestResult { + use super::purgatory_helpers::{ + create_state_event, create_test_repo_with_commit, push_to_relay, CommitVariant, + }; + // Validate usage - cannot provide events in both slices let historic_mode = !historic_events.is_empty(); let live_mode = !live_events.is_empty(); @@ -1137,39 +1156,97 @@ pub async fn run_sync_test(historic_events: &[Event], live_events: &[Event]) -> // 2. Start source relay let source = TestRelay::start().await; - // 3. Create keys and announcement listing both relays + // 3. Create local git repo with a commit + let git_temp_dir = tempfile::tempdir().expect("Failed to create temp dir for git repo"); + let commit_hash = + create_test_repo_with_commit(git_temp_dir.path(), CommitVariant::StateTest) + .expect("Failed to create test git repo"); + + // 4. Create keys and build URLs let keys = Keys::generate(); - let announcement = - create_repo_announcement(&keys, &[&source.domain(), &syncing_domain], "test-repo"); + let npub = keys + .public_key() + .to_bech32() + .expect("Failed to convert public key to npub"); + + // Clone URLs: source relay HTTP endpoint is where git data lives + // The syncing relay's purgatory will fetch from source's clone URL + let clone_url_source = format!("http://{}/{}/{}.git", source.domain(), npub, "test-repo"); + let clone_url_syncing = format!( + "http://{}/{}/{}.git", + syncing_domain, npub, "test-repo" + ); + + let clone_urls = vec![clone_url_source.clone(), clone_url_syncing.clone()]; + let relay_urls = vec![ + format!("ws://{}", source.domain()), + format!("ws://{}", syncing_domain), + ]; - // 4. Send announcement + historic events to source BEFORE syncing relay starts + let announcement = EventBuilder::new(Kind::GitRepoAnnouncement, "Repository state") + .tags(vec![ + Tag::identifier("test-repo"), + Tag::custom(TagKind::custom("clone"), clone_urls.clone()), + Tag::custom(TagKind::custom("relays"), relay_urls.clone()), + ]) + .sign_with_keys(&keys) + .expect("Failed to sign repo announcement"); + + // 5. Create state event referencing the commit + let state_event = create_state_event( + &keys, + "test-repo", + &[("main", &commit_hash)], + &[], + &clone_urls.iter().map(|s| s.as_str()).collect::>(), + &relay_urls.iter().map(|s| s.as_str()).collect::>(), + ) + .expect("Failed to create state event"); + + // 6. Send announcement + state event to source (both go to purgatory) send_to_relay(&source, &announcement) .await .expect("Failed to send announcement"); + send_to_relay(&source, &state_event) + .await + .expect("Failed to send state event"); + + // 7. Git push to source relay → releases both announcement and state event from purgatory + push_to_relay(git_temp_dir.path(), &source.domain(), &npub, "test-repo") + .expect("Failed to push git data to source relay"); + + // 8. Wait for source relay to process the push and release events from purgatory + tokio::time::sleep(Duration::from_secs(2)).await; + + // 9. Send historic events to source BEFORE syncing relay starts for event in historic_events { send_to_relay(&source, event) .await .expect("Failed to send historic event"); } - // 5. Start syncing relay (connects to source) + // 10. Start syncing relay (connects to source) let syncing = TestRelay::start_on_port_with_options(syncing_port, Some(source.url().into()), false).await; - // 6. Wait for sync connection to establish + // 11. Wait for sync connection to establish let _ = wait_for_sync_connection(syncing.url(), 1, Duration::from_secs(5)).await; - // 7. Send live events AFTER connection established + // 12. Send live events AFTER connection established for event in live_events { send_to_relay(&source, event) .await .expect("Failed to send live event"); } - // 8. Allow sync to complete - tokio::time::sleep(Duration::from_millis(100)).await; + // 13. Allow sync + purgatory promotion to complete on the syncing relay. + // The syncing relay receives the announcement (goes to purgatory) and state event. + // The purgatory sync loop (1s interval) fetches git data from source's clone URL + // (http://source-domain/npub/test-repo.git) and releases the announcement. + // We wait up to 8s to allow time for this. + tokio::time::sleep(Duration::from_secs(8)).await; - // 9. Compute repo coordinate before moving keys + // 14. Compute repo coordinate before moving keys let coordinate = repo_coord(&keys, "test-repo"); SyncTestResult { @@ -1177,6 +1254,8 @@ pub async fn run_sync_test(historic_events: &[Event], live_events: &[Event]) -> syncing_relay: syncing, maintainer_keys: keys, repo_coord: coordinate, + _git_server: None, + _git_temp_dir: Some(git_temp_dir), } } -- cgit v1.2.3