// SPDX-License-Identifier: GPL-3.0-or-later package eventlog import ( "encoding/json" "os" "path/filepath" "testing" ) func TestReadRecentSpansRotationInChronologicalOrder(t *testing.T) { path := filepath.Join(t.TempDir(), "events.jsonl") writeLines(t, path+".1", 1, 2, 3) writeLines(t, path, 4, 5) rows, err := ReadRecent(path, 3) if err != nil { t.Fatal(err) } if got := rowSequences(t, rows); len(got) != 3 || got[0] != 3 || got[1] != 4 || got[2] != 5 { t.Fatalf("sequences=%v", got) } } func TestReadRecentReturnsAllWhenUnderLimit(t *testing.T) { path := filepath.Join(t.TempDir(), "events.jsonl") writeLines(t, path, 7, 8) rows, err := ReadRecent(path, 10) if err != nil { t.Fatal(err) } if got := rowSequences(t, rows); len(got) != 2 || got[0] != 7 || got[1] != 8 { t.Fatalf("sequences=%v", got) } } func TestReadRecentRejectsCorruptionAndInvalidArguments(t *testing.T) { path := filepath.Join(t.TempDir(), "events.jsonl") if err := os.WriteFile(path, []byte("{not-json}\n"), 0o600); err != nil { t.Fatal(err) } if _, err := ReadRecent(path, 1); err == nil { t.Fatal("corrupt log accepted") } if _, err := ReadRecent("", 1); err == nil { t.Fatal("empty path accepted") } if _, err := ReadRecent(path, 0); err == nil { t.Fatal("zero limit accepted") } } func writeLines(t *testing.T, path string, sequences ...int) { t.Helper() file, err := os.Create(path) if err != nil { t.Fatal(err) } defer file.Close() encoder := json.NewEncoder(file) for _, sequence := range sequences { if err := encoder.Encode(map[string]any{"sequence": sequence}); err != nil { t.Fatal(err) } } } func rowSequences(t *testing.T, rows [][]byte) []int { t.Helper() result := make([]int, 0, len(rows)) for _, row := range rows { var record struct { Sequence int `json:"sequence"` } if err := json.Unmarshal(row, &record); err != nil { t.Fatal(err) } result = append(result, record.Sequence) } return result }