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.
This commit is contained in:
DanConwayDev
2026-02-18 22:56:13 +00:00
parent fefb37e040
commit 63865548b0
+91 -12
View File
@@ -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<super::git_server::SmartGitServer>,
// Keep temp dir alive for the test duration
_git_temp_dir: Option<tempfile::TempDir>,
}
/// 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
let keys = Keys::generate();
let announcement =
create_repo_announcement(&keys, &[&source.domain(), &syncing_domain], "test-repo");
// 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. Send announcement + historic events to source BEFORE syncing relay starts
// 4. Create keys and build URLs
let keys = Keys::generate();
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),
];
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::<Vec<_>>(),
&relay_urls.iter().map(|s| s.as_str()).collect::<Vec<_>>(),
)
.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),
}
}