Unify trunk on main: initialization → main #3
@@ -1298,3 +1298,65 @@ func TestAContainerGivenNoNamesIsRunAsBefore(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Defends the ordering half of novox/hq work breakdown 1.3: resources are applied in the order
|
||||||
|
// the module declared them.
|
||||||
|
//
|
||||||
|
// **Already true, and untested until now** — the apply loop walks `d.Resources` and sorts nothing,
|
||||||
|
// so a module that needs one thing before another says so by writing it first. Worth an assertion
|
||||||
|
// because it is the kind of property a later change would break silently: sorting the resources
|
||||||
|
// for any good reason at all — by type, by identity, for a tidier report — would still pass every
|
||||||
|
// other test in this package.
|
||||||
|
//
|
||||||
|
// It is sequence, not readiness. A container started is not a container ready, and nothing here
|
||||||
|
// waits: what depends on something being *usable* retries, which is what both example
|
||||||
|
// provisioners do and is more robust than start ordering, because a dependency can also restart
|
||||||
|
// long after everything was applied.
|
||||||
|
func TestResourcesAreAppliedInTheOrderTheyWereDeclared(t *testing.T) {
|
||||||
|
dir := t.TempDir()
|
||||||
|
var order []string
|
||||||
|
done := map[string]bool{}
|
||||||
|
run := func(_ context.Context, name string, args ...string) (string, error) {
|
||||||
|
order = append(order, name+" "+strings.Join(args, " "))
|
||||||
|
// `verify` is the idempotency check, so it has to fail before the step and pass after —
|
||||||
|
// a stub that always succeeds means every action is already done and nothing ever runs,
|
||||||
|
// which is what the first version of this test measured.
|
||||||
|
if name == "check" {
|
||||||
|
if !done[args[0]] {
|
||||||
|
return "", fmt.Errorf("not yet")
|
||||||
|
}
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
done[args[0]] = true
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = dir
|
||||||
|
// Trusted, because the link may not carry an action and only a bundle may (novox/hq ADR 0005).
|
||||||
|
// Actions are used here because they are the one shape whose execution is observable through
|
||||||
|
// the runner, which is what makes the order visible at all.
|
||||||
|
d, err := declaration.ParseTrusted([]byte(`{"declaration":1,"resources":[` +
|
||||||
|
`{"id":"first","type":"action","command":["step","one"],"verify":["check","one"]},` +
|
||||||
|
`{"id":"second","type":"action","command":["step","two"],"verify":["check","two"]},` +
|
||||||
|
`{"id":"third","type":"action","command":["step","three"],"verify":["check","three"]}]}`))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, _, err := Apply(context.Background(), archHost(t), d, store.State{},
|
||||||
|
store.OriginCarried, run, nil, nil); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var ran []string
|
||||||
|
for _, line := range order {
|
||||||
|
if strings.HasPrefix(line, "step ") {
|
||||||
|
ran = append(ran, strings.TrimPrefix(line, "step "))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
want := []string{"one", "two", "three"}
|
||||||
|
if strings.Join(ran, ",") != strings.Join(want, ",") {
|
||||||
|
t.Fatalf("declared one, two, three and ran %v — a module that needs one thing before "+
|
||||||
|
"another has no way to say so", ran)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user