91 lines
2.7 KiB
Go
91 lines
2.7 KiB
Go
package compose
|
|
|
|
import (
|
|
"crypto/ecdh"
|
|
"crypto/rand"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
|
"git.novox.be/novox/mesh-sdk/go/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")
|
|
}
|
|
}
|