Skip to content
This repository was archived by the owner on Dec 13, 2018. It is now read-only.

Commit 206b5e6

Browse files
bouchercrosbymichael
authored andcommitted
First attempt at an integration test for checkpoint/restore.
Adds iptables as a requirement of criu in the Dockerfile. Docker-DCO-1.1-Signed-off-by: Ross Boucher <[email protected]> (github: boucher)
1 parent b3ec1fc commit 206b5e6

File tree

3 files changed

+165
-1
lines changed

3 files changed

+165
-1
lines changed

Diff for: Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
FROM golang:1.4
22

33
RUN echo "deb http://ftp.us.debian.org/debian testing main contrib" >> /etc/apt/sources.list
4-
RUN apt-get update && apt-get install -y criu=1.5.2-1 && rm -rf /var/lib/apt/lists/*
4+
RUN apt-get update && apt-get install -y iptables criu=1.5.2-1 && rm -rf /var/lib/apt/lists/*
55

66
RUN go get golang.org/x/tools/cmd/cover
77

Diff for: factory_linux.go

+1
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ func New(root string, options ...func(*LinuxFactory) error) (Factory, error) {
106106
l := &LinuxFactory{
107107
Root: root,
108108
Validator: validate.New(),
109+
CriuPath: "criu",
109110
}
110111
InitArgs(os.Args[0], "init")(l)
111112
Cgroupfs(l)

Diff for: integration/checkpoint_test.go

+163
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
package integration
2+
3+
import (
4+
"bytes"
5+
"io/ioutil"
6+
"os"
7+
"strings"
8+
"testing"
9+
10+
"github.com/docker/libcontainer"
11+
)
12+
13+
func TestCheckpoint(t *testing.T) {
14+
if testing.Short() {
15+
return
16+
}
17+
root, err := newTestRoot()
18+
if err != nil {
19+
t.Fatal(err)
20+
}
21+
defer os.RemoveAll(root)
22+
23+
rootfs, err := newRootfs()
24+
if err != nil {
25+
t.Fatal(err)
26+
}
27+
defer remove(rootfs)
28+
29+
config := newTemplateConfig(rootfs)
30+
31+
factory, err := libcontainer.New(root, libcontainer.Cgroupfs)
32+
33+
if err != nil {
34+
t.Fatal(err)
35+
}
36+
37+
container, err := factory.Create("test", config)
38+
if err != nil {
39+
t.Fatal(err)
40+
}
41+
defer container.Destroy()
42+
43+
stdinR, stdinW, err := os.Pipe()
44+
if err != nil {
45+
t.Fatal(err)
46+
}
47+
48+
var stdout bytes.Buffer
49+
50+
pconfig := libcontainer.Process{
51+
Args: []string{"cat"},
52+
Env: standardEnvironment,
53+
Stdin: stdinR,
54+
Stdout: &stdout,
55+
}
56+
57+
err = container.Start(&pconfig)
58+
stdinR.Close()
59+
defer stdinW.Close()
60+
if err != nil {
61+
t.Fatal(err)
62+
}
63+
64+
pid, err := pconfig.Pid()
65+
if err != nil {
66+
t.Fatal(err)
67+
}
68+
69+
process, err := os.FindProcess(pid)
70+
if err != nil {
71+
t.Fatal(err)
72+
}
73+
74+
imagesDir, err := ioutil.TempDir("", "criu")
75+
if err != nil {
76+
t.Fatal(err)
77+
}
78+
defer os.RemoveAll(imagesDir)
79+
80+
checkpointOpts := &libcontainer.CriuOpts{
81+
ImagesDirectory: imagesDir,
82+
WorkDirectory: imagesDir,
83+
}
84+
85+
if err := container.Checkpoint(checkpointOpts); err != nil {
86+
t.Fatal(err)
87+
}
88+
89+
state, err := container.Status()
90+
if err != nil {
91+
t.Fatal(err)
92+
}
93+
94+
if state != libcontainer.Checkpointed {
95+
t.Fatal("Unexpected state: ", state)
96+
}
97+
98+
stdinW.Close()
99+
_, err = process.Wait()
100+
if err != nil {
101+
t.Fatal(err)
102+
}
103+
104+
// reload the container
105+
container, err = factory.Load("test")
106+
if err != nil {
107+
t.Fatal(err)
108+
}
109+
110+
restoreStdinR, restoreStdinW, err := os.Pipe()
111+
if err != nil {
112+
t.Fatal(err)
113+
}
114+
115+
restoreProcessConfig := &libcontainer.Process{
116+
Stdin: restoreStdinR,
117+
Stdout: &stdout,
118+
}
119+
120+
err = container.Restore(restoreProcessConfig, &libcontainer.CriuOpts{
121+
ImagesDirectory: imagesDir,
122+
})
123+
restoreStdinR.Close()
124+
defer restoreStdinW.Close()
125+
126+
state, err = container.Status()
127+
if err != nil {
128+
t.Fatal(err)
129+
}
130+
if state != libcontainer.Running {
131+
t.Fatal("Unexpected state: ", state)
132+
}
133+
134+
pid, err = restoreProcessConfig.Pid()
135+
if err != nil {
136+
t.Fatal(err)
137+
}
138+
139+
process, err = os.FindProcess(pid)
140+
if err != nil {
141+
t.Fatal(err)
142+
}
143+
144+
_, err = restoreStdinW.WriteString("Hello!")
145+
if err != nil {
146+
t.Fatal(err)
147+
}
148+
149+
restoreStdinW.Close()
150+
s, err := process.Wait()
151+
if err != nil {
152+
t.Fatal(err)
153+
}
154+
155+
if !s.Success() {
156+
t.Fatal(s.String(), pid)
157+
}
158+
159+
output := string(stdout.Bytes())
160+
if !strings.Contains(output, "Hello!") {
161+
t.Fatal("Did not restore the pipe correctly:", output)
162+
}
163+
}

0 commit comments

Comments
 (0)