mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #37394 from yongtang/07052018-ipcmode
Migrate some ipcmode tests to integration
This commit is contained in:
commit
aba2735e3f
2 changed files with 116 additions and 66 deletions
|
@ -46,72 +46,6 @@ func testIpcCheckDevExists(mm string) (bool, error) {
|
||||||
return false, s.Err()
|
return false, s.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
// testIpcNonePrivateShareable is a helper function to test "none",
|
|
||||||
// "private" and "shareable" modes.
|
|
||||||
func testIpcNonePrivateShareable(c *check.C, mode string, mustBeMounted bool, mustBeShared bool) {
|
|
||||||
cfg := container.Config{
|
|
||||||
Image: "busybox",
|
|
||||||
Cmd: []string{"top"},
|
|
||||||
}
|
|
||||||
hostCfg := container.HostConfig{
|
|
||||||
IpcMode: container.IpcMode(mode),
|
|
||||||
}
|
|
||||||
ctx := context.Background()
|
|
||||||
|
|
||||||
client := testEnv.APIClient()
|
|
||||||
|
|
||||||
resp, err := client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "")
|
|
||||||
c.Assert(err, checker.IsNil)
|
|
||||||
c.Assert(len(resp.Warnings), checker.Equals, 0)
|
|
||||||
|
|
||||||
err = client.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{})
|
|
||||||
c.Assert(err, checker.IsNil)
|
|
||||||
|
|
||||||
// get major:minor pair for /dev/shm from container's /proc/self/mountinfo
|
|
||||||
cmd := "awk '($5 == \"/dev/shm\") {printf $3}' /proc/self/mountinfo"
|
|
||||||
mm := cli.DockerCmd(c, "exec", "-i", resp.ID, "sh", "-c", cmd).Combined()
|
|
||||||
if !mustBeMounted {
|
|
||||||
c.Assert(mm, checker.Equals, "")
|
|
||||||
// no more checks to perform
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.Assert(mm, checker.Matches, "^[0-9]+:[0-9]+$")
|
|
||||||
|
|
||||||
shared, err := testIpcCheckDevExists(mm)
|
|
||||||
c.Assert(err, checker.IsNil)
|
|
||||||
c.Logf("[testIpcPrivateShareable] ipcmode: %v, ipcdev: %v, shared: %v, mustBeShared: %v\n", mode, mm, shared, mustBeShared)
|
|
||||||
c.Assert(shared, checker.Equals, mustBeShared)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TestAPIIpcModeNone checks the container "none" IPC mode
|
|
||||||
* (--ipc none) works as expected. It makes sure there is no
|
|
||||||
* /dev/shm mount inside the container.
|
|
||||||
*/
|
|
||||||
func (s *DockerSuite) TestAPIIpcModeNone(c *check.C) {
|
|
||||||
testRequires(c, DaemonIsLinux, MinimumAPIVersion("1.32"))
|
|
||||||
testIpcNonePrivateShareable(c, "none", false, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TestAPIIpcModePrivate checks the container private IPC mode
|
|
||||||
* (--ipc private) works as expected. It gets the minor:major pair
|
|
||||||
* of /dev/shm mount from the container, and makes sure there is no
|
|
||||||
* such pair on the host.
|
|
||||||
*/
|
|
||||||
func (s *DockerSuite) TestAPIIpcModePrivate(c *check.C) {
|
|
||||||
testRequires(c, DaemonIsLinux, SameHostDaemon)
|
|
||||||
testIpcNonePrivateShareable(c, "private", true, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TestAPIIpcModeShareable checks the container shareable IPC mode
|
|
||||||
* (--ipc shareable) works as expected. It gets the minor:major pair
|
|
||||||
* of /dev/shm mount from the container, and makes sure such pair
|
|
||||||
* also exists on the host.
|
|
||||||
*/
|
|
||||||
func (s *DockerSuite) TestAPIIpcModeShareable(c *check.C) {
|
|
||||||
testRequires(c, DaemonIsLinux, SameHostDaemon)
|
|
||||||
testIpcNonePrivateShareable(c, "shareable", true, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// testIpcContainer is a helper function to test --ipc container:NNN mode in various scenarios
|
// testIpcContainer is a helper function to test --ipc container:NNN mode in various scenarios
|
||||||
func testIpcContainer(s *DockerSuite, c *check.C, donorMode string, mustWork bool) {
|
func testIpcContainer(s *DockerSuite, c *check.C, donorMode string, mustWork bool) {
|
||||||
cfg := container.Config{
|
cfg := container.Config{
|
||||||
|
|
116
integration/container/ipcmode_test.go
Normal file
116
integration/container/ipcmode_test.go
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
package container // import "github.com/docker/docker/integration/container"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"context"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/docker/docker/api/types"
|
||||||
|
containertypes "github.com/docker/docker/api/types/container"
|
||||||
|
"github.com/docker/docker/integration/internal/container"
|
||||||
|
"github.com/docker/docker/internal/test/request"
|
||||||
|
"gotest.tools/assert"
|
||||||
|
is "gotest.tools/assert/cmp"
|
||||||
|
"gotest.tools/skip"
|
||||||
|
)
|
||||||
|
|
||||||
|
// testIpcCheckDevExists checks whether a given mount (identified by its
|
||||||
|
// major:minor pair from /proc/self/mountinfo) exists on the host system.
|
||||||
|
//
|
||||||
|
// The format of /proc/self/mountinfo is like:
|
||||||
|
//
|
||||||
|
// 29 23 0:24 / /dev/shm rw,nosuid,nodev shared:4 - tmpfs tmpfs rw
|
||||||
|
// ^^^^\
|
||||||
|
// - this is the minor:major we look for
|
||||||
|
func testIpcCheckDevExists(mm string) (bool, error) {
|
||||||
|
f, err := os.Open("/proc/self/mountinfo")
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
s := bufio.NewScanner(f)
|
||||||
|
for s.Scan() {
|
||||||
|
fields := strings.Fields(s.Text())
|
||||||
|
if len(fields) < 7 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if fields[2] == mm {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, s.Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
// testIpcNonePrivateShareable is a helper function to test "none",
|
||||||
|
// "private" and "shareable" modes.
|
||||||
|
func testIpcNonePrivateShareable(t *testing.T, mode string, mustBeMounted bool, mustBeShared bool) {
|
||||||
|
defer setupTest(t)()
|
||||||
|
|
||||||
|
cfg := containertypes.Config{
|
||||||
|
Image: "busybox",
|
||||||
|
Cmd: []string{"top"},
|
||||||
|
}
|
||||||
|
hostCfg := containertypes.HostConfig{
|
||||||
|
IpcMode: containertypes.IpcMode(mode),
|
||||||
|
}
|
||||||
|
client := request.NewAPIClient(t)
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
resp, err := client.ContainerCreate(ctx, &cfg, &hostCfg, nil, "")
|
||||||
|
assert.NilError(t, err)
|
||||||
|
assert.Check(t, is.Equal(len(resp.Warnings), 0))
|
||||||
|
|
||||||
|
err = client.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{})
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
// get major:minor pair for /dev/shm from container's /proc/self/mountinfo
|
||||||
|
cmd := "awk '($5 == \"/dev/shm\") {printf $3}' /proc/self/mountinfo"
|
||||||
|
result, err := container.Exec(ctx, client, resp.ID, []string{"sh", "-c", cmd})
|
||||||
|
assert.NilError(t, err)
|
||||||
|
mm := result.Combined()
|
||||||
|
if !mustBeMounted {
|
||||||
|
assert.Check(t, is.Equal(mm, ""))
|
||||||
|
// no more checks to perform
|
||||||
|
return
|
||||||
|
}
|
||||||
|
assert.Check(t, is.Equal(true, regexp.MustCompile("^[0-9]+:[0-9]+$").MatchString(mm)))
|
||||||
|
|
||||||
|
shared, err := testIpcCheckDevExists(mm)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
t.Logf("[testIpcPrivateShareable] ipcmode: %v, ipcdev: %v, shared: %v, mustBeShared: %v\n", mode, mm, shared, mustBeShared)
|
||||||
|
assert.Check(t, is.Equal(shared, mustBeShared))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestIpcModeNone checks the container "none" IPC mode
|
||||||
|
// (--ipc none) works as expected. It makes sure there is no
|
||||||
|
// /dev/shm mount inside the container.
|
||||||
|
func TestIpcModeNone(t *testing.T) {
|
||||||
|
skip.If(t, testEnv.DaemonInfo.OSType != "linux" || testEnv.IsRemoteDaemon())
|
||||||
|
|
||||||
|
testIpcNonePrivateShareable(t, "none", false, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestAPIIpcModePrivate checks the container private IPC mode
|
||||||
|
// (--ipc private) works as expected. It gets the minor:major pair
|
||||||
|
// of /dev/shm mount from the container, and makes sure there is no
|
||||||
|
// such pair on the host.
|
||||||
|
func TestIpcModePrivate(t *testing.T) {
|
||||||
|
skip.If(t, testEnv.DaemonInfo.OSType != "linux" || testEnv.IsRemoteDaemon())
|
||||||
|
|
||||||
|
testIpcNonePrivateShareable(t, "private", true, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestAPIIpcModeShareable checks the container shareable IPC mode
|
||||||
|
// (--ipc shareable) works as expected. It gets the minor:major pair
|
||||||
|
// of /dev/shm mount from the container, and makes sure such pair
|
||||||
|
// also exists on the host.
|
||||||
|
func TestIpcModeShareable(t *testing.T) {
|
||||||
|
skip.If(t, testEnv.DaemonInfo.OSType != "linux" || testEnv.IsRemoteDaemon())
|
||||||
|
|
||||||
|
testIpcNonePrivateShareable(t, "shareable", true, true)
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue