返回 DeepSeek-Reasonix
process_windows_test.go
根目录 / internal / extension / sidecar / process_windows_test.go
1 //go:build windows
2
3 package sidecar
4
5 import (
6 "errors"
7 "sync"
8 "testing"
9
10 "golang.org/x/sys/windows"
11
12 "reasonix/internal/proc"
13 )
14
15 func TestReleasedJobHandleIsNeverClosedAgain(t *testing.T) {
16 for _, first := range []string{"kill", "finish"} {
17 t.Run(first, func(t *testing.T) {
18 cmd := proc.Command("cmd", "/c", "exit", "0")
19 if err := cmd.Run(); err != nil {
20 t.Fatal(err)
21 }
22 job, err := windows.CreateJobObject(nil, nil)
23 if err != nil {
24 t.Fatal(err)
25 }
26 p := &process{cmd: cmd, job: uintptr(job)}
27 if first == "kill" {
28 p.kill()
29 } else {
30 p.finishJob()
31 }
32 if err := windows.SetHandleInformation(job, 0, 0); !errors.Is(err, windows.ERROR_INVALID_HANDLE) {
33 t.Fatalf("completed cleanup did not invalidate the Job Object: %v", err)
34 }
35 event, err := windows.CreateEvent(nil, 0, 0, nil)
36 if err != nil {
37 t.Fatal(err)
38 }
39 defer windows.CloseHandle(event)
40 // Model Windows reusing the stale handle for an unrelated object;
41 // choosing its value explicitly avoids depending on allocator timing.
42 p.job = uintptr(event)
43 var calls sync.WaitGroup
44 for range 8 {
45 calls.Go(p.kill)
46 calls.Go(p.finishJob)
47 }
48 calls.Wait()
49 if err := windows.SetEvent(event); err != nil {
50 t.Fatalf("cleanup closed an unrelated reused handle: %v", err)
51 }
52 })
53 }
54 }
55
55 lines GO