1 package systemd
2
3 import (
4 "os"
5 "os/exec"
6 "strings"
7 "testing"
8
9 "golang.org/x/sys/unix"
10
11 "github.com/opencontainers/runc/libcontainer/cgroups"
12 "github.com/opencontainers/runc/libcontainer/configs"
13 )
14
15 func TestFreezeBeforeSet(t *testing.T) {
16 requireV1(t)
17
18 testCases := []struct {
19 desc string
20
21 cg *configs.Cgroup
22 preFreeze bool
23
24
25 freeze0, thaw0 bool
26
27 freeze1, thaw1 bool
28 }{
29 {
30
31 desc: "slice,skip-devices",
32 cg: &configs.Cgroup{
33 Name: "system-runc_test_freeze_1.slice",
34 Parent: "system.slice",
35 Resources: &configs.Resources{
36 SkipDevices: true,
37 },
38 },
39
40 freeze0: false,
41 thaw0: false,
42 freeze1: false,
43 thaw1: false,
44 },
45 {
46
47
48
49 desc: "scope,skip-devices",
50 cg: &configs.Cgroup{
51 ScopePrefix: "test",
52 Name: "testFreeze2",
53 Parent: "system.slice",
54 Resources: &configs.Resources{
55 SkipDevices: true,
56 },
57 },
58
59 freeze0: false,
60 thaw0: false,
61 freeze1: false,
62 thaw1: false,
63 },
64 {
65
66 desc: "slice,will-freeze",
67 cg: &configs.Cgroup{
68 Name: "system-runc_test_freeze_3.slice",
69 Parent: "system.slice",
70 Resources: &configs.Resources{
71 Freezer: configs.Frozen,
72 },
73 },
74
75 freeze0: true,
76 thaw0: false,
77 freeze1: true,
78 thaw1: false,
79 },
80 {
81
82 desc: "slice,pre-frozen,will-freeze",
83 cg: &configs.Cgroup{
84 Name: "system-runc_test_freeze_4.slice",
85 Parent: "system.slice",
86 Resources: &configs.Resources{
87 Freezer: configs.Frozen,
88 },
89 },
90 preFreeze: true,
91
92 freeze0: true,
93 thaw0: false,
94 freeze1: false,
95 thaw1: false,
96 },
97 {
98
99 desc: "scope,pre-frozen,skip-devices",
100 cg: &configs.Cgroup{
101 ScopePrefix: "test",
102 Name: "testFreeze5",
103 Parent: "system.slice",
104 Resources: &configs.Resources{
105 SkipDevices: true,
106 },
107 },
108 preFreeze: true,
109
110 freeze0: false,
111 thaw0: false,
112 freeze1: false,
113 thaw1: false,
114 },
115 {
116
117 desc: "scope,pre-frozen",
118 cg: &configs.Cgroup{
119 ScopePrefix: "test",
120 Name: "testFreeze6",
121 Parent: "system.slice",
122 Resources: &configs.Resources{},
123 },
124 preFreeze: true,
125
126 freeze0: true,
127 thaw0: true,
128 freeze1: false,
129 thaw1: false,
130 },
131 }
132
133 for _, tc := range testCases {
134 tc := tc
135 t.Run(tc.desc, func(t *testing.T) {
136 m, err := NewLegacyManager(tc.cg, nil)
137 if err != nil {
138 t.Fatal(err)
139 }
140 defer m.Destroy()
141 lm := m.(*legacyManager)
142
143
144 freeze, thaw, err := lm.freezeBeforeSet(getUnitName(tc.cg), tc.cg.Resources)
145 if err != nil {
146 t.Fatal(err)
147 }
148 if freeze != tc.freeze0 || thaw != tc.thaw0 {
149 t.Errorf("before Apply (non-existent unit): expected freeze: %v, thaw: %v, got freeze: %v, thaw: %v",
150 tc.freeze0, tc.thaw0, freeze, thaw)
151 }
152
153
154 pid := -1
155 if strings.HasSuffix(getUnitName(tc.cg), ".scope") {
156
157 cmd := exec.Command("bash", "-c", "sleep 1m")
158 if err := cmd.Start(); err != nil {
159 t.Fatal(err)
160 }
161 pid = cmd.Process.Pid
162
163 defer func() {
164
165 _ = cmd.Process.Kill()
166 _ = cmd.Wait()
167 }()
168 }
169 if err := m.Apply(pid); err != nil {
170 t.Fatal(err)
171 }
172 if tc.preFreeze {
173 if err := m.Freeze(configs.Frozen); err != nil {
174 t.Error(err)
175 return
176 }
177 }
178 freeze, thaw, err = lm.freezeBeforeSet(getUnitName(tc.cg), tc.cg.Resources)
179 if err != nil {
180 t.Error(err)
181 return
182 }
183 if freeze != tc.freeze1 || thaw != tc.thaw1 {
184 t.Errorf("expected freeze: %v, thaw: %v, got freeze: %v, thaw: %v",
185 tc.freeze1, tc.thaw1, freeze, thaw)
186 }
187
188 if tc.preFreeze {
189 if err := m.Freeze(configs.Thawed); err != nil {
190 t.Error(err)
191 }
192 }
193
194 if pid != -1 {
195 if err = unix.Kill(pid, unix.SIGKILL); err != nil {
196 t.Errorf("unable to kill pid %d: %s", pid, err)
197 }
198 }
199
200 if err := m.Destroy(); err != nil {
201 t.Errorf("destroy: %s", err)
202 }
203 })
204 }
205 }
206
207
208
209 func requireV1(t *testing.T) {
210 t.Helper()
211 if cgroups.IsCgroup2UnifiedMode() {
212 t.Skip("Test requires cgroup v1.")
213 }
214 if !IsRunningSystemd() {
215 t.Skip("Test requires systemd.")
216 }
217 if os.Geteuid() != 0 {
218 t.Skip("Test requires root.")
219 }
220 }
221
View as plain text