Files
mesh-controller/internal/inventory/declared_packages_test.go
T

84 lines
3.2 KiB
Go

package inventory
import (
"bytes"
"encoding/json"
"fmt"
"reflect"
"slices"
"testing"
)
// aNodesPackages is the resources of a node whose modules declare packages: one package two modules declare present, one
// declared absent, and a resource that is no package.
func aNodesPackages() ([]map[string]any, map[string]string) {
return []map[string]any{
{"id": "web.pkg-curl", "type": "package", "package": "curl"},
{"id": "backup.pkg-curl", "type": "package", "package": "curl"},
{"id": "web.pkg-nano", "type": "package", "package": "nano", "absent": true},
{"id": "web.conf", "type": "file", "path": "/etc/web.conf"},
},
map[string]string{"web.pkg-curl": "web", "backup.pkg-curl": "backup", "web.pkg-nano": "web", "web.conf": "web"}
}
// 1840/AC5: the declared-packages mirror's value for a node names each package with the modules that declare it and whether
// they declare it absent, and the same declaration is the same bytes however its resources are ordered, so a pass over an
// unchanged node writes nothing.
func TestTheDeclaredPackagesValueNamesEachPackageWithItsModules(t *testing.T) {
resources, owner := aNodesPackages()
got, err := DeclaredPackagesValue("one", resources, owner)
if err != nil {
t.Fatal(err)
}
want := `{"node":"one","packages":[{"package":"curl","modules":["backup","web"],"absent":false},` +
`{"package":"nano","modules":["web"],"absent":true}]}`
if string(got) != want {
t.Errorf("the value is\n%s\nwant\n%s", got, want)
}
reversed := slices.Clone(resources)
slices.Reverse(reversed)
again, err := DeclaredPackagesValue("one", reversed, owner)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(got, again) {
t.Errorf("the same declaration in another order is other bytes:\n%s\n%s", got, again)
}
if got := jsonFields(reflect.TypeOf(DeclaredPackagesMirrored{})); !slices.Equal(got, []string{"node", "packages"}) {
t.Errorf("the value carries %v", got)
}
}
// A node declaring no package has a value that says so, an empty list and not null.
func TestANodeDeclaringNoPackageHasAnEmptyList(t *testing.T) {
got, err := DeclaredPackagesValue("one", nil, nil)
if err != nil || string(got) != `{"node":"one","packages":[]}` {
t.Errorf("the value is %s (%v)", got, err)
}
}
// 1840/S3: a node's value stays under the 64 KiB a mirror's key holds at far more packages than a node declares: 600
// packages, each declared by four modules, is a few times what the largest node declares today.
func TestTheDeclaredPackagesValueOfABigNodeFitsAKey(t *testing.T) {
var resources []map[string]any
owner := map[string]string{}
for p := 0; p < 600; p++ {
for m := 0; m < 4; m++ {
id := fmt.Sprintf("module-%d.pkg-%d", m, p)
resources = append(resources, map[string]any{"id": id, "type": "package", "package": fmt.Sprintf("package-%d", p)})
owner[id] = fmt.Sprintf("module-%d", m)
}
}
got, err := DeclaredPackagesValue("one", resources, owner)
if err != nil {
t.Fatal(err)
}
var v DeclaredPackagesMirrored
if err := json.Unmarshal(got, &v); err != nil || len(v.Packages) != 600 {
t.Fatalf("the value holds %d packages (%v)", len(v.Packages), err)
}
if len(got) >= 64<<10 {
t.Errorf("the value is %d bytes, over the 64 KiB a key holds", len(got))
}
}