What runs is the agent's compositions plus the kept declaration's rest: health, filling, take act, directories and the others held out of an apply read it; a restart trusts the node-engine's own haves; the bed tests run off Arch (review round 1)
This commit is contained in:
@@ -110,15 +110,17 @@ type bed struct {
|
||||
failWith string
|
||||
backup func(module string) Backup
|
||||
kept map[string][]json.RawMessage
|
||||
others [][]delivery.Composed
|
||||
env Env
|
||||
}
|
||||
|
||||
func newBed(t *testing.T) *bed {
|
||||
b := &bed{t: t, wants: newFeed(), comps: newFeed(), haves: &haves{}}
|
||||
b.env = Env{Node: node, Wants: b.wants, Composed: b.comps, Haves: b.haves,
|
||||
Apply: func(_ context.Context, c delivery.Composed, _ []delivery.Composed) Result {
|
||||
Apply: func(_ context.Context, c delivery.Composed, others []delivery.Composed) Result {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
b.others = append(b.others, others)
|
||||
name := c.Module
|
||||
if name == "" {
|
||||
name = NodeModule
|
||||
@@ -144,10 +146,7 @@ func newBed(t *testing.T) *bed {
|
||||
}
|
||||
return Backup{Done: true}
|
||||
},
|
||||
Kept: func(m string) ([]json.RawMessage, bool) {
|
||||
r, ok := b.kept[m]
|
||||
return r, ok
|
||||
},
|
||||
Kept: func() map[string][]json.RawMessage { return b.kept },
|
||||
Trusted: func() []ed25519.PublicKey { return []ed25519.PublicKey{controllerPub, operatorPub} },
|
||||
Say: func(s string) { t.Log(s) },
|
||||
}
|
||||
@@ -556,3 +555,88 @@ func TestWithNoTrustedKeyNothingIsApplied(t *testing.T) {
|
||||
t.Fatalf("applied with no trusted key: %v", got)
|
||||
}
|
||||
}
|
||||
|
||||
// What a module's apply must not take is every other module that runs, those the agent holds and those still running from
|
||||
// the kept declaration (ADR 0429 §4): the resources of the kept declaration reach Apply as the others.
|
||||
func TestApplyingOneModuleHoldsOutTheModulesStillRunningFromTheKeptDeclaration(t *testing.T) {
|
||||
b := newBed(t)
|
||||
b.kept = map[string][]json.RawMessage{"db": {file("db", "x", "1")}, NodeModule: {file("node", "n", "n")}}
|
||||
stop := b.run()
|
||||
defer stop()
|
||||
fp := fpOf("a")
|
||||
ck, craw, dig := composition(t, "web", fp, false, file("web", "x", "1"))
|
||||
b.comps.put(ck, craw)
|
||||
wk, wraw := wantFor(t, "web", fp, dig, "")
|
||||
b.wants.put(wk, wraw)
|
||||
eventually(t, "not applied", func() bool { return len(b.appliedList()) == 1 })
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
var names []string
|
||||
for _, c := range b.others[0] {
|
||||
names = append(names, c.Module)
|
||||
}
|
||||
if len(names) != 2 || !strings.Contains(strings.Join(names, ","), "db") {
|
||||
t.Fatalf("the others of web were %v: db and the node's own run from the kept declaration", names)
|
||||
}
|
||||
}
|
||||
|
||||
// Everything is what runs: the agent's compositions and the kept resources of each module it does not hold.
|
||||
func TestEverythingIsWhatTheAgentRunsAndWhatIsKeptForTheRest(t *testing.T) {
|
||||
b := newBed(t)
|
||||
b.kept = map[string][]json.RawMessage{"db": {file("db", "x", "1")}, "web": {file("web", "x", "old")}}
|
||||
a := New(b.env)
|
||||
if got := a.Everything(); len(got) != 2 {
|
||||
t.Fatalf("before the agent holds anything: %d compositions, want the 2 kept", len(got))
|
||||
}
|
||||
a.running["web"] = delivery.Have{FP: fpOf("a"), Composed: "sha256:" + strings.Repeat("1", 64), Phase: delivery.PhaseRunning}
|
||||
ck, craw, dig := composition(t, "web", fpOf("a"), false, file("web", "x", "new"))
|
||||
a.running["web"] = delivery.Have{FP: fpOf("a"), Composed: dig, Phase: delivery.PhaseRunning}
|
||||
a.takeComposition(Update{Key: ck, Value: craw, Revision: 1})
|
||||
got := a.Everything()
|
||||
if len(got) != 2 {
|
||||
t.Fatalf("%d compositions", len(got))
|
||||
}
|
||||
for _, c := range got {
|
||||
if c.Module == "web" && !strings.Contains(string(c.Resources[0]), "new") {
|
||||
t.Fatal("web is the kept declaration's, not the composition the agent runs")
|
||||
}
|
||||
}
|
||||
if a.HoldsNode() {
|
||||
t.Fatal("the agent holds no node composition")
|
||||
}
|
||||
}
|
||||
|
||||
// A failed apply is applied again after a restart even when the kept declaration holds the composition: once this
|
||||
// node-engine wrote its haves, they are what it knows (the kept declaration is only for the first start after the switch).
|
||||
func TestAFailedApplyIsAppliedAgainAfterARestartWhateverIsKept(t *testing.T) {
|
||||
b := newBed(t)
|
||||
fp := fpOf("a")
|
||||
ck, craw, dig := composition(t, "web", fp, false, file("web", "x", "1"))
|
||||
wk, wraw := wantFor(t, "web", fp, dig, "")
|
||||
b.comps.before(ck, craw)
|
||||
b.wants.before(wk, wraw)
|
||||
b.kept = map[string][]json.RawMessage{"web": {file("web", "x", "1")}}
|
||||
b.haves.stored = map[string]Have{"web": {Module: "web", FP: fp, Composed: dig, Phase: string(delivery.PhaseFailed)}}
|
||||
stop := b.run()
|
||||
defer stop()
|
||||
eventually(t, "a failed apply was marked running from the kept declaration", func() bool { return len(b.appliedList()) == 1 })
|
||||
}
|
||||
|
||||
// A have written before the switch carries no composition: then the kept declaration says what runs.
|
||||
func TestAHaveWithNoCompositionDefersToTheKeptDeclaration(t *testing.T) {
|
||||
b := newBed(t)
|
||||
fp := fpOf("a")
|
||||
ck, craw, dig := composition(t, "web", fp, false, file("web", "x", "1"))
|
||||
wk, wraw := wantFor(t, "web", fp, dig, "")
|
||||
b.comps.before(ck, craw)
|
||||
b.wants.before(wk, wraw)
|
||||
b.kept = map[string][]json.RawMessage{"web": {file("web", "x", "1")}}
|
||||
b.haves.stored = map[string]Have{"web": {Module: "web", Phase: "running"}}
|
||||
stop := b.run()
|
||||
defer stop()
|
||||
eventually(t, "the have was not written", func() bool { return b.haves.last("web").Composed == dig })
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
if got := b.appliedList(); len(got) != 0 {
|
||||
t.Fatalf("applied %v", got)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user