Once chain_moved records the kind, Assign, Unassign and Assigned write and read the keys <node>.<module>, and every join of the store that read assignments is made from the bucket: where a module runs, what is behind, what a machine awaits, a given value due for replacement, taking a module, and whether a module may be forgotten (refused while a standing assignment names it). An unassignment ends the key with a marker and keeps its earlier values, as it removed the row; no ended or pending mark is written yet. The generation rises with each change, and a seat held by an assignment goes with it: the foreign key from seat_holding is dropped by migration 0104 and the controller says both. The provisioner's plan is kept in the values by a pass of the tick that writes that one field by compare-and-set; the assignment-changed event is said from what the bucket holds, whoever wrote it. The start moves the rows with what each machine was last sent, keeping a plan the mirror put in a value.
38 lines
1.3 KiB
Go
38 lines
1.3 KiB
Go
package inventory
|
|
|
|
import (
|
|
"encoding/json"
|
|
"testing"
|
|
)
|
|
|
|
// **An assignment's key is `<node>.<module>`, as the bucket has always had it** (ADR 0408 §3): its readers parse nothing
|
|
// but it.
|
|
func TestAnAssignmentsKeyIsTheNodeAndTheModule(t *testing.T) {
|
|
if got := assignmentKey("anchor", "notes"); got != "anchor.notes" {
|
|
t.Fatalf("the key is %q", got)
|
|
}
|
|
if got := assignmentKey("g14.example", "dunst"); got != "g14.example.dunst" {
|
|
t.Fatalf("the key of a machine whose name holds a dot is %q", got)
|
|
}
|
|
}
|
|
|
|
// **A plan that is absent and a null one are one** (the provisioner's plan in an assignment's value): the pass that keeps
|
|
// the plans writes only where they differ.
|
|
func TestAnAbsentPlanAndANullOneAreTheSame(t *testing.T) {
|
|
for name, tc := range map[string]struct {
|
|
a, b json.RawMessage
|
|
same bool
|
|
}{
|
|
"both absent": {nil, nil, true},
|
|
"null and absent": {json.RawMessage(`null`), nil, true},
|
|
"the same plan": {json.RawMessage(`{"files":[]}`), json.RawMessage(` {"files":[]} `), true},
|
|
"another plan": {json.RawMessage(`{"files":[]}`), json.RawMessage(`{"files":[1]}`), false},
|
|
"a plan and none": {json.RawMessage(`{"files":[]}`), nil, false},
|
|
"none and a plan": {nil, json.RawMessage(`{"files":[]}`), false},
|
|
} {
|
|
if got := sameJSON(tc.a, tc.b); got != tc.same {
|
|
t.Errorf("%s: %v", name, got)
|
|
}
|
|
}
|
|
}
|