Merge #edc95f2b: test(sync): simulate downtime in checkpoint integratio…

test(sync): simulate downtime in checkpoint integration test

nostr:nevent1qgsx2lyl2e4zvfadwcvkd9fkrcwczj7mf858hy85mwqclwgut8wpg2spz3mhxue69uhhyetvv9ujumn8d96zuer9wcq3yamnwvaz7tm8d96xummnw3ezucm0d5q3kamnwvaz7tmwva5hgtnyv9hxxmmwwashjer9wchxxmmdqqswmj2l9wqv8gnmety86n59j6j2vnmdr4rvg3nhlsnadudp4v0nuggz2q9ml

PR-Author: DanConwayDev's Agent
nostr:npub1v47f74n2ycn66asev62nv8sas99akj0g0wg0fkup37u3ckwuzs4q7cwtp0

PR description:

The checkpoint integration test can fail on a loaded builder because its 75 ms sleep leaves only 25 ms before the cold index expires. The nixpkgs 3.0.2 build observed `cold_expired == 1` where the test expected zero.

Simulate two minutes of downtime by editing the temporary checkpoint's `saved_at` field, with hot/cold retention periods of one minute and one week. Keep every existing assertion and leave production behavior unchanged. This extends the approach already applied to the equivalent unit tests in commit 14170f202f to the integration test that retained the sleep.

Validation: independent review, Rust formatting, whitespace checks and application to the released 3.0.2 source passed. Full Rust test execution remains pending in CI and the host nixpkgs build. The proposed nixpkgs package carries the matching test-only patch until a release includes the correction.

AI assistance: Codex (GPT-6) prepared the correction and PR, with an independent agent review. Publication uses dcagent.
This commit is contained in:
DanConwayDev
2026-09-12 14:50:03 +01:00
+17 -8
View File
@@ -766,11 +766,11 @@ async fn test_rejected_cache_entries_expired_during_downtime() {
let temp_dir = tempfile::tempdir().unwrap();
let state_path = temp_dir.path().join("rejected_cache.json");
// Create index with very short expiry
let index = RejectedEventsIndex::new(
Duration::from_millis(50), // Hot cache: 50ms
Duration::from_millis(100), // Cold index: 100ms
);
// Use production-scale retention periods so host scheduling cannot
// accidentally expire the cold entry during this test.
let hot_expiry = Duration::from_secs(60);
let cold_expiry = Duration::from_secs(7 * 24 * 60 * 60);
let index = RejectedEventsIndex::new(hot_expiry, cold_expiry);
let keys = Keys::generate();
let event = create_test_event(&keys, "test").await;
@@ -785,11 +785,20 @@ async fn test_rejected_cache_entries_expired_during_downtime() {
// Save to disk
index.save_to_disk(&state_path).unwrap();
// Simulate downtime longer than hot cache expiry
tokio::time::sleep(Duration::from_millis(75)).await;
// Simulate two minutes of downtime in the persisted snapshot instead
// of relying on a narrow wall-clock interval between two expirations.
let mut snapshot: serde_json::Value =
serde_json::from_slice(&std::fs::read(&state_path).unwrap()).unwrap();
snapshot["saved_at"] = serde_json::to_value(
std::time::SystemTime::now()
.checked_sub(Duration::from_secs(120))
.expect("simulated downtime must fit in SystemTime"),
)
.unwrap();
std::fs::write(&state_path, serde_json::to_vec(&snapshot).unwrap()).unwrap();
// Restore
let index2 = RejectedEventsIndex::new(Duration::from_millis(50), Duration::from_millis(100));
let index2 = RejectedEventsIndex::new(hot_expiry, cold_expiry);
index2.restore_from_disk(&state_path).unwrap();
// Both should be restored initially