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 .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") } }