From 2a13fa7d7a790e1f726c6589a4d678c87fe2888d Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Mon, 14 Sep 2026 14:39:24 +0000 Subject: [PATCH] test(sync): report evidence when setup visibility fails CI passed the readiness and filter-refusal corrections but failed a descendant test inside the shared announcement setup helper. The assertion alone cannot identify the relay or distinguish replacement from promotion or query-delivery failure. On failure only, report the expected event identity and timestamp, query the same replaceable address under a bounded deadline, and print the relay log tail. Keep both exact-ID assertions and their original success deadlines. This adds diagnostics rather than claiming an unconfirmed production fix. Validation: rustfmt and whitespace checks pass. CI/runtime execution remains pending; no Cargo tests or heavyweight builds were run in the VM. Assisted-by: Codex (GPT-6) --- tests/common/sync_helpers.rs | 82 ++++++++++++++++++++++++++++-------- 1 file changed, 65 insertions(+), 17 deletions(-) diff --git a/tests/common/sync_helpers.rs b/tests/common/sync_helpers.rs index 75e9ae9..f448f2c 100644 --- a/tests/common/sync_helpers.rs +++ b/tests/common/sync_helpers.rs @@ -1431,29 +1431,77 @@ pub async fn setup_announcement_on_relay( push_to_relay(git_temp_dir.path(), &relay.domain(), &npub, identifier) .expect("Failed to push git data to relay"); - assert!( - wait_for_event_on_relay( + for (label, event) in [("state", &state_event), ("announcement", &announcement)] { + let visible = wait_for_event_on_relay( relay.url(), - Filter::new().id(state_event.id), - Duration::from_secs(10) + Filter::new().id(event.id), + Duration::from_secs(10), ) - .await, - "pushed state event must leave purgatory" - ); - - assert!( - wait_for_event_on_relay( - relay.url(), - Filter::new().id(announcement.id), - Duration::from_secs(10) - ) - .await, - "pushed announcement must leave purgatory" - ); + .await; + if !visible { + report_setup_visibility_failure(relay, keys, identifier, event).await; + } + assert!(visible, "pushed {label} must leave purgatory"); + } (announcement, git_temp_dir) } +/// Diagnose a failed exact-ID check without extending its success deadline. +async fn report_setup_visibility_failure( + relay: &TestRelay, + keys: &Keys, + identifier: &str, + expected: &Event, +) { + eprintln!( + "setup visibility failure: relay={} kind={} author={} identifier={} expected_id={} created_at={}", + relay.url(), expected.kind.as_u16(), expected.pubkey, identifier, + expected.id, expected.created_at + ); + // A different event at the same replaceable address distinguishes a lost + // replacement race from an event that was never promoted or served. + let diagnostic = tokio::time::timeout(Duration::from_secs(5), async { + let client = TestClient::new(relay.url(), keys.clone()).await?; + let result = client + .client + .fetch_events( + Filter::new() + .kind(expected.kind) + .author(expected.pubkey) + .identifier(identifier), + ) + .timeout(Duration::from_secs(2)) + .await; + client.disconnect().await; + let events = result.map_err(|error| error.to_string())?; + for event in events.iter() { + eprintln!( + "stored candidate: id={} created_at={}", + event.id, event.created_at + ); + } + eprintln!("stored candidate count: {}", events.len()); + Ok::<(), String>(()) + }) + .await; + match diagnostic { + Ok(Ok(())) => {} + Ok(Err(error)) => eprintln!("setup diagnostic query failed: {error}"), + Err(_) => eprintln!("setup diagnostic query timed out"), + } + match std::fs::read_to_string(relay.log_path()) { + Ok(log) => { + let tail = log.lines().rev().take(80).collect::>(); + eprintln!("setup relay log tail:"); + for line in tail.into_iter().rev() { + eprintln!("{line}"); + } + } + Err(error) => eprintln!("setup relay log unavailable: {error}"), + } +} + /// Unified sync test helper that automatically determines sync mode. /// /// This function sets up a complete sync test environment by determining whether