The node-engine applies only a composition signed by the controller or the operator, and when the controller cannot compose its own fix the operator composes, signs and writes one at the terminal (ADR 0539 clauses 3 and 10).
73 lines
2.4 KiB
Go
73 lines
2.4 KiB
Go
package compose
|
|
|
|
import (
|
|
"encoding/json"
|
|
"sort"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/delivery"
|
|
)
|
|
|
|
func fpFor(c byte) string { return delivery.SourcePrefix2 + strings.Repeat(string(c), 64) }
|
|
|
|
// 1943/AC5: a node's compositions are its declaration as Compose gives it, split by the module each resource belongs
|
|
// to: every resource once, each in its module's composition at the fingerprint given, the module's ownership said on
|
|
// it; a module given no fingerprint is named as skipped and composed nowhere.
|
|
func TestCompositionsAreTheDeclarationSplitByModule(t *testing.T) {
|
|
in := aSmallMesh(t)
|
|
d, _, err := Compose(in, "laptop")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var want []string
|
|
for _, r := range d.Resources {
|
|
want = append(want, r["type"].(string)+":"+r["id"].(string))
|
|
}
|
|
sort.Strings(want)
|
|
|
|
fps := map[string]string{"mesh-wireguard": fpFor('a'), "files": fpFor('b')}
|
|
out, skipped, err := Compositions(in, "laptop", fps, Foreseeing)
|
|
if err != nil || len(skipped) != 0 {
|
|
t.Fatalf("Compositions = %v, skipped %v", err, skipped)
|
|
}
|
|
var got []string
|
|
for key, c := range out {
|
|
node, module, fp, isNode, err := delivery.ParseComposedKey(key)
|
|
if err != nil || node != "laptop" || module != c.Module || fp != c.FP || (isNode != (module == "")) {
|
|
t.Errorf("key %s holds %s at %s (%v)", key, c.Module, c.FP, err)
|
|
}
|
|
if !isNode && fp != fps[module] {
|
|
t.Errorf("%s is composed at %s, given %s", module, fp, fps[module])
|
|
}
|
|
if _, err := delivery.EncodeComposed(c); err != nil {
|
|
t.Errorf("%s: %v", key, err)
|
|
}
|
|
for _, raw := range c.Resources {
|
|
var r struct{ ID, Type, Module string }
|
|
_ = json.Unmarshal(raw, &r)
|
|
if r.Module != module {
|
|
t.Errorf("%s holds %s of %q", key, r.ID, r.Module)
|
|
}
|
|
got = append(got, r.Type+":"+r.ID)
|
|
}
|
|
}
|
|
sort.Strings(got)
|
|
if strings.Join(got, " ") != strings.Join(want, " ") {
|
|
t.Errorf("the compositions hold %v, the declaration %v", got, want)
|
|
}
|
|
|
|
one, skipped, err := Compositions(in, "laptop", map[string]string{"files": fpFor('b')}, Foreseeing)
|
|
if err != nil || strings.Join(skipped, ",") != "mesh-wireguard" {
|
|
t.Fatalf("one module: %v, skipped %v", err, skipped)
|
|
}
|
|
for _, c := range one {
|
|
if c.Module == "mesh-wireguard" {
|
|
t.Errorf("a module given no fingerprint was composed")
|
|
}
|
|
}
|
|
if _, _, err := Compositions(in, "nowhere", fps, Foreseeing); err == nil {
|
|
t.Errorf("a node the mesh does not have was composed")
|
|
}
|
|
}
|