mirror of
https://relay.ngit.dev/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit-grasp.git
synced 2026-10-05 15:08:24 +00:00
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:
@@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user