Files
mesh-catalog/modules/mesh-build-node/cmd/mesh-build-node/toolchain_open_test.go
T
jschoubben 00e54d46d7 Give the integration level the node's installed Node toolchains read-only, so the Node build module's tests build offline (issue 1891, ADR 0533)
mesh-build-go binds /var/lib/mesh-build-node-cache/toolchain read-only into the
integration level's one shut-off process when it is there; the unit level never.
mesh-build-node opens its installed toolchains to other accounts (folders 0755,
files 0644, writable by its owner alone; its cache 0711, so the npm cache beside
them stays its own), and realMachine copies the toolchain of its own lock from
there instead of npm ci from the registry, which the level cannot reach.
2026-10-23 11:22:05 +02:00

101 lines
3.5 KiB
Go

package main
import (
"context"
"io/fs"
"os"
"path/filepath"
"testing"
"git.novox.be/novox/mesh-sdk/go/forgekey"
)
// npmAsUmask077 installs as npm does under a umask of 077: node_modules with a package whose folders are 0700, its
// file 0600 and its program 0700.
func npmAsUmask077(f *fakeNpm) forgekey.Runner {
return func(ctx context.Context, env []string, name string, args ...string) forgekey.Ran {
ran := f.run(ctx, env, name, args...)
for i, a := range args {
if a == "--prefix" {
pkg := filepath.Join(args[i+1], "node_modules", "typescript", "bin")
os.MkdirAll(pkg, 0o700)
os.WriteFile(filepath.Join(args[i+1], "node_modules", "typescript", "package.json"), []byte("{}"), 0o600)
os.WriteFile(filepath.Join(pkg, "tsc"), []byte("#!/bin/sh\n"), 0o700)
}
}
return ran
}
}
// checkOpen fails unless every folder from the cache's toolchain down lets others enter and read it and every file lets
// others read it, a program others run, and nothing lets anyone but the owner write.
func checkOpen(t *testing.T, tc Toolchain) {
t.Helper()
root := filepath.Join(tc.Paths.Cache, "toolchain")
err := filepath.WalkDir(root, func(p string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
info, err := d.Info()
if err != nil {
return err
}
mode := info.Mode().Perm()
switch {
case mode&0o022 != 0:
t.Errorf("%s is %o: writable by others than its owner", p, mode)
case d.IsDir() && mode&0o005 != 0o005:
t.Errorf("%s is %o: others may not enter and read it", p, mode)
case !d.IsDir() && mode&0o004 == 0:
t.Errorf("%s is %o: others may not read it", p, mode)
case !d.IsDir() && mode&0o100 != 0 && mode&0o001 == 0:
t.Errorf("%s is %o: a program others may not run", p, mode)
}
return nil
})
if err != nil {
t.Fatal(err)
}
}
// 1891 (ADR 0533 §2): a toolchain the module installs can be read by the other build module's integration level:
// its folders 0755 and its files 0644 (programs 0755), whatever umask npm ran under, and writable by its owner alone.
func TestAnInstalledToolchainIsReadableByOthersAndWritableByItsOwnerAlone(t *testing.T) {
fake := &fakeNpm{}
tc := toolchainIn(t, fake)
tc.Run = npmAsUmask077(fake)
if err := tc.Ensure(context.Background(), "v1"); err != nil {
t.Fatal(err)
}
checkOpen(t, tc)
}
// 1891 (ADR 0533 §2): a toolchain installed before this release, shut to its owner, is opened by the next Ensure
// without installing it again.
func TestAToolchainInstalledShutIsOpenedWithoutAnInstall(t *testing.T) {
fake := &fakeNpm{}
tc := toolchainIn(t, fake)
dir := tc.Paths.Dir("v1")
os.MkdirAll(filepath.Join(dir, "node_modules", "esbuild", "bin"), 0o700)
os.WriteFile(filepath.Join(dir, "node_modules", "esbuild", "bin", "esbuild"), []byte("x"), 0o700)
os.WriteFile(filepath.Join(dir, "package-lock.json"), []byte("{}"), 0o600)
os.WriteFile(filepath.Join(dir, installedMark), []byte("v1\n"), 0o600)
os.Chmod(filepath.Join(tc.Paths.Cache, "toolchain"), 0o700)
if err := tc.Ensure(context.Background(), "v1"); err != nil {
t.Fatal(err)
}
if len(fake.calls) != 0 {
t.Errorf("npm ran %d times for a toolchain already there", len(fake.calls))
}
checkOpen(t, tc)
}
// 1891 (ADR 0533 §2): the cache directory lets other accounts enter it and not list it, so the toolchains beneath it
// can be reached by their path and the npm cache beside them (0700) cannot.
func TestTheCacheDirectoryIsEnteredByOthersNotListed(t *testing.T) {
r := resource(t, readManifest(t), "cache")
if r["mode"] != "0711" {
t.Errorf("the cache directory's mode is %v, want 0711", r["mode"])
}
}