1
16
17 package v2
18
19 import (
20 "fmt"
21 "os"
22 "os/exec"
23 "testing"
24 "time"
25
26 "github.com/opencontainers/runtime-spec/specs-go"
27 "github.com/stretchr/testify/assert"
28 "go.uber.org/goleak"
29 )
30
31 func TestEventChanCleanupOnCgroupRemoval(t *testing.T) {
32 checkCgroupMode(t)
33
34 cmd := exec.Command("cat")
35 stdin, err := cmd.StdinPipe()
36 if err != nil {
37 t.Fatalf("Failed to create cat process: %v", err)
38 }
39 if err := cmd.Start(); err != nil {
40 t.Fatalf("Failed to start cat process: %v", err)
41 }
42 proc := cmd.Process
43 if proc == nil {
44 t.Fatal("Process is nil")
45 }
46
47 group := fmt.Sprintf("testing-watcher-%d.scope", proc.Pid)
48 c, err := NewSystemd("", group, proc.Pid, &Resources{})
49 if err != nil {
50 t.Fatalf("Failed to init new cgroup manager: %v", err)
51 }
52
53 evCh, errCh := c.EventChan()
54
55
56 time.Sleep(500 * time.Millisecond)
57
58 if err := stdin.Close(); err != nil {
59 t.Fatalf("Failed closing stdin: %v", err)
60 }
61 if err := cmd.Wait(); err != nil {
62 t.Fatalf("Failed waiting for cmd: %v", err)
63 }
64
65 done := false
66 for !done {
67 select {
68 case <-evCh:
69 case err := <-errCh:
70 if err != nil {
71 t.Fatalf("Unexpected error on error channel: %v", err)
72 }
73 done = true
74 case <-time.After(5 * time.Second):
75 t.Fatal("Timed out")
76 }
77 }
78 goleak.VerifyNone(t)
79 }
80
81 func TestSystemdFullPath(t *testing.T) {
82 tests := []struct {
83 inputSlice string
84 inputGroup string
85 expectedOut string
86 }{
87 {
88 inputSlice: "user.slice",
89 inputGroup: "myGroup.slice",
90 expectedOut: "/sys/fs/cgroup/user.slice/myGroup.slice",
91 },
92 {
93 inputSlice: "/",
94 inputGroup: "myGroup.slice",
95 expectedOut: "/sys/fs/cgroup/myGroup.slice",
96 },
97 {
98 inputSlice: "system.slice",
99 inputGroup: "myGroup.slice",
100 expectedOut: "/sys/fs/cgroup/system.slice/myGroup.slice",
101 },
102 {
103 inputSlice: "user.slice",
104 inputGroup: "my-group.slice",
105 expectedOut: "/sys/fs/cgroup/user.slice/my.slice/my-group.slice",
106 },
107 {
108 inputSlice: "user.slice",
109 inputGroup: "my-group-more-dashes.slice",
110 expectedOut: "/sys/fs/cgroup/user.slice/my.slice/my-group.slice/my-group-more.slice/my-group-more-dashes.slice",
111 },
112 {
113 inputSlice: "user.slice",
114 inputGroup: "my-group-dashes.slice",
115 expectedOut: "/sys/fs/cgroup/user.slice/my.slice/my-group.slice/my-group-dashes.slice",
116 },
117 {
118 inputSlice: "user.slice",
119 inputGroup: "myGroup.scope",
120 expectedOut: "/sys/fs/cgroup/user.slice/myGroup.scope",
121 },
122 {
123 inputSlice: "user.slice",
124 inputGroup: "my-group-dashes.scope",
125 expectedOut: "/sys/fs/cgroup/user.slice/my-group-dashes.scope",
126 },
127 {
128 inputSlice: "test-waldo.slice",
129 inputGroup: "my-group.slice",
130 expectedOut: "/sys/fs/cgroup/test.slice/test-waldo.slice/my.slice/my-group.slice",
131 },
132 {
133 inputSlice: "test-waldo.slice",
134 inputGroup: "my.service",
135 expectedOut: "/sys/fs/cgroup/test.slice/test-waldo.slice/my.service",
136 },
137 }
138
139 for _, test := range tests {
140 actual := getSystemdFullPath(test.inputSlice, test.inputGroup)
141 assert.Equal(t, test.expectedOut, actual)
142 }
143 }
144
145 func TestMoveTo(t *testing.T) {
146 checkCgroupMode(t)
147 manager, err := NewManager(defaultCgroup2Path, "/test1", ToResources(&specs.LinuxResources{}))
148 if err != nil {
149 t.Error(err)
150 return
151 }
152 proc := os.Getpid()
153 if err := manager.AddProc(uint64(proc)); err != nil {
154 t.Error(err)
155 return
156 }
157 destination, err := NewManager(defaultCgroup2Path, "/test2", ToResources(&specs.LinuxResources{}))
158 if err != nil {
159 t.Error(err)
160 return
161 }
162 if err := manager.MoveTo(destination); err != nil {
163 t.Error(err)
164 return
165 }
166 desProcs, err := destination.Procs(true)
167 desMap := make(map[int]bool)
168 for _, p := range desProcs {
169 desMap[int(p)] = true
170 }
171 if !desMap[proc] {
172 t.Errorf("process %v not in destination cgroup", proc)
173 return
174 }
175 }
176
View as plain text