# Conflicts: # node-tools/internal/firstview/firstview_test.go # node-tools/internal/runtime/announce_test.go # node-tools/internal/runtime/busstate.go # node-tools/internal/runtime/ledgers_test.go
98 lines
4.1 KiB
Go
98 lines
4.1 KiB
Go
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", "seat:mesh-module-assigner.views.assignments",
|
|
"seat:mesh-module-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)
|
|
}
|
|
}
|