package runtime import ( "os" "reflect" "testing" ) func TestGet_Podman(t *testing.T) { rt := Get("podman") if rt == nil { t.Fatal("Get(podman) returned nil") } if rt.Name() != "podman" { t.Errorf("Name() = %q, want %q", rt.Name(), "podman") } } func TestGet_Docker(t *testing.T) { rt := Get("docker") if rt == nil { t.Fatal("Get(docker) returned nil") } if rt.Name() != "docker" { t.Errorf("Name() = %q, want %q", rt.Name(), "docker") } } func TestGet_Unknown(t *testing.T) { rt := Get("containerd") if rt != nil { t.Errorf("Get(containerd) should return nil for unknown runtime, got %+v", rt) } } func TestAvailable_ReturnsRuntimes(t *testing.T) { runtimes := Available() if len(runtimes) == 0 { t.Error("Available() returned empty list") } names := map[string]bool{} for _, rt := range runtimes { names[rt.Name()] = true } if !names["podman"] { t.Error("Available() should include podman") } if !names["docker"] { t.Error("Available() should include docker") } } // ListRunning and Exists are integration-level — they call external binaries. // We test that they don't panic when the binary is absent (returns nil/false, no error). func TestPodman_ListRunning_NoBinary(t *testing.T) { // This test is meaningful if podman isn't installed; if it is, we just check no error occurs p := &Podman{} containers, err := p.ListRunning("") if err != nil { t.Errorf("ListRunning() should not error when podman is absent: %v", err) } // containers may be nil or populated — both are fine _ = containers } func TestDocker_ListRunning_NoBinary(t *testing.T) { d := &Docker{} containers, err := d.ListRunning("") if err != nil { t.Errorf("ListRunning() should not error when docker is absent: %v", err) } _ = containers } func TestAvailable_PodmanFirst(t *testing.T) { runtimes := Available() if len(runtimes) < 2 || runtimes[0].Name() != "podman" || runtimes[1].Name() != "docker" { t.Errorf("Available() order must be podman, docker; got %v", runtimes) } } // Fixture captured from `podman-compose up -d` of testdata/stack/compose.yaml. func TestParsePodmanPS_ComposeStack(t *testing.T) { data, err := os.ReadFile("../testdata/stack/podman_ps.json") if err != nil { t.Fatalf("reading fixture: %v", err) } containers, err := parsePodmanPS(data) if err != nil { t.Fatalf("parsePodmanPS() error: %v", err) } if len(containers) != 2 { t.Fatalf("expected 2 containers, got %d", len(containers)) } for _, c := range containers { if c.Project() != "unitdore-test" { t.Errorf("%s: Project() = %q, want unitdore-test", c.Name, c.Project()) } if c.WorkingDir() == "" { t.Errorf("%s: WorkingDir() empty", c.Name) } if !reflect.DeepEqual(c.ComposeFiles(), []string{"compose.yaml"}) { t.Errorf("%s: ComposeFiles() = %v", c.Name, c.ComposeFiles()) } } } func TestContainer_NoProject(t *testing.T) { c := Container{Name: "plain"} if c.Project() != "" || c.WorkingDir() != "" || c.ComposeFiles() != nil { t.Errorf("container without labels should have no stack info: %+v", c) } } func TestContainer_ComposeFilesMultiple(t *testing.T) { c := Container{Labels: map[string]string{LabelComposeConfigFiles: "compose.yaml, ./override.yaml"}} want := []string{"compose.yaml", "override.yaml"} if got := c.ComposeFiles(); !reflect.DeepEqual(got, want) { t.Errorf("ComposeFiles() = %v, want %v", got, want) } } func TestParseDockerPS_Labels(t *testing.T) { out := []byte(`{"ID":"abc","Names":"web","Image":"nginx","Command":"nginx","State":"running","Labels":"com.docker.compose.project=shop,com.docker.compose.project.config_files=/s/a.yml,/s/b.yml,com.docker.compose.service=web"}`) cs := parseDockerPS(out) if len(cs) != 1 { t.Fatalf("expected 1 container, got %d", len(cs)) } l := cs[0].Labels if l["com.docker.compose.project"] != "shop" { t.Errorf("project label = %q", l["com.docker.compose.project"]) } if l["com.docker.compose.project.config_files"] != "/s/a.yml,/s/b.yml" { t.Errorf("config_files label = %q", l["com.docker.compose.project.config_files"]) } if l["com.docker.compose.service"] != "web" { t.Errorf("service label = %q", l["com.docker.compose.service"]) } // Docker compose stacks are not grouped yet (podman-compose only) if cs[0].Project() != "" { t.Errorf("docker compose container should not report a podman-compose project") } } func TestPodName(t *testing.T) { if PodName("shop") != "pod_shop" { t.Errorf("PodName() = %q", PodName("shop")) } }