Skip to content

Commit 3e5c199

Browse files
odinugekolyshkin
andcommitted
libct/cg/sd: Add freezer tests
This test the issues fixed by the two preceding commits. Co-Authored-By: Kir Kolyshkin <[email protected]> Signed-off-by: Odin Ugedal <[email protected]> Signed-off-by: Kir Kolyshkin <[email protected]>
1 parent 294c486 commit 3e5c199

File tree

1 file changed

+141
-0
lines changed

1 file changed

+141
-0
lines changed

libcontainer/cgroups/systemd/systemd_test.go

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package systemd
22

33
import (
4+
"bufio"
45
"bytes"
56
"os"
67
"os/exec"
@@ -193,3 +194,143 @@ func TestUnitExistsIgnored(t *testing.T) {
193194
}
194195
}
195196
}
197+
198+
func TestFreezePodCgroup(t *testing.T) {
199+
if !IsRunningSystemd() {
200+
t.Skip("Test requires systemd.")
201+
}
202+
if os.Geteuid() != 0 {
203+
t.Skip("Test requires root.")
204+
}
205+
206+
podConfig := &configs.Cgroup{
207+
Parent: "system.slice",
208+
Name: "system-runc_test_pod.slice",
209+
Resources: &configs.Resources{
210+
SkipDevices: true,
211+
Freezer: configs.Frozen,
212+
},
213+
}
214+
// Create a "pod" cgroup (a systemd slice to hold containers),
215+
// which is frozen initially.
216+
pm := newManager(podConfig)
217+
defer pm.Destroy() //nolint:errcheck
218+
if err := pm.Apply(-1); err != nil {
219+
t.Fatal(err)
220+
}
221+
222+
if err := pm.Freeze(configs.Frozen); err != nil {
223+
t.Fatal(err)
224+
}
225+
if err := pm.Set(podConfig.Resources); err != nil {
226+
t.Fatal(err)
227+
}
228+
229+
// Check the pod is frozen.
230+
pf, err := pm.GetFreezerState()
231+
if err != nil {
232+
t.Fatal(err)
233+
}
234+
if pf != configs.Frozen {
235+
t.Fatalf("expected pod to be frozen, got %v", pf)
236+
}
237+
238+
// Create a "container" within the "pod" cgroup.
239+
// This is not a real container, just a process in the cgroup.
240+
containerConfig := &configs.Cgroup{
241+
Parent: "system-runc_test_pod.slice",
242+
ScopePrefix: "test",
243+
Name: "inner-contianer",
244+
Resources: &configs.Resources{},
245+
}
246+
247+
cmd := exec.Command("bash", "-c", "while read; do echo $REPLY; done")
248+
cmd.Env = append(os.Environ(), "LANG=C")
249+
250+
// Setup stdin.
251+
stdinR, stdinW, err := os.Pipe()
252+
if err != nil {
253+
t.Fatal(err)
254+
}
255+
cmd.Stdin = stdinR
256+
257+
// Setup stdout.
258+
stdoutR, stdoutW, err := os.Pipe()
259+
if err != nil {
260+
t.Fatal(err)
261+
}
262+
cmd.Stdout = stdoutW
263+
rdr := bufio.NewReader(stdoutR)
264+
265+
// Setup stderr.
266+
var stderr bytes.Buffer
267+
cmd.Stderr = &stderr
268+
269+
err = cmd.Start()
270+
stdinR.Close()
271+
stdoutW.Close()
272+
defer func() {
273+
_ = stdinW.Close()
274+
_ = stdoutR.Close()
275+
}()
276+
if err != nil {
277+
t.Fatal(err)
278+
}
279+
// Make sure to not leave a zombie.
280+
defer func() {
281+
// These may fail, we don't care.
282+
_ = cmd.Process.Kill()
283+
_ = cmd.Wait()
284+
}()
285+
286+
// Put the process into a cgroup.
287+
cm := newManager(containerConfig)
288+
defer cm.Destroy() //nolint:errcheck
289+
290+
if err := cm.Apply(cmd.Process.Pid); err != nil {
291+
t.Fatal(err)
292+
}
293+
if err := cm.Set(containerConfig.Resources); err != nil {
294+
t.Fatal(err)
295+
}
296+
// Check that we put the "container" into the "pod" cgroup.
297+
if !strings.HasPrefix(cm.Path("freezer"), pm.Path("freezer")) {
298+
t.Fatalf("expected container cgroup path %q to be under pod cgroup path %q",
299+
cm.Path("freezer"), pm.Path("freezer"))
300+
}
301+
// Check the container is not reported as frozen despite the frozen parent.
302+
cf, err := cm.GetFreezerState()
303+
if err != nil {
304+
t.Fatal(err)
305+
}
306+
if cf != configs.Thawed {
307+
t.Fatalf("expected container to be thawed, got %v", cf)
308+
}
309+
310+
// Unfreeze the pod.
311+
if err := pm.Freeze(configs.Thawed); err != nil {
312+
t.Fatal(err)
313+
}
314+
315+
cf, err = cm.GetFreezerState()
316+
if err != nil {
317+
t.Fatal(err)
318+
}
319+
if cf != configs.Thawed {
320+
t.Fatalf("expected container to be thawed, got %v", cf)
321+
}
322+
323+
// Check the "container" works.
324+
marker := "one two\n"
325+
_, err = stdinW.WriteString(marker)
326+
if err != nil {
327+
t.Fatal(err)
328+
}
329+
reply, err := rdr.ReadString('\n')
330+
if err != nil {
331+
t.Fatalf("reading from container: %v", err)
332+
}
333+
if reply != marker {
334+
t.Fatalf("expected %q, got %q", marker, reply)
335+
}
336+
}

0 commit comments

Comments
 (0)