136 lines
6.6 KiB
Go
136 lines
6.6 KiB
Go
package catalogue
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
// A bar's blocks are a collection of text (design 57 L3, issue 781): the holder of node-bar names the kind as
|
|
// `${collected:contribution:node-bar:block:bar=<b>,place=<p>}`, which a handed collector has its client fill from the
|
|
// items and an unhanded one has the controller fill as it fills the old placeholder.
|
|
|
|
const (
|
|
collectedBarsText = "top\n${collected:contribution:node-bar:block:bar=top,place=status}" +
|
|
"bottom\n${collected:contribution:node-bar:block:bar=bottom,place=status}"
|
|
collectedBars = `{"module":"bars","version":"1","moved":true,
|
|
"claims":[{"name":"node-bar","scope":"node","renders":{"block":"{{.shows}}"}}],
|
|
"build":{"artifacts":[{"name":"files","kind":"archive","from":"files"}]},
|
|
"resources":[{"id":"conf","type":"file","path":"/etc/bars.conf","template":"files/bars"}]}`
|
|
itemsOfPower = `{"module":"power","version":"1","moved":true,
|
|
"items":[{"collection":"contribution:node-bar:block","name":"battery","if-capability":"battery","attributes":{"bar":"bottom","place":"status","order":"40"},"template":"files/battery"},
|
|
{"collection":"contribution:node-bar:block","name":"draw","attributes":{"bar":"bottom","place":"status","order":"45"},"template":"files/draw"}],
|
|
"build":{"artifacts":[{"name":"files","kind":"archive","from":"files"}]}}`
|
|
)
|
|
|
|
func collectedBarsOn(t *testing.T, caps map[string]bool) Resolution {
|
|
t.Helper()
|
|
bars := held(t, collectedBars, builtWith("bars", map[string]string{"bars": collectedBarsText}))
|
|
power := held(t, itemsOfPower, builtWith("power", map[string]string{"battery": "B\n", "draw": "D ${machine:name}\n"}))
|
|
r, err := Resolve(shelf(bars, power), []string{"bars", "power"}, workstation(), World{})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
r.Account, r.Capabilities = "op", caps
|
|
return r
|
|
}
|
|
|
|
func TestACollectorMayNameTheBarsBlocksAsACollectionAndNoOtherDataKind(t *testing.T) {
|
|
bars := held(t, collectedBars, builtWith("bars", map[string]string{"bars": collectedBarsText}))
|
|
if _, err := collectedBarsOn(t, nil).Compose(handingTo("store:5000")); err != nil {
|
|
t.Fatalf("the handed collector is refused: %v", err)
|
|
}
|
|
if got := collectedPlaceholderProblems(bars, map[string]any{"id": "x",
|
|
"content": "${collected:contribution:node-bar:block:bar=top,place=status}"}); len(got) != 0 {
|
|
t.Fatalf("the check refuses it: %v", got)
|
|
}
|
|
// A data kind whose shape does not say its items are text stays refused.
|
|
_, plain, _ := receivable(BarSeat, BarKindBlock)
|
|
plain.Shape = &Shape{}
|
|
if collectableAsText(plain) {
|
|
t.Fatal("a shape not marked as text is collectable")
|
|
}
|
|
if _, _, err := oldCollection("contribution:node-bar:block", false); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestTheBarsCollectionIsFilledTheOldWayWhereTheCollectorIsNotHanded(t *testing.T) {
|
|
for _, caps := range []map[string]bool{nil, {"battery": true}} {
|
|
got := composedFile(t, collectedBarsOn(t, caps), "bars.conf")
|
|
want := "top\nbottom\n# power\nD workstation\n"
|
|
if caps["battery"] {
|
|
want = "top\nbottom\n# power\nB\n# power\nD workstation\n"
|
|
}
|
|
if got != want {
|
|
t.Errorf("caps %v: the file is %q, want %q", caps, got, want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTheBarsCollectionIsNamedInTheHandedPlan(t *testing.T) {
|
|
c, _ := composeWith(t, collectedBarsOn(t, map[string]bool{"battery": true}), handingTo("store:5000"))
|
|
if !reflect.DeepEqual(c.Plans["bars"].Collections, []PlanCollection{{Name: "contribution:node-bar:block", Comment: "#"}}) {
|
|
t.Fatalf("the plan collects %+v", c.Plans["bars"].Collections)
|
|
}
|
|
if n := len(c.Plans["power"].Items); n != 2 {
|
|
t.Fatalf("the contributor's plan names %d items", n)
|
|
}
|
|
}
|
|
|
|
// The bars of the catalogue's i3status-rust, with the blocks of power's items, compose to the files the old shaped
|
|
// contribution made (issue 781). testdata/bars holds the catalogue's bars and block texts as of the move and the bars as
|
|
// composed before it, for a machine with neither capability, the battery, the power meter and both. Where the
|
|
// collector is not handed the controller fills the files; where it is, it names the items for the client, which
|
|
// fills the same files (mesh-catalog's provisioner client holds that half against the same golden files).
|
|
func TestTheBarsOfTheCatalogueAreTheSameHandedOrNot(t *testing.T) {
|
|
read := func(name string) string {
|
|
b, err := os.ReadFile(filepath.Join("testdata", "bars", name))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return string(b)
|
|
}
|
|
collector := `{"module":"bars","version":"1","moved":true,"claims":[{"name":"node-bar","scope":"node"}],
|
|
"build":{"artifacts":[{"name":"files","kind":"archive","from":"files"}]},
|
|
"resources":[{"id":"top","type":"file","path":"/t","template":"files/top"},
|
|
{"id":"bottom","type":"file","path":"/b","template":"files/bottom"}]}`
|
|
power := `{"module":"power","version":"1","moved":true,
|
|
"items":[{"collection":"contribution:node-bar:block","name":"battery","if-capability":"battery","attributes":{"bar":"bottom","place":"status","order":"40"},"template":"files/battery"},
|
|
{"collection":"contribution:node-bar:block","name":"power-draw","if-capability":"power-meter","attributes":{"bar":"bottom","place":"status","order":"45"},"template":"files/draw"}],
|
|
"build":{"artifacts":[{"name":"files","kind":"archive","from":"files"}]}}`
|
|
for name, caps := range map[string]map[string]bool{"none": nil, "battery": {"battery": true},
|
|
"power-meter": {"power-meter": true}, "both": {"battery": true, "power-meter": true}} {
|
|
bars := held(t, collector, builtWith("bars", map[string]string{"top": read("top-bar.toml"), "bottom": read("bottom-bar.toml")}))
|
|
blocks := held(t, power, builtWith("power", map[string]string{"battery": read("bar-battery"), "draw": read("bar-power-draw")}))
|
|
r, err := Resolve(shelf(bars, blocks), []string{"bars", "power"}, workstation(), World{})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
r.Account, r.Capabilities = "op", caps
|
|
// Not handed: the controller fills them.
|
|
for id, which := range map[string]string{"bars.top": "top", "bars.bottom": "bottom"} {
|
|
if got := composedFile(t, r, id); got != read(name+"."+which+"-bar.toml") {
|
|
t.Errorf("%s, %s bar, not handed:\n%s\nwant\n%s", name, which, got, read(name+"."+which+"-bar.toml"))
|
|
}
|
|
}
|
|
// Handed: the plan names the items the machine's capabilities allow, for the client to fill.
|
|
c, _ := composeWith(t, r, handingTo("store:5000"))
|
|
var names []string
|
|
for _, it := range c.Plans["power"].Items {
|
|
names = append(names, it.Name)
|
|
}
|
|
want := []string{}
|
|
if caps["battery"] {
|
|
want = append(want, "battery")
|
|
}
|
|
if caps["power-meter"] {
|
|
want = append(want, "power-draw")
|
|
}
|
|
if !reflect.DeepEqual(append([]string{}, names...), want) {
|
|
t.Errorf("%s: the plan names %v, want %v", name, names, want)
|
|
}
|
|
}
|
|
}
|