Rename mesh-control -> mesh-controller, substrate -> foundation
One name per thing, per the HQ glossary: the module/container/image/binary/repo becomes mesh-controller, the seat the-controller, and the store+broker pair the foundation (embedded base bundles, default template and example lock renamed with their go:embed directives). No behaviour change — a pure vocabulary rename. Claude-Session: https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/ecdh"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/novox/mesh-controller/internal/catalogue"
|
||||
"github.com/novox/mesh-controller/internal/inventory"
|
||||
"github.com/novox/mesh-controller/internal/licences"
|
||||
"github.com/novox/mesh-controller/internal/overlay"
|
||||
)
|
||||
|
||||
// A mesh a command can be run against.
|
||||
//
|
||||
// The commands here were tested through the pieces they call and never through themselves, so
|
||||
// three faults that only exist where the pieces meet — an assignment reported as fine while it
|
||||
// blocked other machines, a read-shaped invocation that wrote, a JSON interface that stopped
|
||||
// emitting JSON — were invisible to every test in this package. This raises the real stores and
|
||||
// calls the real functions.
|
||||
|
||||
// aMesh is two placed, capable machines on a private network, with nothing assigned but the
|
||||
// network itself.
|
||||
//
|
||||
// `anchor` is the hub. That is not decoration: a mesh whose hub cannot be resolved has no private
|
||||
// network at all, which is how one machine's problem reaches every other.
|
||||
func aMesh(t *testing.T) *stores {
|
||||
t.Helper()
|
||||
inventory.ForTest(t) // raises the store, migrates it, and points the environment at it
|
||||
licences.ForTest(t) // planning reaches this one too, by name and never by connection
|
||||
|
||||
open, err := openStores(t.Context())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(open.Close)
|
||||
for _, m := range provided {
|
||||
if err := open.inventory.Provide(t.Context(), m); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
for i, name := range []string{"anchor", "laptop"} {
|
||||
record, err := open.inventory.AddNode(t.Context(), name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := open.inventory.SetPlace(t.Context(), name, name+".example:51820", "here",
|
||||
name == "anchor", fmt.Sprintf("10.77.0.%d", i+1)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
reported, err := json.Marshal(map[string]any{"capabilities": []map[string]any{
|
||||
{"name": "container-runtime", "present": true},
|
||||
{"name": "wireguard", "present": true},
|
||||
{"name": "systemd", "present": true},
|
||||
}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var profile map[string]any
|
||||
if err := json.Unmarshal(reported, &profile); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := open.inventory.RecordProfile(t.Context(), record.ID, profile); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := open.inventory.RecordSealingKey(t.Context(), record.ID, aPublicKey(t)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := open.inventory.RecordOverlayKey(t.Context(), record.ID, aPublicKey(t)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := open.inventory.Assign(t.Context(), name, overlay.Name); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
return open
|
||||
}
|
||||
|
||||
// aPublicKey is a key a machine could have reported. Its private half is thrown away: nothing here
|
||||
// opens anything, it only needs the mesh to believe a machine has a key.
|
||||
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())
|
||||
}
|
||||
|
||||
// register puts a manifest in the catalogue.
|
||||
func register(t *testing.T, open *stores, m catalogue.Manifest) {
|
||||
t.Helper()
|
||||
if err := open.inventory.RegisterModule(t.Context(), m, inventory.Source{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// rivals are two modules that cannot share a machine, which is the shortest way to make a node's
|
||||
// own set of assignments incoherent using nothing but commands a person has.
|
||||
func rivals() (catalogue.Manifest, catalogue.Manifest) {
|
||||
claim := []catalogue.Claim{{Name: "the-seat", Scope: catalogue.ScopeNode}}
|
||||
return catalogue.Manifest{Module: "rival-one", Version: "1", Claims: claim},
|
||||
catalogue.Manifest{Module: "rival-two", Version: "1", Claims: claim}
|
||||
}
|
||||
Reference in New Issue
Block a user