diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2026-02-13 10:29:16 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2026-02-13 12:31:48 +0000 |
| commit | d6b955104f4a04dcbe7324e9a861642f4654894f (patch) | |
| tree | 01d6aeb07992780715b8c49bd1417953302e913b | |
| parent | f4e8e1089ae6e8e78c3576246d9747bb585fdc18 (diff) | |
refactor(grasp-audit): clarify PR purgatory test names and intent
- Remove redundant test_pr_event_remains_in_purgatory_until_git_data
- Rename test_pr_event_git_push_accepted -> test_pr_event_in_purgatory_git_push_accepted
- Add PASS/FAIL meaning to each test's documentation
- Note black-box testing limitation for purgatory detection
| -rw-r--r-- | grasp-audit/src/specs/grasp01/purgatory.rs | 109 | ||||
| -rw-r--r-- | tests/purgatory.rs | 5 |
2 files changed, 49 insertions, 65 deletions
diff --git a/grasp-audit/src/specs/grasp01/purgatory.rs b/grasp-audit/src/specs/grasp01/purgatory.rs index 27ab97b..9c4b401 100644 --- a/grasp-audit/src/specs/grasp01/purgatory.rs +++ b/grasp-audit/src/specs/grasp01/purgatory.rs | |||
| @@ -23,8 +23,9 @@ | |||
| 23 | //! - `test_state_event_served_after_git_push` | 23 | //! - `test_state_event_served_after_git_push` |
| 24 | //! | 24 | //! |
| 25 | //! ### PR Purgatory (already implemented) | 25 | //! ### PR Purgatory (already implemented) |
| 26 | //! - `test_pr_event_not_served_before_git_data` | 26 | //! - `test_pr_event_accepted_into_purgatory` - Event accepted, not queryable |
| 27 | //! - `test_pr_event_served_after_correct_push` | 27 | //! - `test_pr_event_in_purgatory_git_push_accepted` - Git push to refs/nostr/<event-id> succeeds |
| 28 | //! - `test_pr_event_served_after_git_push` - Event becomes queryable after git data | ||
| 28 | 29 | ||
| 29 | use crate::specs::grasp01::SpecRef; | 30 | use crate::specs::grasp01::SpecRef; |
| 30 | use crate::{AuditClient, AuditResult, FixtureKind, TestContext, TestResult}; | 31 | use crate::{AuditClient, AuditResult, FixtureKind, TestContext, TestResult}; |
| @@ -50,9 +51,8 @@ impl PurgatoryTests { | |||
| 50 | results.add(Self::test_state_event_served_after_git_push(client).await); | 51 | results.add(Self::test_state_event_served_after_git_push(client).await); |
| 51 | 52 | ||
| 52 | // PR purgatory tests | 53 | // PR purgatory tests |
| 53 | results.add(Self::test_pr_event_before_git_data_accepted_into_purgatory(client).await); | 54 | results.add(Self::test_pr_event_accepted_into_purgatory_and_isnt_served(client).await); |
| 54 | results.add(Self::test_pr_event_remains_in_purgatory_until_git_data(client).await); | 55 | results.add(Self::test_pr_event_in_purgatory_git_push_accepted(client).await); |
| 55 | results.add(Self::test_pr_event_git_push_accepted(client).await); | ||
| 56 | results.add(Self::test_pr_event_served_after_git_push(client).await); | 56 | results.add(Self::test_pr_event_served_after_git_push(client).await); |
| 57 | 57 | ||
| 58 | results | 58 | results |
| @@ -507,32 +507,44 @@ impl PurgatoryTests { | |||
| 507 | // PR Purgatory Tests | 507 | // PR Purgatory Tests |
| 508 | // ============================================================ | 508 | // ============================================================ |
| 509 | 509 | ||
| 510 | /// Test: PR event not served before git data arrives | 510 | /// Test: PR event accepted into purgatory (not served before git data) |
| 511 | /// | 511 | /// |
| 512 | /// Spec: GRASP-01 Line 22 | 512 | /// Spec: GRASP-01 Line 22 |
| 513 | /// "PRs and PR Updates SHOULD be accepted with message | 513 | /// "PRs and PR Updates SHOULD be accepted with message |
| 514 | /// 'purgatory: won't be served until git data arrives'" | 514 | /// 'purgatory: won't be served until git data arrives'" |
| 515 | /// | 515 | /// |
| 516 | /// This test verifies: | 516 | /// This test verifies: |
| 517 | /// 1. Send PR event for a repo | 517 | /// 1. PR event is sent and relay responds OK (accepted) |
| 518 | /// 2. PR event is NOT queryable (in purgatory) | 518 | /// 2. PR event is NOT queryable (in purgatory, not served) |
| 519 | /// 3. No git data exists at refs/nostr/<pr-event-id> | 519 | /// |
| 520 | pub async fn test_pr_event_before_git_data_accepted_into_purgatory( | 520 | /// PASS means: Relay accepted the event and is holding it in purgatory |
| 521 | /// FAIL means: Either event was rejected, or served immediately (purgatory not implemented) | ||
| 522 | /// | ||
| 523 | /// Note: This test cannot distinguish between "event in purgatory" and | ||
| 524 | /// "event accepted but never stored" - both result in event not being queryable. | ||
| 525 | /// The fixture verifies the relay responded OK, which is the best we can do | ||
| 526 | /// with black-box testing. | ||
| 527 | pub async fn test_pr_event_accepted_into_purgatory_and_isnt_served( | ||
| 521 | client: &AuditClient, | 528 | client: &AuditClient, |
| 522 | ) -> TestResult { | 529 | ) -> TestResult { |
| 523 | TestResult::new( | 530 | TestResult::new( |
| 524 | "pr_event_before_git_data_accepted_into_purgatory", | 531 | "pr_event_accepted_into_purgatory", |
| 525 | SpecRef::PurgatoryAcceptUntilGitData, | 532 | SpecRef::PurgatoryAcceptUntilGitData, |
| 526 | "PR event SHOULD be accepted into purgatory when git data doesn't exist", | 533 | "PR event SHOULD be accepted but not served until git data arrives", |
| 527 | ) | 534 | ) |
| 528 | .run(|| async { | 535 | .run(|| async { |
| 529 | let ctx = TestContext::new(client); | 536 | let ctx = TestContext::new(client); |
| 530 | 537 | ||
| 538 | // PREvent2Sent fixture: | ||
| 539 | // 1. Sends PR event | ||
| 540 | // 2. Verifies relay responded OK (not rejected) | ||
| 541 | // 3. Verifies event is NOT queryable (in purgatory) | ||
| 531 | let pr_event = ctx | 542 | let pr_event = ctx |
| 532 | .get_fixture(FixtureKind::PREvent2Sent) | 543 | .get_fixture(FixtureKind::PREvent2Sent) |
| 533 | .await | 544 | .await |
| 534 | .map_err(|e| format!("Failed to send PR event: {}", e))?; | 545 | .map_err(|e| format!("Failed to send PR event: {}", e))?; |
| 535 | 546 | ||
| 547 | // Double-check: event should not be queryable | ||
| 536 | let filter = Filter::new() | 548 | let filter = Filter::new() |
| 537 | .kind(Kind::GitPullRequest) | 549 | .kind(Kind::GitPullRequest) |
| 538 | .author(client.pr_author_keys().public_key()) | 550 | .author(client.pr_author_keys().public_key()) |
| @@ -547,7 +559,7 @@ impl PurgatoryTests { | |||
| 547 | 559 | ||
| 548 | if !events.is_empty() { | 560 | if !events.is_empty() { |
| 549 | return Err(format!( | 561 | return Err(format!( |
| 550 | "PR event was served immediately - should be in purgatory. Event ID: {}", | 562 | "PR event was served immediately - purgatory not implemented. Event ID: {}", |
| 551 | pr_event.id | 563 | pr_event.id |
| 552 | )); | 564 | )); |
| 553 | } | 565 | } |
| @@ -557,62 +569,26 @@ impl PurgatoryTests { | |||
| 557 | .await | 569 | .await |
| 558 | } | 570 | } |
| 559 | 571 | ||
| 560 | /// Test: PR event remains in purgatory until git data arrives | 572 | /// Test: Git push to refs/nostr/<pr-event-id> is accepted |
| 561 | /// | 573 | /// |
| 562 | /// Verifies the event stays in purgatory until matching git data is pushed. | 574 | /// This test verifies that pushing git data for a PR event in purgatory |
| 563 | pub async fn test_pr_event_remains_in_purgatory_until_git_data( | 575 | /// is accepted by the relay. |
| 564 | client: &AuditClient, | ||
| 565 | ) -> TestResult { | ||
| 566 | TestResult::new( | ||
| 567 | "pr_event_remains_in_purgatory_until_git_data", | ||
| 568 | SpecRef::PurgatoryAcceptUntilGitData, | ||
| 569 | "PR event SHOULD remain in purgatory until git data arrives", | ||
| 570 | ) | ||
| 571 | .run(|| async { | ||
| 572 | let ctx = TestContext::new(client); | ||
| 573 | |||
| 574 | let pr_event = ctx | ||
| 575 | .get_fixture(FixtureKind::PREvent2Sent) | ||
| 576 | .await | ||
| 577 | .map_err(|e| format!("Failed to get PR event: {}", e))?; | ||
| 578 | |||
| 579 | tokio::time::sleep(Duration::from_millis(500)).await; | ||
| 580 | |||
| 581 | let filter = Filter::new() | ||
| 582 | .kind(Kind::GitPullRequest) | ||
| 583 | .author(client.pr_author_keys().public_key()) | ||
| 584 | .id(pr_event.id); | ||
| 585 | |||
| 586 | let events = client | ||
| 587 | .query(filter) | ||
| 588 | .await | ||
| 589 | .map_err(|e| format!("Failed to query PR events: {}", e))?; | ||
| 590 | |||
| 591 | if !events.is_empty() { | ||
| 592 | return Err(format!( | ||
| 593 | "PR event was served without git data - purgatory not working. Event ID: {}", | ||
| 594 | pr_event.id | ||
| 595 | )); | ||
| 596 | } | ||
| 597 | |||
| 598 | Ok(()) | ||
| 599 | }) | ||
| 600 | .await | ||
| 601 | } | ||
| 602 | |||
| 603 | /// Test: Git push accepted for PR event in purgatory | ||
| 604 | /// | 576 | /// |
| 605 | /// Verifies that pushing the correct commit to refs/nostr/<pr-event-id> | 577 | /// PASS means: Git push succeeded, relay accepted the git data |
| 606 | /// is accepted. | 578 | /// FAIL means: Git push was rejected (wrong ref, permissions, etc.) |
| 607 | pub async fn test_pr_event_git_push_accepted(client: &AuditClient) -> TestResult { | 579 | pub async fn test_pr_event_in_purgatory_git_push_accepted(client: &AuditClient) -> TestResult { |
| 608 | TestResult::new( | 580 | TestResult::new( |
| 609 | "pr_event_git_push_accepted", | 581 | "pr_event_in_purgatory_git_push_accepted", |
| 610 | SpecRef::PurgatoryAcceptUntilGitData, | 582 | SpecRef::PurgatoryAcceptUntilGitData, |
| 611 | "Git push for PR event SHOULD be accepted", | 583 | "Git push for PR event SHOULD be accepted", |
| 612 | ) | 584 | ) |
| 613 | .run(|| async { | 585 | .run(|| async { |
| 614 | let ctx = TestContext::new(client); | 586 | let ctx = TestContext::new(client); |
| 615 | 587 | ||
| 588 | // PREvent2GitDataPushed fixture: | ||
| 589 | // 1. Gets PR event in purgatory (PREvent2Sent) | ||
| 590 | // 2. Pushes commit to refs/nostr/<pr-event-id> | ||
| 591 | // 3. Verifies push succeeded | ||
| 616 | let _pr_event = ctx | 592 | let _pr_event = ctx |
| 617 | .get_fixture(FixtureKind::PREvent2GitDataPushed) | 593 | .get_fixture(FixtureKind::PREvent2GitDataPushed) |
| 618 | .await | 594 | .await |
| @@ -623,9 +599,14 @@ impl PurgatoryTests { | |||
| 623 | .await | 599 | .await |
| 624 | } | 600 | } |
| 625 | 601 | ||
| 626 | /// Test: PR event served after git push | 602 | /// Test: PR event served after git data arrives |
| 603 | /// | ||
| 604 | /// This test verifies the full purgatory release mechanism: | ||
| 605 | /// after git data is pushed to refs/nostr/<pr-event-id>, the event | ||
| 606 | /// becomes queryable. | ||
| 627 | /// | 607 | /// |
| 628 | /// Verifies the full purgatory release mechanism. | 608 | /// PASS means: Event was released from purgatory and is now served |
| 609 | /// FAIL means: Event still not queryable after git push (purgatory release broken) | ||
| 629 | pub async fn test_pr_event_served_after_git_push(client: &AuditClient) -> TestResult { | 610 | pub async fn test_pr_event_served_after_git_push(client: &AuditClient) -> TestResult { |
| 630 | TestResult::new( | 611 | TestResult::new( |
| 631 | "pr_event_served_after_git_push", | 612 | "pr_event_served_after_git_push", |
| @@ -635,11 +616,15 @@ impl PurgatoryTests { | |||
| 635 | .run(|| async { | 616 | .run(|| async { |
| 636 | let ctx = TestContext::new(client); | 617 | let ctx = TestContext::new(client); |
| 637 | 618 | ||
| 619 | // PREvent2Served fixture: | ||
| 620 | // 1. Gets PR event with git data pushed (PREvent2GitDataPushed) | ||
| 621 | // 2. Verifies event is now queryable | ||
| 638 | let pr_event = ctx | 622 | let pr_event = ctx |
| 639 | .get_fixture(FixtureKind::PREvent2Served) | 623 | .get_fixture(FixtureKind::PREvent2Served) |
| 640 | .await | 624 | .await |
| 641 | .map_err(|e| format!("Failed to complete purgatory release: {}", e))?; | 625 | .map_err(|e| format!("Failed to complete purgatory release: {}", e))?; |
| 642 | 626 | ||
| 627 | // Double-check: event should be queryable now | ||
| 643 | let filter = Filter::new() | 628 | let filter = Filter::new() |
| 644 | .kind(Kind::GitPullRequest) | 629 | .kind(Kind::GitPullRequest) |
| 645 | .author(client.pr_author_keys().public_key()) | 630 | .author(client.pr_author_keys().public_key()) |
diff --git a/tests/purgatory.rs b/tests/purgatory.rs index f124b7c..e99540b 100644 --- a/tests/purgatory.rs +++ b/tests/purgatory.rs | |||
| @@ -77,7 +77,6 @@ isolated_purgatory_test!(test_state_event_served_after_git_push); | |||
| 77 | // PR Purgatory Tests | 77 | // PR Purgatory Tests |
| 78 | // ============================================================ | 78 | // ============================================================ |
| 79 | 79 | ||
| 80 | isolated_purgatory_test!(test_pr_event_before_git_data_accepted_into_purgatory); | 80 | isolated_purgatory_test!(test_pr_event_accepted_into_purgatory_and_isnt_served); |
| 81 | isolated_purgatory_test!(test_pr_event_remains_in_purgatory_until_git_data); | 81 | isolated_purgatory_test!(test_pr_event_in_purgatory_git_push_accepted); |
| 82 | isolated_purgatory_test!(test_pr_event_git_push_accepted); | ||
| 83 | isolated_purgatory_test!(test_pr_event_served_after_git_push); | 82 | isolated_purgatory_test!(test_pr_event_served_after_git_push); |