Feature 57 (config and provisioning): modules declare config and provisions, their files rendered from templates; synced with main (issues of feature 57, 874)
This commit is contained in:
@@ -28,6 +28,11 @@ type manifest struct {
|
||||
Environment struct {
|
||||
Variables map[string]string `json:"variables"`
|
||||
} `json:"environment"`
|
||||
Items []struct {
|
||||
Collection string `json:"collection"`
|
||||
Attributes map[string]string `json:"attributes"`
|
||||
Template string `json:"template"`
|
||||
} `json:"items"`
|
||||
Shell []struct {
|
||||
For, Slot, Code string
|
||||
} `json:"shell"`
|
||||
@@ -46,6 +51,23 @@ func readManifest(t *testing.T) manifest {
|
||||
if err := json.Unmarshal(raw, &m); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// The module's code and variables are the templates of its items (design 57 L3, issues 795 and 807).
|
||||
for _, it := range m.Items {
|
||||
text, err := os.ReadFile(filepath.Join("..", "..", it.Template))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
parts := strings.Split(it.Collection, ":")
|
||||
switch {
|
||||
case len(parts) == 3 && parts[0] == "shell":
|
||||
m.Shell = append(m.Shell, struct{ For, Slot, Code string }{parts[1], parts[2], string(text)})
|
||||
case it.Collection == "environment" && it.Attributes["kind"] == "variable":
|
||||
if m.Environment.Variables == nil {
|
||||
m.Environment.Variables = map[string]string{}
|
||||
}
|
||||
m.Environment.Variables[it.Attributes["name"]] = strings.TrimSuffix(string(text), "\n")
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
@@ -108,9 +130,10 @@ func TestItContributesTheSessionsExecLastAndTheDesktopsIdentity(t *testing.T) {
|
||||
func TestTheConfigurationIsTheModulesFileImprovedAndEndsWithTheDropIns(t *testing.T) {
|
||||
m := readManifest(t)
|
||||
r := resource(t, m, "config")
|
||||
raw, _ := os.ReadFile(filepath.Join("..", "..", "config", "config"))
|
||||
if r["content"] != string(raw) || r["path"] != "${machine:account-home}/.config/i3/config" || r["into"] != nil {
|
||||
t.Fatal("the manifest carries config/config whole, as an owned file")
|
||||
raw, _ := os.ReadFile(filepath.Join("..", "..", "files", "config"))
|
||||
if _, inline := r["content"]; inline || r["template"] != "files/config" || len(raw) == 0 ||
|
||||
r["path"] != "${machine:account-home}/.config/i3/config" || r["into"] != nil {
|
||||
t.Fatal("the manifest takes files/config whole as its template, as an owned file")
|
||||
}
|
||||
c := string(raw)
|
||||
lines := strings.Split(strings.TrimSpace(c), "\n")
|
||||
@@ -159,7 +182,11 @@ func TestTheLoginManagersEntryRunsTheSessionsStart(t *testing.T) {
|
||||
if r["path"] != "/etc/lemurs/wms/i3" || r["mode"] != "0755" {
|
||||
t.Fatalf("%v", r)
|
||||
}
|
||||
if !strings.Contains(r["content"].(string), `exec systemd-cat -t x-session /bin/sh "$HOME/.xinitrc"`) {
|
||||
if r["template"] != "files/wms/i3" {
|
||||
t.Fatalf("the entry's text is not its template files/wms/i3: %v", r["template"])
|
||||
}
|
||||
entry, _ := os.ReadFile(filepath.Join("..", "..", "files", "wms", "i3"))
|
||||
if !strings.Contains(string(entry), `exec systemd-cat -t x-session /bin/sh "$HOME/.xinitrc"`) {
|
||||
t.Fatal("the entry runs the session's start, never i3 bare")
|
||||
}
|
||||
pkgs := map[string]bool{}
|
||||
@@ -219,7 +246,7 @@ func TestTheMainFileAndEveryModulesContributionLoadTogether(t *testing.T) {
|
||||
if len(found) < 5 {
|
||||
t.Fatalf("expected the launcher, clipboard, wallpaper, bars and the laptop to contribute; found %v", found)
|
||||
}
|
||||
main, _ := os.ReadFile(filepath.Join("..", "..", "config", "config"))
|
||||
main, _ := os.ReadFile(filepath.Join("..", "..", "files", "config"))
|
||||
text := strings.Replace(string(main), "${contribution:node-display-session:config}", placed.String(), 1)
|
||||
// The operator's own files are not the catalogue's: the include line itself goes (a contribution may
|
||||
// name it in a comment, so only the line that is exactly it).
|
||||
@@ -230,3 +257,31 @@ func TestTheMainFileAndEveryModulesContributionLoadTogether(t *testing.T) {
|
||||
t.Fatalf("with the contributions of %v: %v\n%s", found, err, out)
|
||||
}
|
||||
}
|
||||
|
||||
// No file resource carries its text inline: each names its template in files/, and the build packs files/
|
||||
// into the one archive the controller reads the templates back from (novox/hq ADR 0349 §2).
|
||||
func TestEveryFileTakesItsTextFromATemplate(t *testing.T) {
|
||||
m := readManifest(t)
|
||||
for _, r := range m.Resources {
|
||||
if _, inline := r["content"]; inline {
|
||||
t.Errorf("resource %v keeps its text inline: keep it in files/ and name it as the template", r["id"])
|
||||
}
|
||||
if name, ok := r["template"].(string); ok {
|
||||
if _, err := os.Stat(filepath.Join("..", "..", name)); err != nil {
|
||||
t.Errorf("resource %v names %s: %v", r["id"], name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
packs := 0
|
||||
for _, a := range m.Build.Artifacts {
|
||||
if a["kind"] == "archive" && a["from"] == "files" {
|
||||
packs++
|
||||
if a["name"] != "files" {
|
||||
t.Errorf("the templates archive is named %v, not files", a["name"])
|
||||
}
|
||||
}
|
||||
}
|
||||
if packs != 1 {
|
||||
t.Errorf("the build packs files/ into %d archives, not one", packs)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user