Ophestra Umiker
eae3034260
Fortify state store instances was specific to aids due to outdated design decisions carried over from the ego rewrite. That no longer makes sense in the current application, so the interface now enables a single store object to manage all transient state. Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
127 lines
2.7 KiB
Go
127 lines
2.7 KiB
Go
package state_test
|
|
|
|
import (
|
|
"math/rand/v2"
|
|
"reflect"
|
|
"slices"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.ophivana.moe/security/fortify/fst"
|
|
"git.ophivana.moe/security/fortify/internal/state"
|
|
)
|
|
|
|
func testStore(t *testing.T, s state.Store) {
|
|
t.Run("list empty store", func(t *testing.T) {
|
|
if aids, err := s.List(); err != nil {
|
|
t.Fatalf("List: error = %v", err)
|
|
} else if len(aids) != 0 {
|
|
t.Fatalf("List: aids = %#v", aids)
|
|
}
|
|
})
|
|
|
|
const (
|
|
insertEntryChecked = iota
|
|
insertEntryNoCheck
|
|
insertEntryOtherApp
|
|
|
|
tl
|
|
)
|
|
|
|
var tc [tl]state.State
|
|
for i := 0; i < tl; i++ {
|
|
makeState(t, &tc[i])
|
|
}
|
|
|
|
do := func(aid int, f func(c state.Cursor)) {
|
|
if ok, err := s.Do(aid, f); err != nil {
|
|
t.Fatalf("Do: ok = %v, error = %v", ok, err)
|
|
}
|
|
}
|
|
|
|
insert := func(i, aid int) {
|
|
do(aid, func(c state.Cursor) {
|
|
if err := c.Save(&tc[i]); err != nil {
|
|
t.Fatalf("Save(&tc[%v]): error = %v", i, err)
|
|
}
|
|
})
|
|
}
|
|
|
|
check := func(i, aid int) {
|
|
do(aid, func(c state.Cursor) {
|
|
if entries, err := c.Load(); err != nil {
|
|
t.Fatalf("Load: error = %v", err)
|
|
} else if got, ok := entries[tc[i].ID]; !ok {
|
|
t.Fatalf("Load: entry %s missing",
|
|
&tc[i].ID)
|
|
} else {
|
|
got.Time = tc[i].Time
|
|
if !reflect.DeepEqual(got, &tc[i]) {
|
|
t.Fatalf("Load: entry %s got %#v, want %#v",
|
|
&tc[i].ID, got, &tc[i])
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
t.Run("insert entry checked", func(t *testing.T) {
|
|
insert(insertEntryChecked, 0)
|
|
check(insertEntryChecked, 0)
|
|
})
|
|
|
|
t.Run("insert entry unchecked", func(t *testing.T) {
|
|
insert(insertEntryNoCheck, 0)
|
|
})
|
|
|
|
t.Run("insert entry different aid", func(t *testing.T) {
|
|
insert(insertEntryOtherApp, 1)
|
|
check(insertEntryOtherApp, 1)
|
|
})
|
|
|
|
t.Run("check previous insertion", func(t *testing.T) {
|
|
check(insertEntryNoCheck, 0)
|
|
})
|
|
|
|
t.Run("list aids", func(t *testing.T) {
|
|
if aids, err := s.List(); err != nil {
|
|
t.Fatalf("List: error = %v", err)
|
|
} else {
|
|
slices.Sort(aids)
|
|
want := []int{0, 1}
|
|
if slices.Compare(aids, want) != 0 {
|
|
t.Fatalf("List() = %#v, want %#v", aids, want)
|
|
}
|
|
}
|
|
})
|
|
|
|
t.Run("clear aid 1", func(t *testing.T) {
|
|
do(1, func(c state.Cursor) {
|
|
if err := c.Destroy(tc[insertEntryOtherApp].ID); err != nil {
|
|
t.Fatalf("Destroy: error = %v", err)
|
|
}
|
|
})
|
|
do(1, func(c state.Cursor) {
|
|
if l, err := c.Len(); err != nil {
|
|
t.Fatalf("Len: error = %v", err)
|
|
} else if l != 0 {
|
|
t.Fatalf("Len() = %d, want 0", l)
|
|
}
|
|
})
|
|
})
|
|
|
|
t.Run("close store", func(t *testing.T) {
|
|
if err := s.Close(); err != nil {
|
|
t.Fatalf("Close: error = %v", err)
|
|
}
|
|
})
|
|
}
|
|
|
|
func makeState(t *testing.T, s *state.State) {
|
|
if err := fst.NewAppID(&s.ID); err != nil {
|
|
t.Fatalf("cannot create dummy state: %v", err)
|
|
}
|
|
s.Config = fst.Template()
|
|
s.PID = rand.Int()
|
|
s.Time = time.Now()
|
|
}
|