upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2025-12-18 16:57:10 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2025-12-18 16:57:10 +0000
commit33530da5864245cc44e96c7a168ad806fdab6d98 (patch)
tree62ac26b00f49610f18aaa69b296ec247656042d2 /tests
parent203aae5e3fca0f6a2b4788c0941412367c162d42 (diff)
test: add unified run_sync_test() helper infrastructure
Add SyncTestResult struct and run_sync_test() helper function to sync_helpers.rs for unified test setup. The helper automatically determines sync mode (historic vs live) based on which event slice has content. Features: - SyncTestResult: holds test fixtures (relays, keys, repo_coord) - run_sync_test(): unified setup for both historic and live sync tests - Panic guards for invalid usage (both slices or neither) - Unit tests for panic conditions Test results: 40 tests total, 38 passing (same as baseline) - 2 pre-existing metric test failures (unchanged from baseline) - All new panic condition tests passing - No regressions introduced
Diffstat (limited to 'tests')
-rw-r--r--tests/common/sync_helpers.rs165
1 files changed, 165 insertions, 0 deletions
diff --git a/tests/common/sync_helpers.rs b/tests/common/sync_helpers.rs
index e07ad1f..67dec3c 100644
--- a/tests/common/sync_helpers.rs
+++ b/tests/common/sync_helpers.rs
@@ -1060,4 +1060,169 @@ mod tests {
1060 let metrics = ParsedMetrics::parse(text); 1060 let metrics = ParsedMetrics::parse(text);
1061 assert_eq!(metrics.relay_connected("ws://127.0.0.1:12345"), Some(true)); 1061 assert_eq!(metrics.relay_connected("ws://127.0.0.1:12345"), Some(true));
1062 } 1062 }
1063
1064// ============================================================================
1065// Unified Sync Test Helper
1066// ============================================================================
1067
1068/// Result from running a sync test setup
1069///
1070/// Holds all fixtures needed for making assertions in sync tests.
1071/// Returned by [`run_sync_test`] after setting up the test environment.
1072pub struct SyncTestResult {
1073 pub source_relay: TestRelay,
1074 pub syncing_relay: TestRelay,
1075 pub maintainer_keys: Keys,
1076 pub repo_coord: String,
1077}
1078
1079/// Helper to send an event to a relay
1080///
1081/// Creates a temporary client, sends the event, and disconnects.
1082async fn send_to_relay(relay: &TestRelay, event: &Event) -> Result<(), String> {
1083 let temp_keys = Keys::generate();
1084 let client = TestClient::new(relay.url(), temp_keys).await?;
1085 client.send_event(event).await?;
1086 client.disconnect().await;
1087 Ok(())
1088}
1089
1090/// Unified sync test helper that automatically determines sync mode.
1091///
1092/// This function sets up a complete sync test environment by determining whether
1093/// to test historic sync (events sent before syncing relay connects) or live sync
1094/// (events sent after syncing relay connects) based on which event slice has content.
1095///
1096/// # Sync Mode Detection
1097///
1098/// - **Historic sync**: If `historic_events` has content and `live_events` is empty
1099/// - **Live sync**: If `live_events` has content and `historic_events` is empty
1100/// - **Panics**: If both slices have content or both are empty (invalid usage)
1101///
1102/// # Arguments
1103///
1104/// * `historic_events` - Events to send BEFORE syncing relay connects (for historic sync tests)
1105/// * `live_events` - Events to send AFTER syncing relay connects (for live sync tests)
1106///
1107/// # Returns
1108///
1109/// [`SyncTestResult`] containing test fixtures for assertions
1110///
1111/// # Example
1112///
1113/// ```ignore
1114/// // Historic sync test
1115/// let issue = build_layer2_issue_event(&keys, &repo_coord, "Historic Issue")?;
1116/// let result = run_sync_test(&[issue], &[]).await;
1117/// // Assert issue synced to result.syncing_relay
1118///
1119/// // Live sync test
1120/// let comment = build_layer3_comment_event(&keys, &issue.id, "Live Comment", Kind::Custom(1111))?;
1121/// let result = run_sync_test(&[], &[comment]).await;
1122/// // Assert comment synced to result.syncing_relay
1123/// ```
1124pub async fn run_sync_test(
1125 historic_events: &[Event],
1126 live_events: &[Event],
1127) -> SyncTestResult {
1128 // Validate usage - exactly one slice must have content
1129 let historic_mode = !historic_events.is_empty();
1130 let live_mode = !live_events.is_empty();
1131
1132 if historic_mode && live_mode {
1133 panic!("Invalid usage: both historic_events and live_events provided. Use one or the other.");
1134 }
1135 if !historic_mode && !live_mode {
1136 panic!("Invalid usage: both historic_events and live_events are empty. Provide at least one.");
1137 }
1138
1139 // 1. Pre-allocate syncing relay port for announcement tags
1140 let syncing_port = TestRelay::find_free_port();
1141 let syncing_domain = format!("127.0.0.1:{}", syncing_port);
1142
1143 // 2. Start source relay
1144 let source = TestRelay::start().await;
1145
1146 // 3. Create keys and announcement listing both relays
1147 let keys = Keys::generate();
1148 let announcement = create_repo_announcement(
1149 &keys,
1150 &[&source.domain(), &syncing_domain],
1151 "test-repo",
1152 );
1153
1154 // 4. Send announcement + historic events to source BEFORE syncing relay starts
1155 send_to_relay(&source, &announcement)
1156 .await
1157 .expect("Failed to send announcement");
1158 for event in historic_events {
1159 send_to_relay(&source, event)
1160 .await
1161 .expect("Failed to send historic event");
1162 }
1163
1164 // 5. Start syncing relay (connects to source)
1165 let syncing = TestRelay::start_on_port_with_options(
1166 syncing_port,
1167 Some(source.url().into()),
1168 false,
1169 )
1170 .await;
1171
1172 // 6. Wait for sync connection to establish
1173 let _ = wait_for_sync_connection(syncing.url(), 1, Duration::from_secs(5)).await;
1174
1175 // 7. Send live events AFTER connection established
1176 for event in live_events {
1177 send_to_relay(&source, event)
1178 .await
1179 .expect("Failed to send live event");
1180 }
1181
1182 // 8. Allow sync to complete
1183 tokio::time::sleep(Duration::from_millis(100)).await;
1184
1185 // 9. Compute repo coordinate before moving keys
1186 let coordinate = repo_coord(&keys, "test-repo");
1187
1188 SyncTestResult {
1189 source_relay: source,
1190 syncing_relay: syncing,
1191 maintainer_keys: keys,
1192 repo_coord: coordinate,
1193 }
1194}
1195
1196// ============================================================================
1197// Tests for Unified Sync Test Helper
1198// ============================================================================
1199
1200#[cfg(test)]
1201mod sync_helper_tests {
1202 use super::*;
1203
1204 // Note: Full integration tests of run_sync_test are in the actual sync test modules.
1205 // These unit tests only verify the panic conditions for invalid usage.
1206
1207 #[tokio::test]
1208 #[should_panic(expected = "both historic_events and live_events provided")]
1209 async fn test_run_sync_test_panics_with_both_slices() {
1210 let keys = Keys::generate();
1211 let coord = repo_coord(&keys, "test");
1212 let historic = build_layer2_issue_event(&keys, &coord, "Historic")
1213 .expect("Should create event");
1214 let live = build_layer3_reply_with_e_tag(&keys, &EventId::all_zeros(), "Live")
1215 .expect("Should create event");
1216
1217 // Should panic - both slices provided
1218 let _result = run_sync_test(&[historic], &[live]).await;
1219 }
1220
1221 #[tokio::test]
1222 #[should_panic(expected = "both historic_events and live_events are empty")]
1223 async fn test_run_sync_test_panics_with_empty_slices() {
1224 // Should panic - both slices empty
1225 let _result = run_sync_test(&[], &[]).await;
1226 }
1227}
1063} 1228}