//go:build windows package runtime import ( "os" "os/exec" "path/filepath" "strconv" "testing" "golang.org/x/sys/windows" ) func TestConfigureManagedProcessCommandDetachesFromRunConsole(t *testing.T) { cmd := exec.Command("cmd.exe") configureManagedProcessCommand(cmd) if cmd.SysProcAttr == nil { t.Fatal("expected Windows process attributes") } if !cmd.SysProcAttr.HideWindow { t.Fatal("expected managed console window to stay hidden") } expected := uint32(windows.DETACHED_PROCESS | windows.CREATE_NEW_PROCESS_GROUP | windows.CREATE_BREAKAWAY_FROM_JOB) if cmd.SysProcAttr.CreationFlags != expected { t.Fatalf("expected a detached breakaway helper isolated from Ctrl+C, got %#x", cmd.SysProcAttr.CreationFlags) } } func TestWriteManagedProcessPIDUsesAtomicSidecar(t *testing.T) { path := filepath.Join(t.TempDir(), "process.stdout.log.pid") if err := writeManagedProcessPID(path, 321); err != nil { t.Fatalf("write managed process pid: %v", err) } body, err := os.ReadFile(path) if err != nil { t.Fatalf("read managed process pid: %v", err) } if got, err := strconv.Atoi(string(body[:len(body)-1])); err != nil || got != 321 { t.Fatalf("expected pid sidecar to contain 321, got %q err=%v", body, err) } if _, err := os.Stat(path + ".tmp"); !os.IsNotExist(err) { t.Fatalf("pid sidecar temp file should not remain, err=%v", err) } } func TestPrepareManagedProcessHelperExecutableCopiesRunOutsideCurrentPath(t *testing.T) { root := t.TempDir() current := filepath.Join(root, "run.exe") output := filepath.Join(root, "state", "process-output", "stdout.log") if err := os.WriteFile(current, []byte("run-binary"), 0o700); err != nil { t.Fatalf("write current executable: %v", err) } helper, err := prepareManagedProcessHelperExecutable(current, output) if err != nil { t.Fatalf("prepare helper executable: %v", err) } defer os.Remove(helper) if helper == current || filepath.Dir(helper) != filepath.Dir(output) { t.Fatalf("expected helper beside durable process output, helper=%q current=%q", helper, current) } body, err := os.ReadFile(helper) if err != nil { t.Fatalf("read helper executable: %v", err) } if string(body) != "run-binary" { t.Fatalf("expected helper to copy current executable, got %q", body) } }