Files
felhom.eu/hub/internal/store/customer_delete_purge_test.go
T
admin 2752e12acc hub v0.60.1: host deletion demotes escrow custody (never destroys) + customer-delete purge point + S6b obsolete
- DeleteHost(deleteEscrow) demotes current host_escrow into host_escrow_superseded (copy-before-delete, same tx), spares existing; one shared demoteCurrentEscrowTx (reused by SaveHostEscrow). F-14 provenance/gate unchanged.
- DeleteCustomerConfig now purges both escrow tables for all the customer's hosts incl. already-deleted (F-14 provenance UNION) — the one true purge point.
- Wording: checkbox/refusal/Danger-zone → demotion. S6b OBSOLETE. Red-proofs TestDeleteHost_Demotes + TestDeleteCustomer_Purges + wording guard.
2026-07-17 11:25:38 +02:00

45 lines
1.9 KiB
Go

package store
import "testing"
// Scenario B (v0.60.1) — the customer Danger-zone Delete is the one true purge point: it removes
// host_escrow AND host_escrow_superseded for ALL the customer's hosts, including hosts already deleted
// (whose demoted blobs survive as superseded rows), so nothing is left orphaned. RED-PROOF: pre-fix
// DeleteCustomerConfig deleted only customer_configs → the escrow blobs survived → the assertions FAIL.
func TestDeleteCustomer_PurgesEscrowCustody(t *testing.T) {
s := newTestStore(t)
const cust = "cust-b"
if err := s.UpsertHost(&Host{HostID: "b1", CustomerID: cust, APIKey: "k1"}); err != nil {
t.Fatal(err)
}
if err := s.UpsertHost(&Host{HostID: "b2", CustomerID: cust, APIKey: "k2"}); err != nil {
t.Fatal(err)
}
// b1: current SHA_A + superseded SHA_OLD; b2: current SHA_B.
s.SaveHostEscrow("b1", []byte("old"), "fp", "zk", "t", "SHA_OLD")
s.SaveHostEscrow("b1", []byte("A"), "fp", "zk", "t", "SHA_A")
s.SaveHostEscrow("b2", []byte("B"), "fp", "zk", "t", "SHA_B")
// ORDERING: delete b2 as a HOST first — SHA_B is demoted to a superseded row and the b2 host row is
// gone (so it can only be found again via the F-14 host_deletions provenance).
if err := s.DeleteHost("b2", true); err != nil {
t.Fatal(err)
}
if n, _ := s.CountSupersededEscrow("b2"); n != 1 {
t.Fatalf("precondition: b2 demoted blob = %d, want 1", n)
}
// The customer Danger-zone Delete purges EVERYTHING for the customer's hosts (current + orphaned).
if err := s.DeleteCustomerConfig(cust); err != nil {
t.Fatalf("DeleteCustomerConfig: %v", err)
}
for _, h := range []string{"b1", "b2"} {
if cur, _ := s.GetHostEscrow(h); cur != nil {
t.Fatalf("%s current escrow survived the customer delete", h)
}
if n, _ := s.CountSupersededEscrow(h); n != 0 {
t.Fatalf("%s retained escrow survived the customer delete: %d (orphaned)", h, n)
}
}
}