mirror of
https://github.com/moby/moby.git
synced 2026-07-12 02:25:19 +00:00
Migrated using
find . -type f -name "*_test.go" |
xargs gofmt -w \
-r "assert.Check(t, strings.Contains(a, b)) -> assert.Check(t, is.Contains(a, b))"
find . -type f -name "*_test.go" |
xargs gofmt -w \
-r "assert.Assert(t, strings.Contains(a, b)) -> assert.Assert(t, is.Contains(a, b))"
Using a boolean in assert.Assert or assert.Check results in error
messages that don't contain the actual problematic string, and when
running the integration suite on an actual machine (where the source
code parsing doesn't work) this makes it almost impossible to figure out
what the actual error is.
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
354 lines
12 KiB
Go
354 lines
12 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/docker/docker/integration-cli/cli"
|
|
"github.com/docker/docker/integration-cli/cli/build"
|
|
"github.com/docker/docker/pkg/stringid"
|
|
"github.com/docker/docker/testutil/fakecontext"
|
|
"github.com/docker/go-connections/nat"
|
|
"gotest.tools/v3/assert"
|
|
is "gotest.tools/v3/assert/cmp"
|
|
)
|
|
|
|
type DockerCLICreateSuite struct {
|
|
ds *DockerSuite
|
|
}
|
|
|
|
func (s *DockerCLICreateSuite) TearDownTest(ctx context.Context, c *testing.T) {
|
|
s.ds.TearDownTest(ctx, c)
|
|
}
|
|
|
|
func (s *DockerCLICreateSuite) OnTimeout(c *testing.T) {
|
|
s.ds.OnTimeout(c)
|
|
}
|
|
|
|
// Make sure we can create a simple container with some args
|
|
func (s *DockerCLICreateSuite) TestCreateArgs(c *testing.T) {
|
|
// Intentionally clear entrypoint, as the Windows busybox image needs an entrypoint, which breaks this test
|
|
containerID := cli.DockerCmd(c, "create", "--entrypoint=", "busybox", "command", "arg1", "arg2", "arg with space", "-c", "flags").Stdout()
|
|
containerID = strings.TrimSpace(containerID)
|
|
|
|
out := cli.DockerCmd(c, "inspect", containerID).Combined()
|
|
|
|
var containers []struct {
|
|
Path string
|
|
Args []string
|
|
}
|
|
|
|
err := json.Unmarshal([]byte(out), &containers)
|
|
assert.Assert(c, err == nil, "Error inspecting the container: %s", err)
|
|
assert.Equal(c, len(containers), 1)
|
|
|
|
cont := containers[0]
|
|
assert.Equal(c, cont.Path, "command", fmt.Sprintf("Unexpected container path. Expected command, received: %s", cont.Path))
|
|
|
|
b := false
|
|
expected := []string{"arg1", "arg2", "arg with space", "-c", "flags"}
|
|
for i, arg := range expected {
|
|
if arg != cont.Args[i] {
|
|
b = true
|
|
break
|
|
}
|
|
}
|
|
if len(cont.Args) != len(expected) || b {
|
|
c.Fatalf("Unexpected args. Expected %v, received: %v", expected, cont.Args)
|
|
}
|
|
}
|
|
|
|
// Make sure we can set hostconfig options too
|
|
func (s *DockerCLICreateSuite) TestCreateHostConfig(c *testing.T) {
|
|
containerID := cli.DockerCmd(c, "create", "-P", "busybox", "echo").Stdout()
|
|
containerID = strings.TrimSpace(containerID)
|
|
|
|
out := cli.DockerCmd(c, "inspect", containerID).Stdout()
|
|
|
|
var containers []struct {
|
|
HostConfig *struct {
|
|
PublishAllPorts bool
|
|
}
|
|
}
|
|
|
|
err := json.Unmarshal([]byte(out), &containers)
|
|
assert.Assert(c, err == nil, "Error inspecting the container: %s", err)
|
|
assert.Equal(c, len(containers), 1)
|
|
|
|
cont := containers[0]
|
|
assert.Assert(c, cont.HostConfig != nil, "Expected HostConfig, got none")
|
|
assert.Assert(c, cont.HostConfig.PublishAllPorts, "Expected PublishAllPorts, got false")
|
|
}
|
|
|
|
func (s *DockerCLICreateSuite) TestCreateWithPortRange(c *testing.T) {
|
|
containerID := cli.DockerCmd(c, "create", "-p", "3300-3303:3300-3303/tcp", "busybox", "echo").Stdout()
|
|
containerID = strings.TrimSpace(containerID)
|
|
|
|
out := cli.DockerCmd(c, "inspect", containerID).Stdout()
|
|
|
|
var containers []struct {
|
|
HostConfig *struct {
|
|
PortBindings map[nat.Port][]nat.PortBinding
|
|
}
|
|
}
|
|
err := json.Unmarshal([]byte(out), &containers)
|
|
assert.Assert(c, err == nil, "Error inspecting the container: %s", err)
|
|
assert.Equal(c, len(containers), 1)
|
|
|
|
cont := containers[0]
|
|
|
|
assert.Assert(c, cont.HostConfig != nil, "Expected HostConfig, got none")
|
|
assert.Equal(c, len(cont.HostConfig.PortBindings), 4, fmt.Sprintf("Expected 4 ports bindings, got %d", len(cont.HostConfig.PortBindings)))
|
|
|
|
for k, v := range cont.HostConfig.PortBindings {
|
|
assert.Equal(c, len(v), 1, fmt.Sprintf("Expected 1 ports binding, for the port %s but found %s", k, v))
|
|
assert.Equal(c, k.Port(), v[0].HostPort, fmt.Sprintf("Expected host port %s to match published port %s", k.Port(), v[0].HostPort))
|
|
}
|
|
}
|
|
|
|
func (s *DockerCLICreateSuite) TestCreateWithLargePortRange(c *testing.T) {
|
|
containerID := cli.DockerCmd(c, "create", "-p", "1-65535:1-65535/tcp", "busybox", "echo").Stdout()
|
|
containerID = strings.TrimSpace(containerID)
|
|
|
|
out := cli.DockerCmd(c, "inspect", containerID).Stdout()
|
|
|
|
var containers []struct {
|
|
HostConfig *struct {
|
|
PortBindings map[nat.Port][]nat.PortBinding
|
|
}
|
|
}
|
|
|
|
err := json.Unmarshal([]byte(out), &containers)
|
|
assert.Assert(c, err == nil, "Error inspecting the container: %s", err)
|
|
assert.Equal(c, len(containers), 1)
|
|
|
|
cont := containers[0]
|
|
assert.Assert(c, cont.HostConfig != nil, "Expected HostConfig, got none")
|
|
assert.Equal(c, len(cont.HostConfig.PortBindings), 65535)
|
|
|
|
for k, v := range cont.HostConfig.PortBindings {
|
|
assert.Equal(c, len(v), 1)
|
|
assert.Equal(c, k.Port(), v[0].HostPort, fmt.Sprintf("Expected host port %s to match published port %s", k.Port(), v[0].HostPort))
|
|
}
|
|
}
|
|
|
|
// "test123" should be printed by docker create + start
|
|
func (s *DockerCLICreateSuite) TestCreateEchoStdout(c *testing.T) {
|
|
containerID := cli.DockerCmd(c, "create", "busybox", "echo", "test123").Stdout()
|
|
containerID = strings.TrimSpace(containerID)
|
|
|
|
out := cli.DockerCmd(c, "start", "-ai", containerID).Combined()
|
|
assert.Equal(c, out, "test123\n", "container should've printed 'test123', got %q", out)
|
|
}
|
|
|
|
func (s *DockerCLICreateSuite) TestCreateVolumesCreated(c *testing.T) {
|
|
testRequires(c, testEnv.IsLocalDaemon)
|
|
prefix, slash := getPrefixAndSlashFromDaemonPlatform()
|
|
|
|
const name = "test_create_volume"
|
|
cli.DockerCmd(c, "create", "--name", name, "-v", prefix+slash+"foo", "busybox")
|
|
|
|
dir, err := inspectMountSourceField(name, prefix+slash+"foo")
|
|
assert.Assert(c, err == nil, "Error getting volume host path: %q", err)
|
|
|
|
if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
|
|
c.Fatalf("Volume was not created")
|
|
}
|
|
if err != nil {
|
|
c.Fatalf("Error statting volume host path: %q", err)
|
|
}
|
|
}
|
|
|
|
func (s *DockerCLICreateSuite) TestCreateLabels(c *testing.T) {
|
|
const name = "test_create_labels"
|
|
expected := map[string]string{"k1": "v1", "k2": "v2"}
|
|
cli.DockerCmd(c, "create", "--name", name, "-l", "k1=v1", "--label", "k2=v2", "busybox")
|
|
|
|
actual := make(map[string]string)
|
|
inspectFieldAndUnmarshall(c, name, "Config.Labels", &actual)
|
|
|
|
if !reflect.DeepEqual(expected, actual) {
|
|
c.Fatalf("Expected %s got %s", expected, actual)
|
|
}
|
|
}
|
|
|
|
func (s *DockerCLICreateSuite) TestCreateLabelFromImage(c *testing.T) {
|
|
imageName := "testcreatebuildlabel"
|
|
buildImageSuccessfully(c, imageName, build.WithDockerfile(`FROM busybox
|
|
LABEL k1=v1 k2=v2`))
|
|
|
|
const name = "test_create_labels_from_image"
|
|
expected := map[string]string{"k2": "x", "k3": "v3", "k1": "v1"}
|
|
cli.DockerCmd(c, "create", "--name", name, "-l", "k2=x", "--label", "k3=v3", imageName)
|
|
|
|
actual := make(map[string]string)
|
|
inspectFieldAndUnmarshall(c, name, "Config.Labels", &actual)
|
|
|
|
if !reflect.DeepEqual(expected, actual) {
|
|
c.Fatalf("Expected %s got %s", expected, actual)
|
|
}
|
|
}
|
|
|
|
func (s *DockerCLICreateSuite) TestCreateHostnameWithNumber(c *testing.T) {
|
|
imgName := "busybox"
|
|
// Busybox on Windows does not implement hostname command
|
|
if testEnv.DaemonInfo.OSType == "windows" {
|
|
imgName = testEnv.PlatformDefaults.BaseImage
|
|
}
|
|
out := cli.DockerCmd(c, "run", "-h", "web.0", imgName, "hostname").Combined()
|
|
assert.Equal(c, strings.TrimSpace(out), "web.0", "hostname not set, expected `web.0`, got: %s", out)
|
|
}
|
|
|
|
func (s *DockerCLICreateSuite) TestCreateRM(c *testing.T) {
|
|
// Test to make sure we can 'rm' a new container that is in
|
|
// "Created" state, and has ever been run. Test "rm -f" too.
|
|
|
|
// create a container
|
|
cID := cli.DockerCmd(c, "create", "busybox").Stdout()
|
|
cID = strings.TrimSpace(cID)
|
|
cli.DockerCmd(c, "rm", cID)
|
|
|
|
// Now do it again so we can "rm -f" this time
|
|
cID = cli.DockerCmd(c, "create", "busybox").Stdout()
|
|
cID = strings.TrimSpace(cID)
|
|
cli.DockerCmd(c, "rm", "-f", cID)
|
|
}
|
|
|
|
func (s *DockerCLICreateSuite) TestCreateModeIpcContainer(c *testing.T) {
|
|
// Uses Linux specific functionality (--ipc)
|
|
testRequires(c, DaemonIsLinux, testEnv.IsLocalDaemon)
|
|
|
|
id := cli.DockerCmd(c, "create", "busybox").Stdout()
|
|
id = strings.TrimSpace(id)
|
|
|
|
cli.DockerCmd(c, "create", fmt.Sprintf("--ipc=container:%s", id), "busybox")
|
|
}
|
|
|
|
func (s *DockerCLICreateSuite) TestCreateByImageID(c *testing.T) {
|
|
imageName := "testcreatebyimageid"
|
|
buildImageSuccessfully(c, imageName, build.WithDockerfile(`FROM busybox
|
|
MAINTAINER dockerio`))
|
|
imageID := getIDByName(c, imageName)
|
|
truncatedImageID := stringid.TruncateID(imageID)
|
|
|
|
cli.DockerCmd(c, "create", imageID)
|
|
cli.DockerCmd(c, "create", truncatedImageID)
|
|
|
|
// Ensure this fails
|
|
out, exit, _ := dockerCmdWithError("create", fmt.Sprintf("%s:%s", imageName, imageID))
|
|
if exit == 0 {
|
|
c.Fatalf("expected non-zero exit code; received %d", exit)
|
|
}
|
|
|
|
if expected := "invalid reference format"; !strings.Contains(out, expected) {
|
|
c.Fatalf(`Expected %q in output; got: %s`, expected, out)
|
|
}
|
|
|
|
if i := strings.IndexRune(imageID, ':'); i >= 0 {
|
|
imageID = imageID[i+1:]
|
|
}
|
|
out, exit, _ = dockerCmdWithError("create", fmt.Sprintf("%s:%s", "wrongimage", imageID))
|
|
if exit == 0 {
|
|
c.Fatalf("expected non-zero exit code; received %d", exit)
|
|
}
|
|
|
|
if expected := "Unable to find image"; !strings.Contains(out, expected) {
|
|
c.Fatalf(`Expected %q in output; got: %s`, expected, out)
|
|
}
|
|
}
|
|
|
|
func (s *DockerCLICreateSuite) TestCreateStopSignal(c *testing.T) {
|
|
const name = "test_create_stop_signal"
|
|
cli.DockerCmd(c, "create", "--name", name, "--stop-signal", "9", "busybox")
|
|
|
|
res := inspectFieldJSON(c, name, "Config.StopSignal")
|
|
assert.Assert(c, is.Contains(res, "9"))
|
|
}
|
|
|
|
func (s *DockerCLICreateSuite) TestCreateWithWorkdir(c *testing.T) {
|
|
const name = "foo"
|
|
|
|
prefix, slash := getPrefixAndSlashFromDaemonPlatform()
|
|
dir := prefix + slash + "home" + slash + "foo" + slash + "bar"
|
|
|
|
cli.DockerCmd(c, "create", "--name", name, "-w", dir, "busybox")
|
|
// Windows does not create the workdir until the container is started
|
|
if testEnv.DaemonInfo.OSType == "windows" {
|
|
cli.DockerCmd(c, "start", name)
|
|
if testEnv.DaemonInfo.Isolation.IsHyperV() {
|
|
// Hyper-V isolated containers do not allow file-operations on a
|
|
// running container. This test currently uses `docker cp` to verify
|
|
// that the WORKDIR was automatically created, which cannot be done
|
|
// while the container is running.
|
|
cli.DockerCmd(c, "stop", name)
|
|
}
|
|
}
|
|
// TODO: rewrite this test to not use `docker cp` for verifying that the WORKDIR was created
|
|
cli.DockerCmd(c, "cp", fmt.Sprintf("%s:%s", name, dir), prefix+slash+"tmp")
|
|
}
|
|
|
|
func (s *DockerCLICreateSuite) TestCreateWithInvalidLogOpts(c *testing.T) {
|
|
const name = "test-invalidate-log-opts"
|
|
out, _, err := dockerCmdWithError("create", "--name", name, "--log-opt", "invalid=true", "busybox")
|
|
assert.ErrorContains(c, err, "")
|
|
assert.Assert(c, is.Contains(out, "unknown log opt"))
|
|
assert.Assert(c, is.Contains(out, "unknown log opt"))
|
|
|
|
out = cli.DockerCmd(c, "ps", "-a").Stdout()
|
|
assert.Assert(c, !strings.Contains(out, name))
|
|
}
|
|
|
|
// #20972
|
|
func (s *DockerCLICreateSuite) TestCreate64ByteHexID(c *testing.T) {
|
|
out := inspectField(c, "busybox", "Id")
|
|
imageID := strings.TrimPrefix(strings.TrimSpace(out), "sha256:")
|
|
|
|
cli.DockerCmd(c, "create", imageID)
|
|
}
|
|
|
|
// Test case for #23498
|
|
func (s *DockerCLICreateSuite) TestCreateUnsetEntrypoint(c *testing.T) {
|
|
const name = "test-entrypoint"
|
|
dockerfile := `FROM busybox
|
|
ADD entrypoint.sh /entrypoint.sh
|
|
RUN chmod 755 /entrypoint.sh
|
|
ENTRYPOINT ["/entrypoint.sh"]
|
|
CMD echo foobar`
|
|
|
|
ctx := fakecontext.New(c, "",
|
|
fakecontext.WithDockerfile(dockerfile),
|
|
fakecontext.WithFiles(map[string]string{
|
|
"entrypoint.sh": `#!/bin/sh
|
|
echo "I am an entrypoint"
|
|
exec "$@"`,
|
|
}))
|
|
defer ctx.Close()
|
|
|
|
cli.BuildCmd(c, name, build.WithExternalBuildContext(ctx))
|
|
|
|
out := cli.DockerCmd(c, "create", "--entrypoint=", name, "echo", "foo").Combined()
|
|
id := strings.TrimSpace(out)
|
|
assert.Assert(c, id != "")
|
|
out = cli.DockerCmd(c, "start", "-a", id).Combined()
|
|
assert.Equal(c, strings.TrimSpace(out), "foo")
|
|
}
|
|
|
|
// #22471
|
|
func (s *DockerCLICreateSuite) TestCreateStopTimeout(c *testing.T) {
|
|
name1 := "test_create_stop_timeout_1"
|
|
cli.DockerCmd(c, "create", "--name", name1, "--stop-timeout", "15", "busybox")
|
|
|
|
res := inspectFieldJSON(c, name1, "Config.StopTimeout")
|
|
assert.Assert(c, is.Contains(res, "15"))
|
|
name2 := "test_create_stop_timeout_2"
|
|
cli.DockerCmd(c, "create", "--name", name2, "busybox")
|
|
|
|
res = inspectFieldJSON(c, name2, "Config.StopTimeout")
|
|
assert.Assert(c, is.Contains(res, "null"))
|
|
}
|