Testing
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
package audit
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TestNopRecorder covers the disabled-auditing no-op implementation.
|
||||
func TestNopRecorder(t *testing.T) {
|
||||
rec := Nop()
|
||||
rec.Record(Event{Action: "x"}) // must not panic
|
||||
got, err := rec.Query(Filter{})
|
||||
if err != nil {
|
||||
t.Fatalf("Nop Query: %v", err)
|
||||
}
|
||||
if len(got) != 0 {
|
||||
t.Errorf("Nop Query returned %d events, want 0", len(got))
|
||||
}
|
||||
if err := rec.Close(); err != nil {
|
||||
t.Errorf("Nop Close: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestQueryFilters covers the End, DS, and Signal (LIKE) filter branches plus
|
||||
// the default-outcome and zero-time stamping in Record.
|
||||
func TestQueryFilters(t *testing.T) {
|
||||
path := filepath.Join(t.TempDir(), "audit.db")
|
||||
rec, err := NewSQLite(path, slog.Default())
|
||||
if err != nil {
|
||||
t.Fatal("NewSQLite:", err)
|
||||
}
|
||||
defer rec.Close()
|
||||
|
||||
// Anchor base in the past so the zero-Time 'c' record (stamped with now)
|
||||
// sorts after a/b and stays out of the End window below.
|
||||
base := time.Now().Add(-time.Hour)
|
||||
rec.Record(Event{Time: base, Actor: "a", ActorType: ActorUser, Action: "signal.write", DS: "epics", Signal: "PV:TEMP"})
|
||||
rec.Record(Event{Time: base.Add(time.Second), Actor: "b", ActorType: ActorUser, Action: "signal.write", DS: "synthetic", Signal: "PV:FLOW"})
|
||||
// Zero Time and empty Outcome exercise the defaulting branches in Record.
|
||||
rec.Record(Event{Actor: "c", ActorType: ActorUser, Action: "interface.update"})
|
||||
|
||||
if err := rec.Close(); err != nil {
|
||||
t.Fatal("Close:", err)
|
||||
}
|
||||
rec, err = NewSQLite(path, slog.Default())
|
||||
if err != nil {
|
||||
t.Fatal("reopen:", err)
|
||||
}
|
||||
defer rec.Close()
|
||||
|
||||
// End filter: only events at or before base.
|
||||
upTo, err := rec.Query(Filter{End: base.Add(500 * time.Millisecond)})
|
||||
if err != nil {
|
||||
t.Fatal("Query end:", err)
|
||||
}
|
||||
if len(upTo) != 1 || upTo[0].Actor != "a" {
|
||||
t.Errorf("end filter = %+v, want one 'a' event", upTo)
|
||||
}
|
||||
|
||||
// DS filter.
|
||||
byDS, err := rec.Query(Filter{DS: "synthetic"})
|
||||
if err != nil {
|
||||
t.Fatal("Query ds:", err)
|
||||
}
|
||||
if len(byDS) != 1 || byDS[0].Signal != "PV:FLOW" {
|
||||
t.Errorf("ds filter = %+v, want one PV:FLOW event", byDS)
|
||||
}
|
||||
|
||||
// Signal LIKE filter (substring match).
|
||||
bySignal, err := rec.Query(Filter{Signal: "TEMP"})
|
||||
if err != nil {
|
||||
t.Fatal("Query signal:", err)
|
||||
}
|
||||
if len(bySignal) != 1 || bySignal[0].DS != "epics" {
|
||||
t.Errorf("signal filter = %+v, want one epics event", bySignal)
|
||||
}
|
||||
|
||||
// The zero-time/empty-outcome record was persisted with a default outcome.
|
||||
def, err := rec.Query(Filter{Actor: "c"})
|
||||
if err != nil {
|
||||
t.Fatal("Query actor c:", err)
|
||||
}
|
||||
if len(def) != 1 || def[0].Outcome != OutcomeOK {
|
||||
t.Errorf("defaulted record = %+v, want one event with outcome ok", def)
|
||||
}
|
||||
if def[0].Time.IsZero() {
|
||||
t.Error("zero Time should have been stamped with now")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user