A tool runner is no longer restarted by a build of the engine: owned paths name the directory of every build, and a restart names its cause (issue 1966)
The tool runner's unit carries the paths modules own, for the holder of node-files. The engine's own archive is unpacked into a place named for its build, so every engine replacement changed that word and restarted the tool runner with nothing of it changed (novox 21:16, 22:25, 22:38 on 2026-11-09). A resource unpacked into a place named for its build now owns the directory holding every build. The restart line now names the unit's directive, word and key that differ, never a value. Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
@@ -357,6 +357,51 @@ func TestAProcessAppliedAgainIsUnchangedAndNotRestarted(t *testing.T) {
|
||||
if o := outcomeOf(third, "node-tools.runtime"); o.Action != "unchanged" {
|
||||
t.Errorf("third apply: %+v, want unchanged", o)
|
||||
}
|
||||
// An input of its unit that differs restarts it, and the line says which (issue 1966).
|
||||
changed := declare(t, `{"id":"node-tools.runtime","type":"process","name":"node-tools","source":"`+serving(t, body)+
|
||||
`","digest":"`+digest+`","run":["node","main.js"],"env":{"MESH_TOOL_MODULES":"a=/x/index.js,b=/y/index.js"}}`)
|
||||
fourth, _, err := Apply(context.Background(), archHost(t), changed, state, store.OriginDeclared, run, nil, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if o := outcomeOf(fourth, "node-tools.runtime"); o.Action != "updated" || !strings.Contains(o.Detail, "its unit's Environment MESH_TOOL_MODULES (b)") {
|
||||
t.Errorf("fourth apply: %+v, want updated and the word and entry that changed named", o)
|
||||
}
|
||||
}
|
||||
|
||||
// A restart nobody asked for names its cause (issue 1966): the unit's own words that differ, the key inside a word that
|
||||
// is a JSON object and the entry of a list, never a value.
|
||||
func TestAProcessRestartedForAnInputSaysWhichInputChanged(t *testing.T) {
|
||||
for _, row := range []struct {
|
||||
name, was, now, says string
|
||||
}{
|
||||
{"a word of a module inside a JSON word", `{"files":{"OWNED":"/a"},"mail":{"X":"1"}}`, `{"files":{"OWNED":"/b"},"mail":{"X":"1"}}`,
|
||||
"Environment TOOL_ENV (files (OWNED))"},
|
||||
{"an entry of a list", "a=/x/1,b=/y/2", "a=/x/1,b=/y/3", "Environment TOOL_MODULES (b)"},
|
||||
{"nothing changed", "a=/x/1", "a=/x/1", ""},
|
||||
} {
|
||||
t.Run(row.name, func(t *testing.T) {
|
||||
word := "TOOL_MODULES"
|
||||
if strings.HasPrefix(row.was, "{") {
|
||||
word = "TOOL_ENV"
|
||||
}
|
||||
mk := func(v string) string {
|
||||
r := aProcess()
|
||||
r.Env = map[string]string{word: v, "SECRET": "never-said-" + v}
|
||||
return "sha256:" + strings.Repeat("a", 64) + " " + unitFor(r)
|
||||
}
|
||||
got := unitDifference(mk(row.was), mk(row.now))
|
||||
if row.says == "" {
|
||||
if got != "" {
|
||||
t.Fatalf("said %q for nothing changed", got)
|
||||
}
|
||||
return
|
||||
}
|
||||
if !strings.Contains(got, row.says) || strings.Contains(got, "never-said") || strings.Contains(got, "/b") {
|
||||
t.Fatalf("said %q, want it to name %q and no value", got, row.says)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// novox/hq ADR 0193: a bundle compiled to a binary runs itself — `./name` is that file in the
|
||||
|
||||
Reference in New Issue
Block a user