package runtime import ( "os" "path/filepath" "strconv" "testing" ) func TestParseProcExitCode(t *testing.T) { tests := []struct { name string statLine string wantCode int wantErr bool }{ { // Real /proc//stat line (simplified). Fields after ")" start with state. // The last field (field 52) is exit_code. name: "normal exit code 0", statLine: "123 (python3) S 1 123 123 0 -1 4194304 1000 0 0 0 100 50 0 0 20 0 1 0 1000 10000000 500 18446744073709551615 0 0 0 0 0 0 0 0 0 0 0 0 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0", wantCode: 0, }, { name: "non-zero exit code", statLine: "456 (bash) Z 1 456 456 0 -1 4194304 100 0 0 0 10 5 0 0 20 0 1 0 500 0 0 18446744073709551615 0 0 0 0 0 0 0 0 0 0 0 0 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 256", wantCode: 256, // signal 1 encoded as WaitStatus }, { // Process names can contain spaces and parentheses. // The parser must use LastIndex(")") to handle this correctly. name: "process name with spaces and parens", statLine: "789 (python3 -m vllm.entrypoints.openai.api_server (worker)) S 1 789 789 0 -1 0 0 0 0 0 0 0 0 0 20 0 1 0 100 0 0 0 0 0 0 0 0 0 0 0 0 0 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 42", wantCode: 42, }, { name: "malformed line no closing paren", statLine: "123 (python3 S 1 123", wantErr: true, }, { name: "empty string", statLine: "", wantErr: true, }, { name: "only pid and comm, nothing after paren", statLine: "1 (init)", wantErr: true, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { ws, err := ParseProcExitCode(tc.statLine) if tc.wantErr { if err == nil { t.Errorf("expected error, got WaitStatus=%d", ws) } return } if err != nil { t.Fatalf("unexpected error: %v", err) } if int(ws) != tc.wantCode { t.Errorf("exit code = %d, want %d", int(ws), tc.wantCode) } }) } } func TestReadProcessDetails(t *testing.T) { procRoot := t.TempDir() pid := 1018 procDir := filepath.Join(procRoot, "1018") if err := os.MkdirAll(procDir, 0755); err != nil { t.Fatalf("MkdirAll(%q): %v", procDir, err) } if err := os.WriteFile(filepath.Join(procDir, "status"), []byte("Name:\tpython3\nPPid:\t0\nNSpid:\t2402711 1018\n"), 0644); err != nil { t.Fatalf("WriteFile(status): %v", err) } if err := os.WriteFile(filepath.Join(procDir, "cmdline"), []byte("python3\x00-m\x00dynamo.vllm\x00"), 0644); err != nil { t.Fatalf("WriteFile(cmdline): %v", err) } details, err := ReadProcessDetails(procRoot, pid) if err != nil { t.Fatalf("ReadProcessDetails(%q, %d): %v", procRoot, pid, err) } if details.ObservedPID != 1018 { t.Fatalf("ObservedPID = %d, want 1018", details.ObservedPID) } if details.ParentPID != 0 { t.Fatalf("ParentPID = %d, want 0", details.ParentPID) } if details.OutermostPID != 2402711 { t.Fatalf("OutermostPID = %d, want 2402711", details.OutermostPID) } if details.InnermostPID != 1018 { t.Fatalf("InnermostPID = %d, want 1018", details.InnermostPID) } if len(details.NamespacePIDs) != 2 || details.NamespacePIDs[0] != 2402711 || details.NamespacePIDs[1] != 1018 { t.Fatalf("NamespacePIDs = %v, want [2402711 1018]", details.NamespacePIDs) } if details.Cmdline != "python3 -m dynamo.vllm" { t.Fatalf("Cmdline = %q, want %q", details.Cmdline, "python3 -m dynamo.vllm") } } func TestReadProcessDetailsOrDefault(t *testing.T) { details := ReadProcessDetailsOrDefault(t.TempDir(), 1234) if details.ObservedPID != 1234 { t.Fatalf("ObservedPID = %d, want 1234", details.ObservedPID) } if details.OutermostPID != 1234 { t.Fatalf("OutermostPID = %d, want 1234", details.OutermostPID) } if details.InnermostPID != 1234 { t.Fatalf("InnermostPID = %d, want 1234", details.InnermostPID) } if len(details.NamespacePIDs) != 1 || details.NamespacePIDs[0] != 1234 { t.Fatalf("NamespacePIDs = %v, want [1234]", details.NamespacePIDs) } } func TestReadProcessTable(t *testing.T) { procRoot := t.TempDir() writeEntry := func(pid int, status string, cmdline string) { t.Helper() procDir := filepath.Join(procRoot, strconv.Itoa(pid)) if err := os.MkdirAll(procDir, 0755); err != nil { t.Fatalf("MkdirAll(%q): %v", procDir, err) } if err := os.WriteFile(filepath.Join(procDir, "status"), []byte(status), 0644); err != nil { t.Fatalf("WriteFile(status): %v", err) } if err := os.WriteFile(filepath.Join(procDir, "cmdline"), []byte(cmdline), 0644); err != nil { t.Fatalf("WriteFile(cmdline): %v", err) } } writeEntry(768, "Name:\tworker\nPPid:\t1\nNSpid:\t2444000 768\n", "VLLM::Worker_TP0\x00") writeEntry(1, "Name:\tpython3\nPPid:\t0\nNSpid:\t2443990 1\n", "python3\x00-m\x00dynamo.vllm\x00") processes, err := ReadProcessTable(procRoot) if err != nil { t.Fatalf("ReadProcessTable(%q): %v", procRoot, err) } if len(processes) != 2 { t.Fatalf("len(ReadProcessTable(%q)) = %d, want 2", procRoot, len(processes)) } if processes[0].InnermostPID != 1 || processes[1].InnermostPID != 768 { t.Fatalf("process order innermost PIDs = [%d %d], want [1 768]", processes[0].InnermostPID, processes[1].InnermostPID) } } func TestResolveManifestPIDsToObservedPIDs(t *testing.T) { processes := []ProcessDetails{ {ObservedPID: 1, ParentPID: 0, OutermostPID: 1, InnermostPID: 1, NamespacePIDs: []int{1}, Cmdline: "sleep infinity"}, {ObservedPID: 50, ParentPID: 0, OutermostPID: 50, InnermostPID: 50, NamespacePIDs: []int{50}, Cmdline: "nsrestore"}, {ObservedPID: 74, ParentPID: 50, OutermostPID: 74, InnermostPID: 1, NamespacePIDs: []int{74, 1}, Cmdline: "python3 -m dynamo.vllm"}, {ObservedPID: 80, ParentPID: 74, OutermostPID: 80, InnermostPID: 750, NamespacePIDs: []int{80, 750}, Cmdline: "VLLM::EngineCore"}, {ObservedPID: 81, ParentPID: 74, OutermostPID: 81, InnermostPID: 749, NamespacePIDs: []int{81, 749}, Cmdline: "resource_tracker"}, } resolved, err := ResolveManifestPIDsToObservedPIDs(processes, 74, []int{1, 750}) if err != nil { t.Fatalf("ResolveManifestPIDsToObservedPIDs(...) returned error: %v", err) } if len(resolved) != 2 { t.Fatalf("len(resolved) = %d, want 2", len(resolved)) } if resolved[0] != 74 || resolved[1] != 80 { t.Fatalf("resolved PIDs = %v, want [74 80]", resolved) } } func TestResolveManifestPIDsToObservedPIDsFailsWhenManifestPIDMissingFromRestoredSubtree(t *testing.T) { processes := []ProcessDetails{ {ObservedPID: 1, ParentPID: 0, OutermostPID: 1, InnermostPID: 1, NamespacePIDs: []int{1}, Cmdline: "sleep infinity"}, {ObservedPID: 50, ParentPID: 0, OutermostPID: 50, InnermostPID: 50, NamespacePIDs: []int{50}, Cmdline: "nsrestore"}, {ObservedPID: 74, ParentPID: 50, OutermostPID: 74, InnermostPID: 1, NamespacePIDs: []int{74, 1}, Cmdline: "python3 -m dynamo.vllm"}, } _, err := ResolveManifestPIDsToObservedPIDs(processes, 74, []int{1, 750}) if err == nil { t.Fatal("ResolveManifestPIDsToObservedPIDs(...) unexpectedly succeeded") } } func TestResolveManifestPIDsToObservedPIDsFailsWhenNamespaceDepthIsNotTwo(t *testing.T) { processes := []ProcessDetails{ {ObservedPID: 50, ParentPID: 0, OutermostPID: 50, InnermostPID: 50, NamespacePIDs: []int{50}, Cmdline: "nsrestore"}, {ObservedPID: 74, ParentPID: 50, OutermostPID: 74, InnermostPID: 1, NamespacePIDs: []int{900, 74, 1}, Cmdline: "python3 -m dynamo.vllm"}, {ObservedPID: 80, ParentPID: 74, OutermostPID: 80, InnermostPID: 750, NamespacePIDs: []int{900, 80, 750}, Cmdline: "VLLM::EngineCore"}, } _, err := ResolveManifestPIDsToObservedPIDs(processes, 74, []int{1, 750}) if err == nil { t.Fatal("ResolveManifestPIDsToObservedPIDs(...) unexpectedly succeeded") } }