fix(tests): test-created devices and fixture dirs now meet the cleanup contract

Test suites that attach devices to the SHARED admin (testuser, the live
dev account) escaped the harness sweeps whenever their names lacked
"test": createContractDeviceNamed named its devices by surface type
("koreader" — the web progress push adopts the device name as sync
source, so conflict tests drive a second named source without a
separate account), the reinstall regression test uses the web flow's
real "Reinstall Device" label, and opds_test.go's folders test named
its device "OPDS Folders Device". None had self-cleanup either, so
every suite run left 3 more rows on the dev account's device grid —
476 by the time anyone looked. TestDeviceSetup.CreateDevice also never
cleanup-registered, so any CURRENT or future helper-created device was
one rename away from the same leak.

Changes:
- TestDeviceSetup.CreateDevice self-deletes its row at test end
  (t.Cleanup): callers owe nothing to name hygiene any more.
- createContractDeviceNamed self-deletes likewise (contract-% prefix).
- device_test.go: core via cleanupDeviceByIdentifier on every device it
  attaches to the admin ("Reinstall Device" by unique identifier —
  the NAME is user-facing-labeled, sweeps must never torch it).
- Harness setup-time admin-device sweep gains the unambiguous harness
  patterns (dev_contract_* tokens, contract-%/opds-%/repro-reinstall-%
  identifiers) as the drift net; ran once with the rebuilt tests image
  and that sweep alone already purged the existing 476 rows.
- metadata_write_test.go now globs ALL test-metadata-write-* dirs in
  its RemoveAll instead of only its own pid's — killed runs left root-
  owned dirs on the user's uploads bind mount (7 found, deleted).

 audits: collections/saved-filters/libraries/sync_queue are clean;
 the only "test"-named media rows left are scans of the user's own
 on-disk test files (Test/, Bookhoard Test/, embedded " test" in two
 real books' metadata) — content, not suite debris.

Verified: filtered runs (contract/OPDS/reinstall/pairing/metadata)
green, zero device residue after the run, uploads mount clean.
This commit is contained in:
John O'Keefe committed 2026-11-02 17:39:29 -05:00
1 parent 0c31e9b88d
commit 7d88ec5184
5 files changed
+68 -4

No files matched your search

+11
View File
@@ -19,6 +19,9 @@ import (
func TestDeviceRegistrationFlow(t *testing.T) {
setup := setupTestServer(t)
// Approved through the shared admin's session; the row must not
// outlive the test (name hygiene alone should never carry it).
cleanupDeviceByIdentifier(t, setup, "kindle-test-hw-id-12345")
// Step 1: Initiate device registration
regRequest := map[string]interface{}{
@@ -208,6 +211,7 @@ func TestDeviceAuthentication(t *testing.T) {
// Create a device directly in the database
userID := getTestUserID(t, setup.DB)
cleanupDeviceByIdentifier(t, setup, "test-device-123")
deviceToken := fmt.Sprintf("dev_%s", uuid.New().String())
_, err := setup.DB.CreateDevice(context.Background(), database.CreateDeviceParams{
@@ -279,6 +283,10 @@ func TestApproveDeviceReapprovalRotatesToken(t *testing.T) {
userID := getTestUserID(t, setup.DB)
identifier := fmt.Sprintf("repro-reinstall-%s", uuid.New().String())
// Self-delete: the row is named "Reinstall Device" — the web
// reinstall flow's own label — so the name-based sweeps can never
// safely touch it. The identifier is this test's fixture alone.
cleanupDeviceByIdentifier(t, setup, identifier)
registerAndApprove := func() string {
regRequest := map[string]interface{}{
@@ -352,6 +360,9 @@ func TestApproveDeviceReapprovalRotatesToken(t *testing.T) {
func TestApproveDeviceRegistration(t *testing.T) {
setup := setupTestServer(t)
// Approved through the shared admin's session; the row must not
// outlive the test (name hygiene alone should never carry it).
cleanupDeviceByIdentifier(t, setup, "test-approval-12345")
regRequest := map[string]interface{}{
"device_name": "Test Device for Approval",