The node-engine owns the composition it alone runs (H1, H2)
ADR 0593 §1 and §7: compose, its bus reader and runtime reader, takein, validate, the overlay generator, the composer's run and mesh-compose, and the judgement of a move leave mesh-sdk for the node-engine's internal packages, so no other module composes and a change to them rebuilds only the node-engine. The shapes others read (the composer's request and verdict, the overlay's names, compositions and answers) stay in mesh-sdk. The node's grant is now a golden file of what the grants part composes, since the composer of the bus's user list leaves mesh-sdk too. Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
package compose
|
||||
|
||||
import (
|
||||
"crypto/ecdh"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
||||
"github.com/novox/mesh-host/internal/overlay"
|
||||
)
|
||||
|
||||
// aPublicKey is a key a machine could have reported, made as mesh-controller's mesh_for_test.go aPublicKey makes it.
|
||||
func aPublicKey(t *testing.T) string {
|
||||
t.Helper()
|
||||
k, err := ecdh.X25519().GenerateKey(rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return base64.StdEncoding.EncodeToString(k.PublicKey().Bytes())
|
||||
}
|
||||
|
||||
// keys are made once per run, so two Inputs made the same way are equal.
|
||||
var keys = map[string]string{}
|
||||
|
||||
func keyOf(t *testing.T, name string) string {
|
||||
t.Helper()
|
||||
if keys[name] == "" {
|
||||
keys[name] = aPublicKey(t)
|
||||
}
|
||||
return keys[name]
|
||||
}
|
||||
|
||||
// theOverlayModule is the module the mesh provides for itself, as mesh-controller's providedModules makes it
|
||||
// (cmd/mesh-controller/modules.go at 6c2a8d62).
|
||||
func theOverlayModule(t *testing.T) catalogue.Manifest {
|
||||
t.Helper()
|
||||
var m catalogue.Manifest
|
||||
b, err := json.Marshal(overlay.Manifest())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := json.Unmarshal(b, &m); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// aMesh is the Input of mesh-controller's aMesh (cmd/mesh-controller/mesh_for_test.go at 6c2a8d62): two placed
|
||||
// machines, `anchor` the hub, both reporting container-runtime, wireguard and systemd, both assigned what puts them on the
|
||||
// private network, each at <name>.example:51820 on the site `here`, anchor at 10.77.0.1 and laptop at 10.77.0.2.
|
||||
func aMesh(t *testing.T) Input {
|
||||
t.Helper()
|
||||
in := Input{Catalogue: map[string]catalogue.Manifest{overlay.Name: theOverlayModule(t)}}
|
||||
for i, name := range []string{"anchor", "laptop"} {
|
||||
in.Nodes = append(in.Nodes, Node{
|
||||
Name: name,
|
||||
Place: Place{Key: keyOf(t, name), Endpoint: name + ".example:51820", Site: "here",
|
||||
Hub: name == "anchor", Address: []string{"10.77.0.1", "10.77.0.2"}[i]},
|
||||
Assigned: []string{overlay.Name},
|
||||
Capabilities: map[string]bool{"container-runtime": true, "wireguard": true, "systemd": true},
|
||||
})
|
||||
}
|
||||
return in
|
||||
}
|
||||
|
||||
// nodeOf is the named node of an Input, for a test to change.
|
||||
func nodeOf(t *testing.T, in *Input, name string) *Node {
|
||||
t.Helper()
|
||||
for i := range in.Nodes {
|
||||
if in.Nodes[i].Name == name {
|
||||
return &in.Nodes[i]
|
||||
}
|
||||
}
|
||||
t.Fatalf("no node %s", name)
|
||||
return nil
|
||||
}
|
||||
|
||||
// unchanged runs call on one Input and compares it with another made the same way: the composition changes nothing in what
|
||||
// it is given (deep equality, nothing shared).
|
||||
func unchanged(t *testing.T, mk func() Input, call func(Input)) {
|
||||
t.Helper()
|
||||
used, same := mk(), mk()
|
||||
call(used)
|
||||
if !reflect.DeepEqual(used, same) {
|
||||
t.Fatalf("the call changed its Input")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user