a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
114 lines
3.2 KiB
Go
114 lines
3.2 KiB
Go
package crashpool
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"sync"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestQuarantine_LoadMissingFile(t *testing.T) {
|
|
q := LoadQuarantine(filepath.Join(t.TempDir(), "nope.json"))
|
|
require.Equal(t, 0, q.Len())
|
|
require.False(t, q.IsQuarantined("a.go", 1))
|
|
}
|
|
|
|
func TestQuarantine_AddAndCheck(t *testing.T) {
|
|
q := LoadQuarantine("")
|
|
q.Add("bad.go", "SIGSEGV", 100)
|
|
|
|
// Same revision → quarantined (skip on retry).
|
|
require.True(t, q.IsQuarantined("bad.go", 100))
|
|
// Changed revision → not quarantined (gets one retry).
|
|
require.False(t, q.IsQuarantined("bad.go", 200))
|
|
// Unknown file → never quarantined.
|
|
require.False(t, q.IsQuarantined("good.go", 100))
|
|
}
|
|
|
|
func TestQuarantine_ReAddBumpsAttempts(t *testing.T) {
|
|
q := LoadQuarantine("")
|
|
q.Add("bad.go", "crash", 100)
|
|
q.Add("bad.go", "crash again", 200)
|
|
|
|
entries := q.Entries()
|
|
require.Len(t, entries, 1)
|
|
require.Equal(t, 2, entries[0].Attempts)
|
|
require.Equal(t, int64(200), entries[0].MtimeNano)
|
|
require.Equal(t, "crash again", entries[0].Reason)
|
|
}
|
|
|
|
func TestQuarantine_Forget(t *testing.T) {
|
|
q := LoadQuarantine("")
|
|
q.Add("bad.go", "crash", 100)
|
|
require.True(t, q.IsQuarantined("bad.go", 100))
|
|
q.Forget("bad.go")
|
|
require.False(t, q.IsQuarantined("bad.go", 100))
|
|
require.Equal(t, 0, q.Len())
|
|
}
|
|
|
|
func TestQuarantine_SaveReload(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "nested", "quarantine.json")
|
|
q := LoadQuarantine(path)
|
|
q.Add("a.go", "boom", 1)
|
|
q.Add("b.go", "hang", 2)
|
|
require.NoError(t, q.Save())
|
|
|
|
reloaded := LoadQuarantine(path)
|
|
require.Equal(t, 2, reloaded.Len())
|
|
require.True(t, reloaded.IsQuarantined("a.go", 1))
|
|
require.True(t, reloaded.IsQuarantined("b.go", 2))
|
|
|
|
entries := reloaded.Entries()
|
|
require.Equal(t, "a.go", entries[0].RelPath) // sorted
|
|
require.Equal(t, "b.go", entries[1].RelPath)
|
|
}
|
|
|
|
func TestQuarantine_NilSafe(t *testing.T) {
|
|
var q *Quarantine
|
|
require.False(t, q.IsQuarantined("x", 1))
|
|
require.Equal(t, 0, q.Len())
|
|
require.Nil(t, q.Entries())
|
|
q.Add("x", "y", 1) // no panic
|
|
q.Forget("x") // no panic
|
|
require.NoError(t, q.Save())
|
|
}
|
|
|
|
func TestQuarantine_EmptyPathSaveNoop(t *testing.T) {
|
|
q := LoadQuarantine("")
|
|
q.Add("a.go", "x", 1)
|
|
require.NoError(t, q.Save()) // no file, no error
|
|
}
|
|
|
|
func TestQuarantine_CorruptFileTolerated(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "corrupt.json")
|
|
require.NoError(t, os.WriteFile(path, []byte("{not json at all"), 0o644))
|
|
q := LoadQuarantine(path)
|
|
require.Equal(t, 0, q.Len()) // corrupt → treated as empty
|
|
}
|
|
|
|
// TestQuarantine_ConcurrentSave runs many Saves at once: a shared
|
|
// quarantine is saved per indexed file across parallel re-indexes, so
|
|
// the unique temp-file name must keep concurrent writes from
|
|
// clobbering each other and leave a final file that decodes cleanly.
|
|
func TestQuarantine_ConcurrentSave(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "q.json")
|
|
q := LoadQuarantine(path)
|
|
q.Add("bad.go", "SIGSEGV", 123)
|
|
|
|
var wg sync.WaitGroup
|
|
for range 16 {
|
|
wg.Add(1)
|
|
go func() {
|
|
defer wg.Done()
|
|
require.NoError(t, q.Save())
|
|
}()
|
|
}
|
|
wg.Wait()
|
|
|
|
reloaded := LoadQuarantine(path)
|
|
require.Equal(t, 1, reloaded.Len())
|
|
require.True(t, reloaded.IsQuarantined("bad.go", 123))
|
|
}
|