package sandbox import ( "os" "path/filepath" "strings" "testing" ) func TestNormalizeBackend(t *testing.T) { got, err := NormalizeBackend("PODMAN") if err != nil || got != BackendPodman { t.Fatalf("got %q err %v", got, err) } if _, err := NormalizeBackend("bwrap"); err == nil { t.Fatal("expected error for removed bwrap backend") } if _, err := NormalizeBackend("firecracker"); err == nil { t.Fatal("expected error for unknown backend") } got, err = NormalizeBackend("") if err != nil || got != BackendPodman { t.Fatalf("empty -> podman, got %q %v", got, err) } } func TestNoneWrap_Passthrough(t *testing.T) { w, err := New(Options{Backend: BackendNone}) if err != nil { t.Fatal(err) } bin := "/opt/blender/blender" cmd, err := w.Wrap(Spec{ BlenderBinary: bin, Args: []string{"-b", "scene.blend"}, WorkDir: "/tmp/job", Env: []string{"HOME=/tmp/job/home"}, }) if err != nil { t.Fatal(err) } if len(cmd.Args) == 0 || cmd.Args[0] != bin { t.Fatalf("args[0]=%v path=%q", cmd.Args, cmd.Path) } if cmd.Dir != "/tmp/job" { t.Fatalf("Dir=%q", cmd.Dir) } } func TestGPUMounts_ForceCPUEmpty(t *testing.T) { m := GPUMounts(true, true, true, true) if len(m) != 0 { t.Fatalf("force CPU should skip GPU mounts, got %#v", m) } } func TestGPUMounts_AMDIncludesKFD(t *testing.T) { m := GPUMounts(true, false, false, false) var hosts []string for _, b := range m { hosts = append(hosts, b.Host) } joined := strings.Join(hosts, ",") if !strings.Contains(joined, "/dev/dri") { t.Fatalf("AMD mounts should include /dev/dri, got %v", hosts) } if !strings.Contains(joined, "/dev/kfd") { t.Fatalf("AMD mounts should include /dev/kfd, got %v", hosts) } } func TestGPUMounts_NVIDIAIncludesCtl(t *testing.T) { m := GPUMounts(false, true, false, false) found := false for _, b := range m { if strings.Contains(b.Host, "nvidia") { found = true break } } if !found { t.Fatalf("NVIDIA mounts should include nvidia devices, got %#v", m) } } func TestPodmanWrap_BuildsRunArgs(t *testing.T) { w := &podmanWrapper{allowNetwork: false, image: "example.com/thin:latest"} if err := w.Available(); err != nil { t.Skipf("podman not installed: %v", err) } tmp := t.TempDir() blendDir := filepath.Join(tmp, "bver") _ = os.MkdirAll(blendDir, 0755) bin := filepath.Join(blendDir, "blender") _ = os.WriteFile(bin, []byte("x"), 0755) job := filepath.Join(tmp, "job") _ = os.MkdirAll(job, 0755) cmd, err := w.Wrap(Spec{ BlenderBinary: bin, Args: []string{"-b", "x.blend"}, WorkDir: job, HomeDir: filepath.Join(job, "home"), Env: []string{"HOME=" + filepath.Join(job, "home")}, HasNVIDIA: true, }) if err != nil { t.Fatal(err) } joined := strings.Join(cmd.Args, " ") if !strings.Contains(joined, "run") || !strings.Contains(joined, "--network=none") { t.Fatalf("expected podman run --network=none: %s", joined) } if !strings.Contains(joined, "example.com/thin:latest") { t.Fatalf("expected image in args: %s", joined) } if !strings.Contains(joined, "--entrypoint") || !strings.Contains(joined, bin) { t.Fatalf("expected entrypoint blender: %s", joined) } if !strings.Contains(joined, blendDir) || !strings.Contains(joined, job) { t.Fatalf("expected volume binds: %s", joined) } } func TestNew_UnknownBackend(t *testing.T) { if _, err := New(Options{Backend: "bwrap"}); err == nil { t.Fatal("expected error for bwrap") } if _, err := New(Options{Backend: "gvisor"}); err == nil { t.Fatal("expected error") } }