Skip to content

test(agents): cover the sandbox reaper pass against a fake apiserver - #21

Draft
tee8z wants to merge 1 commit into
dev-2884-reaper-reconcile-enginefrom
dev-2884-reaper-reconcile-tests
Draft

tee8z wants to merge 1 commit into
dev-2884-reaper-reconcile-enginefrom
dev-2884-reaper-reconcile-tests

Conversation

@tee8z

@tee8z tee8z commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

Layer 3 adds Reconciler::pass without scenario tests. This PR adds them. src/fake_apiserver.rs is an in-memory apiserver for one namespace behind the real kube::Client request path. It serves the Date header, applies JSON merge patches, and returns 409 Conflict on a stale resourceVersion or failed delete precondition. It records every request so tests can assert what the reaper wrote.

Test Expected behavior
a_completed_session_with_a_verified_receipt_is_tombstoned_once One CAS patch with the verified key; the next pass writes nothing
a_completed_session_without_a_checkpoint_is_held_for_24_hours One CheckpointMissing Event; tombstone missing after 24 h
a_failed_recovery_carries_its_restore_checkpoint_forward Hold, then tombstone with the recovered-from key
a_stopped_session_records_the_receipt_its_deleted_pod_left_behind Receipt from the watch is used after the Pod is gone
a_receipt_s3_does_not_confirm_is_recorded_as_missing Unconfirmed receipt gives missing
an_s3_outage_defers_the_tombstone No write while S3 fails
a_replaced_session_is_tombstoned_with_the_old_pods_receipt Reason replaced, old Pod's key
a_lost_pod_is_tombstoned_only_after_the_grace No write at 59 s; reason lost at 60 s
abandoned_bindings_are_tombstoned_without_probing_s3 bind-abandoned and binding-failed; no S3 probe
sessions_without_checkpointing_are_tombstoned_as_unconfigured Checkpoint unconfigured
a_cas_conflict_re_reads_and_re_classifies Peer's tombstone stands; one losing patch only
expired_tombstones_are_deleted_with_uid_and_version_preconditions Delete at 30 days, not 1 s before
foreign_owners_are_left_alone_and_reported_once One SandboxIgnored Event over two passes; unlabeled Sandboxes not listed
without_an_apiserver_date_the_pass_writes_nothing Pass returns an error; no writes
dry_run_decides_but_writes_nothing No writes, no Events
receipt_memory_is_bounded_and_pruned_to_bound_pods At most MAX_RECEIPTS; oversized and blank messages ignored
no_pass_resurrects_or_discards_a_live_session (property) Patches only write the tombstone shape; deletes only expired ended tombstones

proptest-regressions/reconcile_tests.txt keeps two shrunk failure seeds for the property test.

Stack

Position 17 of 20 in the DEV-2884 Buzz stack. Base: #20. Next: #4.

Validation

Run in a worktree at this commit (CARGO_TARGET_DIR shared, CARGO_BUILD_JOBS=4):

  • cargo fmt --check: pass.
  • cargo clippy -p buzz-sandbox-reaper --all-targets --locked -- -D warnings: pass.
  • cargo test -p buzz-sandbox-reaper --locked: 31 passed, 0 failed (17 new reconcile tests).

Limits

  • This layer adds back the 4-line test module declaration that layer 3 omitted from src/reconcile.rs.
  • Temporary glue: src/main.rs is still the placeholder (#![allow(dead_code)], empty fn main() {}). Layer 5 replaces it.
  • The fake apiserver models only the requests the reaper makes. It does not enforce RBAC (role-based access control) or exercise the Pod watch stream. No live cluster is exercised.
  • Buzz AGENTS.md requires a human to test the change before it leaves draft.

Add an in-memory fake Kubernetes apiserver (Sandboxes, Pods, Events,
merge patches with resourceVersion and UID preconditions, Date header)
and reconcile scenario tests over it: tombstoning with verified, missing,
and inherited checkpoints, the 24-hour hold, lost-Pod grace, CAS
conflicts, expired tombstone deletion, foreign owners, and dry run.

A property test checks that no pass resurrects or discards a live
session; its proptest regression seeds are checked in.

Signed-off-by: Tee8z <tee8z@protonmail.com>
@tee8z
tee8z force-pushed the dev-2884-reaper-reconcile-tests branch from 46bd90a to 5f1c312 Compare October 19, 2026 23:28
@coderabbitai

coderabbitai Bot commented Oct 19, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant