mirror of
https://github.com/containers/podman.git
synced 2025-06-17 06:57:43 +08:00
tests: add checkpoint/restore test
Signed-off-by: Adrian Reber <areber@redhat.com>
This commit is contained in:

committed by
Adrian Reber

parent
5bafafc7eb
commit
5246238e7e
12
Dockerfile
12
Dockerfile
@ -18,6 +18,8 @@ RUN apt-get update && apt-get install -y \
|
|||||||
libaio-dev \
|
libaio-dev \
|
||||||
libcap-dev \
|
libcap-dev \
|
||||||
libfuse-dev \
|
libfuse-dev \
|
||||||
|
libnet-dev \
|
||||||
|
libnl-3-dev \
|
||||||
libostree-dev \
|
libostree-dev \
|
||||||
libprotobuf-dev \
|
libprotobuf-dev \
|
||||||
libprotobuf-c0-dev \
|
libprotobuf-c0-dev \
|
||||||
@ -110,6 +112,16 @@ RUN set -x \
|
|||||||
&& go get -u github.com/mailru/easyjson/... \
|
&& go get -u github.com/mailru/easyjson/... \
|
||||||
&& install -D -m 755 "$GOPATH"/bin/easyjson /usr/bin/
|
&& install -D -m 755 "$GOPATH"/bin/easyjson /usr/bin/
|
||||||
|
|
||||||
|
# Install criu
|
||||||
|
ENV CRIU_COMMIT 584cbe4643c3fc7dc901ff08bf923ca0fe7326f9
|
||||||
|
RUN set -x \
|
||||||
|
&& cd /tmp \
|
||||||
|
&& git clone https://github.com/checkpoint-restore/criu.git \
|
||||||
|
&& cd criu \
|
||||||
|
&& make \
|
||||||
|
&& install -D -m 755 criu/criu /usr/sbin/ \
|
||||||
|
&& rm -rf /tmp/criu
|
||||||
|
|
||||||
# Install cni config
|
# Install cni config
|
||||||
#RUN make install.cni
|
#RUN make install.cni
|
||||||
RUN mkdir -p /etc/cni/net.d/
|
RUN mkdir -p /etc/cni/net.d/
|
||||||
|
129
test/e2e/checkpoint_test.go
Normal file
129
test/e2e/checkpoint_test.go
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Podman checkpoint", func() {
|
||||||
|
var (
|
||||||
|
tempdir string
|
||||||
|
err error
|
||||||
|
podmanTest PodmanTest
|
||||||
|
)
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
tempdir, err = CreateTempDirInTempDir()
|
||||||
|
if err != nil {
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
podmanTest = PodmanCreate(tempdir)
|
||||||
|
podmanTest.RestoreAllArtifacts()
|
||||||
|
// At least CRIU 3.11 is needed
|
||||||
|
skip, err := podmanTest.isCriuAtLeast(31100)
|
||||||
|
if err != nil || skip {
|
||||||
|
Skip("CRIU missing or too old.")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
AfterEach(func() {
|
||||||
|
podmanTest.Cleanup()
|
||||||
|
f := CurrentGinkgoTestDescription()
|
||||||
|
timedResult := fmt.Sprintf("Test: %s completed in %f seconds", f.TestText, f.Duration.Seconds())
|
||||||
|
GinkgoWriter.Write([]byte(timedResult))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("podman checkpoint bogus container", func() {
|
||||||
|
session := podmanTest.Podman([]string{"container", "checkpoint", "foobar"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Not(Equal(0)))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("podman restore bogus container", func() {
|
||||||
|
session := podmanTest.Podman([]string{"container", "restore", "foobar"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Not(Equal(0)))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("podman checkpoint a running container by id", func() {
|
||||||
|
// CRIU does not work with seccomp correctly on RHEL7
|
||||||
|
session := podmanTest.Podman([]string{"run", "-it", "--security-opt", "seccomp=unconfined", "-d", ALPINE, "top"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
cid := session.OutputToString()
|
||||||
|
|
||||||
|
result := podmanTest.Podman([]string{"container", "checkpoint", cid})
|
||||||
|
result.WaitWithDefaultTimeout()
|
||||||
|
|
||||||
|
Expect(result.ExitCode()).To(Equal(0))
|
||||||
|
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
|
||||||
|
Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited"))
|
||||||
|
|
||||||
|
result = podmanTest.Podman([]string{"container", "restore", cid})
|
||||||
|
result.WaitWithDefaultTimeout()
|
||||||
|
|
||||||
|
Expect(result.ExitCode()).To(Equal(0))
|
||||||
|
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
|
||||||
|
Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up"))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("podman checkpoint a running container by name", func() {
|
||||||
|
session := podmanTest.Podman([]string{"run", "-it", "--security-opt", "seccomp=unconfined", "--name", "test_name", "-d", ALPINE, "top"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
|
||||||
|
result := podmanTest.Podman([]string{"container", "checkpoint", "test_name"})
|
||||||
|
result.WaitWithDefaultTimeout()
|
||||||
|
|
||||||
|
Expect(result.ExitCode()).To(Equal(0))
|
||||||
|
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
|
||||||
|
Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited"))
|
||||||
|
|
||||||
|
result = podmanTest.Podman([]string{"container", "restore", "test_name"})
|
||||||
|
result.WaitWithDefaultTimeout()
|
||||||
|
|
||||||
|
Expect(result.ExitCode()).To(Equal(0))
|
||||||
|
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
|
||||||
|
Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up"))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("podman pause a checkpointed container by id", func() {
|
||||||
|
session := podmanTest.Podman([]string{"run", "-it", "--security-opt", "seccomp=unconfined", "-d", ALPINE, "top"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
cid := session.OutputToString()
|
||||||
|
|
||||||
|
result := podmanTest.Podman([]string{"container", "checkpoint", cid})
|
||||||
|
result.WaitWithDefaultTimeout()
|
||||||
|
|
||||||
|
Expect(result.ExitCode()).To(Equal(0))
|
||||||
|
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
|
||||||
|
Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited"))
|
||||||
|
|
||||||
|
result = podmanTest.Podman([]string{"pause", cid})
|
||||||
|
result.WaitWithDefaultTimeout()
|
||||||
|
|
||||||
|
Expect(result.ExitCode()).To(Equal(125))
|
||||||
|
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
|
||||||
|
Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited"))
|
||||||
|
|
||||||
|
result = podmanTest.Podman([]string{"container", "restore", cid})
|
||||||
|
result.WaitWithDefaultTimeout()
|
||||||
|
Expect(result.ExitCode()).To(Equal(0))
|
||||||
|
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
|
||||||
|
|
||||||
|
result = podmanTest.Podman([]string{"rm", cid})
|
||||||
|
result.WaitWithDefaultTimeout()
|
||||||
|
Expect(result.ExitCode()).To(Equal(125))
|
||||||
|
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
|
||||||
|
|
||||||
|
result = podmanTest.Podman([]string{"rm", "-f", cid})
|
||||||
|
result.WaitWithDefaultTimeout()
|
||||||
|
Expect(result.ExitCode()).To(Equal(0))
|
||||||
|
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
|
||||||
|
|
||||||
|
})
|
||||||
|
})
|
@ -2,6 +2,7 @@ package integration
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -64,6 +65,7 @@ type PodmanTest struct {
|
|||||||
TempDir string
|
TempDir string
|
||||||
CgroupManager string
|
CgroupManager string
|
||||||
Host HostOS
|
Host HostOS
|
||||||
|
CriuBinary string
|
||||||
}
|
}
|
||||||
|
|
||||||
// HostOS is a simple struct for the test os
|
// HostOS is a simple struct for the test os
|
||||||
@ -164,6 +166,7 @@ func PodmanCreate(tempDir string) PodmanTest {
|
|||||||
runCBinary = "/usr/bin/runc"
|
runCBinary = "/usr/bin/runc"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
criuBinary := "/usr/sbin/criu"
|
||||||
CNIConfigDir := "/etc/cni/net.d"
|
CNIConfigDir := "/etc/cni/net.d"
|
||||||
|
|
||||||
p := PodmanTest{
|
p := PodmanTest{
|
||||||
@ -179,6 +182,7 @@ func PodmanCreate(tempDir string) PodmanTest {
|
|||||||
TempDir: tempDir,
|
TempDir: tempDir,
|
||||||
CgroupManager: cgroupManager,
|
CgroupManager: cgroupManager,
|
||||||
Host: host,
|
Host: host,
|
||||||
|
CriuBinary: criuBinary,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup registries.conf ENV variable
|
// Setup registries.conf ENV variable
|
||||||
@ -678,6 +682,39 @@ func (p *PodmanTest) setRegistriesConfigEnv(b []byte) {
|
|||||||
ioutil.WriteFile(outfile, b, 0644)
|
ioutil.WriteFile(outfile, b, 0644)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *PodmanTest) isCriuAtLeast(version int) (bool, error) {
|
||||||
|
cmd := exec.Command(p.CriuBinary, "-V")
|
||||||
|
var out bytes.Buffer
|
||||||
|
cmd.Stdout = &out
|
||||||
|
err := cmd.Run()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var x int
|
||||||
|
var y int
|
||||||
|
var z int
|
||||||
|
|
||||||
|
fmt.Sscanf(out.String(), "Version: %d.%d.%d", &x, &y, &z)
|
||||||
|
|
||||||
|
if strings.Contains(out.String(), "GitID") {
|
||||||
|
// If CRIU is built from git it contains a git ID.
|
||||||
|
// If that is the case, increase minor by one as this
|
||||||
|
// could mean we are running a development version.
|
||||||
|
y = y + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
parsed_version := x*10000 + y*100 + z
|
||||||
|
|
||||||
|
fmt.Println(parsed_version)
|
||||||
|
|
||||||
|
if parsed_version >= version {
|
||||||
|
return false, nil
|
||||||
|
} else {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func resetRegistriesConfigEnv() {
|
func resetRegistriesConfigEnv() {
|
||||||
os.Setenv("REGISTRIES_CONFIG_PATH", "")
|
os.Setenv("REGISTRIES_CONFIG_PATH", "")
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user