package console import ( "encoding/json" "os" "reflect" "strings" "testing" ) // The tool runner's manifest names no events to wait on (novox/hq ADR 0670 §2): a session waits on any event by its // name. It holds each change of design 34 every-event §11 (E-1): no `waits`, `operator-channel` in `uses` for the asks of // marked waits, the per-machine state `approvals` in the old `state` section with its 48 hours and none in `requires` // (design 46 7-approval-mark §13), and the finding stream (design 47 G §387). func TestTheManifestNamesNoWaitsAndKeepsItsApprovals(t *testing.T) { raw, err := os.ReadFile("../../module.json") if err != nil { t.Fatal(err) } var keys map[string]json.RawMessage if err := json.Unmarshal(raw, &keys); err != nil { t.Fatal(err) } if _, ok := keys["waits"]; ok { t.Error("the manifest still carries waits (novox/hq ADR 0670 §2)") } var m struct { Module string `json:"module"` Uses []string `json:"uses"` State []json.RawMessage `json:"state"` Requires []json.RawMessage `json:"requires"` Consumes []string `json:"consumes"` Streams []struct { Name string `json:"name"` Events []string `json:"events"` } `json:"streams"` } if err := json.Unmarshal(raw, &m); err != nil { t.Fatal(err) } if m.Module != "node-tools" || !reflect.DeepEqual(m.Uses, []string{"operator-channel"}) { t.Errorf("%s uses %v, want operator-channel (design 46 7-approval-mark §7)", m.Module, m.Uses) } type state struct { Name string `json:"name"` PerMachine bool `json:"per-machine"` TTLSeconds int `json:"ttl-seconds"` } var approvals []state for _, r := range m.State { var s state if json.Unmarshal(r, &s) == nil && s.Name == "approvals" { approvals = append(approvals, s) } } if want := []state{{Name: "approvals", PerMachine: true, TTLSeconds: 172800}}; !reflect.DeepEqual(approvals, want) { t.Errorf("the old state section's approvals is %+v, want %+v (design 46 7-approval-mark §13)", approvals, want) } for _, r := range m.Requires { if strings.Contains(string(r), `"approvals"`) { t.Errorf("approvals is asked in requires too: %s", r) } } if len(m.Streams) != 1 || m.Streams[0].Name != "node-tools-findings" || !reflect.DeepEqual(m.Streams[0].Events, []string{"finding-written.*", "finding-cleared.*", "findings-stated.*"}) { t.Errorf("the finding stream is %+v, want node-tools-findings with the three finding events (design 47 G §387)", m.Streams) } // A wait is no consumer (ADR 0367 §2): what it consumes is the assigner's two views families (ADR 0615 §5, issue 1966 // TLS-5), the events of the catalog half's branch follower (design 47 G §196, §614: `catalog-revision`, // `registration-changed`, and the gate's `source-moved`; never the indexer's `views.modules` or `views.manifests`), the two // events of the seat that serves the seat list (ADR 0636 §4) and the keeper's `findings-asked`, and nothing else. wantConsumes := []string{"mesh-catalog.catalog-revision", "mesh-catalog.registration-changed", "mesh-catalog.seat-definition-changed", "mesh-catalog.seat-definition-removed", "mesh-conditions.findings-asked", "mesh-delivery-assigner.views.assignments", "mesh-delivery-assigner.views.seat-holders", "mesh-delivery.source-moved"} if !reflect.DeepEqual(m.Consumes, wantConsumes) { t.Errorf("the tool runner consumes %v, want %v", m.Consumes, wantConsumes) } } // issue 1966 TLS-1: the tool runner declares its own secret `ledgers`, each module's ledger credential, in the directory it // keeps its broker credential in, which is where the runner reads it (runtime.LedgersFileOf). func TestTheManifestDeclaresTheRunnersOwnSecretLedgers(t *testing.T) { raw, err := os.ReadFile("../../module.json") if err != nil { t.Fatal(err) } var m struct { OwnSecrets map[string]string `json:"own-secrets"` } if err := json.Unmarshal(raw, &m); err != nil { t.Fatal(err) } want := map[string]string{"broker": "${dir:mesh-state}/broker", "ledgers": "${dir:mesh-state}/ledgers"} if !reflect.DeepEqual(m.OwnSecrets, want) { t.Errorf("own secrets %v, want %v", m.OwnSecrets, want) } }