A node that reports file-references gets the digest and size of each file over 64 KiB that may travel so, and the content is put in the bucket declaration-files before the declaration is sent; others get every content inline. The controller alone writes the bucket and node-engines read an object by name (the four grants the node-engine's own fetch makes, no list, no write). An object goes a day after no node's latest declaration names it. The near-limit condition warns at 75 percent, and a test holds the control node's declaration, in the reference form, under half the bus's largest message.
72 lines
2.9 KiB
Go
72 lines
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/novox/mesh-controller/internal/conditions"
|
|
)
|
|
|
|
// The vault's export is sent compact (issue 1689): same document, no indentation, one rewrite.
|
|
func TestTheVaultsExportIsSentCompactAndNothingElseIsTouched(t *testing.T) {
|
|
indented := "{\n \"export\": 1,\n \"kept\": [\n {\n \"name\": \"a\"\n }\n ]\n}\n"
|
|
other := "{\n \"x\": 1\n}\n"
|
|
in := []map[string]any{
|
|
{"id": "mesh-vault.kept", "type": "file", "path": "/srv/vault/export.json", "mode": "0600", "content": indented},
|
|
{"id": "mesh-vault.config", "type": "file", "path": "/srv/vault/config.json", "content": other},
|
|
{"id": "other.kept", "type": "file", "path": "/srv/other/notes.json", "content": other},
|
|
}
|
|
out := compactKept(in)
|
|
want := "{\"export\":1,\"kept\":[{\"name\":\"a\"}]}\n"
|
|
if out[0]["content"] != want || out[0]["mode"] != "0600" || out[0]["path"] != "/srv/vault/export.json" {
|
|
t.Fatalf("the export is %q (%v), expected %q with its mode and path kept", out[0]["content"], out[0], want)
|
|
}
|
|
if out[1]["content"] != other || out[2]["content"] != other {
|
|
t.Fatalf("a file that is not the export was rewritten: %v %v", out[1], out[2])
|
|
}
|
|
if in[0]["content"] != indented {
|
|
t.Fatalf("the composed resource was changed in place")
|
|
}
|
|
if again := compactKept(out); again[0]["content"] != want {
|
|
t.Fatalf("compacting twice changed it: %q", again[0]["content"])
|
|
}
|
|
}
|
|
|
|
// From 75% of the bus's largest message (ADR 0486 §8, issue 1698) the declaration is a warning; over it, urgent; back under 75%, cleared.
|
|
func TestADeclarationNearTheBusLimitRaisesAConditionAndClearsWhenSmaller(t *testing.T) {
|
|
store := conditions.NewInMemory()
|
|
k := conditions.NewKeeper(t.Context(), conditions.Options{Store: store, History: store,
|
|
Teller: &conditions.Told{}, Now: func() time.Time { return time.Date(2026, 10, 21, 14, 0, 0, 0, time.UTC) }})
|
|
t.Cleanup(func() { k.Close(t.Context()) })
|
|
const limit = 1000
|
|
key := declarationRoomObservation("novox", 0, limit).Key()
|
|
read := func() (conditions.Condition, bool) {
|
|
t.Helper()
|
|
c, found, err := conditions.ReadOne(t.Context(), store, key)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return c, found
|
|
}
|
|
|
|
settleDeclarationRoom(t.Context(), k, "novox", 749, limit)
|
|
if _, found := read(); found {
|
|
t.Fatal("a declaration at 74.9% raised a condition")
|
|
}
|
|
settleDeclarationRoom(t.Context(), k, "novox", 750, limit)
|
|
c, found := read()
|
|
if !found || c.Severity != conditions.Warning || !strings.Contains(c.Summary, "750 bytes") ||
|
|
!strings.Contains(c.Summary, "1000") || c.Subject.Machine != "novox" {
|
|
t.Fatalf("at 75%% the condition is %v %+v", found, c)
|
|
}
|
|
settleDeclarationRoom(t.Context(), k, "novox", 1001, limit)
|
|
if c, _ := read(); c.Severity != conditions.Urgent {
|
|
t.Fatalf("over the limit the condition is %q, expected urgent", c.Severity)
|
|
}
|
|
settleDeclarationRoom(t.Context(), k, "novox", 700, limit)
|
|
if _, found := read(); found {
|
|
t.Fatal("the condition stayed after the declaration fell under 75%")
|
|
}
|
|
}
|