upleb.uk

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

summaryrefslogtreecommitdiff
path: root/tests/purgatory.rs
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2026-02-23 15:41:32 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2026-02-23 15:41:32 +0000
commitc54ce061d6d278cce8362d5af085808ca60c239b (patch)
treeec967d6195d9f7ec4f061449596611afe3a0950f /tests/purgatory.rs
parente0ad39a489b3398f8208713bf728db0cb11475b0 (diff)
parent113928aa84894ea8f65c247d9987527e792b32a9 (diff)
feat: announcement purgatory
Extends purgatory to hold repository announcements until git data arrives, preventing empty repositories from being served to clients. When an announcement is received, a bare repo is created immediately and the announcement is held in purgatory. It is only promoted and served once a git push confirms real content exists. If no push arrives before expiry, the bare repo is deleted and the announcement is silently discarded. Key behaviours: - Soft expiry: announcements are hidden from clients but kept alive while git pushes are in progress, reviving on successful push - Expiry is extended when a matching state event or git push is observed - NIP-09 deletion events remove announcements from purgatory - Purgatory state (announcements, state events, PR events, expired set) is persisted to disk on graceful shutdown and restored on startup, with elapsed downtime subtracted from expiry deadlines - Purgatory announcements drive StateOnly sync in the sync system so state events are fetched from listed relays before promotion - SyncLevel added to RepoSyncIndex to distinguish purgatory repos (StateOnly) from promoted repos (Full L2+L3 sync)
Diffstat (limited to 'tests/purgatory.rs')
-rw-r--r--tests/purgatory.rs89
1 files changed, 89 insertions, 0 deletions
diff --git a/tests/purgatory.rs b/tests/purgatory.rs
new file mode 100644
index 0000000..73f85ca
--- /dev/null
+++ b/tests/purgatory.rs
@@ -0,0 +1,89 @@
1//! Purgatory Integration Tests
2//!
3//! Tests ngit-grasp relay's implementation of GRASP-01 purgatory behavior.
4//! Uses grasp-audit library to avoid code duplication.
5//!
6//! # Test Strategy
7//!
8//! - Each test runs in complete isolation with its own fresh relay instance
9//! - Uses macro to eliminate boilerplate while maintaining test isolation
10//! - Calls individual test methods from grasp-audit for minimal duplication
11//! - Automatic cleanup via TestRelay fixture (removes container and temp dirs)
12//!
13//! # Running Tests
14//!
15//! ```bash
16//! # Run all purgatory tests
17//! cargo test --test purgatory
18//!
19//! # Run specific test
20//! cargo test --test purgatory test_state_event_not_served_before_git_data
21//!
22//! # With output
23//! cargo test --test purgatory -- --nocapture
24//! ```
25
26mod common;
27
28use common::TestRelay;
29use grasp_audit::specs::grasp01::PurgatoryTests;
30use grasp_audit::{AuditClient, AuditConfig};
31
32/// Macro to generate isolated integration tests for purgatory
33///
34/// Each test runs with its own fresh relay instance to ensure complete isolation.
35/// This eliminates issues with leftover repositories and ensures clean state.
36macro_rules! isolated_purgatory_test {
37 ($test_name:ident) => {
38 #[tokio::test]
39 async fn $test_name() {
40 let relay = TestRelay::start().await;
41 let config = AuditConfig::isolated();
42 let client = AuditClient::new(relay.url(), config)
43 .await
44 .expect("Failed to create audit client");
45
46 let result = PurgatoryTests::$test_name(&client).await;
47
48 relay.stop().await;
49
50 assert!(
51 result.passed,
52 "{} failed: {}",
53 stringify!($test_name),
54 result.error.as_deref().unwrap_or("unknown error")
55 );
56 }
57 };
58}
59
60// ============================================================
61// Announcement Purgatory Tests
62// ============================================================
63
64isolated_purgatory_test!(test_announcement_not_served_before_git_data);
65isolated_purgatory_test!(test_announcement_served_after_git_push);
66isolated_purgatory_test!(test_bare_repo_exists_for_purgatory_announcement);
67isolated_purgatory_test!(test_state_event_accepted_for_purgatory_announcement);
68
69// ============================================================
70// Deletion Event Tests (NIP-09)
71// ============================================================
72
73isolated_purgatory_test!(test_deletion_by_event_id_removes_purgatory_state_event);
74isolated_purgatory_test!(test_deletion_by_coordinate_removes_purgatory_state_event);
75
76// ============================================================
77// State Event Purgatory Tests (already implemented)
78// ============================================================
79
80isolated_purgatory_test!(test_state_event_not_served_before_git_data);
81isolated_purgatory_test!(test_state_event_served_after_git_push);
82
83// ============================================================
84// PR Purgatory Tests
85// ============================================================
86
87isolated_purgatory_test!(test_pr_event_accepted_into_purgatory_and_isnt_served);
88isolated_purgatory_test!(test_pr_event_in_purgatory_git_push_accepted);
89isolated_purgatory_test!(test_pr_event_served_after_git_push);