diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/purgatory_sync.rs | 156 |
1 files changed, 17 insertions, 139 deletions
diff --git a/tests/purgatory_sync.rs b/tests/purgatory_sync.rs index 304865d..eefd6bc 100644 --- a/tests/purgatory_sync.rs +++ b/tests/purgatory_sync.rs | |||
| @@ -980,162 +980,43 @@ async fn test_pr_event_clone_tag_sync_with_partial_oid_aggregation_from_multiple | |||
| 980 | .expect("PR event should be served on mock_relay immediately"); | 980 | .expect("PR event should be served on mock_relay immediately"); |
| 981 | 981 | ||
| 982 | // ======================================================================== | 982 | // ======================================================================== |
| 983 | // Step 5: Start syncing_relay WITHOUT bootstrap and publish announcement directly | 983 | // Step 5: Start syncing_relay with source_grasp as bootstrap |
| 984 | // ======================================================================== | 984 | // ======================================================================== |
| 985 | 985 | ||
| 986 | // Start syncing_relay with sync enabled but NO bootstrap relay | 986 | // Start syncing_relay with source_grasp as bootstrap relay. |
| 987 | // This tests relay discovery from announcement's `relays` tag | 987 | // Negentropy is disabled because MockRelay doesn't support NIP-77, and the |
| 988 | // Note: We disable negentropy because MockRelay doesn't support NIP-77, | 988 | // sync system doesn't properly fall back to REQ+EOSE when negentropy fails. |
| 989 | // and the sync system doesn't properly fall back to REQ+EOSE when negentropy fails. | 989 | // |
| 990 | // We do NOT publish the announcement directly to syncing_relay. Instead, | ||
| 991 | // syncing_relay discovers it via the bootstrap connection to source_grasp, | ||
| 992 | // which has the promoted announcement in its database. | ||
| 990 | let syncing_relay = TestRelay::start_on_port_with_options( | 993 | let syncing_relay = TestRelay::start_on_port_with_options( |
| 991 | syncing_port, | 994 | syncing_port, |
| 992 | None, // NO bootstrap - relay discovery via announcement tags | 995 | Some(source_grasp.url().to_string()), // Bootstrap from source_grasp |
| 993 | true, // Disable negentropy - MockRelay doesn't support NIP-77 | 996 | true, // Disable negentropy - MockRelay doesn't support NIP-77 |
| 994 | ) | 997 | ) |
| 995 | .await; | 998 | .await; |
| 996 | 999 | ||
| 997 | // Publish announcement DIRECTLY to syncing_relay | ||
| 998 | // This triggers relay discovery from the announcement's `relays` tag | ||
| 999 | let syncing_client = Client::new(owner_keys.clone()); | ||
| 1000 | syncing_client | ||
| 1001 | .add_relay(syncing_relay.url()) | ||
| 1002 | .await | ||
| 1003 | .expect("Failed to add syncing_relay"); | ||
| 1004 | syncing_client.connect().await; | ||
| 1005 | tokio::time::sleep(Duration::from_millis(500)).await; | ||
| 1006 | |||
| 1007 | syncing_client | ||
| 1008 | .send_event(&announcement) | ||
| 1009 | .await | ||
| 1010 | .expect("Failed to send announcement to syncing_relay"); | ||
| 1011 | tokio::time::sleep(Duration::from_millis(200)).await; | ||
| 1012 | |||
| 1013 | // Wait for relay discovery and sync connections to establish | ||
| 1014 | // syncing_relay should discover source_grasp and mock_relay from announcement's relays tag | ||
| 1015 | println!("=== Waiting for sync connections ==="); | ||
| 1016 | println!("syncing_relay URL: {}", syncing_relay.url()); | ||
| 1017 | println!("source_grasp URL: {}", source_grasp.url()); | ||
| 1018 | println!("mock_relay URL: {}", mock_relay.url()); | ||
| 1019 | println!("git_server URL: {}", git_server.url()); | ||
| 1020 | |||
| 1021 | wait_for_sync_connection(syncing_relay.url(), 2, Duration::from_secs(10)) | ||
| 1022 | .await | ||
| 1023 | .expect( | ||
| 1024 | "Sync connections should establish to discovered relays (source_grasp + mock_relay)", | ||
| 1025 | ); | ||
| 1026 | println!("Sync connections established!"); | ||
| 1027 | |||
| 1028 | // Debug: Check metrics to see what relays are connected | ||
| 1029 | let metrics_url = syncing_relay | ||
| 1030 | .url() | ||
| 1031 | .replace("ws://", "http://") | ||
| 1032 | .replace("/", "") | ||
| 1033 | + "/metrics"; | ||
| 1034 | println!("Checking metrics at: {}", metrics_url); | ||
| 1035 | if let Ok(response) = reqwest::get(&metrics_url).await { | ||
| 1036 | if let Ok(metrics) = response.text().await { | ||
| 1037 | // Print sync-related metrics | ||
| 1038 | for line in metrics.lines() { | ||
| 1039 | if line.contains("sync") && !line.starts_with('#') { | ||
| 1040 | println!(" {}", line); | ||
| 1041 | } | ||
| 1042 | } | ||
| 1043 | } | ||
| 1044 | } | ||
| 1045 | |||
| 1046 | // Give some time for sync to happen | ||
| 1047 | println!("Waiting 10s for events to sync..."); | ||
| 1048 | tokio::time::sleep(Duration::from_secs(10)).await; | ||
| 1049 | |||
| 1050 | // Check metrics again after waiting | ||
| 1051 | println!("=== Checking metrics after sync wait ==="); | ||
| 1052 | if let Ok(response) = reqwest::get(&metrics_url).await { | ||
| 1053 | if let Ok(metrics) = response.text().await { | ||
| 1054 | for line in metrics.lines() { | ||
| 1055 | if line.contains("sync") && !line.starts_with('#') { | ||
| 1056 | println!(" {}", line); | ||
| 1057 | } | ||
| 1058 | } | ||
| 1059 | } | ||
| 1060 | } | ||
| 1061 | |||
| 1062 | // Debug: Check if PR event is still on mock_relay | ||
| 1063 | println!("=== Debug: Checking PR event on mock_relay ==="); | ||
| 1064 | let pr_on_mock = | ||
| 1065 | wait_for_event_served(mock_relay.url(), &pr_event_id, Duration::from_secs(2)).await; | ||
| 1066 | println!("PR event on mock_relay: {:?}", pr_on_mock.is_ok()); | ||
| 1067 | if let Ok(ref pr) = pr_on_mock { | ||
| 1068 | println!("PR event tags:"); | ||
| 1069 | for tag in pr.tags.iter() { | ||
| 1070 | println!(" {:?}", tag.as_slice()); | ||
| 1071 | } | ||
| 1072 | } | ||
| 1073 | |||
| 1074 | // Debug: Check repo coordinate | ||
| 1075 | let repo_coord = build_repo_coord(&owner_keys, identifier); | ||
| 1076 | println!("Expected repo coordinate: {}", repo_coord); | ||
| 1077 | |||
| 1078 | // Debug: Test if mock_relay responds to tag-based filter (Layer 2 style) | ||
| 1079 | println!("=== Debug: Testing mock_relay tag filter response ==="); | ||
| 1080 | let test_client = Client::new(Keys::generate()); | ||
| 1081 | test_client | ||
| 1082 | .add_relay(mock_relay.url()) | ||
| 1083 | .await | ||
| 1084 | .expect("Failed to add mock_relay"); | ||
| 1085 | test_client.connect().await; | ||
| 1086 | tokio::time::sleep(Duration::from_millis(500)).await; | ||
| 1087 | |||
| 1088 | // Build a Layer 2 style filter (by 'a' tag) | ||
| 1089 | let tag_filter = | ||
| 1090 | Filter::new().custom_tag(SingleLetterTag::lowercase(Alphabet::A), repo_coord.as_str()); | ||
| 1091 | println!("Tag filter: {:?}", tag_filter); | ||
| 1092 | |||
| 1093 | let tag_results = test_client | ||
| 1094 | .fetch_events(tag_filter, Duration::from_secs(5)) | ||
| 1095 | .await; | ||
| 1096 | match tag_results { | ||
| 1097 | Ok(events) => { | ||
| 1098 | println!("Tag filter returned {} events", events.len()); | ||
| 1099 | for event in events.iter() { | ||
| 1100 | println!(" Event ID: {}, Kind: {}", event.id, event.kind.as_u16()); | ||
| 1101 | } | ||
| 1102 | } | ||
| 1103 | Err(e) => { | ||
| 1104 | println!("Tag filter query failed: {:?}", e); | ||
| 1105 | } | ||
| 1106 | } | ||
| 1107 | test_client.disconnect().await; | ||
| 1108 | |||
| 1109 | // The syncing relay will: | 1000 | // The syncing relay will: |
| 1110 | // 1. Receive announcement directly (creates bare repo) | 1001 | // 1. Sync promoted announcement from source_grasp via bootstrap connection → purgatory (no local git data) |
| 1111 | // 2. Discover source_grasp and mock_relay from announcement's `relays` tag | 1002 | // 2. EOSE triggers StateOnly subscription → syncs state event from source_grasp → purgatory sync |
| 1112 | // 3. Connect to discovered relays | 1003 | // 3. Purgatory sync fetches commit_a from source_grasp clone URL → announcement + state promoted |
| 1113 | // 4. Sync state event from source_grasp → purgatory (no commit_a locally) | 1004 | // 4. SelfSubscriber sees promoted announcement → upgrades to Full → connects to mock_relay |
| 1114 | // 5. Sync PR event from mock_relay → purgatory (no commit_b locally) | 1005 | // 5. Syncs PR event from mock_relay → purgatory (no commit_b locally) |
| 1115 | // 6. Purgatory sync triggers | 1006 | // 6. Purgatory sync fetches commit_b from git_server via PR clone tag |
| 1116 | // 7. Fetches commit_a from source_grasp clone URL (from announcement clone tag) | 1007 | // 7. PR event promoted → served |
| 1117 | // 8. Fetches commit_b from git_server (from PR event's clone tag) | ||
| 1118 | // 9. Both events released when all OIDs available | ||
| 1119 | 1008 | ||
| 1120 | // ======================================================================== | 1009 | // ======================================================================== |
| 1121 | // Step 6: Verify Results | 1010 | // Step 6: Verify Results |
| 1122 | // ======================================================================== | 1011 | // ======================================================================== |
| 1123 | 1012 | ||
| 1124 | println!("=== Step 6: Verify Results ==="); | ||
| 1125 | println!("State event ID: {}", state_event_id); | ||
| 1126 | println!("PR event ID: {}", pr_event_id); | ||
| 1127 | println!("commit_a: {}", commit_a); | ||
| 1128 | println!("commit_b: {}", commit_b); | ||
| 1129 | |||
| 1130 | // Wait for state event to be served on syncing_relay | 1013 | // Wait for state event to be served on syncing_relay |
| 1131 | println!("Waiting for state event on syncing_relay..."); | ||
| 1132 | let state_found = wait_for_event_served( | 1014 | let state_found = wait_for_event_served( |
| 1133 | syncing_relay.url(), | 1015 | syncing_relay.url(), |
| 1134 | &state_event_id, | 1016 | &state_event_id, |
| 1135 | Duration::from_secs(30), | 1017 | Duration::from_secs(30), |
| 1136 | ) | 1018 | ) |
| 1137 | .await; | 1019 | .await; |
| 1138 | println!("State event result: {:?}", state_found); | ||
| 1139 | assert!( | 1020 | assert!( |
| 1140 | state_found.is_ok(), | 1021 | state_found.is_ok(), |
| 1141 | "State event should be served on syncing_relay: {:?}", | 1022 | "State event should be served on syncing_relay: {:?}", |
| @@ -1143,10 +1024,8 @@ async fn test_pr_event_clone_tag_sync_with_partial_oid_aggregation_from_multiple | |||
| 1143 | ); | 1024 | ); |
| 1144 | 1025 | ||
| 1145 | // Wait for PR event to be served on syncing_relay | 1026 | // Wait for PR event to be served on syncing_relay |
| 1146 | println!("Waiting for PR event on syncing_relay..."); | ||
| 1147 | let pr_found = | 1027 | let pr_found = |
| 1148 | wait_for_event_served(syncing_relay.url(), &pr_event_id, Duration::from_secs(30)).await; | 1028 | wait_for_event_served(syncing_relay.url(), &pr_event_id, Duration::from_secs(30)).await; |
| 1149 | println!("PR event result: {:?}", pr_found); | ||
| 1150 | assert!( | 1029 | assert!( |
| 1151 | pr_found.is_ok(), | 1030 | pr_found.is_ok(), |
| 1152 | "PR event should be served on syncing_relay (fetched commit_b from git_server via PR clone tag): {:?}", | 1031 | "PR event should be served on syncing_relay (fetched commit_b from git_server via PR clone tag): {:?}", |
| @@ -1187,7 +1066,6 @@ async fn test_pr_event_clone_tag_sync_with_partial_oid_aggregation_from_multiple | |||
| 1187 | source_client.disconnect().await; | 1066 | source_client.disconnect().await; |
| 1188 | mock_client.disconnect().await; | 1067 | mock_client.disconnect().await; |
| 1189 | pr_client.disconnect().await; | 1068 | pr_client.disconnect().await; |
| 1190 | syncing_client.disconnect().await; | ||
| 1191 | git_server.stop().await; | 1069 | git_server.stop().await; |
| 1192 | mock_relay.stop().await; | 1070 | mock_relay.stop().await; |
| 1193 | syncing_relay.stop().await; | 1071 | syncing_relay.stop().await; |