package mailhold import ( "bytes" "errors" "log" "os" "path/filepath" "strings" "testing" ) func TestHold_MarkerDecidesAndReleaseRemovesIt(t *testing.T) { dir := t.TempDir() buf := &bytes.Buffer{} h := New(dir, log.New(buf, "", 0)) if h.Held() { t.Fatal("no marker: must not hold") } if err := h.Check("kernel notice", "c1"); err != nil { t.Fatalf("no marker: Check = %v", err) } if err := os.WriteFile(filepath.Join(dir, FileName), nil, 0o644); err != nil { t.Fatal(err) } if err := h.Check("kernel notice", "c1"); !errors.Is(err, ErrHeld) { t.Fatalf("marker present: Check = %v, want ErrHeld", err) } if got := buf.String(); !strings.Contains(got, "[WARN] MAIL-HOLD: not sending kernel notice to c1") { t.Fatalf("held mail log line missing: %q", got) } if err := h.Release(); err != nil { t.Fatal(err) } if _, err := os.Stat(filepath.Join(dir, FileName)); !os.IsNotExist(err) { t.Fatalf("Release left the marker: %v", err) } if err := h.Release(); err != nil { t.Fatalf("a second Release must be a no-op, got %v", err) } } // Fail-closed: a marker state that cannot be read (here: the data dir is a FILE, so stat says ENOTDIR) holds mail. func TestHold_UnreadableStateHolds(t *testing.T) { f := filepath.Join(t.TempDir(), "not-a-dir") if err := os.WriteFile(f, nil, 0o644); err != nil { t.Fatal(err) } if !New(f, nil).Held() { t.Fatal("an unreadable marker state must count as HELD") } } func TestHold_NilNeverHolds(t *testing.T) { var h *Hold if h.Held() || h.Check("x", "y") != nil || h.Release() != nil { t.Fatal("a nil hold must never hold and never fail") } }