H5 engine-integration: the node-engine whole applies if-config, config-lines and a module's stop at a failure
The existing node-engine integration test's module gains a file under if-config, a template with config-lines from a list, and two files that fail and are left under a value; the test asserts the file appears and goes with its value, the lines follow the list, and the failing resource fails the module with the later resource left. No integration test is added. Builds: design 42 zfs-owns-zfs §5 (and §1 to §3), A-22
This commit is contained in:
@@ -425,8 +425,16 @@ func h8(t *testing.T, b *itBed, checkBuild bool) (func(), h8state) {
|
|||||||
candidates := kvOf(buckets.ProposalCandidates)
|
candidates := kvOf(buckets.ProposalCandidates)
|
||||||
packages := kvOf(link.PackagesBucket)
|
packages := kvOf(link.PackagesBucket)
|
||||||
path := filepath.Join(b.dir, "web.conf")
|
path := filepath.Join(b.dir, "web.conf")
|
||||||
man := `{"module":"web","version":"1","config":{"greeting":{"type":"string","description":"what the file says","default":"hello"}},` +
|
// Beside the greeting: a file under `if-config`, a template with `config-lines` from a list, and two files under a
|
||||||
|
// value that makes the first of them fail (a file below a file), the second being left (design 42 zfs-owns-zfs §5).
|
||||||
|
more := func(name string) string { return filepath.Join(b.dir, "web-"+name+".conf") }
|
||||||
|
man := `{"module":"web","version":"1","config":{"greeting":{"type":"string","description":"what the file says","default":"hello"},` +
|
||||||
|
`"mods":{"type":"list","description":"lines","default":["a","b"]}},` +
|
||||||
`"resources":[{"id":"conf","type":"file","path":"` + path + `","mode":"0644","content":"greeting=${config:greeting}\n"},` +
|
`"resources":[{"id":"conf","type":"file","path":"` + path + `","mode":"0644","content":"greeting=${config:greeting}\n"},` +
|
||||||
|
`{"id":"mods","type":"file","path":"` + more("mods") + `","mode":"0644","content":"${config-lines:mods:m=}\n"},` +
|
||||||
|
`{"id":"salut","type":"file","path":"` + more("salut") + `","mode":"0644","content":"salut\n","if-config":["greeting=salut"]},` +
|
||||||
|
`{"id":"bad","type":"file","path":"` + path + `/x","mode":"0644","content":"x\n","if-config":["greeting=boom"]},` +
|
||||||
|
`{"id":"after","type":"file","path":"` + more("after") + `","mode":"0644","content":"after\n","if-config":["greeting=boom"]},` +
|
||||||
`{"id":"tools","type":"package","package":"web-tools"}],` +
|
`{"id":"tools","type":"package","package":"web-tools"}],` +
|
||||||
`"build":{"artifacts":[{"name":"files","kind":"archive","from":"files"}]}}`
|
`"build":{"artifacts":[{"name":"files","kind":"archive","from":"files"}]}}`
|
||||||
digest := meshcatalogclient.ManifestDigest([]byte(man))
|
digest := meshcatalogclient.ManifestDigest([]byte(man))
|
||||||
@@ -538,6 +546,36 @@ func h8rest(t *testing.T, b *itBed, resolved, candidates nats.KeyValue, hkey str
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
within(t, 3*time.Second, "a changed config value was not composed and applied again", func() bool { return b.file("web") == "greeting=salut\n" })
|
within(t, 3*time.Second, "a changed config value was not composed and applied again", func() bool { return b.file("web") == "greeting=salut\n" })
|
||||||
|
// Design 42 zfs-owns-zfs §5: the file under `if-config` appears with its value and goes with it, the template's lines
|
||||||
|
// follow the list, and a failing resource stops its module's apply with the later resource left.
|
||||||
|
other := func(name string) string {
|
||||||
|
got, _ := os.ReadFile(filepath.Join(b.dir, "web-"+name+".conf"))
|
||||||
|
return string(got)
|
||||||
|
}
|
||||||
|
setGreeting := func(value string) {
|
||||||
|
if _, err := resolved.Put(itNode+".web.greeting", []byte(`{"value":"`+value+`","source":"module"}`)); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
within(t, 3*time.Second, "the file under if-config did not appear with its value, or the lines do not follow the list", func() bool {
|
||||||
|
return other("salut") == "salut\n" && other("mods") == "m=a\nm=b\n"
|
||||||
|
})
|
||||||
|
setGreeting("bonjour")
|
||||||
|
within(t, 3*time.Second, "the file under if-config did not go with its value", func() bool {
|
||||||
|
_, err := os.Stat(filepath.Join(b.dir, "web-salut.conf"))
|
||||||
|
return b.file("web") == "greeting=bonjour\n" && errors.Is(err, os.ErrNotExist)
|
||||||
|
})
|
||||||
|
setGreeting("boom")
|
||||||
|
within(t, 5*time.Second, "the failing resource did not fail its module", func() bool {
|
||||||
|
return b.have("web").Phase == nec.PhaseFailed
|
||||||
|
})
|
||||||
|
if got := other("after"); got != "" {
|
||||||
|
t.Errorf("a resource after the failed one was applied: %q", got)
|
||||||
|
}
|
||||||
|
setGreeting("salut")
|
||||||
|
within(t, 5*time.Second, "the module did not run again once its value held no failing resource", func() bool {
|
||||||
|
return b.file("web") == "greeting=salut\n" && b.have("web").Phase == nec.PhaseRunning
|
||||||
|
})
|
||||||
within(t, 2*time.Second, "the have does not name the revision", func() bool {
|
within(t, 2*time.Second, "the have does not name the revision", func() bool {
|
||||||
h := b.have("web")
|
h := b.have("web")
|
||||||
return h.Fp == fp && h.Composed != first && h.Phase == nec.PhaseRunning
|
return h.Fp == fp && h.Composed != first && h.Phase == nec.PhaseRunning
|
||||||
|
|||||||
Reference in New Issue
Block a user