repositories / bugabinga.net
bugabinga.net
personal infrastructure for bugabinga!
owned by admin
services/luci/internal/history/history_test.go
Rawpackage history
import (
"errors"
"io"
"os"
"strings"
"testing"
"time"
"github.com/klauspost/compress/zstd"
)
func TestAppendBoundsUntrustedEventText(t *testing.T) {
store := Store{DataDir: t.TempDir()}
matrix := map[string]string{}
for i := range 64 {
matrix[string(rune('A'+i%26))+strings.Repeat("k", 1100)] = strings.Repeat("v", 5000)
}
if _, err := store.Append(Event{RunID: "large", ChildID: "run", Repo: "repo", Job: strings.Repeat("j", 70000), Status: "failed", Detail: strings.Repeat("x", 70000), Matrix: matrix}); err != nil {
t.Fatal(err)
}
events, err := ReadAll(store.DataDir)
if err != nil || len(events) != 1 || len(events[0].Job) > 4100 || len(events[0].Detail) > 8200 {
t.Fatalf("events=%d err=%v", len(events), err)
}
}
func TestReadAllEmptyAndInvalidFiles(t *testing.T) {
dir := t.TempDir()
events, err := ReadAll(dir)
if err != nil {
t.Fatalf("ReadAll empty error = %v", err)
}
if len(events) != 0 {
t.Fatalf("empty events = %#v", events)
}
if err := os.MkdirAll(dir+"/events", 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(dir+"/events/bad.jsonl.zst", []byte("not zstd"), 0o644); err != nil {
t.Fatal(err)
}
if _, err := ReadAll(dir); err == nil {
t.Fatal("invalid zstd accepted")
}
}
func TestReadAllRejectsBrokenInputs(t *testing.T) {
dir := t.TempDir()
if err := os.MkdirAll(dir+"/events", 0o755); err != nil {
t.Fatal(err)
}
if err := os.Symlink("missing", dir+"/events/missing.jsonl.zst"); err != nil {
t.Fatal(err)
}
if _, err := ReadAll(dir); err == nil {
t.Fatal("broken symlink accepted")
}
if err := os.Remove(dir + "/events/missing.jsonl.zst"); err != nil {
t.Fatal(err)
}
writeZstd(t, dir+"/events/bad-json.jsonl.zst", []byte("{\n"))
if _, err := ReadAll(dir); err == nil {
t.Fatal("bad JSON accepted")
}
if err := os.Remove(dir + "/events/bad-json.jsonl.zst"); err != nil {
t.Fatal(err)
}
writeZstd(t, dir+"/events/huge.jsonl.zst", []byte(strings.Repeat("x", 70*1024)))
if _, err := ReadAll(dir); err == nil {
t.Fatal("huge scanner token accepted")
}
}
func writeZstd(t *testing.T, path string, data []byte) {
t.Helper()
file, err := os.Create(path)
if err != nil {
t.Fatal(err)
}
encoder, err := zstd.NewWriter(file)
if err != nil {
t.Fatal(err)
}
if _, err := encoder.Write(data); err != nil {
t.Fatal(err)
}
if err := encoder.Close(); err != nil {
t.Fatal(err)
}
if err := file.Close(); err != nil {
t.Fatal(err)
}
}
func TestAppendRejectsBadDataDir(t *testing.T) {
root := t.TempDir()
bad := root + "/file"
if err := os.WriteFile(bad, []byte("x"), 0o644); err != nil {
t.Fatal(err)
}
_, err := Store{DataDir: bad, Now: func() time.Time { return time.Date(2026, 6, 18, 1, 2, 3, 0, time.UTC) }}.Append(Event{RunID: "run"})
if err == nil {
t.Fatal("append under file path accepted")
}
}
func TestAppendRejectsExistingDirectoryLogPath(t *testing.T) {
store := Store{DataDir: t.TempDir(), Now: func() time.Time { return time.Date(2026, 6, 18, 1, 2, 3, 0, time.UTC) }}
if err := os.MkdirAll(store.DataDir+"/events/2026-06.jsonl.zst", 0o755); err != nil {
t.Fatal(err)
}
if _, err := store.Append(Event{RunID: "run"}); err == nil {
t.Fatal("append accepted directory log path")
}
}
func TestReadAllInjectedReaderFailure(t *testing.T) {
dir := t.TempDir()
if err := os.MkdirAll(dir+"/events", 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(dir+"/events/x.jsonl.zst", []byte("x"), 0o644); err != nil {
t.Fatal(err)
}
old := newReader
newReader = func(io.Reader) (zstdReader, error) { return nil, errors.New("reader boom") }
defer func() { newReader = old }()
if _, err := ReadAll(dir); err == nil {
t.Fatal("reader failure hidden")
}
}
func TestAppendInjectedFailures(t *testing.T) {
store := Store{DataDir: t.TempDir(), Now: func() time.Time { return time.Date(2026, 6, 18, 1, 2, 3, 0, time.UTC) }}
boom := errors.New("boom")
oldWriter := newWriter
newWriter = func(io.Writer) (zstdWriter, error) { return nil, boom }
if _, err := store.Append(Event{RunID: "run"}); !errors.Is(err, boom) {
t.Fatalf("writer err = %v", err)
}
newWriter = oldWriter
oldMarshal := marshal
marshal = func(any) ([]byte, error) { return nil, boom }
if _, err := store.Append(Event{RunID: "run"}); !errors.Is(err, boom) {
t.Fatalf("marshal err = %v", err)
}
marshal = oldMarshal
oldWriter = newWriter
newWriter = func(io.Writer) (zstdWriter, error) { return failWriter{writeErr: boom}, nil }
if _, err := store.Append(Event{RunID: "run"}); !errors.Is(err, boom) {
t.Fatalf("write err = %v", err)
}
newWriter = oldWriter
newWriter = func(io.Writer) (zstdWriter, error) { return failWriter{closeErr: boom}, nil }
if _, err := store.Append(Event{RunID: "run"}); !errors.Is(err, boom) {
t.Fatalf("close err = %v", err)
}
newWriter = oldWriter
oldOpen := openAppend
openAppend = func(string) (appendFile, error) { return failFile{closeErr: boom}, nil }
if _, err := store.Append(Event{RunID: "run"}); !errors.Is(err, boom) {
t.Fatalf("file close err = %v", err)
}
openAppend = oldOpen
}
type failWriter struct{ writeErr, closeErr error }
func (w failWriter) Write([]byte) (int, error) { return 0, w.writeErr }
func (w failWriter) Close() error { return w.closeErr }
type failFile struct{ closeErr error }
type partialFile struct {
*os.File
err error
}
func (f partialFile) Write(p []byte) (int, error) {
if len(p) == 0 {
return 0, f.err
}
n, _ := f.File.Write(p[:max(1, len(p)/2)])
return n, f.err
}
func (f failFile) Write(p []byte) (int, error) { return len(p), nil }
func (f failFile) Close() error { return f.closeErr }
func TestFailedAppendLeavesPreviousHistoryReadable(t *testing.T) {
store := Store{DataDir: t.TempDir(), Now: func() time.Time { return time.Date(2026, 6, 18, 1, 2, 3, 0, time.UTC) }}
if _, err := store.Append(Event{RunID: "first", ChildID: "run", Repo: "repo", Job: "check", Status: "success"}); err != nil {
t.Fatal(err)
}
boom := errors.New("disk full")
oldOpen := openAppend
t.Cleanup(func() { openAppend = oldOpen })
openAppend = func(path string) (appendFile, error) {
file, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o644)
if err != nil {
return nil, err
}
return partialFile{File: file, err: boom}, nil
}
if _, err := store.Append(Event{RunID: "second", ChildID: "run", Repo: "repo", Job: "check", Status: "failed"}); !errors.Is(err, boom) {
t.Fatalf("append err=%v", err)
}
openAppend = oldOpen
events, err := ReadAll(store.DataDir)
if err != nil || len(events) != 1 || events[0].RunID != "first" {
t.Fatalf("events=%#v err=%v", events, err)
}
}
func TestAppendAndReadAllCompressedJSONL(t *testing.T) {
store := Store{DataDir: t.TempDir(), Now: func() time.Time { return time.Date(2026, 6, 18, 1, 2, 3, 0, time.UTC) }}
path, err := store.Append(Event{RunID: "run1", Repo: "repo", Job: "check", Rev: "abc", Status: "success"})
if err != nil {
t.Fatalf("Append() error = %v", err)
}
if _, err := store.Append(Event{RunID: "run2", Repo: "repo", Job: "test", Rev: "def", Status: "failed"}); err != nil {
t.Fatalf("Append() second error = %v", err)
}
file, err := os.Open(path)
if err != nil {
t.Fatal(err)
}
decoder, err := zstd.NewReader(file)
if err != nil {
t.Fatal(err)
}
data, err := io.ReadAll(decoder)
decoder.Close()
file.Close()
if err != nil {
t.Fatal(err)
}
text := string(data)
if !strings.Contains(text, `"run_id":"run1"`) || !strings.Contains(text, `"status":"success"`) || !strings.HasSuffix(text, "\n") {
t.Fatalf("jsonl = %q", text)
}
events, err := ReadAll(store.DataDir)
if err != nil {
t.Fatalf("ReadAll() error = %v", err)
}
if len(events) != 2 || events[0].RunID != "run1" || events[1].RunID != "run2" {
t.Fatalf("events = %#v", events)
}
}
func TestAppendOnceUsesRunAndChildIdentity(t *testing.T) {
now := time.Date(2026, 8, 5, 1, 2, 3, 4, time.UTC)
store := Store{DataDir: t.TempDir(), Now: func() time.Time { return now }}
event := Event{RunID: "42", ChildID: "run", Repo: "smith", Job: "push", Rev: "abc", Ref: "refs/heads/trunk", Trigger: "push", Status: "success", StartedAt: now.Add(-time.Second)}
appended, err := store.AppendOnce(event)
if err != nil || !appended {
t.Fatalf("first append=%v err=%v", appended, err)
}
appended, err = store.AppendOnce(event)
if err != nil || appended {
t.Fatalf("second append=%v err=%v", appended, err)
}
events, err := ReadAll(store.DataDir)
if err != nil || len(events) != 1 || events[0].ChildID != "run" || events[0].Ref != "refs/heads/trunk" || events[0].Trigger != "push" || !events[0].StartedAt.Equal(now.Add(-time.Second)) {
t.Fatalf("events=%#v err=%v", events, err)
}
found, err := store.Contains("42", "run")
if err != nil || !found {
t.Fatalf("found=%v err=%v", found, err)
}
found, err = store.Contains("42", "001")
if err != nil || found {
t.Fatalf("absent=%v err=%v", found, err)
}
}
func TestLegacyEventRemainsReadable(t *testing.T) {
dir := t.TempDir()
if err := os.MkdirAll(dir+"/events", 0o755); err != nil {
t.Fatal(err)
}
writeZstd(t, dir+"/events/legacy.jsonl.zst", []byte(`{"run_id":"old","repo":"repo","job":"check","rev":"abc","status":"success","time":"2026-08-05T00:00:00Z"}`+"\n"))
events, err := ReadAll(dir)
if err != nil || len(events) != 1 {
t.Fatalf("events=%#v err=%v", events, err)
}
got := events[0]
if got.ChildID != "" || got.Ref != "" || got.Trigger != "" || !got.StartedAt.IsZero() {
t.Fatalf("legacy fields=%#v", got)
}
}
func TestReadAllRejectsEventsFile(t *testing.T) {
dir := t.TempDir()
if err := os.WriteFile(dir+"/events", []byte("x"), 0o644); err != nil {
t.Fatal(err)
}
if _, err := ReadAll(dir); err == nil {
t.Fatal("events file accepted as empty history")
}
}