package spool import ( "bytes" "errors" "os" "path/filepath" "testing" ) func TestRoundTrip(t *testing.T) { dir := filepath.Join(t.TempDir(), "spool") s, err := Open(dir, 0) if err != nil { t.Fatal(err) } if fi, err := os.Stat(dir); err != nil || fi.Mode().Perm() != 0o700 { t.Fatalf("spool dir perms: %v %v", fi, err) } if _, _, err := s.Oldest(); !errors.Is(err, ErrEmpty) { t.Fatalf("expected ErrEmpty, got %v", err) } a := []byte("batch-a") b := []byte("batch-b-longer") na, _ := s.Write(a) nb, _ := s.Write(b) if na >= nb { t.Fatalf("names must sort chronologically: %s %s", na, nb) } n, size := s.Stats() if n != 2 || size != int64(len(a)+len(b)) { t.Fatalf("stats = %d %d", n, size) } name, data, err := s.Oldest() if err != nil || name != na || !bytes.Equal(data, a) { t.Fatalf("oldest = %s %q %v", name, data, err) } if err := s.Remove(name); err != nil { t.Fatal(err) } name, data, _ = s.Oldest() if name != nb || !bytes.Equal(data, b) { t.Fatalf("second oldest = %s %q", name, data) } s.Remove(name) if _, _, err := s.Oldest(); !errors.Is(err, ErrEmpty) { t.Fatal("spool should be empty") } if err := s.Remove("does-not-exist.json.gz"); err != nil { t.Fatalf("removing a missing file must be a no-op: %v", err) } } func TestCapDropsOldest(t *testing.T) { s, err := Open(t.TempDir(), 1000) if err != nil { t.Fatal(err) } chunk := bytes.Repeat([]byte("x"), 300) var names []string for i := 0; i < 5; i++ { // 1500 bytes > cap 1000 → the two oldest must go n, err := s.Write(chunk) if err != nil { t.Fatal(err) } names = append(names, n) } count, size := s.Stats() if count != 3 || size != 900 { t.Fatalf("after cap: %d files, %d bytes", count, size) } oldest, _, _ := s.Oldest() if oldest != names[2] { t.Fatalf("oldest kept should be %s, got %s", names[2], oldest) } } func TestIgnoresForeignFilesAndTmp(t *testing.T) { dir := t.TempDir() s, _ := Open(dir, 0) os.WriteFile(filepath.Join(dir, "notes.txt"), []byte("x"), 0o600) os.WriteFile(filepath.Join(dir, "1.json.gz.tmp"), []byte("x"), 0o600) if n, _ := s.Stats(); n != 0 { t.Fatalf("foreign files counted: %d", n) } s.Write([]byte("ok")) if _, err := os.Stat(filepath.Join(dir, "1.json.gz.tmp")); !errors.Is(err, os.ErrNotExist) { t.Fatal("stale tmp file should be cleaned on write") } }