Answer the verbs release 6 removed by name, and drop the merge window and push settings from the manifest (release 6, issue 1945 B10)
This commit is contained in:
@@ -360,6 +360,9 @@ func connectionName(command, verb string) string {
|
||||
// removedByName refuses a command the controller no longer has, naming what replaced it (novox/hq ADR 0501 §4, §5;
|
||||
// ADR 0429 §18; ADR 0503 §3; issue 1851, A11, and issue 1318).
|
||||
func removedByName(command string) error {
|
||||
if why, removed := removedInRelease6(command); removed {
|
||||
return &removedCommand{msg: fmt.Sprintf("`%s` no longer exists: %s", command, why)}
|
||||
}
|
||||
replacement := map[string]string{
|
||||
"build": "the controller asks no build (ADR 0501 §5): the builder builds every fingerprint the indexer writes, a " +
|
||||
"module is registered from its done key, and a branch is tried with `try`; a module from a repository the " +
|
||||
@@ -382,6 +385,8 @@ func removedByName(command string) error {
|
||||
"resume, or its capacity",
|
||||
"forget-checks": "build-agent makes no check build from R4e (ADR 0503 §3), so there is nothing to let go of",
|
||||
"delivery-plan": "a delivery's plan is read with `delivery-order` and the checker's verdict (ADR 0503 §3)",
|
||||
"durations": "the controller measures no sends, tiers or applies since release 6 (ADR 0539 §17): the haves and wants " +
|
||||
"on the bus carry what a delivery took",
|
||||
"delivery-check": "the checker judges every head and every delivery group (ADR 0503 §3, ADR 0527): the controller asks " +
|
||||
"nothing and says no verdict of a pull request",
|
||||
}[command]
|
||||
|
||||
@@ -58,6 +58,9 @@ func argvFor(verb string, args map[string]any) ([]string, error) {
|
||||
if removedVerbs[verb] {
|
||||
return nil, removedByName(verb)
|
||||
}
|
||||
if why, removed := removedInRelease6(verb); removed {
|
||||
return nil, &removedCommand{msg: fmt.Sprintf("`%s` no longer exists: %s", verb, why)}
|
||||
}
|
||||
a, err := readArguments(verb, args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -93,13 +96,15 @@ type verbArguments struct {
|
||||
}
|
||||
|
||||
// removedVerbs are the controller seat's verbs R4e removed, kept in its table with no input so a caller is answered
|
||||
// by name (ADR 0501 §5, ADR 0503 §3, ADR 0450 §8).
|
||||
// by name (ADR 0501 §5, ADR 0503 §3, ADR 0450 §8). The verbs release 6 removed are catalogue.RemovedControllerVerbs.
|
||||
var removedVerbs = map[string]bool{"build": true, "rebuild": true, "forget-checks": true, "delivery-plan": true,
|
||||
"delivery-check": true, "queue": true, "cancel": true, "clear": true, "kill": true, "replay": true, "pause": true, "resume": true,
|
||||
// Release 6 (ADR 0539 §5): a delivery is each machine following its wants, so the verbs that planned, started, stopped,
|
||||
// retried or closed one are gone.
|
||||
"plans": true, "plan": true, "push": true, "deliver": true, "delivery-stop": true, "delivery-backups-again": true,
|
||||
"delivery-walks": true, "delivery-order": true}
|
||||
"delivery-check": true, "queue": true, "cancel": true, "clear": true, "kill": true, "replay": true, "pause": true, "resume": true}
|
||||
|
||||
// removedInRelease6 says a verb is one release 6 removed (ADR 0539, ADR 0429 §8): refused by name, with its replacement.
|
||||
func removedInRelease6(verb string) (string, bool) {
|
||||
why, removed := catalogue.RemovedControllerVerbs[verb]
|
||||
return why, removed
|
||||
}
|
||||
|
||||
// controllerVerb is this binary's own definition of a verb: what it runs is what it declares, so the
|
||||
// arguments are checked against the table compiled beside argvFor, not a row a newer or older build
|
||||
@@ -1187,47 +1192,6 @@ var inProcess = map[string]bool{"tools": true, "calls": true, "doctor": true,
|
||||
// issue 1937).
|
||||
"held": true}
|
||||
|
||||
// pushFileVar names the file the controller's push settings are written to (module.json, `push-wait`).
|
||||
const pushFileVar = "MESH_PUSH_FILE"
|
||||
|
||||
// pushWait is how long a push to a named machine waits for its answer (novox/hq issue 629): the call's own
|
||||
// `wait` when given, else the controller's setting `push-wait`, else nothing. No length is written here: the
|
||||
// setting's default is the module's, and a setting that cannot be read waits for nothing, as a push did
|
||||
// before, and is said.
|
||||
func pushWait(given string) (time.Duration, error) {
|
||||
if strings.TrimSpace(given) != "" {
|
||||
d, ok := durationSetting(given)
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("push: wait %q is no duration: say it as \"90s\", \"2m\", or \"0\" to wait for nothing", given)
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
path := os.Getenv(pushFileVar)
|
||||
if path == "" {
|
||||
return 0, nil
|
||||
}
|
||||
raw, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "the push settings cannot be read (%v); a push waits for nothing\n", err)
|
||||
return 0, nil
|
||||
}
|
||||
var values map[string]any
|
||||
if err := json.Unmarshal(raw, &values); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "the push settings are not JSON (%v); a push waits for nothing\n", err)
|
||||
return 0, nil
|
||||
}
|
||||
v, has := values["push-wait"]
|
||||
if !has || v == "" {
|
||||
return 0, nil
|
||||
}
|
||||
d, ok := durationSetting(v)
|
||||
if !ok {
|
||||
fmt.Fprintf(os.Stderr, "the setting push-wait=%v is no duration; a push waits for nothing\n", v)
|
||||
return 0, nil
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// answersFirst is a command line whose caller is answered before it runs: a push, by its verb or
|
||||
// through `command`. A push sends the machine holding the bus first when its user list changed, the
|
||||
// broker reloads, and a reload forgets every answer the bus was about to permit — so an answer
|
||||
|
||||
@@ -3,8 +3,13 @@ package main
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
||||
)
|
||||
|
||||
// `builds` given a build's id no longer reads a log from the bus: the build seat is retired (ADR 0525 clause 7).
|
||||
@@ -226,3 +231,58 @@ func TestAQuotedValueRoundTrips(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// **A verb release 6 removed is refused by name, with what replaces it** (ADR 0539, ADR 0429 §8, issue 1945 B10): every
|
||||
// verb of catalogue.RemovedControllerVerbs is answered "no longer exists" naming itself and its replacement, whatever
|
||||
// arguments it is given, and the tool-call path and the terminal's command line give the same words.
|
||||
func TestTheVerbsReleaseSixRemovedAreRefusedByName(t *testing.T) {
|
||||
if len(catalogue.RemovedControllerVerbs) == 0 {
|
||||
t.Fatal("the SDK lists no removed controller verb")
|
||||
}
|
||||
for verb, why := range catalogue.RemovedControllerVerbs {
|
||||
argv, err := argvFor(verb, map[string]any{"node": "anchor", "why": "w"})
|
||||
if err == nil || len(argv) != 0 {
|
||||
t.Errorf("%s was composed into %v", verb, argv)
|
||||
continue
|
||||
}
|
||||
for _, want := range []string{"`" + verb + "`", "no longer exists", why} {
|
||||
if !strings.Contains(err.Error(), want) {
|
||||
t.Errorf("%s: the refusal %q lacks %q", verb, err, want)
|
||||
}
|
||||
}
|
||||
if cmd := removedByName(verb); cmd == nil || cmd.Error() != err.Error() {
|
||||
t.Errorf("%s: the terminal says %v, the tool says %v", verb, cmd, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The controller's size, printed against the 111,386 non-test lines its repository held before release 6 (acceptance test 20, ADR
|
||||
// 0539 §17): raw lines of every non-test Go file of the module, which the pull request reports.
|
||||
func TestTheControllersNonTestLinesArePrinted(t *testing.T) {
|
||||
const before = 111386
|
||||
total := 0
|
||||
err := filepath.WalkDir("../..", func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if d.IsDir() && (d.Name() == ".git" || d.Name() == "testdata") {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
if d.IsDir() || !strings.HasSuffix(path, ".go") || strings.HasSuffix(path, "_test.go") {
|
||||
return nil
|
||||
}
|
||||
raw, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
total += strings.Count(string(raw), "\n")
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Logf("non-test Go lines: %d against %d before release 6 (%+d)", total, before, total-before)
|
||||
if total >= before {
|
||||
t.Errorf("the controller holds %d non-test lines, no fewer than the %d it held before release 6", total, before)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-37
@@ -25,23 +25,6 @@
|
||||
},
|
||||
"secrets-owner": "mesh-controller",
|
||||
"prepares": true,
|
||||
"settings": {
|
||||
"merge-window": {
|
||||
"kind": "preference",
|
||||
"default": "90s",
|
||||
"why": "merges are collected while they keep coming, and a batch is planned once no merge came for this long (novox/hq ADR 0276)"
|
||||
},
|
||||
"merge-window-at-most": {
|
||||
"kind": "preference",
|
||||
"default": "10m",
|
||||
"why": "a busy period never holds a batch longer than this after its first merge (novox/hq ADR 0276)"
|
||||
},
|
||||
"push-wait": {
|
||||
"kind": "preference",
|
||||
"default": "2m",
|
||||
"why": "how long a push to a named machine waits for that machine's answer, so its call says how it went; a call's own wait overrides it, and 0 waits for nothing (novox/hq issue 629)"
|
||||
}
|
||||
},
|
||||
"tools": [
|
||||
"tools",
|
||||
"calls",
|
||||
@@ -124,23 +107,6 @@
|
||||
"place": "mesh",
|
||||
"owner": "mesh-controller"
|
||||
},
|
||||
{
|
||||
"id": "merge-window",
|
||||
"type": "file",
|
||||
"path": "${dir:mesh-state}/merge-window.json",
|
||||
"mode": "0600",
|
||||
"owner": "mesh-controller",
|
||||
"content": "{\n \"merge-window\": \"${setting:merge-window}\",\n \"merge-window-at-most\": \"${setting:merge-window-at-most}\"\n}\n"
|
||||
},
|
||||
{
|
||||
"id": "push",
|
||||
"trusted": false,
|
||||
"type": "file",
|
||||
"path": "${dir:mesh-state}/push.json",
|
||||
"mode": "0600",
|
||||
"owner": "mesh-controller",
|
||||
"content": "{\n \"push-wait\": \"${setting:push-wait}\"\n}\n"
|
||||
},
|
||||
{
|
||||
"id": "controller",
|
||||
"type": "process",
|
||||
@@ -164,9 +130,7 @@
|
||||
"MESH_BROKER_MANAGEMENT_PORT": "${seat:mesh-broker:15672}",
|
||||
"MESH_BROKER_ADDRESS_PORT": "${seat:mesh-broker:5671}",
|
||||
"MESH_BUS_NATS_FILE": "${dir:mesh-state}/bus",
|
||||
"MESH_CONTROLLER_VERSION": "${version}",
|
||||
"MESH_MERGE_WINDOW_FILE": "${dir:mesh-state}/merge-window.json",
|
||||
"MESH_PUSH_FILE": "${dir:mesh-state}/push.json"
|
||||
"MESH_CONTROLLER_VERSION": "${version}"
|
||||
},
|
||||
"replaces": [
|
||||
"server"
|
||||
|
||||
Reference in New Issue
Block a user