Download
61 lines 1.6 KiBGoModified 2026-10-18 raw
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
package queue

import (
	"os"
	"path/filepath"
	"strings"
	"testing"
)

// Run one with `make fuzz`; plain `go test` runs only the seeds.

// Whatever ends up in a queue file, parsing it yields only well-formed
// jobs and never fails: a bad file would wedge every kick after it.
func FuzzParse(f *testing.F) {
	for _, s := range []string{
		"", "\n", "r\trefs/heads/main\t0\t1\n", "r\tx\ty\n", "a\tb\tc\td\te\n", "r\tref\t0\t1\r\n", "r\tref\t0\t1",
	} {
		f.Add([]byte(s))
	}
	f.Fuzz(func(t *testing.T, data []byte) {
		p := filepath.Join(t.TempDir(), "queue")
		if err := os.WriteFile(p, data, 0o644); err != nil {
			t.Fatal(err)
		}
		jobs, err := parse(p)
		if err != nil {
			t.Fatal(err)
		}
		for _, j := range jobs {
			for _, field := range []string{j.Repo, j.Ref, j.Old, j.New} {
				if strings.ContainsAny(field, "\t\n") {
					t.Fatalf("job field %q from %q", field, data)
				}
			}
		}
	})
}

// A job Append writes comes back from Take as it went in.
func FuzzAppendTake(f *testing.F) {
	f.Add("repo", "refs/heads/main", "0000", "1111")
	f.Add("", "", "", "")
	f.Fuzz(func(t *testing.T, repo, ref, old, new string) {
		j := Job{repo, ref, old, new}
		for _, field := range []string{repo, ref, old, new} {
			// enqueue rejects these; repo names and object ids can hold
			// neither, and refs no tab or newline.
			if strings.ContainsAny(field, "\t\n\r") {
				return
			}
		}
		q := filepath.Join(t.TempDir(), "queue")
		if err := Append(q, j); err != nil {
			t.Fatal(err)
		}
		jobs, _, err := Take(q)
		if err != nil || len(jobs) != 1 || jobs[0] != j {
			t.Fatalf("appended %+v, took %+v (%v)", j, jobs, err)
		}
	})
}