mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 17:11:30 +00:00
7d2106bfb5
* fix(test): reclaim fixture scratch dirs stranded in /tmp The shared predastore fixture and the integration suite's JetStream store both outlive any individual test, so neither can use t.TempDir() - the first test to finish would delete files the daemon still has open. Both used os.MkdirTemp with nothing removing the directory afterwards, so every run stranded one, and a run killed by a timeout panic or the OOM killer stranded it regardless. /tmp is a tmpfs on the dev boxes, so the leak is charged to RAM and swap, and swapped tmpfs pages have no backing store to be dropped to. Add a shared sweep that reclaims a directory only when it matches both the prefix and an age no live run can reach. The NATS store also has a clean shutdown point, so TestMain now removes it outright and the sweep is left to cover the killed-run case. The predastore daemon runs until the process exits and has no such point, so the sweep is its only mechanism. * chore: repin viperblock to the dev tip carrying the scratch-dir fix Test-only upstream change, so the build output is unchanged - this keeps go.mod aligned with the submodule pointer rather than delivering a fix.
51 lines
1.9 KiB
Go
51 lines
1.9 KiB
Go
package scratch
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// The sweep runs against a directory shared with other processes, so what it
|
|
// declines to touch matters as much as what it reclaims: only a directory that
|
|
// matches the prefix AND is far older than any live run may go.
|
|
func TestSweepAbandoned(t *testing.T) {
|
|
tmpDir := t.TempDir()
|
|
stale := time.Now().Add(-DefaultMaxAge - time.Hour)
|
|
|
|
mkdir := func(name string, modTime time.Time) string {
|
|
path := filepath.Join(tmpDir, name)
|
|
require.NoError(t, os.MkdirAll(filepath.Join(path, "data"), 0o750))
|
|
require.NoError(t, os.Chtimes(path, modTime, modTime))
|
|
return path
|
|
}
|
|
|
|
abandoned := mkdir("fixture-1234567890", stale)
|
|
concurrent := mkdir("fixture-0987654321", time.Now())
|
|
otherPrefix := mkdir("some-other-tool-cache", stale)
|
|
|
|
// A stale FILE sharing the prefix is not scratch and is not ours to delete.
|
|
stalefile := filepath.Join(tmpDir, "fixture-notadir")
|
|
require.NoError(t, os.WriteFile(stalefile, []byte("x"), 0o600))
|
|
require.NoError(t, os.Chtimes(stalefile, stale, stale))
|
|
|
|
SweepAbandoned(tmpDir, "fixture-", DefaultMaxAge)
|
|
|
|
assert.NoDirExists(t, abandoned, "a stale scratch dir from a killed run must be reclaimed")
|
|
assert.DirExists(t, concurrent, "a freshly-modified scratch dir may belong to a concurrent test binary")
|
|
assert.DirExists(t, otherPrefix, "the sweep must not touch directories outside its own prefix")
|
|
assert.FileExists(t, stalefile, "the sweep must only remove directories")
|
|
}
|
|
|
|
// A missing or unreadable directory is not a test failure: the sweep exists to
|
|
// reclaim disk, and failing to do so must never take the run down with it.
|
|
func TestSweepAbandonedToleratesUnreadableDir(t *testing.T) {
|
|
assert.NotPanics(t, func() {
|
|
SweepAbandoned(filepath.Join(t.TempDir(), "does-not-exist"), "fixture-", DefaultMaxAge)
|
|
})
|
|
}
|