Files
mesh-catalog/modules/zfs/cmd/zfs-tools/applied_test.go
T

78 lines
2.6 KiB
Go

package main
import (
"encoding/json"
"sort"
"strings"
"testing"
"time"
)
type memStates map[string]json.RawMessage
func (s memStates) Put(state, key string, v any) error {
b, _ := json.Marshal(v)
s[state+"/"+key] = b
return nil
}
func (s memStates) Delete(state, key string) error { delete(s, state+"/"+key); return nil }
func (s memStates) Keys(state string) ([]string, error) {
var out []string
for k := range s {
if rest, ok := strings.CutPrefix(k, state+"/"); ok {
out = append(out, rest)
}
}
sort.Strings(out)
return out, nil
}
func (s memStates) Get(state, key string) (json.RawMessage, bool, error) {
b, ok := s[state+"/"+key]
return b, ok, nil
}
// §25, §26: each change emits its event with before and after and keeps its key of the state `applied`, a
// refusal and a wait too, a wait keeping its first since, and a value back to not managed leaves the state.
func TestEachChangeIsSaidAndKeptAndANotManagedValueLeavesTheState(t *testing.T) {
f := newFake(t)
m := f.machine()
st := memStates{}
m.States = st
if err := m.Changed("pool", "pool-properties.autotrim", "off", "on", "on"); err != nil {
t.Fatal(err)
}
e := f.emitted[0]
if e["_type"] != "config.applied" || e["target"] != "pool" || e["key"] != "pool-properties.autotrim" ||
e["before"] != "off" || e["after"] != "on" || e["read-back"] != "on" {
t.Errorf("event: %v", e)
}
var got AppliedEntry
json.Unmarshal(st["applied/pool-properties.autotrim"], &got)
if got.Before != "off" || got.After != "on" || got.Outcome != OutcomeApplied || !got.At.Equal(f.now.UTC()) {
t.Errorf("state: %+v", got)
}
if err := m.Refused(Refusal{Key: "hostid", Value: "zzz", Reason: "is not eight hexadecimal digits"}); err != nil {
t.Fatal(err)
}
if f.emitted[1]["_type"] != "config.refused" || f.emitted[1]["reason"] == "" || !strings.Contains(string(st["applied/hostid"]), `"refused"`) {
t.Errorf("refusal: %v %s", f.emitted[1], st["applied/hostid"])
}
m.Waiting("log-devices", "the pool's scrub")
first := f.now
f.now = f.now.Add(time.Hour)
m.Waiting("log-devices", "the pool's scrub")
var w AppliedEntry
json.Unmarshal(st["applied/log-devices"], &w)
if f.emitted[3]["_type"] != "config.waiting" || !w.Since.Equal(first.UTC()) || !w.At.Equal(f.now.UTC()) || w.Outcome != OutcomeWaiting {
t.Errorf("wait: %v %+v", f.emitted[3], w)
}
m.NotManaged("log-devices")
if _, ok := st["applied/log-devices"]; ok {
t.Error("the key stays after the value went back to not managed")
}
m.Emit = nil
if err := m.Changed("pool", "k", "a", "b", "b"); err == nil {
t.Error("an event that cannot be said is said as done")
}
}