forked from shenwei356/rush
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprocess_linux_test.go
More file actions
128 lines (116 loc) · 3.22 KB
/
Copy pathprocess_linux_test.go
File metadata and controls
128 lines (116 loc) · 3.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//go:build linux
package process
import (
"os"
"os/exec"
"strconv"
"sync"
"testing"
"time"
)
func TestProcessInspectionDoesNotNeedExternalCommands(t *testing.T) {
if os.Getenv("RUSH_PROCESS_TEST_HELPER") == "1" {
time.Sleep(30 * time.Second)
return
}
oldMarker := ChildMarker
oldPidRecords := pidRecords
ChildMarker = "test_" + strconv.Itoa(os.Getpid())
pidRecords = make(map[int]ProcessRecord)
t.Cleanup(func() {
ChildMarker = oldMarker
pidRecords = oldPidRecords
})
cmd := exec.Command(os.Args[0], "-test.run=^TestProcessInspectionDoesNotNeedExternalCommands$")
cmd.Env = append(os.Environ(),
"RUSH_PROCESS_TEST_HELPER=1",
getChildMarkerKey()+"="+getChildMarkerValue(),
)
if err := cmd.Start(); err != nil {
t.Fatal(err)
}
t.Cleanup(func() {
cmd.Process.Kill()
cmd.Wait()
})
t.Setenv("PATH", "")
records := getChildProcesses(&sync.Mutex{}, nil, nil)
for _, record := range records {
if record.pid == cmd.Process.Pid {
return
}
}
t.Fatalf("marked child process %d was not found without ps, kill, sh, or xargs in PATH", cmd.Process.Pid)
}
func TestReleaseProcessesClearsRecords(t *testing.T) {
oldPidRecords := pidRecords
pidRecords = map[int]ProcessRecord{
12345: {pid: 12345, processHandle: 12345},
}
t.Cleanup(func() {
pidRecords = oldPidRecords
})
releaseProcesses(&sync.Mutex{})
if len(pidRecords) != 0 {
t.Fatalf("process records were not released: %v", pidRecords)
}
}
func TestSignalSelectionHonorsExclusions(t *testing.T) {
tests := []struct {
name string
noStopExes []string
noKillExes []string
want int
}{
{name: "stop and kill", want: SEND_CTRL_C_SIGNAL | SEND_KILL_SIGNAL},
{name: "skip graceful stop by name", noStopExes: []string{"worker"}, want: SEND_KILL_SIGNAL},
{name: "skip graceful stop for all", noStopExes: []string{"all"}, want: SEND_KILL_SIGNAL},
{name: "skip force kill by name", noKillExes: []string{"worker"}, want: SEND_CTRL_C_SIGNAL},
{name: "skip every signal", noStopExes: []string{"all"}, noKillExes: []string{"all"}, want: SEND_NO_SIGNAL},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := getSignalsToSend("worker", tt.noStopExes, tt.noKillExes)
if err != nil {
t.Fatal(err)
}
if got != tt.want {
t.Fatalf("signals: %d; want %d", got, tt.want)
}
})
}
}
func TestContainsMarkerMatchesExactAndNestedValues(t *testing.T) {
oldMarker := ChildMarker
ChildMarker = "123_ab"
t.Cleanup(func() {
ChildMarker = oldMarker
})
tests := []struct {
name string
env string
want bool
}{
{name: "exact", env: "A=1\x00RUSH_CHILD_GROUP=[123_ab]\x00", want: true},
{name: "nested", env: "RUSH_CHILD_GROUP=[parent_1][123_ab]", want: true},
{name: "different marker", env: "RUSH_CHILD_GROUP=[123_abc]", want: false},
{name: "different variable", env: "OTHER=[123_ab]", want: false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := containsMarker(tt.env); got != tt.want {
t.Fatalf("containsMarker(%q): %t; want %t", tt.env, got, tt.want)
}
})
}
}
func TestForceStopIsIdempotent(t *testing.T) {
opts := &Options{}
opts.ForceStop()
opts.ForceStop()
select {
case <-opts.forceStopChannel():
default:
t.Fatal("force-stop channel is not closed")
}
}