package spool import ( "context" "errors" "path/filepath" "testing" "time" rvboxv1 "github.com/rvbox/rvbox/gen/go/rvbox/v1" "github.com/rvbox/rvbox/internal/domain" ) func TestCheckSpoolPayloadsAndCounters_HP_CLIENT_09(t *testing.T) { t.Parallel() ctx := context.Background() store := openTestStore(t, ctx, filepath.Join(t.TempDir(), "spool"), DefaultTombstoneLimit) issue := testUUID(t, "019c46f1-1d02-7000-8000-000000000041") if _, err := store.AcceptCommand(ctx, testCommand(issue, []byte("recovery")), time.Now().UTC()); err != nil { t.Fatal(err) } if _, err := store.AppendEvent(ctx, issue, EventInput{Kind: 1, Compression: 1, Payload: []byte("durable event"), CreatedAt: time.Now().UTC()}); err != nil { t.Fatal(err) } report, err := store.Check(ctx) if err != nil || report.EventsChecked != 1 || report.ScriptsChecked != 0 { t.Fatalf("initial Check = %#v, %v", report, err) } if _, err := store.db.ExecContext(ctx, `UPDATE events SET payload = ? WHERE issue_uuid = ?`, []byte("tampered"), issue[:]); err != nil { t.Fatal(err) } if _, err := store.Check(ctx); !errors.Is(err, ErrStoredPayloadChecksum) { t.Fatalf("tampered event Check error = %v, want ErrStoredPayloadChecksum", err) } } func TestCheckSpoolRejectsCounterDrift_BH_CLIENT_03(t *testing.T) { t.Parallel() ctx := context.Background() store := openTestStore(t, ctx, filepath.Join(t.TempDir(), "spool"), DefaultTombstoneLimit) issue := testUUID(t, "019c46f1-1d02-7000-8000-000000000042") if _, err := store.AcceptCommand(ctx, testCommand(issue, []byte("recovery")), time.Now().UTC()); err != nil { t.Fatal(err) } if _, err := store.db.ExecContext(ctx, `UPDATE spool_counters SET client_total_charged_bytes = client_total_charged_bytes + 1`); err != nil { t.Fatal(err) } if _, err := store.Check(ctx); !errors.Is(err, ErrQuotaCounterMismatch) { t.Fatalf("counter-drift Check error = %v, want ErrQuotaCounterMismatch", err) } } func TestRecoverLaunchUncertaintyFencesRedispatchAfterRestart_HP_CLIENT_12(t *testing.T) { t.Parallel() ctx := context.Background() store := openTestStore(t, ctx, filepath.Join(t.TempDir(), "spool"), DefaultTombstoneLimit) issue := testUUID(t, "019c46f1-1d02-7000-8000-000000000043") command := testCommand(issue, []byte("uncertain launch")) command.Phase = uint32(rvboxv1.CommandLifecycle_COMMAND_ACCEPTED) now := time.Date(2026, time.September, 6, 12, 0, 0, 0, time.UTC) if _, err := store.AcceptCommand(ctx, command, now); err != nil { t.Fatal(err) } if err := store.SetLaunchPhase(ctx, issue, domain.LaunchPhaseAuthorized, "LOCAL_SYSTEM", 42); err != nil { t.Fatal(err) } recovered, err := store.RecoverLaunchUncertainty(ctx, now.Add(time.Second)) if err != nil || len(recovered) != 1 || recovered[0] != issue { t.Fatalf("recovered = %v, %v", recovered, err) } var phase, launchPhase uint32 if err := store.db.QueryRow(`SELECT phase, launch_phase FROM commands WHERE issue_uuid = ?`, issue[:]).Scan(&phase, &launchPhase); err != nil { t.Fatal(err) } if phase != uint32(rvboxv1.CommandLifecycle_COMMAND_INTERRUPTED) || launchPhase != 0 { t.Fatalf("recovered phase/barrier = %d/%d", phase, launchPhase) } if second, err := store.RecoverLaunchUncertainty(ctx, now.Add(2*time.Second)); err != nil || len(second) != 0 { t.Fatalf("recovery repeated = %v, %v", second, err) } }