package paths import ( "encoding/json" "os" "path/filepath" "testing" "banger/internal/runtimebundle" ) func TestResolveRuntimeDirPrefersEnv(t *testing.T) { t.Setenv("BANGER_RUNTIME_DIR", "/env/runtime") if got := ResolveRuntimeDir("/config/runtime", "/deprecated/repo"); got != "/env/runtime" { t.Fatalf("ResolveRuntimeDir() = %q, want /env/runtime", got) } } func TestResolveRuntimeDirUsesInstalledLayout(t *testing.T) { root := t.TempDir() runtimeDir := filepath.Join(root, "lib", "banger") createRuntimeBundle(t, runtimeDir) origExecutablePath := executablePath executablePath = func() (string, error) { return filepath.Join(root, "bin", "banger"), nil } t.Cleanup(func() { executablePath = origExecutablePath }) if got := ResolveRuntimeDir("", ""); got != runtimeDir { t.Fatalf("ResolveRuntimeDir() = %q, want %q", got, runtimeDir) } } func TestResolveRuntimeDirUsesBuildRuntimeForSourceCheckoutBinary(t *testing.T) { root := t.TempDir() runtimeDir := filepath.Join(root, "build", "runtime") createRuntimeBundle(t, runtimeDir) origExecutablePath := executablePath executablePath = func() (string, error) { return filepath.Join(root, "banger"), nil } t.Cleanup(func() { executablePath = origExecutablePath }) if got := ResolveRuntimeDir("", ""); got != runtimeDir { t.Fatalf("ResolveRuntimeDir() = %q, want %q", got, runtimeDir) } } func TestResolveRuntimeDirUsesBuildRuntimeForBuildBinExecutable(t *testing.T) { root := t.TempDir() runtimeDir := filepath.Join(root, "build", "runtime") createRuntimeBundle(t, runtimeDir) origExecutablePath := executablePath executablePath = func() (string, error) { return filepath.Join(root, "build", "bin", "banger"), nil } t.Cleanup(func() { executablePath = origExecutablePath }) if got := ResolveRuntimeDir("", ""); got != runtimeDir { t.Fatalf("ResolveRuntimeDir() = %q, want %q", got, runtimeDir) } } func createRuntimeBundle(t *testing.T, runtimeDir string) { t.Helper() metadata := runtimebundle.BundleMetadata{ FirecrackerBin: "bin/firecracker", SSHKeyPath: "keys/id_ed25519", NamegenPath: "bin/namegen", CustomizeScript: "scripts/customize.sh", VSockAgentPath: "bin/banger-vsock-agent", DefaultPackages: "config/packages.apt", DefaultRootfs: "images/rootfs-docker.ext4", DefaultKernel: "kernels/vmlinux", } for _, rel := range []string{ metadata.FirecrackerBin, metadata.SSHKeyPath, metadata.NamegenPath, metadata.CustomizeScript, metadata.VSockAgentPath, metadata.DefaultPackages, metadata.DefaultRootfs, metadata.DefaultKernel, } { path := filepath.Join(runtimeDir, rel) if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { t.Fatalf("mkdir %s: %v", filepath.Dir(path), err) } if err := os.WriteFile(path, []byte("test"), 0o644); err != nil { t.Fatalf("write %s: %v", path, err) } } data, err := json.Marshal(metadata) if err != nil { t.Fatalf("Marshal: %v", err) } if err := os.WriteFile(filepath.Join(runtimeDir, runtimebundle.BundleMetadataFile), data, 0o644); err != nil { t.Fatalf("write bundle metadata: %v", err) } }