Removes streamHear, HandPoll, HandWait and the stream mark; keeps toolEmit. Builds: design 42 zfs-owns-zfs §24, §25, lead answers A-43, A-44
71 lines
2.5 KiB
Go
71 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// §23, §24, A-12, A-17, A-18: a hand act writes its key and starts the run's unit with {scope, unit}; the tool
|
|
// answers "started" at once and never "done" (A-43); a failed start
|
|
// leaves no key; pause writes `paused`, resume deletes it.
|
|
func TestAHandActWritesItsKeyStartsTheRunAndAnswersStartedAtOnce(t *testing.T) {
|
|
cases := []struct {
|
|
name, act, why string
|
|
callErr error
|
|
outcome string
|
|
err string
|
|
keyLeft bool
|
|
}{
|
|
{name: "snapshots", act: ActSnapshots, why: "before the move", outcome: "started", keyLeft: true},
|
|
{name: "prune", act: ActPrune, why: "free space", outcome: "started", keyLeft: true},
|
|
{name: "apply", act: ActApply, why: "now", outcome: "started", keyLeft: true},
|
|
{name: "start refused", act: ActSnapshots, why: "x", callErr: errors.New("refused"), err: "did not start"},
|
|
{name: "no why", act: ActSnapshots, why: "", err: "say why"},
|
|
{name: "unknown act", act: "destroy", why: "x", err: "not an act"},
|
|
}
|
|
for _, c := range cases {
|
|
f := newFake(t)
|
|
m := f.machine()
|
|
st := memStates{}
|
|
m.States, m.Node = st, "ace"
|
|
var key string
|
|
var body any
|
|
m.Call = func(k string, b any) (json.RawMessage, error) { key, body = k, b; return nil, c.callErr }
|
|
a, err := m.HandAct(context.Background(), c.act, "caller@node", c.why)
|
|
if c.err != "" {
|
|
if err == nil || !strings.Contains(err.Error(), c.err) {
|
|
t.Errorf("%s: %v", c.name, err)
|
|
}
|
|
} else if err != nil || a.Outcome != c.outcome {
|
|
t.Errorf("%s: %+v %v", c.name, a, err)
|
|
}
|
|
if _, left := st["schedule/"+c.act]; left != c.keyLeft {
|
|
t.Errorf("%s: key left %v, want %v", c.name, left, c.keyLeft)
|
|
}
|
|
if c.err == "" || c.callErr != nil {
|
|
args, _ := body.(map[string]any)
|
|
if key != "seat:node-service-manager.start@ace" || args["unit"] != "zfs-mesh-run.service" || args["scope"] != "system" || len(args) != 2 {
|
|
t.Errorf("%s: called %s with %v", c.name, key, body)
|
|
}
|
|
}
|
|
if c.outcome == "started" && !strings.Contains(a.Said, "zfs_module_events") {
|
|
t.Errorf("%s: did not say where the outcome is read: %s", c.name, a.Said)
|
|
}
|
|
if c.outcome == "started" && strings.Contains(a.Said, "done") {
|
|
t.Errorf("%s: said done for what it did not see: %s", c.name, a.Said)
|
|
}
|
|
}
|
|
f := newFake(t)
|
|
m := f.machine()
|
|
m.States = memStates{}
|
|
if err := m.Pause("p@n", "maintenance"); err != nil || !m.Paused() {
|
|
t.Fatal(err, m.Paused())
|
|
}
|
|
if err := m.Resume(); err != nil || m.Paused() {
|
|
t.Fatal(err, m.Paused())
|
|
}
|
|
}
|