Files

85 lines
2.2 KiB
Go

package agent
import (
"bytes"
"os"
"path/filepath"
"testing"
"time"
)
func testSpool(t *testing.T) *Spool {
t.Helper()
now := time.Date(2026, 9, 18, 0, 0, 0, 0, time.UTC)
s, err := NewSpool(t.TempDir(), func() time.Time { return now })
if err != nil {
t.Fatal(err)
}
return s
}
func TestSpoolAtomicStateAndBootUnknown(t *testing.T) {
s := testSpool(t)
if _, err := s.Start("exec-1", 1, "session-1"); err != nil {
t.Fatal(err)
}
if _, err := s.Update("exec-1", "running", ""); err != nil {
t.Fatal(err)
}
report, err := s.MarkUnknownOnBoot()
if err != nil {
t.Fatal(err)
}
if len(report.Unknown) != 1 || report.Unknown[0] != "exec-1" {
t.Fatalf("recovery report = %+v", report)
}
state, err := s.Load("exec-1")
if err != nil {
t.Fatal(err)
}
if state.Status != "unknown" || !state.Unknown {
t.Fatalf("state = %+v", state)
}
}
func TestSpoolQuarantinesCorruptStateAndNeverDeletesIt(t *testing.T) {
s := testSpool(t)
if err := os.MkdirAll(filepath.Join(s.Root(), "broken"), 0o700); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(s.Root(), "broken", "state.json"), []byte("{"), 0o600); err != nil {
t.Fatal(err)
}
report, err := s.MarkUnknownOnBoot()
if err != nil {
t.Fatal(err)
}
if len(report.Quarantined) != 1 || len(report.Unknown) != 0 {
t.Fatalf("recovery report = %+v", report)
}
matches, err := filepath.Glob(filepath.Join(s.Root(), "broken", "state.json.corrupt-*"))
if err != nil || len(matches) != 1 {
t.Fatalf("quarantine files = %v, err=%v", matches, err)
}
}
func TestSpoolTranscriptAndAssetAreDurableFiles(t *testing.T) {
s := testSpool(t)
if _, err := s.Start("exec-2", 1, "session-2"); err != nil {
t.Fatal(err)
}
if err := s.AppendTranscript("exec-2", []byte(`{"text":"hello","final":true}`)); err != nil {
t.Fatal(err)
}
path, n, hash, err := s.WriteAsset("exec-2", "recording.pcm", bytes.NewReader([]byte("pcm")))
if err != nil {
t.Fatal(err)
}
if n != 3 || hash == "" || path == "" {
t.Fatalf("asset result path=%q bytes=%d hash=%q", path, n, hash)
}
if _, err := os.Stat(filepath.Join(s.Root(), "exec-2", "assets", "recording.pcm.part")); !os.IsNotExist(err) {
t.Fatalf("temporary asset still exists: %v", err)
}
}