119 lines
4.2 KiB
Go
119 lines
4.2 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/delivery"
|
|
"git.novox.be/novox/mesh-sdk/go/forgekey"
|
|
"git.novox.be/novox/mesh-sdk/go/health"
|
|
)
|
|
|
|
// 1703a: a machine where buildah runs, the account holds ranges in both files and a namespace can be made is healthy,
|
|
// and the health names buildah and the ranges (ADR 0487 §2: proven, not declared).
|
|
func TestHealthIsHealthyWithBuildahRangesAndANamespace(t *testing.T) {
|
|
f := newFake(t)
|
|
m := moduleWith(t, f, newStates())
|
|
a := m.Health(context.Background())
|
|
if a.State != health.StateHealthy || !a.Healthy {
|
|
t.Fatalf("health = %+v, want healthy", a)
|
|
}
|
|
for _, want := range []string{"buildah 1.45.1", "mesh-build-image holds 65536 subordinate uids and 65536 gids"} {
|
|
if !strings.Contains(a.Why, want) {
|
|
t.Errorf("health says %q, lacks %q", a.Why, want)
|
|
}
|
|
}
|
|
if _, err := os.Stat(m.Store + "/xdg"); err != nil {
|
|
t.Errorf("the runtime directory inside the store was not made: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestHealthIsUnhealthyWithoutBuildah(t *testing.T) {
|
|
f := newFake(t)
|
|
m := moduleWith(t, f, newStates())
|
|
m.Run = func(ctx context.Context, env []string, name string, args ...string) forgekey.Ran {
|
|
return forgekey.Ran{Status: 127, Err: "exec: \"buildah\": executable file not found in $PATH"}
|
|
}
|
|
a := m.Health(context.Background())
|
|
if a.Healthy || !strings.Contains(a.Why, "buildah") {
|
|
t.Errorf("health = %+v, want unhealthy naming buildah", a)
|
|
}
|
|
}
|
|
|
|
// The ranges are read from the two files, one each: without one in /etc/subuid or in /etc/subgid the account has no ids to
|
|
// map, and the health says which file.
|
|
func TestHealthIsUnhealthyWithoutARangeInEitherFile(t *testing.T) {
|
|
for file, set := range map[string]func(*Module, string){
|
|
"subuid": func(m *Module, p string) { m.SubUIDFile = p },
|
|
"subgid": func(m *Module, p string) { m.SubGIDFile = p },
|
|
} {
|
|
f := newFake(t)
|
|
m := moduleWith(t, f, newStates())
|
|
p := t.TempDir() + "/" + file
|
|
os.WriteFile(p, []byte("someone-else:100000:65536\n"), 0o644)
|
|
set(m, p)
|
|
a := m.Health(context.Background())
|
|
if a.Healthy || !strings.Contains(a.Why, p) || !strings.Contains(a.Why, "mesh-build-image") {
|
|
t.Errorf("%s: health = %+v, want unhealthy naming %s and the account", file, a, p)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestHealthIsUnhealthyWhenANamespaceCannotBeMade(t *testing.T) {
|
|
f := newFake(t)
|
|
m := moduleWith(t, f, newStates())
|
|
run := m.Run
|
|
m.Run = func(ctx context.Context, env []string, name string, args ...string) forgekey.Ran {
|
|
if len(args) >= 2 && args[len(args)-2] == "unshare" {
|
|
return forgekey.Ran{Status: 125, Stderr: "Error: cannot clone: Operation not permitted\n"}
|
|
}
|
|
return run(ctx, env, name, args...)
|
|
}
|
|
a := m.Health(context.Background())
|
|
if a.Healthy || !strings.Contains(a.Why, "user namespace") {
|
|
t.Errorf("health = %+v, want unhealthy naming the user namespace", a)
|
|
}
|
|
}
|
|
|
|
func TestSubRangeSumsTheAccountsLinesByNameOrUid(t *testing.T) {
|
|
p := t.TempDir() + "/subuid"
|
|
os.WriteFile(p, []byte("a:1:10\nmesh-build-image:100:65536\n1234:200000:100\nb:5:5\nbad line\n"), 0o644)
|
|
if n, err := SubRange(p, "mesh-build-image", "1234"); err != nil || n != 65636 {
|
|
t.Errorf("range = %d, %v, want 65636", n, err)
|
|
}
|
|
if n, _ := SubRange(p, "nobody", ""); n != 0 {
|
|
t.Errorf("nobody has %d", n)
|
|
}
|
|
}
|
|
|
|
// A step on a machine that cannot build ends refused with the cause named, and nothing else runs.
|
|
func TestAStepOnAMachineThatCannotBuildEndsRefused(t *testing.T) {
|
|
f := newFake(t)
|
|
states := newStates()
|
|
m := moduleWith(t, f, states)
|
|
m.SubGIDFile = "/nonexistent/subgid"
|
|
if _, err := tool(t, m, FetchTool)(map[string]any{"repository": "novox/mesh-catalog", "commit": commitSHA}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
st := states.waitEnd(t)
|
|
if st.State != delivery.StepRefused || !strings.Contains(st.Reason, "/nonexistent/subgid") {
|
|
t.Errorf("step = %+v, want refused naming the file", st)
|
|
}
|
|
for _, l := range f.lines() {
|
|
if strings.HasPrefix(l, "git ") {
|
|
t.Errorf("a refused step ran %q", l)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestStatusSaysWhatTheMachineHas(t *testing.T) {
|
|
f := newFake(t)
|
|
m := moduleWith(t, f, newStates())
|
|
s := m.Status(context.Background())
|
|
if s["refusing"] != false || s["buildah"] != "1.45.1" || s["subuids"] != 65536 || s["account"] != "mesh-build-image" {
|
|
t.Errorf("status = %v", s)
|
|
}
|
|
}
|