Both are official packages already on both workstations, started once by dex from an XDG autostart entry (the client's own, the package's). The modules declare the package, add no second start, own none of the apps' files, and give the mesh status, log, restart and check.
110 lines
3.7 KiB
Go
110 lines
3.7 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// blueman's shape (novox/hq ADR 0208, ADR 0210): one official package, no seat, the X display on its
|
|
// own machine, no start of its own (the package's autostart entry is the one start), nothing of the
|
|
// bluetooth module's (bluez, its utilities, its daemon), and the Go bundle serving exactly the listed
|
|
// blueman_ tools.
|
|
|
|
type manifest struct {
|
|
Module string `json:"module"`
|
|
Version string `json:"version"`
|
|
Capabilities []string `json:"capabilities"`
|
|
Requires []string `json:"requires"`
|
|
Tools []string `json:"tools"`
|
|
Resources []map[string]any `json:"resources"`
|
|
Claims []any `json:"claims"`
|
|
Seats []any `json:"seats"`
|
|
Shell []any `json:"shell"`
|
|
Contributions []any `json:"contributions"`
|
|
Environment any `json:"environment"`
|
|
Build struct {
|
|
Artifacts []map[string]any `json:"artifacts"`
|
|
} `json:"build"`
|
|
}
|
|
|
|
func readManifest(t *testing.T) (manifest, string) {
|
|
t.Helper()
|
|
raw, err := os.ReadFile(filepath.Join("..", "..", "module.json"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
dec := json.NewDecoder(strings.NewReader(string(raw)))
|
|
dec.DisallowUnknownFields()
|
|
var m manifest
|
|
if err := dec.Decode(&m); err != nil {
|
|
t.Fatalf("module.json: %v", err)
|
|
}
|
|
return m, string(raw)
|
|
}
|
|
|
|
func TestItInstallsTheAppletAndNothingElse(t *testing.T) {
|
|
m, _ := readManifest(t)
|
|
if m.Module != "blueman" || !reflect.DeepEqual(m.Requires, []string{"x11-display"}) ||
|
|
!reflect.DeepEqual(m.Capabilities, []string{"package-manager"}) {
|
|
t.Fatalf("%+v", m)
|
|
}
|
|
if len(m.Resources) != 1 || m.Resources[0]["type"] != "package" || m.Resources[0]["package"] != packageFor {
|
|
t.Fatalf("resources: %v", m.Resources)
|
|
}
|
|
if m.Claims != nil || m.Seats != nil || m.Environment != nil {
|
|
t.Fatal("it holds no seat and sets no environment")
|
|
}
|
|
}
|
|
|
|
func TestItAddsNoSecondStartAndDeclaresNothingOfTheBluetoothModule(t *testing.T) {
|
|
m, raw := readManifest(t)
|
|
// The package ships its XDG autostart entry, which the session's dex runs: an xinitrc slot or a
|
|
// window-manager exec would start it twice.
|
|
if m.Shell != nil || m.Contributions != nil {
|
|
t.Fatalf("a second start: shell %v, contributions %v", m.Shell, m.Contributions)
|
|
}
|
|
for _, never := range []string{"autostart", "service", "bluez", "/etc/bluetooth"} {
|
|
if strings.Contains(raw, never) {
|
|
t.Errorf("module.json names %q: the start is the package's, the stack the bluetooth module's", never)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTheToolsAgreeWithTheManifest(t *testing.T) {
|
|
m, raw := readManifest(t)
|
|
served := map[string]bool{}
|
|
for _, tool := range tools() {
|
|
served[tool.Name] = true
|
|
if !strings.HasPrefix(tool.Name, "blueman_") || strings.TrimSpace(tool.Description) == "" {
|
|
t.Errorf("%s: prefixed blueman_ and described", tool.Name)
|
|
}
|
|
}
|
|
for _, name := range m.Tools {
|
|
if !served[name] {
|
|
t.Errorf("module.json lists %s, which the bundle does not serve", name)
|
|
}
|
|
delete(served, name)
|
|
}
|
|
for name := range served {
|
|
t.Errorf("the bundle serves %s, which module.json does not list", name)
|
|
}
|
|
if len(m.Build.Artifacts) != 1 {
|
|
t.Fatalf("%v", m.Build.Artifacts)
|
|
}
|
|
b := m.Build.Artifacts[0]
|
|
if b["kind"] != "bundle" || b["language"] != "go" || b["system"] != "arch" ||
|
|
b["from"] != "cmd/blueman-tools" || b["binary"] != "blueman-tools" {
|
|
t.Errorf("the Go tools bundle: %v", b)
|
|
}
|
|
s := strings.ToLower(raw)
|
|
for _, never := range []string{"/home/", "jochen", "g14", "shanks", "novox.be", "http", "password", "token"} {
|
|
if strings.Contains(s, never) {
|
|
t.Errorf("module.json names %q", never)
|
|
}
|
|
}
|
|
}
|