From d38825c72dd19112b828bac24cc0b5a067e42cd3 Mon Sep 17 00:00:00 2001 From: ChakraFusion <112588066+ChakraFusion@users.noreply.github.com> Date: Tue, 20 Oct 2026 21:52:50 +0200 Subject: [PATCH 1/2] api: the age-sweep test waits for the archive to go, as it does for the row TestSettings_AutoDeleteOldSnapshots_SweepsWhenSwitchedOn waited until the old snapshot's row was gone, then looked once for its archive. The sweep (PruneOlderThan) deletes the rows first and the archives only after its last row, so under load the archive was still there: "the deleted snapshot's archive is still on disk". With a 300 ms pause put before the archives are dropped, the old test fails 3/3 and this one passes. Co-Authored-By: Claude Opus 5.5 --- internal/api/age_retention_test.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/internal/api/age_retention_test.go b/internal/api/age_retention_test.go index 29b06450..7c968155 100644 --- a/internal/api/age_retention_test.go +++ b/internal/api/age_retention_test.go @@ -72,7 +72,13 @@ func TestSettings_AutoDeleteOldSnapshots_SweepsWhenSwitchedOn(t *testing.T) { if _, err := ts.daemon.Store.GetSnapshot(newest[0].ID); err != nil { t.Errorf("the branch's newest snapshot was deleted") } - if _, err := os.Stat(filepath.Join(backups, "snap_old_auto.zip")); err == nil { + // Waited for, not looked at once: the sweep deletes the rows first and + // the archives after its last row (PruneOlderThan), so under load the row + // was found gone while the archive was still there. + if !waitFor(10*time.Second, func() bool { + _, err := os.Stat(filepath.Join(backups, "snap_old_auto.zip")) + return os.IsNotExist(err) + }) { t.Errorf("the deleted snapshot's archive is still on disk") } } From a0442228c5499d54c3747cd7c53b53e62b9420ea Mon Sep 17 00:00:00 2001 From: ChakraFusion <112588066+ChakraFusion@users.noreply.github.com> Date: Wed, 21 Oct 2026 00:33:47 +0200 Subject: [PATCH 2/2] api: the missing-location test retries removing the folder it just added Adding a save location starts its watch and first read in the background (RewatchGame). The test removed the folder straight away, and on Windows under load that failed: "The process cannot access the file because it is being used by another process" - the test racing the app, as testutil.RemoveTree says of the same race in the e2e tests. Retried for up to five seconds. Co-Authored-By: Claude Opus 5.5 --- internal/api/savefiles_edge_test.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/internal/api/savefiles_edge_test.go b/internal/api/savefiles_edge_test.go index 0e62616e..8fe89943 100644 --- a/internal/api/savefiles_edge_test.go +++ b/internal/api/savefiles_edge_test.go @@ -8,6 +8,7 @@ import ( "runtime" "strconv" "testing" + "time" ) // A location whose folder is gone must not blank the listing. Somebody who @@ -33,9 +34,13 @@ func TestSaveFiles_MissingLocationDoesNotBreakTheListing(t *testing.T) { } ts.do(t, http.MethodPost, "/api/games/gone-loc/roots", map[string]string{"name": "config", "path": cfg}) - // The drive goes away. - if err := os.RemoveAll(cfg); err != nil { - t.Fatal(err) + // The drive goes away. Retried briefly: adding the location started its + // watch and first read in the background (RewatchGame), and on Windows a + // folder being read cannot be removed ("used by another process") — this + // test racing the app, as testutil.RemoveTree says of the same race. + var rmErr error + if !waitFor(5*time.Second, func() bool { rmErr = os.RemoveAll(cfg); return rmErr == nil }) { + t.Fatal(rmErr) } list := getSaveFiles(t, ts, "gone-loc", nil)