From c9c8799088b60ac58c943ee5545ebcba7483cd4c Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Tue, 13 Mar 2018 21:17:11 -0700 Subject: [PATCH 01/36] daemon.ContainerExport(): do not panic In case ContainerExport() is called for an unmounted container, it leads to a daemon panic as container.BaseFS, which is dereferenced here, is nil. To fix, do not rely on container.BaseFS; use the one returned from rwlayer.Mount(). Fixes: 7a7357dae1bccc ("LCOW: Implemented support for docker cp + build") Signed-off-by: Kir Kolyshkin (cherry picked from commit 81f6307eda44ab3a91de6e29304810a976161d74) Signed-off-by: Sebastiaan van Stijn --- components/engine/daemon/export.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/engine/daemon/export.go b/components/engine/daemon/export.go index 1f788ad9a8e..d6d091d1a90 100644 --- a/components/engine/daemon/export.go +++ b/components/engine/daemon/export.go @@ -61,12 +61,12 @@ func (daemon *Daemon) containerExport(container *container.Container) (arch io.R } }() - _, err = rwlayer.Mount(container.GetMountLabel()) + basefs, err := rwlayer.Mount(container.GetMountLabel()) if err != nil { return nil, err } - archive, err := archivePath(container.BaseFS, container.BaseFS.Path(), &archive.TarOptions{ + archive, err := archivePath(basefs, basefs.Path(), &archive.TarOptions{ Compression: archive.Uncompressed, UIDMaps: daemon.idMappings.UIDs(), GIDMaps: daemon.idMappings.GIDs(), From 46ad9721ef5b4a37f7a43271e708d349f2697d98 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Tue, 13 Mar 2018 19:45:21 -0700 Subject: [PATCH 02/36] container.BaseFS: check for nil before deref Commit 7a7357dae1bccc ("LCOW: Implemented support for docker cp + build") changed `container.BaseFS` from being a string (that could be empty but can't lead to nil pointer dereference) to containerfs.ContainerFS, which could be be `nil` and so nil dereference is at least theoretically possible, which leads to panic (i.e. engine crashes). Such a panic can be avoided by carefully analysing the source code in all the places that dereference a variable, to make the variable can't be nil. Practically, this analisys are impossible as code is constantly evolving. Still, we need to avoid panics and crashes. A good way to do so is to explicitly check that a variable is non-nil, returning an error otherwise. Even in case such a check looks absolutely redundant, further changes to the code might make it useful, and having an extra check is not a big price to pay to avoid a panic. This commit adds such checks for all the places where it is not obvious that container.BaseFS is not nil (which in this case means we do not call daemon.Mount() a few lines earlier). Signed-off-by: Kir Kolyshkin (cherry picked from commit d6ea46cedaca0098c15843c5254a337d087f5cd6) Signed-off-by: Sebastiaan van Stijn --- components/engine/container/archive.go | 7 +++++++ components/engine/container/container.go | 3 +++ components/engine/daemon/oci_linux.go | 3 +++ components/engine/daemon/oci_windows.go | 3 +++ 4 files changed, 16 insertions(+) diff --git a/components/engine/container/archive.go b/components/engine/container/archive.go index 960d7bf615c..ed72c4a4051 100644 --- a/components/engine/container/archive.go +++ b/components/engine/container/archive.go @@ -6,6 +6,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/system" + "github.com/pkg/errors" ) // ResolvePath resolves the given path in the container to a resource on the @@ -13,6 +14,9 @@ import ( // the absolute path to the resource relative to the container's rootfs, and // an error if the path points to outside the container's rootfs. func (container *Container) ResolvePath(path string) (resolvedPath, absPath string, err error) { + if container.BaseFS == nil { + return "", "", errors.New("ResolvePath: BaseFS of container " + container.ID + " is unexpectedly nil") + } // Check if a drive letter supplied, it must be the system drive. No-op except on Windows path, err = system.CheckSystemDriveAndRemoveDriveLetter(path, container.BaseFS) if err != nil { @@ -45,6 +49,9 @@ func (container *Container) ResolvePath(path string) (resolvedPath, absPath stri // resolved to a path on the host corresponding to the given absolute path // inside the container. func (container *Container) StatPath(resolvedPath, absPath string) (stat *types.ContainerPathStat, err error) { + if container.BaseFS == nil { + return nil, errors.New("StatPath: BaseFS of container " + container.ID + " is unexpectedly nil") + } driver := container.BaseFS lstat, err := driver.Lstat(resolvedPath) diff --git a/components/engine/container/container.go b/components/engine/container/container.go index 461139b4355..a076e80746e 100644 --- a/components/engine/container/container.go +++ b/components/engine/container/container.go @@ -311,6 +311,9 @@ func (container *Container) SetupWorkingDirectory(rootIDs idtools.IDPair) error // symlinking to a different path) between using this method and using the // path. See symlink.FollowSymlinkInScope for more details. func (container *Container) GetResourcePath(path string) (string, error) { + if container.BaseFS == nil { + return "", errors.New("GetResourcePath: BaseFS of container " + container.ID + " is unexpectedly nil") + } // IMPORTANT - These are paths on the OS where the daemon is running, hence // any filepath operations must be done in an OS agnostic way. r, e := container.BaseFS.ResolveScopedPath(path, false) diff --git a/components/engine/daemon/oci_linux.go b/components/engine/daemon/oci_linux.go index 8d5eebb885f..256e1c3e555 100644 --- a/components/engine/daemon/oci_linux.go +++ b/components/engine/daemon/oci_linux.go @@ -705,6 +705,9 @@ func setMounts(daemon *Daemon, s *specs.Spec, c *container.Container, mounts []c } func (daemon *Daemon) populateCommonSpec(s *specs.Spec, c *container.Container) error { + if c.BaseFS == nil { + return errors.New("populateCommonSpec: BaseFS of container " + c.ID + " is unexpectedly nil") + } linkedEnv, err := daemon.setupLinkedContainers(c) if err != nil { return err diff --git a/components/engine/daemon/oci_windows.go b/components/engine/daemon/oci_windows.go index 64c651c4af1..7af8942910c 100644 --- a/components/engine/daemon/oci_windows.go +++ b/components/engine/daemon/oci_windows.go @@ -241,6 +241,9 @@ func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) { // Sets the Windows-specific fields of the OCI spec func (daemon *Daemon) createSpecWindowsFields(c *container.Container, s *specs.Spec, isHyperV bool) error { + if c.BaseFS == nil { + return errors.New("createSpecWindowsFields: BaseFS of container " + c.ID + " is unexpectedly nil") + } if len(s.Process.Cwd) == 0 { // We default to C:\ to workaround the oddity of the case that the // default directory for cmd running as LocalSystem (or From 3c896e300b54bb59c5e9432eda0573e45625174e Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Thu, 15 Mar 2018 00:30:11 -0700 Subject: [PATCH 03/36] integration/TestExportContainerAfterDaemonRestart: add This test case checks that a container created before start of the currently running dockerd can be exported (as reported in #36561). To satisfy this condition, either a pre-existing container is required, or a daemon restart after container creation. Signed-off-by: Kir Kolyshkin (cherry picked from commit 6e7141c7a2c0de6fa3d6c9dcc56978a81f9d835e) Signed-off-by: Sebastiaan van Stijn --- .../integration/container/export_test.go | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/components/engine/integration/container/export_test.go b/components/engine/integration/container/export_test.go index 657b1fce412..8f846b5a294 100644 --- a/components/engine/integration/container/export_test.go +++ b/components/engine/integration/container/export_test.go @@ -7,7 +7,9 @@ import ( "time" "github.com/docker/docker/api/types" + containerTypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" "github.com/docker/docker/pkg/jsonmessage" @@ -51,3 +53,32 @@ func TestExportContainerAndImportImage(t *testing.T) { require.NoError(t, err) assert.Equal(t, jm.Status, images[0].ID) } + +// TestExportContainerAfterDaemonRestart checks that a container +// created before start of the currently running dockerd +// can be exported (as reported in #36561). To satisfy this +// condition, daemon restart is needed after container creation. +func TestExportContainerAfterDaemonRestart(t *testing.T) { + skip.If(t, testEnv.DaemonInfo.OSType != "linux") + skip.If(t, testEnv.IsRemoteDaemon()) + + d := daemon.New(t, "", "dockerd", daemon.Config{}) + client, err := d.NewClient() + require.NoError(t, err) + + d.StartWithBusybox(t) + defer d.Stop(t) + + ctx := context.Background() + cfg := containerTypes.Config{ + Image: "busybox", + Cmd: []string{"top"}, + } + ctr, err := client.ContainerCreate(ctx, &cfg, nil, nil, "") + require.NoError(t, err) + + d.Restart(t) + + _, err = client.ContainerExport(ctx, ctr.ID) + assert.NoError(t, err) +} From a978050d4f2229d11a23fceff1fcc2c65fac2967 Mon Sep 17 00:00:00 2001 From: John Howard Date: Thu, 15 Mar 2018 15:36:36 -0700 Subject: [PATCH 04/36] Windows: Fix Hyper-V containers regression from 36586 Signed-off-by: John Howard (cherry picked from commit 0f5fe3f9cf17457761dab28473ece5a7c94f4a0c) Signed-off-by: Sebastiaan van Stijn --- components/engine/daemon/oci_windows.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/components/engine/daemon/oci_windows.go b/components/engine/daemon/oci_windows.go index 7af8942910c..6777c389954 100644 --- a/components/engine/daemon/oci_windows.go +++ b/components/engine/daemon/oci_windows.go @@ -241,9 +241,6 @@ func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) { // Sets the Windows-specific fields of the OCI spec func (daemon *Daemon) createSpecWindowsFields(c *container.Container, s *specs.Spec, isHyperV bool) error { - if c.BaseFS == nil { - return errors.New("createSpecWindowsFields: BaseFS of container " + c.ID + " is unexpectedly nil") - } if len(s.Process.Cwd) == 0 { // We default to C:\ to workaround the oddity of the case that the // default directory for cmd running as LocalSystem (or @@ -257,6 +254,10 @@ func (daemon *Daemon) createSpecWindowsFields(c *container.Container, s *specs.S s.Root.Readonly = false // Windows does not support a read-only root filesystem if !isHyperV { + if c.BaseFS == nil { + return errors.New("createSpecWindowsFields: BaseFS of container " + c.ID + " is unexpectedly nil") + } + s.Root.Path = c.BaseFS.Path() // This is not set for Hyper-V containers if !strings.HasSuffix(s.Root.Path, `\`) { s.Root.Path = s.Root.Path + `\` // Ensure a correctly formatted volume GUID path \\?\Volume{GUID}\ From a415a11279c649f1c278f3d609e536335431fc77 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Fri, 22 Dec 2017 16:18:34 -0500 Subject: [PATCH 05/36] Cleanup some assertions Signed-off-by: Daniel Nephin (cherry picked from commit ef01dea8935932486f03a37069720987e805dce6) Signed-off-by: Sebastiaan van Stijn --- .../engine/daemon/logger/awslogs/cloudwatchlogs.go | 2 ++ .../daemon/logger/awslogs/cloudwatchlogs_test.go | 8 +------- components/engine/pkg/term/proxy_test.go | 13 +++++-------- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/components/engine/daemon/logger/awslogs/cloudwatchlogs.go b/components/engine/daemon/logger/awslogs/cloudwatchlogs.go index 835379b3b4f..d6312b660a8 100644 --- a/components/engine/daemon/logger/awslogs/cloudwatchlogs.go +++ b/components/engine/daemon/logger/awslogs/cloudwatchlogs.go @@ -69,6 +69,8 @@ type logStream struct { sequenceToken *string } +var _ logger.SizedLogger = &logStream{} + type api interface { CreateLogGroup(*cloudwatchlogs.CreateLogGroupInput) (*cloudwatchlogs.CreateLogGroupOutput, error) CreateLogStream(*cloudwatchlogs.CreateLogStreamInput) (*cloudwatchlogs.CreateLogStreamOutput, error) diff --git a/components/engine/daemon/logger/awslogs/cloudwatchlogs_test.go b/components/engine/daemon/logger/awslogs/cloudwatchlogs_test.go index 080157b2ea8..99d0f907f88 100644 --- a/components/engine/daemon/logger/awslogs/cloudwatchlogs_test.go +++ b/components/engine/daemon/logger/awslogs/cloudwatchlogs_test.go @@ -1143,11 +1143,6 @@ func TestCreateTagSuccess(t *testing.T) { } } -func TestIsSizedLogger(t *testing.T) { - awslogs := &logStream{} - assert.Implements(t, (*logger.SizedLogger)(nil), awslogs, "awslogs should implement SizedLogger") -} - func BenchmarkUnwrapEvents(b *testing.B) { events := make([]wrappedEvent, maximumLogEventsPerPut) for i := 0; i < maximumLogEventsPerPut; i++ { @@ -1157,11 +1152,10 @@ func BenchmarkUnwrapEvents(b *testing.B) { } } - as := assert.New(b) b.ResetTimer() for i := 0; i < b.N; i++ { res := unwrapEvents(events) - as.Len(res, maximumLogEventsPerPut) + assert.Len(b, res, maximumLogEventsPerPut) } } diff --git a/components/engine/pkg/term/proxy_test.go b/components/engine/pkg/term/proxy_test.go index ff40c1beff9..01be1d55be0 100644 --- a/components/engine/pkg/term/proxy_test.go +++ b/components/engine/pkg/term/proxy_test.go @@ -3,9 +3,9 @@ package term // import "github.com/docker/docker/pkg/term" import ( "bytes" "fmt" - "reflect" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -25,7 +25,8 @@ func TestEscapeProxyRead(t *testing.T) { nr, err = reader.Read(buf) require.Error(t, err, "Should throw error when no keys are to read") require.EqualValues(t, nr, 0, "nr should be zero") - require.Condition(t, func() (success bool) { return len(keys) == 0 && len(buf) == 0 }, "keys & the read buffer size should be zero") + assert.Len(t, keys, 0) + assert.Len(t, buf, 0) escapeKeys, _ = ToBytes("ctrl-x,ctrl-@") keys, _ = ToBytes("DEL") @@ -41,9 +42,7 @@ func TestEscapeProxyRead(t *testing.T) { reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) buf = make([]byte, len(keys)) nr, err = reader.Read(buf) - require.Condition(t, func() (success bool) { - return reflect.TypeOf(err).Name() == "EscapeError" - }, err) + require.EqualError(t, err, "read escape sequence") require.EqualValues(t, nr, 0, "nr should be equal to 0") require.Equal(t, keys, buf, "keys & the read buffer should be equal") @@ -56,9 +55,7 @@ func TestEscapeProxyRead(t *testing.T) { require.EqualValues(t, nr, 0, "nr should be equal to 0") require.Equal(t, keys[0:1], buf, "keys & the read buffer should be equal") nr, err = reader.Read(buf) - require.Condition(t, func() (success bool) { - return reflect.TypeOf(err).Name() == "EscapeError" - }, err) + require.EqualError(t, err, "read escape sequence") require.EqualValues(t, nr, 0, "nr should be equal to 0") require.Equal(t, keys[1:], buf, "keys & the read buffer should be equal") From 2ad8904abbb8f7c25b89c4e3b63f0dd49ef77ef5 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Fri, 22 Dec 2017 16:33:58 -0500 Subject: [PATCH 06/36] Update vendor Signed-off-by: Daniel Nephin (cherry picked from commit 073963e3b770efbdf8bd4b4f92d46b2c62eaf434) Signed-off-by: Sebastiaan van Stijn --- components/engine/vendor.conf | 6 +- .../vendor/github.com/davecgh/go-spew/LICENSE | 15 - .../github.com/davecgh/go-spew/README.md | 205 ---- .../github.com/davecgh/go-spew/spew/bypass.go | 152 --- .../davecgh/go-spew/spew/bypasssafe.go | 38 - .../github.com/davecgh/go-spew/spew/common.go | 341 ------ .../github.com/davecgh/go-spew/spew/config.go | 306 ----- .../github.com/davecgh/go-spew/spew/doc.go | 211 ---- .../github.com/davecgh/go-spew/spew/dump.go | 509 -------- .../github.com/davecgh/go-spew/spew/format.go | 419 ------- .../github.com/davecgh/go-spew/spew/spew.go | 148 --- .../vendor/github.com/google/go-cmp/README.md | 2 +- .../google/go-cmp/cmp/cmpopts/equate.go | 89 ++ .../google/go-cmp/cmp/cmpopts/ignore.go | 145 +++ .../google/go-cmp/cmp/cmpopts/sort.go | 146 +++ .../google/go-cmp/cmp/cmpopts/sort_go17.go | 46 + .../google/go-cmp/cmp/cmpopts/sort_go18.go | 31 + .../go-cmp/cmp/cmpopts/struct_filter.go | 182 +++ .../github.com/google/go-cmp/cmp/compare.go | 42 +- .../go-cmp/cmp/internal/diff/debug_enable.go | 2 +- .../google/go-cmp/cmp/internal/diff/diff.go | 18 +- .../go-cmp/cmp/internal/value/format.go | 78 +- .../google/go-cmp/cmp/internal/value/sort.go | 2 +- .../github.com/google/go-cmp/cmp/options.go | 37 +- .../github.com/google/go-cmp/cmp/path.go | 36 +- .../github.com/google/go-cmp/cmp/reporter.go | 12 +- .../google/go-cmp/cmp/unsafe_panic.go | 2 +- .../google/go-cmp/cmp/unsafe_reflect.go | 2 +- .../gotestyourself/gotestyourself/README.md | 1 + .../gotestyourself/assert/assert.go | 215 +++- .../gotestyourself/assert/cmp/compare.go | 277 +++-- .../gotestyourself/assert/cmp/result.go | 94 ++ .../gotestyourself/assert/result.go | 107 ++ .../gotestyourself/gotestyourself/env/env.go | 24 +- .../gotestyourself/gotestyourself/fs/ops.go | 31 + .../gotestyourself/icmd/command.go | 36 +- .../gotestyourself/internal/source/source.go | 124 +- .../gotestyourself/skip/skip.go | 2 +- .../github.com/stretchr/testify/LICENSE | 22 - .../github.com/stretchr/testify/README.md | 332 ----- .../testify/assert/assertion_forward.go | 352 ------ .../stretchr/testify/assert/assertions.go | 1069 ----------------- .../github.com/stretchr/testify/assert/doc.go | 45 - .../stretchr/testify/assert/errors.go | 10 - .../testify/assert/forward_assertions.go | 16 - .../testify/assert/http_assertions.go | 106 -- .../stretchr/testify/require/doc.go | 28 - .../testify/require/forward_requirements.go | 16 - .../stretchr/testify/require/require.go | 429 ------- .../testify/require/require_forward.go | 353 ------ .../stretchr/testify/require/requirements.go | 9 - 51 files changed, 1497 insertions(+), 5423 deletions(-) delete mode 100644 components/engine/vendor/github.com/davecgh/go-spew/LICENSE delete mode 100644 components/engine/vendor/github.com/davecgh/go-spew/README.md delete mode 100644 components/engine/vendor/github.com/davecgh/go-spew/spew/bypass.go delete mode 100644 components/engine/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go delete mode 100644 components/engine/vendor/github.com/davecgh/go-spew/spew/common.go delete mode 100644 components/engine/vendor/github.com/davecgh/go-spew/spew/config.go delete mode 100644 components/engine/vendor/github.com/davecgh/go-spew/spew/doc.go delete mode 100644 components/engine/vendor/github.com/davecgh/go-spew/spew/dump.go delete mode 100644 components/engine/vendor/github.com/davecgh/go-spew/spew/format.go delete mode 100644 components/engine/vendor/github.com/davecgh/go-spew/spew/spew.go create mode 100644 components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/equate.go create mode 100644 components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/ignore.go create mode 100644 components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/sort.go create mode 100644 components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/sort_go17.go create mode 100644 components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/sort_go18.go create mode 100644 components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/struct_filter.go create mode 100644 components/engine/vendor/github.com/gotestyourself/gotestyourself/assert/cmp/result.go create mode 100644 components/engine/vendor/github.com/gotestyourself/gotestyourself/assert/result.go delete mode 100644 components/engine/vendor/github.com/stretchr/testify/LICENSE delete mode 100644 components/engine/vendor/github.com/stretchr/testify/README.md delete mode 100644 components/engine/vendor/github.com/stretchr/testify/assert/assertion_forward.go delete mode 100644 components/engine/vendor/github.com/stretchr/testify/assert/assertions.go delete mode 100644 components/engine/vendor/github.com/stretchr/testify/assert/doc.go delete mode 100644 components/engine/vendor/github.com/stretchr/testify/assert/errors.go delete mode 100644 components/engine/vendor/github.com/stretchr/testify/assert/forward_assertions.go delete mode 100644 components/engine/vendor/github.com/stretchr/testify/assert/http_assertions.go delete mode 100644 components/engine/vendor/github.com/stretchr/testify/require/doc.go delete mode 100644 components/engine/vendor/github.com/stretchr/testify/require/forward_requirements.go delete mode 100644 components/engine/vendor/github.com/stretchr/testify/require/require.go delete mode 100644 components/engine/vendor/github.com/stretchr/testify/require/require_forward.go delete mode 100644 components/engine/vendor/github.com/stretchr/testify/require/requirements.go diff --git a/components/engine/vendor.conf b/components/engine/vendor.conf index df1373e7ff5..2c1a9a1b650 100644 --- a/components/engine/vendor.conf +++ b/components/engine/vendor.conf @@ -2,7 +2,6 @@ github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109 github.com/Microsoft/hcsshim v0.6.8 github.com/Microsoft/go-winio v0.4.6 -github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76 github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a github.com/go-check/check 4ed411733c5785b40214c70bce814c3a3a689609 https://github.com/cpuguy83/check.git github.com/gorilla/context v1.1 @@ -18,10 +17,9 @@ golang.org/x/sys 37707fdb30a5b38865cfb95e5aab41707daec7fd github.com/docker/go-units 9e638d38cf6977a37a8ea0078f3ee75a7cdb2dd1 github.com/docker/go-connections 7beb39f0b969b075d1325fecb092faf27fd357b6 golang.org/x/text f72d8390a633d5dfb0cc84043294db9f6c935756 -github.com/stretchr/testify 4d4bfba8f1d1027c4fdbe371823030df51419987 github.com/pmezard/go-difflib v1.0.0 -github.com/gotestyourself/gotestyourself 511344eed30e4384f010579a593dfb442033a692 -github.com/google/go-cmp v0.1.0 +github.com/gotestyourself/gotestyourself cf3a5ab914a2efa8bc838d09f5918c1d44d029 +github.com/google/go-cmp v0.2.0 github.com/RackSec/srslog 456df3a81436d29ba874f3590eeeee25d666f8a5 github.com/imdario/mergo 0.2.1 diff --git a/components/engine/vendor/github.com/davecgh/go-spew/LICENSE b/components/engine/vendor/github.com/davecgh/go-spew/LICENSE deleted file mode 100644 index c836416192d..00000000000 --- a/components/engine/vendor/github.com/davecgh/go-spew/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -ISC License - -Copyright (c) 2012-2016 Dave Collins - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/components/engine/vendor/github.com/davecgh/go-spew/README.md b/components/engine/vendor/github.com/davecgh/go-spew/README.md deleted file mode 100644 index 262430449b2..00000000000 --- a/components/engine/vendor/github.com/davecgh/go-spew/README.md +++ /dev/null @@ -1,205 +0,0 @@ -go-spew -======= - -[![Build Status](https://img.shields.io/travis/davecgh/go-spew.svg)] -(https://travis-ci.org/davecgh/go-spew) [![ISC License] -(http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) [![Coverage Status] -(https://img.shields.io/coveralls/davecgh/go-spew.svg)] -(https://coveralls.io/r/davecgh/go-spew?branch=master) - - -Go-spew implements a deep pretty printer for Go data structures to aid in -debugging. A comprehensive suite of tests with 100% test coverage is provided -to ensure proper functionality. See `test_coverage.txt` for the gocov coverage -report. Go-spew is licensed under the liberal ISC license, so it may be used in -open source or commercial projects. - -If you're interested in reading about how this package came to life and some -of the challenges involved in providing a deep pretty printer, there is a blog -post about it -[here](https://web.archive.org/web/20160304013555/https://blog.cyphertite.com/go-spew-a-journey-into-dumping-go-data-structures/). - -## Documentation - -[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)] -(http://godoc.org/github.com/davecgh/go-spew/spew) - -Full `go doc` style documentation for the project can be viewed online without -installing this package by using the excellent GoDoc site here: -http://godoc.org/github.com/davecgh/go-spew/spew - -You can also view the documentation locally once the package is installed with -the `godoc` tool by running `godoc -http=":6060"` and pointing your browser to -http://localhost:6060/pkg/github.com/davecgh/go-spew/spew - -## Installation - -```bash -$ go get -u github.com/davecgh/go-spew/spew -``` - -## Quick Start - -Add this import line to the file you're working in: - -```Go -import "github.com/davecgh/go-spew/spew" -``` - -To dump a variable with full newlines, indentation, type, and pointer -information use Dump, Fdump, or Sdump: - -```Go -spew.Dump(myVar1, myVar2, ...) -spew.Fdump(someWriter, myVar1, myVar2, ...) -str := spew.Sdump(myVar1, myVar2, ...) -``` - -Alternatively, if you would prefer to use format strings with a compacted inline -printing style, use the convenience wrappers Printf, Fprintf, etc with %v (most -compact), %+v (adds pointer addresses), %#v (adds types), or %#+v (adds types -and pointer addresses): - -```Go -spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) -spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) -spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) -spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) -``` - -## Debugging a Web Application Example - -Here is an example of how you can use `spew.Sdump()` to help debug a web application. Please be sure to wrap your output using the `html.EscapeString()` function for safety reasons. You should also only use this debugging technique in a development environment, never in production. - -```Go -package main - -import ( - "fmt" - "html" - "net/http" - - "github.com/davecgh/go-spew/spew" -) - -func handler(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "text/html") - fmt.Fprintf(w, "Hi there, %s!", r.URL.Path[1:]) - fmt.Fprintf(w, "") -} - -func main() { - http.HandleFunc("/", handler) - http.ListenAndServe(":8080", nil) -} -``` - -## Sample Dump Output - -``` -(main.Foo) { - unexportedField: (*main.Bar)(0xf84002e210)({ - flag: (main.Flag) flagTwo, - data: (uintptr) - }), - ExportedField: (map[interface {}]interface {}) { - (string) "one": (bool) true - } -} -([]uint8) { - 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... | - 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0| - 00000020 31 32 |12| -} -``` - -## Sample Formatter Output - -Double pointer to a uint8: -``` - %v: <**>5 - %+v: <**>(0xf8400420d0->0xf8400420c8)5 - %#v: (**uint8)5 - %#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5 -``` - -Pointer to circular struct with a uint8 field and a pointer to itself: -``` - %v: <*>{1 <*>} - %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)} - %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)} - %#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)} -``` - -## Configuration Options - -Configuration of spew is handled by fields in the ConfigState type. For -convenience, all of the top-level functions use a global state available via the -spew.Config global. - -It is also possible to create a ConfigState instance that provides methods -equivalent to the top-level functions. This allows concurrent configuration -options. See the ConfigState documentation for more details. - -``` -* Indent - String to use for each indentation level for Dump functions. - It is a single space by default. A popular alternative is "\t". - -* MaxDepth - Maximum number of levels to descend into nested data structures. - There is no limit by default. - -* DisableMethods - Disables invocation of error and Stringer interface methods. - Method invocation is enabled by default. - -* DisablePointerMethods - Disables invocation of error and Stringer interface methods on types - which only accept pointer receivers from non-pointer variables. This option - relies on access to the unsafe package, so it will not have any effect when - running in environments without access to the unsafe package such as Google - App Engine or with the "safe" build tag specified. - Pointer method invocation is enabled by default. - -* DisablePointerAddresses - DisablePointerAddresses specifies whether to disable the printing of - pointer addresses. This is useful when diffing data structures in tests. - -* DisableCapacities - DisableCapacities specifies whether to disable the printing of capacities - for arrays, slices, maps and channels. This is useful when diffing data - structures in tests. - -* ContinueOnMethod - Enables recursion into types after invoking error and Stringer interface - methods. Recursion after method invocation is disabled by default. - -* SortKeys - Specifies map keys should be sorted before being printed. Use - this to have a more deterministic, diffable output. Note that - only native types (bool, int, uint, floats, uintptr and string) - and types which implement error or Stringer interfaces are supported, - with other types sorted according to the reflect.Value.String() output - which guarantees display stability. Natural map order is used by - default. - -* SpewKeys - SpewKeys specifies that, as a last resort attempt, map keys should be - spewed to strings and sorted by those strings. This is only considered - if SortKeys is true. - -``` - -## Unsafe Package Dependency - -This package relies on the unsafe package to perform some of the more advanced -features, however it also supports a "limited" mode which allows it to work in -environments where the unsafe package is not available. By default, it will -operate in this mode on Google App Engine and when compiled with GopherJS. The -"safe" build tag may also be specified to force the package to build without -using the unsafe package. - -## License - -Go-spew is licensed under the [copyfree](http://copyfree.org) ISC License. diff --git a/components/engine/vendor/github.com/davecgh/go-spew/spew/bypass.go b/components/engine/vendor/github.com/davecgh/go-spew/spew/bypass.go deleted file mode 100644 index 8a4a6589a2d..00000000000 --- a/components/engine/vendor/github.com/davecgh/go-spew/spew/bypass.go +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright (c) 2015-2016 Dave Collins -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -// NOTE: Due to the following build constraints, this file will only be compiled -// when the code is not running on Google App Engine, compiled by GopherJS, and -// "-tags safe" is not added to the go build command line. The "disableunsafe" -// tag is deprecated and thus should not be used. -// +build !js,!appengine,!safe,!disableunsafe - -package spew - -import ( - "reflect" - "unsafe" -) - -const ( - // UnsafeDisabled is a build-time constant which specifies whether or - // not access to the unsafe package is available. - UnsafeDisabled = false - - // ptrSize is the size of a pointer on the current arch. - ptrSize = unsafe.Sizeof((*byte)(nil)) -) - -var ( - // offsetPtr, offsetScalar, and offsetFlag are the offsets for the - // internal reflect.Value fields. These values are valid before golang - // commit ecccf07e7f9d which changed the format. The are also valid - // after commit 82f48826c6c7 which changed the format again to mirror - // the original format. Code in the init function updates these offsets - // as necessary. - offsetPtr = uintptr(ptrSize) - offsetScalar = uintptr(0) - offsetFlag = uintptr(ptrSize * 2) - - // flagKindWidth and flagKindShift indicate various bits that the - // reflect package uses internally to track kind information. - // - // flagRO indicates whether or not the value field of a reflect.Value is - // read-only. - // - // flagIndir indicates whether the value field of a reflect.Value is - // the actual data or a pointer to the data. - // - // These values are valid before golang commit 90a7c3c86944 which - // changed their positions. Code in the init function updates these - // flags as necessary. - flagKindWidth = uintptr(5) - flagKindShift = uintptr(flagKindWidth - 1) - flagRO = uintptr(1 << 0) - flagIndir = uintptr(1 << 1) -) - -func init() { - // Older versions of reflect.Value stored small integers directly in the - // ptr field (which is named val in the older versions). Versions - // between commits ecccf07e7f9d and 82f48826c6c7 added a new field named - // scalar for this purpose which unfortunately came before the flag - // field, so the offset of the flag field is different for those - // versions. - // - // This code constructs a new reflect.Value from a known small integer - // and checks if the size of the reflect.Value struct indicates it has - // the scalar field. When it does, the offsets are updated accordingly. - vv := reflect.ValueOf(0xf00) - if unsafe.Sizeof(vv) == (ptrSize * 4) { - offsetScalar = ptrSize * 2 - offsetFlag = ptrSize * 3 - } - - // Commit 90a7c3c86944 changed the flag positions such that the low - // order bits are the kind. This code extracts the kind from the flags - // field and ensures it's the correct type. When it's not, the flag - // order has been changed to the newer format, so the flags are updated - // accordingly. - upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag) - upfv := *(*uintptr)(upf) - flagKindMask := uintptr((1<>flagKindShift != uintptr(reflect.Int) { - flagKindShift = 0 - flagRO = 1 << 5 - flagIndir = 1 << 6 - - // Commit adf9b30e5594 modified the flags to separate the - // flagRO flag into two bits which specifies whether or not the - // field is embedded. This causes flagIndir to move over a bit - // and means that flagRO is the combination of either of the - // original flagRO bit and the new bit. - // - // This code detects the change by extracting what used to be - // the indirect bit to ensure it's set. When it's not, the flag - // order has been changed to the newer format, so the flags are - // updated accordingly. - if upfv&flagIndir == 0 { - flagRO = 3 << 5 - flagIndir = 1 << 7 - } - } -} - -// unsafeReflectValue converts the passed reflect.Value into a one that bypasses -// the typical safety restrictions preventing access to unaddressable and -// unexported data. It works by digging the raw pointer to the underlying -// value out of the protected value and generating a new unprotected (unsafe) -// reflect.Value to it. -// -// This allows us to check for implementations of the Stringer and error -// interfaces to be used for pretty printing ordinarily unaddressable and -// inaccessible values such as unexported struct fields. -func unsafeReflectValue(v reflect.Value) (rv reflect.Value) { - indirects := 1 - vt := v.Type() - upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr) - rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag)) - if rvf&flagIndir != 0 { - vt = reflect.PtrTo(v.Type()) - indirects++ - } else if offsetScalar != 0 { - // The value is in the scalar field when it's not one of the - // reference types. - switch vt.Kind() { - case reflect.Uintptr: - case reflect.Chan: - case reflect.Func: - case reflect.Map: - case reflect.Ptr: - case reflect.UnsafePointer: - default: - upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + - offsetScalar) - } - } - - pv := reflect.NewAt(vt, upv) - rv = pv - for i := 0; i < indirects; i++ { - rv = rv.Elem() - } - return rv -} diff --git a/components/engine/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go b/components/engine/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go deleted file mode 100644 index 1fe3cf3d5d1..00000000000 --- a/components/engine/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2015-2016 Dave Collins -// -// Permission to use, copy, modify, and distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -// NOTE: Due to the following build constraints, this file will only be compiled -// when the code is running on Google App Engine, compiled by GopherJS, or -// "-tags safe" is added to the go build command line. The "disableunsafe" -// tag is deprecated and thus should not be used. -// +build js appengine safe disableunsafe - -package spew - -import "reflect" - -const ( - // UnsafeDisabled is a build-time constant which specifies whether or - // not access to the unsafe package is available. - UnsafeDisabled = true -) - -// unsafeReflectValue typically converts the passed reflect.Value into a one -// that bypasses the typical safety restrictions preventing access to -// unaddressable and unexported data. However, doing this relies on access to -// the unsafe package. This is a stub version which simply returns the passed -// reflect.Value when the unsafe package is not available. -func unsafeReflectValue(v reflect.Value) reflect.Value { - return v -} diff --git a/components/engine/vendor/github.com/davecgh/go-spew/spew/common.go b/components/engine/vendor/github.com/davecgh/go-spew/spew/common.go deleted file mode 100644 index 7c519ff47ac..00000000000 --- a/components/engine/vendor/github.com/davecgh/go-spew/spew/common.go +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "bytes" - "fmt" - "io" - "reflect" - "sort" - "strconv" -) - -// Some constants in the form of bytes to avoid string overhead. This mirrors -// the technique used in the fmt package. -var ( - panicBytes = []byte("(PANIC=") - plusBytes = []byte("+") - iBytes = []byte("i") - trueBytes = []byte("true") - falseBytes = []byte("false") - interfaceBytes = []byte("(interface {})") - commaNewlineBytes = []byte(",\n") - newlineBytes = []byte("\n") - openBraceBytes = []byte("{") - openBraceNewlineBytes = []byte("{\n") - closeBraceBytes = []byte("}") - asteriskBytes = []byte("*") - colonBytes = []byte(":") - colonSpaceBytes = []byte(": ") - openParenBytes = []byte("(") - closeParenBytes = []byte(")") - spaceBytes = []byte(" ") - pointerChainBytes = []byte("->") - nilAngleBytes = []byte("") - maxNewlineBytes = []byte("\n") - maxShortBytes = []byte("") - circularBytes = []byte("") - circularShortBytes = []byte("") - invalidAngleBytes = []byte("") - openBracketBytes = []byte("[") - closeBracketBytes = []byte("]") - percentBytes = []byte("%") - precisionBytes = []byte(".") - openAngleBytes = []byte("<") - closeAngleBytes = []byte(">") - openMapBytes = []byte("map[") - closeMapBytes = []byte("]") - lenEqualsBytes = []byte("len=") - capEqualsBytes = []byte("cap=") -) - -// hexDigits is used to map a decimal value to a hex digit. -var hexDigits = "0123456789abcdef" - -// catchPanic handles any panics that might occur during the handleMethods -// calls. -func catchPanic(w io.Writer, v reflect.Value) { - if err := recover(); err != nil { - w.Write(panicBytes) - fmt.Fprintf(w, "%v", err) - w.Write(closeParenBytes) - } -} - -// handleMethods attempts to call the Error and String methods on the underlying -// type the passed reflect.Value represents and outputes the result to Writer w. -// -// It handles panics in any called methods by catching and displaying the error -// as the formatted value. -func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) { - // We need an interface to check if the type implements the error or - // Stringer interface. However, the reflect package won't give us an - // interface on certain things like unexported struct fields in order - // to enforce visibility rules. We use unsafe, when it's available, - // to bypass these restrictions since this package does not mutate the - // values. - if !v.CanInterface() { - if UnsafeDisabled { - return false - } - - v = unsafeReflectValue(v) - } - - // Choose whether or not to do error and Stringer interface lookups against - // the base type or a pointer to the base type depending on settings. - // Technically calling one of these methods with a pointer receiver can - // mutate the value, however, types which choose to satisify an error or - // Stringer interface with a pointer receiver should not be mutating their - // state inside these interface methods. - if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() { - v = unsafeReflectValue(v) - } - if v.CanAddr() { - v = v.Addr() - } - - // Is it an error or Stringer? - switch iface := v.Interface().(type) { - case error: - defer catchPanic(w, v) - if cs.ContinueOnMethod { - w.Write(openParenBytes) - w.Write([]byte(iface.Error())) - w.Write(closeParenBytes) - w.Write(spaceBytes) - return false - } - - w.Write([]byte(iface.Error())) - return true - - case fmt.Stringer: - defer catchPanic(w, v) - if cs.ContinueOnMethod { - w.Write(openParenBytes) - w.Write([]byte(iface.String())) - w.Write(closeParenBytes) - w.Write(spaceBytes) - return false - } - w.Write([]byte(iface.String())) - return true - } - return false -} - -// printBool outputs a boolean value as true or false to Writer w. -func printBool(w io.Writer, val bool) { - if val { - w.Write(trueBytes) - } else { - w.Write(falseBytes) - } -} - -// printInt outputs a signed integer value to Writer w. -func printInt(w io.Writer, val int64, base int) { - w.Write([]byte(strconv.FormatInt(val, base))) -} - -// printUint outputs an unsigned integer value to Writer w. -func printUint(w io.Writer, val uint64, base int) { - w.Write([]byte(strconv.FormatUint(val, base))) -} - -// printFloat outputs a floating point value using the specified precision, -// which is expected to be 32 or 64bit, to Writer w. -func printFloat(w io.Writer, val float64, precision int) { - w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision))) -} - -// printComplex outputs a complex value using the specified float precision -// for the real and imaginary parts to Writer w. -func printComplex(w io.Writer, c complex128, floatPrecision int) { - r := real(c) - w.Write(openParenBytes) - w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision))) - i := imag(c) - if i >= 0 { - w.Write(plusBytes) - } - w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision))) - w.Write(iBytes) - w.Write(closeParenBytes) -} - -// printHexPtr outputs a uintptr formatted as hexidecimal with a leading '0x' -// prefix to Writer w. -func printHexPtr(w io.Writer, p uintptr) { - // Null pointer. - num := uint64(p) - if num == 0 { - w.Write(nilAngleBytes) - return - } - - // Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix - buf := make([]byte, 18) - - // It's simpler to construct the hex string right to left. - base := uint64(16) - i := len(buf) - 1 - for num >= base { - buf[i] = hexDigits[num%base] - num /= base - i-- - } - buf[i] = hexDigits[num] - - // Add '0x' prefix. - i-- - buf[i] = 'x' - i-- - buf[i] = '0' - - // Strip unused leading bytes. - buf = buf[i:] - w.Write(buf) -} - -// valuesSorter implements sort.Interface to allow a slice of reflect.Value -// elements to be sorted. -type valuesSorter struct { - values []reflect.Value - strings []string // either nil or same len and values - cs *ConfigState -} - -// newValuesSorter initializes a valuesSorter instance, which holds a set of -// surrogate keys on which the data should be sorted. It uses flags in -// ConfigState to decide if and how to populate those surrogate keys. -func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface { - vs := &valuesSorter{values: values, cs: cs} - if canSortSimply(vs.values[0].Kind()) { - return vs - } - if !cs.DisableMethods { - vs.strings = make([]string, len(values)) - for i := range vs.values { - b := bytes.Buffer{} - if !handleMethods(cs, &b, vs.values[i]) { - vs.strings = nil - break - } - vs.strings[i] = b.String() - } - } - if vs.strings == nil && cs.SpewKeys { - vs.strings = make([]string, len(values)) - for i := range vs.values { - vs.strings[i] = Sprintf("%#v", vs.values[i].Interface()) - } - } - return vs -} - -// canSortSimply tests whether a reflect.Kind is a primitive that can be sorted -// directly, or whether it should be considered for sorting by surrogate keys -// (if the ConfigState allows it). -func canSortSimply(kind reflect.Kind) bool { - // This switch parallels valueSortLess, except for the default case. - switch kind { - case reflect.Bool: - return true - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - return true - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - return true - case reflect.Float32, reflect.Float64: - return true - case reflect.String: - return true - case reflect.Uintptr: - return true - case reflect.Array: - return true - } - return false -} - -// Len returns the number of values in the slice. It is part of the -// sort.Interface implementation. -func (s *valuesSorter) Len() int { - return len(s.values) -} - -// Swap swaps the values at the passed indices. It is part of the -// sort.Interface implementation. -func (s *valuesSorter) Swap(i, j int) { - s.values[i], s.values[j] = s.values[j], s.values[i] - if s.strings != nil { - s.strings[i], s.strings[j] = s.strings[j], s.strings[i] - } -} - -// valueSortLess returns whether the first value should sort before the second -// value. It is used by valueSorter.Less as part of the sort.Interface -// implementation. -func valueSortLess(a, b reflect.Value) bool { - switch a.Kind() { - case reflect.Bool: - return !a.Bool() && b.Bool() - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - return a.Int() < b.Int() - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - return a.Uint() < b.Uint() - case reflect.Float32, reflect.Float64: - return a.Float() < b.Float() - case reflect.String: - return a.String() < b.String() - case reflect.Uintptr: - return a.Uint() < b.Uint() - case reflect.Array: - // Compare the contents of both arrays. - l := a.Len() - for i := 0; i < l; i++ { - av := a.Index(i) - bv := b.Index(i) - if av.Interface() == bv.Interface() { - continue - } - return valueSortLess(av, bv) - } - } - return a.String() < b.String() -} - -// Less returns whether the value at index i should sort before the -// value at index j. It is part of the sort.Interface implementation. -func (s *valuesSorter) Less(i, j int) bool { - if s.strings == nil { - return valueSortLess(s.values[i], s.values[j]) - } - return s.strings[i] < s.strings[j] -} - -// sortValues is a sort function that handles both native types and any type that -// can be converted to error or Stringer. Other inputs are sorted according to -// their Value.String() value to ensure display stability. -func sortValues(values []reflect.Value, cs *ConfigState) { - if len(values) == 0 { - return - } - sort.Sort(newValuesSorter(values, cs)) -} diff --git a/components/engine/vendor/github.com/davecgh/go-spew/spew/config.go b/components/engine/vendor/github.com/davecgh/go-spew/spew/config.go deleted file mode 100644 index 2e3d22f3120..00000000000 --- a/components/engine/vendor/github.com/davecgh/go-spew/spew/config.go +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "bytes" - "fmt" - "io" - "os" -) - -// ConfigState houses the configuration options used by spew to format and -// display values. There is a global instance, Config, that is used to control -// all top-level Formatter and Dump functionality. Each ConfigState instance -// provides methods equivalent to the top-level functions. -// -// The zero value for ConfigState provides no indentation. You would typically -// want to set it to a space or a tab. -// -// Alternatively, you can use NewDefaultConfig to get a ConfigState instance -// with default settings. See the documentation of NewDefaultConfig for default -// values. -type ConfigState struct { - // Indent specifies the string to use for each indentation level. The - // global config instance that all top-level functions use set this to a - // single space by default. If you would like more indentation, you might - // set this to a tab with "\t" or perhaps two spaces with " ". - Indent string - - // MaxDepth controls the maximum number of levels to descend into nested - // data structures. The default, 0, means there is no limit. - // - // NOTE: Circular data structures are properly detected, so it is not - // necessary to set this value unless you specifically want to limit deeply - // nested data structures. - MaxDepth int - - // DisableMethods specifies whether or not error and Stringer interfaces are - // invoked for types that implement them. - DisableMethods bool - - // DisablePointerMethods specifies whether or not to check for and invoke - // error and Stringer interfaces on types which only accept a pointer - // receiver when the current type is not a pointer. - // - // NOTE: This might be an unsafe action since calling one of these methods - // with a pointer receiver could technically mutate the value, however, - // in practice, types which choose to satisify an error or Stringer - // interface with a pointer receiver should not be mutating their state - // inside these interface methods. As a result, this option relies on - // access to the unsafe package, so it will not have any effect when - // running in environments without access to the unsafe package such as - // Google App Engine or with the "safe" build tag specified. - DisablePointerMethods bool - - // DisablePointerAddresses specifies whether to disable the printing of - // pointer addresses. This is useful when diffing data structures in tests. - DisablePointerAddresses bool - - // DisableCapacities specifies whether to disable the printing of capacities - // for arrays, slices, maps and channels. This is useful when diffing - // data structures in tests. - DisableCapacities bool - - // ContinueOnMethod specifies whether or not recursion should continue once - // a custom error or Stringer interface is invoked. The default, false, - // means it will print the results of invoking the custom error or Stringer - // interface and return immediately instead of continuing to recurse into - // the internals of the data type. - // - // NOTE: This flag does not have any effect if method invocation is disabled - // via the DisableMethods or DisablePointerMethods options. - ContinueOnMethod bool - - // SortKeys specifies map keys should be sorted before being printed. Use - // this to have a more deterministic, diffable output. Note that only - // native types (bool, int, uint, floats, uintptr and string) and types - // that support the error or Stringer interfaces (if methods are - // enabled) are supported, with other types sorted according to the - // reflect.Value.String() output which guarantees display stability. - SortKeys bool - - // SpewKeys specifies that, as a last resort attempt, map keys should - // be spewed to strings and sorted by those strings. This is only - // considered if SortKeys is true. - SpewKeys bool -} - -// Config is the active configuration of the top-level functions. -// The configuration can be changed by modifying the contents of spew.Config. -var Config = ConfigState{Indent: " "} - -// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the formatted string as a value that satisfies error. See NewFormatter -// for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Errorf(format string, a ...interface{}) (err error) { - return fmt.Errorf(format, c.convertArgs(a)...) -} - -// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) { - return fmt.Fprint(w, c.convertArgs(a)...) -} - -// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { - return fmt.Fprintf(w, format, c.convertArgs(a)...) -} - -// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it -// passed with a Formatter interface returned by c.NewFormatter. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { - return fmt.Fprintln(w, c.convertArgs(a)...) -} - -// Print is a wrapper for fmt.Print that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Print(c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Print(a ...interface{}) (n int, err error) { - return fmt.Print(c.convertArgs(a)...) -} - -// Printf is a wrapper for fmt.Printf that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) { - return fmt.Printf(format, c.convertArgs(a)...) -} - -// Println is a wrapper for fmt.Println that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Println(c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Println(a ...interface{}) (n int, err error) { - return fmt.Println(c.convertArgs(a)...) -} - -// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprint(c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Sprint(a ...interface{}) string { - return fmt.Sprint(c.convertArgs(a)...) -} - -// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were -// passed with a Formatter interface returned by c.NewFormatter. It returns -// the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Sprintf(format string, a ...interface{}) string { - return fmt.Sprintf(format, c.convertArgs(a)...) -} - -// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it -// were passed with a Formatter interface returned by c.NewFormatter. It -// returns the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b)) -func (c *ConfigState) Sprintln(a ...interface{}) string { - return fmt.Sprintln(c.convertArgs(a)...) -} - -/* -NewFormatter returns a custom formatter that satisfies the fmt.Formatter -interface. As a result, it integrates cleanly with standard fmt package -printing functions. The formatter is useful for inline printing of smaller data -types similar to the standard %v format specifier. - -The custom formatter only responds to the %v (most compact), %+v (adds pointer -addresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb -combinations. Any other verbs such as %x and %q will be sent to the the -standard fmt package for formatting. In addition, the custom formatter ignores -the width and precision arguments (however they will still work on the format -specifiers not handled by the custom formatter). - -Typically this function shouldn't be called directly. It is much easier to make -use of the custom formatter by calling one of the convenience functions such as -c.Printf, c.Println, or c.Printf. -*/ -func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter { - return newFormatter(c, v) -} - -// Fdump formats and displays the passed arguments to io.Writer w. It formats -// exactly the same as Dump. -func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) { - fdump(c, w, a...) -} - -/* -Dump displays the passed parameters to standard out with newlines, customizable -indentation, and additional debug information such as complete types and all -pointer addresses used to indirect to the final value. It provides the -following features over the built-in printing facilities provided by the fmt -package: - - * Pointers are dereferenced and followed - * Circular data structures are detected and handled properly - * Custom Stringer/error interfaces are optionally invoked, including - on unexported types - * Custom types which only implement the Stringer/error interfaces via - a pointer receiver are optionally invoked when passing non-pointer - variables - * Byte arrays and slices are dumped like the hexdump -C command which - includes offsets, byte values in hex, and ASCII output - -The configuration options are controlled by modifying the public members -of c. See ConfigState for options documentation. - -See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to -get the formatted result as a string. -*/ -func (c *ConfigState) Dump(a ...interface{}) { - fdump(c, os.Stdout, a...) -} - -// Sdump returns a string with the passed arguments formatted exactly the same -// as Dump. -func (c *ConfigState) Sdump(a ...interface{}) string { - var buf bytes.Buffer - fdump(c, &buf, a...) - return buf.String() -} - -// convertArgs accepts a slice of arguments and returns a slice of the same -// length with each argument converted to a spew Formatter interface using -// the ConfigState associated with s. -func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) { - formatters = make([]interface{}, len(args)) - for index, arg := range args { - formatters[index] = newFormatter(c, arg) - } - return formatters -} - -// NewDefaultConfig returns a ConfigState with the following default settings. -// -// Indent: " " -// MaxDepth: 0 -// DisableMethods: false -// DisablePointerMethods: false -// ContinueOnMethod: false -// SortKeys: false -func NewDefaultConfig() *ConfigState { - return &ConfigState{Indent: " "} -} diff --git a/components/engine/vendor/github.com/davecgh/go-spew/spew/doc.go b/components/engine/vendor/github.com/davecgh/go-spew/spew/doc.go deleted file mode 100644 index aacaac6f1e1..00000000000 --- a/components/engine/vendor/github.com/davecgh/go-spew/spew/doc.go +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* -Package spew implements a deep pretty printer for Go data structures to aid in -debugging. - -A quick overview of the additional features spew provides over the built-in -printing facilities for Go data types are as follows: - - * Pointers are dereferenced and followed - * Circular data structures are detected and handled properly - * Custom Stringer/error interfaces are optionally invoked, including - on unexported types - * Custom types which only implement the Stringer/error interfaces via - a pointer receiver are optionally invoked when passing non-pointer - variables - * Byte arrays and slices are dumped like the hexdump -C command which - includes offsets, byte values in hex, and ASCII output (only when using - Dump style) - -There are two different approaches spew allows for dumping Go data structures: - - * Dump style which prints with newlines, customizable indentation, - and additional debug information such as types and all pointer addresses - used to indirect to the final value - * A custom Formatter interface that integrates cleanly with the standard fmt - package and replaces %v, %+v, %#v, and %#+v to provide inline printing - similar to the default %v while providing the additional functionality - outlined above and passing unsupported format verbs such as %x and %q - along to fmt - -Quick Start - -This section demonstrates how to quickly get started with spew. See the -sections below for further details on formatting and configuration options. - -To dump a variable with full newlines, indentation, type, and pointer -information use Dump, Fdump, or Sdump: - spew.Dump(myVar1, myVar2, ...) - spew.Fdump(someWriter, myVar1, myVar2, ...) - str := spew.Sdump(myVar1, myVar2, ...) - -Alternatively, if you would prefer to use format strings with a compacted inline -printing style, use the convenience wrappers Printf, Fprintf, etc with -%v (most compact), %+v (adds pointer addresses), %#v (adds types), or -%#+v (adds types and pointer addresses): - spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) - spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) - spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) - spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) - -Configuration Options - -Configuration of spew is handled by fields in the ConfigState type. For -convenience, all of the top-level functions use a global state available -via the spew.Config global. - -It is also possible to create a ConfigState instance that provides methods -equivalent to the top-level functions. This allows concurrent configuration -options. See the ConfigState documentation for more details. - -The following configuration options are available: - * Indent - String to use for each indentation level for Dump functions. - It is a single space by default. A popular alternative is "\t". - - * MaxDepth - Maximum number of levels to descend into nested data structures. - There is no limit by default. - - * DisableMethods - Disables invocation of error and Stringer interface methods. - Method invocation is enabled by default. - - * DisablePointerMethods - Disables invocation of error and Stringer interface methods on types - which only accept pointer receivers from non-pointer variables. - Pointer method invocation is enabled by default. - - * DisablePointerAddresses - DisablePointerAddresses specifies whether to disable the printing of - pointer addresses. This is useful when diffing data structures in tests. - - * DisableCapacities - DisableCapacities specifies whether to disable the printing of - capacities for arrays, slices, maps and channels. This is useful when - diffing data structures in tests. - - * ContinueOnMethod - Enables recursion into types after invoking error and Stringer interface - methods. Recursion after method invocation is disabled by default. - - * SortKeys - Specifies map keys should be sorted before being printed. Use - this to have a more deterministic, diffable output. Note that - only native types (bool, int, uint, floats, uintptr and string) - and types which implement error or Stringer interfaces are - supported with other types sorted according to the - reflect.Value.String() output which guarantees display - stability. Natural map order is used by default. - - * SpewKeys - Specifies that, as a last resort attempt, map keys should be - spewed to strings and sorted by those strings. This is only - considered if SortKeys is true. - -Dump Usage - -Simply call spew.Dump with a list of variables you want to dump: - - spew.Dump(myVar1, myVar2, ...) - -You may also call spew.Fdump if you would prefer to output to an arbitrary -io.Writer. For example, to dump to standard error: - - spew.Fdump(os.Stderr, myVar1, myVar2, ...) - -A third option is to call spew.Sdump to get the formatted output as a string: - - str := spew.Sdump(myVar1, myVar2, ...) - -Sample Dump Output - -See the Dump example for details on the setup of the types and variables being -shown here. - - (main.Foo) { - unexportedField: (*main.Bar)(0xf84002e210)({ - flag: (main.Flag) flagTwo, - data: (uintptr) - }), - ExportedField: (map[interface {}]interface {}) (len=1) { - (string) (len=3) "one": (bool) true - } - } - -Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C -command as shown. - ([]uint8) (len=32 cap=32) { - 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... | - 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0| - 00000020 31 32 |12| - } - -Custom Formatter - -Spew provides a custom formatter that implements the fmt.Formatter interface -so that it integrates cleanly with standard fmt package printing functions. The -formatter is useful for inline printing of smaller data types similar to the -standard %v format specifier. - -The custom formatter only responds to the %v (most compact), %+v (adds pointer -addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb -combinations. Any other verbs such as %x and %q will be sent to the the -standard fmt package for formatting. In addition, the custom formatter ignores -the width and precision arguments (however they will still work on the format -specifiers not handled by the custom formatter). - -Custom Formatter Usage - -The simplest way to make use of the spew custom formatter is to call one of the -convenience functions such as spew.Printf, spew.Println, or spew.Printf. The -functions have syntax you are most likely already familiar with: - - spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) - spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) - spew.Println(myVar, myVar2) - spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) - spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) - -See the Index for the full list convenience functions. - -Sample Formatter Output - -Double pointer to a uint8: - %v: <**>5 - %+v: <**>(0xf8400420d0->0xf8400420c8)5 - %#v: (**uint8)5 - %#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5 - -Pointer to circular struct with a uint8 field and a pointer to itself: - %v: <*>{1 <*>} - %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)} - %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)} - %#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)} - -See the Printf example for details on the setup of variables being shown -here. - -Errors - -Since it is possible for custom Stringer/error interfaces to panic, spew -detects them and handles them internally by printing the panic information -inline with the output. Since spew is intended to provide deep pretty printing -capabilities on structures, it intentionally does not return any errors. -*/ -package spew diff --git a/components/engine/vendor/github.com/davecgh/go-spew/spew/dump.go b/components/engine/vendor/github.com/davecgh/go-spew/spew/dump.go deleted file mode 100644 index df1d582a728..00000000000 --- a/components/engine/vendor/github.com/davecgh/go-spew/spew/dump.go +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "bytes" - "encoding/hex" - "fmt" - "io" - "os" - "reflect" - "regexp" - "strconv" - "strings" -) - -var ( - // uint8Type is a reflect.Type representing a uint8. It is used to - // convert cgo types to uint8 slices for hexdumping. - uint8Type = reflect.TypeOf(uint8(0)) - - // cCharRE is a regular expression that matches a cgo char. - // It is used to detect character arrays to hexdump them. - cCharRE = regexp.MustCompile("^.*\\._Ctype_char$") - - // cUnsignedCharRE is a regular expression that matches a cgo unsigned - // char. It is used to detect unsigned character arrays to hexdump - // them. - cUnsignedCharRE = regexp.MustCompile("^.*\\._Ctype_unsignedchar$") - - // cUint8tCharRE is a regular expression that matches a cgo uint8_t. - // It is used to detect uint8_t arrays to hexdump them. - cUint8tCharRE = regexp.MustCompile("^.*\\._Ctype_uint8_t$") -) - -// dumpState contains information about the state of a dump operation. -type dumpState struct { - w io.Writer - depth int - pointers map[uintptr]int - ignoreNextType bool - ignoreNextIndent bool - cs *ConfigState -} - -// indent performs indentation according to the depth level and cs.Indent -// option. -func (d *dumpState) indent() { - if d.ignoreNextIndent { - d.ignoreNextIndent = false - return - } - d.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth)) -} - -// unpackValue returns values inside of non-nil interfaces when possible. -// This is useful for data types like structs, arrays, slices, and maps which -// can contain varying types packed inside an interface. -func (d *dumpState) unpackValue(v reflect.Value) reflect.Value { - if v.Kind() == reflect.Interface && !v.IsNil() { - v = v.Elem() - } - return v -} - -// dumpPtr handles formatting of pointers by indirecting them as necessary. -func (d *dumpState) dumpPtr(v reflect.Value) { - // Remove pointers at or below the current depth from map used to detect - // circular refs. - for k, depth := range d.pointers { - if depth >= d.depth { - delete(d.pointers, k) - } - } - - // Keep list of all dereferenced pointers to show later. - pointerChain := make([]uintptr, 0) - - // Figure out how many levels of indirection there are by dereferencing - // pointers and unpacking interfaces down the chain while detecting circular - // references. - nilFound := false - cycleFound := false - indirects := 0 - ve := v - for ve.Kind() == reflect.Ptr { - if ve.IsNil() { - nilFound = true - break - } - indirects++ - addr := ve.Pointer() - pointerChain = append(pointerChain, addr) - if pd, ok := d.pointers[addr]; ok && pd < d.depth { - cycleFound = true - indirects-- - break - } - d.pointers[addr] = d.depth - - ve = ve.Elem() - if ve.Kind() == reflect.Interface { - if ve.IsNil() { - nilFound = true - break - } - ve = ve.Elem() - } - } - - // Display type information. - d.w.Write(openParenBytes) - d.w.Write(bytes.Repeat(asteriskBytes, indirects)) - d.w.Write([]byte(ve.Type().String())) - d.w.Write(closeParenBytes) - - // Display pointer information. - if !d.cs.DisablePointerAddresses && len(pointerChain) > 0 { - d.w.Write(openParenBytes) - for i, addr := range pointerChain { - if i > 0 { - d.w.Write(pointerChainBytes) - } - printHexPtr(d.w, addr) - } - d.w.Write(closeParenBytes) - } - - // Display dereferenced value. - d.w.Write(openParenBytes) - switch { - case nilFound == true: - d.w.Write(nilAngleBytes) - - case cycleFound == true: - d.w.Write(circularBytes) - - default: - d.ignoreNextType = true - d.dump(ve) - } - d.w.Write(closeParenBytes) -} - -// dumpSlice handles formatting of arrays and slices. Byte (uint8 under -// reflection) arrays and slices are dumped in hexdump -C fashion. -func (d *dumpState) dumpSlice(v reflect.Value) { - // Determine whether this type should be hex dumped or not. Also, - // for types which should be hexdumped, try to use the underlying data - // first, then fall back to trying to convert them to a uint8 slice. - var buf []uint8 - doConvert := false - doHexDump := false - numEntries := v.Len() - if numEntries > 0 { - vt := v.Index(0).Type() - vts := vt.String() - switch { - // C types that need to be converted. - case cCharRE.MatchString(vts): - fallthrough - case cUnsignedCharRE.MatchString(vts): - fallthrough - case cUint8tCharRE.MatchString(vts): - doConvert = true - - // Try to use existing uint8 slices and fall back to converting - // and copying if that fails. - case vt.Kind() == reflect.Uint8: - // We need an addressable interface to convert the type - // to a byte slice. However, the reflect package won't - // give us an interface on certain things like - // unexported struct fields in order to enforce - // visibility rules. We use unsafe, when available, to - // bypass these restrictions since this package does not - // mutate the values. - vs := v - if !vs.CanInterface() || !vs.CanAddr() { - vs = unsafeReflectValue(vs) - } - if !UnsafeDisabled { - vs = vs.Slice(0, numEntries) - - // Use the existing uint8 slice if it can be - // type asserted. - iface := vs.Interface() - if slice, ok := iface.([]uint8); ok { - buf = slice - doHexDump = true - break - } - } - - // The underlying data needs to be converted if it can't - // be type asserted to a uint8 slice. - doConvert = true - } - - // Copy and convert the underlying type if needed. - if doConvert && vt.ConvertibleTo(uint8Type) { - // Convert and copy each element into a uint8 byte - // slice. - buf = make([]uint8, numEntries) - for i := 0; i < numEntries; i++ { - vv := v.Index(i) - buf[i] = uint8(vv.Convert(uint8Type).Uint()) - } - doHexDump = true - } - } - - // Hexdump the entire slice as needed. - if doHexDump { - indent := strings.Repeat(d.cs.Indent, d.depth) - str := indent + hex.Dump(buf) - str = strings.Replace(str, "\n", "\n"+indent, -1) - str = strings.TrimRight(str, d.cs.Indent) - d.w.Write([]byte(str)) - return - } - - // Recursively call dump for each item. - for i := 0; i < numEntries; i++ { - d.dump(d.unpackValue(v.Index(i))) - if i < (numEntries - 1) { - d.w.Write(commaNewlineBytes) - } else { - d.w.Write(newlineBytes) - } - } -} - -// dump is the main workhorse for dumping a value. It uses the passed reflect -// value to figure out what kind of object we are dealing with and formats it -// appropriately. It is a recursive function, however circular data structures -// are detected and handled properly. -func (d *dumpState) dump(v reflect.Value) { - // Handle invalid reflect values immediately. - kind := v.Kind() - if kind == reflect.Invalid { - d.w.Write(invalidAngleBytes) - return - } - - // Handle pointers specially. - if kind == reflect.Ptr { - d.indent() - d.dumpPtr(v) - return - } - - // Print type information unless already handled elsewhere. - if !d.ignoreNextType { - d.indent() - d.w.Write(openParenBytes) - d.w.Write([]byte(v.Type().String())) - d.w.Write(closeParenBytes) - d.w.Write(spaceBytes) - } - d.ignoreNextType = false - - // Display length and capacity if the built-in len and cap functions - // work with the value's kind and the len/cap itself is non-zero. - valueLen, valueCap := 0, 0 - switch v.Kind() { - case reflect.Array, reflect.Slice, reflect.Chan: - valueLen, valueCap = v.Len(), v.Cap() - case reflect.Map, reflect.String: - valueLen = v.Len() - } - if valueLen != 0 || !d.cs.DisableCapacities && valueCap != 0 { - d.w.Write(openParenBytes) - if valueLen != 0 { - d.w.Write(lenEqualsBytes) - printInt(d.w, int64(valueLen), 10) - } - if !d.cs.DisableCapacities && valueCap != 0 { - if valueLen != 0 { - d.w.Write(spaceBytes) - } - d.w.Write(capEqualsBytes) - printInt(d.w, int64(valueCap), 10) - } - d.w.Write(closeParenBytes) - d.w.Write(spaceBytes) - } - - // Call Stringer/error interfaces if they exist and the handle methods flag - // is enabled - if !d.cs.DisableMethods { - if (kind != reflect.Invalid) && (kind != reflect.Interface) { - if handled := handleMethods(d.cs, d.w, v); handled { - return - } - } - } - - switch kind { - case reflect.Invalid: - // Do nothing. We should never get here since invalid has already - // been handled above. - - case reflect.Bool: - printBool(d.w, v.Bool()) - - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - printInt(d.w, v.Int(), 10) - - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - printUint(d.w, v.Uint(), 10) - - case reflect.Float32: - printFloat(d.w, v.Float(), 32) - - case reflect.Float64: - printFloat(d.w, v.Float(), 64) - - case reflect.Complex64: - printComplex(d.w, v.Complex(), 32) - - case reflect.Complex128: - printComplex(d.w, v.Complex(), 64) - - case reflect.Slice: - if v.IsNil() { - d.w.Write(nilAngleBytes) - break - } - fallthrough - - case reflect.Array: - d.w.Write(openBraceNewlineBytes) - d.depth++ - if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { - d.indent() - d.w.Write(maxNewlineBytes) - } else { - d.dumpSlice(v) - } - d.depth-- - d.indent() - d.w.Write(closeBraceBytes) - - case reflect.String: - d.w.Write([]byte(strconv.Quote(v.String()))) - - case reflect.Interface: - // The only time we should get here is for nil interfaces due to - // unpackValue calls. - if v.IsNil() { - d.w.Write(nilAngleBytes) - } - - case reflect.Ptr: - // Do nothing. We should never get here since pointers have already - // been handled above. - - case reflect.Map: - // nil maps should be indicated as different than empty maps - if v.IsNil() { - d.w.Write(nilAngleBytes) - break - } - - d.w.Write(openBraceNewlineBytes) - d.depth++ - if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { - d.indent() - d.w.Write(maxNewlineBytes) - } else { - numEntries := v.Len() - keys := v.MapKeys() - if d.cs.SortKeys { - sortValues(keys, d.cs) - } - for i, key := range keys { - d.dump(d.unpackValue(key)) - d.w.Write(colonSpaceBytes) - d.ignoreNextIndent = true - d.dump(d.unpackValue(v.MapIndex(key))) - if i < (numEntries - 1) { - d.w.Write(commaNewlineBytes) - } else { - d.w.Write(newlineBytes) - } - } - } - d.depth-- - d.indent() - d.w.Write(closeBraceBytes) - - case reflect.Struct: - d.w.Write(openBraceNewlineBytes) - d.depth++ - if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { - d.indent() - d.w.Write(maxNewlineBytes) - } else { - vt := v.Type() - numFields := v.NumField() - for i := 0; i < numFields; i++ { - d.indent() - vtf := vt.Field(i) - d.w.Write([]byte(vtf.Name)) - d.w.Write(colonSpaceBytes) - d.ignoreNextIndent = true - d.dump(d.unpackValue(v.Field(i))) - if i < (numFields - 1) { - d.w.Write(commaNewlineBytes) - } else { - d.w.Write(newlineBytes) - } - } - } - d.depth-- - d.indent() - d.w.Write(closeBraceBytes) - - case reflect.Uintptr: - printHexPtr(d.w, uintptr(v.Uint())) - - case reflect.UnsafePointer, reflect.Chan, reflect.Func: - printHexPtr(d.w, v.Pointer()) - - // There were not any other types at the time this code was written, but - // fall back to letting the default fmt package handle it in case any new - // types are added. - default: - if v.CanInterface() { - fmt.Fprintf(d.w, "%v", v.Interface()) - } else { - fmt.Fprintf(d.w, "%v", v.String()) - } - } -} - -// fdump is a helper function to consolidate the logic from the various public -// methods which take varying writers and config states. -func fdump(cs *ConfigState, w io.Writer, a ...interface{}) { - for _, arg := range a { - if arg == nil { - w.Write(interfaceBytes) - w.Write(spaceBytes) - w.Write(nilAngleBytes) - w.Write(newlineBytes) - continue - } - - d := dumpState{w: w, cs: cs} - d.pointers = make(map[uintptr]int) - d.dump(reflect.ValueOf(arg)) - d.w.Write(newlineBytes) - } -} - -// Fdump formats and displays the passed arguments to io.Writer w. It formats -// exactly the same as Dump. -func Fdump(w io.Writer, a ...interface{}) { - fdump(&Config, w, a...) -} - -// Sdump returns a string with the passed arguments formatted exactly the same -// as Dump. -func Sdump(a ...interface{}) string { - var buf bytes.Buffer - fdump(&Config, &buf, a...) - return buf.String() -} - -/* -Dump displays the passed parameters to standard out with newlines, customizable -indentation, and additional debug information such as complete types and all -pointer addresses used to indirect to the final value. It provides the -following features over the built-in printing facilities provided by the fmt -package: - - * Pointers are dereferenced and followed - * Circular data structures are detected and handled properly - * Custom Stringer/error interfaces are optionally invoked, including - on unexported types - * Custom types which only implement the Stringer/error interfaces via - a pointer receiver are optionally invoked when passing non-pointer - variables - * Byte arrays and slices are dumped like the hexdump -C command which - includes offsets, byte values in hex, and ASCII output - -The configuration options are controlled by an exported package global, -spew.Config. See ConfigState for options documentation. - -See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to -get the formatted result as a string. -*/ -func Dump(a ...interface{}) { - fdump(&Config, os.Stdout, a...) -} diff --git a/components/engine/vendor/github.com/davecgh/go-spew/spew/format.go b/components/engine/vendor/github.com/davecgh/go-spew/spew/format.go deleted file mode 100644 index c49875bacbb..00000000000 --- a/components/engine/vendor/github.com/davecgh/go-spew/spew/format.go +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "bytes" - "fmt" - "reflect" - "strconv" - "strings" -) - -// supportedFlags is a list of all the character flags supported by fmt package. -const supportedFlags = "0-+# " - -// formatState implements the fmt.Formatter interface and contains information -// about the state of a formatting operation. The NewFormatter function can -// be used to get a new Formatter which can be used directly as arguments -// in standard fmt package printing calls. -type formatState struct { - value interface{} - fs fmt.State - depth int - pointers map[uintptr]int - ignoreNextType bool - cs *ConfigState -} - -// buildDefaultFormat recreates the original format string without precision -// and width information to pass in to fmt.Sprintf in the case of an -// unrecognized type. Unless new types are added to the language, this -// function won't ever be called. -func (f *formatState) buildDefaultFormat() (format string) { - buf := bytes.NewBuffer(percentBytes) - - for _, flag := range supportedFlags { - if f.fs.Flag(int(flag)) { - buf.WriteRune(flag) - } - } - - buf.WriteRune('v') - - format = buf.String() - return format -} - -// constructOrigFormat recreates the original format string including precision -// and width information to pass along to the standard fmt package. This allows -// automatic deferral of all format strings this package doesn't support. -func (f *formatState) constructOrigFormat(verb rune) (format string) { - buf := bytes.NewBuffer(percentBytes) - - for _, flag := range supportedFlags { - if f.fs.Flag(int(flag)) { - buf.WriteRune(flag) - } - } - - if width, ok := f.fs.Width(); ok { - buf.WriteString(strconv.Itoa(width)) - } - - if precision, ok := f.fs.Precision(); ok { - buf.Write(precisionBytes) - buf.WriteString(strconv.Itoa(precision)) - } - - buf.WriteRune(verb) - - format = buf.String() - return format -} - -// unpackValue returns values inside of non-nil interfaces when possible and -// ensures that types for values which have been unpacked from an interface -// are displayed when the show types flag is also set. -// This is useful for data types like structs, arrays, slices, and maps which -// can contain varying types packed inside an interface. -func (f *formatState) unpackValue(v reflect.Value) reflect.Value { - if v.Kind() == reflect.Interface { - f.ignoreNextType = false - if !v.IsNil() { - v = v.Elem() - } - } - return v -} - -// formatPtr handles formatting of pointers by indirecting them as necessary. -func (f *formatState) formatPtr(v reflect.Value) { - // Display nil if top level pointer is nil. - showTypes := f.fs.Flag('#') - if v.IsNil() && (!showTypes || f.ignoreNextType) { - f.fs.Write(nilAngleBytes) - return - } - - // Remove pointers at or below the current depth from map used to detect - // circular refs. - for k, depth := range f.pointers { - if depth >= f.depth { - delete(f.pointers, k) - } - } - - // Keep list of all dereferenced pointers to possibly show later. - pointerChain := make([]uintptr, 0) - - // Figure out how many levels of indirection there are by derferencing - // pointers and unpacking interfaces down the chain while detecting circular - // references. - nilFound := false - cycleFound := false - indirects := 0 - ve := v - for ve.Kind() == reflect.Ptr { - if ve.IsNil() { - nilFound = true - break - } - indirects++ - addr := ve.Pointer() - pointerChain = append(pointerChain, addr) - if pd, ok := f.pointers[addr]; ok && pd < f.depth { - cycleFound = true - indirects-- - break - } - f.pointers[addr] = f.depth - - ve = ve.Elem() - if ve.Kind() == reflect.Interface { - if ve.IsNil() { - nilFound = true - break - } - ve = ve.Elem() - } - } - - // Display type or indirection level depending on flags. - if showTypes && !f.ignoreNextType { - f.fs.Write(openParenBytes) - f.fs.Write(bytes.Repeat(asteriskBytes, indirects)) - f.fs.Write([]byte(ve.Type().String())) - f.fs.Write(closeParenBytes) - } else { - if nilFound || cycleFound { - indirects += strings.Count(ve.Type().String(), "*") - } - f.fs.Write(openAngleBytes) - f.fs.Write([]byte(strings.Repeat("*", indirects))) - f.fs.Write(closeAngleBytes) - } - - // Display pointer information depending on flags. - if f.fs.Flag('+') && (len(pointerChain) > 0) { - f.fs.Write(openParenBytes) - for i, addr := range pointerChain { - if i > 0 { - f.fs.Write(pointerChainBytes) - } - printHexPtr(f.fs, addr) - } - f.fs.Write(closeParenBytes) - } - - // Display dereferenced value. - switch { - case nilFound == true: - f.fs.Write(nilAngleBytes) - - case cycleFound == true: - f.fs.Write(circularShortBytes) - - default: - f.ignoreNextType = true - f.format(ve) - } -} - -// format is the main workhorse for providing the Formatter interface. It -// uses the passed reflect value to figure out what kind of object we are -// dealing with and formats it appropriately. It is a recursive function, -// however circular data structures are detected and handled properly. -func (f *formatState) format(v reflect.Value) { - // Handle invalid reflect values immediately. - kind := v.Kind() - if kind == reflect.Invalid { - f.fs.Write(invalidAngleBytes) - return - } - - // Handle pointers specially. - if kind == reflect.Ptr { - f.formatPtr(v) - return - } - - // Print type information unless already handled elsewhere. - if !f.ignoreNextType && f.fs.Flag('#') { - f.fs.Write(openParenBytes) - f.fs.Write([]byte(v.Type().String())) - f.fs.Write(closeParenBytes) - } - f.ignoreNextType = false - - // Call Stringer/error interfaces if they exist and the handle methods - // flag is enabled. - if !f.cs.DisableMethods { - if (kind != reflect.Invalid) && (kind != reflect.Interface) { - if handled := handleMethods(f.cs, f.fs, v); handled { - return - } - } - } - - switch kind { - case reflect.Invalid: - // Do nothing. We should never get here since invalid has already - // been handled above. - - case reflect.Bool: - printBool(f.fs, v.Bool()) - - case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: - printInt(f.fs, v.Int(), 10) - - case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: - printUint(f.fs, v.Uint(), 10) - - case reflect.Float32: - printFloat(f.fs, v.Float(), 32) - - case reflect.Float64: - printFloat(f.fs, v.Float(), 64) - - case reflect.Complex64: - printComplex(f.fs, v.Complex(), 32) - - case reflect.Complex128: - printComplex(f.fs, v.Complex(), 64) - - case reflect.Slice: - if v.IsNil() { - f.fs.Write(nilAngleBytes) - break - } - fallthrough - - case reflect.Array: - f.fs.Write(openBracketBytes) - f.depth++ - if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { - f.fs.Write(maxShortBytes) - } else { - numEntries := v.Len() - for i := 0; i < numEntries; i++ { - if i > 0 { - f.fs.Write(spaceBytes) - } - f.ignoreNextType = true - f.format(f.unpackValue(v.Index(i))) - } - } - f.depth-- - f.fs.Write(closeBracketBytes) - - case reflect.String: - f.fs.Write([]byte(v.String())) - - case reflect.Interface: - // The only time we should get here is for nil interfaces due to - // unpackValue calls. - if v.IsNil() { - f.fs.Write(nilAngleBytes) - } - - case reflect.Ptr: - // Do nothing. We should never get here since pointers have already - // been handled above. - - case reflect.Map: - // nil maps should be indicated as different than empty maps - if v.IsNil() { - f.fs.Write(nilAngleBytes) - break - } - - f.fs.Write(openMapBytes) - f.depth++ - if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { - f.fs.Write(maxShortBytes) - } else { - keys := v.MapKeys() - if f.cs.SortKeys { - sortValues(keys, f.cs) - } - for i, key := range keys { - if i > 0 { - f.fs.Write(spaceBytes) - } - f.ignoreNextType = true - f.format(f.unpackValue(key)) - f.fs.Write(colonBytes) - f.ignoreNextType = true - f.format(f.unpackValue(v.MapIndex(key))) - } - } - f.depth-- - f.fs.Write(closeMapBytes) - - case reflect.Struct: - numFields := v.NumField() - f.fs.Write(openBraceBytes) - f.depth++ - if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { - f.fs.Write(maxShortBytes) - } else { - vt := v.Type() - for i := 0; i < numFields; i++ { - if i > 0 { - f.fs.Write(spaceBytes) - } - vtf := vt.Field(i) - if f.fs.Flag('+') || f.fs.Flag('#') { - f.fs.Write([]byte(vtf.Name)) - f.fs.Write(colonBytes) - } - f.format(f.unpackValue(v.Field(i))) - } - } - f.depth-- - f.fs.Write(closeBraceBytes) - - case reflect.Uintptr: - printHexPtr(f.fs, uintptr(v.Uint())) - - case reflect.UnsafePointer, reflect.Chan, reflect.Func: - printHexPtr(f.fs, v.Pointer()) - - // There were not any other types at the time this code was written, but - // fall back to letting the default fmt package handle it if any get added. - default: - format := f.buildDefaultFormat() - if v.CanInterface() { - fmt.Fprintf(f.fs, format, v.Interface()) - } else { - fmt.Fprintf(f.fs, format, v.String()) - } - } -} - -// Format satisfies the fmt.Formatter interface. See NewFormatter for usage -// details. -func (f *formatState) Format(fs fmt.State, verb rune) { - f.fs = fs - - // Use standard formatting for verbs that are not v. - if verb != 'v' { - format := f.constructOrigFormat(verb) - fmt.Fprintf(fs, format, f.value) - return - } - - if f.value == nil { - if fs.Flag('#') { - fs.Write(interfaceBytes) - } - fs.Write(nilAngleBytes) - return - } - - f.format(reflect.ValueOf(f.value)) -} - -// newFormatter is a helper function to consolidate the logic from the various -// public methods which take varying config states. -func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter { - fs := &formatState{value: v, cs: cs} - fs.pointers = make(map[uintptr]int) - return fs -} - -/* -NewFormatter returns a custom formatter that satisfies the fmt.Formatter -interface. As a result, it integrates cleanly with standard fmt package -printing functions. The formatter is useful for inline printing of smaller data -types similar to the standard %v format specifier. - -The custom formatter only responds to the %v (most compact), %+v (adds pointer -addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb -combinations. Any other verbs such as %x and %q will be sent to the the -standard fmt package for formatting. In addition, the custom formatter ignores -the width and precision arguments (however they will still work on the format -specifiers not handled by the custom formatter). - -Typically this function shouldn't be called directly. It is much easier to make -use of the custom formatter by calling one of the convenience functions such as -Printf, Println, or Fprintf. -*/ -func NewFormatter(v interface{}) fmt.Formatter { - return newFormatter(&Config, v) -} diff --git a/components/engine/vendor/github.com/davecgh/go-spew/spew/spew.go b/components/engine/vendor/github.com/davecgh/go-spew/spew/spew.go deleted file mode 100644 index 32c0e338825..00000000000 --- a/components/engine/vendor/github.com/davecgh/go-spew/spew/spew.go +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2013-2016 Dave Collins - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -package spew - -import ( - "fmt" - "io" -) - -// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the formatted string as a value that satisfies error. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b)) -func Errorf(format string, a ...interface{}) (err error) { - return fmt.Errorf(format, convertArgs(a)...) -} - -// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b)) -func Fprint(w io.Writer, a ...interface{}) (n int, err error) { - return fmt.Fprint(w, convertArgs(a)...) -} - -// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b)) -func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { - return fmt.Fprintf(w, format, convertArgs(a)...) -} - -// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it -// passed with a default Formatter interface returned by NewFormatter. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b)) -func Fprintln(w io.Writer, a ...interface{}) (n int, err error) { - return fmt.Fprintln(w, convertArgs(a)...) -} - -// Print is a wrapper for fmt.Print that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b)) -func Print(a ...interface{}) (n int, err error) { - return fmt.Print(convertArgs(a)...) -} - -// Printf is a wrapper for fmt.Printf that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b)) -func Printf(format string, a ...interface{}) (n int, err error) { - return fmt.Printf(format, convertArgs(a)...) -} - -// Println is a wrapper for fmt.Println that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the number of bytes written and any write error encountered. See -// NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b)) -func Println(a ...interface{}) (n int, err error) { - return fmt.Println(convertArgs(a)...) -} - -// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b)) -func Sprint(a ...interface{}) string { - return fmt.Sprint(convertArgs(a)...) -} - -// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were -// passed with a default Formatter interface returned by NewFormatter. It -// returns the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b)) -func Sprintf(format string, a ...interface{}) string { - return fmt.Sprintf(format, convertArgs(a)...) -} - -// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it -// were passed with a default Formatter interface returned by NewFormatter. It -// returns the resulting string. See NewFormatter for formatting details. -// -// This function is shorthand for the following syntax: -// -// fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b)) -func Sprintln(a ...interface{}) string { - return fmt.Sprintln(convertArgs(a)...) -} - -// convertArgs accepts a slice of arguments and returns a slice of the same -// length with each argument converted to a default spew Formatter interface. -func convertArgs(args []interface{}) (formatters []interface{}) { - formatters = make([]interface{}, len(args)) - for index, arg := range args { - formatters[index] = NewFormatter(arg) - } - return formatters -} diff --git a/components/engine/vendor/github.com/google/go-cmp/README.md b/components/engine/vendor/github.com/google/go-cmp/README.md index d82f10bfcb5..61c9c4cd987 100644 --- a/components/engine/vendor/github.com/google/go-cmp/README.md +++ b/components/engine/vendor/github.com/google/go-cmp/README.md @@ -21,7 +21,7 @@ The primary features of `cmp` are: equality is determined by recursively comparing the primitive kinds on both values, much like `reflect.DeepEqual`. Unlike `reflect.DeepEqual`, unexported fields are not compared by default; they result in panics unless suppressed - by using an `Ignore` option (see `cmpopts.IgnoreUnexported`) or explictly + by using an `Ignore` option (see `cmpopts.IgnoreUnexported`) or explicitly compared using the `AllowUnexported` option. See the [GoDoc documentation][godoc] for more information. diff --git a/components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/equate.go b/components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/equate.go new file mode 100644 index 00000000000..41bbddc61b2 --- /dev/null +++ b/components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/equate.go @@ -0,0 +1,89 @@ +// Copyright 2017, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +// Package cmpopts provides common options for the cmp package. +package cmpopts + +import ( + "math" + "reflect" + + "github.com/google/go-cmp/cmp" +) + +func equateAlways(_, _ interface{}) bool { return true } + +// EquateEmpty returns a Comparer option that determines all maps and slices +// with a length of zero to be equal, regardless of whether they are nil. +// +// EquateEmpty can be used in conjunction with SortSlices and SortMaps. +func EquateEmpty() cmp.Option { + return cmp.FilterValues(isEmpty, cmp.Comparer(equateAlways)) +} + +func isEmpty(x, y interface{}) bool { + vx, vy := reflect.ValueOf(x), reflect.ValueOf(y) + return (x != nil && y != nil && vx.Type() == vy.Type()) && + (vx.Kind() == reflect.Slice || vx.Kind() == reflect.Map) && + (vx.Len() == 0 && vy.Len() == 0) +} + +// EquateApprox returns a Comparer option that determines float32 or float64 +// values to be equal if they are within a relative fraction or absolute margin. +// This option is not used when either x or y is NaN or infinite. +// +// The fraction determines that the difference of two values must be within the +// smaller fraction of the two values, while the margin determines that the two +// values must be within some absolute margin. +// To express only a fraction or only a margin, use 0 for the other parameter. +// The fraction and margin must be non-negative. +// +// The mathematical expression used is equivalent to: +// |x-y| ≤ max(fraction*min(|x|, |y|), margin) +// +// EquateApprox can be used in conjunction with EquateNaNs. +func EquateApprox(fraction, margin float64) cmp.Option { + if margin < 0 || fraction < 0 || math.IsNaN(margin) || math.IsNaN(fraction) { + panic("margin or fraction must be a non-negative number") + } + a := approximator{fraction, margin} + return cmp.Options{ + cmp.FilterValues(areRealF64s, cmp.Comparer(a.compareF64)), + cmp.FilterValues(areRealF32s, cmp.Comparer(a.compareF32)), + } +} + +type approximator struct{ frac, marg float64 } + +func areRealF64s(x, y float64) bool { + return !math.IsNaN(x) && !math.IsNaN(y) && !math.IsInf(x, 0) && !math.IsInf(y, 0) +} +func areRealF32s(x, y float32) bool { + return areRealF64s(float64(x), float64(y)) +} +func (a approximator) compareF64(x, y float64) bool { + relMarg := a.frac * math.Min(math.Abs(x), math.Abs(y)) + return math.Abs(x-y) <= math.Max(a.marg, relMarg) +} +func (a approximator) compareF32(x, y float32) bool { + return a.compareF64(float64(x), float64(y)) +} + +// EquateNaNs returns a Comparer option that determines float32 and float64 +// NaN values to be equal. +// +// EquateNaNs can be used in conjunction with EquateApprox. +func EquateNaNs() cmp.Option { + return cmp.Options{ + cmp.FilterValues(areNaNsF64s, cmp.Comparer(equateAlways)), + cmp.FilterValues(areNaNsF32s, cmp.Comparer(equateAlways)), + } +} + +func areNaNsF64s(x, y float64) bool { + return math.IsNaN(x) && math.IsNaN(y) +} +func areNaNsF32s(x, y float32) bool { + return areNaNsF64s(float64(x), float64(y)) +} diff --git a/components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/ignore.go b/components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/ignore.go new file mode 100644 index 00000000000..e86554b92b4 --- /dev/null +++ b/components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/ignore.go @@ -0,0 +1,145 @@ +// Copyright 2017, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +package cmpopts + +import ( + "fmt" + "reflect" + "unicode" + "unicode/utf8" + + "github.com/google/go-cmp/cmp" +) + +// IgnoreFields returns an Option that ignores exported fields of the +// given names on a single struct type. +// The struct type is specified by passing in a value of that type. +// +// The name may be a dot-delimited string (e.g., "Foo.Bar") to ignore a +// specific sub-field that is embedded or nested within the parent struct. +// +// This does not handle unexported fields; use IgnoreUnexported instead. +func IgnoreFields(typ interface{}, names ...string) cmp.Option { + sf := newStructFilter(typ, names...) + return cmp.FilterPath(sf.filter, cmp.Ignore()) +} + +// IgnoreTypes returns an Option that ignores all values assignable to +// certain types, which are specified by passing in a value of each type. +func IgnoreTypes(typs ...interface{}) cmp.Option { + tf := newTypeFilter(typs...) + return cmp.FilterPath(tf.filter, cmp.Ignore()) +} + +type typeFilter []reflect.Type + +func newTypeFilter(typs ...interface{}) (tf typeFilter) { + for _, typ := range typs { + t := reflect.TypeOf(typ) + if t == nil { + // This occurs if someone tries to pass in sync.Locker(nil) + panic("cannot determine type; consider using IgnoreInterfaces") + } + tf = append(tf, t) + } + return tf +} +func (tf typeFilter) filter(p cmp.Path) bool { + if len(p) < 1 { + return false + } + t := p.Last().Type() + for _, ti := range tf { + if t.AssignableTo(ti) { + return true + } + } + return false +} + +// IgnoreInterfaces returns an Option that ignores all values or references of +// values assignable to certain interface types. These interfaces are specified +// by passing in an anonymous struct with the interface types embedded in it. +// For example, to ignore sync.Locker, pass in struct{sync.Locker}{}. +func IgnoreInterfaces(ifaces interface{}) cmp.Option { + tf := newIfaceFilter(ifaces) + return cmp.FilterPath(tf.filter, cmp.Ignore()) +} + +type ifaceFilter []reflect.Type + +func newIfaceFilter(ifaces interface{}) (tf ifaceFilter) { + t := reflect.TypeOf(ifaces) + if ifaces == nil || t.Name() != "" || t.Kind() != reflect.Struct { + panic("input must be an anonymous struct") + } + for i := 0; i < t.NumField(); i++ { + fi := t.Field(i) + switch { + case !fi.Anonymous: + panic("struct cannot have named fields") + case fi.Type.Kind() != reflect.Interface: + panic("embedded field must be an interface type") + case fi.Type.NumMethod() == 0: + // This matches everything; why would you ever want this? + panic("cannot ignore empty interface") + default: + tf = append(tf, fi.Type) + } + } + return tf +} +func (tf ifaceFilter) filter(p cmp.Path) bool { + if len(p) < 1 { + return false + } + t := p.Last().Type() + for _, ti := range tf { + if t.AssignableTo(ti) { + return true + } + if t.Kind() != reflect.Ptr && reflect.PtrTo(t).AssignableTo(ti) { + return true + } + } + return false +} + +// IgnoreUnexported returns an Option that only ignores the immediate unexported +// fields of a struct, including anonymous fields of unexported types. +// In particular, unexported fields within the struct's exported fields +// of struct types, including anonymous fields, will not be ignored unless the +// type of the field itself is also passed to IgnoreUnexported. +func IgnoreUnexported(typs ...interface{}) cmp.Option { + ux := newUnexportedFilter(typs...) + return cmp.FilterPath(ux.filter, cmp.Ignore()) +} + +type unexportedFilter struct{ m map[reflect.Type]bool } + +func newUnexportedFilter(typs ...interface{}) unexportedFilter { + ux := unexportedFilter{m: make(map[reflect.Type]bool)} + for _, typ := range typs { + t := reflect.TypeOf(typ) + if t == nil || t.Kind() != reflect.Struct { + panic(fmt.Sprintf("invalid struct type: %T", typ)) + } + ux.m[t] = true + } + return ux +} +func (xf unexportedFilter) filter(p cmp.Path) bool { + sf, ok := p.Index(-1).(cmp.StructField) + if !ok { + return false + } + return xf.m[p.Index(-2).Type()] && !isExported(sf.Name()) +} + +// isExported reports whether the identifier is exported. +func isExported(id string) bool { + r, _ := utf8.DecodeRuneInString(id) + return unicode.IsUpper(r) +} diff --git a/components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/sort.go b/components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/sort.go new file mode 100644 index 00000000000..da17d746938 --- /dev/null +++ b/components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/sort.go @@ -0,0 +1,146 @@ +// Copyright 2017, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +package cmpopts + +import ( + "fmt" + "reflect" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/internal/function" +) + +// SortSlices returns a Transformer option that sorts all []V. +// The less function must be of the form "func(T, T) bool" which is used to +// sort any slice with element type V that is assignable to T. +// +// The less function must be: +// • Deterministic: less(x, y) == less(x, y) +// • Irreflexive: !less(x, x) +// • Transitive: if !less(x, y) and !less(y, z), then !less(x, z) +// +// The less function does not have to be "total". That is, if !less(x, y) and +// !less(y, x) for two elements x and y, their relative order is maintained. +// +// SortSlices can be used in conjunction with EquateEmpty. +func SortSlices(less interface{}) cmp.Option { + vf := reflect.ValueOf(less) + if !function.IsType(vf.Type(), function.Less) || vf.IsNil() { + panic(fmt.Sprintf("invalid less function: %T", less)) + } + ss := sliceSorter{vf.Type().In(0), vf} + return cmp.FilterValues(ss.filter, cmp.Transformer("Sort", ss.sort)) +} + +type sliceSorter struct { + in reflect.Type // T + fnc reflect.Value // func(T, T) bool +} + +func (ss sliceSorter) filter(x, y interface{}) bool { + vx, vy := reflect.ValueOf(x), reflect.ValueOf(y) + if !(x != nil && y != nil && vx.Type() == vy.Type()) || + !(vx.Kind() == reflect.Slice && vx.Type().Elem().AssignableTo(ss.in)) || + (vx.Len() <= 1 && vy.Len() <= 1) { + return false + } + // Check whether the slices are already sorted to avoid an infinite + // recursion cycle applying the same transform to itself. + ok1 := sliceIsSorted(x, func(i, j int) bool { return ss.less(vx, i, j) }) + ok2 := sliceIsSorted(y, func(i, j int) bool { return ss.less(vy, i, j) }) + return !ok1 || !ok2 +} +func (ss sliceSorter) sort(x interface{}) interface{} { + src := reflect.ValueOf(x) + dst := reflect.MakeSlice(src.Type(), src.Len(), src.Len()) + for i := 0; i < src.Len(); i++ { + dst.Index(i).Set(src.Index(i)) + } + sortSliceStable(dst.Interface(), func(i, j int) bool { return ss.less(dst, i, j) }) + ss.checkSort(dst) + return dst.Interface() +} +func (ss sliceSorter) checkSort(v reflect.Value) { + start := -1 // Start of a sequence of equal elements. + for i := 1; i < v.Len(); i++ { + if ss.less(v, i-1, i) { + // Check that first and last elements in v[start:i] are equal. + if start >= 0 && (ss.less(v, start, i-1) || ss.less(v, i-1, start)) { + panic(fmt.Sprintf("incomparable values detected: want equal elements: %v", v.Slice(start, i))) + } + start = -1 + } else if start == -1 { + start = i + } + } +} +func (ss sliceSorter) less(v reflect.Value, i, j int) bool { + vx, vy := v.Index(i), v.Index(j) + return ss.fnc.Call([]reflect.Value{vx, vy})[0].Bool() +} + +// SortMaps returns a Transformer option that flattens map[K]V types to be a +// sorted []struct{K, V}. The less function must be of the form +// "func(T, T) bool" which is used to sort any map with key K that is +// assignable to T. +// +// Flattening the map into a slice has the property that cmp.Equal is able to +// use Comparers on K or the K.Equal method if it exists. +// +// The less function must be: +// • Deterministic: less(x, y) == less(x, y) +// • Irreflexive: !less(x, x) +// • Transitive: if !less(x, y) and !less(y, z), then !less(x, z) +// • Total: if x != y, then either less(x, y) or less(y, x) +// +// SortMaps can be used in conjunction with EquateEmpty. +func SortMaps(less interface{}) cmp.Option { + vf := reflect.ValueOf(less) + if !function.IsType(vf.Type(), function.Less) || vf.IsNil() { + panic(fmt.Sprintf("invalid less function: %T", less)) + } + ms := mapSorter{vf.Type().In(0), vf} + return cmp.FilterValues(ms.filter, cmp.Transformer("Sort", ms.sort)) +} + +type mapSorter struct { + in reflect.Type // T + fnc reflect.Value // func(T, T) bool +} + +func (ms mapSorter) filter(x, y interface{}) bool { + vx, vy := reflect.ValueOf(x), reflect.ValueOf(y) + return (x != nil && y != nil && vx.Type() == vy.Type()) && + (vx.Kind() == reflect.Map && vx.Type().Key().AssignableTo(ms.in)) && + (vx.Len() != 0 || vy.Len() != 0) +} +func (ms mapSorter) sort(x interface{}) interface{} { + src := reflect.ValueOf(x) + outType := mapEntryType(src.Type()) + dst := reflect.MakeSlice(reflect.SliceOf(outType), src.Len(), src.Len()) + for i, k := range src.MapKeys() { + v := reflect.New(outType).Elem() + v.Field(0).Set(k) + v.Field(1).Set(src.MapIndex(k)) + dst.Index(i).Set(v) + } + sortSlice(dst.Interface(), func(i, j int) bool { return ms.less(dst, i, j) }) + ms.checkSort(dst) + return dst.Interface() +} +func (ms mapSorter) checkSort(v reflect.Value) { + for i := 1; i < v.Len(); i++ { + if !ms.less(v, i-1, i) { + panic(fmt.Sprintf("partial order detected: want %v < %v", v.Index(i-1), v.Index(i))) + } + } +} +func (ms mapSorter) less(v reflect.Value, i, j int) bool { + vx, vy := v.Index(i).Field(0), v.Index(j).Field(0) + if !hasReflectStructOf { + vx, vy = vx.Elem(), vy.Elem() + } + return ms.fnc.Call([]reflect.Value{vx, vy})[0].Bool() +} diff --git a/components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/sort_go17.go b/components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/sort_go17.go new file mode 100644 index 00000000000..839b88ca402 --- /dev/null +++ b/components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/sort_go17.go @@ -0,0 +1,46 @@ +// Copyright 2017, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +// +build !go1.8 + +package cmpopts + +import ( + "reflect" + "sort" +) + +const hasReflectStructOf = false + +func mapEntryType(reflect.Type) reflect.Type { + return reflect.TypeOf(struct{ K, V interface{} }{}) +} + +func sliceIsSorted(slice interface{}, less func(i, j int) bool) bool { + return sort.IsSorted(reflectSliceSorter{reflect.ValueOf(slice), less}) +} +func sortSlice(slice interface{}, less func(i, j int) bool) { + sort.Sort(reflectSliceSorter{reflect.ValueOf(slice), less}) +} +func sortSliceStable(slice interface{}, less func(i, j int) bool) { + sort.Stable(reflectSliceSorter{reflect.ValueOf(slice), less}) +} + +type reflectSliceSorter struct { + slice reflect.Value + less func(i, j int) bool +} + +func (ss reflectSliceSorter) Len() int { + return ss.slice.Len() +} +func (ss reflectSliceSorter) Less(i, j int) bool { + return ss.less(i, j) +} +func (ss reflectSliceSorter) Swap(i, j int) { + vi := ss.slice.Index(i).Interface() + vj := ss.slice.Index(j).Interface() + ss.slice.Index(i).Set(reflect.ValueOf(vj)) + ss.slice.Index(j).Set(reflect.ValueOf(vi)) +} diff --git a/components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/sort_go18.go b/components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/sort_go18.go new file mode 100644 index 00000000000..8a59c0d38fd --- /dev/null +++ b/components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/sort_go18.go @@ -0,0 +1,31 @@ +// Copyright 2017, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +// +build go1.8 + +package cmpopts + +import ( + "reflect" + "sort" +) + +const hasReflectStructOf = true + +func mapEntryType(t reflect.Type) reflect.Type { + return reflect.StructOf([]reflect.StructField{ + {Name: "K", Type: t.Key()}, + {Name: "V", Type: t.Elem()}, + }) +} + +func sliceIsSorted(slice interface{}, less func(i, j int) bool) bool { + return sort.SliceIsSorted(slice, less) +} +func sortSlice(slice interface{}, less func(i, j int) bool) { + sort.Slice(slice, less) +} +func sortSliceStable(slice interface{}, less func(i, j int) bool) { + sort.SliceStable(slice, less) +} diff --git a/components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/struct_filter.go b/components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/struct_filter.go new file mode 100644 index 00000000000..97f707983c0 --- /dev/null +++ b/components/engine/vendor/github.com/google/go-cmp/cmp/cmpopts/struct_filter.go @@ -0,0 +1,182 @@ +// Copyright 2017, The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE.md file. + +package cmpopts + +import ( + "fmt" + "reflect" + "strings" + + "github.com/google/go-cmp/cmp" +) + +// filterField returns a new Option where opt is only evaluated on paths that +// include a specific exported field on a single struct type. +// The struct type is specified by passing in a value of that type. +// +// The name may be a dot-delimited string (e.g., "Foo.Bar") to select a +// specific sub-field that is embedded or nested within the parent struct. +func filterField(typ interface{}, name string, opt cmp.Option) cmp.Option { + // TODO: This is currently unexported over concerns of how helper filters + // can be composed together easily. + // TODO: Add tests for FilterField. + + sf := newStructFilter(typ, name) + return cmp.FilterPath(sf.filter, opt) +} + +type structFilter struct { + t reflect.Type // The root struct type to match on + ft fieldTree // Tree of fields to match on +} + +func newStructFilter(typ interface{}, names ...string) structFilter { + // TODO: Perhaps allow * as a special identifier to allow ignoring any + // number of path steps until the next field match? + // This could be useful when a concrete struct gets transformed into + // an anonymous struct where it is not possible to specify that by type, + // but the transformer happens to provide guarantees about the names of + // the transformed fields. + + t := reflect.TypeOf(typ) + if t == nil || t.Kind() != reflect.Struct { + panic(fmt.Sprintf("%T must be a struct", typ)) + } + var ft fieldTree + for _, name := range names { + cname, err := canonicalName(t, name) + if err != nil { + panic(fmt.Sprintf("%s: %v", strings.Join(cname, "."), err)) + } + ft.insert(cname) + } + return structFilter{t, ft} +} + +func (sf structFilter) filter(p cmp.Path) bool { + for i, ps := range p { + if ps.Type().AssignableTo(sf.t) && sf.ft.matchPrefix(p[i+1:]) { + return true + } + } + return false +} + +// fieldTree represents a set of dot-separated identifiers. +// +// For example, inserting the following selectors: +// Foo +// Foo.Bar.Baz +// Foo.Buzz +// Nuka.Cola.Quantum +// +// Results in a tree of the form: +// {sub: { +// "Foo": {ok: true, sub: { +// "Bar": {sub: { +// "Baz": {ok: true}, +// }}, +// "Buzz": {ok: true}, +// }}, +// "Nuka": {sub: { +// "Cola": {sub: { +// "Quantum": {ok: true}, +// }}, +// }}, +// }} +type fieldTree struct { + ok bool // Whether this is a specified node + sub map[string]fieldTree // The sub-tree of fields under this node +} + +// insert inserts a sequence of field accesses into the tree. +func (ft *fieldTree) insert(cname []string) { + if ft.sub == nil { + ft.sub = make(map[string]fieldTree) + } + if len(cname) == 0 { + ft.ok = true + return + } + sub := ft.sub[cname[0]] + sub.insert(cname[1:]) + ft.sub[cname[0]] = sub +} + +// matchPrefix reports whether any selector in the fieldTree matches +// the start of path p. +func (ft fieldTree) matchPrefix(p cmp.Path) bool { + for _, ps := range p { + switch ps := ps.(type) { + case cmp.StructField: + ft = ft.sub[ps.Name()] + if ft.ok { + return true + } + if len(ft.sub) == 0 { + return false + } + case cmp.Indirect: + default: + return false + } + } + return false +} + +// canonicalName returns a list of identifiers where any struct field access +// through an embedded field is expanded to include the names of the embedded +// types themselves. +// +// For example, suppose field "Foo" is not directly in the parent struct, +// but actually from an embedded struct of type "Bar". Then, the canonical name +// of "Foo" is actually "Bar.Foo". +// +// Suppose field "Foo" is not directly in the parent struct, but actually +// a field in two different embedded structs of types "Bar" and "Baz". +// Then the selector "Foo" causes a panic since it is ambiguous which one it +// refers to. The user must specify either "Bar.Foo" or "Baz.Foo". +func canonicalName(t reflect.Type, sel string) ([]string, error) { + var name string + sel = strings.TrimPrefix(sel, ".") + if sel == "" { + return nil, fmt.Errorf("name must not be empty") + } + if i := strings.IndexByte(sel, '.'); i < 0 { + name, sel = sel, "" + } else { + name, sel = sel[:i], sel[i:] + } + + // Type must be a struct or pointer to struct. + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + if t.Kind() != reflect.Struct { + return nil, fmt.Errorf("%v must be a struct", t) + } + + // Find the canonical name for this current field name. + // If the field exists in an embedded struct, then it will be expanded. + if !isExported(name) { + // Disallow unexported fields: + // * To discourage people from actually touching unexported fields + // * FieldByName is buggy (https://golang.org/issue/4876) + return []string{name}, fmt.Errorf("name must be exported") + } + sf, ok := t.FieldByName(name) + if !ok { + return []string{name}, fmt.Errorf("does not exist") + } + var ss []string + for i := range sf.Index { + ss = append(ss, t.FieldByIndex(sf.Index[:i+1]).Name) + } + if sel == "" { + return ss, nil + } + ssPost, err := canonicalName(sf.Type, sel) + return append(ss, ssPost...), err +} diff --git a/components/engine/vendor/github.com/google/go-cmp/cmp/compare.go b/components/engine/vendor/github.com/google/go-cmp/cmp/compare.go index 5527f014976..7e215f22029 100644 --- a/components/engine/vendor/github.com/google/go-cmp/cmp/compare.go +++ b/components/engine/vendor/github.com/google/go-cmp/cmp/compare.go @@ -22,7 +22,7 @@ // equality is determined by recursively comparing the primitive kinds on both // values, much like reflect.DeepEqual. Unlike reflect.DeepEqual, unexported // fields are not compared by default; they result in panics unless suppressed -// by using an Ignore option (see cmpopts.IgnoreUnexported) or explictly compared +// by using an Ignore option (see cmpopts.IgnoreUnexported) or explicitly compared // using the AllowUnexported option. package cmp @@ -35,7 +35,7 @@ import ( "github.com/google/go-cmp/cmp/internal/value" ) -// BUG: Maps with keys containing NaN values cannot be properly compared due to +// BUG(dsnet): Maps with keys containing NaN values cannot be properly compared due to // the reflection package's inability to retrieve such entries. Equal will panic // anytime it comes across a NaN key, but this behavior may change. // @@ -61,8 +61,8 @@ var nothing = reflect.Value{} // // • If the values have an Equal method of the form "(T) Equal(T) bool" or // "(T) Equal(I) bool" where T is assignable to I, then use the result of -// x.Equal(y). Otherwise, no such method exists and evaluation proceeds to -// the next rule. +// x.Equal(y) even if x or y is nil. +// Otherwise, no such method exists and evaluation proceeds to the next rule. // // • Lastly, try to compare x and y based on their basic kinds. // Simple kinds like booleans, integers, floats, complex numbers, strings, and @@ -304,7 +304,8 @@ func (s *state) tryOptions(vx, vy reflect.Value, t reflect.Type) bool { // Evaluate all filters and apply the remaining options. if opt := opts.filter(s, vx, vy, t); opt != nil { - return opt.apply(s, vx, vy) + opt.apply(s, vx, vy) + return true } return false } @@ -322,6 +323,7 @@ func (s *state) tryMethod(vx, vy reflect.Value, t reflect.Type) bool { } func (s *state) callTRFunc(f, v reflect.Value) reflect.Value { + v = sanitizeValue(v, f.Type().In(0)) if !s.dynChecker.Next() { return f.Call([]reflect.Value{v})[0] } @@ -345,6 +347,8 @@ func (s *state) callTRFunc(f, v reflect.Value) reflect.Value { } func (s *state) callTTBFunc(f, x, y reflect.Value) bool { + x = sanitizeValue(x, f.Type().In(0)) + y = sanitizeValue(y, f.Type().In(1)) if !s.dynChecker.Next() { return f.Call([]reflect.Value{x, y})[0].Bool() } @@ -372,20 +376,40 @@ func detectRaces(c chan<- reflect.Value, f reflect.Value, vs ...reflect.Value) { ret = f.Call(vs)[0] } +// sanitizeValue converts nil interfaces of type T to those of type R, +// assuming that T is assignable to R. +// Otherwise, it returns the input value as is. +func sanitizeValue(v reflect.Value, t reflect.Type) reflect.Value { + // TODO(dsnet): Remove this hacky workaround. + // See https://golang.org/issue/22143 + if v.Kind() == reflect.Interface && v.IsNil() && v.Type() != t { + return reflect.New(t).Elem() + } + return v +} + func (s *state) compareArray(vx, vy reflect.Value, t reflect.Type) { step := &sliceIndex{pathStep{t.Elem()}, 0, 0} s.curPath.push(step) // Compute an edit-script for slices vx and vy. - eq, es := diff.Difference(vx.Len(), vy.Len(), func(ix, iy int) diff.Result { + es := diff.Difference(vx.Len(), vy.Len(), func(ix, iy int) diff.Result { step.xkey, step.ykey = ix, iy return s.statelessCompare(vx.Index(ix), vy.Index(iy)) }) - // Equal or no edit-script, so report entire slices as is. - if eq || es == nil { + // Report the entire slice as is if the arrays are of primitive kind, + // and the arrays are different enough. + isPrimitive := false + switch t.Elem().Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, + reflect.Bool, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128: + isPrimitive = true + } + if isPrimitive && es.Dist() > (vx.Len()+vy.Len())/4 { s.curPath.pop() // Pop first since we are reporting the whole slice - s.report(eq, vx, vy) + s.report(false, vx, vy) return } diff --git a/components/engine/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go b/components/engine/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go index ba46c62e1c1..fd9f7f17739 100644 --- a/components/engine/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go +++ b/components/engine/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go @@ -50,7 +50,7 @@ import ( // // The series of '.', 'X', 'Y', and 'M' characters at the bottom represents // the currently established path from the forward and reverse searches, -// seperated by a '|' character. +// separated by a '|' character. const ( updateDelay = 100 * time.Millisecond diff --git a/components/engine/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go b/components/engine/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go index baa41fd23ca..260befea2fd 100644 --- a/components/engine/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go +++ b/components/engine/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go @@ -106,9 +106,9 @@ func (r Result) Similar() bool { // Difference reports whether two lists of lengths nx and ny are equal // given the definition of equality provided as f. // -// This function may return a edit-script, which is a sequence of operations -// needed to convert one list into the other. If non-nil, the following -// invariants for the edit-script are maintained: +// This function returns an edit-script, which is a sequence of operations +// needed to convert one list into the other. The following invariants for +// the edit-script are maintained: // • eq == (es.Dist()==0) // • nx == es.LenX() // • ny == es.LenY() @@ -117,17 +117,7 @@ func (r Result) Similar() bool { // produces an edit-script with a minimal Levenshtein distance). This algorithm // favors performance over optimality. The exact output is not guaranteed to // be stable and may change over time. -func Difference(nx, ny int, f EqualFunc) (eq bool, es EditScript) { - es = searchGraph(nx, ny, f) - st := es.stats() - eq = len(es) == st.NI - if !eq && st.NI < (nx+ny)/4 { - return eq, nil // Edit-script more distracting than helpful - } - return eq, es -} - -func searchGraph(nx, ny int, f EqualFunc) EditScript { +func Difference(nx, ny int, f EqualFunc) (es EditScript) { // This algorithm is based on traversing what is known as an "edit-graph". // See Figure 1 from "An O(ND) Difference Algorithm and Its Variations" // by Eugene W. Myers. Since D can be as large as N itself, this is diff --git a/components/engine/vendor/github.com/google/go-cmp/cmp/internal/value/format.go b/components/engine/vendor/github.com/google/go-cmp/cmp/internal/value/format.go index abaeca89e79..657e508779d 100644 --- a/components/engine/vendor/github.com/google/go-cmp/cmp/internal/value/format.go +++ b/components/engine/vendor/github.com/google/go-cmp/cmp/internal/value/format.go @@ -8,15 +8,11 @@ package value import ( "fmt" "reflect" + "strconv" "strings" "unicode" - "unicode/utf8" ) -// formatFakePointers controls whether to substitute pointer addresses with nil. -// This is used for deterministic testing. -var formatFakePointers = false - var stringerIface = reflect.TypeOf((*fmt.Stringer)(nil)).Elem() // Format formats the value v as a string. @@ -26,28 +22,35 @@ var stringerIface = reflect.TypeOf((*fmt.Stringer)(nil)).Elem() // * Avoids printing struct fields that are zero // * Prints a nil-slice as being nil, not empty // * Prints map entries in deterministic order -func Format(v reflect.Value, useStringer bool) string { - return formatAny(v, formatConfig{useStringer, true, true, !formatFakePointers}, nil) +func Format(v reflect.Value, conf FormatConfig) string { + conf.printType = true + conf.followPointers = true + conf.realPointers = true + return formatAny(v, conf, nil) } -type formatConfig struct { - useStringer bool // Should the String method be used if available? - printType bool // Should we print the type before the value? - followPointers bool // Should we recursively follow pointers? - realPointers bool // Should we print the real address of pointers? +type FormatConfig struct { + UseStringer bool // Should the String method be used if available? + printType bool // Should we print the type before the value? + PrintPrimitiveType bool // Should we print the type of primitives? + followPointers bool // Should we recursively follow pointers? + realPointers bool // Should we print the real address of pointers? } -func formatAny(v reflect.Value, conf formatConfig, visited map[uintptr]bool) string { +func formatAny(v reflect.Value, conf FormatConfig, visited map[uintptr]bool) string { // TODO: Should this be a multi-line printout in certain situations? if !v.IsValid() { return "" } - if conf.useStringer && v.Type().Implements(stringerIface) && v.CanInterface() { + if conf.UseStringer && v.Type().Implements(stringerIface) && v.CanInterface() { if (v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface) && v.IsNil() { return "" } - return fmt.Sprintf("%q", v.Interface().(fmt.Stringer).String()) + + const stringerPrefix = "s" // Indicates that the String method was used + s := v.Interface().(fmt.Stringer).String() + return stringerPrefix + formatString(s) } switch v.Kind() { @@ -66,7 +69,7 @@ func formatAny(v reflect.Value, conf formatConfig, visited map[uintptr]bool) str case reflect.Complex64, reflect.Complex128: return formatPrimitive(v.Type(), v.Complex(), conf) case reflect.String: - return formatPrimitive(v.Type(), fmt.Sprintf("%q", v), conf) + return formatPrimitive(v.Type(), formatString(v.String()), conf) case reflect.UnsafePointer, reflect.Chan, reflect.Func: return formatPointer(v, conf) case reflect.Ptr: @@ -127,11 +130,13 @@ func formatAny(v reflect.Value, conf formatConfig, visited map[uintptr]bool) str visited = insertPointer(visited, v.Pointer()) var ss []string - subConf := conf - subConf.printType = v.Type().Elem().Kind() == reflect.Interface + keyConf, valConf := conf, conf + keyConf.printType = v.Type().Key().Kind() == reflect.Interface + keyConf.followPointers = false + valConf.printType = v.Type().Elem().Kind() == reflect.Interface for _, k := range SortKeys(v.MapKeys()) { - sk := formatAny(k, formatConfig{realPointers: conf.realPointers}, visited) - sv := formatAny(v.MapIndex(k), subConf, visited) + sk := formatAny(k, keyConf, visited) + sv := formatAny(v.MapIndex(k), valConf, visited) ss = append(ss, fmt.Sprintf("%s: %s", sk, sv)) } s := fmt.Sprintf("{%s}", strings.Join(ss, ", ")) @@ -149,7 +154,7 @@ func formatAny(v reflect.Value, conf formatConfig, visited map[uintptr]bool) str continue // Elide zero value fields } name := v.Type().Field(i).Name - subConf.useStringer = conf.useStringer && isExported(name) + subConf.UseStringer = conf.UseStringer s := formatAny(vv, subConf, visited) ss = append(ss, fmt.Sprintf("%s: %s", name, s)) } @@ -163,14 +168,33 @@ func formatAny(v reflect.Value, conf formatConfig, visited map[uintptr]bool) str } } -func formatPrimitive(t reflect.Type, v interface{}, conf formatConfig) string { - if conf.printType && t.PkgPath() != "" { +func formatString(s string) string { + // Use quoted string if it the same length as a raw string literal. + // Otherwise, attempt to use the raw string form. + qs := strconv.Quote(s) + if len(qs) == 1+len(s)+1 { + return qs + } + + // Disallow newlines to ensure output is a single line. + // Only allow printable runes for readability purposes. + rawInvalid := func(r rune) bool { + return r == '`' || r == '\n' || !unicode.IsPrint(r) + } + if strings.IndexFunc(s, rawInvalid) < 0 { + return "`" + s + "`" + } + return qs +} + +func formatPrimitive(t reflect.Type, v interface{}, conf FormatConfig) string { + if conf.printType && (conf.PrintPrimitiveType || t.PkgPath() != "") { return fmt.Sprintf("%v(%v)", t, v) } return fmt.Sprintf("%v", v) } -func formatPointer(v reflect.Value, conf formatConfig) string { +func formatPointer(v reflect.Value, conf FormatConfig) string { p := v.Pointer() if !conf.realPointers { p = 0 // For deterministic printing purposes @@ -251,9 +275,3 @@ func isZero(v reflect.Value) bool { } return false } - -// isExported reports whether the identifier is exported. -func isExported(id string) bool { - r, _ := utf8.DecodeRuneInString(id) - return unicode.IsUpper(r) -} diff --git a/components/engine/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go b/components/engine/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go index ea73cf14391..fe8aa27a077 100644 --- a/components/engine/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go +++ b/components/engine/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go @@ -24,7 +24,7 @@ func SortKeys(vs []reflect.Value) []reflect.Value { // Deduplicate keys (fails for NaNs). vs2 := vs[:1] for _, v := range vs[1:] { - if v.Interface() != vs2[len(vs2)-1].Interface() { + if isLess(vs2[len(vs2)-1], v) { vs2 = append(vs2, v) } } diff --git a/components/engine/vendor/github.com/google/go-cmp/cmp/options.go b/components/engine/vendor/github.com/google/go-cmp/cmp/options.go index a4e159ac483..91d4b066e05 100644 --- a/components/engine/vendor/github.com/google/go-cmp/cmp/options.go +++ b/components/engine/vendor/github.com/google/go-cmp/cmp/options.go @@ -38,9 +38,8 @@ type Option interface { type applicableOption interface { Option - // apply executes the option and reports whether the option was applied. - // Each option may mutate s. - apply(s *state, vx, vy reflect.Value) bool + // apply executes the option, which may mutate s or panic. + apply(s *state, vx, vy reflect.Value) } // coreOption represents the following types: @@ -85,7 +84,7 @@ func (opts Options) filter(s *state, vx, vy reflect.Value, t reflect.Type) (out return out } -func (opts Options) apply(s *state, _, _ reflect.Value) bool { +func (opts Options) apply(s *state, _, _ reflect.Value) { const warning = "ambiguous set of applicable options" const help = "consider using filters to ensure at most one Comparer or Transformer may apply" var ss []string @@ -196,7 +195,7 @@ type ignore struct{ core } func (ignore) isFiltered() bool { return false } func (ignore) filter(_ *state, _, _ reflect.Value, _ reflect.Type) applicableOption { return ignore{} } -func (ignore) apply(_ *state, _, _ reflect.Value) bool { return true } +func (ignore) apply(_ *state, _, _ reflect.Value) { return } func (ignore) String() string { return "Ignore()" } // invalid is a sentinel Option type to indicate that some options could not @@ -204,7 +203,7 @@ func (ignore) String() string type invalid struct{ core } func (invalid) filter(_ *state, _, _ reflect.Value, _ reflect.Type) applicableOption { return invalid{} } -func (invalid) apply(s *state, _, _ reflect.Value) bool { +func (invalid) apply(s *state, _, _ reflect.Value) { const help = "consider using AllowUnexported or cmpopts.IgnoreUnexported" panic(fmt.Sprintf("cannot handle unexported field: %#v\n%s", s.curPath, help)) } @@ -215,9 +214,12 @@ func (invalid) apply(s *state, _, _ reflect.Value) bool { // The transformer f must be a function "func(T) R" that converts values of // type T to those of type R and is implicitly filtered to input values // assignable to T. The transformer must not mutate T in any way. -// If T and R are the same type, an additional filter must be applied to -// act as the base case to prevent an infinite recursion applying the same -// transform to itself (see the SortedSlice example). +// +// To help prevent some cases of infinite recursive cycles applying the +// same transform to the output of itself (e.g., in the case where the +// input and output types are the same), an implicit filter is added such that +// a transformer is applicable only if that exact transformer is not already +// in the tail of the Path since the last non-Transform step. // // The name is a user provided label that is used as the Transform.Name in the // transformation PathStep. If empty, an arbitrary name is used. @@ -248,14 +250,21 @@ type transformer struct { func (tr *transformer) isFiltered() bool { return tr.typ != nil } -func (tr *transformer) filter(_ *state, _, _ reflect.Value, t reflect.Type) applicableOption { +func (tr *transformer) filter(s *state, _, _ reflect.Value, t reflect.Type) applicableOption { + for i := len(s.curPath) - 1; i >= 0; i-- { + if t, ok := s.curPath[i].(*transform); !ok { + break // Hit most recent non-Transform step + } else if tr == t.trans { + return nil // Cannot directly use same Transform + } + } if tr.typ == nil || t.AssignableTo(tr.typ) { return tr } return nil } -func (tr *transformer) apply(s *state, vx, vy reflect.Value) bool { +func (tr *transformer) apply(s *state, vx, vy reflect.Value) { // Update path before calling the Transformer so that dynamic checks // will use the updated path. s.curPath.push(&transform{pathStep{tr.fnc.Type().Out(0)}, tr}) @@ -264,7 +273,6 @@ func (tr *transformer) apply(s *state, vx, vy reflect.Value) bool { vx = s.callTRFunc(tr.fnc, vx) vy = s.callTRFunc(tr.fnc, vy) s.compareAny(vx, vy) - return true } func (tr transformer) String() string { @@ -310,10 +318,9 @@ func (cm *comparer) filter(_ *state, _, _ reflect.Value, t reflect.Type) applica return nil } -func (cm *comparer) apply(s *state, vx, vy reflect.Value) bool { +func (cm *comparer) apply(s *state, vx, vy reflect.Value) { eq := s.callTTBFunc(cm.fnc, vx, vy) s.report(eq, vx, vy) - return true } func (cm comparer) String() string { @@ -348,7 +355,7 @@ func (cm comparer) String() string { // all unexported fields on specified struct types. func AllowUnexported(types ...interface{}) Option { if !supportAllowUnexported { - panic("AllowUnexported is not supported on App Engine Classic or GopherJS") + panic("AllowUnexported is not supported on purego builds, Google App Engine Standard, or GopherJS") } m := make(map[reflect.Type]bool) for _, typ := range types { diff --git a/components/engine/vendor/github.com/google/go-cmp/cmp/path.go b/components/engine/vendor/github.com/google/go-cmp/cmp/path.go index 0c2eb333ff6..c08a3cf80d9 100644 --- a/components/engine/vendor/github.com/google/go-cmp/cmp/path.go +++ b/components/engine/vendor/github.com/google/go-cmp/cmp/path.go @@ -79,6 +79,11 @@ type ( PathStep Name() string Func() reflect.Value + + // Option returns the originally constructed Transformer option. + // The == operator can be used to detect the exact option used. + Option() Option + isTransform() } ) @@ -94,10 +99,21 @@ func (pa *Path) pop() { // Last returns the last PathStep in the Path. // If the path is empty, this returns a non-nil PathStep that reports a nil Type. func (pa Path) Last() PathStep { - if len(pa) > 0 { - return pa[len(pa)-1] + return pa.Index(-1) +} + +// Index returns the ith step in the Path and supports negative indexing. +// A negative index starts counting from the tail of the Path such that -1 +// refers to the last step, -2 refers to the second-to-last step, and so on. +// If index is invalid, this returns a non-nil PathStep that reports a nil Type. +func (pa Path) Index(i int) PathStep { + if i < 0 { + i = len(pa) + i + } + if i < 0 || i >= len(pa) { + return pathStep{} } - return pathStep{} + return pa[i] } // String returns the simplified path to a node. @@ -150,13 +166,12 @@ func (pa Path) GoString() string { ssPost = append(ssPost, ")") continue case *typeAssertion: - // Elide type assertions immediately following a transform to - // prevent overly verbose path printouts. - // Some transforms return interface{} because of Go's lack of - // generics, but typically take in and return the exact same - // concrete type. Other times, the transform creates an anonymous - // struct, which will be very verbose to print. - if _, ok := nextStep.(*transform); ok { + // As a special-case, elide type assertions on anonymous types + // since they are typically generated dynamically and can be very + // verbose. For example, some transforms return interface{} because + // of Go's lack of generics, but typically take in and return the + // exact same concrete type. + if s.Type().PkgPath() == "" { continue } } @@ -250,6 +265,7 @@ func (sf structField) Name() string { return sf.name } func (sf structField) Index() int { return sf.idx } func (tf transform) Name() string { return tf.trans.name } func (tf transform) Func() reflect.Value { return tf.trans.fnc } +func (tf transform) Option() Option { return tf.trans } func (pathStep) isPathStep() {} func (sliceIndex) isSliceIndex() {} diff --git a/components/engine/vendor/github.com/google/go-cmp/cmp/reporter.go b/components/engine/vendor/github.com/google/go-cmp/cmp/reporter.go index a21d0cded2c..20e9f18e0dd 100644 --- a/components/engine/vendor/github.com/google/go-cmp/cmp/reporter.go +++ b/components/engine/vendor/github.com/google/go-cmp/cmp/reporter.go @@ -30,12 +30,12 @@ func (r *defaultReporter) Report(x, y reflect.Value, eq bool, p Path) { const maxLines = 256 r.ndiffs++ if r.nbytes < maxBytes && r.nlines < maxLines { - sx := value.Format(x, true) - sy := value.Format(y, true) + sx := value.Format(x, value.FormatConfig{UseStringer: true}) + sy := value.Format(y, value.FormatConfig{UseStringer: true}) if sx == sy { - // Stringer is not helpful, so rely on more exact formatting. - sx = value.Format(x, false) - sy = value.Format(y, false) + // Unhelpful output, so use more exact formatting. + sx = value.Format(x, value.FormatConfig{PrintPrimitiveType: true}) + sy = value.Format(y, value.FormatConfig{PrintPrimitiveType: true}) } s := fmt.Sprintf("%#v:\n\t-: %s\n\t+: %s\n", p, sx, sy) r.diffs = append(r.diffs, s) @@ -49,5 +49,5 @@ func (r *defaultReporter) String() string { if r.ndiffs == len(r.diffs) { return s } - return fmt.Sprintf("%s... %d more differences ...", s, len(r.diffs)-r.ndiffs) + return fmt.Sprintf("%s... %d more differences ...", s, r.ndiffs-len(r.diffs)) } diff --git a/components/engine/vendor/github.com/google/go-cmp/cmp/unsafe_panic.go b/components/engine/vendor/github.com/google/go-cmp/cmp/unsafe_panic.go index 0d44987f5b6..d1518eb3a8c 100644 --- a/components/engine/vendor/github.com/google/go-cmp/cmp/unsafe_panic.go +++ b/components/engine/vendor/github.com/google/go-cmp/cmp/unsafe_panic.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE.md file. -// +build appengine js +// +build purego appengine js package cmp diff --git a/components/engine/vendor/github.com/google/go-cmp/cmp/unsafe_reflect.go b/components/engine/vendor/github.com/google/go-cmp/cmp/unsafe_reflect.go index 81fb82632e3..579b65507f6 100644 --- a/components/engine/vendor/github.com/google/go-cmp/cmp/unsafe_reflect.go +++ b/components/engine/vendor/github.com/google/go-cmp/cmp/unsafe_reflect.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE.md file. -// +build !appengine,!js +// +build !purego,!appengine,!js package cmp diff --git a/components/engine/vendor/github.com/gotestyourself/gotestyourself/README.md b/components/engine/vendor/github.com/gotestyourself/gotestyourself/README.md index f2b68b4a238..aad893ae033 100644 --- a/components/engine/vendor/github.com/gotestyourself/gotestyourself/README.md +++ b/components/engine/vendor/github.com/gotestyourself/gotestyourself/README.md @@ -30,3 +30,4 @@ patterns. ## Related * [maxbrunsfeld/counterfeiter](https://github.com/maxbrunsfeld/counterfeiter) - generate fakes for interfaces +* [jonboulle/clockwork](https://github.com/jonboulle/clockwork) - a fake clock for testing code that uses `time` diff --git a/components/engine/vendor/github.com/gotestyourself/gotestyourself/assert/assert.go b/components/engine/vendor/github.com/gotestyourself/gotestyourself/assert/assert.go index 139ea855cbf..d2b05f41655 100644 --- a/components/engine/vendor/github.com/gotestyourself/gotestyourself/assert/assert.go +++ b/components/engine/vendor/github.com/gotestyourself/gotestyourself/assert/assert.go @@ -1,6 +1,5 @@ -/*Package assert provides assertions and checks for comparing expected values to -actual values. When an assertion or check fails a helpful error message is -printed. +/*Package assert provides assertions for comparing expected values to actual +values. When an assertion fails a helpful error message is printed. Assert and Check @@ -23,7 +22,7 @@ The example below shows assert used with some common types. func TestEverything(t *testing.T) { // booleans - assert.Assert(t, isOk) + assert.Assert(t, ok) assert.Assert(t, !missing) // primitives @@ -33,14 +32,15 @@ The example below shows assert used with some common types. // errors assert.NilError(t, closer.Close()) - assert.Assert(t, is.Error(err, "the exact error message")) - assert.Assert(t, is.ErrorContains(err, "includes this")) + assert.Error(t, err, "the exact error message") + assert.ErrorContains(t, err, "includes this") + assert.ErrorType(t, err, os.IsNotExist) // complex types + assert.DeepEqual(t, result, myStruct{Name: "title"}) assert.Assert(t, is.Len(items, 3)) assert.Assert(t, len(sequence) != 0) // NotEmpty assert.Assert(t, is.Contains(mapping, "key")) - assert.Assert(t, is.Compare(result, myStruct{Name: "title"})) // pointers and interface assert.Assert(t, is.Nil(ref)) @@ -51,40 +51,25 @@ Comparisons https://godoc.org/github.com/gotestyourself/gotestyourself/assert/cmp provides many common comparisons. Additional comparisons can be written to compare -values in other ways. - -Below is an example of a custom comparison using a regex pattern: - - func RegexP(value string, pattern string) func() (bool, string) { - return func() (bool, string) { - re := regexp.MustCompile(pattern) - msg := fmt.Sprintf("%q did not match pattern %q", value, pattern) - return re.MatchString(value), msg - } - } +values in other ways. See the example Assert (CustomComparison). */ package assert import ( "fmt" + "go/ast" + "go/token" + gocmp "github.com/google/go-cmp/cmp" "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/internal/format" "github.com/gotestyourself/gotestyourself/internal/source" ) -// BoolOrComparison can be a bool, or Comparison. Other types will panic. +// BoolOrComparison can be a bool, or cmp.Comparison. See Assert() for usage. type BoolOrComparison interface{} -// Comparison is a function which compares values and returns true if the actual -// value matches the expected value. If the values do not match it returns a message -// with details about why it failed. -// -// https://godoc.org/github.com/gotestyourself/gotestyourself/assert/cmp -// provides many general purpose Comparisons. -type Comparison func() (success bool, message string) - // TestingT is the subset of testing.T used by the assert package. type TestingT interface { FailNow() @@ -96,84 +81,156 @@ type helperT interface { Helper() } -// stackIndex = Assert()/Check(), assert() -const stackIndex = 2 -const comparisonArgPos = 1 - const failureMessage = "assertion failed: " +// nolint: gocyclo func assert( t TestingT, failer func(), + argSelector argSelector, comparison BoolOrComparison, msgAndArgs ...interface{}, ) bool { if ht, ok := t.(helperT); ok { ht.Helper() } + var success bool switch check := comparison.(type) { case bool: if check { return true } - source, err := source.GetCondition(stackIndex, comparisonArgPos) - if err != nil { - t.Log(err.Error()) - } + logFailureFromBool(t, msgAndArgs...) - msg := " is false" - t.Log(format.WithCustomMessage(failureMessage+source+msg, msgAndArgs...)) - failer() - return false + // Undocumented legacy comparison without Result type + case func() (success bool, message string): + success = runCompareFunc(t, check, msgAndArgs...) - case Comparison: - return runCompareFunc(failer, t, check, msgAndArgs...) + case nil: + return true - case func() (success bool, message string): - return runCompareFunc(failer, t, check, msgAndArgs...) + case error: + msg := "error is not nil: " + t.Log(format.WithCustomMessage(failureMessage+msg+check.Error(), msgAndArgs...)) + + case cmp.Comparison: + success = runComparison(t, argSelector, check, msgAndArgs...) + + case func() cmp.Result: + success = runComparison(t, argSelector, check, msgAndArgs...) default: - panic(fmt.Sprintf("comparison arg must be bool or Comparison, not %T", comparison)) + t.Log(fmt.Sprintf("invalid Comparison: %v (%T)", check, check)) + } + + if success { + return true } + failer() + return false } -func runCompareFunc(failer func(), t TestingT, f Comparison, msgAndArgs ...interface{}) bool { +func runCompareFunc( + t TestingT, + f func() (success bool, message string), + msgAndArgs ...interface{}, +) bool { if ht, ok := t.(helperT); ok { ht.Helper() } if success, message := f(); !success { t.Log(format.WithCustomMessage(failureMessage+message, msgAndArgs...)) - failer() return false } return true } -// Assert performs a comparison, marks the test as having failed if the comparison -// returns false, and stops execution immediately. +func logFailureFromBool(t TestingT, msgAndArgs ...interface{}) { + if ht, ok := t.(helperT); ok { + ht.Helper() + } + const stackIndex = 3 // Assert()/Check(), assert(), formatFailureFromBool() + const comparisonArgPos = 1 + args, err := source.CallExprArgs(stackIndex) + if err != nil { + t.Log(err.Error()) + return + } + + msg, err := boolFailureMessage(args[comparisonArgPos]) + if err != nil { + t.Log(err.Error()) + msg = "expression is false" + } + + t.Log(format.WithCustomMessage(failureMessage+msg, msgAndArgs...)) +} + +func boolFailureMessage(expr ast.Expr) (string, error) { + if binaryExpr, ok := expr.(*ast.BinaryExpr); ok && binaryExpr.Op == token.NEQ { + x, err := source.FormatNode(binaryExpr.X) + if err != nil { + return "", err + } + y, err := source.FormatNode(binaryExpr.Y) + if err != nil { + return "", err + } + return x + " is " + y, nil + } + + if unaryExpr, ok := expr.(*ast.UnaryExpr); ok && unaryExpr.Op == token.NOT { + x, err := source.FormatNode(unaryExpr.X) + if err != nil { + return "", err + } + return x + " is true", nil + } + + formatted, err := source.FormatNode(expr) + if err != nil { + return "", err + } + return "expression is false: " + formatted, nil +} + +// Assert performs a comparison. If the comparison fails the test is marked as +// failed, a failure message is logged, and execution is stopped immediately. +// +// The comparison argument may be one of three types: bool, cmp.Comparison or +// error. +// When called with a bool the failure message will contain the literal source +// code of the expression. +// When called with a cmp.Comparison the comparison is responsible for producing +// a helpful failure message. +// When called with an error a nil value is considered success. A non-nil error +// is a failure, and Error() is used as the failure message. func Assert(t TestingT, comparison BoolOrComparison, msgAndArgs ...interface{}) { if ht, ok := t.(helperT); ok { ht.Helper() } - assert(t, t.FailNow, comparison, msgAndArgs...) + assert(t, t.FailNow, argsFromComparisonCall, comparison, msgAndArgs...) } -// Check performs a comparison and marks the test as having failed if the comparison -// returns false. Returns the result of the comparison. +// Check performs a comparison. If the comparison fails the test is marked as +// failed, a failure message is logged, and Check returns false. Otherwise returns +// true. +// +// See Assert for details about the comparison arg and failure messages. func Check(t TestingT, comparison BoolOrComparison, msgAndArgs ...interface{}) bool { if ht, ok := t.(helperT); ok { ht.Helper() } - return assert(t, t.Fail, comparison, msgAndArgs...) + return assert(t, t.Fail, argsFromComparisonCall, comparison, msgAndArgs...) } -// NilError fails the test immediately if the last arg is a non-nil error. -// This is equivalent to Assert(t, cmp.NilError(err)). +// NilError fails the test immediately if err is not nil. +// This is equivalent to Assert(t, err) func NilError(t TestingT, err error, msgAndArgs ...interface{}) { if ht, ok := t.(helperT); ok { ht.Helper() } - assert(t, t.FailNow, cmp.NilError(err), msgAndArgs...) + assert(t, t.FailNow, argsAfterT, err, msgAndArgs...) } // Equal uses the == operator to assert two values are equal and fails the test @@ -182,5 +239,51 @@ func Equal(t TestingT, x, y interface{}, msgAndArgs ...interface{}) { if ht, ok := t.(helperT); ok { ht.Helper() } - assert(t, t.FailNow, cmp.Equal(x, y), msgAndArgs...) + assert(t, t.FailNow, argsAfterT, cmp.Equal(x, y), msgAndArgs...) +} + +// DeepEqual uses https://github.com/google/go-cmp/cmp to assert two values +// are equal and fails the test if they are not equal. +// This is equivalent to Assert(t, cmp.DeepEqual(x, y)). +func DeepEqual(t TestingT, x, y interface{}, opts ...gocmp.Option) { + if ht, ok := t.(helperT); ok { + ht.Helper() + } + assert(t, t.FailNow, argsAfterT, cmp.DeepEqual(x, y, opts...)) +} + +// Error fails the test if err is nil, or the error message is not the expected +// message. +// Equivalent to Assert(t, cmp.Error(err, message)). +func Error(t TestingT, err error, message string, msgAndArgs ...interface{}) { + if ht, ok := t.(helperT); ok { + ht.Helper() + } + assert(t, t.FailNow, argsAfterT, cmp.Error(err, message), msgAndArgs...) +} + +// ErrorContains fails the test if err is nil, or the error message does not +// contain the expected substring. +// Equivalent to Assert(t, cmp.ErrorContains(err, substring)). +func ErrorContains(t TestingT, err error, substring string, msgAndArgs ...interface{}) { + if ht, ok := t.(helperT); ok { + ht.Helper() + } + assert(t, t.FailNow, argsAfterT, cmp.ErrorContains(err, substring), msgAndArgs...) +} + +// ErrorType fails the test if err is nil, or err is not the expected type. +// +// Expected can be one of: +// a func(error) bool which returns true if the error is the expected type, +// an instance of a struct of the expected type, +// a pointer to an interface the error is expected to implement, +// a reflect.Type of the expected struct or interface. +// +// Equivalent to Assert(t, cmp.ErrorType(err, expected)). +func ErrorType(t TestingT, err error, expected interface{}, msgAndArgs ...interface{}) { + if ht, ok := t.(helperT); ok { + ht.Helper() + } + assert(t, t.FailNow, argsAfterT, cmp.ErrorType(err, expected), msgAndArgs...) } diff --git a/components/engine/vendor/github.com/gotestyourself/gotestyourself/assert/cmp/compare.go b/components/engine/vendor/github.com/gotestyourself/gotestyourself/assert/cmp/compare.go index c30b28b9f0e..64a25f00b33 100644 --- a/components/engine/vendor/github.com/gotestyourself/gotestyourself/assert/cmp/compare.go +++ b/components/engine/vendor/github.com/gotestyourself/gotestyourself/assert/cmp/compare.go @@ -10,53 +10,113 @@ import ( "github.com/pmezard/go-difflib/difflib" ) -// Compare two complex values using https://godoc.org/github.com/google/go-cmp/cmp +// Comparison is a function which compares values and returns ResultSuccess if +// the actual value matches the expected value. If the values do not match the +// Result will contain a message about why it failed. +type Comparison func() Result + +// DeepEqual compares two values using https://godoc.org/github.com/google/go-cmp/cmp // and succeeds if the values are equal. // // The comparison can be customized using comparison Options. -func Compare(x, y interface{}, opts ...cmp.Option) func() (bool, string) { - return func() (bool, string) { +func DeepEqual(x, y interface{}, opts ...cmp.Option) Comparison { + return func() (result Result) { + defer func() { + if panicmsg, handled := handleCmpPanic(recover()); handled { + result = ResultFailure(panicmsg) + } + }() diff := cmp.Diff(x, y, opts...) - return diff == "", "\n" + diff + return toResult(diff == "", "\n"+diff) + } +} + +func handleCmpPanic(r interface{}) (string, bool) { + if r == nil { + return "", false } + panicmsg, ok := r.(string) + if !ok { + panic(r) + } + switch { + case strings.HasPrefix(panicmsg, "cannot handle unexported field"): + return panicmsg, true + } + panic(r) +} + +func toResult(success bool, msg string) Result { + if success { + return ResultSuccess + } + return ResultFailure(msg) } // Equal succeeds if x == y. -func Equal(x, y interface{}) func() (success bool, message string) { - return func() (bool, string) { - return x == y, fmt.Sprintf("%v (%T) != %v (%T)", x, x, y, y) +func Equal(x, y interface{}) Comparison { + return func() Result { + switch { + case x == y: + return ResultSuccess + case isMultiLineStringCompare(x, y): + return multiLineStringDiffResult(x.(string), y.(string)) + } + return ResultFailureTemplate(` + {{- .Data.x}} ( + {{- with callArg 0 }}{{ formatNode . }} {{end -}} + {{- printf "%T" .Data.x -}} + ) != {{ .Data.y}} ( + {{- with callArg 1 }}{{ formatNode . }} {{end -}} + {{- printf "%T" .Data.y -}} + )`, + map[string]interface{}{"x": x, "y": y}) } } +func isMultiLineStringCompare(x, y interface{}) bool { + strX, ok := x.(string) + if !ok { + return false + } + strY, ok := y.(string) + if !ok { + return false + } + return strings.Contains(strX, "\n") || strings.Contains(strY, "\n") +} + +func multiLineStringDiffResult(x, y string) Result { + diff, err := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ + A: difflib.SplitLines(x), + B: difflib.SplitLines(y), + Context: 3, + }) + if err != nil { + return ResultFailure(fmt.Sprintf("failed to diff: %s", err)) + } + return ResultFailureTemplate(` +--- {{ with callArg 0 }}{{ formatNode . }}{{else}}←{{end}} ++++ {{ with callArg 1 }}{{ formatNode . }}{{else}}→{{end}} +{{ .Data.diff }}`, + map[string]interface{}{"diff": diff}) +} + // Len succeeds if the sequence has the expected length. -func Len(seq interface{}, expected int) func() (bool, string) { - return func() (success bool, message string) { +func Len(seq interface{}, expected int) Comparison { + return func() (result Result) { defer func() { if e := recover(); e != nil { - success = false - message = fmt.Sprintf("type %T does not have a length", seq) + result = ResultFailure(fmt.Sprintf("type %T does not have a length", seq)) } }() value := reflect.ValueOf(seq) length := value.Len() if length == expected { - return true, "" + return ResultSuccess } msg := fmt.Sprintf("expected %s (length %d) to have length %d", seq, length, expected) - return false, msg - } -} - -// NilError succeeds if the last argument is a nil error. -func NilError(arg interface{}, args ...interface{}) func() (bool, string) { - return func() (bool, string) { - msgFunc := func(value reflect.Value) string { - return fmt.Sprintf("error is not nil: %s", value.Interface().(error).Error()) - } - if len(args) == 0 { - return isNil(arg, msgFunc)() - } - return isNil(args[len(args)-1], msgFunc)() + return ResultFailure(msg) } } @@ -68,11 +128,11 @@ func NilError(arg interface{}, args ...interface{}) func() (bool, string) { // If collection is a Map, contains will succeed if item is a key in the map. // If collection is a slice or array, item is compared to each item in the // sequence using reflect.DeepEqual(). -func Contains(collection interface{}, item interface{}) func() (bool, string) { - return func() (bool, string) { +func Contains(collection interface{}, item interface{}) Comparison { + return func() Result { colValue := reflect.ValueOf(collection) if !colValue.IsValid() { - return false, fmt.Sprintf("nil does not contain items") + return ResultFailure(fmt.Sprintf("nil does not contain items")) } msg := fmt.Sprintf("%v does not contain %v", collection, item) @@ -80,94 +140,72 @@ func Contains(collection interface{}, item interface{}) func() (bool, string) { switch colValue.Type().Kind() { case reflect.String: if itemValue.Type().Kind() != reflect.String { - return false, "string may only contain strings" + return ResultFailure("string may only contain strings") } - success := strings.Contains(colValue.String(), itemValue.String()) - return success, fmt.Sprintf("string %q does not contain %q", collection, item) + return toResult( + strings.Contains(colValue.String(), itemValue.String()), + fmt.Sprintf("string %q does not contain %q", collection, item)) case reflect.Map: if itemValue.Type() != colValue.Type().Key() { - return false, fmt.Sprintf( - "%v can not contain a %v key", colValue.Type(), itemValue.Type()) + return ResultFailure(fmt.Sprintf( + "%v can not contain a %v key", colValue.Type(), itemValue.Type())) } - index := colValue.MapIndex(itemValue) - return index.IsValid(), msg + return toResult(colValue.MapIndex(itemValue).IsValid(), msg) case reflect.Slice, reflect.Array: for i := 0; i < colValue.Len(); i++ { if reflect.DeepEqual(colValue.Index(i).Interface(), item) { - return true, "" + return ResultSuccess } } - return false, msg + return ResultFailure(msg) default: - return false, fmt.Sprintf("type %T does not contain items", collection) + return ResultFailure(fmt.Sprintf("type %T does not contain items", collection)) } } } // Panics succeeds if f() panics. -func Panics(f func()) func() (bool, string) { - return func() (success bool, message string) { +func Panics(f func()) Comparison { + return func() (result Result) { defer func() { if err := recover(); err != nil { - success = true + result = ResultSuccess } }() f() - return false, "did not panic" - } -} - -// EqualMultiLine succeeds if the two strings are equal. If they are not equal -// the failure message will be the difference between the two strings. -func EqualMultiLine(x, y string) func() (bool, string) { - return func() (bool, string) { - if x == y { - return true, "" - } - - diff, err := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ - A: difflib.SplitLines(x), - B: difflib.SplitLines(y), - FromFile: "left", - ToFile: "right", - Context: 3, - }) - if err != nil { - return false, fmt.Sprintf("failed to produce diff: %s", err) - } - return false, "\n" + diff + return ResultFailure("did not panic") } } // Error succeeds if err is a non-nil error, and the error message equals the // expected message. -func Error(err error, message string) func() (bool, string) { - return func() (bool, string) { +func Error(err error, message string) Comparison { + return func() Result { switch { case err == nil: - return false, "expected an error, got nil" + return ResultFailure("expected an error, got nil") case err.Error() != message: - return false, fmt.Sprintf( - "expected error message %q, got %q", message, err.Error()) + return ResultFailure(fmt.Sprintf( + "expected error %q, got %+v", message, err)) } - return true, "" + return ResultSuccess } } // ErrorContains succeeds if err is a non-nil error, and the error message contains // the expected substring. -func ErrorContains(err error, substring string) func() (bool, string) { - return func() (bool, string) { +func ErrorContains(err error, substring string) Comparison { + return func() Result { switch { case err == nil: - return false, "expected an error, got nil" + return ResultFailure("expected an error, got nil") case !strings.Contains(err.Error(), substring): - return false, fmt.Sprintf( - "expected error message to contain %q, got %q", substring, err.Error()) + return ResultFailure(fmt.Sprintf( + "expected error to contain %q, got %+v", substring, err)) } - return true, "" + return ResultSuccess } } @@ -175,27 +213,98 @@ func ErrorContains(err error, substring string) func() (bool, string) { // // Use NilError() for comparing errors. Use Len(obj, 0) for comparing slices, // maps, and channels. -func Nil(obj interface{}) func() (bool, string) { +func Nil(obj interface{}) Comparison { msgFunc := func(value reflect.Value) string { return fmt.Sprintf("%v (type %s) is not nil", reflect.Indirect(value), value.Type()) } return isNil(obj, msgFunc) } -func isNil(obj interface{}, msgFunc func(reflect.Value) string) func() (bool, string) { - return func() (bool, string) { +func isNil(obj interface{}, msgFunc func(reflect.Value) string) Comparison { + return func() Result { if obj == nil { - return true, "" + return ResultSuccess } value := reflect.ValueOf(obj) kind := value.Type().Kind() if kind >= reflect.Chan && kind <= reflect.Slice { if value.IsNil() { - return true, "" + return ResultSuccess + } + return ResultFailure(msgFunc(value)) + } + + return ResultFailure(fmt.Sprintf("%v (type %s) can not be nil", value, value.Type())) + } +} + +// ErrorType succeeds if err is not nil and is of the expected type. +// +// Expected can be one of: +// a func(error) bool which returns true if the error is the expected type, +// an instance of a struct of the expected type, +// a pointer to an interface the error is expected to implement, +// a reflect.Type of the expected struct or interface. +func ErrorType(err error, expected interface{}) Comparison { + return func() Result { + switch expectedType := expected.(type) { + case func(error) bool: + return cmpErrorTypeFunc(err, expectedType) + case reflect.Type: + if expectedType.Kind() == reflect.Interface { + return cmpErrorTypeImplementsType(err, expectedType) } - return false, msgFunc(value) + return cmpErrorTypeEqualType(err, expectedType) + case nil: + return ResultFailure(fmt.Sprintf("invalid type for expected: nil")) } - return false, fmt.Sprintf("%v (type %s) can not be nil", value, value.Type()) + expectedType := reflect.TypeOf(expected) + switch { + case expectedType.Kind() == reflect.Struct: + return cmpErrorTypeEqualType(err, expectedType) + case isPtrToInterface(expectedType): + return cmpErrorTypeImplementsType(err, expectedType.Elem()) + } + return ResultFailure(fmt.Sprintf("invalid type for expected: %T", expected)) } } + +func cmpErrorTypeFunc(err error, f func(error) bool) Result { + if f(err) { + return ResultSuccess + } + actual := "nil" + if err != nil { + actual = fmt.Sprintf("%s (%T)", err, err) + } + return ResultFailureTemplate(`error is {{ .Data.actual }} + {{- with callArg 1 }}, not {{ formatNode . }}{{end -}}`, + map[string]interface{}{"actual": actual}) +} + +func cmpErrorTypeEqualType(err error, expectedType reflect.Type) Result { + if err == nil { + return ResultFailure(fmt.Sprintf("error is nil, not %s", expectedType)) + } + errValue := reflect.ValueOf(err) + if errValue.Type() == expectedType { + return ResultSuccess + } + return ResultFailure(fmt.Sprintf("error is %s (%T), not %s", err, err, expectedType)) +} + +func cmpErrorTypeImplementsType(err error, expectedType reflect.Type) Result { + if err == nil { + return ResultFailure(fmt.Sprintf("error is nil, not %s", expectedType)) + } + errValue := reflect.ValueOf(err) + if errValue.Type().Implements(expectedType) { + return ResultSuccess + } + return ResultFailure(fmt.Sprintf("error is %s (%T), not %s", err, err, expectedType)) +} + +func isPtrToInterface(typ reflect.Type) bool { + return typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Interface +} diff --git a/components/engine/vendor/github.com/gotestyourself/gotestyourself/assert/cmp/result.go b/components/engine/vendor/github.com/gotestyourself/gotestyourself/assert/cmp/result.go new file mode 100644 index 00000000000..99f39eeb274 --- /dev/null +++ b/components/engine/vendor/github.com/gotestyourself/gotestyourself/assert/cmp/result.go @@ -0,0 +1,94 @@ +package cmp + +import ( + "bytes" + "fmt" + "go/ast" + "text/template" + + "github.com/gotestyourself/gotestyourself/internal/source" +) + +// Result of a Comparison. +type Result interface { + Success() bool +} + +type result struct { + success bool + message string +} + +func (r result) Success() bool { + return r.success +} + +func (r result) FailureMessage() string { + return r.message +} + +// ResultSuccess is a constant which is returned by a ComparisonWithResult to +// indicate success. +var ResultSuccess = result{success: true} + +// ResultFailure returns a failed Result with a failure message. +func ResultFailure(message string) Result { + return result{message: message} +} + +// ResultFromError returns ResultSuccess if err is nil. Otherwise ResultFailure +// is returned with the error message as the failure message. +func ResultFromError(err error) Result { + if err == nil { + return ResultSuccess + } + return ResultFailure(err.Error()) +} + +type templatedResult struct { + success bool + template string + data map[string]interface{} +} + +func (r templatedResult) Success() bool { + return r.success +} + +func (r templatedResult) FailureMessage(args []ast.Expr) string { + msg, err := renderMessage(r, args) + if err != nil { + return fmt.Sprintf("failed to render failure message: %s", err) + } + return msg +} + +// ResultFailureTemplate returns a Result with a template string and data which +// can be used to format a failure message. The template may access data from .Data, +// the comparison args with the callArg function, and the formatNode function may +// be used to format the call args. +func ResultFailureTemplate(template string, data map[string]interface{}) Result { + return templatedResult{template: template, data: data} +} + +func renderMessage(result templatedResult, args []ast.Expr) (string, error) { + tmpl := template.New("failure").Funcs(template.FuncMap{ + "formatNode": source.FormatNode, + "callArg": func(index int) ast.Expr { + if index >= len(args) { + return nil + } + return args[index] + }, + }) + var err error + tmpl, err = tmpl.Parse(result.template) + if err != nil { + return "", err + } + buf := new(bytes.Buffer) + err = tmpl.Execute(buf, map[string]interface{}{ + "Data": result.data, + }) + return buf.String(), err +} diff --git a/components/engine/vendor/github.com/gotestyourself/gotestyourself/assert/result.go b/components/engine/vendor/github.com/gotestyourself/gotestyourself/assert/result.go new file mode 100644 index 00000000000..b685b7f3e5c --- /dev/null +++ b/components/engine/vendor/github.com/gotestyourself/gotestyourself/assert/result.go @@ -0,0 +1,107 @@ +package assert + +import ( + "fmt" + "go/ast" + + "github.com/gotestyourself/gotestyourself/assert/cmp" + "github.com/gotestyourself/gotestyourself/internal/format" + "github.com/gotestyourself/gotestyourself/internal/source" +) + +func runComparison( + t TestingT, + argSelector argSelector, + f cmp.Comparison, + msgAndArgs ...interface{}, +) bool { + if ht, ok := t.(helperT); ok { + ht.Helper() + } + result := f() + if result.Success() { + return true + } + + var message string + switch typed := result.(type) { + case resultWithComparisonArgs: + const stackIndex = 3 // Assert/Check, assert, runComparison + args, err := source.CallExprArgs(stackIndex) + if err != nil { + t.Log(err.Error()) + } + message = typed.FailureMessage(filterPrintableExpr(argSelector(args))) + case resultBasic: + message = typed.FailureMessage() + default: + message = fmt.Sprintf("comparison returned invalid Result type: %T", result) + } + + t.Log(format.WithCustomMessage(failureMessage+message, msgAndArgs...)) + return false +} + +type resultWithComparisonArgs interface { + FailureMessage(args []ast.Expr) string +} + +type resultBasic interface { + FailureMessage() string +} + +// filterPrintableExpr filters the ast.Expr slice to only include Expr that are +// easy to read when printed and contain relevant information to an assertion. +// +// Ident and SelectorExpr are included because they print nicely and the variable +// names may provide additional context to their values. +// BasicLit and CompositeLit are excluded because their source is equivalent to +// their value, which is already available. +// Other types are ignored for now, but could be added if they are relevant. +func filterPrintableExpr(args []ast.Expr) []ast.Expr { + result := make([]ast.Expr, len(args)) + for i, arg := range args { + if isShortPrintableExpr(arg) { + result[i] = arg + continue + } + + if starExpr, ok := arg.(*ast.StarExpr); ok { + result[i] = starExpr.X + continue + } + result[i] = nil + } + return result +} + +func isShortPrintableExpr(expr ast.Expr) bool { + switch expr.(type) { + case *ast.Ident, *ast.SelectorExpr, *ast.IndexExpr, *ast.SliceExpr: + return true + case *ast.BinaryExpr, *ast.UnaryExpr: + return true + default: + // CallExpr, ParenExpr, TypeAssertExpr, KeyValueExpr, StarExpr + return false + } +} + +type argSelector func([]ast.Expr) []ast.Expr + +func argsAfterT(args []ast.Expr) []ast.Expr { + if len(args) < 1 { + return nil + } + return args[1:] +} + +func argsFromComparisonCall(args []ast.Expr) []ast.Expr { + if len(args) < 1 { + return nil + } + if callExpr, ok := args[1].(*ast.CallExpr); ok { + return callExpr.Args + } + return nil +} diff --git a/components/engine/vendor/github.com/gotestyourself/gotestyourself/env/env.go b/components/engine/vendor/github.com/gotestyourself/gotestyourself/env/env.go index 95a53bee9c8..700430f1dd1 100644 --- a/components/engine/vendor/github.com/gotestyourself/gotestyourself/env/env.go +++ b/components/engine/vendor/github.com/gotestyourself/gotestyourself/env/env.go @@ -45,7 +45,7 @@ func PatchAll(t assert.TestingT, env map[string]string) func() { os.Clearenv() for key, value := range env { - assert.NilError(t, os.Setenv(key, value)) + assert.NilError(t, os.Setenv(key, value), "setenv %s=%s", key, value) } return func() { if ht, ok := t.(helperT); ok { @@ -53,7 +53,7 @@ func PatchAll(t assert.TestingT, env map[string]string) func() { } os.Clearenv() for key, oldVal := range ToMap(oldEnv) { - assert.NilError(t, os.Setenv(key, oldVal)) + assert.NilError(t, os.Setenv(key, oldVal), "setenv %s=%s", key, oldVal) } } } @@ -63,17 +63,23 @@ func PatchAll(t assert.TestingT, env map[string]string) func() { func ToMap(env []string) map[string]string { result := map[string]string{} for _, raw := range env { - parts := strings.SplitN(raw, "=", 2) - switch len(parts) { - case 1: - result[raw] = "" - case 2: - result[parts[0]] = parts[1] - } + key, value := getParts(raw) + result[key] = value } return result } +func getParts(raw string) (string, string) { + // Environment variables on windows can begin with = + // http://blogs.msdn.com/b/oldnewthing/archive/2010/05/06/10008132.aspx + parts := strings.SplitN(raw[1:], "=", 2) + key := raw[:1] + parts[0] + if len(parts) == 1 { + return key, "" + } + return key, parts[1] +} + // ChangeWorkingDir to the directory, and return a function which restores the // previous working directory. func ChangeWorkingDir(t assert.TestingT, dir string) func() { diff --git a/components/engine/vendor/github.com/gotestyourself/gotestyourself/fs/ops.go b/components/engine/vendor/github.com/gotestyourself/gotestyourself/fs/ops.go index 7cc63994c84..bf9d2150b35 100644 --- a/components/engine/vendor/github.com/gotestyourself/gotestyourself/fs/ops.go +++ b/components/engine/vendor/github.com/gotestyourself/gotestyourself/fs/ops.go @@ -4,6 +4,7 @@ import ( "io/ioutil" "os" "path/filepath" + "time" ) // PathOp is a function which accepts a Path to perform some operation @@ -125,3 +126,33 @@ func copyFile(source, dest string) error { } return ioutil.WriteFile(dest, content, 0644) } + +// WithSymlink creates a symlink in the directory which links to target. +// Target must be a path relative to the directory. +// +// Note: the argument order is the inverse of os.Symlink to be consistent with +// the other functions in this package. +func WithSymlink(path, target string) PathOp { + return func(root Path) error { + return os.Symlink(filepath.Join(root.Path(), target), filepath.Join(root.Path(), path)) + } +} + +// WithHardlink creates a link in the directory which links to target. +// Target must be a path relative to the directory. +// +// Note: the argument order is the inverse of os.Link to be consistent with +// the other functions in this package. +func WithHardlink(path, target string) PathOp { + return func(root Path) error { + return os.Link(filepath.Join(root.Path(), target), filepath.Join(root.Path(), path)) + } +} + +// WithTimestamps sets the access and modification times of the file system object +// at path. +func WithTimestamps(atime, mtime time.Time) PathOp { + return func(root Path) error { + return os.Chtimes(root.Path(), atime, mtime) + } +} diff --git a/components/engine/vendor/github.com/gotestyourself/gotestyourself/icmd/command.go b/components/engine/vendor/github.com/gotestyourself/gotestyourself/icmd/command.go index 379f13c815f..0066c51514c 100644 --- a/components/engine/vendor/github.com/gotestyourself/gotestyourself/icmd/command.go +++ b/components/engine/vendor/github.com/gotestyourself/gotestyourself/icmd/command.go @@ -10,11 +10,10 @@ import ( "strings" "sync" "time" -) -type testingT interface { - Fatalf(string, ...interface{}) -} + "github.com/gotestyourself/gotestyourself/assert" + "github.com/gotestyourself/gotestyourself/assert/cmp" +) type helperT interface { Helper() @@ -53,23 +52,32 @@ type Result struct { // Assert compares the Result against the Expected struct, and fails the test if // any of the expectations are not met. -// TODO: deprecate and replace with assert.CompareFunc -func (r *Result) Assert(t testingT, exp Expected) *Result { +// +// This function is equivalent to assert.Assert(t, result.Equal(exp)). +func (r *Result) Assert(t assert.TestingT, exp Expected) *Result { if ht, ok := t.(helperT); ok { ht.Helper() } - err := r.Compare(exp) - if err == nil { - return r + assert.Assert(t, r.Equal(exp)) + return r +} + +// Equal compares the result to Expected. If the result doesn't match expected +// returns a formatted failure message with the command, stdout, stderr, exit code, +// and any failed expectations. +func (r *Result) Equal(exp Expected) cmp.Comparison { + return func() cmp.Result { + return cmp.ResultFromError(r.match(exp)) } - t.Fatalf(err.Error() + "\n") - return nil } -// Compare returns a formatted error with the command, stdout, stderr, exit -// code, and any failed expectations -// nolint: gocyclo +// Compare the result to Expected and return an error if they do not match. func (r *Result) Compare(exp Expected) error { + return r.match(exp) +} + +// nolint: gocyclo +func (r *Result) match(exp Expected) error { errors := []string{} add := func(format string, args ...interface{}) { errors = append(errors, fmt.Sprintf(format, args...)) diff --git a/components/engine/vendor/github.com/gotestyourself/gotestyourself/internal/source/source.go b/components/engine/vendor/github.com/gotestyourself/gotestyourself/internal/source/source.go index 46f484bc821..f71c5129b87 100644 --- a/components/engine/vendor/github.com/gotestyourself/gotestyourself/internal/source/source.go +++ b/components/engine/vendor/github.com/gotestyourself/gotestyourself/internal/source/source.go @@ -2,31 +2,29 @@ package source import ( "bytes" + "fmt" "go/ast" "go/format" "go/parser" "go/token" + "os" "runtime" + "strconv" + "strings" "github.com/pkg/errors" ) const baseStackIndex = 1 -// GetCondition returns the condition string by reading it from the file -// identified in the callstack. In golang 1.9 the line number changed from -// being the line where the statement ended to the line where the statement began. -func GetCondition(stackIndex int, argPos int) (string, error) { - _, filename, lineNum, ok := runtime.Caller(baseStackIndex + stackIndex) - if !ok { - return "", errors.New("failed to get caller info") - } - - node, err := getNodeAtLine(filename, lineNum) +// FormattedCallExprArg returns the argument from an ast.CallExpr at the +// index in the call stack. The argument is formatted using FormatNode. +func FormattedCallExprArg(stackIndex int, argPos int) (string, error) { + args, err := CallExprArgs(stackIndex + 1) if err != nil { return "", err } - return getArgSourceFromAST(node, argPos) + return FormatNode(args[argPos]) } func getNodeAtLine(filename string, lineNum int) (ast.Node, error) { @@ -38,7 +36,7 @@ func getNodeAtLine(filename string, lineNum int) (ast.Node, error) { node := scanToLine(fileset, astFile, lineNum) if node == nil { - return nil, errors.Wrapf(err, + return nil, errors.Errorf( "failed to find an expression on line %d in %s", lineNum, filename) } return node, nil @@ -60,32 +58,46 @@ func (v *scanToLineVisitor) Visit(node ast.Node) ast.Visitor { if node == nil || v.matchedNode != nil { return nil } - - var position token.Position - switch { - case runtime.Version() < "go1.9": - position = v.fileset.Position(node.End()) - default: - position = v.fileset.Position(node.Pos()) - } - - if position.Line == v.lineNum { + if v.nodePosition(node).Line == v.lineNum { v.matchedNode = node return nil } return v } -func getArgSourceFromAST(node ast.Node, argPos int) (string, error) { +// In golang 1.9 the line number changed from being the line where the statement +// ended to the line where the statement began. +func (v *scanToLineVisitor) nodePosition(node ast.Node) token.Position { + if goVersionBefore19 { + return v.fileset.Position(node.End()) + } + return v.fileset.Position(node.Pos()) +} + +var goVersionBefore19 = isGOVersionBefore19() + +func isGOVersionBefore19() bool { + version := runtime.Version() + // not a release version + if !strings.HasPrefix(version, "go") { + return false + } + version = strings.TrimPrefix(version, "go") + parts := strings.Split(version, ".") + if len(parts) < 2 { + return false + } + minor, err := strconv.ParseInt(parts[1], 10, 32) + return err == nil && parts[0] == "1" && minor < 9 +} + +func getCallExprArgs(node ast.Node) ([]ast.Expr, error) { visitor := &callExprVisitor{} ast.Walk(visitor, node) if visitor.expr == nil { - return "", errors.Errorf("unexpected ast") + return nil, errors.New("failed to find call expression") } - - buf := new(bytes.Buffer) - err := format.Node(buf, token.NewFileSet(), visitor.expr.Args[argPos]) - return buf.String(), err + return visitor.expr.Args, nil } type callExprVisitor struct { @@ -93,17 +105,59 @@ type callExprVisitor struct { } func (v *callExprVisitor) Visit(node ast.Node) ast.Visitor { - switch typed := node.(type) { - case nil: + if v.expr != nil || node == nil { return nil - case *ast.IfStmt: - ast.Walk(v, typed.Cond) - case *ast.CallExpr: - v.expr = typed } + debug("visit (%T): %s", node, debugFormatNode{node}) - if v.expr != nil { + if callExpr, ok := node.(*ast.CallExpr); ok { + v.expr = callExpr return nil } return v } + +// FormatNode using go/format.Node and return the result as a string +func FormatNode(node ast.Node) (string, error) { + buf := new(bytes.Buffer) + err := format.Node(buf, token.NewFileSet(), node) + return buf.String(), err +} + +// CallExprArgs returns the ast.Expr slice for the args of an ast.CallExpr at +// the index in the call stack. +func CallExprArgs(stackIndex int) ([]ast.Expr, error) { + _, filename, lineNum, ok := runtime.Caller(baseStackIndex + stackIndex) + if !ok { + return nil, errors.New("failed to get call stack") + } + debug("call stack position: %s:%d", filename, lineNum) + + node, err := getNodeAtLine(filename, lineNum) + if err != nil { + return nil, err + } + debug("found node (%T): %s", node, debugFormatNode{node}) + + return getCallExprArgs(node) +} + +var debugEnabled = os.Getenv("GOTESTYOURSELF_DEBUG") != "" + +func debug(format string, args ...interface{}) { + if debugEnabled { + fmt.Fprintf(os.Stderr, "DEBUG: "+format+"\n", args...) + } +} + +type debugFormatNode struct { + ast.Node +} + +func (n debugFormatNode) String() string { + out, err := FormatNode(n.Node) + if err != nil { + return fmt.Sprintf("failed to format %s: %s", n.Node, err) + } + return out +} diff --git a/components/engine/vendor/github.com/gotestyourself/gotestyourself/skip/skip.go b/components/engine/vendor/github.com/gotestyourself/gotestyourself/skip/skip.go index 3891112fa97..46ab288819b 100644 --- a/components/engine/vendor/github.com/gotestyourself/gotestyourself/skip/skip.go +++ b/components/engine/vendor/github.com/gotestyourself/gotestyourself/skip/skip.go @@ -72,7 +72,7 @@ func ifCondition(t skipT, condition bool, msgAndArgs ...interface{}) { stackIndex = 2 argPos = 1 ) - source, err := source.GetCondition(stackIndex, argPos) + source, err := source.FormattedCallExprArg(stackIndex, argPos) if err != nil { t.Log(err.Error()) t.Skip(format.Message(msgAndArgs...)) diff --git a/components/engine/vendor/github.com/stretchr/testify/LICENSE b/components/engine/vendor/github.com/stretchr/testify/LICENSE deleted file mode 100644 index 473b670a7c6..00000000000 --- a/components/engine/vendor/github.com/stretchr/testify/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell - -Please consider promoting this project if you find it useful. - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of the Software, -and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT -OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/components/engine/vendor/github.com/stretchr/testify/README.md b/components/engine/vendor/github.com/stretchr/testify/README.md deleted file mode 100644 index e57b1811f0a..00000000000 --- a/components/engine/vendor/github.com/stretchr/testify/README.md +++ /dev/null @@ -1,332 +0,0 @@ -Testify - Thou Shalt Write Tests -================================ - -[![Build Status](https://travis-ci.org/stretchr/testify.svg)](https://travis-ci.org/stretchr/testify) [![Go Report Card](https://goreportcard.com/badge/github.com/stretchr/testify)](https://goreportcard.com/report/github.com/stretchr/testify) [![GoDoc](https://godoc.org/github.com/stretchr/testify?status.svg)](https://godoc.org/github.com/stretchr/testify) - -Go code (golang) set of packages that provide many tools for testifying that your code will behave as you intend. - -Features include: - - * [Easy assertions](#assert-package) - * [Mocking](#mock-package) - * [HTTP response trapping](#http-package) - * [Testing suite interfaces and functions](#suite-package) - -Get started: - - * Install testify with [one line of code](#installation), or [update it with another](#staying-up-to-date) - * For an introduction to writing test code in Go, see http://golang.org/doc/code.html#Testing - * Check out the API Documentation http://godoc.org/github.com/stretchr/testify - * To make your testing life easier, check out our other project, [gorc](http://github.com/stretchr/gorc) - * A little about [Test-Driven Development (TDD)](http://en.wikipedia.org/wiki/Test-driven_development) - - - -[`assert`](http://godoc.org/github.com/stretchr/testify/assert "API documentation") package -------------------------------------------------------------------------------------------- - -The `assert` package provides some helpful methods that allow you to write better test code in Go. - - * Prints friendly, easy to read failure descriptions - * Allows for very readable code - * Optionally annotate each assertion with a message - -See it in action: - -```go -package yours - -import ( - "testing" - "github.com/stretchr/testify/assert" -) - -func TestSomething(t *testing.T) { - - // assert equality - assert.Equal(t, 123, 123, "they should be equal") - - // assert inequality - assert.NotEqual(t, 123, 456, "they should not be equal") - - // assert for nil (good for errors) - assert.Nil(t, object) - - // assert for not nil (good when you expect something) - if assert.NotNil(t, object) { - - // now we know that object isn't nil, we are safe to make - // further assertions without causing any errors - assert.Equal(t, "Something", object.Value) - - } - -} -``` - - * Every assert func takes the `testing.T` object as the first argument. This is how it writes the errors out through the normal `go test` capabilities. - * Every assert func returns a bool indicating whether the assertion was successful or not, this is useful for if you want to go on making further assertions under certain conditions. - -if you assert many times, use the below: - -```go -package yours - -import ( - "testing" - "github.com/stretchr/testify/assert" -) - -func TestSomething(t *testing.T) { - assert := assert.New(t) - - // assert equality - assert.Equal(123, 123, "they should be equal") - - // assert inequality - assert.NotEqual(123, 456, "they should not be equal") - - // assert for nil (good for errors) - assert.Nil(object) - - // assert for not nil (good when you expect something) - if assert.NotNil(object) { - - // now we know that object isn't nil, we are safe to make - // further assertions without causing any errors - assert.Equal("Something", object.Value) - } -} -``` - -[`require`](http://godoc.org/github.com/stretchr/testify/require "API documentation") package ---------------------------------------------------------------------------------------------- - -The `require` package provides same global functions as the `assert` package, but instead of returning a boolean result they terminate current test. - -See [t.FailNow](http://golang.org/pkg/testing/#T.FailNow) for details. - - -[`http`](http://godoc.org/github.com/stretchr/testify/http "API documentation") package ---------------------------------------------------------------------------------------- - -The `http` package contains test objects useful for testing code that relies on the `net/http` package. Check out the [(deprecated) API documentation for the `http` package](http://godoc.org/github.com/stretchr/testify/http). - -We recommend you use [httptest](http://golang.org/pkg/net/http/httptest) instead. - -[`mock`](http://godoc.org/github.com/stretchr/testify/mock "API documentation") package ----------------------------------------------------------------------------------------- - -The `mock` package provides a mechanism for easily writing mock objects that can be used in place of real objects when writing test code. - -An example test function that tests a piece of code that relies on an external object `testObj`, can setup expectations (testify) and assert that they indeed happened: - -```go -package yours - -import ( - "testing" - "github.com/stretchr/testify/mock" -) - -/* - Test objects -*/ - -// MyMockedObject is a mocked object that implements an interface -// that describes an object that the code I am testing relies on. -type MyMockedObject struct{ - mock.Mock -} - -// DoSomething is a method on MyMockedObject that implements some interface -// and just records the activity, and returns what the Mock object tells it to. -// -// In the real object, this method would do something useful, but since this -// is a mocked object - we're just going to stub it out. -// -// NOTE: This method is not being tested here, code that uses this object is. -func (m *MyMockedObject) DoSomething(number int) (bool, error) { - - args := m.Called(number) - return args.Bool(0), args.Error(1) - -} - -/* - Actual test functions -*/ - -// TestSomething is an example of how to use our test object to -// make assertions about some target code we are testing. -func TestSomething(t *testing.T) { - - // create an instance of our test object - testObj := new(MyMockedObject) - - // setup expectations - testObj.On("DoSomething", 123).Return(true, nil) - - // call the code we are testing - targetFuncThatDoesSomethingWithObj(testObj) - - // assert that the expectations were met - testObj.AssertExpectations(t) - -} -``` - -For more information on how to write mock code, check out the [API documentation for the `mock` package](http://godoc.org/github.com/stretchr/testify/mock). - -You can use the [mockery tool](http://github.com/vektra/mockery) to autogenerate the mock code against an interface as well, making using mocks much quicker. - -[`suite`](http://godoc.org/github.com/stretchr/testify/suite "API documentation") package ------------------------------------------------------------------------------------------ - -The `suite` package provides functionality that you might be used to from more common object oriented languages. With it, you can build a testing suite as a struct, build setup/teardown methods and testing methods on your struct, and run them with 'go test' as per normal. - -An example suite is shown below: - -```go -// Basic imports -import ( - "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/suite" -) - -// Define the suite, and absorb the built-in basic suite -// functionality from testify - including a T() method which -// returns the current testing context -type ExampleTestSuite struct { - suite.Suite - VariableThatShouldStartAtFive int -} - -// Make sure that VariableThatShouldStartAtFive is set to five -// before each test -func (suite *ExampleTestSuite) SetupTest() { - suite.VariableThatShouldStartAtFive = 5 -} - -// All methods that begin with "Test" are run as tests within a -// suite. -func (suite *ExampleTestSuite) TestExample() { - assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive) -} - -// In order for 'go test' to run this suite, we need to create -// a normal test function and pass our suite to suite.Run -func TestExampleTestSuite(t *testing.T) { - suite.Run(t, new(ExampleTestSuite)) -} -``` - -For a more complete example, using all of the functionality provided by the suite package, look at our [example testing suite](https://github.com/stretchr/testify/blob/master/suite/suite_test.go) - -For more information on writing suites, check out the [API documentation for the `suite` package](http://godoc.org/github.com/stretchr/testify/suite). - -`Suite` object has assertion methods: - -```go -// Basic imports -import ( - "testing" - "github.com/stretchr/testify/suite" -) - -// Define the suite, and absorb the built-in basic suite -// functionality from testify - including assertion methods. -type ExampleTestSuite struct { - suite.Suite - VariableThatShouldStartAtFive int -} - -// Make sure that VariableThatShouldStartAtFive is set to five -// before each test -func (suite *ExampleTestSuite) SetupTest() { - suite.VariableThatShouldStartAtFive = 5 -} - -// All methods that begin with "Test" are run as tests within a -// suite. -func (suite *ExampleTestSuite) TestExample() { - suite.Equal(suite.VariableThatShouldStartAtFive, 5) -} - -// In order for 'go test' to run this suite, we need to create -// a normal test function and pass our suite to suite.Run -func TestExampleTestSuite(t *testing.T) { - suite.Run(t, new(ExampleTestSuite)) -} -``` - ------- - -Installation -============ - -To install Testify, use `go get`: - - * Latest version: go get github.com/stretchr/testify - * Specific version: go get gopkg.in/stretchr/testify.v1 - -This will then make the following packages available to you: - - github.com/stretchr/testify/assert - github.com/stretchr/testify/mock - github.com/stretchr/testify/http - -Import the `testify/assert` package into your code using this template: - -```go -package yours - -import ( - "testing" - "github.com/stretchr/testify/assert" -) - -func TestSomething(t *testing.T) { - - assert.True(t, true, "True is true!") - -} -``` - ------- - -Staying up to date -================== - -To update Testify to the latest version, use `go get -u github.com/stretchr/testify`. - ------- - -Version History -=============== - - * 1.0 - New package versioning strategy adopted. - ------- - -Contributing -============ - -Please feel free to submit issues, fork the repository and send pull requests! - -When submitting an issue, we ask that you please include a complete test function that demonstrates the issue. Extra credit for those using Testify to write the test code that demonstrates it. - ------- - -Licence -======= -Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell - -Please consider promoting this project if you find it useful. - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/components/engine/vendor/github.com/stretchr/testify/assert/assertion_forward.go b/components/engine/vendor/github.com/stretchr/testify/assert/assertion_forward.go deleted file mode 100644 index aa4311ff846..00000000000 --- a/components/engine/vendor/github.com/stretchr/testify/assert/assertion_forward.go +++ /dev/null @@ -1,352 +0,0 @@ -/* -* CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen -* THIS FILE MUST NOT BE EDITED BY HAND - */ - -package assert - -import ( - http "net/http" - url "net/url" - time "time" -) - -// Condition uses a Comparison to assert a complex condition. -func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool { - return Condition(a.t, comp, msgAndArgs...) -} - -// Contains asserts that the specified string, list(array, slice...) or map contains the -// specified substring or element. -// -// a.Contains("Hello World", "World", "But 'Hello World' does contain 'World'") -// a.Contains(["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'") -// a.Contains({"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { - return Contains(a.t, s, contains, msgAndArgs...) -} - -// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// a.Empty(obj) -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool { - return Empty(a.t, object, msgAndArgs...) -} - -// Equal asserts that two objects are equal. -// -// a.Equal(123, 123, "123 and 123 should be equal") -// -// Returns whether the assertion was successful (true) or not (false). -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). -func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { - return Equal(a.t, expected, actual, msgAndArgs...) -} - -// EqualError asserts that a function returned an error (i.e. not `nil`) -// and that it is equal to the provided error. -// -// actualObj, err := SomeFunction() -// a.EqualError(err, expectedErrorString, "An error was expected") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool { - return EqualError(a.t, theError, errString, msgAndArgs...) -} - -// EqualValues asserts that two objects are equal or convertable to the same types -// and equal. -// -// a.EqualValues(uint32(123), int32(123), "123 and 123 should be equal") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { - return EqualValues(a.t, expected, actual, msgAndArgs...) -} - -// Error asserts that a function returned an error (i.e. not `nil`). -// -// actualObj, err := SomeFunction() -// if a.Error(err, "An error was expected") { -// assert.Equal(t, err, expectedError) -// } -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool { - return Error(a.t, err, msgAndArgs...) -} - -// Exactly asserts that two objects are equal is value and type. -// -// a.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { - return Exactly(a.t, expected, actual, msgAndArgs...) -} - -// Fail reports a failure through -func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool { - return Fail(a.t, failureMessage, msgAndArgs...) -} - -// FailNow fails test -func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) bool { - return FailNow(a.t, failureMessage, msgAndArgs...) -} - -// False asserts that the specified value is false. -// -// a.False(myBool, "myBool should be false") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool { - return False(a.t, value, msgAndArgs...) -} - -// HTTPBodyContains asserts that a specified handler returns a -// body that contains a string. -// -// a.HTTPBodyContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) bool { - return HTTPBodyContains(a.t, handler, method, url, values, str) -} - -// HTTPBodyNotContains asserts that a specified handler returns a -// body that does not contain a string. -// -// a.HTTPBodyNotContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) bool { - return HTTPBodyNotContains(a.t, handler, method, url, values, str) -} - -// HTTPError asserts that a specified handler returns an error status code. -// -// a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values) bool { - return HTTPError(a.t, handler, method, url, values) -} - -// HTTPRedirect asserts that a specified handler returns a redirect status code. -// -// a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values) bool { - return HTTPRedirect(a.t, handler, method, url, values) -} - -// HTTPSuccess asserts that a specified handler returns a success status code. -// -// a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values) bool { - return HTTPSuccess(a.t, handler, method, url, values) -} - -// Implements asserts that an object is implemented by the specified interface. -// -// a.Implements((*MyInterface)(nil), new(MyObject), "MyObject") -func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { - return Implements(a.t, interfaceObject, object, msgAndArgs...) -} - -// InDelta asserts that the two numerals are within delta of each other. -// -// a.InDelta(math.Pi, (22 / 7.0), 0.01) -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { - return InDelta(a.t, expected, actual, delta, msgAndArgs...) -} - -// InDeltaSlice is the same as InDelta, except it compares two slices. -func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { - return InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...) -} - -// InEpsilon asserts that expected and actual have a relative error less than epsilon -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { - return InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...) -} - -// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. -func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { - return InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...) -} - -// IsType asserts that the specified objects are of the same type. -func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { - return IsType(a.t, expectedType, object, msgAndArgs...) -} - -// JSONEq asserts that two JSON strings are equivalent. -// -// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool { - return JSONEq(a.t, expected, actual, msgAndArgs...) -} - -// Len asserts that the specified object has specific length. -// Len also fails if the object has a type that len() not accept. -// -// a.Len(mySlice, 3, "The size of slice is not 3") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool { - return Len(a.t, object, length, msgAndArgs...) -} - -// Nil asserts that the specified object is nil. -// -// a.Nil(err, "err should be nothing") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool { - return Nil(a.t, object, msgAndArgs...) -} - -// NoError asserts that a function returned no error (i.e. `nil`). -// -// actualObj, err := SomeFunction() -// if a.NoError(err) { -// assert.Equal(t, actualObj, expectedObj) -// } -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool { - return NoError(a.t, err, msgAndArgs...) -} - -// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the -// specified substring or element. -// -// a.NotContains("Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'") -// a.NotContains(["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'") -// a.NotContains({"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { - return NotContains(a.t, s, contains, msgAndArgs...) -} - -// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// if a.NotEmpty(obj) { -// assert.Equal(t, "two", obj[1]) -// } -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool { - return NotEmpty(a.t, object, msgAndArgs...) -} - -// NotEqual asserts that the specified values are NOT equal. -// -// a.NotEqual(obj1, obj2, "two objects shouldn't be equal") -// -// Returns whether the assertion was successful (true) or not (false). -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). -func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { - return NotEqual(a.t, expected, actual, msgAndArgs...) -} - -// NotNil asserts that the specified object is not nil. -// -// a.NotNil(err, "err should be something") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool { - return NotNil(a.t, object, msgAndArgs...) -} - -// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. -// -// a.NotPanics(func(){ -// RemainCalm() -// }, "Calling RemainCalm() should NOT panic") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool { - return NotPanics(a.t, f, msgAndArgs...) -} - -// NotRegexp asserts that a specified regexp does not match a string. -// -// a.NotRegexp(regexp.MustCompile("starts"), "it's starting") -// a.NotRegexp("^start", "it's not starting") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { - return NotRegexp(a.t, rx, str, msgAndArgs...) -} - -// NotZero asserts that i is not the zero value for its type and returns the truth. -func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool { - return NotZero(a.t, i, msgAndArgs...) -} - -// Panics asserts that the code inside the specified PanicTestFunc panics. -// -// a.Panics(func(){ -// GoCrazy() -// }, "Calling GoCrazy() should panic") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool { - return Panics(a.t, f, msgAndArgs...) -} - -// Regexp asserts that a specified regexp matches a string. -// -// a.Regexp(regexp.MustCompile("start"), "it's starting") -// a.Regexp("start...$", "it's not starting") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { - return Regexp(a.t, rx, str, msgAndArgs...) -} - -// True asserts that the specified value is true. -// -// a.True(myBool, "myBool should be true") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool { - return True(a.t, value, msgAndArgs...) -} - -// WithinDuration asserts that the two times are within duration delta of each other. -// -// a.WithinDuration(time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { - return WithinDuration(a.t, expected, actual, delta, msgAndArgs...) -} - -// Zero asserts that i is the zero value for its type and returns the truth. -func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool { - return Zero(a.t, i, msgAndArgs...) -} diff --git a/components/engine/vendor/github.com/stretchr/testify/assert/assertions.go b/components/engine/vendor/github.com/stretchr/testify/assert/assertions.go deleted file mode 100644 index d1552e5e3f8..00000000000 --- a/components/engine/vendor/github.com/stretchr/testify/assert/assertions.go +++ /dev/null @@ -1,1069 +0,0 @@ -package assert - -import ( - "bufio" - "bytes" - "encoding/json" - "fmt" - "math" - "reflect" - "regexp" - "runtime" - "strings" - "time" - "unicode" - "unicode/utf8" - - "github.com/davecgh/go-spew/spew" - "github.com/pmezard/go-difflib/difflib" -) - -// TestingT is an interface wrapper around *testing.T -type TestingT interface { - Errorf(format string, args ...interface{}) -} - -// Comparison a custom function that returns true on success and false on failure -type Comparison func() (success bool) - -/* - Helper functions -*/ - -// ObjectsAreEqual determines if two objects are considered equal. -// -// This function does no assertion of any kind. -func ObjectsAreEqual(expected, actual interface{}) bool { - - if expected == nil || actual == nil { - return expected == actual - } - - return reflect.DeepEqual(expected, actual) - -} - -// ObjectsAreEqualValues gets whether two objects are equal, or if their -// values are equal. -func ObjectsAreEqualValues(expected, actual interface{}) bool { - if ObjectsAreEqual(expected, actual) { - return true - } - - actualType := reflect.TypeOf(actual) - if actualType == nil { - return false - } - expectedValue := reflect.ValueOf(expected) - if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) { - // Attempt comparison after type conversion - return reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), actual) - } - - return false -} - -/* CallerInfo is necessary because the assert functions use the testing object -internally, causing it to print the file:line of the assert method, rather than where -the problem actually occurred in calling code.*/ - -// CallerInfo returns an array of strings containing the file and line number -// of each stack frame leading from the current test to the assert call that -// failed. -func CallerInfo() []string { - - pc := uintptr(0) - file := "" - line := 0 - ok := false - name := "" - - callers := []string{} - for i := 0; ; i++ { - pc, file, line, ok = runtime.Caller(i) - if !ok { - // The breaks below failed to terminate the loop, and we ran off the - // end of the call stack. - break - } - - // This is a huge edge case, but it will panic if this is the case, see #180 - if file == "" { - break - } - - f := runtime.FuncForPC(pc) - if f == nil { - break - } - name = f.Name() - - // testing.tRunner is the standard library function that calls - // tests. Subtests are called directly by tRunner, without going through - // the Test/Benchmark/Example function that contains the t.Run calls, so - // with subtests we should break when we hit tRunner, without adding it - // to the list of callers. - if name == "testing.tRunner" { - break - } - - parts := strings.Split(file, "/") - dir := parts[len(parts)-2] - file = parts[len(parts)-1] - if (dir != "assert" && dir != "mock" && dir != "require") || file == "mock_test.go" { - callers = append(callers, fmt.Sprintf("%s:%d", file, line)) - } - - // Drop the package - segments := strings.Split(name, ".") - name = segments[len(segments)-1] - if isTest(name, "Test") || - isTest(name, "Benchmark") || - isTest(name, "Example") { - break - } - } - - return callers -} - -// Stolen from the `go test` tool. -// isTest tells whether name looks like a test (or benchmark, according to prefix). -// It is a Test (say) if there is a character after Test that is not a lower-case letter. -// We don't want TesticularCancer. -func isTest(name, prefix string) bool { - if !strings.HasPrefix(name, prefix) { - return false - } - if len(name) == len(prefix) { // "Test" is ok - return true - } - rune, _ := utf8.DecodeRuneInString(name[len(prefix):]) - return !unicode.IsLower(rune) -} - -// getWhitespaceString returns a string that is long enough to overwrite the default -// output from the go testing framework. -func getWhitespaceString() string { - - _, file, line, ok := runtime.Caller(1) - if !ok { - return "" - } - parts := strings.Split(file, "/") - file = parts[len(parts)-1] - - return strings.Repeat(" ", len(fmt.Sprintf("%s:%d: ", file, line))) - -} - -func messageFromMsgAndArgs(msgAndArgs ...interface{}) string { - if len(msgAndArgs) == 0 || msgAndArgs == nil { - return "" - } - if len(msgAndArgs) == 1 { - return msgAndArgs[0].(string) - } - if len(msgAndArgs) > 1 { - return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...) - } - return "" -} - -// Aligns the provided message so that all lines after the first line start at the same location as the first line. -// Assumes that the first line starts at the correct location (after carriage return, tab, label, spacer and tab). -// The longestLabelLen parameter specifies the length of the longest label in the output (required becaues this is the -// basis on which the alignment occurs). -func indentMessageLines(message string, longestLabelLen int) string { - outBuf := new(bytes.Buffer) - - for i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ { - // no need to align first line because it starts at the correct location (after the label) - if i != 0 { - // append alignLen+1 spaces to align with "{{longestLabel}}:" before adding tab - outBuf.WriteString("\n\r\t" + strings.Repeat(" ", longestLabelLen +1) + "\t") - } - outBuf.WriteString(scanner.Text()) - } - - return outBuf.String() -} - -type failNower interface { - FailNow() -} - -// FailNow fails test -func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { - Fail(t, failureMessage, msgAndArgs...) - - // We cannot extend TestingT with FailNow() and - // maintain backwards compatibility, so we fallback - // to panicking when FailNow is not available in - // TestingT. - // See issue #263 - - if t, ok := t.(failNower); ok { - t.FailNow() - } else { - panic("test failed and t is missing `FailNow()`") - } - return false -} - -// Fail reports a failure through -func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { - content := []labeledContent{ - {"Error Trace", strings.Join(CallerInfo(), "\n\r\t\t\t")}, - {"Error", failureMessage}, - } - - message := messageFromMsgAndArgs(msgAndArgs...) - if len(message) > 0 { - content = append(content, labeledContent{"Messages", message}) - } - - t.Errorf("\r" + getWhitespaceString() + labeledOutput(content...)) - - return false -} - -type labeledContent struct { - label string - content string -} - -// labeledOutput returns a string consisting of the provided labeledContent. Each labeled output is appended in the following manner: -// -// \r\t{{label}}:{{align_spaces}}\t{{content}}\n -// -// The initial carriage return is required to undo/erase any padding added by testing.T.Errorf. The "\t{{label}}:" is for the label. -// If a label is shorter than the longest label provided, padding spaces are added to make all the labels match in length. Once this -// alignment is achieved, "\t{{content}}\n" is added for the output. -// -// If the content of the labeledOutput contains line breaks, the subsequent lines are aligned so that they start at the same location as the first line. -func labeledOutput(content ...labeledContent) string { - longestLabel := 0 - for _, v := range content { - if len(v.label) > longestLabel { - longestLabel = len(v.label) - } - } - var output string - for _, v := range content { - output += "\r\t" + v.label + ":" + strings.Repeat(" ", longestLabel-len(v.label)) + "\t" + indentMessageLines(v.content, longestLabel) + "\n" - } - return output -} - -// Implements asserts that an object is implemented by the specified interface. -// -// assert.Implements(t, (*MyInterface)(nil), new(MyObject), "MyObject") -func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { - - interfaceType := reflect.TypeOf(interfaceObject).Elem() - - if !reflect.TypeOf(object).Implements(interfaceType) { - return Fail(t, fmt.Sprintf("%T must implement %v", object, interfaceType), msgAndArgs...) - } - - return true - -} - -// IsType asserts that the specified objects are of the same type. -func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { - - if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) { - return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...) - } - - return true -} - -// Equal asserts that two objects are equal. -// -// assert.Equal(t, 123, 123, "123 and 123 should be equal") -// -// Returns whether the assertion was successful (true) or not (false). -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). -func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { - - if !ObjectsAreEqual(expected, actual) { - diff := diff(expected, actual) - expected, actual = formatUnequalValues(expected, actual) - return Fail(t, fmt.Sprintf("Not equal: \n"+ - "expected: %s\n"+ - "received: %s%s", expected, actual, diff), msgAndArgs...) - } - - return true - -} - -// formatUnequalValues takes two values of arbitrary types and returns string -// representations appropriate to be presented to the user. -// -// If the values are not of like type, the returned strings will be prefixed -// with the type name, and the value will be enclosed in parenthesis similar -// to a type conversion in the Go grammar. -func formatUnequalValues(expected, actual interface{}) (e string, a string) { - if reflect.TypeOf(expected) != reflect.TypeOf(actual) { - return fmt.Sprintf("%T(%#v)", expected, expected), - fmt.Sprintf("%T(%#v)", actual, actual) - } - - return fmt.Sprintf("%#v", expected), - fmt.Sprintf("%#v", actual) -} - -// EqualValues asserts that two objects are equal or convertable to the same types -// and equal. -// -// assert.EqualValues(t, uint32(123), int32(123), "123 and 123 should be equal") -// -// Returns whether the assertion was successful (true) or not (false). -func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { - - if !ObjectsAreEqualValues(expected, actual) { - diff := diff(expected, actual) - expected, actual = formatUnequalValues(expected, actual) - return Fail(t, fmt.Sprintf("Not equal: \n"+ - "expected: %s\n"+ - "received: %s%s", expected, actual, diff), msgAndArgs...) - } - - return true - -} - -// Exactly asserts that two objects are equal is value and type. -// -// assert.Exactly(t, int32(123), int64(123), "123 and 123 should NOT be equal") -// -// Returns whether the assertion was successful (true) or not (false). -func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { - - aType := reflect.TypeOf(expected) - bType := reflect.TypeOf(actual) - - if aType != bType { - return Fail(t, fmt.Sprintf("Types expected to match exactly\n\r\t%v != %v", aType, bType), msgAndArgs...) - } - - return Equal(t, expected, actual, msgAndArgs...) - -} - -// NotNil asserts that the specified object is not nil. -// -// assert.NotNil(t, err, "err should be something") -// -// Returns whether the assertion was successful (true) or not (false). -func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { - if !isNil(object) { - return true - } - return Fail(t, "Expected value not to be nil.", msgAndArgs...) -} - -// isNil checks if a specified object is nil or not, without Failing. -func isNil(object interface{}) bool { - if object == nil { - return true - } - - value := reflect.ValueOf(object) - kind := value.Kind() - if kind >= reflect.Chan && kind <= reflect.Slice && value.IsNil() { - return true - } - - return false -} - -// Nil asserts that the specified object is nil. -// -// assert.Nil(t, err, "err should be nothing") -// -// Returns whether the assertion was successful (true) or not (false). -func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { - if isNil(object) { - return true - } - return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...) -} - -var numericZeros = []interface{}{ - int(0), - int8(0), - int16(0), - int32(0), - int64(0), - uint(0), - uint8(0), - uint16(0), - uint32(0), - uint64(0), - float32(0), - float64(0), -} - -// isEmpty gets whether the specified object is considered empty or not. -func isEmpty(object interface{}) bool { - - if object == nil { - return true - } else if object == "" { - return true - } else if object == false { - return true - } - - for _, v := range numericZeros { - if object == v { - return true - } - } - - objValue := reflect.ValueOf(object) - - switch objValue.Kind() { - case reflect.Map: - fallthrough - case reflect.Slice, reflect.Chan: - { - return (objValue.Len() == 0) - } - case reflect.Struct: - switch object.(type) { - case time.Time: - return object.(time.Time).IsZero() - } - case reflect.Ptr: - { - if objValue.IsNil() { - return true - } - switch object.(type) { - case *time.Time: - return object.(*time.Time).IsZero() - default: - return false - } - } - } - return false -} - -// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// assert.Empty(t, obj) -// -// Returns whether the assertion was successful (true) or not (false). -func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { - - pass := isEmpty(object) - if !pass { - Fail(t, fmt.Sprintf("Should be empty, but was %v", object), msgAndArgs...) - } - - return pass - -} - -// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// if assert.NotEmpty(t, obj) { -// assert.Equal(t, "two", obj[1]) -// } -// -// Returns whether the assertion was successful (true) or not (false). -func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { - - pass := !isEmpty(object) - if !pass { - Fail(t, fmt.Sprintf("Should NOT be empty, but was %v", object), msgAndArgs...) - } - - return pass - -} - -// getLen try to get length of object. -// return (false, 0) if impossible. -func getLen(x interface{}) (ok bool, length int) { - v := reflect.ValueOf(x) - defer func() { - if e := recover(); e != nil { - ok = false - } - }() - return true, v.Len() -} - -// Len asserts that the specified object has specific length. -// Len also fails if the object has a type that len() not accept. -// -// assert.Len(t, mySlice, 3, "The size of slice is not 3") -// -// Returns whether the assertion was successful (true) or not (false). -func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool { - ok, l := getLen(object) - if !ok { - return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...) - } - - if l != length { - return Fail(t, fmt.Sprintf("\"%s\" should have %d item(s), but has %d", object, length, l), msgAndArgs...) - } - return true -} - -// True asserts that the specified value is true. -// -// assert.True(t, myBool, "myBool should be true") -// -// Returns whether the assertion was successful (true) or not (false). -func True(t TestingT, value bool, msgAndArgs ...interface{}) bool { - - if value != true { - return Fail(t, "Should be true", msgAndArgs...) - } - - return true - -} - -// False asserts that the specified value is false. -// -// assert.False(t, myBool, "myBool should be false") -// -// Returns whether the assertion was successful (true) or not (false). -func False(t TestingT, value bool, msgAndArgs ...interface{}) bool { - - if value != false { - return Fail(t, "Should be false", msgAndArgs...) - } - - return true - -} - -// NotEqual asserts that the specified values are NOT equal. -// -// assert.NotEqual(t, obj1, obj2, "two objects shouldn't be equal") -// -// Returns whether the assertion was successful (true) or not (false). -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). -func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { - - if ObjectsAreEqual(expected, actual) { - return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...) - } - - return true - -} - -// containsElement try loop over the list check if the list includes the element. -// return (false, false) if impossible. -// return (true, false) if element was not found. -// return (true, true) if element was found. -func includeElement(list interface{}, element interface{}) (ok, found bool) { - - listValue := reflect.ValueOf(list) - elementValue := reflect.ValueOf(element) - defer func() { - if e := recover(); e != nil { - ok = false - found = false - } - }() - - if reflect.TypeOf(list).Kind() == reflect.String { - return true, strings.Contains(listValue.String(), elementValue.String()) - } - - if reflect.TypeOf(list).Kind() == reflect.Map { - mapKeys := listValue.MapKeys() - for i := 0; i < len(mapKeys); i++ { - if ObjectsAreEqual(mapKeys[i].Interface(), element) { - return true, true - } - } - return true, false - } - - for i := 0; i < listValue.Len(); i++ { - if ObjectsAreEqual(listValue.Index(i).Interface(), element) { - return true, true - } - } - return true, false - -} - -// Contains asserts that the specified string, list(array, slice...) or map contains the -// specified substring or element. -// -// assert.Contains(t, "Hello World", "World", "But 'Hello World' does contain 'World'") -// assert.Contains(t, ["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'") -// assert.Contains(t, {"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'") -// -// Returns whether the assertion was successful (true) or not (false). -func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { - - ok, found := includeElement(s, contains) - if !ok { - return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...) - } - if !found { - return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", s, contains), msgAndArgs...) - } - - return true - -} - -// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the -// specified substring or element. -// -// assert.NotContains(t, "Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'") -// assert.NotContains(t, ["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'") -// assert.NotContains(t, {"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'") -// -// Returns whether the assertion was successful (true) or not (false). -func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { - - ok, found := includeElement(s, contains) - if !ok { - return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...) - } - if found { - return Fail(t, fmt.Sprintf("\"%s\" should not contain \"%s\"", s, contains), msgAndArgs...) - } - - return true - -} - -// Condition uses a Comparison to assert a complex condition. -func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool { - result := comp() - if !result { - Fail(t, "Condition failed!", msgAndArgs...) - } - return result -} - -// PanicTestFunc defines a func that should be passed to the assert.Panics and assert.NotPanics -// methods, and represents a simple func that takes no arguments, and returns nothing. -type PanicTestFunc func() - -// didPanic returns true if the function passed to it panics. Otherwise, it returns false. -func didPanic(f PanicTestFunc) (bool, interface{}) { - - didPanic := false - var message interface{} - func() { - - defer func() { - if message = recover(); message != nil { - didPanic = true - } - }() - - // call the target function - f() - - }() - - return didPanic, message - -} - -// Panics asserts that the code inside the specified PanicTestFunc panics. -// -// assert.Panics(t, func(){ -// GoCrazy() -// }, "Calling GoCrazy() should panic") -// -// Returns whether the assertion was successful (true) or not (false). -func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { - - if funcDidPanic, panicValue := didPanic(f); !funcDidPanic { - return Fail(t, fmt.Sprintf("func %#v should panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...) - } - - return true -} - -// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. -// -// assert.NotPanics(t, func(){ -// RemainCalm() -// }, "Calling RemainCalm() should NOT panic") -// -// Returns whether the assertion was successful (true) or not (false). -func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { - - if funcDidPanic, panicValue := didPanic(f); funcDidPanic { - return Fail(t, fmt.Sprintf("func %#v should not panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...) - } - - return true -} - -// WithinDuration asserts that the two times are within duration delta of each other. -// -// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s") -// -// Returns whether the assertion was successful (true) or not (false). -func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { - - dt := expected.Sub(actual) - if dt < -delta || dt > delta { - return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...) - } - - return true -} - -func toFloat(x interface{}) (float64, bool) { - var xf float64 - xok := true - - switch xn := x.(type) { - case uint8: - xf = float64(xn) - case uint16: - xf = float64(xn) - case uint32: - xf = float64(xn) - case uint64: - xf = float64(xn) - case int: - xf = float64(xn) - case int8: - xf = float64(xn) - case int16: - xf = float64(xn) - case int32: - xf = float64(xn) - case int64: - xf = float64(xn) - case float32: - xf = float64(xn) - case float64: - xf = float64(xn) - default: - xok = false - } - - return xf, xok -} - -// InDelta asserts that the two numerals are within delta of each other. -// -// assert.InDelta(t, math.Pi, (22 / 7.0), 0.01) -// -// Returns whether the assertion was successful (true) or not (false). -func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { - - af, aok := toFloat(expected) - bf, bok := toFloat(actual) - - if !aok || !bok { - return Fail(t, fmt.Sprintf("Parameters must be numerical"), msgAndArgs...) - } - - if math.IsNaN(af) { - return Fail(t, fmt.Sprintf("Actual must not be NaN"), msgAndArgs...) - } - - if math.IsNaN(bf) { - return Fail(t, fmt.Sprintf("Expected %v with delta %v, but was NaN", expected, delta), msgAndArgs...) - } - - dt := af - bf - if dt < -delta || dt > delta { - return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...) - } - - return true -} - -// InDeltaSlice is the same as InDelta, except it compares two slices. -func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { - if expected == nil || actual == nil || - reflect.TypeOf(actual).Kind() != reflect.Slice || - reflect.TypeOf(expected).Kind() != reflect.Slice { - return Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...) - } - - actualSlice := reflect.ValueOf(actual) - expectedSlice := reflect.ValueOf(expected) - - for i := 0; i < actualSlice.Len(); i++ { - result := InDelta(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta) - if !result { - return result - } - } - - return true -} - -func calcRelativeError(expected, actual interface{}) (float64, error) { - af, aok := toFloat(expected) - if !aok { - return 0, fmt.Errorf("expected value %q cannot be converted to float", expected) - } - if af == 0 { - return 0, fmt.Errorf("expected value must have a value other than zero to calculate the relative error") - } - bf, bok := toFloat(actual) - if !bok { - return 0, fmt.Errorf("expected value %q cannot be converted to float", actual) - } - - return math.Abs(af-bf) / math.Abs(af), nil -} - -// InEpsilon asserts that expected and actual have a relative error less than epsilon -// -// Returns whether the assertion was successful (true) or not (false). -func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { - actualEpsilon, err := calcRelativeError(expected, actual) - if err != nil { - return Fail(t, err.Error(), msgAndArgs...) - } - if actualEpsilon > epsilon { - return Fail(t, fmt.Sprintf("Relative error is too high: %#v (expected)\n"+ - " < %#v (actual)", actualEpsilon, epsilon), msgAndArgs...) - } - - return true -} - -// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. -func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { - if expected == nil || actual == nil || - reflect.TypeOf(actual).Kind() != reflect.Slice || - reflect.TypeOf(expected).Kind() != reflect.Slice { - return Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...) - } - - actualSlice := reflect.ValueOf(actual) - expectedSlice := reflect.ValueOf(expected) - - for i := 0; i < actualSlice.Len(); i++ { - result := InEpsilon(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), epsilon) - if !result { - return result - } - } - - return true -} - -/* - Errors -*/ - -// NoError asserts that a function returned no error (i.e. `nil`). -// -// actualObj, err := SomeFunction() -// if assert.NoError(t, err) { -// assert.Equal(t, actualObj, expectedObj) -// } -// -// Returns whether the assertion was successful (true) or not (false). -func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { - if err != nil { - return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...) - } - - return true -} - -// Error asserts that a function returned an error (i.e. not `nil`). -// -// actualObj, err := SomeFunction() -// if assert.Error(t, err, "An error was expected") { -// assert.Equal(t, err, expectedError) -// } -// -// Returns whether the assertion was successful (true) or not (false). -func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { - - if err == nil { - return Fail(t, "An error is expected but got nil.", msgAndArgs...) - } - - return true -} - -// EqualError asserts that a function returned an error (i.e. not `nil`) -// and that it is equal to the provided error. -// -// actualObj, err := SomeFunction() -// assert.EqualError(t, err, expectedErrorString, "An error was expected") -// -// Returns whether the assertion was successful (true) or not (false). -func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool { - if !Error(t, theError, msgAndArgs...) { - return false - } - expected := errString - actual := theError.Error() - // don't need to use deep equals here, we know they are both strings - if expected != actual { - return Fail(t, fmt.Sprintf("Error message not equal:\n"+ - "expected: %q\n"+ - "received: %q", expected, actual), msgAndArgs...) - } - return true -} - -// matchRegexp return true if a specified regexp matches a string. -func matchRegexp(rx interface{}, str interface{}) bool { - - var r *regexp.Regexp - if rr, ok := rx.(*regexp.Regexp); ok { - r = rr - } else { - r = regexp.MustCompile(fmt.Sprint(rx)) - } - - return (r.FindStringIndex(fmt.Sprint(str)) != nil) - -} - -// Regexp asserts that a specified regexp matches a string. -// -// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") -// assert.Regexp(t, "start...$", "it's not starting") -// -// Returns whether the assertion was successful (true) or not (false). -func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { - - match := matchRegexp(rx, str) - - if !match { - Fail(t, fmt.Sprintf("Expect \"%v\" to match \"%v\"", str, rx), msgAndArgs...) - } - - return match -} - -// NotRegexp asserts that a specified regexp does not match a string. -// -// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") -// assert.NotRegexp(t, "^start", "it's not starting") -// -// Returns whether the assertion was successful (true) or not (false). -func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { - match := matchRegexp(rx, str) - - if match { - Fail(t, fmt.Sprintf("Expect \"%v\" to NOT match \"%v\"", str, rx), msgAndArgs...) - } - - return !match - -} - -// Zero asserts that i is the zero value for its type and returns the truth. -func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { - if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { - return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...) - } - return true -} - -// NotZero asserts that i is not the zero value for its type and returns the truth. -func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { - if i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { - return Fail(t, fmt.Sprintf("Should not be zero, but was %v", i), msgAndArgs...) - } - return true -} - -// JSONEq asserts that two JSON strings are equivalent. -// -// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) -// -// Returns whether the assertion was successful (true) or not (false). -func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool { - var expectedJSONAsInterface, actualJSONAsInterface interface{} - - if err := json.Unmarshal([]byte(expected), &expectedJSONAsInterface); err != nil { - return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid json.\nJSON parsing error: '%s'", expected, err.Error()), msgAndArgs...) - } - - if err := json.Unmarshal([]byte(actual), &actualJSONAsInterface); err != nil { - return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid json.\nJSON parsing error: '%s'", actual, err.Error()), msgAndArgs...) - } - - return Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...) -} - -func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) { - t := reflect.TypeOf(v) - k := t.Kind() - - if k == reflect.Ptr { - t = t.Elem() - k = t.Kind() - } - return t, k -} - -// diff returns a diff of both values as long as both are of the same type and -// are a struct, map, slice or array. Otherwise it returns an empty string. -func diff(expected interface{}, actual interface{}) string { - if expected == nil || actual == nil { - return "" - } - - et, ek := typeAndKind(expected) - at, _ := typeAndKind(actual) - - if et != at { - return "" - } - - if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array { - return "" - } - - e := spewConfig.Sdump(expected) - a := spewConfig.Sdump(actual) - - diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ - A: difflib.SplitLines(e), - B: difflib.SplitLines(a), - FromFile: "Expected", - FromDate: "", - ToFile: "Actual", - ToDate: "", - Context: 1, - }) - - return "\n\nDiff:\n" + diff -} - -var spewConfig = spew.ConfigState{ - Indent: " ", - DisablePointerAddresses: true, - DisableCapacities: true, - SortKeys: true, -} diff --git a/components/engine/vendor/github.com/stretchr/testify/assert/doc.go b/components/engine/vendor/github.com/stretchr/testify/assert/doc.go deleted file mode 100644 index c9dccc4d6cd..00000000000 --- a/components/engine/vendor/github.com/stretchr/testify/assert/doc.go +++ /dev/null @@ -1,45 +0,0 @@ -// Package assert provides a set of comprehensive testing tools for use with the normal Go testing system. -// -// Example Usage -// -// The following is a complete example using assert in a standard test function: -// import ( -// "testing" -// "github.com/stretchr/testify/assert" -// ) -// -// func TestSomething(t *testing.T) { -// -// var a string = "Hello" -// var b string = "Hello" -// -// assert.Equal(t, a, b, "The two words should be the same.") -// -// } -// -// if you assert many times, use the format below: -// -// import ( -// "testing" -// "github.com/stretchr/testify/assert" -// ) -// -// func TestSomething(t *testing.T) { -// assert := assert.New(t) -// -// var a string = "Hello" -// var b string = "Hello" -// -// assert.Equal(a, b, "The two words should be the same.") -// } -// -// Assertions -// -// Assertions allow you to easily write test code, and are global funcs in the `assert` package. -// All assertion functions take, as the first argument, the `*testing.T` object provided by the -// testing framework. This allows the assertion funcs to write the failings and other details to -// the correct place. -// -// Every assertion function also takes an optional string message as the final argument, -// allowing custom error messages to be appended to the message the assertion method outputs. -package assert diff --git a/components/engine/vendor/github.com/stretchr/testify/assert/errors.go b/components/engine/vendor/github.com/stretchr/testify/assert/errors.go deleted file mode 100644 index ac9dc9d1d61..00000000000 --- a/components/engine/vendor/github.com/stretchr/testify/assert/errors.go +++ /dev/null @@ -1,10 +0,0 @@ -package assert - -import ( - "errors" -) - -// AnError is an error instance useful for testing. If the code does not care -// about error specifics, and only needs to return the error for example, this -// error should be used to make the test code more readable. -var AnError = errors.New("assert.AnError general error for testing") diff --git a/components/engine/vendor/github.com/stretchr/testify/assert/forward_assertions.go b/components/engine/vendor/github.com/stretchr/testify/assert/forward_assertions.go deleted file mode 100644 index b867e95ea57..00000000000 --- a/components/engine/vendor/github.com/stretchr/testify/assert/forward_assertions.go +++ /dev/null @@ -1,16 +0,0 @@ -package assert - -// Assertions provides assertion methods around the -// TestingT interface. -type Assertions struct { - t TestingT -} - -// New makes a new Assertions object for the specified TestingT. -func New(t TestingT) *Assertions { - return &Assertions{ - t: t, - } -} - -//go:generate go run ../_codegen/main.go -output-package=assert -template=assertion_forward.go.tmpl diff --git a/components/engine/vendor/github.com/stretchr/testify/assert/http_assertions.go b/components/engine/vendor/github.com/stretchr/testify/assert/http_assertions.go deleted file mode 100644 index fa7ab89b180..00000000000 --- a/components/engine/vendor/github.com/stretchr/testify/assert/http_assertions.go +++ /dev/null @@ -1,106 +0,0 @@ -package assert - -import ( - "fmt" - "net/http" - "net/http/httptest" - "net/url" - "strings" -) - -// httpCode is a helper that returns HTTP code of the response. It returns -1 -// if building a new request fails. -func httpCode(handler http.HandlerFunc, method, url string, values url.Values) int { - w := httptest.NewRecorder() - req, err := http.NewRequest(method, url+"?"+values.Encode(), nil) - if err != nil { - return -1 - } - handler(w, req) - return w.Code -} - -// HTTPSuccess asserts that a specified handler returns a success status code. -// -// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool { - code := httpCode(handler, method, url, values) - if code == -1 { - return false - } - return code >= http.StatusOK && code <= http.StatusPartialContent -} - -// HTTPRedirect asserts that a specified handler returns a redirect status code. -// -// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool { - code := httpCode(handler, method, url, values) - if code == -1 { - return false - } - return code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect -} - -// HTTPError asserts that a specified handler returns an error status code. -// -// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values) bool { - code := httpCode(handler, method, url, values) - if code == -1 { - return false - } - return code >= http.StatusBadRequest -} - -// HTTPBody is a helper that returns HTTP body of the response. It returns -// empty string if building a new request fails. -func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) string { - w := httptest.NewRecorder() - req, err := http.NewRequest(method, url+"?"+values.Encode(), nil) - if err != nil { - return "" - } - handler(w, req) - return w.Body.String() -} - -// HTTPBodyContains asserts that a specified handler returns a -// body that contains a string. -// -// assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool { - body := HTTPBody(handler, method, url, values) - - contains := strings.Contains(body, fmt.Sprint(str)) - if !contains { - Fail(t, fmt.Sprintf("Expected response body for \"%s\" to contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body)) - } - - return contains -} - -// HTTPBodyNotContains asserts that a specified handler returns a -// body that does not contain a string. -// -// assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}) bool { - body := HTTPBody(handler, method, url, values) - - contains := strings.Contains(body, fmt.Sprint(str)) - if contains { - Fail(t, fmt.Sprintf("Expected response body for \"%s\" to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body)) - } - - return !contains -} diff --git a/components/engine/vendor/github.com/stretchr/testify/require/doc.go b/components/engine/vendor/github.com/stretchr/testify/require/doc.go deleted file mode 100644 index 169de39221c..00000000000 --- a/components/engine/vendor/github.com/stretchr/testify/require/doc.go +++ /dev/null @@ -1,28 +0,0 @@ -// Package require implements the same assertions as the `assert` package but -// stops test execution when a test fails. -// -// Example Usage -// -// The following is a complete example using require in a standard test function: -// import ( -// "testing" -// "github.com/stretchr/testify/require" -// ) -// -// func TestSomething(t *testing.T) { -// -// var a string = "Hello" -// var b string = "Hello" -// -// require.Equal(t, a, b, "The two words should be the same.") -// -// } -// -// Assertions -// -// The `require` package have same global functions as in the `assert` package, -// but instead of returning a boolean result they call `t.FailNow()`. -// -// Every assertion function also takes an optional string message as the final argument, -// allowing custom error messages to be appended to the message the assertion method outputs. -package require diff --git a/components/engine/vendor/github.com/stretchr/testify/require/forward_requirements.go b/components/engine/vendor/github.com/stretchr/testify/require/forward_requirements.go deleted file mode 100644 index d3c2ab9bc7e..00000000000 --- a/components/engine/vendor/github.com/stretchr/testify/require/forward_requirements.go +++ /dev/null @@ -1,16 +0,0 @@ -package require - -// Assertions provides assertion methods around the -// TestingT interface. -type Assertions struct { - t TestingT -} - -// New makes a new Assertions object for the specified TestingT. -func New(t TestingT) *Assertions { - return &Assertions{ - t: t, - } -} - -//go:generate go run ../_codegen/main.go -output-package=require -template=require_forward.go.tmpl diff --git a/components/engine/vendor/github.com/stretchr/testify/require/require.go b/components/engine/vendor/github.com/stretchr/testify/require/require.go deleted file mode 100644 index fc567f140a2..00000000000 --- a/components/engine/vendor/github.com/stretchr/testify/require/require.go +++ /dev/null @@ -1,429 +0,0 @@ -/* -* CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen -* THIS FILE MUST NOT BE EDITED BY HAND - */ - -package require - -import ( - assert "github.com/stretchr/testify/assert" - http "net/http" - url "net/url" - time "time" -) - -// Condition uses a Comparison to assert a complex condition. -func Condition(t TestingT, comp assert.Comparison, msgAndArgs ...interface{}) { - if !assert.Condition(t, comp, msgAndArgs...) { - t.FailNow() - } -} - -// Contains asserts that the specified string, list(array, slice...) or map contains the -// specified substring or element. -// -// assert.Contains(t, "Hello World", "World", "But 'Hello World' does contain 'World'") -// assert.Contains(t, ["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'") -// assert.Contains(t, {"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'") -// -// Returns whether the assertion was successful (true) or not (false). -func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) { - if !assert.Contains(t, s, contains, msgAndArgs...) { - t.FailNow() - } -} - -// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// assert.Empty(t, obj) -// -// Returns whether the assertion was successful (true) or not (false). -func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) { - if !assert.Empty(t, object, msgAndArgs...) { - t.FailNow() - } -} - -// Equal asserts that two objects are equal. -// -// assert.Equal(t, 123, 123, "123 and 123 should be equal") -// -// Returns whether the assertion was successful (true) or not (false). -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). -func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if !assert.Equal(t, expected, actual, msgAndArgs...) { - t.FailNow() - } -} - -// EqualError asserts that a function returned an error (i.e. not `nil`) -// and that it is equal to the provided error. -// -// actualObj, err := SomeFunction() -// assert.EqualError(t, err, expectedErrorString, "An error was expected") -// -// Returns whether the assertion was successful (true) or not (false). -func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) { - if !assert.EqualError(t, theError, errString, msgAndArgs...) { - t.FailNow() - } -} - -// EqualValues asserts that two objects are equal or convertable to the same types -// and equal. -// -// assert.EqualValues(t, uint32(123), int32(123), "123 and 123 should be equal") -// -// Returns whether the assertion was successful (true) or not (false). -func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if !assert.EqualValues(t, expected, actual, msgAndArgs...) { - t.FailNow() - } -} - -// Error asserts that a function returned an error (i.e. not `nil`). -// -// actualObj, err := SomeFunction() -// if assert.Error(t, err, "An error was expected") { -// assert.Equal(t, err, expectedError) -// } -// -// Returns whether the assertion was successful (true) or not (false). -func Error(t TestingT, err error, msgAndArgs ...interface{}) { - if !assert.Error(t, err, msgAndArgs...) { - t.FailNow() - } -} - -// Exactly asserts that two objects are equal is value and type. -// -// assert.Exactly(t, int32(123), int64(123), "123 and 123 should NOT be equal") -// -// Returns whether the assertion was successful (true) or not (false). -func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if !assert.Exactly(t, expected, actual, msgAndArgs...) { - t.FailNow() - } -} - -// Fail reports a failure through -func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) { - if !assert.Fail(t, failureMessage, msgAndArgs...) { - t.FailNow() - } -} - -// FailNow fails test -func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) { - if !assert.FailNow(t, failureMessage, msgAndArgs...) { - t.FailNow() - } -} - -// False asserts that the specified value is false. -// -// assert.False(t, myBool, "myBool should be false") -// -// Returns whether the assertion was successful (true) or not (false). -func False(t TestingT, value bool, msgAndArgs ...interface{}) { - if !assert.False(t, value, msgAndArgs...) { - t.FailNow() - } -} - -// HTTPBodyContains asserts that a specified handler returns a -// body that contains a string. -// -// assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) { - if !assert.HTTPBodyContains(t, handler, method, url, values, str) { - t.FailNow() - } -} - -// HTTPBodyNotContains asserts that a specified handler returns a -// body that does not contain a string. -// -// assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) { - if !assert.HTTPBodyNotContains(t, handler, method, url, values, str) { - t.FailNow() - } -} - -// HTTPError asserts that a specified handler returns an error status code. -// -// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values) { - if !assert.HTTPError(t, handler, method, url, values) { - t.FailNow() - } -} - -// HTTPRedirect asserts that a specified handler returns a redirect status code. -// -// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values) { - if !assert.HTTPRedirect(t, handler, method, url, values) { - t.FailNow() - } -} - -// HTTPSuccess asserts that a specified handler returns a success status code. -// -// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) -// -// Returns whether the assertion was successful (true) or not (false). -func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values) { - if !assert.HTTPSuccess(t, handler, method, url, values) { - t.FailNow() - } -} - -// Implements asserts that an object is implemented by the specified interface. -// -// assert.Implements(t, (*MyInterface)(nil), new(MyObject), "MyObject") -func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { - if !assert.Implements(t, interfaceObject, object, msgAndArgs...) { - t.FailNow() - } -} - -// InDelta asserts that the two numerals are within delta of each other. -// -// assert.InDelta(t, math.Pi, (22 / 7.0), 0.01) -// -// Returns whether the assertion was successful (true) or not (false). -func InDelta(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { - if !assert.InDelta(t, expected, actual, delta, msgAndArgs...) { - t.FailNow() - } -} - -// InDeltaSlice is the same as InDelta, except it compares two slices. -func InDeltaSlice(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { - if !assert.InDeltaSlice(t, expected, actual, delta, msgAndArgs...) { - t.FailNow() - } -} - -// InEpsilon asserts that expected and actual have a relative error less than epsilon -// -// Returns whether the assertion was successful (true) or not (false). -func InEpsilon(t TestingT, expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) { - if !assert.InEpsilon(t, expected, actual, epsilon, msgAndArgs...) { - t.FailNow() - } -} - -// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. -func InEpsilonSlice(t TestingT, expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) { - if !assert.InEpsilonSlice(t, expected, actual, epsilon, msgAndArgs...) { - t.FailNow() - } -} - -// IsType asserts that the specified objects are of the same type. -func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) { - if !assert.IsType(t, expectedType, object, msgAndArgs...) { - t.FailNow() - } -} - -// JSONEq asserts that two JSON strings are equivalent. -// -// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) -// -// Returns whether the assertion was successful (true) or not (false). -func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) { - if !assert.JSONEq(t, expected, actual, msgAndArgs...) { - t.FailNow() - } -} - -// Len asserts that the specified object has specific length. -// Len also fails if the object has a type that len() not accept. -// -// assert.Len(t, mySlice, 3, "The size of slice is not 3") -// -// Returns whether the assertion was successful (true) or not (false). -func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) { - if !assert.Len(t, object, length, msgAndArgs...) { - t.FailNow() - } -} - -// Nil asserts that the specified object is nil. -// -// assert.Nil(t, err, "err should be nothing") -// -// Returns whether the assertion was successful (true) or not (false). -func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) { - if !assert.Nil(t, object, msgAndArgs...) { - t.FailNow() - } -} - -// NoError asserts that a function returned no error (i.e. `nil`). -// -// actualObj, err := SomeFunction() -// if assert.NoError(t, err) { -// assert.Equal(t, actualObj, expectedObj) -// } -// -// Returns whether the assertion was successful (true) or not (false). -func NoError(t TestingT, err error, msgAndArgs ...interface{}) { - if !assert.NoError(t, err, msgAndArgs...) { - t.FailNow() - } -} - -// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the -// specified substring or element. -// -// assert.NotContains(t, "Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'") -// assert.NotContains(t, ["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'") -// assert.NotContains(t, {"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'") -// -// Returns whether the assertion was successful (true) or not (false). -func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) { - if !assert.NotContains(t, s, contains, msgAndArgs...) { - t.FailNow() - } -} - -// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// if assert.NotEmpty(t, obj) { -// assert.Equal(t, "two", obj[1]) -// } -// -// Returns whether the assertion was successful (true) or not (false). -func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) { - if !assert.NotEmpty(t, object, msgAndArgs...) { - t.FailNow() - } -} - -// NotEqual asserts that the specified values are NOT equal. -// -// assert.NotEqual(t, obj1, obj2, "two objects shouldn't be equal") -// -// Returns whether the assertion was successful (true) or not (false). -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). -func NotEqual(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - if !assert.NotEqual(t, expected, actual, msgAndArgs...) { - t.FailNow() - } -} - -// NotNil asserts that the specified object is not nil. -// -// assert.NotNil(t, err, "err should be something") -// -// Returns whether the assertion was successful (true) or not (false). -func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) { - if !assert.NotNil(t, object, msgAndArgs...) { - t.FailNow() - } -} - -// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. -// -// assert.NotPanics(t, func(){ -// RemainCalm() -// }, "Calling RemainCalm() should NOT panic") -// -// Returns whether the assertion was successful (true) or not (false). -func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { - if !assert.NotPanics(t, f, msgAndArgs...) { - t.FailNow() - } -} - -// NotRegexp asserts that a specified regexp does not match a string. -// -// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") -// assert.NotRegexp(t, "^start", "it's not starting") -// -// Returns whether the assertion was successful (true) or not (false). -func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) { - if !assert.NotRegexp(t, rx, str, msgAndArgs...) { - t.FailNow() - } -} - -// NotZero asserts that i is not the zero value for its type and returns the truth. -func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) { - if !assert.NotZero(t, i, msgAndArgs...) { - t.FailNow() - } -} - -// Panics asserts that the code inside the specified PanicTestFunc panics. -// -// assert.Panics(t, func(){ -// GoCrazy() -// }, "Calling GoCrazy() should panic") -// -// Returns whether the assertion was successful (true) or not (false). -func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) { - if !assert.Panics(t, f, msgAndArgs...) { - t.FailNow() - } -} - -// Regexp asserts that a specified regexp matches a string. -// -// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") -// assert.Regexp(t, "start...$", "it's not starting") -// -// Returns whether the assertion was successful (true) or not (false). -func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) { - if !assert.Regexp(t, rx, str, msgAndArgs...) { - t.FailNow() - } -} - -// True asserts that the specified value is true. -// -// assert.True(t, myBool, "myBool should be true") -// -// Returns whether the assertion was successful (true) or not (false). -func True(t TestingT, value bool, msgAndArgs ...interface{}) { - if !assert.True(t, value, msgAndArgs...) { - t.FailNow() - } -} - -// WithinDuration asserts that the two times are within duration delta of each other. -// -// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s") -// -// Returns whether the assertion was successful (true) or not (false). -func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) { - if !assert.WithinDuration(t, expected, actual, delta, msgAndArgs...) { - t.FailNow() - } -} - -// Zero asserts that i is the zero value for its type and returns the truth. -func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) { - if !assert.Zero(t, i, msgAndArgs...) { - t.FailNow() - } -} diff --git a/components/engine/vendor/github.com/stretchr/testify/require/require_forward.go b/components/engine/vendor/github.com/stretchr/testify/require/require_forward.go deleted file mode 100644 index caa18793dfa..00000000000 --- a/components/engine/vendor/github.com/stretchr/testify/require/require_forward.go +++ /dev/null @@ -1,353 +0,0 @@ -/* -* CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen -* THIS FILE MUST NOT BE EDITED BY HAND - */ - -package require - -import ( - assert "github.com/stretchr/testify/assert" - http "net/http" - url "net/url" - time "time" -) - -// Condition uses a Comparison to assert a complex condition. -func (a *Assertions) Condition(comp assert.Comparison, msgAndArgs ...interface{}) { - Condition(a.t, comp, msgAndArgs...) -} - -// Contains asserts that the specified string, list(array, slice...) or map contains the -// specified substring or element. -// -// a.Contains("Hello World", "World", "But 'Hello World' does contain 'World'") -// a.Contains(["Hello", "World"], "World", "But ["Hello", "World"] does contain 'World'") -// a.Contains({"Hello": "World"}, "Hello", "But {'Hello': 'World'} does contain 'Hello'") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) { - Contains(a.t, s, contains, msgAndArgs...) -} - -// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// a.Empty(obj) -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) { - Empty(a.t, object, msgAndArgs...) -} - -// Equal asserts that two objects are equal. -// -// a.Equal(123, 123, "123 and 123 should be equal") -// -// Returns whether the assertion was successful (true) or not (false). -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). -func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - Equal(a.t, expected, actual, msgAndArgs...) -} - -// EqualError asserts that a function returned an error (i.e. not `nil`) -// and that it is equal to the provided error. -// -// actualObj, err := SomeFunction() -// a.EqualError(err, expectedErrorString, "An error was expected") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) { - EqualError(a.t, theError, errString, msgAndArgs...) -} - -// EqualValues asserts that two objects are equal or convertable to the same types -// and equal. -// -// a.EqualValues(uint32(123), int32(123), "123 and 123 should be equal") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - EqualValues(a.t, expected, actual, msgAndArgs...) -} - -// Error asserts that a function returned an error (i.e. not `nil`). -// -// actualObj, err := SomeFunction() -// if a.Error(err, "An error was expected") { -// assert.Equal(t, err, expectedError) -// } -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) Error(err error, msgAndArgs ...interface{}) { - Error(a.t, err, msgAndArgs...) -} - -// Exactly asserts that two objects are equal is value and type. -// -// a.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - Exactly(a.t, expected, actual, msgAndArgs...) -} - -// Fail reports a failure through -func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) { - Fail(a.t, failureMessage, msgAndArgs...) -} - -// FailNow fails test -func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) { - FailNow(a.t, failureMessage, msgAndArgs...) -} - -// False asserts that the specified value is false. -// -// a.False(myBool, "myBool should be false") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) False(value bool, msgAndArgs ...interface{}) { - False(a.t, value, msgAndArgs...) -} - -// HTTPBodyContains asserts that a specified handler returns a -// body that contains a string. -// -// a.HTTPBodyContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) { - HTTPBodyContains(a.t, handler, method, url, values, str) -} - -// HTTPBodyNotContains asserts that a specified handler returns a -// body that does not contain a string. -// -// a.HTTPBodyNotContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}) { - HTTPBodyNotContains(a.t, handler, method, url, values, str) -} - -// HTTPError asserts that a specified handler returns an error status code. -// -// a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values) { - HTTPError(a.t, handler, method, url, values) -} - -// HTTPRedirect asserts that a specified handler returns a redirect status code. -// -// a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values) { - HTTPRedirect(a.t, handler, method, url, values) -} - -// HTTPSuccess asserts that a specified handler returns a success status code. -// -// a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values) { - HTTPSuccess(a.t, handler, method, url, values) -} - -// Implements asserts that an object is implemented by the specified interface. -// -// a.Implements((*MyInterface)(nil), new(MyObject), "MyObject") -func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) { - Implements(a.t, interfaceObject, object, msgAndArgs...) -} - -// InDelta asserts that the two numerals are within delta of each other. -// -// a.InDelta(math.Pi, (22 / 7.0), 0.01) -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { - InDelta(a.t, expected, actual, delta, msgAndArgs...) -} - -// InDeltaSlice is the same as InDelta, except it compares two slices. -func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) { - InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...) -} - -// InEpsilon asserts that expected and actual have a relative error less than epsilon -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) { - InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...) -} - -// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. -func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) { - InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...) -} - -// IsType asserts that the specified objects are of the same type. -func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) { - IsType(a.t, expectedType, object, msgAndArgs...) -} - -// JSONEq asserts that two JSON strings are equivalent. -// -// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) { - JSONEq(a.t, expected, actual, msgAndArgs...) -} - -// Len asserts that the specified object has specific length. -// Len also fails if the object has a type that len() not accept. -// -// a.Len(mySlice, 3, "The size of slice is not 3") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) { - Len(a.t, object, length, msgAndArgs...) -} - -// Nil asserts that the specified object is nil. -// -// a.Nil(err, "err should be nothing") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) { - Nil(a.t, object, msgAndArgs...) -} - -// NoError asserts that a function returned no error (i.e. `nil`). -// -// actualObj, err := SomeFunction() -// if a.NoError(err) { -// assert.Equal(t, actualObj, expectedObj) -// } -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) { - NoError(a.t, err, msgAndArgs...) -} - -// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the -// specified substring or element. -// -// a.NotContains("Hello World", "Earth", "But 'Hello World' does NOT contain 'Earth'") -// a.NotContains(["Hello", "World"], "Earth", "But ['Hello', 'World'] does NOT contain 'Earth'") -// a.NotContains({"Hello": "World"}, "Earth", "But {'Hello': 'World'} does NOT contain 'Earth'") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) { - NotContains(a.t, s, contains, msgAndArgs...) -} - -// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either -// a slice or a channel with len == 0. -// -// if a.NotEmpty(obj) { -// assert.Equal(t, "two", obj[1]) -// } -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) { - NotEmpty(a.t, object, msgAndArgs...) -} - -// NotEqual asserts that the specified values are NOT equal. -// -// a.NotEqual(obj1, obj2, "two objects shouldn't be equal") -// -// Returns whether the assertion was successful (true) or not (false). -// -// Pointer variable equality is determined based on the equality of the -// referenced values (as opposed to the memory addresses). -func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) { - NotEqual(a.t, expected, actual, msgAndArgs...) -} - -// NotNil asserts that the specified object is not nil. -// -// a.NotNil(err, "err should be something") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) { - NotNil(a.t, object, msgAndArgs...) -} - -// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. -// -// a.NotPanics(func(){ -// RemainCalm() -// }, "Calling RemainCalm() should NOT panic") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) NotPanics(f assert.PanicTestFunc, msgAndArgs ...interface{}) { - NotPanics(a.t, f, msgAndArgs...) -} - -// NotRegexp asserts that a specified regexp does not match a string. -// -// a.NotRegexp(regexp.MustCompile("starts"), "it's starting") -// a.NotRegexp("^start", "it's not starting") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) { - NotRegexp(a.t, rx, str, msgAndArgs...) -} - -// NotZero asserts that i is not the zero value for its type and returns the truth. -func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) { - NotZero(a.t, i, msgAndArgs...) -} - -// Panics asserts that the code inside the specified PanicTestFunc panics. -// -// a.Panics(func(){ -// GoCrazy() -// }, "Calling GoCrazy() should panic") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) Panics(f assert.PanicTestFunc, msgAndArgs ...interface{}) { - Panics(a.t, f, msgAndArgs...) -} - -// Regexp asserts that a specified regexp matches a string. -// -// a.Regexp(regexp.MustCompile("start"), "it's starting") -// a.Regexp("start...$", "it's not starting") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) { - Regexp(a.t, rx, str, msgAndArgs...) -} - -// True asserts that the specified value is true. -// -// a.True(myBool, "myBool should be true") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) True(value bool, msgAndArgs ...interface{}) { - True(a.t, value, msgAndArgs...) -} - -// WithinDuration asserts that the two times are within duration delta of each other. -// -// a.WithinDuration(time.Now(), time.Now(), 10*time.Second, "The difference should not be more than 10s") -// -// Returns whether the assertion was successful (true) or not (false). -func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) { - WithinDuration(a.t, expected, actual, delta, msgAndArgs...) -} - -// Zero asserts that i is the zero value for its type and returns the truth. -func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) { - Zero(a.t, i, msgAndArgs...) -} diff --git a/components/engine/vendor/github.com/stretchr/testify/require/requirements.go b/components/engine/vendor/github.com/stretchr/testify/require/requirements.go deleted file mode 100644 index 41147562d86..00000000000 --- a/components/engine/vendor/github.com/stretchr/testify/require/requirements.go +++ /dev/null @@ -1,9 +0,0 @@ -package require - -// TestingT is an interface wrapper around *testing.T -type TestingT interface { - Errorf(format string, args ...interface{}) - FailNow() -} - -//go:generate go run ../_codegen/main.go -output-package=require -template=require.go.tmpl From 03ad49ebec59815bf659bfb9480693c55979bdb7 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Tue, 13 Mar 2018 15:28:34 -0400 Subject: [PATCH 07/36] Automated migration using gty-migrate-from-testify --ignore-build-tags Signed-off-by: Daniel Nephin (cherry picked from commit 6be0f709830113966f295401327b027ec2f0bbca) Signed-off-by: Sebastiaan van Stijn --- .../api/server/middleware/debug_test.go | 5 +- .../api/server/middleware/version_test.go | 21 +-- .../engine/api/types/filters/parse_test.go | 15 +- .../builder/dockerfile/buildargs_test.go | 17 +- .../engine/builder/dockerfile/builder_test.go | 9 +- .../engine/builder/dockerfile/copy_test.go | 9 +- .../builder/dockerfile/dispatchers_test.go | 150 +++++++++--------- .../dockerfile/instructions/parse_test.go | 28 ++-- .../dockerfile/internals_linux_test.go | 10 +- .../builder/dockerfile/internals_test.go | 16 +- .../dockerfile/internals_windows_test.go | 7 +- .../dockerfile/parser/line_parsers_test.go | 15 +- .../builder/dockerfile/parser/parser_test.go | 48 +++--- .../builder/dockerfile/shell/lex_test.go | 13 +- .../engine/builder/fscache/fscache_test.go | 75 ++++----- .../remotecontext/git/gitutils_test.go | 110 ++++++------- .../builder/remotecontext/mimetype_test.go | 8 +- .../builder/remotecontext/remote_test.go | 18 +-- components/engine/client/client_test.go | 44 ++--- .../engine/client/config_create_test.go | 5 +- .../engine/client/config_inspect_test.go | 5 +- components/engine/client/config_list_test.go | 5 +- .../engine/client/config_remove_test.go | 5 +- .../engine/client/config_update_test.go | 5 +- .../engine/client/container_prune_test.go | 13 +- .../engine/client/container_remove_test.go | 11 +- .../client/distribution_inspect_test.go | 5 +- components/engine/client/image_prune_test.go | 13 +- components/engine/client/image_remove_test.go | 9 +- .../engine/client/network_inspect_test.go | 11 +- .../engine/client/network_prune_test.go | 9 +- components/engine/client/ping_test.go | 27 ++-- components/engine/client/request_test.go | 6 +- .../engine/client/secret_create_test.go | 5 +- .../engine/client/secret_inspect_test.go | 5 +- components/engine/client/secret_list_test.go | 5 +- .../engine/client/secret_remove_test.go | 5 +- .../engine/client/secret_update_test.go | 5 +- .../engine/client/service_create_test.go | 11 +- .../engine/client/service_remove_test.go | 9 +- .../client/swarm_get_unlock_key_test.go | 8 +- .../engine/client/volume_inspect_test.go | 10 +- .../engine/cmd/dockerd/config_unix_test.go | 9 +- components/engine/cmd/dockerd/daemon_test.go | 82 +++++----- .../engine/cmd/dockerd/daemon_unix_test.go | 58 +++---- components/engine/cmd/dockerd/options_test.go | 19 +-- .../engine/container/container_unit_test.go | 18 +-- components/engine/container/view_test.go | 51 +++--- .../daemon/cluster/convert/service_test.go | 8 +- .../executor/container/container_test.go | 4 +- .../engine/daemon/config/config_test.go | 19 +-- .../engine/daemon/config/config_unix_test.go | 24 +-- .../daemon/config/config_windows_test.go | 12 +- .../engine/daemon/container_unix_test.go | 6 +- components/engine/daemon/create_test.go | 4 +- components/engine/daemon/daemon_linux_test.go | 12 +- components/engine/daemon/daemon_test.go | 7 +- components/engine/daemon/daemon_unix_test.go | 6 +- components/engine/daemon/delete_test.go | 4 +- .../engine/daemon/discovery/discovery_test.go | 20 +-- .../daemon/graphdriver/aufs/aufs_test.go | 38 ++--- .../daemon/graphdriver/copy/copy_test.go | 78 ++++----- .../engine/daemon/graphdriver/driver_test.go | 19 ++- .../graphdriver/graphtest/graphbench_unix.go | 4 +- .../graphdriver/graphtest/graphtest_unix.go | 26 +-- .../graphdriver/graphtest/testutil_unix.go | 36 ++--- .../graphdriver/quota/projectquota_test.go | 42 ++--- components/engine/daemon/info_unix_test.go | 9 +- components/engine/daemon/inspect_test.go | 8 +- .../engine/daemon/logger/adapter_test.go | 25 +-- .../logger/awslogs/cloudwatchlogs_test.go | 85 +++++----- .../logger/jsonfilelog/jsonfilelog_test.go | 22 +-- .../jsonfilelog/jsonlog/jsonlogbytes_test.go | 7 +- .../jsonlog/time_marshalling_test.go | 14 +- .../daemon/logger/jsonfilelog/read_test.go | 6 +- .../daemon/logger/splunk/splunk_test.go | 18 +-- .../daemon/logger/templates/templates_test.go | 9 +- components/engine/daemon/oci_linux_test.go | 16 +- components/engine/daemon/reload_test.go | 5 +- components/engine/daemon/trustkey_test.go | 30 ++-- .../metadata/v1_id_service_test.go | 4 +- components/engine/image/fs_test.go | 73 ++++----- components/engine/image/image_test.go | 40 ++--- components/engine/image/store_test.go | 103 ++++++------ .../cli/build/fakegit/fakegit.go | 4 +- .../cli/build/fakestorage/storage.go | 4 +- .../engine/integration-cli/daemon/daemon.go | 18 +-- .../integration-cli/daemon/daemon_swarm.go | 10 +- .../integration-cli/docker_api_build_test.go | 110 ++++++------- .../docker_api_containers_test.go | 34 ++-- .../docker_api_containers_windows_test.go | 12 +- .../docker_api_inspect_test.go | 7 +- .../integration-cli/docker_api_swarm_test.go | 16 +- .../docker_cli_by_digest_test.go | 5 +- .../engine/integration/build/build_test.go | 68 ++++---- .../engine/integration/config/config_test.go | 74 ++++----- .../engine/integration/container/copy_test.go | 11 +- .../container/daemon_linux_test.go | 22 +-- .../engine/integration/container/diff_test.go | 8 +- .../engine/integration/container/exec_test.go | 15 +- .../integration/container/export_test.go | 20 +-- .../integration/container/inspect_test.go | 12 +- .../engine/integration/container/kill_test.go | 28 ++-- .../integration/container/links_linux_test.go | 18 +-- .../engine/integration/container/logs_test.go | 6 +- .../container/mounts_linux_test.go | 14 +- .../engine/integration/container/nat_test.go | 28 ++-- .../integration/container/pause_test.go | 20 +-- .../engine/integration/container/ps_test.go | 12 +- .../integration/container/remove_test.go | 20 +-- .../integration/container/rename_test.go | 54 +++---- .../integration/container/resize_test.go | 10 +- .../integration/container/stats_test.go | 14 +- .../engine/integration/container/stop_test.go | 8 +- .../container/update_linux_test.go | 40 ++--- .../integration/container/update_test.go | 12 +- .../engine/integration/image/commit_test.go | 16 +- .../engine/integration/image/remove_test.go | 22 +-- .../internal/container/container.go | 6 +- .../integration/internal/request/client.go | 8 +- .../integration/internal/swarm/service.go | 14 +- .../engine/integration/network/delete_test.go | 30 ++-- .../integration/network/inspect_test.go | 32 ++-- .../integration/network/service_test.go | 10 +- .../plugin/authz/authz_plugin_test.go | 110 ++++++------- .../plugin/authz/authz_plugin_v2_test.go | 52 +++--- .../plugin/logging/validation_test.go | 6 +- .../engine/integration/secret/secret_test.go | 78 ++++----- .../engine/integration/service/create_test.go | 82 +++++----- .../integration/service/inspect_test.go | 16 +- .../integration/service/network_test.go | 28 ++-- .../integration/session/session_test.go | 28 ++-- .../engine/integration/system/event_test.go | 34 ++-- .../integration/system/info_linux_test.go | 46 +++--- .../engine/integration/system/info_test.go | 8 +- .../engine/integration/system/login_test.go | 5 +- .../engine/integration/system/version_test.go | 16 +- .../engine/integration/volume/volume_test.go | 32 ++-- .../engine/internal/test/environment/clean.go | 29 ++-- .../internal/test/environment/protect.go | 22 +-- .../engine/internal/testutil/helpers.go | 10 +- .../internal/testutil/stringutils_test.go | 9 +- components/engine/libcontainerd/queue_test.go | 8 +- components/engine/opts/quotedstring_test.go | 17 +- .../engine/pkg/archive/archive_linux_test.go | 44 ++--- components/engine/pkg/archive/archive_test.go | 52 +++--- .../engine/pkg/archive/archive_unix_test.go | 80 +++++----- components/engine/pkg/archive/changes_test.go | 106 ++++++------- .../engine/pkg/archive/copy_unix_test.go | 46 +++--- components/engine/pkg/archive/wrap_test.go | 10 +- .../engine/pkg/authorization/api_test.go | 21 +-- .../pkg/authorization/middleware_test.go | 20 +-- .../pkg/authorization/middleware_unix_test.go | 9 +- .../engine/pkg/fileutils/fileutils_test.go | 8 +- .../engine/pkg/idtools/idtools_unix_test.go | 82 +++++----- components/engine/pkg/ioutils/readers_test.go | 5 +- .../pkg/jsonmessage/jsonmessage_test.go | 5 +- components/engine/pkg/plugins/client_test.go | 14 +- .../engine/pkg/plugins/discovery_unix_test.go | 4 +- components/engine/pkg/plugins/plugin_test.go | 7 +- .../engine/pkg/plugins/transport/http_test.go | 5 +- components/engine/pkg/pools/pools_test.go | 12 +- components/engine/pkg/reexec/reexec_test.go | 17 +- .../engine/pkg/signal/signal_linux_test.go | 9 +- components/engine/pkg/signal/signal_test.go | 15 +- .../engine/pkg/signal/trap_linux_test.go | 24 +-- .../streamformatter/streamformatter_test.go | 34 ++-- .../pkg/streamformatter/streamwriter_test.go | 16 +- .../engine/pkg/sysinfo/sysinfo_linux_test.go | 22 +-- .../engine/pkg/system/stat_unix_test.go | 6 +- components/engine/pkg/tarsum/tarsum_test.go | 16 +- components/engine/pkg/term/ascii_test.go | 18 +-- components/engine/pkg/term/proxy_test.go | 66 ++++---- components/engine/pkg/term/term_linux_test.go | 68 ++++---- components/engine/reference/store_test.go | 20 +-- components/engine/registry/config_test.go | 13 +- components/engine/registry/registry_test.go | 6 +- .../resumable/resumablerequestreader_test.go | 56 +++---- components/engine/runconfig/config_test.go | 16 +- .../engine/runconfig/hostconfig_test.go | 17 +- components/engine/volume/store/db_test.go | 21 +-- .../engine/volume/store/restore_test.go | 24 +-- components/engine/volume/store/store_test.go | 46 +++--- 183 files changed, 2256 insertions(+), 2202 deletions(-) diff --git a/components/engine/api/server/middleware/debug_test.go b/components/engine/api/server/middleware/debug_test.go index a467c4a442d..cc227b32484 100644 --- a/components/engine/api/server/middleware/debug_test.go +++ b/components/engine/api/server/middleware/debug_test.go @@ -3,7 +3,8 @@ package middleware // import "github.com/docker/docker/api/server/middleware" import ( "testing" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestMaskSecretKeys(t *testing.T) { @@ -53,6 +54,6 @@ func TestMaskSecretKeys(t *testing.T) { for _, testcase := range tests { maskSecretKeys(testcase.input, testcase.path) - assert.Equal(t, testcase.expected, testcase.input) + assert.Check(t, is.DeepEqual(testcase.expected, testcase.input)) } } diff --git a/components/engine/api/server/middleware/version_test.go b/components/engine/api/server/middleware/version_test.go index 37d22b5c468..f426acf0a30 100644 --- a/components/engine/api/server/middleware/version_test.go +++ b/components/engine/api/server/middleware/version_test.go @@ -7,7 +7,8 @@ import ( "testing" "github.com/docker/docker/api/server/httputils" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -17,7 +18,7 @@ func TestVersionMiddlewareVersion(t *testing.T) { expectedVersion := defaultVersion handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { v := httputils.VersionFromContext(ctx) - assert.Equal(t, expectedVersion, v) + assert.Check(t, is.Equal(expectedVersion, v)) return nil } @@ -56,9 +57,9 @@ func TestVersionMiddlewareVersion(t *testing.T) { err := h(ctx, resp, req, map[string]string{"version": test.reqVersion}) if test.errString != "" { - assert.EqualError(t, err, test.errString) + assert.Check(t, is.Error(err, test.errString)) } else { - assert.NoError(t, err) + assert.Check(t, err) } } } @@ -66,7 +67,7 @@ func TestVersionMiddlewareVersion(t *testing.T) { func TestVersionMiddlewareWithErrorsReturnsHeaders(t *testing.T) { handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { v := httputils.VersionFromContext(ctx) - assert.NotEmpty(t, v) + assert.Check(t, len(v) != 0) return nil } @@ -81,11 +82,11 @@ func TestVersionMiddlewareWithErrorsReturnsHeaders(t *testing.T) { vars := map[string]string{"version": "0.1"} err := h(ctx, resp, req, vars) - assert.Error(t, err) + assert.Check(t, is.ErrorContains(err, "")) hdr := resp.Result().Header - assert.Contains(t, hdr.Get("Server"), "Docker/"+defaultVersion) - assert.Contains(t, hdr.Get("Server"), runtime.GOOS) - assert.Equal(t, hdr.Get("API-Version"), defaultVersion) - assert.Equal(t, hdr.Get("OSType"), runtime.GOOS) + assert.Check(t, is.Contains(hdr.Get("Server"), "Docker/"+defaultVersion)) + assert.Check(t, is.Contains(hdr.Get("Server"), runtime.GOOS)) + assert.Check(t, is.Equal(hdr.Get("API-Version"), defaultVersion)) + assert.Check(t, is.Equal(hdr.Get("OSType"), runtime.GOOS)) } diff --git a/components/engine/api/types/filters/parse_test.go b/components/engine/api/types/filters/parse_test.go index b54ffa66ecc..fbd9ae4fb17 100644 --- a/components/engine/api/types/filters/parse_test.go +++ b/components/engine/api/types/filters/parse_test.go @@ -4,8 +4,8 @@ import ( "errors" "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestParseArgs(t *testing.T) { @@ -22,10 +22,10 @@ func TestParseArgs(t *testing.T) { for i := range flagArgs { args, err = ParseFlag(flagArgs[i], args) - require.NoError(t, err) + assert.NilError(t, err) } - assert.Len(t, args.Get("created"), 1) - assert.Len(t, args.Get("image.name"), 2) + assert.Check(t, is.Len(args.Get("created"), 1)) + assert.Check(t, is.Len(args.Get("image.name"), 2)) } func TestParseArgsEdgeCase(t *testing.T) { @@ -231,7 +231,7 @@ func TestArgsMatch(t *testing.T) { } for args, field := range matches { - assert.True(t, args.Match(field, source), + assert.Check(t, args.Match(field, source), "Expected field %s to match %s", field, source) } @@ -255,8 +255,7 @@ func TestArgsMatch(t *testing.T) { } for args, field := range differs { - assert.False(t, args.Match(field, source), - "Expected field %s to not match %s", field, source) + assert.Check(t, !args.Match(field, source), "Expected field %s to not match %s", field, source) } } diff --git a/components/engine/builder/dockerfile/buildargs_test.go b/components/engine/builder/dockerfile/buildargs_test.go index c46dd7d49e5..1ce841b404a 100644 --- a/components/engine/builder/dockerfile/buildargs_test.go +++ b/components/engine/builder/dockerfile/buildargs_test.go @@ -4,7 +4,8 @@ import ( "bytes" "testing" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func strPtr(source string) *string { @@ -39,7 +40,7 @@ func TestGetAllAllowed(t *testing.T) { "ArgFromMeta": "frommeta1", "ArgFromMetaOverridden": "fromdockerfile3", } - assert.Equal(t, expected, all) + assert.Check(t, is.DeepEqual(expected, all)) } func TestGetAllMeta(t *testing.T) { @@ -61,7 +62,7 @@ func TestGetAllMeta(t *testing.T) { "ArgOverriddenByOptions": "fromopt2", "ArgNoDefaultInMetaFromOptions": "fromopt3", } - assert.Equal(t, expected, all) + assert.Check(t, is.DeepEqual(expected, all)) } func TestWarnOnUnusedBuildArgs(t *testing.T) { @@ -80,7 +81,7 @@ func TestWarnOnUnusedBuildArgs(t *testing.T) { assert.NotContains(t, out, "ThisArgIsUsed") assert.NotContains(t, out, "HTTPS_PROXY") assert.NotContains(t, out, "HTTP_PROXY") - assert.Contains(t, out, "ThisArgIsNotUsed") + assert.Check(t, is.Contains(out, "ThisArgIsNotUsed")) } func TestIsUnreferencedBuiltin(t *testing.T) { @@ -93,8 +94,8 @@ func TestIsUnreferencedBuiltin(t *testing.T) { buildArgs.AddArg("ThisArgIsUsed", nil) buildArgs.AddArg("HTTPS_PROXY", nil) - assert.True(t, buildArgs.IsReferencedOrNotBuiltin("ThisArgIsUsed")) - assert.True(t, buildArgs.IsReferencedOrNotBuiltin("ThisArgIsNotUsed")) - assert.True(t, buildArgs.IsReferencedOrNotBuiltin("HTTPS_PROXY")) - assert.False(t, buildArgs.IsReferencedOrNotBuiltin("HTTP_PROXY")) + assert.Check(t, buildArgs.IsReferencedOrNotBuiltin("ThisArgIsUsed")) + assert.Check(t, buildArgs.IsReferencedOrNotBuiltin("ThisArgIsNotUsed")) + assert.Check(t, buildArgs.IsReferencedOrNotBuiltin("HTTPS_PROXY")) + assert.Check(t, !buildArgs.IsReferencedOrNotBuiltin("HTTP_PROXY")) } diff --git a/components/engine/builder/dockerfile/builder_test.go b/components/engine/builder/dockerfile/builder_test.go index a3a1f122f9d..6c73b6cceda 100644 --- a/components/engine/builder/dockerfile/builder_test.go +++ b/components/engine/builder/dockerfile/builder_test.go @@ -5,13 +5,14 @@ import ( "testing" "github.com/docker/docker/builder/dockerfile/parser" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestAddNodesForLabelOption(t *testing.T) { dockerfile := "FROM scratch" result, err := parser.Parse(strings.NewReader(dockerfile)) - assert.NoError(t, err) + assert.Check(t, err) labels := map[string]string{ "org.e": "cli-e", @@ -27,8 +28,8 @@ func TestAddNodesForLabelOption(t *testing.T) { "FROM scratch", `LABEL "org.a"='cli-a' "org.b"='cli-b' "org.c"='cli-c' "org.d"='cli-d' "org.e"='cli-e'`, } - assert.Len(t, nodes.Children, 2) + assert.Check(t, is.Len(nodes.Children, 2)) for i, v := range nodes.Children { - assert.Equal(t, expected[i], v.Original) + assert.Check(t, is.Equal(expected[i], v.Original)) } } diff --git a/components/engine/builder/dockerfile/copy_test.go b/components/engine/builder/dockerfile/copy_test.go index da8e0711ac7..f2f895387ce 100644 --- a/components/engine/builder/dockerfile/copy_test.go +++ b/components/engine/builder/dockerfile/copy_test.go @@ -5,8 +5,9 @@ import ( "testing" "github.com/docker/docker/pkg/containerfs" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/fs" - "github.com/stretchr/testify/assert" ) func TestIsExistingDirectory(t *testing.T) { @@ -39,10 +40,10 @@ func TestIsExistingDirectory(t *testing.T) { for _, testcase := range testcases { result, err := isExistingDirectory(©Endpoint{driver: containerfs.NewLocalDriver(), path: testcase.path}) - if !assert.NoError(t, err) { + if !assert.Check(t, err) { continue } - assert.Equal(t, testcase.expected, result, testcase.doc) + assert.Check(t, is.Equal(testcase.expected, result), testcase.doc) } } @@ -142,6 +143,6 @@ func TestGetFilenameForDownload(t *testing.T) { resp.Header.Add("Content-Disposition", testcase.disposition) } filename := getFilenameForDownload(testcase.path, &resp) - assert.Equal(t, testcase.expected, filename) + assert.Check(t, is.Equal(testcase.expected, filename)) } } diff --git a/components/engine/builder/dockerfile/dispatchers_test.go b/components/engine/builder/dockerfile/dispatchers_test.go index 6d52e7e619b..988580cb152 100644 --- a/components/engine/builder/dockerfile/dispatchers_test.go +++ b/components/engine/builder/dockerfile/dispatchers_test.go @@ -16,8 +16,8 @@ import ( "github.com/docker/docker/image" "github.com/docker/docker/pkg/system" "github.com/docker/go-connections/nat" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func newBuilderWithMockBackend() *Builder { @@ -49,13 +49,13 @@ func TestEnv2Variables(t *testing.T) { }, } err := dispatch(sb, envCommand) - require.NoError(t, err) + assert.NilError(t, err) expected := []string{ "var1=val1", "var2=val2", } - assert.Equal(t, expected, sb.state.runConfig.Env) + assert.Check(t, is.DeepEqual(expected, sb.state.runConfig.Env)) } func TestEnvValueWithExistingRunConfigEnv(t *testing.T) { @@ -68,12 +68,12 @@ func TestEnvValueWithExistingRunConfigEnv(t *testing.T) { }, } err := dispatch(sb, envCommand) - require.NoError(t, err) + assert.NilError(t, err) expected := []string{ "var1=val1", "var2=fromenv", } - assert.Equal(t, expected, sb.state.runConfig.Env) + assert.Check(t, is.DeepEqual(expected, sb.state.runConfig.Env)) } func TestMaintainer(t *testing.T) { @@ -82,8 +82,8 @@ func TestMaintainer(t *testing.T) { sb := newDispatchRequest(b, '\\', nil, newBuildArgs(make(map[string]*string)), newStagesBuildResults()) cmd := &instructions.MaintainerCommand{Maintainer: maintainerEntry} err := dispatch(sb, cmd) - require.NoError(t, err) - assert.Equal(t, maintainerEntry, sb.state.maintainer) + assert.NilError(t, err) + assert.Check(t, is.Equal(maintainerEntry, sb.state.maintainer)) } func TestLabel(t *testing.T) { @@ -98,10 +98,10 @@ func TestLabel(t *testing.T) { }, } err := dispatch(sb, cmd) - require.NoError(t, err) + assert.NilError(t, err) - require.Contains(t, sb.state.runConfig.Labels, labelName) - assert.Equal(t, sb.state.runConfig.Labels[labelName], labelValue) + assert.Assert(t, is.Contains(sb.state.runConfig.Labels, labelName)) + assert.Check(t, is.Equal(sb.state.runConfig.Labels[labelName], labelValue)) } func TestFromScratch(t *testing.T) { @@ -113,22 +113,22 @@ func TestFromScratch(t *testing.T) { err := initializeStage(sb, cmd) if runtime.GOOS == "windows" && !system.LCOWSupported() { - assert.EqualError(t, err, "Windows does not support FROM scratch") + assert.Check(t, is.Error(err, "Windows does not support FROM scratch")) return } - require.NoError(t, err) - assert.True(t, sb.state.hasFromImage()) - assert.Equal(t, "", sb.state.imageID) + assert.NilError(t, err) + assert.Check(t, sb.state.hasFromImage()) + assert.Check(t, is.Equal("", sb.state.imageID)) expected := "PATH=" + system.DefaultPathEnv(runtime.GOOS) - assert.Equal(t, []string{expected}, sb.state.runConfig.Env) + assert.Check(t, is.DeepEqual([]string{expected}, sb.state.runConfig.Env)) } func TestFromWithArg(t *testing.T) { tag, expected := ":sometag", "expectedthisid" getImage := func(name string) (builder.Image, builder.ROLayer, error) { - assert.Equal(t, "alpine"+tag, name) + assert.Check(t, is.Equal("alpine"+tag, name)) return &mockImage{id: "expectedthisid"}, nil, nil } b := newBuilderWithMockBackend() @@ -146,21 +146,21 @@ func TestFromWithArg(t *testing.T) { err := processMetaArg(metaArg, shell.NewLex('\\'), args) sb := newDispatchRequest(b, '\\', nil, args, newStagesBuildResults()) - require.NoError(t, err) + assert.NilError(t, err) err = initializeStage(sb, cmd) - require.NoError(t, err) + assert.NilError(t, err) - assert.Equal(t, expected, sb.state.imageID) - assert.Equal(t, expected, sb.state.baseImage.ImageID()) - assert.Len(t, sb.state.buildArgs.GetAllAllowed(), 0) - assert.Len(t, sb.state.buildArgs.GetAllMeta(), 1) + assert.Check(t, is.Equal(expected, sb.state.imageID)) + assert.Check(t, is.Equal(expected, sb.state.baseImage.ImageID())) + assert.Check(t, is.Len(sb.state.buildArgs.GetAllAllowed(), 0)) + assert.Check(t, is.Len(sb.state.buildArgs.GetAllMeta(), 1)) } func TestFromWithUndefinedArg(t *testing.T) { tag, expected := "sometag", "expectedthisid" getImage := func(name string) (builder.Image, builder.ROLayer, error) { - assert.Equal(t, "alpine", name) + assert.Check(t, is.Equal("alpine", name)) return &mockImage{id: "expectedthisid"}, nil, nil } b := newBuilderWithMockBackend() @@ -173,8 +173,8 @@ func TestFromWithUndefinedArg(t *testing.T) { BaseName: "alpine${THETAG}", } err := initializeStage(sb, cmd) - require.NoError(t, err) - assert.Equal(t, expected, sb.state.imageID) + assert.NilError(t, err) + assert.Check(t, is.Equal(expected, sb.state.imageID)) } func TestFromMultiStageWithNamedStage(t *testing.T) { @@ -185,13 +185,13 @@ func TestFromMultiStageWithNamedStage(t *testing.T) { firstSB := newDispatchRequest(b, '\\', nil, newBuildArgs(make(map[string]*string)), previousResults) secondSB := newDispatchRequest(b, '\\', nil, newBuildArgs(make(map[string]*string)), previousResults) err := initializeStage(firstSB, firstFrom) - require.NoError(t, err) - assert.True(t, firstSB.state.hasFromImage()) + assert.NilError(t, err) + assert.Check(t, firstSB.state.hasFromImage()) previousResults.indexed["base"] = firstSB.state.runConfig previousResults.flat = append(previousResults.flat, firstSB.state.runConfig) err = initializeStage(secondSB, secondFrom) - require.NoError(t, err) - assert.True(t, secondSB.state.hasFromImage()) + assert.NilError(t, err) + assert.Check(t, secondSB.state.hasFromImage()) } func TestOnbuild(t *testing.T) { @@ -201,8 +201,8 @@ func TestOnbuild(t *testing.T) { Expression: "ADD . /app/src", } err := dispatch(sb, cmd) - require.NoError(t, err) - assert.Equal(t, "ADD . /app/src", sb.state.runConfig.OnBuild[0]) + assert.NilError(t, err) + assert.Check(t, is.Equal("ADD . /app/src", sb.state.runConfig.OnBuild[0])) } func TestWorkdir(t *testing.T) { @@ -217,8 +217,8 @@ func TestWorkdir(t *testing.T) { } err := dispatch(sb, cmd) - require.NoError(t, err) - assert.Equal(t, workingDir, sb.state.runConfig.WorkingDir) + assert.NilError(t, err) + assert.Check(t, is.Equal(workingDir, sb.state.runConfig.WorkingDir)) } func TestCmd(t *testing.T) { @@ -233,7 +233,7 @@ func TestCmd(t *testing.T) { }, } err := dispatch(sb, cmd) - require.NoError(t, err) + assert.NilError(t, err) var expectedCommand strslice.StrSlice if runtime.GOOS == "windows" { @@ -242,8 +242,8 @@ func TestCmd(t *testing.T) { expectedCommand = strslice.StrSlice(append([]string{"/bin/sh"}, "-c", command)) } - assert.Equal(t, expectedCommand, sb.state.runConfig.Cmd) - assert.True(t, sb.state.cmdSet) + assert.Check(t, is.DeepEqual(expectedCommand, sb.state.runConfig.Cmd)) + assert.Check(t, sb.state.cmdSet) } func TestHealthcheckNone(t *testing.T) { @@ -255,10 +255,10 @@ func TestHealthcheckNone(t *testing.T) { }, } err := dispatch(sb, cmd) - require.NoError(t, err) + assert.NilError(t, err) - require.NotNil(t, sb.state.runConfig.Healthcheck) - assert.Equal(t, []string{"NONE"}, sb.state.runConfig.Healthcheck.Test) + assert.Assert(t, sb.state.runConfig.Healthcheck != nil) + assert.Check(t, is.DeepEqual([]string{"NONE"}, sb.state.runConfig.Healthcheck.Test)) } func TestHealthcheckCmd(t *testing.T) { @@ -272,10 +272,10 @@ func TestHealthcheckCmd(t *testing.T) { }, } err := dispatch(sb, cmd) - require.NoError(t, err) + assert.NilError(t, err) - require.NotNil(t, sb.state.runConfig.Healthcheck) - assert.Equal(t, expectedTest, sb.state.runConfig.Healthcheck.Test) + assert.Assert(t, sb.state.runConfig.Healthcheck != nil) + assert.Check(t, is.DeepEqual(expectedTest, sb.state.runConfig.Healthcheck.Test)) } func TestEntrypoint(t *testing.T) { @@ -290,8 +290,8 @@ func TestEntrypoint(t *testing.T) { }, } err := dispatch(sb, cmd) - require.NoError(t, err) - require.NotNil(t, sb.state.runConfig.Entrypoint) + assert.NilError(t, err) + assert.Assert(t, sb.state.runConfig.Entrypoint != nil) var expectedEntrypoint strslice.StrSlice if runtime.GOOS == "windows" { @@ -299,7 +299,7 @@ func TestEntrypoint(t *testing.T) { } else { expectedEntrypoint = strslice.StrSlice(append([]string{"/bin/sh"}, "-c", entrypointCmd)) } - assert.Equal(t, expectedEntrypoint, sb.state.runConfig.Entrypoint) + assert.Check(t, is.DeepEqual(expectedEntrypoint, sb.state.runConfig.Entrypoint)) } func TestExpose(t *testing.T) { @@ -311,14 +311,14 @@ func TestExpose(t *testing.T) { Ports: []string{exposedPort}, } err := dispatch(sb, cmd) - require.NoError(t, err) + assert.NilError(t, err) - require.NotNil(t, sb.state.runConfig.ExposedPorts) - require.Len(t, sb.state.runConfig.ExposedPorts, 1) + assert.Assert(t, sb.state.runConfig.ExposedPorts != nil) + assert.Assert(t, is.Len(sb.state.runConfig.ExposedPorts, 1)) portsMapping, err := nat.ParsePortSpec(exposedPort) - require.NoError(t, err) - assert.Contains(t, sb.state.runConfig.ExposedPorts, portsMapping[0].Port) + assert.NilError(t, err) + assert.Check(t, is.Contains(sb.state.runConfig.ExposedPorts, portsMapping[0].Port)) } func TestUser(t *testing.T) { @@ -329,8 +329,8 @@ func TestUser(t *testing.T) { User: "test", } err := dispatch(sb, cmd) - require.NoError(t, err) - assert.Equal(t, "test", sb.state.runConfig.User) + assert.NilError(t, err) + assert.Check(t, is.Equal("test", sb.state.runConfig.User)) } func TestVolume(t *testing.T) { @@ -343,10 +343,10 @@ func TestVolume(t *testing.T) { Volumes: []string{exposedVolume}, } err := dispatch(sb, cmd) - require.NoError(t, err) - require.NotNil(t, sb.state.runConfig.Volumes) - assert.Len(t, sb.state.runConfig.Volumes, 1) - assert.Contains(t, sb.state.runConfig.Volumes, exposedVolume) + assert.NilError(t, err) + assert.Assert(t, sb.state.runConfig.Volumes != nil) + assert.Check(t, is.Len(sb.state.runConfig.Volumes, 1)) + assert.Check(t, is.Contains(sb.state.runConfig.Volumes, exposedVolume)) } func TestStopSignal(t *testing.T) { @@ -362,8 +362,8 @@ func TestStopSignal(t *testing.T) { Signal: signal, } err := dispatch(sb, cmd) - require.NoError(t, err) - assert.Equal(t, signal, sb.state.runConfig.StopSignal) + assert.NilError(t, err) + assert.Check(t, is.Equal(signal, sb.state.runConfig.StopSignal)) } func TestArg(t *testing.T) { @@ -374,10 +374,10 @@ func TestArg(t *testing.T) { argVal := "bar" cmd := &instructions.ArgCommand{Key: argName, Value: &argVal} err := dispatch(sb, cmd) - require.NoError(t, err) + assert.NilError(t, err) expected := map[string]string{argName: argVal} - assert.Equal(t, expected, sb.state.buildArgs.GetAllAllowed()) + assert.Check(t, is.DeepEqual(expected, sb.state.buildArgs.GetAllAllowed())) } func TestShell(t *testing.T) { @@ -388,10 +388,10 @@ func TestShell(t *testing.T) { cmd := &instructions.ShellCommand{Shell: strslice.StrSlice{shellCmd}} err := dispatch(sb, cmd) - require.NoError(t, err) + assert.NilError(t, err) expectedShell := strslice.StrSlice([]string{shellCmd}) - assert.Equal(t, expectedShell, sb.state.runConfig.Shell) + assert.Check(t, is.DeepEqual(expectedShell, sb.state.runConfig.Shell)) } func TestPrependEnvOnCmd(t *testing.T) { @@ -403,7 +403,7 @@ func TestPrependEnvOnCmd(t *testing.T) { cmdWithEnv := prependEnvOnCmd(buildArgs, args, cmd) expected := strslice.StrSlice([]string{ "|3", "NO_PROXY=YA", "args=not", "sorted=nope", "foo", "bar"}) - assert.Equal(t, expected, cmdWithEnv) + assert.Check(t, is.DeepEqual(expected, cmdWithEnv)) } func TestRunWithBuildArgs(t *testing.T) { @@ -422,8 +422,8 @@ func TestRunWithBuildArgs(t *testing.T) { imageCache := &mockImageCache{ getCacheFunc: func(parentID string, cfg *container.Config) (string, error) { // Check the runConfig.Cmd sent to probeCache() - assert.Equal(t, cachedCmd, cfg.Cmd) - assert.Equal(t, strslice.StrSlice(nil), cfg.Entrypoint) + assert.Check(t, is.DeepEqual(cachedCmd, cfg.Cmd)) + assert.Check(t, is.DeepEqual(strslice.StrSlice(nil), cfg.Entrypoint)) return "", nil }, } @@ -441,21 +441,21 @@ func TestRunWithBuildArgs(t *testing.T) { } mockBackend.containerCreateFunc = func(config types.ContainerCreateConfig) (container.ContainerCreateCreatedBody, error) { // Check the runConfig.Cmd sent to create() - assert.Equal(t, cmdWithShell, config.Config.Cmd) - assert.Contains(t, config.Config.Env, "one=two") - assert.Equal(t, strslice.StrSlice{""}, config.Config.Entrypoint) + assert.Check(t, is.DeepEqual(cmdWithShell, config.Config.Cmd)) + assert.Check(t, is.Contains(config.Config.Env, "one=two")) + assert.Check(t, is.DeepEqual(strslice.StrSlice{""}, config.Config.Entrypoint)) return container.ContainerCreateCreatedBody{ID: "12345"}, nil } mockBackend.commitFunc = func(cfg backend.CommitConfig) (image.ID, error) { // Check the runConfig.Cmd sent to commit() - assert.Equal(t, origCmd, cfg.Config.Cmd) - assert.Equal(t, cachedCmd, cfg.ContainerConfig.Cmd) - assert.Equal(t, strslice.StrSlice(nil), cfg.Config.Entrypoint) + assert.Check(t, is.DeepEqual(origCmd, cfg.Config.Cmd)) + assert.Check(t, is.DeepEqual(cachedCmd, cfg.ContainerConfig.Cmd)) + assert.Check(t, is.DeepEqual(strslice.StrSlice(nil), cfg.Config.Entrypoint)) return "", nil } from := &instructions.Stage{BaseName: "abcdef"} err := initializeStage(sb, from) - require.NoError(t, err) + assert.NilError(t, err) sb.state.buildArgs.AddArg("one", strPtr("two")) run := &instructions.RunCommand{ ShellDependantCmdLine: instructions.ShellDependantCmdLine{ @@ -463,8 +463,8 @@ func TestRunWithBuildArgs(t *testing.T) { PrependShell: true, }, } - require.NoError(t, dispatch(sb, run)) + assert.NilError(t, dispatch(sb, run)) // Check that runConfig.Cmd has not been modified by run - assert.Equal(t, origCmd, sb.state.runConfig.Cmd) + assert.Check(t, is.DeepEqual(origCmd, sb.state.runConfig.Cmd)) } diff --git a/components/engine/builder/dockerfile/instructions/parse_test.go b/components/engine/builder/dockerfile/instructions/parse_test.go index ffd6d4f45c8..b084ad11c77 100644 --- a/components/engine/builder/dockerfile/instructions/parse_test.go +++ b/components/engine/builder/dockerfile/instructions/parse_test.go @@ -7,8 +7,8 @@ import ( "github.com/docker/docker/builder/dockerfile/command" "github.com/docker/docker/builder/dockerfile/parser" "github.com/docker/docker/internal/testutil" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestCommandsExactlyOneArgument(t *testing.T) { @@ -21,9 +21,9 @@ func TestCommandsExactlyOneArgument(t *testing.T) { for _, command := range commands { ast, err := parser.Parse(strings.NewReader(command)) - require.NoError(t, err) + assert.NilError(t, err) _, err = ParseInstruction(ast.AST.Children[0]) - assert.EqualError(t, err, errExactlyOneArgument(command).Error()) + assert.Check(t, is.Error(err, errExactlyOneArgument(command).Error())) } } @@ -39,9 +39,9 @@ func TestCommandsAtLeastOneArgument(t *testing.T) { for _, command := range commands { ast, err := parser.Parse(strings.NewReader(command)) - require.NoError(t, err) + assert.NilError(t, err) _, err = ParseInstruction(ast.AST.Children[0]) - assert.EqualError(t, err, errAtLeastOneArgument(command).Error()) + assert.Check(t, is.Error(err, errAtLeastOneArgument(command).Error())) } } @@ -53,9 +53,9 @@ func TestCommandsNoDestinationArgument(t *testing.T) { for _, command := range commands { ast, err := parser.Parse(strings.NewReader(command + " arg1")) - require.NoError(t, err) + assert.NilError(t, err) _, err = ParseInstruction(ast.AST.Children[0]) - assert.EqualError(t, err, errNoDestinationArgument(command).Error()) + assert.Check(t, is.Error(err, errNoDestinationArgument(command).Error())) } } @@ -80,7 +80,7 @@ func TestCommandsTooManyArguments(t *testing.T) { }, } _, err := ParseInstruction(node) - assert.EqualError(t, err, errTooManyArguments(command).Error()) + assert.Check(t, is.Error(err, errTooManyArguments(command).Error())) } } @@ -102,7 +102,7 @@ func TestCommandsBlankNames(t *testing.T) { }, } _, err := ParseInstruction(node) - assert.EqualError(t, err, errBlankCommandNames(command).Error()) + assert.Check(t, is.Error(err, errBlankCommandNames(command).Error())) } } @@ -120,11 +120,11 @@ func TestHealthCheckCmd(t *testing.T) { }, } cmd, err := ParseInstruction(node) - assert.NoError(t, err) + assert.Check(t, err) hc, ok := cmd.(*HealthCheckCommand) - assert.True(t, ok) + assert.Check(t, ok) expected := []string{"CMD-SHELL", "hello world"} - assert.Equal(t, expected, hc.Health.Test) + assert.Check(t, is.DeepEqual(expected, hc.Health.Test)) } func TestParseOptInterval(t *testing.T) { @@ -138,7 +138,7 @@ func TestParseOptInterval(t *testing.T) { flInterval.Value = "1ms" _, err = parseOptInterval(flInterval) - require.NoError(t, err) + assert.NilError(t, err) } func TestErrorCases(t *testing.T) { diff --git a/components/engine/builder/dockerfile/internals_linux_test.go b/components/engine/builder/dockerfile/internals_linux_test.go index 08067f8573a..c244ddfe3fe 100644 --- a/components/engine/builder/dockerfile/internals_linux_test.go +++ b/components/engine/builder/dockerfile/internals_linux_test.go @@ -6,8 +6,8 @@ import ( "testing" "github.com/docker/docker/pkg/idtools" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestChownFlagParsing(t *testing.T) { @@ -99,8 +99,8 @@ othergrp:x:6666: } { t.Run(testcase.name, func(t *testing.T) { idPair, err := parseChownFlag(testcase.chownStr, contextDir, testcase.idMapping) - require.NoError(t, err, "Failed to parse chown flag: %q", testcase.chownStr) - assert.Equal(t, testcase.expected, idPair, "chown flag mapping failure") + assert.NilError(t, err, "Failed to parse chown flag: %q", testcase.chownStr) + assert.Check(t, is.DeepEqual(testcase.expected, idPair), "chown flag mapping failure") }) } @@ -132,7 +132,7 @@ othergrp:x:6666: } { t.Run(testcase.name, func(t *testing.T) { _, err := parseChownFlag(testcase.chownStr, contextDir, testcase.idMapping) - assert.EqualError(t, err, testcase.descr, "Expected error string doesn't match") + assert.Check(t, is.Error(err, testcase.descr), "Expected error string doesn't match") }) } } diff --git a/components/engine/builder/dockerfile/internals_test.go b/components/engine/builder/dockerfile/internals_test.go index 24103ecd8ed..ae20026833a 100644 --- a/components/engine/builder/dockerfile/internals_test.go +++ b/components/engine/builder/dockerfile/internals_test.go @@ -12,8 +12,8 @@ import ( "github.com/docker/docker/builder/remotecontext" "github.com/docker/docker/pkg/archive" "github.com/docker/go-connections/nat" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestEmptyDockerfile(t *testing.T) { @@ -60,7 +60,7 @@ func TestNonExistingDockerfile(t *testing.T) { func readAndCheckDockerfile(t *testing.T, testName, contextDir, dockerfilePath, expectedError string) { tarStream, err := archive.Tar(contextDir, archive.Uncompressed) - require.NoError(t, err) + assert.NilError(t, err) defer func() { if err = tarStream.Close(); err != nil { @@ -77,7 +77,7 @@ func readAndCheckDockerfile(t *testing.T, testName, contextDir, dockerfilePath, Source: tarStream, } _, _, err = remotecontext.Detect(config) - assert.EqualError(t, err, expectedError) + assert.Check(t, is.Error(err, expectedError)) } func TestCopyRunConfig(t *testing.T) { @@ -124,9 +124,9 @@ func TestCopyRunConfig(t *testing.T) { Env: defaultEnv, } runConfigCopy := copyRunConfig(runConfig, testcase.modifiers...) - assert.Equal(t, testcase.expected, runConfigCopy, testcase.doc) + assert.Check(t, is.DeepEqual(testcase.expected, runConfigCopy), testcase.doc) // Assert the original was not modified - assert.NotEqual(t, runConfig, runConfigCopy, testcase.doc) + assert.Check(t, runConfig != runConfigCopy, testcase.doc) } } @@ -156,7 +156,7 @@ func fullMutableRunConfig() *container.Config { func TestDeepCopyRunConfig(t *testing.T) { runConfig := fullMutableRunConfig() copy := copyRunConfig(runConfig) - assert.Equal(t, fullMutableRunConfig(), copy) + assert.Check(t, is.DeepEqual(fullMutableRunConfig(), copy)) copy.Cmd[1] = "arg2" copy.Env[1] = "env2=new" @@ -166,5 +166,5 @@ func TestDeepCopyRunConfig(t *testing.T) { copy.OnBuild[0] = "start" copy.Labels["label3"] = "value3" copy.Shell[0] = "sh" - assert.Equal(t, fullMutableRunConfig(), runConfig) + assert.Check(t, is.DeepEqual(fullMutableRunConfig(), runConfig)) } diff --git a/components/engine/builder/dockerfile/internals_windows_test.go b/components/engine/builder/dockerfile/internals_windows_test.go index 08f394ac606..1fc55c07522 100644 --- a/components/engine/builder/dockerfile/internals_windows_test.go +++ b/components/engine/builder/dockerfile/internals_windows_test.go @@ -7,7 +7,8 @@ import ( "testing" "github.com/docker/docker/internal/testutil" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestNormalizeDest(t *testing.T) { @@ -42,10 +43,10 @@ func TestNormalizeDest(t *testing.T) { msg := fmt.Sprintf("Input: %s, %s", testcase.current, testcase.requested) actual, err := normalizeDest(testcase.current, testcase.requested, "windows") if testcase.etext == "" { - if !assert.NoError(t, err, msg) { + if !assert.Check(t, err, msg) { continue } - assert.Equal(t, testcase.expected, actual, msg) + assert.Check(t, is.Equal(testcase.expected, actual), msg) } else { testutil.ErrorContains(t, err, testcase.etext) } diff --git a/components/engine/builder/dockerfile/parser/line_parsers_test.go b/components/engine/builder/dockerfile/parser/line_parsers_test.go index 8ce6a7ad6f7..20369cad0b0 100644 --- a/components/engine/builder/dockerfile/parser/line_parsers_test.go +++ b/components/engine/builder/dockerfile/parser/line_parsers_test.go @@ -3,25 +3,26 @@ package parser // import "github.com/docker/docker/builder/dockerfile/parser" import ( "testing" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestParseNameValOldFormat(t *testing.T) { directive := Directive{} node, err := parseNameVal("foo bar", "LABEL", &directive) - assert.NoError(t, err) + assert.Check(t, err) expected := &Node{ Value: "foo", Next: &Node{Value: "bar"}, } - assert.Equal(t, expected, node) + assert.Check(t, is.DeepEqual(expected, node)) } func TestParseNameValNewFormat(t *testing.T) { directive := Directive{} node, err := parseNameVal("foo=bar thing=star", "LABEL", &directive) - assert.NoError(t, err) + assert.Check(t, err) expected := &Node{ Value: "foo", @@ -35,7 +36,7 @@ func TestParseNameValNewFormat(t *testing.T) { }, }, } - assert.Equal(t, expected, node) + assert.Check(t, is.DeepEqual(expected, node)) } func TestNodeFromLabels(t *testing.T) { @@ -61,7 +62,7 @@ func TestNodeFromLabels(t *testing.T) { } node := NodeFromLabels(labels) - assert.Equal(t, expected, node) + assert.Check(t, is.DeepEqual(expected, node)) } @@ -70,5 +71,5 @@ func TestParseNameValWithoutVal(t *testing.T) { // In Config.Env, a variable without `=` is removed from the environment. (#31634) // However, in Dockerfile, we don't allow "unsetting" an environment variable. (#11922) _, err := parseNameVal("foo", "ENV", &directive) - assert.Error(t, err, "ENV must have two arguments") + assert.Check(t, is.ErrorContains(err, ""), "ENV must have two arguments") } diff --git a/components/engine/builder/dockerfile/parser/parser_test.go b/components/engine/builder/dockerfile/parser/parser_test.go index 807ac1b0973..10bed1f756c 100644 --- a/components/engine/builder/dockerfile/parser/parser_test.go +++ b/components/engine/builder/dockerfile/parser/parser_test.go @@ -11,8 +11,8 @@ import ( "strings" "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) const testDir = "testfiles" @@ -21,11 +21,11 @@ const testFileLineInfo = "testfile-line/Dockerfile" func getDirs(t *testing.T, dir string) []string { f, err := os.Open(dir) - require.NoError(t, err) + assert.NilError(t, err) defer f.Close() dirs, err := f.Readdirnames(0) - require.NoError(t, err) + assert.NilError(t, err) return dirs } @@ -34,11 +34,11 @@ func TestParseErrorCases(t *testing.T) { dockerfile := filepath.Join(negativeTestDir, dir, "Dockerfile") df, err := os.Open(dockerfile) - require.NoError(t, err, dockerfile) + assert.NilError(t, err, dockerfile) defer df.Close() _, err = Parse(df) - assert.Error(t, err, dockerfile) + assert.Check(t, is.ErrorContains(err, ""), dockerfile) } } @@ -48,20 +48,20 @@ func TestParseCases(t *testing.T) { resultfile := filepath.Join(testDir, dir, "result") df, err := os.Open(dockerfile) - require.NoError(t, err, dockerfile) + assert.NilError(t, err, dockerfile) defer df.Close() result, err := Parse(df) - require.NoError(t, err, dockerfile) + assert.NilError(t, err, dockerfile) content, err := ioutil.ReadFile(resultfile) - require.NoError(t, err, resultfile) + assert.NilError(t, err, resultfile) if runtime.GOOS == "windows" { // CRLF --> CR to match Unix behavior content = bytes.Replace(content, []byte{'\x0d', '\x0a'}, []byte{'\x0a'}, -1) } - assert.Equal(t, result.AST.Dump()+"\n", string(content), "In "+dockerfile) + assert.Check(t, is.Equal(result.AST.Dump()+"\n", string(content)), "In "+dockerfile) } } @@ -103,22 +103,22 @@ func TestParseWords(t *testing.T) { for _, test := range tests { words := parseWords(test["input"][0], NewDefaultDirective()) - assert.Equal(t, test["expect"], words) + assert.Check(t, is.DeepEqual(test["expect"], words)) } } func TestParseIncludesLineNumbers(t *testing.T) { df, err := os.Open(testFileLineInfo) - require.NoError(t, err) + assert.NilError(t, err) defer df.Close() result, err := Parse(df) - require.NoError(t, err) + assert.NilError(t, err) ast := result.AST - assert.Equal(t, 5, ast.StartLine) - assert.Equal(t, 31, ast.endLine) - assert.Len(t, ast.Children, 3) + assert.Check(t, is.Equal(5, ast.StartLine)) + assert.Check(t, is.Equal(31, ast.endLine)) + assert.Check(t, is.Len(ast.Children, 3)) expected := [][]int{ {5, 5}, {11, 12}, @@ -126,7 +126,7 @@ func TestParseIncludesLineNumbers(t *testing.T) { } for i, child := range ast.Children { msg := fmt.Sprintf("Child %d", i) - assert.Equal(t, expected[i], []int{child.StartLine, child.endLine}, msg) + assert.Check(t, is.DeepEqual(expected[i], []int{child.StartLine, child.endLine}), msg) } } @@ -153,13 +153,13 @@ RUN indented \ `) result, err := Parse(dockerfile) - require.NoError(t, err) + assert.NilError(t, err) warnings := result.Warnings - assert.Len(t, warnings, 3) - assert.Contains(t, warnings[0], "Empty continuation line found in") - assert.Contains(t, warnings[0], "RUN something following more") - assert.Contains(t, warnings[1], "RUN another thing") - assert.Contains(t, warnings[2], "will become errors in a future release") + assert.Check(t, is.Len(warnings, 3)) + assert.Check(t, is.Contains(warnings[0], "Empty continuation line found in")) + assert.Check(t, is.Contains(warnings[0], "RUN something following more")) + assert.Check(t, is.Contains(warnings[1], "RUN another thing")) + assert.Check(t, is.Contains(warnings[2], "will become errors in a future release")) } func TestParseReturnsScannerErrors(t *testing.T) { @@ -170,5 +170,5 @@ func TestParseReturnsScannerErrors(t *testing.T) { LABEL test=%s `, label)) _, err := Parse(dockerfile) - assert.EqualError(t, err, "dockerfile line greater than max allowed size of 65535") + assert.Check(t, is.Error(err, "dockerfile line greater than max allowed size of 65535")) } diff --git a/components/engine/builder/dockerfile/shell/lex_test.go b/components/engine/builder/dockerfile/shell/lex_test.go index 6932a44e3d6..7a726ad79be 100644 --- a/components/engine/builder/dockerfile/shell/lex_test.go +++ b/components/engine/builder/dockerfile/shell/lex_test.go @@ -7,7 +7,8 @@ import ( "strings" "testing" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestShellParser4EnvVars(t *testing.T) { @@ -15,7 +16,7 @@ func TestShellParser4EnvVars(t *testing.T) { lineCount := 0 file, err := os.Open(fn) - assert.NoError(t, err) + assert.Check(t, err) defer file.Close() shlex := NewLex('\\') @@ -37,7 +38,7 @@ func TestShellParser4EnvVars(t *testing.T) { } words := strings.Split(line, "|") - assert.Len(t, words, 3) + assert.Check(t, is.Len(words, 3)) platform := strings.TrimSpace(words[0]) source := strings.TrimSpace(words[1]) @@ -52,10 +53,10 @@ func TestShellParser4EnvVars(t *testing.T) { ((platform == "U" || platform == "A") && runtime.GOOS != "windows") { newWord, err := shlex.ProcessWord(source, envs) if expected == "error" { - assert.Error(t, err) + assert.Check(t, is.ErrorContains(err, "")) } else { - assert.NoError(t, err) - assert.Equal(t, newWord, expected) + assert.Check(t, err) + assert.Check(t, is.Equal(newWord, expected)) } } } diff --git a/components/engine/builder/fscache/fscache_test.go b/components/engine/builder/fscache/fscache_test.go index 7afee49ed5d..613070f7b67 100644 --- a/components/engine/builder/fscache/fscache_test.go +++ b/components/engine/builder/fscache/fscache_test.go @@ -7,14 +7,15 @@ import ( "testing" "time" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/moby/buildkit/session/filesync" - "github.com/stretchr/testify/assert" "golang.org/x/net/context" ) func TestFSCache(t *testing.T) { tmpDir, err := ioutil.TempDir("", "fscache") - assert.Nil(t, err) + assert.Check(t, err) defer os.RemoveAll(tmpDir) backend := NewNaiveCacheBackend(filepath.Join(tmpDir, "backend")) @@ -26,84 +27,84 @@ func TestFSCache(t *testing.T) { } fscache, err := NewFSCache(opt) - assert.Nil(t, err) + assert.Check(t, err) defer fscache.Close() err = fscache.RegisterTransport("test", &testTransport{}) - assert.Nil(t, err) + assert.Check(t, err) src1, err := fscache.SyncFrom(context.TODO(), &testIdentifier{"foo", "data", "bar"}) - assert.Nil(t, err) + assert.Check(t, err) dt, err := ioutil.ReadFile(filepath.Join(src1.Root().Path(), "foo")) - assert.Nil(t, err) - assert.Equal(t, string(dt), "data") + assert.Check(t, err) + assert.Check(t, is.Equal(string(dt), "data")) // same id doesn't recalculate anything src2, err := fscache.SyncFrom(context.TODO(), &testIdentifier{"foo", "data2", "bar"}) - assert.Nil(t, err) - assert.Equal(t, src1.Root().Path(), src2.Root().Path()) + assert.Check(t, err) + assert.Check(t, is.Equal(src1.Root().Path(), src2.Root().Path())) dt, err = ioutil.ReadFile(filepath.Join(src1.Root().Path(), "foo")) - assert.Nil(t, err) - assert.Equal(t, string(dt), "data") - assert.Nil(t, src2.Close()) + assert.Check(t, err) + assert.Check(t, is.Equal(string(dt), "data")) + assert.Check(t, src2.Close()) src3, err := fscache.SyncFrom(context.TODO(), &testIdentifier{"foo2", "data2", "bar"}) - assert.Nil(t, err) - assert.NotEqual(t, src1.Root().Path(), src3.Root().Path()) + assert.Check(t, err) + assert.Check(t, src1.Root().Path() != src3.Root().Path()) dt, err = ioutil.ReadFile(filepath.Join(src3.Root().Path(), "foo2")) - assert.Nil(t, err) - assert.Equal(t, string(dt), "data2") + assert.Check(t, err) + assert.Check(t, is.Equal(string(dt), "data2")) s, err := fscache.DiskUsage() - assert.Nil(t, err) - assert.Equal(t, s, int64(0)) + assert.Check(t, err) + assert.Check(t, is.Equal(s, int64(0))) - assert.Nil(t, src3.Close()) + assert.Check(t, src3.Close()) s, err = fscache.DiskUsage() - assert.Nil(t, err) - assert.Equal(t, s, int64(5)) + assert.Check(t, err) + assert.Check(t, is.Equal(s, int64(5))) // new upload with the same shared key shoutl overwrite src4, err := fscache.SyncFrom(context.TODO(), &testIdentifier{"foo3", "data3", "bar"}) - assert.Nil(t, err) - assert.NotEqual(t, src1.Root().Path(), src3.Root().Path()) + assert.Check(t, err) + assert.Check(t, src1.Root().Path() != src3.Root().Path()) dt, err = ioutil.ReadFile(filepath.Join(src3.Root().Path(), "foo3")) - assert.Nil(t, err) - assert.Equal(t, string(dt), "data3") - assert.Equal(t, src4.Root().Path(), src3.Root().Path()) - assert.Nil(t, src4.Close()) + assert.Check(t, err) + assert.Check(t, is.Equal(string(dt), "data3")) + assert.Check(t, is.Equal(src4.Root().Path(), src3.Root().Path())) + assert.Check(t, src4.Close()) s, err = fscache.DiskUsage() - assert.Nil(t, err) - assert.Equal(t, s, int64(10)) + assert.Check(t, err) + assert.Check(t, is.Equal(s, int64(10))) // this one goes over the GC limit src5, err := fscache.SyncFrom(context.TODO(), &testIdentifier{"foo4", "datadata", "baz"}) - assert.Nil(t, err) - assert.Nil(t, src5.Close()) + assert.Check(t, err) + assert.Check(t, src5.Close()) // GC happens async time.Sleep(100 * time.Millisecond) // only last insertion after GC s, err = fscache.DiskUsage() - assert.Nil(t, err) - assert.Equal(t, s, int64(8)) + assert.Check(t, err) + assert.Check(t, is.Equal(s, int64(8))) // prune deletes everything released, err := fscache.Prune(context.TODO()) - assert.Nil(t, err) - assert.Equal(t, released, uint64(8)) + assert.Check(t, err) + assert.Check(t, is.Equal(released, uint64(8))) s, err = fscache.DiskUsage() - assert.Nil(t, err) - assert.Equal(t, s, int64(0)) + assert.Check(t, err) + assert.Check(t, is.Equal(s, int64(0))) } type testTransport struct { diff --git a/components/engine/builder/remotecontext/git/gitutils_test.go b/components/engine/builder/remotecontext/git/gitutils_test.go index 4f4d8335089..cb2adb8c291 100644 --- a/components/engine/builder/remotecontext/git/gitutils_test.go +++ b/components/engine/builder/remotecontext/git/gitutils_test.go @@ -13,40 +13,40 @@ import ( "strings" "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestParseRemoteURL(t *testing.T) { dir, err := parseRemoteURL("git://github.com/user/repo.git") - require.NoError(t, err) - assert.NotEmpty(t, dir) - assert.Equal(t, gitRepo{"git://github.com/user/repo.git", "master", ""}, dir) + assert.NilError(t, err) + assert.Check(t, len(dir) != 0) + assert.Check(t, is.DeepEqual(gitRepo{"git://github.com/user/repo.git", "master", ""}, dir)) dir, err = parseRemoteURL("git://github.com/user/repo.git#mybranch:mydir/mysubdir/") - require.NoError(t, err) - assert.NotEmpty(t, dir) - assert.Equal(t, gitRepo{"git://github.com/user/repo.git", "mybranch", "mydir/mysubdir/"}, dir) + assert.NilError(t, err) + assert.Check(t, len(dir) != 0) + assert.Check(t, is.DeepEqual(gitRepo{"git://github.com/user/repo.git", "mybranch", "mydir/mysubdir/"}, dir)) dir, err = parseRemoteURL("https://github.com/user/repo.git") - require.NoError(t, err) - assert.NotEmpty(t, dir) - assert.Equal(t, gitRepo{"https://github.com/user/repo.git", "master", ""}, dir) + assert.NilError(t, err) + assert.Check(t, len(dir) != 0) + assert.Check(t, is.DeepEqual(gitRepo{"https://github.com/user/repo.git", "master", ""}, dir)) dir, err = parseRemoteURL("https://github.com/user/repo.git#mybranch:mydir/mysubdir/") - require.NoError(t, err) - assert.NotEmpty(t, dir) - assert.Equal(t, gitRepo{"https://github.com/user/repo.git", "mybranch", "mydir/mysubdir/"}, dir) + assert.NilError(t, err) + assert.Check(t, len(dir) != 0) + assert.Check(t, is.DeepEqual(gitRepo{"https://github.com/user/repo.git", "mybranch", "mydir/mysubdir/"}, dir)) dir, err = parseRemoteURL("git@github.com:user/repo.git") - require.NoError(t, err) - assert.NotEmpty(t, dir) - assert.Equal(t, gitRepo{"git@github.com:user/repo.git", "master", ""}, dir) + assert.NilError(t, err) + assert.Check(t, len(dir) != 0) + assert.Check(t, is.DeepEqual(gitRepo{"git@github.com:user/repo.git", "master", ""}, dir)) dir, err = parseRemoteURL("git@github.com:user/repo.git#mybranch:mydir/mysubdir/") - require.NoError(t, err) - assert.NotEmpty(t, dir) - assert.Equal(t, gitRepo{"git@github.com:user/repo.git", "mybranch", "mydir/mysubdir/"}, dir) + assert.NilError(t, err) + assert.Check(t, len(dir) != 0) + assert.Check(t, is.DeepEqual(gitRepo{"git@github.com:user/repo.git", "mybranch", "mydir/mysubdir/"}, dir)) } func TestCloneArgsSmartHttp(t *testing.T) { @@ -63,7 +63,7 @@ func TestCloneArgsSmartHttp(t *testing.T) { args := fetchArgs(serverURL.String(), "master") exp := []string{"fetch", "--depth", "1", "origin", "master"} - assert.Equal(t, exp, args) + assert.Check(t, is.DeepEqual(exp, args)) } func TestCloneArgsDumbHttp(t *testing.T) { @@ -79,13 +79,13 @@ func TestCloneArgsDumbHttp(t *testing.T) { args := fetchArgs(serverURL.String(), "master") exp := []string{"fetch", "origin", "master"} - assert.Equal(t, exp, args) + assert.Check(t, is.DeepEqual(exp, args)) } func TestCloneArgsGit(t *testing.T) { args := fetchArgs("git://github.com/docker/docker", "master") exp := []string{"fetch", "--depth", "1", "origin", "master"} - assert.Equal(t, exp, args) + assert.Check(t, is.DeepEqual(exp, args)) } func gitGetConfig(name string) string { @@ -100,7 +100,7 @@ func gitGetConfig(name string) string { func TestCheckoutGit(t *testing.T) { root, err := ioutil.TempDir("", "docker-build-git-checkout") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(root) autocrlf := gitGetConfig("core.autocrlf") @@ -115,22 +115,22 @@ func TestCheckoutGit(t *testing.T) { gitDir := filepath.Join(root, "repo") _, err = git("init", gitDir) - require.NoError(t, err) + assert.NilError(t, err) _, err = gitWithinDir(gitDir, "config", "user.email", "test@docker.com") - require.NoError(t, err) + assert.NilError(t, err) _, err = gitWithinDir(gitDir, "config", "user.name", "Docker test") - require.NoError(t, err) + assert.NilError(t, err) err = ioutil.WriteFile(filepath.Join(gitDir, "Dockerfile"), []byte("FROM scratch"), 0644) - require.NoError(t, err) + assert.NilError(t, err) subDir := filepath.Join(gitDir, "subdir") - require.NoError(t, os.Mkdir(subDir, 0755)) + assert.NilError(t, os.Mkdir(subDir, 0755)) err = ioutil.WriteFile(filepath.Join(subDir, "Dockerfile"), []byte("FROM scratch\nEXPOSE 5000"), 0644) - require.NoError(t, err) + assert.NilError(t, err) if runtime.GOOS != "windows" { if err = os.Symlink("../subdir", filepath.Join(gitDir, "parentlink")); err != nil { @@ -143,58 +143,58 @@ func TestCheckoutGit(t *testing.T) { } _, err = gitWithinDir(gitDir, "add", "-A") - require.NoError(t, err) + assert.NilError(t, err) _, err = gitWithinDir(gitDir, "commit", "-am", "First commit") - require.NoError(t, err) + assert.NilError(t, err) _, err = gitWithinDir(gitDir, "checkout", "-b", "test") - require.NoError(t, err) + assert.NilError(t, err) err = ioutil.WriteFile(filepath.Join(gitDir, "Dockerfile"), []byte("FROM scratch\nEXPOSE 3000"), 0644) - require.NoError(t, err) + assert.NilError(t, err) err = ioutil.WriteFile(filepath.Join(subDir, "Dockerfile"), []byte("FROM busybox\nEXPOSE 5000"), 0644) - require.NoError(t, err) + assert.NilError(t, err) _, err = gitWithinDir(gitDir, "add", "-A") - require.NoError(t, err) + assert.NilError(t, err) _, err = gitWithinDir(gitDir, "commit", "-am", "Branch commit") - require.NoError(t, err) + assert.NilError(t, err) _, err = gitWithinDir(gitDir, "checkout", "master") - require.NoError(t, err) + assert.NilError(t, err) // set up submodule subrepoDir := filepath.Join(root, "subrepo") _, err = git("init", subrepoDir) - require.NoError(t, err) + assert.NilError(t, err) _, err = gitWithinDir(subrepoDir, "config", "user.email", "test@docker.com") - require.NoError(t, err) + assert.NilError(t, err) _, err = gitWithinDir(subrepoDir, "config", "user.name", "Docker test") - require.NoError(t, err) + assert.NilError(t, err) err = ioutil.WriteFile(filepath.Join(subrepoDir, "subfile"), []byte("subcontents"), 0644) - require.NoError(t, err) + assert.NilError(t, err) _, err = gitWithinDir(subrepoDir, "add", "-A") - require.NoError(t, err) + assert.NilError(t, err) _, err = gitWithinDir(subrepoDir, "commit", "-am", "Subrepo initial") - require.NoError(t, err) + assert.NilError(t, err) cmd := exec.Command("git", "submodule", "add", subrepoDir, "sub") // this command doesn't work with --work-tree cmd.Dir = gitDir - require.NoError(t, cmd.Run()) + assert.NilError(t, cmd.Run()) _, err = gitWithinDir(gitDir, "add", "-A") - require.NoError(t, err) + assert.NilError(t, err) _, err = gitWithinDir(gitDir, "commit", "-am", "With submodule") - require.NoError(t, err) + assert.NilError(t, err) type singleCase struct { frag string @@ -232,24 +232,24 @@ func TestCheckoutGit(t *testing.T) { r, err := cloneGitRepo(gitRepo{remote: gitDir, ref: ref, subdir: subdir}) if c.fail { - assert.Error(t, err) + assert.Check(t, is.ErrorContains(err, "")) continue } - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(r) if c.submodule { b, err := ioutil.ReadFile(filepath.Join(r, "sub/subfile")) - require.NoError(t, err) - assert.Equal(t, "subcontents", string(b)) + assert.NilError(t, err) + assert.Check(t, is.Equal("subcontents", string(b))) } else { _, err := os.Stat(filepath.Join(r, "sub/subfile")) - require.Error(t, err) - require.True(t, os.IsNotExist(err)) + assert.Assert(t, is.ErrorContains(err, "")) + assert.Assert(t, os.IsNotExist(err)) } b, err := ioutil.ReadFile(filepath.Join(r, "Dockerfile")) - require.NoError(t, err) - assert.Equal(t, c.exp, string(b)) + assert.NilError(t, err) + assert.Check(t, is.Equal(c.exp, string(b))) } } diff --git a/components/engine/builder/remotecontext/mimetype_test.go b/components/engine/builder/remotecontext/mimetype_test.go index ff097c2e7b0..b13429cfa8a 100644 --- a/components/engine/builder/remotecontext/mimetype_test.go +++ b/components/engine/builder/remotecontext/mimetype_test.go @@ -3,14 +3,14 @@ package remotecontext // import "github.com/docker/docker/builder/remotecontext" import ( "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestDetectContentType(t *testing.T) { input := []byte("That is just a plain text") contentType, _, err := detectContentType(input) - require.NoError(t, err) - assert.Equal(t, "text/plain", contentType) + assert.NilError(t, err) + assert.Check(t, is.Equal("text/plain", contentType)) } diff --git a/components/engine/builder/remotecontext/remote_test.go b/components/engine/builder/remotecontext/remote_test.go index 3983bd1b6c4..5267d23969f 100644 --- a/components/engine/builder/remotecontext/remote_test.go +++ b/components/engine/builder/remotecontext/remote_test.go @@ -11,9 +11,9 @@ import ( "github.com/docker/docker/builder" "github.com/docker/docker/internal/testutil" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/fs" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) var binaryContext = []byte{0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00} //xz magic @@ -189,12 +189,12 @@ func TestDownloadRemote(t *testing.T) { mux.Handle("/", http.FileServer(http.Dir(contextDir.Path()))) contentType, content, err := downloadRemote(remoteURL) - require.NoError(t, err) + assert.NilError(t, err) - assert.Equal(t, mimeTypes.TextPlain, contentType) + assert.Check(t, is.Equal(mimeTypes.TextPlain, contentType)) raw, err := ioutil.ReadAll(content) - require.NoError(t, err) - assert.Equal(t, dockerfileContents, string(raw)) + assert.NilError(t, err) + assert.Check(t, is.Equal(dockerfileContents, string(raw))) } func TestGetWithStatusError(t *testing.T) { @@ -226,11 +226,11 @@ func TestGetWithStatusError(t *testing.T) { response, err := GetWithStatusError(ts.URL) if testcase.expectedErr == "" { - require.NoError(t, err) + assert.NilError(t, err) body, err := readBody(response.Body) - require.NoError(t, err) - assert.Contains(t, string(body), testcase.expectedBody) + assert.NilError(t, err) + assert.Check(t, is.Contains(string(body), testcase.expectedBody)) } else { testutil.ErrorContains(t, err, testcase.expectedErr) } diff --git a/components/engine/client/client_test.go b/components/engine/client/client_test.go index db394e24b56..381a561c197 100644 --- a/components/engine/client/client_test.go +++ b/components/engine/client/client_test.go @@ -11,10 +11,10 @@ import ( "github.com/docker/docker/api" "github.com/docker/docker/api/types" "github.com/docker/docker/internal/testutil" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/env" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestNewEnvClient(t *testing.T) { @@ -89,19 +89,19 @@ func TestNewEnvClient(t *testing.T) { env.PatchAll(t, c.envs) apiclient, err := NewEnvClient() if c.expectedError != "" { - assert.Error(t, err, c.doc) - assert.Equal(t, c.expectedError, err.Error(), c.doc) + assert.Check(t, is.ErrorContains(err, ""), c.doc) + assert.Check(t, is.Equal(c.expectedError, err.Error()), c.doc) } else { - assert.NoError(t, err, c.doc) + assert.Check(t, err, c.doc) version := apiclient.ClientVersion() - assert.Equal(t, c.expectedVersion, version, c.doc) + assert.Check(t, is.Equal(c.expectedVersion, version), c.doc) } if c.envs["DOCKER_TLS_VERIFY"] != "" { // pedantic checking that this is handled correctly tr := apiclient.client.Transport.(*http.Transport) - assert.NotNil(t, tr.TLSClientConfig, c.doc) - assert.Equal(t, tr.TLSClientConfig.InsecureSkipVerify, false, c.doc) + assert.Check(t, tr.TLSClientConfig != nil, c.doc) + assert.Check(t, is.Equal(tr.TLSClientConfig.InsecureSkipVerify, false), c.doc) } } } @@ -128,7 +128,7 @@ func TestGetAPIPath(t *testing.T) { for _, testcase := range testcases { c := Client{version: testcase.version, basePath: "/"} actual := c.getAPIPath(testcase.path, testcase.query) - assert.Equal(t, actual, testcase.expected) + assert.Check(t, is.Equal(actual, testcase.expected)) } } @@ -165,7 +165,7 @@ func TestParseHostURL(t *testing.T) { if testcase.expectedErr != "" { testutil.ErrorContains(t, err, testcase.expectedErr) } - assert.Equal(t, testcase.expected, actual) + assert.Check(t, is.DeepEqual(testcase.expected, actual)) } } @@ -181,7 +181,7 @@ func TestNewEnvClientSetsDefaultVersion(t *testing.T) { if err != nil { t.Fatal(err) } - assert.Equal(t, client.version, api.DefaultVersion) + assert.Check(t, is.Equal(client.version, api.DefaultVersion)) expected := "1.22" os.Setenv("DOCKER_API_VERSION", expected) @@ -189,7 +189,7 @@ func TestNewEnvClientSetsDefaultVersion(t *testing.T) { if err != nil { t.Fatal(err) } - assert.Equal(t, expected, client.version) + assert.Check(t, is.Equal(expected, client.version)) } // TestNegotiateAPIVersionEmpty asserts that client.Client can @@ -198,7 +198,7 @@ func TestNegotiateAPIVersionEmpty(t *testing.T) { defer env.PatchAll(t, map[string]string{"DOCKER_API_VERSION": ""}) client, err := NewEnvClient() - require.NoError(t, err) + assert.NilError(t, err) ping := types.Ping{ APIVersion: "", @@ -215,14 +215,14 @@ func TestNegotiateAPIVersionEmpty(t *testing.T) { // test downgrade client.NegotiateAPIVersionPing(ping) - assert.Equal(t, expected, client.version) + assert.Check(t, is.Equal(expected, client.version)) } // TestNegotiateAPIVersion asserts that client.Client can // negotiate a compatible APIVersion with the server func TestNegotiateAPIVersion(t *testing.T) { client, err := NewEnvClient() - require.NoError(t, err) + assert.NilError(t, err) expected := "1.21" ping := types.Ping{ @@ -236,14 +236,14 @@ func TestNegotiateAPIVersion(t *testing.T) { // test downgrade client.NegotiateAPIVersionPing(ping) - assert.Equal(t, expected, client.version) + assert.Check(t, is.Equal(expected, client.version)) // set the client version to something older, and verify that we keep the // original setting. expected = "1.20" client.version = expected client.NegotiateAPIVersionPing(ping) - assert.Equal(t, expected, client.version) + assert.Check(t, is.Equal(expected, client.version)) } @@ -254,7 +254,7 @@ func TestNegotiateAPVersionOverride(t *testing.T) { defer env.PatchAll(t, map[string]string{"DOCKER_API_VERSION": expected})() client, err := NewEnvClient() - require.NoError(t, err) + assert.NilError(t, err) ping := types.Ping{ APIVersion: "1.24", @@ -264,7 +264,7 @@ func TestNegotiateAPVersionOverride(t *testing.T) { // test that we honored the env var client.NegotiateAPIVersionPing(ping) - assert.Equal(t, expected, client.version) + assert.Check(t, is.Equal(expected, client.version)) } type roundTripFunc func(*http.Request) (*http.Response, error) @@ -309,9 +309,9 @@ func TestClientRedirect(t *testing.T) { for _, tc := range cases { req, err := http.NewRequest(tc.httpMethod, "/redirectme", nil) - assert.NoError(t, err) + assert.Check(t, err) resp, err := client.Do(req) - assert.Equal(t, tc.expectedErr, err) - assert.Equal(t, tc.statusCode, resp.StatusCode) + assert.Check(t, is.DeepEqual(tc.expectedErr, err)) + assert.Check(t, is.Equal(tc.statusCode, resp.StatusCode)) } } diff --git a/components/engine/client/config_create_test.go b/components/engine/client/config_create_test.go index 3f3cb3fc56d..2ee8f1fd40f 100644 --- a/components/engine/client/config_create_test.go +++ b/components/engine/client/config_create_test.go @@ -11,7 +11,8 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -21,7 +22,7 @@ func TestConfigCreateUnsupported(t *testing.T) { client: &http.Client{}, } _, err := client.ConfigCreate(context.Background(), swarm.ConfigSpec{}) - assert.EqualError(t, err, `"config create" requires API version 1.30, but the Docker daemon API version is 1.29`) + assert.Check(t, is.Error(err, `"config create" requires API version 1.30, but the Docker daemon API version is 1.29`)) } func TestConfigCreateError(t *testing.T) { diff --git a/components/engine/client/config_inspect_test.go b/components/engine/client/config_inspect_test.go index c6d73e5c024..9d5af0bf8c6 100644 --- a/components/engine/client/config_inspect_test.go +++ b/components/engine/client/config_inspect_test.go @@ -10,8 +10,9 @@ import ( "testing" "github.com/docker/docker/api/types/swarm" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/pkg/errors" - "github.com/stretchr/testify/assert" "golang.org/x/net/context" ) @@ -44,7 +45,7 @@ func TestConfigInspectUnsupported(t *testing.T) { client: &http.Client{}, } _, _, err := client.ConfigInspectWithRaw(context.Background(), "nothing") - assert.EqualError(t, err, `"config inspect" requires API version 1.30, but the Docker daemon API version is 1.29`) + assert.Check(t, is.Error(err, `"config inspect" requires API version 1.30, but the Docker daemon API version is 1.29`)) } func TestConfigInspectError(t *testing.T) { diff --git a/components/engine/client/config_list_test.go b/components/engine/client/config_list_test.go index 4b4a5e84ce1..0cd99c50d1e 100644 --- a/components/engine/client/config_list_test.go +++ b/components/engine/client/config_list_test.go @@ -12,7 +12,8 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/swarm" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -22,7 +23,7 @@ func TestConfigListUnsupported(t *testing.T) { client: &http.Client{}, } _, err := client.ConfigList(context.Background(), types.ConfigListOptions{}) - assert.EqualError(t, err, `"config list" requires API version 1.30, but the Docker daemon API version is 1.29`) + assert.Check(t, is.Error(err, `"config list" requires API version 1.30, but the Docker daemon API version is 1.29`)) } func TestConfigListError(t *testing.T) { diff --git a/components/engine/client/config_remove_test.go b/components/engine/client/config_remove_test.go index 290395aae52..25a5c4ac876 100644 --- a/components/engine/client/config_remove_test.go +++ b/components/engine/client/config_remove_test.go @@ -8,7 +8,8 @@ import ( "strings" "testing" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -18,7 +19,7 @@ func TestConfigRemoveUnsupported(t *testing.T) { client: &http.Client{}, } err := client.ConfigRemove(context.Background(), "config_id") - assert.EqualError(t, err, `"config remove" requires API version 1.30, but the Docker daemon API version is 1.29`) + assert.Check(t, is.Error(err, `"config remove" requires API version 1.30, but the Docker daemon API version is 1.29`)) } func TestConfigRemoveError(t *testing.T) { diff --git a/components/engine/client/config_update_test.go b/components/engine/client/config_update_test.go index 99f2e173c29..a7eea2f8b14 100644 --- a/components/engine/client/config_update_test.go +++ b/components/engine/client/config_update_test.go @@ -9,7 +9,8 @@ import ( "testing" "github.com/docker/docker/api/types/swarm" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -19,7 +20,7 @@ func TestConfigUpdateUnsupported(t *testing.T) { client: &http.Client{}, } err := client.ConfigUpdate(context.Background(), "config_id", swarm.Version{}, swarm.ConfigSpec{}) - assert.EqualError(t, err, `"config update" requires API version 1.30, but the Docker daemon API version is 1.29`) + assert.Check(t, is.Error(err, `"config update" requires API version 1.30, but the Docker daemon API version is 1.29`)) } func TestConfigUpdateError(t *testing.T) { diff --git a/components/engine/client/container_prune_test.go b/components/engine/client/container_prune_test.go index 1f8c22cbfe9..7ffd9c7ecf6 100644 --- a/components/engine/client/container_prune_test.go +++ b/components/engine/client/container_prune_test.go @@ -11,7 +11,8 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -24,7 +25,7 @@ func TestContainersPruneError(t *testing.T) { filters := filters.NewArgs() _, err := client.ContainersPrune(context.Background(), filters) - assert.EqualError(t, err, "Error response from daemon: Server error") + assert.Check(t, is.Error(err, "Error response from daemon: Server error")) } func TestContainersPrune(t *testing.T) { @@ -99,7 +100,7 @@ func TestContainersPrune(t *testing.T) { query := req.URL.Query() for key, expected := range listCase.expectedQueryParams { actual := query.Get(key) - assert.Equal(t, expected, actual) + assert.Check(t, is.Equal(expected, actual)) } content, err := json.Marshal(types.ContainersPruneReport{ ContainersDeleted: []string{"container_id1", "container_id2"}, @@ -117,8 +118,8 @@ func TestContainersPrune(t *testing.T) { } report, err := client.ContainersPrune(context.Background(), listCase.filters) - assert.NoError(t, err) - assert.Len(t, report.ContainersDeleted, 2) - assert.Equal(t, uint64(9999), report.SpaceReclaimed) + assert.Check(t, err) + assert.Check(t, is.Len(report.ContainersDeleted, 2)) + assert.Check(t, is.Equal(uint64(9999), report.SpaceReclaimed)) } } diff --git a/components/engine/client/container_remove_test.go b/components/engine/client/container_remove_test.go index 0b1b64fa3a4..537272cd1d5 100644 --- a/components/engine/client/container_remove_test.go +++ b/components/engine/client/container_remove_test.go @@ -9,7 +9,8 @@ import ( "testing" "github.com/docker/docker/api/types" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -18,7 +19,7 @@ func TestContainerRemoveError(t *testing.T) { client: newMockClient(errorMock(http.StatusInternalServerError, "Server error")), } err := client.ContainerRemove(context.Background(), "container_id", types.ContainerRemoveOptions{}) - assert.EqualError(t, err, "Error response from daemon: Server error") + assert.Check(t, is.Error(err, "Error response from daemon: Server error")) } func TestContainerRemoveNotFoundError(t *testing.T) { @@ -26,8 +27,8 @@ func TestContainerRemoveNotFoundError(t *testing.T) { client: newMockClient(errorMock(http.StatusNotFound, "missing")), } err := client.ContainerRemove(context.Background(), "container_id", types.ContainerRemoveOptions{}) - assert.EqualError(t, err, "Error: No such container: container_id") - assert.True(t, IsErrNotFound(err)) + assert.Check(t, is.Error(err, "Error: No such container: container_id")) + assert.Check(t, IsErrNotFound(err)) } func TestContainerRemove(t *testing.T) { @@ -61,5 +62,5 @@ func TestContainerRemove(t *testing.T) { RemoveVolumes: true, Force: true, }) - assert.NoError(t, err) + assert.Check(t, err) } diff --git a/components/engine/client/distribution_inspect_test.go b/components/engine/client/distribution_inspect_test.go index 90b35a285b3..d4124bfa153 100644 --- a/components/engine/client/distribution_inspect_test.go +++ b/components/engine/client/distribution_inspect_test.go @@ -4,8 +4,9 @@ import ( "net/http" "testing" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/pkg/errors" - "github.com/stretchr/testify/assert" "golang.org/x/net/context" ) @@ -15,7 +16,7 @@ func TestDistributionInspectUnsupported(t *testing.T) { client: &http.Client{}, } _, err := client.DistributionInspect(context.Background(), "foobar:1.0", "") - assert.EqualError(t, err, `"distribution inspect" requires API version 1.30, but the Docker daemon API version is 1.29`) + assert.Check(t, is.Error(err, `"distribution inspect" requires API version 1.30, but the Docker daemon API version is 1.29`)) } func TestDistributionInspectWithEmptyID(t *testing.T) { diff --git a/components/engine/client/image_prune_test.go b/components/engine/client/image_prune_test.go index f165e5c7462..9b161531f28 100644 --- a/components/engine/client/image_prune_test.go +++ b/components/engine/client/image_prune_test.go @@ -11,7 +11,8 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -24,7 +25,7 @@ func TestImagesPruneError(t *testing.T) { filters := filters.NewArgs() _, err := client.ImagesPrune(context.Background(), filters) - assert.EqualError(t, err, "Error response from daemon: Server error") + assert.Check(t, is.Error(err, "Error response from daemon: Server error")) } func TestImagesPrune(t *testing.T) { @@ -87,7 +88,7 @@ func TestImagesPrune(t *testing.T) { query := req.URL.Query() for key, expected := range listCase.expectedQueryParams { actual := query.Get(key) - assert.Equal(t, expected, actual) + assert.Check(t, is.Equal(expected, actual)) } content, err := json.Marshal(types.ImagesPruneReport{ ImagesDeleted: []types.ImageDeleteResponseItem{ @@ -112,8 +113,8 @@ func TestImagesPrune(t *testing.T) { } report, err := client.ImagesPrune(context.Background(), listCase.filters) - assert.NoError(t, err) - assert.Len(t, report.ImagesDeleted, 2) - assert.Equal(t, uint64(9999), report.SpaceReclaimed) + assert.Check(t, err) + assert.Check(t, is.Len(report.ImagesDeleted, 2)) + assert.Check(t, is.Equal(uint64(9999), report.SpaceReclaimed)) } } diff --git a/components/engine/client/image_remove_test.go b/components/engine/client/image_remove_test.go index 8f5aa0120db..a1686e6496e 100644 --- a/components/engine/client/image_remove_test.go +++ b/components/engine/client/image_remove_test.go @@ -10,7 +10,8 @@ import ( "testing" "github.com/docker/docker/api/types" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -20,7 +21,7 @@ func TestImageRemoveError(t *testing.T) { } _, err := client.ImageRemove(context.Background(), "image_id", types.ImageRemoveOptions{}) - assert.EqualError(t, err, "Error response from daemon: Server error") + assert.Check(t, is.Error(err, "Error response from daemon: Server error")) } func TestImageRemoveImageNotFound(t *testing.T) { @@ -29,8 +30,8 @@ func TestImageRemoveImageNotFound(t *testing.T) { } _, err := client.ImageRemove(context.Background(), "unknown", types.ImageRemoveOptions{}) - assert.EqualError(t, err, "Error: No such image: unknown") - assert.True(t, IsErrNotFound(err)) + assert.Check(t, is.Error(err, "Error: No such image: unknown")) + assert.Check(t, IsErrNotFound(err)) } func TestImageRemove(t *testing.T) { diff --git a/components/engine/client/network_inspect_test.go b/components/engine/client/network_inspect_test.go index 70316119111..8778021ed96 100644 --- a/components/engine/client/network_inspect_test.go +++ b/components/engine/client/network_inspect_test.go @@ -11,8 +11,9 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/network" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/pkg/errors" - "github.com/stretchr/testify/assert" "golang.org/x/net/context" ) @@ -22,7 +23,7 @@ func TestNetworkInspectError(t *testing.T) { } _, err := client.NetworkInspect(context.Background(), "nothing", types.NetworkInspectOptions{}) - assert.EqualError(t, err, "Error response from daemon: Server error") + assert.Check(t, is.Error(err, "Error response from daemon: Server error")) } func TestNetworkInspectNotFoundError(t *testing.T) { @@ -31,8 +32,8 @@ func TestNetworkInspectNotFoundError(t *testing.T) { } _, err := client.NetworkInspect(context.Background(), "unknown", types.NetworkInspectOptions{}) - assert.EqualError(t, err, "Error: No such network: unknown") - assert.True(t, IsErrNotFound(err)) + assert.Check(t, is.Error(err, "Error: No such network: unknown")) + assert.Check(t, IsErrNotFound(err)) } func TestNetworkInspectWithEmptyID(t *testing.T) { @@ -113,5 +114,5 @@ func TestNetworkInspect(t *testing.T) { } _, err = client.NetworkInspect(context.Background(), "network_id", types.NetworkInspectOptions{Scope: "global"}) - assert.EqualError(t, err, "Error: No such network: network_id") + assert.Check(t, is.Error(err, "Error: No such network: network_id")) } diff --git a/components/engine/client/network_prune_test.go b/components/engine/client/network_prune_test.go index 8bba3751e7e..85908f0cf32 100644 --- a/components/engine/client/network_prune_test.go +++ b/components/engine/client/network_prune_test.go @@ -11,7 +11,8 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -89,7 +90,7 @@ func TestNetworksPrune(t *testing.T) { query := req.URL.Query() for key, expected := range listCase.expectedQueryParams { actual := query.Get(key) - assert.Equal(t, expected, actual) + assert.Check(t, is.Equal(expected, actual)) } content, err := json.Marshal(types.NetworksPruneReport{ NetworksDeleted: []string{"network_id1", "network_id2"}, @@ -106,7 +107,7 @@ func TestNetworksPrune(t *testing.T) { } report, err := client.NetworksPrune(context.Background(), listCase.filters) - assert.NoError(t, err) - assert.Len(t, report.NetworksDeleted, 2) + assert.Check(t, err) + assert.Check(t, is.Len(report.NetworksDeleted, 2)) } } diff --git a/components/engine/client/ping_test.go b/components/engine/client/ping_test.go index 69ff86269d1..f83233aceb3 100644 --- a/components/engine/client/ping_test.go +++ b/components/engine/client/ping_test.go @@ -7,7 +7,8 @@ import ( "strings" "testing" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -31,15 +32,15 @@ func TestPingFail(t *testing.T) { } ping, err := client.Ping(context.Background()) - assert.Error(t, err) - assert.Equal(t, false, ping.Experimental) - assert.Equal(t, "", ping.APIVersion) + assert.Check(t, is.ErrorContains(err, "")) + assert.Check(t, is.Equal(false, ping.Experimental)) + assert.Check(t, is.Equal("", ping.APIVersion)) withHeader = true ping2, err := client.Ping(context.Background()) - assert.Error(t, err) - assert.Equal(t, true, ping2.Experimental) - assert.Equal(t, "awesome", ping2.APIVersion) + assert.Check(t, is.ErrorContains(err, "")) + assert.Check(t, is.Equal(true, ping2.Experimental)) + assert.Check(t, is.Equal("awesome", ping2.APIVersion)) } // TestPingWithError tests the case where there is a protocol error in the ping. @@ -57,9 +58,9 @@ func TestPingWithError(t *testing.T) { } ping, err := client.Ping(context.Background()) - assert.Error(t, err) - assert.Equal(t, false, ping.Experimental) - assert.Equal(t, "", ping.APIVersion) + assert.Check(t, is.ErrorContains(err, "")) + assert.Check(t, is.Equal(false, ping.Experimental)) + assert.Check(t, is.Equal("", ping.APIVersion)) } // TestPingSuccess tests that we are able to get the expected API headers/ping @@ -76,7 +77,7 @@ func TestPingSuccess(t *testing.T) { }), } ping, err := client.Ping(context.Background()) - assert.Error(t, err) - assert.Equal(t, true, ping.Experimental) - assert.Equal(t, "awesome", ping.APIVersion) + assert.Check(t, is.ErrorContains(err, "")) + assert.Check(t, is.Equal(true, ping.Experimental)) + assert.Check(t, is.Equal("awesome", ping.APIVersion)) } diff --git a/components/engine/client/request_test.go b/components/engine/client/request_test.go index 1dbfed62c78..1a0a87e2f46 100644 --- a/components/engine/client/request_test.go +++ b/components/engine/client/request_test.go @@ -9,7 +9,7 @@ import ( "testing" "github.com/docker/docker/api/types" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" "golang.org/x/net/context" ) @@ -46,7 +46,7 @@ func TestSetHostHeader(t *testing.T) { for c, test := range testCases { hostURL, err := ParseHostURL(test.host) - require.NoError(t, err) + assert.NilError(t, err) client := &Client{ client: newMockClient(func(req *http.Request) (*http.Response, error) { @@ -71,7 +71,7 @@ func TestSetHostHeader(t *testing.T) { } _, err = client.sendRequest(context.Background(), "GET", testURL, nil, nil, nil) - require.NoError(t, err) + assert.NilError(t, err) } } diff --git a/components/engine/client/secret_create_test.go b/components/engine/client/secret_create_test.go index 7d54e1aeb09..b31cab509fa 100644 --- a/components/engine/client/secret_create_test.go +++ b/components/engine/client/secret_create_test.go @@ -11,7 +11,8 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/swarm" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -21,7 +22,7 @@ func TestSecretCreateUnsupported(t *testing.T) { client: &http.Client{}, } _, err := client.SecretCreate(context.Background(), swarm.SecretSpec{}) - assert.EqualError(t, err, `"secret create" requires API version 1.25, but the Docker daemon API version is 1.24`) + assert.Check(t, is.Error(err, `"secret create" requires API version 1.25, but the Docker daemon API version is 1.24`)) } func TestSecretCreateError(t *testing.T) { diff --git a/components/engine/client/secret_inspect_test.go b/components/engine/client/secret_inspect_test.go index eb63162c183..0bb3ae24cc8 100644 --- a/components/engine/client/secret_inspect_test.go +++ b/components/engine/client/secret_inspect_test.go @@ -10,8 +10,9 @@ import ( "testing" "github.com/docker/docker/api/types/swarm" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/pkg/errors" - "github.com/stretchr/testify/assert" "golang.org/x/net/context" ) @@ -21,7 +22,7 @@ func TestSecretInspectUnsupported(t *testing.T) { client: &http.Client{}, } _, _, err := client.SecretInspectWithRaw(context.Background(), "nothing") - assert.EqualError(t, err, `"secret inspect" requires API version 1.25, but the Docker daemon API version is 1.24`) + assert.Check(t, is.Error(err, `"secret inspect" requires API version 1.25, but the Docker daemon API version is 1.24`)) } func TestSecretInspectError(t *testing.T) { diff --git a/components/engine/client/secret_list_test.go b/components/engine/client/secret_list_test.go index 2bd427898b0..36d8e8e2f04 100644 --- a/components/engine/client/secret_list_test.go +++ b/components/engine/client/secret_list_test.go @@ -12,7 +12,8 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/swarm" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -22,7 +23,7 @@ func TestSecretListUnsupported(t *testing.T) { client: &http.Client{}, } _, err := client.SecretList(context.Background(), types.SecretListOptions{}) - assert.EqualError(t, err, `"secret list" requires API version 1.25, but the Docker daemon API version is 1.24`) + assert.Check(t, is.Error(err, `"secret list" requires API version 1.25, but the Docker daemon API version is 1.24`)) } func TestSecretListError(t *testing.T) { diff --git a/components/engine/client/secret_remove_test.go b/components/engine/client/secret_remove_test.go index 44cc0cbcc40..37c22650d14 100644 --- a/components/engine/client/secret_remove_test.go +++ b/components/engine/client/secret_remove_test.go @@ -8,7 +8,8 @@ import ( "strings" "testing" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -18,7 +19,7 @@ func TestSecretRemoveUnsupported(t *testing.T) { client: &http.Client{}, } err := client.SecretRemove(context.Background(), "secret_id") - assert.EqualError(t, err, `"secret remove" requires API version 1.25, but the Docker daemon API version is 1.24`) + assert.Check(t, is.Error(err, `"secret remove" requires API version 1.25, but the Docker daemon API version is 1.24`)) } func TestSecretRemoveError(t *testing.T) { diff --git a/components/engine/client/secret_update_test.go b/components/engine/client/secret_update_test.go index d2fca4b2d53..3ff172ba534 100644 --- a/components/engine/client/secret_update_test.go +++ b/components/engine/client/secret_update_test.go @@ -9,7 +9,8 @@ import ( "testing" "github.com/docker/docker/api/types/swarm" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -19,7 +20,7 @@ func TestSecretUpdateUnsupported(t *testing.T) { client: &http.Client{}, } err := client.SecretUpdate(context.Background(), "secret_id", swarm.Version{}, swarm.SecretSpec{}) - assert.EqualError(t, err, `"secret update" requires API version 1.25, but the Docker daemon API version is 1.24`) + assert.Check(t, is.Error(err, `"secret update" requires API version 1.25, but the Docker daemon API version is 1.24`)) } func TestSecretUpdateError(t *testing.T) { diff --git a/components/engine/client/service_create_test.go b/components/engine/client/service_create_test.go index 9e859b18ac2..c5d8ae4ff9f 100644 --- a/components/engine/client/service_create_test.go +++ b/components/engine/client/service_create_test.go @@ -12,9 +12,10 @@ import ( "github.com/docker/docker/api/types" registrytypes "github.com/docker/docker/api/types/registry" "github.com/docker/docker/api/types/swarm" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/opencontainers/go-digest" "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/stretchr/testify/assert" "golang.org/x/net/context" ) @@ -73,8 +74,8 @@ func TestServiceCreateCompatiblePlatforms(t *testing.T) { return nil, err } - assert.Equal(t, "foobar:1.0@sha256:c0537ff6a5218ef531ece93d4984efc99bbf3f7497c0a7726c88e2bb7584dc96", serviceSpec.TaskTemplate.ContainerSpec.Image) - assert.Len(t, serviceSpec.TaskTemplate.Placement.Platforms, 1) + assert.Check(t, is.Equal("foobar:1.0@sha256:c0537ff6a5218ef531ece93d4984efc99bbf3f7497c0a7726c88e2bb7584dc96", serviceSpec.TaskTemplate.ContainerSpec.Image)) + assert.Check(t, is.Len(serviceSpec.TaskTemplate.Placement.Platforms, 1)) p := serviceSpec.TaskTemplate.Placement.Platforms[0] b, err := json.Marshal(types.ServiceCreateResponse{ @@ -115,8 +116,8 @@ func TestServiceCreateCompatiblePlatforms(t *testing.T) { spec := swarm.ServiceSpec{TaskTemplate: swarm.TaskSpec{ContainerSpec: &swarm.ContainerSpec{Image: "foobar:1.0"}}} r, err := client.ServiceCreate(context.Background(), spec, types.ServiceCreateOptions{QueryRegistry: true}) - assert.NoError(t, err) - assert.Equal(t, "service_linux_amd64", r.ID) + assert.Check(t, err) + assert.Check(t, is.Equal("service_linux_amd64", r.ID)) } func TestServiceCreateDigestPinning(t *testing.T) { diff --git a/components/engine/client/service_remove_test.go b/components/engine/client/service_remove_test.go index 0909c9e0649..9198763f8e9 100644 --- a/components/engine/client/service_remove_test.go +++ b/components/engine/client/service_remove_test.go @@ -8,7 +8,8 @@ import ( "strings" "testing" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -18,7 +19,7 @@ func TestServiceRemoveError(t *testing.T) { } err := client.ServiceRemove(context.Background(), "service_id") - assert.EqualError(t, err, "Error response from daemon: Server error") + assert.Check(t, is.Error(err, "Error response from daemon: Server error")) } func TestServiceRemoveNotFoundError(t *testing.T) { @@ -27,8 +28,8 @@ func TestServiceRemoveNotFoundError(t *testing.T) { } err := client.ServiceRemove(context.Background(), "service_id") - assert.EqualError(t, err, "Error: No such service: service_id") - assert.True(t, IsErrNotFound(err)) + assert.Check(t, is.Error(err, "Error: No such service: service_id")) + assert.Check(t, IsErrNotFound(err)) } func TestServiceRemove(t *testing.T) { diff --git a/components/engine/client/swarm_get_unlock_key_test.go b/components/engine/client/swarm_get_unlock_key_test.go index c4ac70738af..aff79440fec 100644 --- a/components/engine/client/swarm_get_unlock_key_test.go +++ b/components/engine/client/swarm_get_unlock_key_test.go @@ -11,8 +11,8 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/internal/testutil" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -55,6 +55,6 @@ func TestSwarmGetUnlockKey(t *testing.T) { } resp, err := client.SwarmGetUnlockKey(context.Background()) - require.NoError(t, err) - assert.Equal(t, unlockKey, resp.UnlockKey) + assert.NilError(t, err) + assert.Check(t, is.Equal(unlockKey, resp.UnlockKey)) } diff --git a/components/engine/client/volume_inspect_test.go b/components/engine/client/volume_inspect_test.go index c97f5c7215e..4a2cf7c7d7b 100644 --- a/components/engine/client/volume_inspect_test.go +++ b/components/engine/client/volume_inspect_test.go @@ -11,9 +11,9 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/internal/testutil" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/pkg/errors" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "golang.org/x/net/context" ) @@ -32,7 +32,7 @@ func TestVolumeInspectNotFound(t *testing.T) { } _, err := client.VolumeInspect(context.Background(), "unknown") - assert.True(t, IsErrNotFound(err)) + assert.Check(t, IsErrNotFound(err)) } func TestVolumeInspectWithEmptyID(t *testing.T) { @@ -75,6 +75,6 @@ func TestVolumeInspect(t *testing.T) { } volume, err := client.VolumeInspect(context.Background(), "volume_id") - require.NoError(t, err) - assert.Equal(t, expected, volume) + assert.NilError(t, err) + assert.Check(t, is.DeepEqual(expected, volume)) } diff --git a/components/engine/cmd/dockerd/config_unix_test.go b/components/engine/cmd/dockerd/config_unix_test.go index 2705d671bab..eaa53d8f6fe 100644 --- a/components/engine/cmd/dockerd/config_unix_test.go +++ b/components/engine/cmd/dockerd/config_unix_test.go @@ -6,8 +6,9 @@ import ( "testing" "github.com/docker/docker/daemon/config" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/spf13/pflag" - "github.com/stretchr/testify/assert" ) func TestDaemonParseShmSize(t *testing.T) { @@ -16,7 +17,7 @@ func TestDaemonParseShmSize(t *testing.T) { conf := &config.Config{} installConfigFlags(conf, flags) // By default `--default-shm-size=64M` - assert.Equal(t, int64(64*1024*1024), conf.ShmSize.Value()) - assert.NoError(t, flags.Set("default-shm-size", "128M")) - assert.Equal(t, int64(128*1024*1024), conf.ShmSize.Value()) + assert.Check(t, is.Equal(int64(64*1024*1024), conf.ShmSize.Value())) + assert.Check(t, flags.Set("default-shm-size", "128M")) + assert.Check(t, is.Equal(int64(128*1024*1024), conf.ShmSize.Value())) } diff --git a/components/engine/cmd/dockerd/daemon_test.go b/components/engine/cmd/dockerd/daemon_test.go index b065831871a..e5c2c2ec7cb 100644 --- a/components/engine/cmd/dockerd/daemon_test.go +++ b/components/engine/cmd/dockerd/daemon_test.go @@ -5,11 +5,11 @@ import ( "github.com/docker/docker/daemon/config" "github.com/docker/docker/internal/testutil" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/fs" "github.com/sirupsen/logrus" "github.com/spf13/pflag" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func defaultOptions(configFile string) *daemonOptions { @@ -27,8 +27,8 @@ func TestLoadDaemonCliConfigWithoutOverriding(t *testing.T) { opts.Debug = true loadedConfig, err := loadDaemonCliConfig(opts) - require.NoError(t, err) - require.NotNil(t, loadedConfig) + assert.NilError(t, err) + assert.Assert(t, loadedConfig != nil) if !loadedConfig.Debug { t.Fatalf("expected debug to be copied from the common flags, got false") } @@ -40,9 +40,9 @@ func TestLoadDaemonCliConfigWithTLS(t *testing.T) { opts.TLS = true loadedConfig, err := loadDaemonCliConfig(opts) - require.NoError(t, err) - require.NotNil(t, loadedConfig) - assert.Equal(t, "/tmp/ca.pem", loadedConfig.CommonTLSOptions.CAFile) + assert.NilError(t, err) + assert.Assert(t, loadedConfig != nil) + assert.Check(t, is.Equal("/tmp/ca.pem", loadedConfig.CommonTLSOptions.CAFile)) } func TestLoadDaemonCliConfigWithConflicts(t *testing.T) { @@ -53,9 +53,9 @@ func TestLoadDaemonCliConfigWithConflicts(t *testing.T) { opts := defaultOptions(configFile) flags := opts.flags - assert.NoError(t, flags.Set("config-file", configFile)) - assert.NoError(t, flags.Set("label", "l1=bar")) - assert.NoError(t, flags.Set("label", "l2=baz")) + assert.Check(t, flags.Set("config-file", configFile)) + assert.Check(t, flags.Set("label", "l1=bar")) + assert.Check(t, flags.Set("label", "l2=baz")) _, err := loadDaemonCliConfig(opts) testutil.ErrorContains(t, err, "as a flag and in the configuration file: labels") @@ -69,9 +69,9 @@ func TestLoadDaemonCliWithConflictingNodeGenericResources(t *testing.T) { opts := defaultOptions(configFile) flags := opts.flags - assert.NoError(t, flags.Set("config-file", configFile)) - assert.NoError(t, flags.Set("node-generic-resource", "r1=bar")) - assert.NoError(t, flags.Set("node-generic-resource", "r2=baz")) + assert.Check(t, flags.Set("config-file", configFile)) + assert.Check(t, flags.Set("node-generic-resource", "r1=bar")) + assert.Check(t, flags.Set("node-generic-resource", "r2=baz")) _, err := loadDaemonCliConfig(opts) testutil.ErrorContains(t, err, "as a flag and in the configuration file: node-generic-resources") @@ -81,22 +81,22 @@ func TestLoadDaemonCliWithConflictingLabels(t *testing.T) { opts := defaultOptions("") flags := opts.flags - assert.NoError(t, flags.Set("label", "foo=bar")) - assert.NoError(t, flags.Set("label", "foo=baz")) + assert.Check(t, flags.Set("label", "foo=bar")) + assert.Check(t, flags.Set("label", "foo=baz")) _, err := loadDaemonCliConfig(opts) - assert.EqualError(t, err, "conflict labels for foo=baz and foo=bar") + assert.Check(t, is.Error(err, "conflict labels for foo=baz and foo=bar")) } func TestLoadDaemonCliWithDuplicateLabels(t *testing.T) { opts := defaultOptions("") flags := opts.flags - assert.NoError(t, flags.Set("label", "foo=the-same")) - assert.NoError(t, flags.Set("label", "foo=the-same")) + assert.Check(t, flags.Set("label", "foo=the-same")) + assert.Check(t, flags.Set("label", "foo=the-same")) _, err := loadDaemonCliConfig(opts) - assert.NoError(t, err) + assert.Check(t, err) } func TestLoadDaemonCliConfigWithTLSVerify(t *testing.T) { @@ -107,9 +107,9 @@ func TestLoadDaemonCliConfigWithTLSVerify(t *testing.T) { opts.TLSOptions.CAFile = "/tmp/ca.pem" loadedConfig, err := loadDaemonCliConfig(opts) - require.NoError(t, err) - require.NotNil(t, loadedConfig) - assert.Equal(t, loadedConfig.TLS, true) + assert.NilError(t, err) + assert.Assert(t, loadedConfig != nil) + assert.Check(t, is.Equal(loadedConfig.TLS, true)) } func TestLoadDaemonCliConfigWithExplicitTLSVerifyFalse(t *testing.T) { @@ -120,9 +120,9 @@ func TestLoadDaemonCliConfigWithExplicitTLSVerifyFalse(t *testing.T) { opts.TLSOptions.CAFile = "/tmp/ca.pem" loadedConfig, err := loadDaemonCliConfig(opts) - require.NoError(t, err) - require.NotNil(t, loadedConfig) - assert.True(t, loadedConfig.TLS) + assert.NilError(t, err) + assert.Assert(t, loadedConfig != nil) + assert.Check(t, loadedConfig.TLS) } func TestLoadDaemonCliConfigWithoutTLSVerify(t *testing.T) { @@ -133,9 +133,9 @@ func TestLoadDaemonCliConfigWithoutTLSVerify(t *testing.T) { opts.TLSOptions.CAFile = "/tmp/ca.pem" loadedConfig, err := loadDaemonCliConfig(opts) - require.NoError(t, err) - require.NotNil(t, loadedConfig) - assert.False(t, loadedConfig.TLS) + assert.NilError(t, err) + assert.Assert(t, loadedConfig != nil) + assert.Check(t, !loadedConfig.TLS) } func TestLoadDaemonCliConfigWithLogLevel(t *testing.T) { @@ -144,10 +144,10 @@ func TestLoadDaemonCliConfigWithLogLevel(t *testing.T) { opts := defaultOptions(tempFile.Path()) loadedConfig, err := loadDaemonCliConfig(opts) - require.NoError(t, err) - require.NotNil(t, loadedConfig) - assert.Equal(t, "warn", loadedConfig.LogLevel) - assert.Equal(t, logrus.WarnLevel, logrus.GetLevel()) + assert.NilError(t, err) + assert.Assert(t, loadedConfig != nil) + assert.Check(t, is.Equal("warn", loadedConfig.LogLevel)) + assert.Check(t, is.Equal(logrus.WarnLevel, logrus.GetLevel())) } func TestLoadDaemonConfigWithEmbeddedOptions(t *testing.T) { @@ -157,10 +157,10 @@ func TestLoadDaemonConfigWithEmbeddedOptions(t *testing.T) { opts := defaultOptions(tempFile.Path()) loadedConfig, err := loadDaemonCliConfig(opts) - require.NoError(t, err) - require.NotNil(t, loadedConfig) - assert.Equal(t, "/etc/certs/ca.pem", loadedConfig.CommonTLSOptions.CAFile) - assert.Equal(t, "syslog", loadedConfig.LogConfig.Type) + assert.NilError(t, err) + assert.Assert(t, loadedConfig != nil) + assert.Check(t, is.Equal("/etc/certs/ca.pem", loadedConfig.CommonTLSOptions.CAFile)) + assert.Check(t, is.Equal("syslog", loadedConfig.LogConfig.Type)) } func TestLoadDaemonConfigWithRegistryOptions(t *testing.T) { @@ -174,10 +174,10 @@ func TestLoadDaemonConfigWithRegistryOptions(t *testing.T) { opts := defaultOptions(tempFile.Path()) loadedConfig, err := loadDaemonCliConfig(opts) - require.NoError(t, err) - require.NotNil(t, loadedConfig) + assert.NilError(t, err) + assert.Assert(t, loadedConfig != nil) - assert.Len(t, loadedConfig.AllowNondistributableArtifacts, 1) - assert.Len(t, loadedConfig.Mirrors, 1) - assert.Len(t, loadedConfig.InsecureRegistries, 1) + assert.Check(t, is.Len(loadedConfig.AllowNondistributableArtifacts, 1)) + assert.Check(t, is.Len(loadedConfig.Mirrors, 1)) + assert.Check(t, is.Len(loadedConfig.InsecureRegistries, 1)) } diff --git a/components/engine/cmd/dockerd/daemon_unix_test.go b/components/engine/cmd/dockerd/daemon_unix_test.go index 41c392e1b15..39ff1e68226 100644 --- a/components/engine/cmd/dockerd/daemon_unix_test.go +++ b/components/engine/cmd/dockerd/daemon_unix_test.go @@ -6,9 +6,9 @@ import ( "testing" "github.com/docker/docker/daemon/config" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/fs" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestLoadDaemonCliConfigWithDaemonFlags(t *testing.T) { @@ -19,17 +19,17 @@ func TestLoadDaemonCliConfigWithDaemonFlags(t *testing.T) { opts := defaultOptions(tempFile.Path()) opts.Debug = true opts.LogLevel = "info" - assert.NoError(t, opts.flags.Set("selinux-enabled", "true")) + assert.Check(t, opts.flags.Set("selinux-enabled", "true")) loadedConfig, err := loadDaemonCliConfig(opts) - require.NoError(t, err) - require.NotNil(t, loadedConfig) - - assert.True(t, loadedConfig.Debug) - assert.Equal(t, "info", loadedConfig.LogLevel) - assert.True(t, loadedConfig.EnableSelinuxSupport) - assert.Equal(t, "json-file", loadedConfig.LogConfig.Type) - assert.Equal(t, "1k", loadedConfig.LogConfig.Config["max-size"]) + assert.NilError(t, err) + assert.Assert(t, loadedConfig != nil) + + assert.Check(t, loadedConfig.Debug) + assert.Check(t, is.Equal("info", loadedConfig.LogLevel)) + assert.Check(t, loadedConfig.EnableSelinuxSupport) + assert.Check(t, is.Equal("json-file", loadedConfig.LogConfig.Type)) + assert.Check(t, is.Equal("1k", loadedConfig.LogConfig.Config["max-size"])) } func TestLoadDaemonConfigWithNetwork(t *testing.T) { @@ -39,11 +39,11 @@ func TestLoadDaemonConfigWithNetwork(t *testing.T) { opts := defaultOptions(tempFile.Path()) loadedConfig, err := loadDaemonCliConfig(opts) - require.NoError(t, err) - require.NotNil(t, loadedConfig) + assert.NilError(t, err) + assert.Assert(t, loadedConfig != nil) - assert.Equal(t, "127.0.0.2", loadedConfig.IP) - assert.Equal(t, "127.0.0.1", loadedConfig.DefaultIP.String()) + assert.Check(t, is.Equal("127.0.0.2", loadedConfig.IP)) + assert.Check(t, is.Equal("127.0.0.1", loadedConfig.DefaultIP.String())) } func TestLoadDaemonConfigWithMapOptions(t *testing.T) { @@ -56,14 +56,14 @@ func TestLoadDaemonConfigWithMapOptions(t *testing.T) { opts := defaultOptions(tempFile.Path()) loadedConfig, err := loadDaemonCliConfig(opts) - require.NoError(t, err) - require.NotNil(t, loadedConfig) - assert.NotNil(t, loadedConfig.ClusterOpts) + assert.NilError(t, err) + assert.Assert(t, loadedConfig != nil) + assert.Check(t, loadedConfig.ClusterOpts != nil) expectedPath := "/var/lib/docker/discovery_certs/ca.pem" - assert.Equal(t, expectedPath, loadedConfig.ClusterOpts["kv.cacertfile"]) - assert.NotNil(t, loadedConfig.LogConfig.Config) - assert.Equal(t, "test", loadedConfig.LogConfig.Config["tag"]) + assert.Check(t, is.Equal(expectedPath, loadedConfig.ClusterOpts["kv.cacertfile"])) + assert.Check(t, loadedConfig.LogConfig.Config != nil) + assert.Check(t, is.Equal("test", loadedConfig.LogConfig.Config["tag"])) } func TestLoadDaemonConfigWithTrueDefaultValues(t *testing.T) { @@ -73,17 +73,17 @@ func TestLoadDaemonConfigWithTrueDefaultValues(t *testing.T) { opts := defaultOptions(tempFile.Path()) loadedConfig, err := loadDaemonCliConfig(opts) - require.NoError(t, err) - require.NotNil(t, loadedConfig) + assert.NilError(t, err) + assert.Assert(t, loadedConfig != nil) - assert.False(t, loadedConfig.EnableUserlandProxy) + assert.Check(t, !loadedConfig.EnableUserlandProxy) // make sure reloading doesn't generate configuration // conflicts after normalizing boolean values. reload := func(reloadedConfig *config.Config) { - assert.False(t, reloadedConfig.EnableUserlandProxy) + assert.Check(t, !reloadedConfig.EnableUserlandProxy) } - assert.NoError(t, config.Reload(opts.configFile, opts.flags, reload)) + assert.Check(t, config.Reload(opts.configFile, opts.flags, reload)) } func TestLoadDaemonConfigWithTrueDefaultValuesLeaveDefaults(t *testing.T) { @@ -92,8 +92,8 @@ func TestLoadDaemonConfigWithTrueDefaultValuesLeaveDefaults(t *testing.T) { opts := defaultOptions(tempFile.Path()) loadedConfig, err := loadDaemonCliConfig(opts) - require.NoError(t, err) - require.NotNil(t, loadedConfig) + assert.NilError(t, err) + assert.Assert(t, loadedConfig != nil) - assert.True(t, loadedConfig.EnableUserlandProxy) + assert.Check(t, loadedConfig.EnableUserlandProxy) } diff --git a/components/engine/cmd/dockerd/options_test.go b/components/engine/cmd/dockerd/options_test.go index c3298a0ac69..2a4e63b6b62 100644 --- a/components/engine/cmd/dockerd/options_test.go +++ b/components/engine/cmd/dockerd/options_test.go @@ -6,8 +6,9 @@ import ( cliconfig "github.com/docker/docker/cli/config" "github.com/docker/docker/daemon/config" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/spf13/pflag" - "github.com/stretchr/testify/assert" ) func TestCommonOptionsInstallFlags(t *testing.T) { @@ -20,10 +21,10 @@ func TestCommonOptionsInstallFlags(t *testing.T) { "--tlscert=\"/foo/cert\"", "--tlskey=\"/foo/key\"", }) - assert.NoError(t, err) - assert.Equal(t, "/foo/cafile", opts.TLSOptions.CAFile) - assert.Equal(t, "/foo/cert", opts.TLSOptions.CertFile) - assert.Equal(t, opts.TLSOptions.KeyFile, "/foo/key") + assert.Check(t, err) + assert.Check(t, is.Equal("/foo/cafile", opts.TLSOptions.CAFile)) + assert.Check(t, is.Equal("/foo/cert", opts.TLSOptions.CertFile)) + assert.Check(t, is.Equal(opts.TLSOptions.KeyFile, "/foo/key")) } func defaultPath(filename string) string { @@ -36,8 +37,8 @@ func TestCommonOptionsInstallFlagsWithDefaults(t *testing.T) { opts.InstallFlags(flags) err := flags.Parse([]string{}) - assert.NoError(t, err) - assert.Equal(t, defaultPath("ca.pem"), opts.TLSOptions.CAFile) - assert.Equal(t, defaultPath("cert.pem"), opts.TLSOptions.CertFile) - assert.Equal(t, defaultPath("key.pem"), opts.TLSOptions.KeyFile) + assert.Check(t, err) + assert.Check(t, is.Equal(defaultPath("ca.pem"), opts.TLSOptions.CAFile)) + assert.Check(t, is.Equal(defaultPath("cert.pem"), opts.TLSOptions.CertFile)) + assert.Check(t, is.Equal(defaultPath("key.pem"), opts.TLSOptions.KeyFile)) } diff --git a/components/engine/container/container_unit_test.go b/components/engine/container/container_unit_test.go index 863a47a1f22..bf45df942e7 100644 --- a/components/engine/container/container_unit_test.go +++ b/components/engine/container/container_unit_test.go @@ -11,7 +11,7 @@ import ( swarmtypes "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/daemon/logger/jsonfilelog" "github.com/docker/docker/pkg/signal" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) func TestContainerStopSignal(t *testing.T) { @@ -74,7 +74,7 @@ func TestContainerSecretReferenceDestTarget(t *testing.T) { func TestContainerLogPathSetForJSONFileLogger(t *testing.T) { containerRoot, err := ioutil.TempDir("", "TestContainerLogPathSetForJSONFileLogger") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(containerRoot) c := &Container{ @@ -89,17 +89,17 @@ func TestContainerLogPathSetForJSONFileLogger(t *testing.T) { } logger, err := c.StartLogger() - require.NoError(t, err) + assert.NilError(t, err) defer logger.Close() expectedLogPath, err := filepath.Abs(filepath.Join(containerRoot, fmt.Sprintf("%s-json.log", c.ID))) - require.NoError(t, err) - require.Equal(t, c.LogPath, expectedLogPath) + assert.NilError(t, err) + assert.Equal(t, c.LogPath, expectedLogPath) } func TestContainerLogPathSetForRingLogger(t *testing.T) { containerRoot, err := ioutil.TempDir("", "TestContainerLogPathSetForRingLogger") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(containerRoot) c := &Container{ @@ -117,10 +117,10 @@ func TestContainerLogPathSetForRingLogger(t *testing.T) { } logger, err := c.StartLogger() - require.NoError(t, err) + assert.NilError(t, err) defer logger.Close() expectedLogPath, err := filepath.Abs(filepath.Join(containerRoot, fmt.Sprintf("%s-json.log", c.ID))) - require.NoError(t, err) - require.Equal(t, c.LogPath, expectedLogPath) + assert.NilError(t, err) + assert.Equal(t, c.LogPath, expectedLogPath) } diff --git a/components/engine/container/view_test.go b/components/engine/container/view_test.go index 26803b04e63..a872dffea61 100644 --- a/components/engine/container/view_test.go +++ b/components/engine/container/view_test.go @@ -8,8 +8,9 @@ import ( "github.com/docker/docker/api/types" containertypes "github.com/docker/docker/api/types/container" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/pborman/uuid" - "github.com/stretchr/testify/assert" ) var root string @@ -109,56 +110,56 @@ func TestNames(t *testing.T) { if err != nil { t.Fatal(err) } - assert.NoError(t, db.ReserveName("name1", "containerid1")) - assert.NoError(t, db.ReserveName("name1", "containerid1")) // idempotent - assert.NoError(t, db.ReserveName("name2", "containerid2")) - assert.EqualError(t, db.ReserveName("name2", "containerid3"), ErrNameReserved.Error()) + assert.Check(t, db.ReserveName("name1", "containerid1")) + assert.Check(t, db.ReserveName("name1", "containerid1")) // idempotent + assert.Check(t, db.ReserveName("name2", "containerid2")) + assert.Check(t, is.Error(db.ReserveName("name2", "containerid3"), ErrNameReserved.Error())) // Releasing a name allows the name to point to something else later. - assert.NoError(t, db.ReleaseName("name2")) - assert.NoError(t, db.ReserveName("name2", "containerid3")) + assert.Check(t, db.ReleaseName("name2")) + assert.Check(t, db.ReserveName("name2", "containerid3")) view := db.Snapshot() id, err := view.GetID("name1") - assert.NoError(t, err) - assert.Equal(t, "containerid1", id) + assert.Check(t, err) + assert.Check(t, is.Equal("containerid1", id)) id, err = view.GetID("name2") - assert.NoError(t, err) - assert.Equal(t, "containerid3", id) + assert.Check(t, err) + assert.Check(t, is.Equal("containerid3", id)) _, err = view.GetID("notreserved") - assert.EqualError(t, err, ErrNameNotReserved.Error()) + assert.Check(t, is.Error(err, ErrNameNotReserved.Error())) // Releasing and re-reserving a name doesn't affect the snapshot. - assert.NoError(t, db.ReleaseName("name2")) - assert.NoError(t, db.ReserveName("name2", "containerid4")) + assert.Check(t, db.ReleaseName("name2")) + assert.Check(t, db.ReserveName("name2", "containerid4")) id, err = view.GetID("name1") - assert.NoError(t, err) - assert.Equal(t, "containerid1", id) + assert.Check(t, err) + assert.Check(t, is.Equal("containerid1", id)) id, err = view.GetID("name2") - assert.NoError(t, err) - assert.Equal(t, "containerid3", id) + assert.Check(t, err) + assert.Check(t, is.Equal("containerid3", id)) // GetAllNames - assert.Equal(t, map[string][]string{"containerid1": {"name1"}, "containerid3": {"name2"}}, view.GetAllNames()) + assert.Check(t, is.DeepEqual(map[string][]string{"containerid1": {"name1"}, "containerid3": {"name2"}}, view.GetAllNames())) - assert.NoError(t, db.ReserveName("name3", "containerid1")) - assert.NoError(t, db.ReserveName("name4", "containerid1")) + assert.Check(t, db.ReserveName("name3", "containerid1")) + assert.Check(t, db.ReserveName("name4", "containerid1")) view = db.Snapshot() - assert.Equal(t, map[string][]string{"containerid1": {"name1", "name3", "name4"}, "containerid4": {"name2"}}, view.GetAllNames()) + assert.Check(t, is.DeepEqual(map[string][]string{"containerid1": {"name1", "name3", "name4"}, "containerid4": {"name2"}}, view.GetAllNames())) // Release containerid1's names with Delete even though no container exists - assert.NoError(t, db.Delete(&Container{ID: "containerid1"})) + assert.Check(t, db.Delete(&Container{ID: "containerid1"})) // Reusing one of those names should work - assert.NoError(t, db.ReserveName("name1", "containerid4")) + assert.Check(t, db.ReserveName("name1", "containerid4")) view = db.Snapshot() - assert.Equal(t, map[string][]string{"containerid4": {"name1", "name2"}}, view.GetAllNames()) + assert.Check(t, is.DeepEqual(map[string][]string{"containerid4": {"name1", "name2"}}, view.GetAllNames())) } // Test case for GitHub issue 35920 diff --git a/components/engine/daemon/cluster/convert/service_test.go b/components/engine/daemon/cluster/convert/service_test.go index 347aa028bec..0794af99a66 100644 --- a/components/engine/daemon/cluster/convert/service_test.go +++ b/components/engine/daemon/cluster/convert/service_test.go @@ -8,7 +8,7 @@ import ( "github.com/docker/docker/api/types/swarm/runtime" swarmapi "github.com/docker/swarmkit/api" google_protobuf3 "github.com/gogo/protobuf/types" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) func TestServiceConvertFromGRPCRuntimeContainer(t *testing.T) { @@ -178,12 +178,12 @@ func TestServiceConvertToGRPCIsolation(t *testing.T) { }, } res, err := ServiceSpecToGRPC(s) - require.NoError(t, err) + assert.NilError(t, err) v, ok := res.Task.Runtime.(*swarmapi.TaskSpec_Container) if !ok { t.Fatal("expected type swarmapi.TaskSpec_Container") } - require.Equal(t, c.to, v.Container.Isolation) + assert.Equal(t, c.to, v.Container.Isolation) }) } } @@ -228,7 +228,7 @@ func TestServiceConvertFromGRPCIsolation(t *testing.T) { t.Fatal(err) } - require.Equal(t, c.to, svc.Spec.TaskTemplate.ContainerSpec.Isolation) + assert.Equal(t, c.to, svc.Spec.TaskTemplate.ContainerSpec.Isolation) }) } } diff --git a/components/engine/daemon/cluster/executor/container/container_test.go b/components/engine/daemon/cluster/executor/container/container_test.go index 456cd403b1b..1e941719741 100644 --- a/components/engine/daemon/cluster/executor/container/container_test.go +++ b/components/engine/daemon/cluster/executor/container/container_test.go @@ -5,7 +5,7 @@ import ( container "github.com/docker/docker/api/types/container" swarmapi "github.com/docker/swarmkit/api" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) func TestIsolationConversion(t *testing.T) { @@ -31,7 +31,7 @@ func TestIsolationConversion(t *testing.T) { }, } config := containerConfig{task: &task} - require.Equal(t, c.to, config.hostConfig().Isolation) + assert.Equal(t, c.to, config.hostConfig().Isolation) }) } } diff --git a/components/engine/daemon/config/config_test.go b/components/engine/daemon/config/config_test.go index 53db2922cb1..2fe2b3805cc 100644 --- a/components/engine/daemon/config/config_test.go +++ b/components/engine/daemon/config/config_test.go @@ -9,9 +9,10 @@ import ( "github.com/docker/docker/daemon/discovery" "github.com/docker/docker/internal/testutil" "github.com/docker/docker/opts" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/fs" "github.com/spf13/pflag" - "github.com/stretchr/testify/assert" ) func TestDaemonConfigurationNotFound(t *testing.T) { @@ -59,7 +60,7 @@ func TestFindConfigurationConflicts(t *testing.T) { flags := pflag.NewFlagSet("test", pflag.ContinueOnError) flags.String("authorization-plugins", "", "") - assert.NoError(t, flags.Set("authorization-plugins", "asdf")) + assert.Check(t, flags.Set("authorization-plugins", "asdf")) testutil.ErrorContains(t, findConfigurationConflicts(config, flags), @@ -72,8 +73,8 @@ func TestFindConfigurationConflictsWithNamedOptions(t *testing.T) { var hosts []string flags.VarP(opts.NewNamedListOptsRef("hosts", &hosts, opts.ValidateHost), "host", "H", "Daemon socket(s) to connect to") - assert.NoError(t, flags.Set("host", "tcp://127.0.0.1:4444")) - assert.NoError(t, flags.Set("host", "unix:///var/run/docker.sock")) + assert.Check(t, flags.Set("host", "tcp://127.0.0.1:4444")) + assert.Check(t, flags.Set("host", "unix:///var/run/docker.sock")) testutil.ErrorContains(t, findConfigurationConflicts(config, flags), "hosts") } @@ -424,7 +425,7 @@ func TestReloadSetConfigFileNotExist(t *testing.T) { flags.Set("config-file", configFile) err := Reload(configFile, flags, func(c *Config) {}) - assert.Error(t, err) + assert.Check(t, is.ErrorContains(err, "")) testutil.ErrorContains(t, err, "unable to configure the Docker daemon with file") } @@ -438,8 +439,8 @@ func TestReloadDefaultConfigNotExist(t *testing.T) { err := Reload(configFile, flags, func(c *Config) { reloaded = true }) - assert.Nil(t, err) - assert.True(t, reloaded) + assert.Check(t, err) + assert.Check(t, reloaded) } // TestReloadBadDefaultConfig tests that when `--config-file` is not set @@ -457,7 +458,7 @@ func TestReloadBadDefaultConfig(t *testing.T) { flags := pflag.NewFlagSet("test", pflag.ContinueOnError) flags.String("config-file", configFile, "") err = Reload(configFile, flags, func(c *Config) {}) - assert.Error(t, err) + assert.Check(t, is.ErrorContains(err, "")) testutil.ErrorContains(t, err, "unable to configure the Docker daemon with file") } @@ -484,5 +485,5 @@ func TestReloadWithDuplicateLabels(t *testing.T) { flags.String("config-file", configFile, "") flags.StringSlice("labels", lbls, "") err := Reload(configFile, flags, func(c *Config) {}) - assert.NoError(t, err) + assert.Check(t, err) } diff --git a/components/engine/daemon/config/config_unix_test.go b/components/engine/daemon/config/config_unix_test.go index b4efa95e0e3..53eb4282646 100644 --- a/components/engine/daemon/config/config_unix_test.go +++ b/components/engine/daemon/config/config_unix_test.go @@ -7,10 +7,10 @@ import ( "github.com/docker/docker/opts" units "github.com/docker/go-units" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/fs" "github.com/spf13/pflag" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestGetConflictFreeConfiguration(t *testing.T) { @@ -39,9 +39,9 @@ func TestGetConflictFreeConfiguration(t *testing.T) { flags.Var(opts.NewNamedMapOpts("log-opts", nil, nil), "log-opt", "") cc, err := getConflictFreeConfiguration(file.Path(), flags) - require.NoError(t, err) + assert.NilError(t, err) - assert.True(t, cc.Debug) + assert.Check(t, cc.Debug) expectedUlimits := map[string]*units.Ulimit{ "nofile": { @@ -51,7 +51,7 @@ func TestGetConflictFreeConfiguration(t *testing.T) { }, } - assert.Equal(t, expectedUlimits, cc.Ulimits) + assert.Check(t, is.DeepEqual(expectedUlimits, cc.Ulimits)) } func TestDaemonConfigurationMerge(t *testing.T) { @@ -91,17 +91,17 @@ func TestDaemonConfigurationMerge(t *testing.T) { flags.Var(opts.NewNamedMapOpts("log-opts", nil, nil), "log-opt", "") cc, err := MergeDaemonConfigurations(c, flags, file.Path()) - require.NoError(t, err) + assert.NilError(t, err) - assert.True(t, cc.Debug) - assert.True(t, cc.AutoRestart) + assert.Check(t, cc.Debug) + assert.Check(t, cc.AutoRestart) expectedLogConfig := LogConfig{ Type: "syslog", Config: map[string]string{"tag": "test_tag"}, } - assert.Equal(t, expectedLogConfig, cc.LogConfig) + assert.Check(t, is.DeepEqual(expectedLogConfig, cc.LogConfig)) expectedUlimits := map[string]*units.Ulimit{ "nofile": { @@ -111,7 +111,7 @@ func TestDaemonConfigurationMerge(t *testing.T) { }, } - assert.Equal(t, expectedUlimits, cc.Ulimits) + assert.Check(t, is.DeepEqual(expectedUlimits, cc.Ulimits)) } func TestDaemonConfigurationMergeShmSize(t *testing.T) { @@ -127,8 +127,8 @@ func TestDaemonConfigurationMergeShmSize(t *testing.T) { flags.Var(&shmSize, "default-shm-size", "") cc, err := MergeDaemonConfigurations(c, flags, file.Path()) - require.NoError(t, err) + assert.NilError(t, err) expectedValue := 1 * 1024 * 1024 * 1024 - assert.Equal(t, int64(expectedValue), cc.ShmSize.Value()) + assert.Check(t, is.Equal(int64(expectedValue), cc.ShmSize.Value())) } diff --git a/components/engine/daemon/config/config_windows_test.go b/components/engine/daemon/config/config_windows_test.go index 5382bb3b770..fff98014f98 100644 --- a/components/engine/daemon/config/config_windows_test.go +++ b/components/engine/daemon/config/config_windows_test.go @@ -7,9 +7,9 @@ import ( "testing" "github.com/docker/docker/opts" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/spf13/pflag" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestDaemonConfigurationMerge(t *testing.T) { @@ -46,15 +46,15 @@ func TestDaemonConfigurationMerge(t *testing.T) { flags.Var(opts.NewNamedMapOpts("log-opts", nil, nil), "log-opt", "") cc, err := MergeDaemonConfigurations(c, flags, configFile) - require.NoError(t, err) + assert.NilError(t, err) - assert.True(t, cc.Debug) - assert.True(t, cc.AutoRestart) + assert.Check(t, cc.Debug) + assert.Check(t, cc.AutoRestart) expectedLogConfig := LogConfig{ Type: "syslog", Config: map[string]string{"tag": "test_tag"}, } - assert.Equal(t, expectedLogConfig, cc.LogConfig) + assert.Check(t, is.DeepEqual(expectedLogConfig, cc.LogConfig)) } diff --git a/components/engine/daemon/container_unix_test.go b/components/engine/daemon/container_unix_test.go index e102be6cdc1..12075f8b8df 100644 --- a/components/engine/daemon/container_unix_test.go +++ b/components/engine/daemon/container_unix_test.go @@ -9,7 +9,7 @@ import ( containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/daemon/config" "github.com/docker/go-connections/nat" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) // TestContainerWarningHostAndPublishPorts that a warning is returned when setting network mode to host and specifying published ports. @@ -38,7 +38,7 @@ func TestContainerWarningHostAndPublishPorts(t *testing.T) { } d := &Daemon{configStore: cs} wrns, err := d.verifyContainerSettings("", hostConfig, &containertypes.Config{}, false) - require.NoError(t, err) - require.Equal(t, tc.warnings, wrns) + assert.NilError(t, err) + assert.DeepEqual(t, tc.warnings, wrns) } } diff --git a/components/engine/daemon/create_test.go b/components/engine/daemon/create_test.go index 3e355f64736..7ef49d76233 100644 --- a/components/engine/daemon/create_test.go +++ b/components/engine/daemon/create_test.go @@ -5,7 +5,7 @@ import ( "github.com/docker/docker/api/types/network" "github.com/docker/docker/errdefs" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" ) // Test case for 35752 @@ -17,5 +17,5 @@ func TestVerifyNetworkingConfig(t *testing.T) { EndpointsConfig: endpoints, } err := verifyNetworkingConfig(nwConfig) - assert.True(t, errdefs.IsInvalidParameter(err)) + assert.Check(t, errdefs.IsInvalidParameter(err)) } diff --git a/components/engine/daemon/daemon_linux_test.go b/components/engine/daemon/daemon_linux_test.go index ad651e3e1c9..195afb1e0fb 100644 --- a/components/engine/daemon/daemon_linux_test.go +++ b/components/engine/daemon/daemon_linux_test.go @@ -11,8 +11,8 @@ import ( "github.com/docker/docker/oci" "github.com/docker/docker/pkg/idtools" "github.com/docker/docker/pkg/mount" - - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) const mountsFixture = `142 78 0:38 / / rw,relatime - aufs none rw,si=573b861da0b3a05b,dio @@ -138,7 +138,7 @@ func TestTmpfsDevShmSizeOverride(t *testing.T) { // convert ms to spec spec := oci.DefaultSpec() err := setMounts(&d, &spec, c, ms) - assert.NoError(t, err) + assert.Check(t, err) // Check the resulting spec for the correct size found := false @@ -149,7 +149,7 @@ func TestTmpfsDevShmSizeOverride(t *testing.T) { continue } t.Logf("%+v\n", m.Options) - assert.Equal(t, "size="+size, o) + assert.Check(t, is.Equal("size="+size, o)) found = true } } @@ -163,7 +163,7 @@ func TestValidateContainerIsolationLinux(t *testing.T) { d := Daemon{} _, err := d.verifyContainerSettings("linux", &containertypes.HostConfig{Isolation: containertypes.IsolationHyperV}, nil, false) - assert.EqualError(t, err, "invalid isolation 'hyperv' on linux") + assert.Check(t, is.Error(err, "invalid isolation 'hyperv' on linux")) } func TestShouldUnmountRoot(t *testing.T) { @@ -222,7 +222,7 @@ func TestShouldUnmountRoot(t *testing.T) { if test.info != nil { test.info.Optional = options.Optional } - assert.Equal(t, expect, shouldUnmountRoot(test.root, test.info)) + assert.Check(t, is.Equal(expect, shouldUnmountRoot(test.root, test.info))) }) } }) diff --git a/components/engine/daemon/daemon_test.go b/components/engine/daemon/daemon_test.go index 5d40e111436..2fb4ff902ae 100644 --- a/components/engine/daemon/daemon_test.go +++ b/components/engine/daemon/daemon_test.go @@ -19,8 +19,9 @@ import ( "github.com/docker/docker/volume/store" "github.com/docker/go-connections/nat" "github.com/docker/libnetwork" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/pkg/errors" - "github.com/stretchr/testify/assert" ) // @@ -312,7 +313,7 @@ func TestValidateContainerIsolation(t *testing.T) { d := Daemon{} _, err := d.verifyContainerSettings(runtime.GOOS, &containertypes.HostConfig{Isolation: containertypes.Isolation("invalid")}, nil, false) - assert.EqualError(t, err, "invalid isolation 'invalid' on "+runtime.GOOS) + assert.Check(t, is.Error(err, "invalid isolation 'invalid' on "+runtime.GOOS)) } func TestFindNetworkErrorType(t *testing.T) { @@ -320,6 +321,6 @@ func TestFindNetworkErrorType(t *testing.T) { _, err := d.FindNetwork("fakeNet") _, ok := errors.Cause(err).(libnetwork.ErrNoSuchNetwork) if !errdefs.IsNotFound(err) || !ok { - assert.Fail(t, "The FindNetwork method MUST always return an error that implements the NotFound interface and is ErrNoSuchNetwork") + t.Error("The FindNetwork method MUST always return an error that implements the NotFound interface and is ErrNoSuchNetwork") } } diff --git a/components/engine/daemon/daemon_unix_test.go b/components/engine/daemon/daemon_unix_test.go index cd88b383350..84281c0b8c2 100644 --- a/components/engine/daemon/daemon_unix_test.go +++ b/components/engine/daemon/daemon_unix_test.go @@ -17,7 +17,7 @@ import ( "github.com/docker/docker/volume/drivers" "github.com/docker/docker/volume/local" "github.com/docker/docker/volume/store" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) type fakeContainerGetter struct { @@ -290,12 +290,12 @@ func TestMigratePre17Volumes(t *testing.T) { containerRoot := filepath.Join(rootDir, "containers") cid := "1234" err = os.MkdirAll(filepath.Join(containerRoot, cid), 0755) - require.NoError(t, err) + assert.NilError(t, err) vid := "5678" vfsPath := filepath.Join(rootDir, "vfs", "dir", vid) err = os.MkdirAll(vfsPath, 0755) - require.NoError(t, err) + assert.NilError(t, err) config := []byte(` { diff --git a/components/engine/daemon/delete_test.go b/components/engine/daemon/delete_test.go index 48a8afec486..8bfa5d81709 100644 --- a/components/engine/daemon/delete_test.go +++ b/components/engine/daemon/delete_test.go @@ -10,12 +10,12 @@ import ( containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/container" "github.com/docker/docker/internal/testutil" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) func newDaemonWithTmpRoot(t *testing.T) (*Daemon, func()) { tmp, err := ioutil.TempDir("", "docker-daemon-unix-test-") - require.NoError(t, err) + assert.NilError(t, err) d := &Daemon{ repository: tmp, root: tmp, diff --git a/components/engine/daemon/discovery/discovery_test.go b/components/engine/daemon/discovery/discovery_test.go index 4560af28785..d00e02e10b2 100644 --- a/components/engine/daemon/discovery/discovery_test.go +++ b/components/engine/daemon/discovery/discovery_test.go @@ -5,8 +5,8 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestDiscoveryOptsErrors(t *testing.T) { @@ -42,26 +42,26 @@ func TestDiscoveryOptsErrors(t *testing.T) { for _, testcase := range testcases { _, _, err := discoveryOpts(testcase.opts) - assert.Error(t, err, testcase.doc) + assert.Check(t, is.ErrorContains(err, ""), testcase.doc) } } func TestDiscoveryOpts(t *testing.T) { clusterOpts := map[string]string{"discovery.heartbeat": "10", "discovery.ttl": "20"} heartbeat, ttl, err := discoveryOpts(clusterOpts) - require.NoError(t, err) - assert.Equal(t, 10*time.Second, heartbeat) - assert.Equal(t, 20*time.Second, ttl) + assert.NilError(t, err) + assert.Check(t, is.Equal(10*time.Second, heartbeat)) + assert.Check(t, is.Equal(20*time.Second, ttl)) clusterOpts = map[string]string{"discovery.heartbeat": "10"} heartbeat, ttl, err = discoveryOpts(clusterOpts) - require.NoError(t, err) - assert.Equal(t, 10*time.Second, heartbeat) - assert.Equal(t, 10*defaultDiscoveryTTLFactor*time.Second, ttl) + assert.NilError(t, err) + assert.Check(t, is.Equal(10*time.Second, heartbeat)) + assert.Check(t, is.Equal(10*defaultDiscoveryTTLFactor*time.Second, ttl)) clusterOpts = map[string]string{"discovery.ttl": "30"} heartbeat, ttl, err = discoveryOpts(clusterOpts) - require.NoError(t, err) + assert.NilError(t, err) if ttl != 30*time.Second { t.Fatalf("TTL - Expected : %v, Actual : %v", 30*time.Second, ttl) diff --git a/components/engine/daemon/graphdriver/aufs/aufs_test.go b/components/engine/daemon/graphdriver/aufs/aufs_test.go index d0641abe35c..2338ad320d7 100644 --- a/components/engine/daemon/graphdriver/aufs/aufs_test.go +++ b/components/engine/daemon/graphdriver/aufs/aufs_test.go @@ -17,8 +17,8 @@ import ( "github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/reexec" "github.com/docker/docker/pkg/stringid" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) var ( @@ -189,7 +189,7 @@ func TestCleanupWithNoDirs(t *testing.T) { defer os.RemoveAll(tmp) err := d.Cleanup() - assert.NoError(t, err) + assert.Check(t, err) } func TestCleanupWithDir(t *testing.T) { @@ -210,11 +210,11 @@ func TestMountedFalseResponse(t *testing.T) { defer os.RemoveAll(tmp) err := d.Create("1", "", nil) - require.NoError(t, err) + assert.NilError(t, err) response, err := d.mounted(d.getDiffPath("1")) - require.NoError(t, err) - assert.False(t, response) + assert.NilError(t, err) + assert.Check(t, !response) } func TestMountedTrueResponse(t *testing.T) { @@ -223,16 +223,16 @@ func TestMountedTrueResponse(t *testing.T) { defer d.Cleanup() err := d.Create("1", "", nil) - require.NoError(t, err) + assert.NilError(t, err) err = d.Create("2", "1", nil) - require.NoError(t, err) + assert.NilError(t, err) _, err = d.Get("2", "") - require.NoError(t, err) + assert.NilError(t, err) response, err := d.mounted(d.pathCache["2"]) - require.NoError(t, err) - assert.True(t, response) + assert.NilError(t, err) + assert.Check(t, response) } func TestMountWithParent(t *testing.T) { @@ -567,7 +567,7 @@ func TestStatus(t *testing.T) { } status := d.Status() - assert.Len(t, status, 4) + assert.Check(t, is.Len(status, 4)) rootDir := status[0] dirs := status[2] @@ -670,18 +670,18 @@ func testMountMoreThan42Layers(t *testing.T, mountPath string) { current = hash(current) err := d.CreateReadWrite(current, parent, nil) - require.NoError(t, err, "current layer %d", i) + assert.NilError(t, err, "current layer %d", i) point, err := driverGet(d, current, "") - require.NoError(t, err, "current layer %d", i) + assert.NilError(t, err, "current layer %d", i) f, err := os.Create(path.Join(point, current)) - require.NoError(t, err, "current layer %d", i) + assert.NilError(t, err, "current layer %d", i) f.Close() if i%10 == 0 { err := os.Remove(path.Join(point, parent)) - require.NoError(t, err, "current layer %d", i) + assert.NilError(t, err, "current layer %d", i) expected-- } last = current @@ -689,10 +689,10 @@ func testMountMoreThan42Layers(t *testing.T, mountPath string) { // Perform the actual mount for the top most image point, err := driverGet(d, last, "") - require.NoError(t, err) + assert.NilError(t, err) files, err := ioutil.ReadDir(point) - require.NoError(t, err) - assert.Len(t, files, expected) + assert.NilError(t, err) + assert.Check(t, is.Len(files, expected)) } func TestMountMoreThan42Layers(t *testing.T) { diff --git a/components/engine/daemon/graphdriver/copy/copy_test.go b/components/engine/daemon/graphdriver/copy/copy_test.go index 6d4387c94e5..a09bb2637ea 100644 --- a/components/engine/daemon/graphdriver/copy/copy_test.go +++ b/components/engine/daemon/graphdriver/copy/copy_test.go @@ -14,8 +14,8 @@ import ( "github.com/docker/docker/pkg/parsers/kernel" "github.com/docker/docker/pkg/system" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/sys/unix" ) @@ -24,16 +24,16 @@ func TestIsCopyFileRangeSyscallAvailable(t *testing.T) { // 1. That copyFileRangeEnabled is being set to true when copy_file_range syscall is available // 2. That isCopyFileRangeSyscallAvailable() works on "new" kernels v, err := kernel.GetKernelVersion() - require.NoError(t, err) + assert.NilError(t, err) copyWithFileRange := true copyWithFileClone := false doCopyTest(t, ©WithFileRange, ©WithFileClone) if kernel.CompareKernelVersion(*v, kernel.VersionInfo{Kernel: 4, Major: 5, Minor: 0}) < 0 { - assert.False(t, copyWithFileRange) + assert.Check(t, !copyWithFileRange) } else { - assert.True(t, copyWithFileRange) + assert.Check(t, copyWithFileRange) } } @@ -52,47 +52,47 @@ func TestCopyWithoutRange(t *testing.T) { func TestCopyDir(t *testing.T) { srcDir, err := ioutil.TempDir("", "srcDir") - require.NoError(t, err) + assert.NilError(t, err) populateSrcDir(t, srcDir, 3) dstDir, err := ioutil.TempDir("", "testdst") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(dstDir) - assert.NoError(t, DirCopy(srcDir, dstDir, Content, false)) - require.NoError(t, filepath.Walk(srcDir, func(srcPath string, f os.FileInfo, err error) error { + assert.Check(t, DirCopy(srcDir, dstDir, Content, false)) + assert.NilError(t, filepath.Walk(srcDir, func(srcPath string, f os.FileInfo, err error) error { if err != nil { return err } // Rebase path relPath, err := filepath.Rel(srcDir, srcPath) - require.NoError(t, err) + assert.NilError(t, err) if relPath == "." { return nil } dstPath := filepath.Join(dstDir, relPath) - require.NoError(t, err) + assert.NilError(t, err) // If we add non-regular dirs and files to the test // then we need to add more checks here. dstFileInfo, err := os.Lstat(dstPath) - require.NoError(t, err) + assert.NilError(t, err) srcFileSys := f.Sys().(*syscall.Stat_t) dstFileSys := dstFileInfo.Sys().(*syscall.Stat_t) t.Log(relPath) if srcFileSys.Dev == dstFileSys.Dev { - assert.NotEqual(t, srcFileSys.Ino, dstFileSys.Ino) + assert.Check(t, srcFileSys.Ino != dstFileSys.Ino) } // Todo: check size, and ctim is not equal /// on filesystems that have granular ctimes - assert.Equal(t, srcFileSys.Mode, dstFileSys.Mode) - assert.Equal(t, srcFileSys.Uid, dstFileSys.Uid) - assert.Equal(t, srcFileSys.Gid, dstFileSys.Gid) - assert.Equal(t, srcFileSys.Mtim, dstFileSys.Mtim) + assert.Check(t, is.DeepEqual(srcFileSys.Mode, dstFileSys.Mode)) + assert.Check(t, is.DeepEqual(srcFileSys.Uid, dstFileSys.Uid)) + assert.Check(t, is.DeepEqual(srcFileSys.Gid, dstFileSys.Gid)) + assert.Check(t, is.DeepEqual(srcFileSys.Mtim, dstFileSys.Mtim)) return nil })) @@ -115,22 +115,22 @@ func populateSrcDir(t *testing.T, srcDir string, remainingDepth int) { for i := 0; i < 10; i++ { dirName := filepath.Join(srcDir, fmt.Sprintf("srcdir-%d", i)) // Owner all bits set - require.NoError(t, os.Mkdir(dirName, randomMode(0700))) + assert.NilError(t, os.Mkdir(dirName, randomMode(0700))) populateSrcDir(t, dirName, remainingDepth-1) - require.NoError(t, system.Chtimes(dirName, aTime, mTime)) + assert.NilError(t, system.Chtimes(dirName, aTime, mTime)) } for i := 0; i < 10; i++ { fileName := filepath.Join(srcDir, fmt.Sprintf("srcfile-%d", i)) // Owner read bit set - require.NoError(t, ioutil.WriteFile(fileName, []byte{}, randomMode(0400))) - require.NoError(t, system.Chtimes(fileName, aTime, mTime)) + assert.NilError(t, ioutil.WriteFile(fileName, []byte{}, randomMode(0400))) + assert.NilError(t, system.Chtimes(fileName, aTime, mTime)) } } func doCopyTest(t *testing.T, copyWithFileRange, copyWithFileClone *bool) { dir, err := ioutil.TempDir("", "docker-copy-check") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(dir) srcFilename := filepath.Join(dir, "srcFilename") dstFilename := filepath.Join(dir, "dstilename") @@ -138,42 +138,42 @@ func doCopyTest(t *testing.T, copyWithFileRange, copyWithFileClone *bool) { r := rand.New(rand.NewSource(0)) buf := make([]byte, 1024) _, err = r.Read(buf) - require.NoError(t, err) - require.NoError(t, ioutil.WriteFile(srcFilename, buf, 0777)) + assert.NilError(t, err) + assert.NilError(t, ioutil.WriteFile(srcFilename, buf, 0777)) fileinfo, err := os.Stat(srcFilename) - require.NoError(t, err) + assert.NilError(t, err) - require.NoError(t, copyRegular(srcFilename, dstFilename, fileinfo, copyWithFileRange, copyWithFileClone)) + assert.NilError(t, copyRegular(srcFilename, dstFilename, fileinfo, copyWithFileRange, copyWithFileClone)) readBuf, err := ioutil.ReadFile(dstFilename) - require.NoError(t, err) - assert.Equal(t, buf, readBuf) + assert.NilError(t, err) + assert.Check(t, is.DeepEqual(buf, readBuf)) } func TestCopyHardlink(t *testing.T) { var srcFile1FileInfo, srcFile2FileInfo, dstFile1FileInfo, dstFile2FileInfo unix.Stat_t srcDir, err := ioutil.TempDir("", "srcDir") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(srcDir) dstDir, err := ioutil.TempDir("", "dstDir") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(dstDir) srcFile1 := filepath.Join(srcDir, "file1") srcFile2 := filepath.Join(srcDir, "file2") dstFile1 := filepath.Join(dstDir, "file1") dstFile2 := filepath.Join(dstDir, "file2") - require.NoError(t, ioutil.WriteFile(srcFile1, []byte{}, 0777)) - require.NoError(t, os.Link(srcFile1, srcFile2)) + assert.NilError(t, ioutil.WriteFile(srcFile1, []byte{}, 0777)) + assert.NilError(t, os.Link(srcFile1, srcFile2)) - assert.NoError(t, DirCopy(srcDir, dstDir, Content, false)) + assert.Check(t, DirCopy(srcDir, dstDir, Content, false)) - require.NoError(t, unix.Stat(srcFile1, &srcFile1FileInfo)) - require.NoError(t, unix.Stat(srcFile2, &srcFile2FileInfo)) - require.Equal(t, srcFile1FileInfo.Ino, srcFile2FileInfo.Ino) + assert.NilError(t, unix.Stat(srcFile1, &srcFile1FileInfo)) + assert.NilError(t, unix.Stat(srcFile2, &srcFile2FileInfo)) + assert.Equal(t, srcFile1FileInfo.Ino, srcFile2FileInfo.Ino) - require.NoError(t, unix.Stat(dstFile1, &dstFile1FileInfo)) - require.NoError(t, unix.Stat(dstFile2, &dstFile2FileInfo)) - assert.Equal(t, dstFile1FileInfo.Ino, dstFile2FileInfo.Ino) + assert.NilError(t, unix.Stat(dstFile1, &dstFile1FileInfo)) + assert.NilError(t, unix.Stat(dstFile2, &dstFile2FileInfo)) + assert.Check(t, is.Equal(dstFile1FileInfo.Ino, dstFile2FileInfo.Ino)) } diff --git a/components/engine/daemon/graphdriver/driver_test.go b/components/engine/daemon/graphdriver/driver_test.go index 777bac7af9f..4a29465f152 100644 --- a/components/engine/daemon/graphdriver/driver_test.go +++ b/components/engine/daemon/graphdriver/driver_test.go @@ -6,32 +6,31 @@ import ( "path/filepath" "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) func TestIsEmptyDir(t *testing.T) { tmp, err := ioutil.TempDir("", "test-is-empty-dir") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(tmp) d := filepath.Join(tmp, "empty-dir") err = os.Mkdir(d, 0755) - require.NoError(t, err) + assert.NilError(t, err) empty := isEmptyDir(d) - assert.True(t, empty) + assert.Check(t, empty) d = filepath.Join(tmp, "dir-with-subdir") err = os.MkdirAll(filepath.Join(d, "subdir"), 0755) - require.NoError(t, err) + assert.NilError(t, err) empty = isEmptyDir(d) - assert.False(t, empty) + assert.Check(t, !empty) d = filepath.Join(tmp, "dir-with-empty-file") err = os.Mkdir(d, 0755) - require.NoError(t, err) + assert.NilError(t, err) _, err = ioutil.TempFile(d, "file") - require.NoError(t, err) + assert.NilError(t, err) empty = isEmptyDir(d) - assert.False(t, empty) + assert.Check(t, !empty) } diff --git a/components/engine/daemon/graphdriver/graphtest/graphbench_unix.go b/components/engine/daemon/graphdriver/graphtest/graphbench_unix.go index 2eb4184c0fc..1b221dabeff 100644 --- a/components/engine/daemon/graphdriver/graphtest/graphbench_unix.go +++ b/components/engine/daemon/graphdriver/graphtest/graphbench_unix.go @@ -9,7 +9,7 @@ import ( contdriver "github.com/containerd/continuity/driver" "github.com/docker/docker/pkg/stringid" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) // DriverBenchExists benchmarks calls to exist @@ -251,7 +251,7 @@ func DriverBenchDeepLayerRead(b *testing.B, layerCount int, drivername string, d } b.StopTimer() - require.Equal(b, content, c) + assert.DeepEqual(b, content, c) b.StartTimer() } } diff --git a/components/engine/daemon/graphdriver/graphtest/graphtest_unix.go b/components/engine/daemon/graphdriver/graphtest/graphtest_unix.go index a7bdd8cdaa6..5ac3979752a 100644 --- a/components/engine/daemon/graphdriver/graphtest/graphtest_unix.go +++ b/components/engine/daemon/graphdriver/graphtest/graphtest_unix.go @@ -16,8 +16,8 @@ import ( "github.com/docker/docker/daemon/graphdriver/quota" "github.com/docker/docker/pkg/stringid" "github.com/docker/go-units" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/sys/unix" ) @@ -36,9 +36,9 @@ type Driver struct { func newDriver(t testing.TB, name string, options []string) *Driver { root, err := ioutil.TempDir("", "docker-graphtest-") - require.NoError(t, err) + assert.NilError(t, err) - require.NoError(t, os.MkdirAll(root, 0755)) + assert.NilError(t, os.MkdirAll(root, 0755)) d, err := graphdriver.GetDriver(name, nil, graphdriver.Options{DriverOptions: options, Root: root}) if err != nil { t.Logf("graphdriver: %v\n", err) @@ -85,10 +85,10 @@ func DriverTestCreateEmpty(t testing.TB, drivername string, driverOptions ...str defer PutDriver(t) err := driver.Create("empty", "", nil) - require.NoError(t, err) + assert.NilError(t, err) defer func() { - require.NoError(t, driver.Remove("empty")) + assert.NilError(t, driver.Remove("empty")) }() if !driver.Exists("empty") { @@ -96,14 +96,14 @@ func DriverTestCreateEmpty(t testing.TB, drivername string, driverOptions ...str } dir, err := driver.Get("empty", "") - require.NoError(t, err) + assert.NilError(t, err) verifyFile(t, dir.Path(), 0755|os.ModeDir, 0, 0) // Verify that the directory is empty fis, err := readDir(dir, dir.Path()) - require.NoError(t, err) - assert.Len(t, fis, 0) + assert.NilError(t, err) + assert.Check(t, is.Len(fis, 0)) driver.Put("empty") } @@ -115,7 +115,7 @@ func DriverTestCreateBase(t testing.TB, drivername string, driverOptions ...stri createBase(t, driver, "Base") defer func() { - require.NoError(t, driver.Remove("Base")) + assert.NilError(t, driver.Remove("Base")) }() verifyBase(t, driver, "Base") } @@ -127,13 +127,13 @@ func DriverTestCreateSnap(t testing.TB, drivername string, driverOptions ...stri createBase(t, driver, "Base") defer func() { - require.NoError(t, driver.Remove("Base")) + assert.NilError(t, driver.Remove("Base")) }() err := driver.Create("Snap", "Base", nil) - require.NoError(t, err) + assert.NilError(t, err) defer func() { - require.NoError(t, driver.Remove("Snap")) + assert.NilError(t, driver.Remove("Snap")) }() verifyBase(t, driver, "Snap") diff --git a/components/engine/daemon/graphdriver/graphtest/testutil_unix.go b/components/engine/daemon/graphdriver/graphtest/testutil_unix.go index 4659bf2a191..3103df150d2 100644 --- a/components/engine/daemon/graphdriver/graphtest/testutil_unix.go +++ b/components/engine/daemon/graphdriver/graphtest/testutil_unix.go @@ -9,25 +9,25 @@ import ( contdriver "github.com/containerd/continuity/driver" "github.com/docker/docker/daemon/graphdriver" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/sys/unix" ) func verifyFile(t testing.TB, path string, mode os.FileMode, uid, gid uint32) { fi, err := os.Stat(path) - require.NoError(t, err) + assert.NilError(t, err) actual := fi.Mode() - assert.Equal(t, mode&os.ModeType, actual&os.ModeType, path) - assert.Equal(t, mode&os.ModePerm, actual&os.ModePerm, path) - assert.Equal(t, mode&os.ModeSticky, actual&os.ModeSticky, path) - assert.Equal(t, mode&os.ModeSetuid, actual&os.ModeSetuid, path) - assert.Equal(t, mode&os.ModeSetgid, actual&os.ModeSetgid, path) + assert.Check(t, is.Equal(mode&os.ModeType, actual&os.ModeType), path) + assert.Check(t, is.Equal(mode&os.ModePerm, actual&os.ModePerm), path) + assert.Check(t, is.Equal(mode&os.ModeSticky, actual&os.ModeSticky), path) + assert.Check(t, is.Equal(mode&os.ModeSetuid, actual&os.ModeSetuid), path) + assert.Check(t, is.Equal(mode&os.ModeSetgid, actual&os.ModeSetgid), path) if stat, ok := fi.Sys().(*syscall.Stat_t); ok { - assert.Equal(t, uid, stat.Uid, path) - assert.Equal(t, gid, stat.Gid, path) + assert.Check(t, is.Equal(uid, stat.Uid), path) + assert.Check(t, is.Equal(gid, stat.Gid), path) } } @@ -37,24 +37,24 @@ func createBase(t testing.TB, driver graphdriver.Driver, name string) { defer unix.Umask(oldmask) err := driver.CreateReadWrite(name, "", nil) - require.NoError(t, err) + assert.NilError(t, err) dirFS, err := driver.Get(name, "") - require.NoError(t, err) + assert.NilError(t, err) defer driver.Put(name) subdir := dirFS.Join(dirFS.Path(), "a subdir") - require.NoError(t, dirFS.Mkdir(subdir, 0705|os.ModeSticky)) - require.NoError(t, dirFS.Lchown(subdir, 1, 2)) + assert.NilError(t, dirFS.Mkdir(subdir, 0705|os.ModeSticky)) + assert.NilError(t, dirFS.Lchown(subdir, 1, 2)) file := dirFS.Join(dirFS.Path(), "a file") err = contdriver.WriteFile(dirFS, file, []byte("Some data"), 0222|os.ModeSetuid) - require.NoError(t, err) + assert.NilError(t, err) } func verifyBase(t testing.TB, driver graphdriver.Driver, name string) { dirFS, err := driver.Get(name, "") - require.NoError(t, err) + assert.NilError(t, err) defer driver.Put(name) subdir := dirFS.Join(dirFS.Path(), "a subdir") @@ -64,6 +64,6 @@ func verifyBase(t testing.TB, driver graphdriver.Driver, name string) { verifyFile(t, file, 0222|os.ModeSetuid, 0, 0) files, err := readDir(dirFS, dirFS.Path()) - require.NoError(t, err) - assert.Len(t, files, 2) + assert.NilError(t, err) + assert.Check(t, is.Len(files, 2)) } diff --git a/components/engine/daemon/graphdriver/quota/projectquota_test.go b/components/engine/daemon/graphdriver/quota/projectquota_test.go index 939044fdc32..b7debf79e23 100644 --- a/components/engine/daemon/graphdriver/quota/projectquota_test.go +++ b/components/engine/daemon/graphdriver/quota/projectquota_test.go @@ -10,9 +10,9 @@ import ( "path/filepath" "testing" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/fs" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "golang.org/x/sys/unix" ) @@ -80,14 +80,14 @@ func wrapMountTest(imageFileName string, enableQuota bool, testFunc func(t *test } } - require.NoError(t, err, "mount failed: %s", out) + assert.NilError(t, err, "mount failed: %s", out) defer func() { - require.NoError(t, unix.Unmount(mountPoint, 0)) + assert.NilError(t, unix.Unmount(mountPoint, 0)) }() backingFsDev, err := makeBackingFsDev(mountPoint) - require.NoError(t, err) + assert.NilError(t, err) testFunc(t, mountPoint, backingFsDev) } @@ -95,58 +95,58 @@ func wrapMountTest(imageFileName string, enableQuota bool, testFunc func(t *test func testBlockDevQuotaDisabled(t *testing.T, mountPoint, backingFsDev string) { hasSupport, err := hasQuotaSupport(backingFsDev) - require.NoError(t, err) - assert.False(t, hasSupport) + assert.NilError(t, err) + assert.Check(t, !hasSupport) } func testBlockDevQuotaEnabled(t *testing.T, mountPoint, backingFsDev string) { hasSupport, err := hasQuotaSupport(backingFsDev) - require.NoError(t, err) - assert.True(t, hasSupport) + assert.NilError(t, err) + assert.Check(t, hasSupport) } func wrapQuotaTest(testFunc func(t *testing.T, ctrl *Control, mountPoint, testDir, testSubDir string)) func(t *testing.T, mountPoint, backingFsDev string) { return func(t *testing.T, mountPoint, backingFsDev string) { testDir, err := ioutil.TempDir(mountPoint, "per-test") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(testDir) ctrl, err := NewControl(testDir) - require.NoError(t, err) + assert.NilError(t, err) testSubDir, err := ioutil.TempDir(testDir, "quota-test") - require.NoError(t, err) + assert.NilError(t, err) testFunc(t, ctrl, mountPoint, testDir, testSubDir) } } func testSmallerThanQuota(t *testing.T, ctrl *Control, homeDir, testDir, testSubDir string) { - require.NoError(t, ctrl.SetQuota(testSubDir, Quota{testQuotaSize})) + assert.NilError(t, ctrl.SetQuota(testSubDir, Quota{testQuotaSize})) smallerThanQuotaFile := filepath.Join(testSubDir, "smaller-than-quota") - require.NoError(t, ioutil.WriteFile(smallerThanQuotaFile, make([]byte, testQuotaSize/2), 0644)) - require.NoError(t, os.Remove(smallerThanQuotaFile)) + assert.NilError(t, ioutil.WriteFile(smallerThanQuotaFile, make([]byte, testQuotaSize/2), 0644)) + assert.NilError(t, os.Remove(smallerThanQuotaFile)) } func testBiggerThanQuota(t *testing.T, ctrl *Control, homeDir, testDir, testSubDir string) { // Make sure the quota is being enforced // TODO: When we implement this under EXT4, we need to shed CAP_SYS_RESOURCE, otherwise // we're able to violate quota without issue - require.NoError(t, ctrl.SetQuota(testSubDir, Quota{testQuotaSize})) + assert.NilError(t, ctrl.SetQuota(testSubDir, Quota{testQuotaSize})) biggerThanQuotaFile := filepath.Join(testSubDir, "bigger-than-quota") err := ioutil.WriteFile(biggerThanQuotaFile, make([]byte, testQuotaSize+1), 0644) - require.Error(t, err) + assert.Assert(t, is.ErrorContains(err, "")) if err == io.ErrShortWrite { - require.NoError(t, os.Remove(biggerThanQuotaFile)) + assert.NilError(t, os.Remove(biggerThanQuotaFile)) } } func testRetrieveQuota(t *testing.T, ctrl *Control, homeDir, testDir, testSubDir string) { // Validate that we can retrieve quota - require.NoError(t, ctrl.SetQuota(testSubDir, Quota{testQuotaSize})) + assert.NilError(t, ctrl.SetQuota(testSubDir, Quota{testQuotaSize})) var q Quota - require.NoError(t, ctrl.GetQuota(testSubDir, &q)) - assert.EqualValues(t, testQuotaSize, q.Size) + assert.NilError(t, ctrl.GetQuota(testSubDir, &q)) + assert.Check(t, is.Equal(testQuotaSize, q.Size)) } diff --git a/components/engine/daemon/info_unix_test.go b/components/engine/daemon/info_unix_test.go index 92a336162a4..7ff10093265 100644 --- a/components/engine/daemon/info_unix_test.go +++ b/components/engine/daemon/info_unix_test.go @@ -7,7 +7,8 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/dockerversion" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestParseInitVersion(t *testing.T) { @@ -43,10 +44,10 @@ func TestParseInitVersion(t *testing.T) { for _, test := range tests { ver, err := parseInitVersion(string(test.version)) if test.invalid { - assert.Error(t, err) + assert.Check(t, is.ErrorContains(err, "")) } else { - assert.NoError(t, err) + assert.Check(t, err) } - assert.Equal(t, test.result, ver) + assert.Check(t, is.DeepEqual(test.result, ver)) } } diff --git a/components/engine/daemon/inspect_test.go b/components/engine/daemon/inspect_test.go index c10cc567961..d1ad5b0e0a4 100644 --- a/components/engine/daemon/inspect_test.go +++ b/components/engine/daemon/inspect_test.go @@ -7,8 +7,8 @@ import ( "github.com/docker/docker/container" "github.com/docker/docker/daemon/config" "github.com/docker/docker/daemon/exec" - - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestGetInspectData(t *testing.T) { @@ -25,9 +25,9 @@ func TestGetInspectData(t *testing.T) { } _, err := d.getInspectData(c) - assert.Error(t, err) + assert.Check(t, is.ErrorContains(err, "")) c.Dead = true _, err = d.getInspectData(c) - assert.NoError(t, err) + assert.Check(t, err) } diff --git a/components/engine/daemon/logger/adapter_test.go b/components/engine/daemon/logger/adapter_test.go index 25abab57178..7c1db6f575e 100644 --- a/components/engine/daemon/logger/adapter_test.go +++ b/components/engine/daemon/logger/adapter_test.go @@ -10,7 +10,8 @@ import ( "github.com/docker/docker/api/types/plugins/logdriver" protoio "github.com/gogo/protobuf/io" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) // mockLoggingPlugin implements the loggingPlugin interface for testing purposes @@ -88,7 +89,7 @@ func (l *mockLoggingPlugin) ReadLogs(info Info, config ReadConfig) (io.ReadClose func newMockPluginAdapter(t *testing.T) Logger { r, w := io.Pipe() f, err := ioutil.TempFile("", "mock-plugin-adapter") - assert.NoError(t, err) + assert.Check(t, err) enc := logdriver.NewLogEntryEncoder(w) a := &pluginAdapterWithRead{ @@ -116,11 +117,11 @@ func TestAdapterReadLogs(t *testing.T) { } for _, msg := range testMsg { m := msg.copy() - assert.NoError(t, l.Log(m)) + assert.Check(t, l.Log(m)) } lr, ok := l.(LogReader) - assert.NotNil(t, ok) + assert.Check(t, ok != nil) lw := lr.ReadLogs(ReadConfig{}) @@ -135,7 +136,7 @@ func TestAdapterReadLogs(t *testing.T) { select { case _, ok := <-lw.Msg: - assert.False(t, ok, "expected message channel to be closed") + assert.Check(t, !ok, "expected message channel to be closed") case <-time.After(10 * time.Second): t.Fatal("timeout waiting for message channel to close") @@ -153,11 +154,11 @@ func TestAdapterReadLogs(t *testing.T) { } x := Message{Line: []byte("Too infinity and beyond!"), Timestamp: time.Now()} - assert.NoError(t, l.Log(x.copy())) + assert.Check(t, l.Log(x.copy())) select { case msg, ok := <-lw.Msg: - assert.NotNil(t, ok, "message channel unexpectedly closed") + assert.Check(t, ok != nil, "message channel unexpectedly closed") testMessageEqual(t, &x, msg) case <-time.After(10 * time.Second): t.Fatal("timeout reading logs") @@ -166,15 +167,15 @@ func TestAdapterReadLogs(t *testing.T) { l.Close() select { case msg, ok := <-lw.Msg: - assert.False(t, ok, "expected message channel to be closed") - assert.Nil(t, msg) + assert.Check(t, !ok, "expected message channel to be closed") + assert.Check(t, is.Nil(msg)) case <-time.After(10 * time.Second): t.Fatal("timeout waiting for logger to close") } } func testMessageEqual(t *testing.T, a, b *Message) { - assert.Equal(t, a.Line, b.Line) - assert.Equal(t, a.Timestamp.UnixNano(), b.Timestamp.UnixNano()) - assert.Equal(t, a.Source, b.Source) + assert.Check(t, is.DeepEqual(a.Line, b.Line)) + assert.Check(t, is.DeepEqual(a.Timestamp.UnixNano(), b.Timestamp.UnixNano())) + assert.Check(t, is.Equal(a.Source, b.Source)) } diff --git a/components/engine/daemon/logger/awslogs/cloudwatchlogs_test.go b/components/engine/daemon/logger/awslogs/cloudwatchlogs_test.go index 99d0f907f88..4a37d981678 100644 --- a/components/engine/daemon/logger/awslogs/cloudwatchlogs_test.go +++ b/components/engine/daemon/logger/awslogs/cloudwatchlogs_test.go @@ -21,7 +21,8 @@ import ( "github.com/docker/docker/daemon/logger" "github.com/docker/docker/daemon/logger/loggerutils" "github.com/docker/docker/dockerversion" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) const ( @@ -544,17 +545,17 @@ func TestCollectBatchMultilinePattern(t *testing.T) { // Verify single multiline event argument := <-mockClient.putLogEventsArgument - assert.NotNil(t, argument, "Expected non-nil PutLogEventsInput") - assert.Equal(t, 1, len(argument.LogEvents), "Expected single multiline event") - assert.Equal(t, logline+"\n"+logline+"\n", *argument.LogEvents[0].Message, "Received incorrect multiline message") + assert.Check(t, argument != nil, "Expected non-nil PutLogEventsInput") + assert.Check(t, is.Equal(1, len(argument.LogEvents)), "Expected single multiline event") + assert.Check(t, is.Equal(logline+"\n"+logline+"\n", *argument.LogEvents[0].Message), "Received incorrect multiline message") stream.Close() // Verify single event argument = <-mockClient.putLogEventsArgument - assert.NotNil(t, argument, "Expected non-nil PutLogEventsInput") - assert.Equal(t, 1, len(argument.LogEvents), "Expected single multiline event") - assert.Equal(t, "xxxx "+logline+"\n", *argument.LogEvents[0].Message, "Received incorrect multiline message") + assert.Check(t, argument != nil, "Expected non-nil PutLogEventsInput") + assert.Check(t, is.Equal(1, len(argument.LogEvents)), "Expected single multiline event") + assert.Check(t, is.Equal("xxxx "+logline+"\n", *argument.LogEvents[0].Message), "Received incorrect multiline message") } func BenchmarkCollectBatch(b *testing.B) { @@ -657,9 +658,9 @@ func TestCollectBatchMultilinePatternMaxEventAge(t *testing.T) { // Verify single multiline event is flushed after maximum event buffer age (batchPublishFrequency) argument := <-mockClient.putLogEventsArgument - assert.NotNil(t, argument, "Expected non-nil PutLogEventsInput") - assert.Equal(t, 1, len(argument.LogEvents), "Expected single multiline event") - assert.Equal(t, logline+"\n"+logline+"\n", *argument.LogEvents[0].Message, "Received incorrect multiline message") + assert.Check(t, argument != nil, "Expected non-nil PutLogEventsInput") + assert.Check(t, is.Equal(1, len(argument.LogEvents)), "Expected single multiline event") + assert.Check(t, is.Equal(logline+"\n"+logline+"\n", *argument.LogEvents[0].Message), "Received incorrect multiline message") // Log an event 1 second later stream.Log(&logger.Message{ @@ -672,9 +673,9 @@ func TestCollectBatchMultilinePatternMaxEventAge(t *testing.T) { // Verify the event buffer is truly flushed - we should only receive a single event argument = <-mockClient.putLogEventsArgument - assert.NotNil(t, argument, "Expected non-nil PutLogEventsInput") - assert.Equal(t, 1, len(argument.LogEvents), "Expected single multiline event") - assert.Equal(t, logline+"\n", *argument.LogEvents[0].Message, "Received incorrect multiline message") + assert.Check(t, argument != nil, "Expected non-nil PutLogEventsInput") + assert.Check(t, is.Equal(1, len(argument.LogEvents)), "Expected single multiline event") + assert.Check(t, is.Equal(logline+"\n", *argument.LogEvents[0].Message), "Received incorrect multiline message") stream.Close() } @@ -719,9 +720,9 @@ func TestCollectBatchMultilinePatternNegativeEventAge(t *testing.T) { // Verify single multiline event is flushed with a negative event buffer age argument := <-mockClient.putLogEventsArgument - assert.NotNil(t, argument, "Expected non-nil PutLogEventsInput") - assert.Equal(t, 1, len(argument.LogEvents), "Expected single multiline event") - assert.Equal(t, logline+"\n"+logline+"\n", *argument.LogEvents[0].Message, "Received incorrect multiline message") + assert.Check(t, argument != nil, "Expected non-nil PutLogEventsInput") + assert.Check(t, is.Equal(1, len(argument.LogEvents)), "Expected single multiline event") + assert.Check(t, is.Equal(logline+"\n"+logline+"\n", *argument.LogEvents[0].Message), "Received incorrect multiline message") stream.Close() } @@ -772,10 +773,10 @@ func TestCollectBatchMultilinePatternMaxEventSize(t *testing.T) { // We expect a maximum sized event with no new line characters and a // second short event with a new line character at the end argument := <-mockClient.putLogEventsArgument - assert.NotNil(t, argument, "Expected non-nil PutLogEventsInput") - assert.Equal(t, 2, len(argument.LogEvents), "Expected two events") - assert.Equal(t, longline, *argument.LogEvents[0].Message, "Received incorrect multiline message") - assert.Equal(t, shortline+"\n", *argument.LogEvents[1].Message, "Received incorrect multiline message") + assert.Check(t, argument != nil, "Expected non-nil PutLogEventsInput") + assert.Check(t, is.Equal(2, len(argument.LogEvents)), "Expected two events") + assert.Check(t, is.Equal(longline, *argument.LogEvents[0].Message), "Received incorrect multiline message") + assert.Check(t, is.Equal(shortline+"\n", *argument.LogEvents[1].Message), "Received incorrect multiline message") stream.Close() } @@ -1069,8 +1070,8 @@ func TestParseLogOptionsMultilinePattern(t *testing.T) { } multilinePattern, err := parseMultilineOptions(info) - assert.Nil(t, err, "Received unexpected error") - assert.True(t, multilinePattern.MatchString("xxxx"), "No multiline pattern match found") + assert.Check(t, err, "Received unexpected error") + assert.Check(t, multilinePattern.MatchString("xxxx"), "No multiline pattern match found") } func TestParseLogOptionsDatetimeFormat(t *testing.T) { @@ -1094,8 +1095,8 @@ func TestParseLogOptionsDatetimeFormat(t *testing.T) { }, } multilinePattern, err := parseMultilineOptions(info) - assert.Nil(t, err, "Received unexpected error") - assert.True(t, multilinePattern.MatchString(dt.match), "No multiline pattern match found") + assert.Check(t, err, "Received unexpected error") + assert.Check(t, multilinePattern.MatchString(dt.match), "No multiline pattern match found") }) } } @@ -1109,8 +1110,8 @@ func TestValidateLogOptionsDatetimeFormatAndMultilinePattern(t *testing.T) { conflictingLogOptionsError := "you cannot configure log opt 'awslogs-datetime-format' and 'awslogs-multiline-pattern' at the same time" err := ValidateLogOpt(cfg) - assert.NotNil(t, err, "Expected an error") - assert.Equal(t, err.Error(), conflictingLogOptionsError, "Received invalid error") + assert.Check(t, err != nil, "Expected an error") + assert.Check(t, is.Equal(err.Error(), conflictingLogOptionsError), "Received invalid error") } func TestCreateTagSuccess(t *testing.T) { @@ -1155,7 +1156,7 @@ func BenchmarkUnwrapEvents(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { res := unwrapEvents(events) - assert.Len(b, res, maximumLogEventsPerPut) + assert.Check(b, is.Len(res, maximumLogEventsPerPut)) } } @@ -1188,15 +1189,15 @@ func TestNewAWSLogsClientCredentialEndpointDetect(t *testing.T) { info.Config["awslogs-credentials-endpoint"] = "/creds" c, err := newAWSLogsClient(info) - assert.NoError(t, err) + assert.Check(t, err) client := c.(*cloudwatchlogs.CloudWatchLogs) creds, err := client.Config.Credentials.Get() - assert.NoError(t, err) + assert.Check(t, err) - assert.Equal(t, expectedAccessKeyID, creds.AccessKeyID) - assert.Equal(t, expectedSecretAccessKey, creds.SecretAccessKey) + assert.Check(t, is.Equal(expectedAccessKeyID, creds.AccessKeyID)) + assert.Check(t, is.Equal(expectedSecretAccessKey, creds.SecretAccessKey)) } func TestNewAWSLogsClientCredentialEnvironmentVariable(t *testing.T) { @@ -1218,15 +1219,15 @@ func TestNewAWSLogsClientCredentialEnvironmentVariable(t *testing.T) { } c, err := newAWSLogsClient(info) - assert.NoError(t, err) + assert.Check(t, err) client := c.(*cloudwatchlogs.CloudWatchLogs) creds, err := client.Config.Credentials.Get() - assert.NoError(t, err) + assert.Check(t, err) - assert.Equal(t, expectedAccessKeyID, creds.AccessKeyID) - assert.Equal(t, expectedSecretAccessKey, creds.SecretAccessKey) + assert.Check(t, is.Equal(expectedAccessKeyID, creds.AccessKeyID)) + assert.Check(t, is.Equal(expectedSecretAccessKey, creds.SecretAccessKey)) } @@ -1247,13 +1248,13 @@ func TestNewAWSLogsClientCredentialSharedFile(t *testing.T) { tmpfile, err := ioutil.TempFile("", "example") defer os.Remove(tmpfile.Name()) // clean up - assert.NoError(t, err) + assert.Check(t, err) _, err = tmpfile.Write(content) - assert.NoError(t, err) + assert.Check(t, err) err = tmpfile.Close() - assert.NoError(t, err) + assert.Check(t, err) os.Unsetenv("AWS_ACCESS_KEY_ID") os.Unsetenv("AWS_SECRET_ACCESS_KEY") @@ -1266,13 +1267,13 @@ func TestNewAWSLogsClientCredentialSharedFile(t *testing.T) { } c, err := newAWSLogsClient(info) - assert.NoError(t, err) + assert.Check(t, err) client := c.(*cloudwatchlogs.CloudWatchLogs) creds, err := client.Config.Credentials.Get() - assert.NoError(t, err) + assert.Check(t, err) - assert.Equal(t, expectedAccessKeyID, creds.AccessKeyID) - assert.Equal(t, expectedSecretAccessKey, creds.SecretAccessKey) + assert.Check(t, is.Equal(expectedAccessKeyID, creds.AccessKeyID)) + assert.Check(t, is.Equal(expectedSecretAccessKey, creds.SecretAccessKey)) } diff --git a/components/engine/daemon/logger/jsonfilelog/jsonfilelog_test.go b/components/engine/daemon/logger/jsonfilelog/jsonfilelog_test.go index 2f74e260912..0174d88c0da 100644 --- a/components/engine/daemon/logger/jsonfilelog/jsonfilelog_test.go +++ b/components/engine/daemon/logger/jsonfilelog/jsonfilelog_test.go @@ -13,9 +13,9 @@ import ( "github.com/docker/docker/daemon/logger" "github.com/docker/docker/daemon/logger/jsonfilelog/jsonlog" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/fs" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestJSONFileLogger(t *testing.T) { @@ -63,7 +63,7 @@ func TestJSONFileLoggerWithTags(t *testing.T) { cname := "test-container" tmp, err := ioutil.TempDir("", "docker-logger-") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(tmp) filename := filepath.Join(tmp, "container.log") @@ -76,26 +76,26 @@ func TestJSONFileLoggerWithTags(t *testing.T) { LogPath: filename, }) - require.NoError(t, err) + assert.NilError(t, err) defer l.Close() err = l.Log(&logger.Message{Line: []byte("line1"), Source: "src1"}) - require.NoError(t, err) + assert.NilError(t, err) err = l.Log(&logger.Message{Line: []byte("line2"), Source: "src2"}) - require.NoError(t, err) + assert.NilError(t, err) err = l.Log(&logger.Message{Line: []byte("line3"), Source: "src3"}) - require.NoError(t, err) + assert.NilError(t, err) res, err := ioutil.ReadFile(filename) - require.NoError(t, err) + assert.NilError(t, err) expected := `{"log":"line1\n","stream":"src1","attrs":{"tag":"a7317399f3f8/test-container"},"time":"0001-01-01T00:00:00Z"} {"log":"line2\n","stream":"src2","attrs":{"tag":"a7317399f3f8/test-container"},"time":"0001-01-01T00:00:00Z"} {"log":"line3\n","stream":"src3","attrs":{"tag":"a7317399f3f8/test-container"},"time":"0001-01-01T00:00:00Z"} ` - assert.Equal(t, expected, string(res)) + assert.Check(t, is.Equal(expected, string(res))) } func BenchmarkJSONFileLoggerLog(b *testing.B) { @@ -113,7 +113,7 @@ func BenchmarkJSONFileLoggerLog(b *testing.B) { "second": "label_foo", }, }) - require.NoError(b, err) + assert.NilError(b, err) defer jsonlogger.Close() msg := &logger.Message{ @@ -123,7 +123,7 @@ func BenchmarkJSONFileLoggerLog(b *testing.B) { } buf := bytes.NewBuffer(nil) - require.NoError(b, marshalMessage(msg, nil, buf)) + assert.NilError(b, marshalMessage(msg, nil, buf)) b.SetBytes(int64(buf.Len())) b.ResetTimer() diff --git a/components/engine/daemon/logger/jsonfilelog/jsonlog/jsonlogbytes_test.go b/components/engine/daemon/logger/jsonfilelog/jsonlog/jsonlogbytes_test.go index 37011243544..d3e56df8cc2 100644 --- a/components/engine/daemon/logger/jsonfilelog/jsonlog/jsonlogbytes_test.go +++ b/components/engine/daemon/logger/jsonfilelog/jsonlog/jsonlogbytes_test.go @@ -7,8 +7,7 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) func TestJSONLogsMarshalJSONBuf(t *testing.T) { @@ -35,8 +34,8 @@ func TestJSONLogsMarshalJSONBuf(t *testing.T) { for jsonLog, expression := range logs { var buf bytes.Buffer err := jsonLog.MarshalJSONBuf(&buf) - require.NoError(t, err) + assert.NilError(t, err) assert.Regexp(t, regexp.MustCompile(expression), buf.String()) - assert.NoError(t, json.Unmarshal(buf.Bytes(), &map[string]interface{}{})) + assert.Check(t, json.Unmarshal(buf.Bytes(), &map[string]interface{}{})) } } diff --git a/components/engine/daemon/logger/jsonfilelog/jsonlog/time_marshalling_test.go b/components/engine/daemon/logger/jsonfilelog/jsonlog/time_marshalling_test.go index fee091eb6c2..76f299a0f60 100644 --- a/components/engine/daemon/logger/jsonfilelog/jsonlog/time_marshalling_test.go +++ b/components/engine/daemon/logger/jsonfilelog/jsonlog/time_marshalling_test.go @@ -5,8 +5,8 @@ import ( "time" "github.com/docker/docker/internal/testutil" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestFastTimeMarshalJSONWithInvalidYear(t *testing.T) { @@ -22,14 +22,14 @@ func TestFastTimeMarshalJSONWithInvalidYear(t *testing.T) { func TestFastTimeMarshalJSON(t *testing.T) { aTime := time.Date(2015, 5, 29, 11, 1, 2, 3, time.UTC) json, err := fastTimeMarshalJSON(aTime) - require.NoError(t, err) - assert.Equal(t, "\"2015-05-29T11:01:02.000000003Z\"", json) + assert.NilError(t, err) + assert.Check(t, is.Equal("\"2015-05-29T11:01:02.000000003Z\"", json)) location, err := time.LoadLocation("Europe/Paris") - require.NoError(t, err) + assert.NilError(t, err) aTime = time.Date(2015, 5, 29, 11, 1, 2, 3, location) json, err = fastTimeMarshalJSON(aTime) - require.NoError(t, err) - assert.Equal(t, "\"2015-05-29T11:01:02.000000003+02:00\"", json) + assert.NilError(t, err) + assert.Check(t, is.Equal("\"2015-05-29T11:01:02.000000003+02:00\"", json)) } diff --git a/components/engine/daemon/logger/jsonfilelog/read_test.go b/components/engine/daemon/logger/jsonfilelog/read_test.go index 342b538c284..f89fabfe1c6 100644 --- a/components/engine/daemon/logger/jsonfilelog/read_test.go +++ b/components/engine/daemon/logger/jsonfilelog/read_test.go @@ -6,8 +6,8 @@ import ( "time" "github.com/docker/docker/daemon/logger" + "github.com/gotestyourself/gotestyourself/assert" "github.com/gotestyourself/gotestyourself/fs" - "github.com/stretchr/testify/require" ) func BenchmarkJSONFileLoggerReadLogs(b *testing.B) { @@ -25,7 +25,7 @@ func BenchmarkJSONFileLoggerReadLogs(b *testing.B) { "second": "label_foo", }, }) - require.NoError(b, err) + assert.NilError(b, err) defer jsonlogger.Close() msg := &logger.Message{ @@ -35,7 +35,7 @@ func BenchmarkJSONFileLoggerReadLogs(b *testing.B) { } buf := bytes.NewBuffer(nil) - require.NoError(b, marshalMessage(msg, nil, buf)) + assert.NilError(b, marshalMessage(msg, nil, buf)) b.SetBytes(int64(buf.Len())) b.ResetTimer() diff --git a/components/engine/daemon/logger/splunk/splunk_test.go b/components/engine/daemon/logger/splunk/splunk_test.go index 9744cb561af..62895a6dd68 100644 --- a/components/engine/daemon/logger/splunk/splunk_test.go +++ b/components/engine/daemon/logger/splunk/splunk_test.go @@ -11,8 +11,8 @@ import ( "time" "github.com/docker/docker/daemon/logger" + "github.com/gotestyourself/gotestyourself/assert" "github.com/gotestyourself/gotestyourself/env" - "github.com/stretchr/testify/require" ) // Validate options @@ -99,19 +99,19 @@ func TestNewWithProxy(t *testing.T) { }, ContainerID: "containeriid", }) - require.NoError(t, err) + assert.NilError(t, err) splunkLogger := logger.(*splunkLoggerInline) proxyFunc := splunkLogger.transport.Proxy - require.NotNil(t, proxyFunc) + assert.Assert(t, proxyFunc != nil) req, err := http.NewRequest("GET", splunkURL, nil) - require.NoError(t, err) + assert.NilError(t, err) proxyURL, err := proxyFunc(req) - require.NoError(t, err) - require.NotNil(t, proxyURL) - require.Equal(t, proxy, proxyURL.String()) + assert.NilError(t, err) + assert.Assert(t, proxyURL != nil) + assert.Equal(t, proxy, proxyURL.String()) } // Test default settings @@ -483,10 +483,10 @@ func TestRawFormat(t *testing.T) { } hostname, err := info.Hostname() - require.NoError(t, err) + assert.NilError(t, err) loggerDriver, err := New(info) - require.NoError(t, err) + assert.NilError(t, err) if !hec.connectionVerified { t.Fatal("By default connection should be verified") diff --git a/components/engine/daemon/logger/templates/templates_test.go b/components/engine/daemon/logger/templates/templates_test.go index 5e71d96f262..b767037477a 100644 --- a/components/engine/daemon/logger/templates/templates_test.go +++ b/components/engine/daemon/logger/templates/templates_test.go @@ -4,15 +4,16 @@ import ( "bytes" "testing" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestNewParse(t *testing.T) { tm, err := NewParse("foo", "this is a {{ . }}") - assert.NoError(t, err) + assert.Check(t, err) var b bytes.Buffer - assert.NoError(t, tm.Execute(&b, "string")) + assert.Check(t, tm.Execute(&b, "string")) want := "this is a string" - assert.Equal(t, want, b.String()) + assert.Check(t, is.Equal(want, b.String())) } diff --git a/components/engine/daemon/oci_linux_test.go b/components/engine/daemon/oci_linux_test.go index f6bda797457..5f2731b8d65 100644 --- a/components/engine/daemon/oci_linux_test.go +++ b/components/engine/daemon/oci_linux_test.go @@ -8,8 +8,8 @@ import ( "github.com/docker/docker/daemon/config" "github.com/docker/docker/oci" "github.com/docker/docker/pkg/idtools" - - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) // TestTmpfsDevShmNoDupMount checks that a user-specified /dev/shm tmpfs @@ -36,17 +36,17 @@ func TestTmpfsDevShmNoDupMount(t *testing.T) { // Mimick the code flow of daemon.createSpec(), enough to reproduce the issue ms, err := d.setupMounts(c) - assert.NoError(t, err) + assert.Check(t, err) ms = append(ms, c.IpcMounts()...) tmpfsMounts, err := c.TmpfsMounts() - assert.NoError(t, err) + assert.Check(t, err) ms = append(ms, tmpfsMounts...) s := oci.DefaultSpec() err = setMounts(&d, &s, c, ms) - assert.NoError(t, err) + assert.Check(t, err) } // TestIpcPrivateVsReadonly checks that in case of IpcMode: private @@ -70,19 +70,19 @@ func TestIpcPrivateVsReadonly(t *testing.T) { // We can't call createSpec() so mimick the minimal part // of its code flow, just enough to reproduce the issue. ms, err := d.setupMounts(c) - assert.NoError(t, err) + assert.Check(t, err) s := oci.DefaultSpec() s.Root.Readonly = c.HostConfig.ReadonlyRootfs err = setMounts(&d, &s, c, ms) - assert.NoError(t, err) + assert.Check(t, err) // Find the /dev/shm mount in ms, check it does not have ro for _, m := range s.Mounts { if m.Destination != "/dev/shm" { continue } - assert.Equal(t, false, inSlice(m.Options, "ro")) + assert.Check(t, is.Equal(false, inSlice(m.Options, "ro"))) } } diff --git a/components/engine/daemon/reload_test.go b/components/engine/daemon/reload_test.go index 83e86fc5a0b..2985602716d 100644 --- a/components/engine/daemon/reload_test.go +++ b/components/engine/daemon/reload_test.go @@ -11,7 +11,8 @@ import ( _ "github.com/docker/docker/pkg/discovery/memory" "github.com/docker/docker/registry" "github.com/docker/libnetwork" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestDaemonReloadLabels(t *testing.T) { @@ -93,7 +94,7 @@ func TestDaemonReloadAllowNondistributableArtifacts(t *testing.T) { sort.Strings(registries) sort.Strings(actual) - assert.Equal(t, registries, actual) + assert.Check(t, is.DeepEqual(registries, actual)) } func TestDaemonReloadMirrors(t *testing.T) { diff --git a/components/engine/daemon/trustkey_test.go b/components/engine/daemon/trustkey_test.go index c49341d2a9e..ebc7e28ee32 100644 --- a/components/engine/daemon/trustkey_test.go +++ b/components/engine/daemon/trustkey_test.go @@ -7,19 +7,19 @@ import ( "testing" "github.com/docker/docker/internal/testutil" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/fs" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) // LoadOrCreateTrustKey func TestLoadOrCreateTrustKeyInvalidKeyFile(t *testing.T) { tmpKeyFolderPath, err := ioutil.TempDir("", "api-trustkey-test") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(tmpKeyFolderPath) tmpKeyFile, err := ioutil.TempFile(tmpKeyFolderPath, "keyfile") - require.NoError(t, err) + assert.NilError(t, err) _, err = loadOrCreateTrustKey(tmpKeyFile.Name()) testutil.ErrorContains(t, err, "Error loading key file") @@ -33,11 +33,11 @@ func TestLoadOrCreateTrustKeyCreateKeyWhenFileDoesNotExist(t *testing.T) { tmpKeyFile := tmpKeyFolderPath.Join("keyfile") key, err := loadOrCreateTrustKey(tmpKeyFile) - require.NoError(t, err) - assert.NotNil(t, key) + assert.NilError(t, err) + assert.Check(t, key != nil) _, err = os.Stat(tmpKeyFile) - require.NoError(t, err, "key file doesn't exist") + assert.NilError(t, err, "key file doesn't exist") } func TestLoadOrCreateTrustKeyCreateKeyWhenDirectoryDoesNotExist(t *testing.T) { @@ -46,27 +46,27 @@ func TestLoadOrCreateTrustKeyCreateKeyWhenDirectoryDoesNotExist(t *testing.T) { tmpKeyFile := tmpKeyFolderPath.Join("folder/hierarchy/keyfile") key, err := loadOrCreateTrustKey(tmpKeyFile) - require.NoError(t, err) - assert.NotNil(t, key) + assert.NilError(t, err) + assert.Check(t, key != nil) _, err = os.Stat(tmpKeyFile) - require.NoError(t, err, "key file doesn't exist") + assert.NilError(t, err, "key file doesn't exist") } func TestLoadOrCreateTrustKeyCreateKeyNoPath(t *testing.T) { defer os.Remove("keyfile") key, err := loadOrCreateTrustKey("keyfile") - require.NoError(t, err) - assert.NotNil(t, key) + assert.NilError(t, err) + assert.Check(t, key != nil) _, err = os.Stat("keyfile") - require.NoError(t, err, "key file doesn't exist") + assert.NilError(t, err, "key file doesn't exist") } func TestLoadOrCreateTrustKeyLoadValidKey(t *testing.T) { tmpKeyFile := filepath.Join("testdata", "keyfile") key, err := loadOrCreateTrustKey(tmpKeyFile) - require.NoError(t, err) + assert.NilError(t, err) expected := "AWX2:I27X:WQFX:IOMK:CNAK:O7PW:VYNB:ZLKC:CVAE:YJP2:SI4A:XXAY" - assert.Contains(t, key.String(), expected) + assert.Check(t, is.Contains(key.String(), expected)) } diff --git a/components/engine/distribution/metadata/v1_id_service_test.go b/components/engine/distribution/metadata/v1_id_service_test.go index 8a3647b3b3c..7bac8e82123 100644 --- a/components/engine/distribution/metadata/v1_id_service_test.go +++ b/components/engine/distribution/metadata/v1_id_service_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/docker/docker/layer" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) func TestV1IDService(t *testing.T) { @@ -24,7 +24,7 @@ func TestV1IDService(t *testing.T) { ns := v1IDService.namespace() - require.Equal(t, "v1id", ns) + assert.Equal(t, "v1id", ns) testVectors := []struct { registry string diff --git a/components/engine/image/fs_test.go b/components/engine/image/fs_test.go index 6a634377e71..dcf4da75f8a 100644 --- a/components/engine/image/fs_test.go +++ b/components/engine/image/fs_test.go @@ -11,16 +11,17 @@ import ( "testing" "github.com/docker/docker/internal/testutil" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" digest "github.com/opencontainers/go-digest" - "github.com/stretchr/testify/assert" ) func defaultFSStoreBackend(t *testing.T) (StoreBackend, func()) { tmpdir, err := ioutil.TempDir("", "images-fs-store") - assert.NoError(t, err) + assert.Check(t, err) fsBackend, err := NewFSStoreBackend(tmpdir) - assert.NoError(t, err) + assert.Check(t, err) return fsBackend, func() { os.RemoveAll(tmpdir) } } @@ -30,12 +31,12 @@ func TestFSGetInvalidData(t *testing.T) { defer cleanup() id, err := store.Set([]byte("foobar")) - assert.NoError(t, err) + assert.Check(t, err) dgst := digest.Digest(id) err = ioutil.WriteFile(filepath.Join(store.(*fs).root, contentDirName, string(dgst.Algorithm()), dgst.Hex()), []byte("foobar2"), 0600) - assert.NoError(t, err) + assert.Check(t, err) _, err = store.Get(id) testutil.ErrorContains(t, err, "failed to verify") @@ -47,7 +48,7 @@ func TestFSInvalidSet(t *testing.T) { id := digest.FromBytes([]byte("foobar")) err := os.Mkdir(filepath.Join(store.(*fs).root, contentDirName, string(id.Algorithm()), id.Hex()), 0700) - assert.NoError(t, err) + assert.Check(t, err) _, err = store.Set([]byte("foobar")) testutil.ErrorContains(t, err, "failed to write digest data") @@ -55,7 +56,7 @@ func TestFSInvalidSet(t *testing.T) { func TestFSInvalidRoot(t *testing.T) { tmpdir, err := ioutil.TempDir("", "images-fs-store") - assert.NoError(t, err) + assert.Check(t, err) defer os.RemoveAll(tmpdir) tcases := []struct { @@ -70,10 +71,10 @@ func TestFSInvalidRoot(t *testing.T) { root := filepath.Join(tmpdir, tc.root) filePath := filepath.Join(tmpdir, tc.invalidFile) err := os.MkdirAll(filepath.Dir(filePath), 0700) - assert.NoError(t, err) + assert.Check(t, err) f, err := os.Create(filePath) - assert.NoError(t, err) + assert.Check(t, err) f.Close() _, err = NewFSStoreBackend(root) @@ -89,10 +90,10 @@ func TestFSMetadataGetSet(t *testing.T) { defer cleanup() id, err := store.Set([]byte("foo")) - assert.NoError(t, err) + assert.Check(t, err) id2, err := store.Set([]byte("bar")) - assert.NoError(t, err) + assert.Check(t, err) tcases := []struct { id digest.Digest @@ -106,12 +107,12 @@ func TestFSMetadataGetSet(t *testing.T) { for _, tc := range tcases { err = store.SetMetadata(tc.id, tc.key, tc.value) - assert.NoError(t, err) + assert.Check(t, err) actual, err := store.GetMetadata(tc.id, tc.key) - assert.NoError(t, err) + assert.Check(t, err) - assert.Equal(t, tc.value, actual) + assert.Check(t, is.DeepEqual(tc.value, actual)) } _, err = store.GetMetadata(id2, "tkey2") @@ -130,19 +131,19 @@ func TestFSInvalidWalker(t *testing.T) { defer cleanup() fooID, err := store.Set([]byte("foo")) - assert.NoError(t, err) + assert.Check(t, err) err = ioutil.WriteFile(filepath.Join(store.(*fs).root, contentDirName, "sha256/foobar"), []byte("foobar"), 0600) - assert.NoError(t, err) + assert.Check(t, err) n := 0 err = store.Walk(func(id digest.Digest) error { - assert.Equal(t, fooID, id) + assert.Check(t, is.Equal(fooID, id)) n++ return nil }) - assert.NoError(t, err) - assert.Equal(t, 1, n) + assert.Check(t, err) + assert.Check(t, is.Equal(1, n)) } func TestFSGetSet(t *testing.T) { @@ -159,12 +160,12 @@ func TestFSGetSet(t *testing.T) { randomInput := make([]byte, 8*1024) _, err := rand.Read(randomInput) - assert.NoError(t, err) + assert.Check(t, err) // skipping use of digest pkg because it is used by the implementation h := sha256.New() _, err = h.Write(randomInput) - assert.NoError(t, err) + assert.Check(t, err) tcases = append(tcases, tcase{ input: randomInput, @@ -173,14 +174,14 @@ func TestFSGetSet(t *testing.T) { for _, tc := range tcases { id, err := store.Set([]byte(tc.input)) - assert.NoError(t, err) - assert.Equal(t, tc.expected, id) + assert.Check(t, err) + assert.Check(t, is.Equal(tc.expected, id)) } for _, tc := range tcases { data, err := store.Get(tc.expected) - assert.NoError(t, err) - assert.Equal(t, tc.input, data) + assert.Check(t, err) + assert.Check(t, is.DeepEqual(tc.input, data)) } } @@ -209,22 +210,22 @@ func TestFSDelete(t *testing.T) { defer cleanup() id, err := store.Set([]byte("foo")) - assert.NoError(t, err) + assert.Check(t, err) id2, err := store.Set([]byte("bar")) - assert.NoError(t, err) + assert.Check(t, err) err = store.Delete(id) - assert.NoError(t, err) + assert.Check(t, err) _, err = store.Get(id) testutil.ErrorContains(t, err, "failed to get digest") _, err = store.Get(id2) - assert.NoError(t, err) + assert.Check(t, err) err = store.Delete(id2) - assert.NoError(t, err) + assert.Check(t, err) _, err = store.Get(id2) testutil.ErrorContains(t, err, "failed to get digest") @@ -235,10 +236,10 @@ func TestFSWalker(t *testing.T) { defer cleanup() id, err := store.Set([]byte("foo")) - assert.NoError(t, err) + assert.Check(t, err) id2, err := store.Set([]byte("bar")) - assert.NoError(t, err) + assert.Check(t, err) tcases := make(map[digest.Digest]struct{}) tcases[id] = struct{}{} @@ -249,9 +250,9 @@ func TestFSWalker(t *testing.T) { n++ return nil }) - assert.NoError(t, err) - assert.Equal(t, 2, n) - assert.Len(t, tcases, 0) + assert.Check(t, err) + assert.Check(t, is.Equal(2, n)) + assert.Check(t, is.Len(tcases, 0)) } func TestFSWalkerStopOnError(t *testing.T) { @@ -259,7 +260,7 @@ func TestFSWalkerStopOnError(t *testing.T) { defer cleanup() id, err := store.Set([]byte("foo")) - assert.NoError(t, err) + assert.Check(t, err) tcases := make(map[digest.Digest]struct{}) tcases[id] = struct{}{} diff --git a/components/engine/image/image_test.go b/components/engine/image/image_test.go index 429f2029782..265db0167c7 100644 --- a/components/engine/image/image_test.go +++ b/components/engine/image/image_test.go @@ -9,8 +9,8 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/layer" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) const sampleImageJSON = `{ @@ -25,13 +25,13 @@ const sampleImageJSON = `{ func TestNewFromJSON(t *testing.T) { img, err := NewFromJSON([]byte(sampleImageJSON)) - require.NoError(t, err) - assert.Equal(t, sampleImageJSON, string(img.RawJSON())) + assert.NilError(t, err) + assert.Check(t, is.Equal(sampleImageJSON, string(img.RawJSON()))) } func TestNewFromJSONWithInvalidJSON(t *testing.T) { _, err := NewFromJSON([]byte("{}")) - assert.EqualError(t, err, "invalid image JSON, no RootFS key") + assert.Check(t, is.Error(err, "invalid image JSON, no RootFS key")) } func TestMarshalKeyOrder(t *testing.T) { @@ -42,7 +42,7 @@ func TestMarshalKeyOrder(t *testing.T) { Architecture: "c", }, }) - assert.NoError(t, err) + assert.Check(t, err) expectedOrder := []string{"architecture", "author", "comment"} var indexes []int @@ -71,10 +71,10 @@ func TestImage(t *testing.T) { computedID: ID(cid), } - assert.Equal(t, cid, img.ImageID()) - assert.Equal(t, cid, img.ID().String()) - assert.Equal(t, os, img.OperatingSystem()) - assert.Equal(t, config, img.RunConfig()) + assert.Check(t, is.Equal(cid, img.ImageID())) + assert.Check(t, is.Equal(cid, img.ID().String())) + assert.Check(t, is.Equal(os, img.OperatingSystem())) + assert.Check(t, is.DeepEqual(config, img.RunConfig())) } func TestImageOSNotEmpty(t *testing.T) { @@ -85,7 +85,7 @@ func TestImageOSNotEmpty(t *testing.T) { }, OSVersion: "osversion", } - assert.Equal(t, os, img.OperatingSystem()) + assert.Check(t, is.Equal(os, img.OperatingSystem())) } func TestNewChildImageFromImageWithRootFS(t *testing.T) { @@ -109,16 +109,16 @@ func TestNewChildImageFromImageWithRootFS(t *testing.T) { newImage := NewChildImage(parent, childConfig, "platform") expectedDiffIDs := []layer.DiffID{layer.DiffID("ba5e"), layer.DiffID("abcdef")} - assert.Equal(t, expectedDiffIDs, newImage.RootFS.DiffIDs) - assert.Equal(t, childConfig.Author, newImage.Author) - assert.Equal(t, childConfig.Config, newImage.Config) - assert.Equal(t, *childConfig.ContainerConfig, newImage.ContainerConfig) - assert.Equal(t, "platform", newImage.OS) - assert.Equal(t, childConfig.Config, newImage.Config) + assert.Check(t, is.DeepEqual(expectedDiffIDs, newImage.RootFS.DiffIDs)) + assert.Check(t, is.Equal(childConfig.Author, newImage.Author)) + assert.Check(t, is.DeepEqual(childConfig.Config, newImage.Config)) + assert.Check(t, is.DeepEqual(*childConfig.ContainerConfig, newImage.ContainerConfig)) + assert.Check(t, is.Equal("platform", newImage.OS)) + assert.Check(t, is.DeepEqual(childConfig.Config, newImage.Config)) - assert.Len(t, newImage.History, 2) - assert.Equal(t, childConfig.Comment, newImage.History[1].Comment) + assert.Check(t, is.Len(newImage.History, 2)) + assert.Check(t, is.Equal(childConfig.Comment, newImage.History[1].Comment)) // RootFS should be copied not mutated - assert.NotEqual(t, parent.RootFS.DiffIDs, newImage.RootFS.DiffIDs) + assert.Check(t, parent.RootFS.DiffIDs != newImage.RootFS.DiffIDs) } diff --git a/components/engine/image/store_test.go b/components/engine/image/store_test.go index ff40f7ea22c..73737656f60 100644 --- a/components/engine/image/store_test.go +++ b/components/engine/image/store_test.go @@ -6,8 +6,9 @@ import ( "github.com/docker/docker/internal/testutil" "github.com/docker/docker/layer" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/opencontainers/go-digest" - "github.com/stretchr/testify/assert" ) func TestRestore(t *testing.T) { @@ -15,53 +16,53 @@ func TestRestore(t *testing.T) { defer cleanup() id1, err := fs.Set([]byte(`{"comment": "abc", "rootfs": {"type": "layers"}}`)) - assert.NoError(t, err) + assert.Check(t, err) _, err = fs.Set([]byte(`invalid`)) - assert.NoError(t, err) + assert.Check(t, err) id2, err := fs.Set([]byte(`{"comment": "def", "rootfs": {"type": "layers", "diff_ids": ["2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"]}}`)) - assert.NoError(t, err) + assert.Check(t, err) err = fs.SetMetadata(id2, "parent", []byte(id1)) - assert.NoError(t, err) + assert.Check(t, err) mlgrMap := make(map[string]LayerGetReleaser) mlgrMap[runtime.GOOS] = &mockLayerGetReleaser{} is, err := NewImageStore(fs, mlgrMap) - assert.NoError(t, err) + assert.Check(t, err) - assert.Len(t, is.Map(), 2) + assert.Check(t, is.Len(is.Map(), 2)) img1, err := is.Get(ID(id1)) - assert.NoError(t, err) - assert.Equal(t, ID(id1), img1.computedID) - assert.Equal(t, string(id1), img1.computedID.String()) + assert.Check(t, err) + assert.Check(t, is.Equal(ID(id1), img1.computedID)) + assert.Check(t, is.Equal(string(id1), img1.computedID.String())) img2, err := is.Get(ID(id2)) - assert.NoError(t, err) - assert.Equal(t, "abc", img1.Comment) - assert.Equal(t, "def", img2.Comment) + assert.Check(t, err) + assert.Check(t, is.Equal("abc", img1.Comment)) + assert.Check(t, is.Equal("def", img2.Comment)) _, err = is.GetParent(ID(id1)) testutil.ErrorContains(t, err, "failed to read metadata") p, err := is.GetParent(ID(id2)) - assert.NoError(t, err) - assert.Equal(t, ID(id1), p) + assert.Check(t, err) + assert.Check(t, is.Equal(ID(id1), p)) children := is.Children(ID(id1)) - assert.Len(t, children, 1) - assert.Equal(t, ID(id2), children[0]) - assert.Len(t, is.Heads(), 1) + assert.Check(t, is.Len(children, 1)) + assert.Check(t, is.Equal(ID(id2), children[0])) + assert.Check(t, is.Len(is.Heads(), 1)) sid1, err := is.Search(string(id1)[:10]) - assert.NoError(t, err) - assert.Equal(t, ID(id1), sid1) + assert.Check(t, err) + assert.Check(t, is.Equal(ID(id1), sid1)) sid1, err = is.Search(digest.Digest(id1).Hex()[:6]) - assert.NoError(t, err) - assert.Equal(t, ID(id1), sid1) + assert.Check(t, err) + assert.Check(t, is.Equal(ID(id1), sid1)) invalidPattern := digest.Digest(id1).Hex()[1:6] _, err = is.Search(invalidPattern) @@ -73,31 +74,31 @@ func TestAddDelete(t *testing.T) { defer cleanup() id1, err := is.Create([]byte(`{"comment": "abc", "rootfs": {"type": "layers", "diff_ids": ["2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"]}}`)) - assert.NoError(t, err) - assert.Equal(t, ID("sha256:8d25a9c45df515f9d0fe8e4a6b1c64dd3b965a84790ddbcc7954bb9bc89eb993"), id1) + assert.Check(t, err) + assert.Check(t, is.Equal(ID("sha256:8d25a9c45df515f9d0fe8e4a6b1c64dd3b965a84790ddbcc7954bb9bc89eb993"), id1)) img, err := is.Get(id1) - assert.NoError(t, err) - assert.Equal(t, "abc", img.Comment) + assert.Check(t, err) + assert.Check(t, is.Equal("abc", img.Comment)) id2, err := is.Create([]byte(`{"comment": "def", "rootfs": {"type": "layers", "diff_ids": ["2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"]}}`)) - assert.NoError(t, err) + assert.Check(t, err) err = is.SetParent(id2, id1) - assert.NoError(t, err) + assert.Check(t, err) pid1, err := is.GetParent(id2) - assert.NoError(t, err) - assert.Equal(t, pid1, id1) + assert.Check(t, err) + assert.Check(t, is.Equal(pid1, id1)) _, err = is.Delete(id1) - assert.NoError(t, err) + assert.Check(t, err) _, err = is.Get(id1) testutil.ErrorContains(t, err, "failed to get digest") _, err = is.Get(id2) - assert.NoError(t, err) + assert.Check(t, err) _, err = is.GetParent(id2) testutil.ErrorContains(t, err, "failed to read metadata") @@ -108,14 +109,14 @@ func TestSearchAfterDelete(t *testing.T) { defer cleanup() id, err := is.Create([]byte(`{"comment": "abc", "rootfs": {"type": "layers"}}`)) - assert.NoError(t, err) + assert.Check(t, err) id1, err := is.Search(string(id)[:15]) - assert.NoError(t, err) - assert.Equal(t, id1, id) + assert.Check(t, err) + assert.Check(t, is.Equal(id1, id)) _, err = is.Delete(id) - assert.NoError(t, err) + assert.Check(t, err) _, err = is.Search(string(id)[:15]) testutil.ErrorContains(t, err, "No such image") @@ -126,20 +127,20 @@ func TestParentReset(t *testing.T) { defer cleanup() id, err := is.Create([]byte(`{"comment": "abc1", "rootfs": {"type": "layers"}}`)) - assert.NoError(t, err) + assert.Check(t, err) id2, err := is.Create([]byte(`{"comment": "abc2", "rootfs": {"type": "layers"}}`)) - assert.NoError(t, err) + assert.Check(t, err) id3, err := is.Create([]byte(`{"comment": "abc3", "rootfs": {"type": "layers"}}`)) - assert.NoError(t, err) + assert.Check(t, err) - assert.NoError(t, is.SetParent(id, id2)) - assert.Len(t, is.Children(id2), 1) + assert.Check(t, is.SetParent(id, id2)) + assert.Check(t, is.Len(is.Children(id2), 1)) - assert.NoError(t, is.SetParent(id, id3)) - assert.Len(t, is.Children(id2), 0) - assert.Len(t, is.Children(id3), 1) + assert.Check(t, is.SetParent(id, id3)) + assert.Check(t, is.Len(is.Children(id2), 0)) + assert.Check(t, is.Len(is.Children(id3), 1)) } func defaultImageStore(t *testing.T) (Store, func()) { @@ -148,7 +149,7 @@ func defaultImageStore(t *testing.T) (Store, func()) { mlgrMap := make(map[string]LayerGetReleaser) mlgrMap[runtime.GOOS] = &mockLayerGetReleaser{} store, err := NewImageStore(fsBackend, mlgrMap) - assert.NoError(t, err) + assert.Check(t, err) return store, cleanup } @@ -158,17 +159,17 @@ func TestGetAndSetLastUpdated(t *testing.T) { defer cleanup() id, err := store.Create([]byte(`{"comment": "abc1", "rootfs": {"type": "layers"}}`)) - assert.NoError(t, err) + assert.Check(t, err) updated, err := store.GetLastUpdated(id) - assert.NoError(t, err) - assert.Equal(t, updated.IsZero(), true) + assert.Check(t, err) + assert.Check(t, is.Equal(updated.IsZero(), true)) - assert.NoError(t, store.SetLastUpdated(id)) + assert.Check(t, store.SetLastUpdated(id)) updated, err = store.GetLastUpdated(id) - assert.NoError(t, err) - assert.Equal(t, updated.IsZero(), false) + assert.Check(t, err) + assert.Check(t, is.Equal(updated.IsZero(), false)) } type mockLayerGetReleaser struct{} diff --git a/components/engine/integration-cli/cli/build/fakegit/fakegit.go b/components/engine/integration-cli/cli/build/fakegit/fakegit.go index eb175365a50..b05bfc322bd 100644 --- a/components/engine/integration-cli/cli/build/fakegit/fakegit.go +++ b/components/engine/integration-cli/cli/build/fakegit/fakegit.go @@ -11,11 +11,11 @@ import ( "github.com/docker/docker/integration-cli/cli/build/fakecontext" "github.com/docker/docker/integration-cli/cli/build/fakestorage" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) type testingT interface { - require.TestingT + assert.TestingT logT Fatal(args ...interface{}) Fatalf(string, ...interface{}) diff --git a/components/engine/integration-cli/cli/build/fakestorage/storage.go b/components/engine/integration-cli/cli/build/fakestorage/storage.go index c8c837ed2ac..bd49a33cfe6 100644 --- a/components/engine/integration-cli/cli/build/fakestorage/storage.go +++ b/components/engine/integration-cli/cli/build/fakestorage/storage.go @@ -15,13 +15,13 @@ import ( "github.com/docker/docker/integration-cli/request" "github.com/docker/docker/internal/test/environment" "github.com/docker/docker/internal/testutil" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) var testEnv *environment.Execution type testingT interface { - require.TestingT + assert.TestingT logT Fatal(args ...interface{}) Fatalf(string, ...interface{}) diff --git a/components/engine/integration-cli/daemon/daemon.go b/components/engine/integration-cli/daemon/daemon.go index 9672d160f87..9ca54236f48 100644 --- a/components/engine/integration-cli/daemon/daemon.go +++ b/components/engine/integration-cli/daemon/daemon.go @@ -24,14 +24,14 @@ import ( "github.com/docker/go-connections/sockets" "github.com/docker/go-connections/tlsconfig" "github.com/go-check/check" + "github.com/gotestyourself/gotestyourself/assert" "github.com/gotestyourself/gotestyourself/icmd" "github.com/pkg/errors" - "github.com/stretchr/testify/require" "golang.org/x/net/context" ) type testingT interface { - require.TestingT + assert.TestingT logT Fatalf(string, ...interface{}) } @@ -487,20 +487,20 @@ func (d *Daemon) handleUserns() { // LoadBusybox image into the daemon func (d *Daemon) LoadBusybox(t testingT) { clientHost, err := client.NewEnvClient() - require.NoError(t, err, "failed to create client") + assert.NilError(t, err, "failed to create client") defer clientHost.Close() ctx := context.Background() reader, err := clientHost.ImageSave(ctx, []string{"busybox:latest"}) - require.NoError(t, err, "failed to download busybox") + assert.NilError(t, err, "failed to download busybox") defer reader.Close() client, err := d.NewClient() - require.NoError(t, err, "failed to create client") + assert.NilError(t, err, "failed to create client") defer client.Close() resp, err := client.ImageLoad(ctx, reader, true) - require.NoError(t, err, "failed to load busybox") + assert.NilError(t, err, "failed to load busybox") defer resp.Body.Close() } @@ -563,11 +563,11 @@ func (d *Daemon) WaitRun(contID string) error { } // Info returns the info struct for this daemon -func (d *Daemon) Info(t require.TestingT) types.Info { +func (d *Daemon) Info(t assert.TestingT) types.Info { apiclient, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - require.NoError(t, err) + assert.NilError(t, err) info, err := apiclient.Info(context.Background()) - require.NoError(t, err) + assert.NilError(t, err) return info } diff --git a/components/engine/integration-cli/daemon/daemon_swarm.go b/components/engine/integration-cli/daemon/daemon_swarm.go index cb44f63f23c..be0ddef99e8 100644 --- a/components/engine/integration-cli/daemon/daemon_swarm.go +++ b/components/engine/integration-cli/daemon/daemon_swarm.go @@ -11,8 +11,8 @@ import ( "github.com/docker/docker/client" "github.com/docker/docker/integration-cli/checker" "github.com/go-check/check" + "github.com/gotestyourself/gotestyourself/assert" "github.com/pkg/errors" - "github.com/stretchr/testify/require" "golang.org/x/net/context" ) @@ -235,12 +235,12 @@ func (d *Swarm) CheckServiceUpdateState(service string) func(*check.C) (interfac func (d *Swarm) CheckPluginRunning(plugin string) func(c *check.C) (interface{}, check.CommentInterface) { return func(c *check.C) (interface{}, check.CommentInterface) { apiclient, err := d.NewClient() - require.NoError(c, err) + assert.NilError(c, err) resp, _, err := apiclient.PluginInspectWithRaw(context.Background(), plugin) if client.IsErrNotFound(err) { return false, check.Commentf("%v", err) } - require.NoError(c, err) + assert.NilError(c, err) return resp.Enabled, check.Commentf("%+v", resp) } } @@ -249,12 +249,12 @@ func (d *Swarm) CheckPluginRunning(plugin string) func(c *check.C) (interface{}, func (d *Swarm) CheckPluginImage(plugin string) func(c *check.C) (interface{}, check.CommentInterface) { return func(c *check.C) (interface{}, check.CommentInterface) { apiclient, err := d.NewClient() - require.NoError(c, err) + assert.NilError(c, err) resp, _, err := apiclient.PluginInspectWithRaw(context.Background(), plugin) if client.IsErrNotFound(err) { return false, check.Commentf("%v", err) } - require.NoError(c, err) + assert.NilError(c, err) return resp.PluginReference, check.Commentf("%+v", resp) } } diff --git a/components/engine/integration-cli/docker_api_build_test.go b/components/engine/integration-cli/docker_api_build_test.go index e5423a4741f..cae7c1afe74 100644 --- a/components/engine/integration-cli/docker_api_build_test.go +++ b/components/engine/integration-cli/docker_api_build_test.go @@ -18,10 +18,10 @@ import ( "github.com/docker/docker/integration-cli/cli/build/fakestorage" "github.com/docker/docker/integration-cli/request" "github.com/go-check/check" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/moby/buildkit/session" "github.com/moby/buildkit/session/filesync" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "golang.org/x/net/context" "golang.org/x/sync/errgroup" ) @@ -296,12 +296,12 @@ func (s *DockerSuite) TestBuildOnBuildCache(c *check.C) { "/build", request.RawContent(ctx.AsTarReader(c)), request.ContentType("application/x-tar")) - require.NoError(c, err) - assert.Equal(c, http.StatusOK, res.StatusCode) + assert.NilError(c, err) + assert.Check(c, is.DeepEqual(http.StatusOK, res.StatusCode)) out, err := request.ReadBody(body) - require.NoError(c, err) - assert.Contains(c, string(out), "Successfully built") + assert.NilError(c, err) + assert.Check(c, is.Contains(string(out), "Successfully built")) return out } @@ -316,15 +316,15 @@ func (s *DockerSuite) TestBuildOnBuildCache(c *check.C) { out := build(dockerfile) imageIDs := getImageIDsFromBuild(c, out) - assert.Len(c, imageIDs, 2) + assert.Check(c, is.Len(imageIDs, 2)) parentID, childID := imageIDs[0], imageIDs[1] client := testEnv.APIClient() // check parentID is correct image, _, err := client.ImageInspectWithRaw(context.Background(), childID) - require.NoError(c, err) - assert.Equal(c, parentID, image.Parent) + assert.NilError(c, err) + assert.Check(c, is.Equal(parentID, image.Parent)) } func (s *DockerRegistrySuite) TestBuildCopyFromForcePull(c *check.C) { @@ -333,12 +333,12 @@ func (s *DockerRegistrySuite) TestBuildCopyFromForcePull(c *check.C) { repoName := fmt.Sprintf("%v/dockercli/busybox", privateRegistryURL) // tag the image to upload it to the private registry err := client.ImageTag(context.TODO(), "busybox", repoName) - assert.Nil(c, err) + assert.Check(c, err) // push the image to the registry rc, err := client.ImagePush(context.TODO(), repoName, types.ImagePushOptions{RegistryAuth: "{}"}) - assert.Nil(c, err) + assert.Check(c, err) _, err = io.Copy(ioutil.Discard, rc) - assert.Nil(c, err) + assert.Check(c, err) dockerfile := fmt.Sprintf(` FROM %s AS foo @@ -356,12 +356,12 @@ func (s *DockerRegistrySuite) TestBuildCopyFromForcePull(c *check.C) { "/build?pull=1", request.RawContent(ctx.AsTarReader(c)), request.ContentType("application/x-tar")) - require.NoError(c, err) - assert.Equal(c, http.StatusOK, res.StatusCode) + assert.NilError(c, err) + assert.Check(c, is.DeepEqual(http.StatusOK, res.StatusCode)) out, err := request.ReadBody(body) - require.NoError(c, err) - assert.Contains(c, string(out), "Successfully built") + assert.NilError(c, err) + assert.Check(c, is.Contains(string(out), "Successfully built")) } func (s *DockerSuite) TestBuildAddRemoteNoDecompress(c *check.C) { @@ -374,11 +374,11 @@ func (s *DockerSuite) TestBuildAddRemoteNoDecompress(c *check.C) { Mode: 0600, Typeflag: tar.TypeReg, }) - require.NoError(c, err) + assert.NilError(c, err) _, err = tw.Write(dt) - require.NoError(c, err) + assert.NilError(c, err) err = tw.Close() - require.NoError(c, err) + assert.NilError(c, err) server := fakestorage.New(c, "", fakecontext.WithBinaryFiles(map[string]*bytes.Buffer{ "test.tar": buffer, @@ -400,12 +400,12 @@ func (s *DockerSuite) TestBuildAddRemoteNoDecompress(c *check.C) { "/build", request.RawContent(ctx.AsTarReader(c)), request.ContentType("application/x-tar")) - require.NoError(c, err) - assert.Equal(c, http.StatusOK, res.StatusCode) + assert.NilError(c, err) + assert.Check(c, is.DeepEqual(http.StatusOK, res.StatusCode)) out, err := request.ReadBody(body) - require.NoError(c, err) - assert.Contains(c, string(out), "Successfully built") + assert.NilError(c, err) + assert.Check(c, is.Contains(string(out), "Successfully built")) } func (s *DockerSuite) TestBuildChownOnCopy(c *check.C) { @@ -433,8 +433,8 @@ func (s *DockerSuite) TestBuildChownOnCopy(c *check.C) { c.Assert(res.StatusCode, checker.Equals, http.StatusOK) out, err := request.ReadBody(body) - require.NoError(c, err) - assert.Contains(c, string(out), "Successfully built") + assert.NilError(c, err) + assert.Check(c, is.Contains(string(out), "Successfully built")) } func (s *DockerSuite) TestBuildCopyCacheOnFileChange(c *check.C) { @@ -454,11 +454,11 @@ COPY file /file` request.RawContent(ctx.AsTarReader(c)), request.ContentType("application/x-tar")) - require.NoError(c, err) - assert.Equal(c, http.StatusOK, res.StatusCode) + assert.NilError(c, err) + assert.Check(c, is.DeepEqual(http.StatusOK, res.StatusCode)) out, err := request.ReadBody(body) - require.NoError(c, err) + assert.NilError(c, err) ids := getImageIDsFromBuild(c, out) return ids[len(ids)-1] @@ -493,11 +493,11 @@ ADD file /file` request.RawContent(ctx.AsTarReader(c)), request.ContentType("application/x-tar")) - require.NoError(c, err) - assert.Equal(c, http.StatusOK, res.StatusCode) + assert.NilError(c, err) + assert.Check(c, is.DeepEqual(http.StatusOK, res.StatusCode)) out, err := request.ReadBody(body) - require.NoError(c, err) + assert.NilError(c, err) ids := getImageIDsFromBuild(c, out) return ids[len(ids)-1] @@ -530,7 +530,7 @@ func (s *DockerSuite) TestBuildWithSession(c *check.C) { defer fctx.Close() out := testBuildWithSession(c, fctx.Dir, dockerfile) - assert.Contains(c, out, "some content") + assert.Check(c, is.Contains(out, "some content")) fctx.Add("second", "contentcontent") @@ -540,20 +540,20 @@ func (s *DockerSuite) TestBuildWithSession(c *check.C) { ` out = testBuildWithSession(c, fctx.Dir, dockerfile) - assert.Equal(c, strings.Count(out, "Using cache"), 2) - assert.Contains(c, out, "contentcontent") + assert.Check(c, is.Equal(strings.Count(out, "Using cache"), 2)) + assert.Check(c, is.Contains(out, "contentcontent")) client := testEnv.APIClient() du, err := client.DiskUsage(context.TODO()) - assert.Nil(c, err) - assert.True(c, du.BuilderSize > 10) + assert.Check(c, err) + assert.Check(c, du.BuilderSize > 10) out = testBuildWithSession(c, fctx.Dir, dockerfile) - assert.Equal(c, strings.Count(out, "Using cache"), 4) + assert.Check(c, is.Equal(strings.Count(out, "Using cache"), 4)) du2, err := client.DiskUsage(context.TODO()) - assert.Nil(c, err) - assert.Equal(c, du.BuilderSize, du2.BuilderSize) + assert.Check(c, err) + assert.Check(c, is.Equal(du.BuilderSize, du2.BuilderSize)) // rebuild with regular tar, confirm cache still applies fctx.Add("Dockerfile", dockerfile) @@ -561,26 +561,26 @@ func (s *DockerSuite) TestBuildWithSession(c *check.C) { "/build", request.RawContent(fctx.AsTarReader(c)), request.ContentType("application/x-tar")) - require.NoError(c, err) - assert.Equal(c, http.StatusOK, res.StatusCode) + assert.NilError(c, err) + assert.Check(c, is.DeepEqual(http.StatusOK, res.StatusCode)) outBytes, err := request.ReadBody(body) - require.NoError(c, err) - assert.Contains(c, string(outBytes), "Successfully built") - assert.Equal(c, strings.Count(string(outBytes), "Using cache"), 4) + assert.NilError(c, err) + assert.Check(c, is.Contains(string(outBytes), "Successfully built")) + assert.Check(c, is.Equal(strings.Count(string(outBytes), "Using cache"), 4)) _, err = client.BuildCachePrune(context.TODO()) - assert.Nil(c, err) + assert.Check(c, err) du, err = client.DiskUsage(context.TODO()) - assert.Nil(c, err) - assert.Equal(c, du.BuilderSize, int64(0)) + assert.Check(c, err) + assert.Check(c, is.Equal(du.BuilderSize, int64(0))) } func testBuildWithSession(c *check.C, dir, dockerfile string) (outStr string) { client := testEnv.APIClient() sess, err := session.NewSession("foo1", "foo") - assert.Nil(c, err) + assert.Check(c, err) fsProvider := filesync.NewFSSyncProvider([]filesync.SyncedDir{ {Dir: dir}, @@ -601,17 +601,17 @@ func testBuildWithSession(c *check.C, dir, dockerfile string) (outStr string) { if err != nil { return err } - assert.Equal(c, res.StatusCode, http.StatusOK) + assert.Check(c, is.DeepEqual(res.StatusCode, http.StatusOK)) out, err := request.ReadBody(body) - require.NoError(c, err) - assert.Contains(c, string(out), "Successfully built") + assert.NilError(c, err) + assert.Check(c, is.Contains(string(out), "Successfully built")) sess.Close() outStr = string(out) return nil }) err = g.Wait() - assert.Nil(c, err) + assert.Check(c, err) return } @@ -633,8 +633,8 @@ ENV foo bar` c.Assert(res.StatusCode, checker.Equals, http.StatusOK) out, err := request.ReadBody(body) - require.NoError(c, err) - assert.Contains(c, string(out), "Successfully built") + assert.NilError(c, err) + assert.Check(c, is.Contains(string(out), "Successfully built")) } type buildLine struct { @@ -651,7 +651,7 @@ func getImageIDsFromBuild(c *check.C, output []byte) []string { continue } entry := buildLine{} - require.NoError(c, json.Unmarshal(line, &entry)) + assert.NilError(c, json.Unmarshal(line, &entry)) if entry.Aux.ID != "" { ids = append(ids, entry.Aux.ID) } diff --git a/components/engine/integration-cli/docker_api_containers_test.go b/components/engine/integration-cli/docker_api_containers_test.go index a91c91abe5d..76dcedb6766 100644 --- a/components/engine/integration-cli/docker_api_containers_test.go +++ b/components/engine/integration-cli/docker_api_containers_test.go @@ -31,9 +31,9 @@ import ( "github.com/docker/docker/volume" "github.com/docker/go-connections/nat" "github.com/go-check/check" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/poll" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "golang.org/x/net/context" ) @@ -2027,47 +2027,47 @@ func (s *DockerSuite) TestContainersAPICreateMountsCreate(c *check.C) { &containertypes.HostConfig{Mounts: []mounttypes.Mount{x.spec}}, &networktypes.NetworkingConfig{}, "") - require.NoError(c, err) + assert.NilError(c, err) containerInspect, err := apiclient.ContainerInspect(ctx, container.ID) - require.NoError(c, err) + assert.NilError(c, err) mps := containerInspect.Mounts - require.Len(c, mps, 1) + assert.Assert(c, is.Len(mps, 1)) mountPoint := mps[0] if x.expected.Source != "" { - assert.Equal(c, x.expected.Source, mountPoint.Source) + assert.Check(c, is.Equal(x.expected.Source, mountPoint.Source)) } if x.expected.Name != "" { - assert.Equal(c, x.expected.Name, mountPoint.Name) + assert.Check(c, is.Equal(x.expected.Name, mountPoint.Name)) } if x.expected.Driver != "" { - assert.Equal(c, x.expected.Driver, mountPoint.Driver) + assert.Check(c, is.Equal(x.expected.Driver, mountPoint.Driver)) } if x.expected.Propagation != "" { - assert.Equal(c, x.expected.Propagation, mountPoint.Propagation) + assert.Check(c, is.Equal(x.expected.Propagation, mountPoint.Propagation)) } - assert.Equal(c, x.expected.RW, mountPoint.RW) - assert.Equal(c, x.expected.Type, mountPoint.Type) - assert.Equal(c, x.expected.Mode, mountPoint.Mode) - assert.Equal(c, x.expected.Destination, mountPoint.Destination) + assert.Check(c, is.Equal(x.expected.RW, mountPoint.RW)) + assert.Check(c, is.Equal(x.expected.Type, mountPoint.Type)) + assert.Check(c, is.Equal(x.expected.Mode, mountPoint.Mode)) + assert.Check(c, is.Equal(x.expected.Destination, mountPoint.Destination)) err = apiclient.ContainerStart(ctx, container.ID, types.ContainerStartOptions{}) - require.NoError(c, err) + assert.NilError(c, err) poll.WaitOn(c, containerExit(apiclient, container.ID), poll.WithDelay(time.Second)) err = apiclient.ContainerRemove(ctx, container.ID, types.ContainerRemoveOptions{ RemoveVolumes: true, Force: true, }) - require.NoError(c, err) + assert.NilError(c, err) switch { // Named volumes still exist after the container is removed case x.spec.Type == "volume" && len(x.spec.Source) > 0: _, err := apiclient.VolumeInspect(ctx, mountPoint.Name) - require.NoError(c, err) + assert.NilError(c, err) // Bind mounts are never removed with the container case x.spec.Type == "bind": @@ -2075,7 +2075,7 @@ func (s *DockerSuite) TestContainersAPICreateMountsCreate(c *check.C) { // anonymous volumes are removed default: _, err := apiclient.VolumeInspect(ctx, mountPoint.Name) - assert.True(c, client.IsErrNotFound(err)) + assert.Check(c, client.IsErrNotFound(err)) } } } diff --git a/components/engine/integration-cli/docker_api_containers_windows_test.go b/components/engine/integration-cli/docker_api_containers_windows_test.go index eb2892575ce..4c8ace48427 100644 --- a/components/engine/integration-cli/docker_api_containers_windows_test.go +++ b/components/engine/integration-cli/docker_api_containers_windows_test.go @@ -13,8 +13,8 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/mount" "github.com/go-check/check" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -65,12 +65,12 @@ func (s *DockerSuite) TestContainersAPICreateMountsBindNamedPipe(c *check.C) { }, }, nil, name) - require.NoError(c, err) + assert.NilError(c, err) err = client.ContainerStart(ctx, name, types.ContainerStartOptions{}) - require.NoError(c, err) + assert.NilError(c, err) err = <-ch - require.NoError(c, err) - assert.Equal(c, text, strings.TrimSpace(string(b))) + assert.NilError(c, err) + assert.Check(c, is.Equal(text, strings.TrimSpace(string(b)))) } diff --git a/components/engine/integration-cli/docker_api_inspect_test.go b/components/engine/integration-cli/docker_api_inspect_test.go index 52a889f08b5..2f81d6e1eb6 100644 --- a/components/engine/integration-cli/docker_api_inspect_test.go +++ b/components/engine/integration-cli/docker_api_inspect_test.go @@ -11,7 +11,8 @@ import ( "github.com/docker/docker/client" "github.com/docker/docker/integration-cli/checker" "github.com/go-check/check" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func (s *DockerSuite) TestInspectAPIContainerResponse(c *check.C) { @@ -115,8 +116,8 @@ func (s *DockerSuite) TestInspectAPIImageResponse(c *check.C) { c.Assert(err, checker.IsNil) c.Assert(imageJSON.RepoTags, checker.HasLen, 2) - assert.Contains(c, imageJSON.RepoTags, "busybox:latest") - assert.Contains(c, imageJSON.RepoTags, "busybox:mytag") + assert.Check(c, is.Contains(imageJSON.RepoTags, "busybox:latest")) + assert.Check(c, is.Contains(imageJSON.RepoTags, "busybox:mytag")) } // #17131, #17139, #17173 diff --git a/components/engine/integration-cli/docker_api_swarm_test.go b/components/engine/integration-cli/docker_api_swarm_test.go index fd0b4e62780..2f54c3816e1 100644 --- a/components/engine/integration-cli/docker_api_swarm_test.go +++ b/components/engine/integration-cli/docker_api_swarm_test.go @@ -25,8 +25,8 @@ import ( "github.com/docker/docker/integration-cli/request" "github.com/docker/swarmkit/ca" "github.com/go-check/check" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -1010,16 +1010,16 @@ func (s *DockerSwarmSuite) TestAPINetworkInspectWithScope(c *check.C) { name := "test-scoped-network" ctx := context.Background() apiclient, err := d.NewClient() - require.NoError(c, err) + assert.NilError(c, err) resp, err := apiclient.NetworkCreate(ctx, name, types.NetworkCreate{Driver: "overlay"}) - require.NoError(c, err) + assert.NilError(c, err) network, err := apiclient.NetworkInspect(ctx, name, types.NetworkInspectOptions{}) - require.NoError(c, err) - assert.Equal(c, "swarm", network.Scope) - assert.Equal(c, resp.ID, network.ID) + assert.NilError(c, err) + assert.Check(c, is.Equal("swarm", network.Scope)) + assert.Check(c, is.Equal(resp.ID, network.ID)) _, err = apiclient.NetworkInspect(ctx, name, types.NetworkInspectOptions{Scope: "local"}) - assert.True(c, client.IsErrNotFound(err)) + assert.Check(c, client.IsErrNotFound(err)) } diff --git a/components/engine/integration-cli/docker_cli_by_digest_test.go b/components/engine/integration-cli/docker_cli_by_digest_test.go index 2d5dd486e72..ac97e0aecc5 100644 --- a/components/engine/integration-cli/docker_cli_by_digest_test.go +++ b/components/engine/integration-cli/docker_cli_by_digest_test.go @@ -15,8 +15,9 @@ import ( "github.com/docker/docker/integration-cli/cli" "github.com/docker/docker/integration-cli/cli/build" "github.com/go-check/check" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/opencontainers/go-digest" - "github.com/stretchr/testify/assert" ) var ( @@ -403,7 +404,7 @@ func (s *DockerRegistrySuite) TestInspectImageWithDigests(c *check.C) { c.Assert(err, checker.IsNil) c.Assert(imageJSON, checker.HasLen, 1) c.Assert(imageJSON[0].RepoDigests, checker.HasLen, 1) - assert.Contains(c, imageJSON[0].RepoDigests, imageReference) + assert.Check(c, is.Contains(imageJSON[0].RepoDigests, imageReference)) } func (s *DockerRegistrySuite) TestPsListContainersFilterAncestorImageByDigest(c *check.C) { diff --git a/components/engine/integration/build/build_test.go b/components/engine/integration/build/build_test.go index 124f1107fbd..daede7bc331 100644 --- a/components/engine/integration/build/build_test.go +++ b/components/engine/integration/build/build_test.go @@ -15,8 +15,8 @@ import ( "github.com/docker/docker/integration-cli/cli/build/fakecontext" "github.com/docker/docker/integration/internal/request" "github.com/docker/docker/pkg/jsonmessage" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestBuildWithRemoveAndForceRemove(t *testing.T) { @@ -94,21 +94,21 @@ func TestBuildWithRemoveAndForceRemove(t *testing.T) { buff := bytes.NewBuffer(nil) tw := tar.NewWriter(buff) - require.NoError(t, tw.WriteHeader(&tar.Header{ + assert.NilError(t, tw.WriteHeader(&tar.Header{ Name: "Dockerfile", Size: int64(len(dockerfile)), })) _, err := tw.Write(dockerfile) - require.NoError(t, err) - require.NoError(t, tw.Close()) + assert.NilError(t, err) + assert.NilError(t, tw.Close()) resp, err := client.ImageBuild(ctx, buff, types.ImageBuildOptions{Remove: c.rm, ForceRemove: c.forceRm, NoCache: true}) - require.NoError(t, err) + assert.NilError(t, err) defer resp.Body.Close() filter, err := buildContainerIdsFilter(resp.Body) - require.NoError(t, err) + assert.NilError(t, err) remainingContainers, err := client.ContainerList(ctx, types.ContainerListOptions{Filters: filter, All: true}) - require.NoError(t, err) - require.Equal(t, c.numberOfIntermediateContainers, len(remainingContainers), "Expected %v remaining intermediate containers, got %v", c.numberOfIntermediateContainers, len(remainingContainers)) + assert.NilError(t, err) + assert.Equal(t, c.numberOfIntermediateContainers, len(remainingContainers), "Expected %v remaining intermediate containers, got %v", c.numberOfIntermediateContainers, len(remainingContainers)) }) } } @@ -158,16 +158,16 @@ func TestBuildMultiStageParentConfig(t *testing.T) { ForceRemove: true, Tags: []string{"build1"}, }) - require.NoError(t, err) + assert.NilError(t, err) _, err = io.Copy(ioutil.Discard, resp.Body) resp.Body.Close() - require.NoError(t, err) + assert.NilError(t, err) image, _, err := apiclient.ImageInspectWithRaw(ctx, "build1") - require.NoError(t, err) + assert.NilError(t, err) - assert.Equal(t, "/foo/sub2", image.Config.WorkingDir) - assert.Contains(t, image.Config.Env, "WHO=parent") + assert.Check(t, is.Equal("/foo/sub2", image.Config.WorkingDir)) + assert.Check(t, is.Contains(image.Config.Env, "WHO=parent")) } func TestBuildWithEmptyLayers(t *testing.T) { @@ -192,10 +192,10 @@ func TestBuildWithEmptyLayers(t *testing.T) { Remove: true, ForceRemove: true, }) - require.NoError(t, err) + assert.NilError(t, err) _, err = io.Copy(ioutil.Discard, resp.Body) resp.Body.Close() - require.NoError(t, err) + assert.NilError(t, err) } // TestBuildMultiStageOnBuild checks that ONBUILD commands are applied to @@ -228,20 +228,20 @@ RUN cat somefile` }) out := bytes.NewBuffer(nil) - require.NoError(t, err) + assert.NilError(t, err) _, err = io.Copy(out, resp.Body) resp.Body.Close() - require.NoError(t, err) + assert.NilError(t, err) - assert.Contains(t, out.String(), "Successfully built") + assert.Check(t, is.Contains(out.String(), "Successfully built")) imageIDs, err := getImageIDsFromBuild(out.Bytes()) - require.NoError(t, err) - assert.Equal(t, 3, len(imageIDs)) + assert.NilError(t, err) + assert.Check(t, is.Equal(3, len(imageIDs))) image, _, err := apiclient.ImageInspectWithRaw(context.Background(), imageIDs[2]) - require.NoError(t, err) - assert.Contains(t, image.Config.Env, "bar=baz") + assert.NilError(t, err) + assert.Check(t, is.Contains(image.Config.Env, "bar=baz")) } // #35403 #36122 @@ -260,7 +260,7 @@ COPY bar /` writeTarRecord(t, w, "../foo", "foocontents0") writeTarRecord(t, w, "/bar", "barcontents0") err := w.Close() - require.NoError(t, err) + assert.NilError(t, err) apiclient := testEnv.APIClient() resp, err := apiclient.ImageBuild(ctx, @@ -271,10 +271,10 @@ COPY bar /` }) out := bytes.NewBuffer(nil) - require.NoError(t, err) + assert.NilError(t, err) _, err = io.Copy(out, resp.Body) resp.Body.Close() - require.NoError(t, err) + assert.NilError(t, err) // repeat with changed data should not cause cache hits @@ -284,7 +284,7 @@ COPY bar /` writeTarRecord(t, w, "../foo", "foocontents1") writeTarRecord(t, w, "/bar", "barcontents1") err = w.Close() - require.NoError(t, err) + assert.NilError(t, err) resp, err = apiclient.ImageBuild(ctx, buf, @@ -294,10 +294,10 @@ COPY bar /` }) out = bytes.NewBuffer(nil) - require.NoError(t, err) + assert.NilError(t, err) _, err = io.Copy(out, resp.Body) resp.Body.Close() - require.NoError(t, err) + assert.NilError(t, err) require.NotContains(t, out.String(), "Using cache") } @@ -333,12 +333,12 @@ RUN [ ! -f foo ] }) out := bytes.NewBuffer(nil) - require.NoError(t, err) + assert.NilError(t, err) _, err = io.Copy(out, resp.Body) resp.Body.Close() - require.NoError(t, err) + assert.NilError(t, err) - assert.Contains(t, out.String(), "Successfully built") + assert.Check(t, is.Contains(out.String(), "Successfully built")) } func writeTarRecord(t *testing.T, w *tar.Writer, fn, contents string) { @@ -348,9 +348,9 @@ func writeTarRecord(t *testing.T, w *tar.Writer, fn, contents string) { Size: int64(len(contents)), Typeflag: '0', }) - require.NoError(t, err) + assert.NilError(t, err) _, err = w.Write([]byte(contents)) - require.NoError(t, err) + assert.NilError(t, err) } type buildLine struct { diff --git a/components/engine/integration/config/config_test.go b/components/engine/integration/config/config_test.go index 4e31b205ee2..91cd7ff9bba 100644 --- a/components/engine/integration/config/config_test.go +++ b/components/engine/integration/config/config_test.go @@ -14,9 +14,9 @@ import ( "github.com/docker/docker/integration/internal/swarm" "github.com/docker/docker/internal/testutil" "github.com/docker/docker/pkg/stdcopy" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "golang.org/x/net/context" ) @@ -27,14 +27,14 @@ func TestConfigList(t *testing.T) { d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - require.NoError(t, err) + assert.NilError(t, err) ctx := context.Background() // This test case is ported from the original TestConfigsEmptyList configs, err := client.ConfigList(ctx, types.ConfigListOptions{}) - require.NoError(t, err) - assert.Equal(t, len(configs), 0) + assert.NilError(t, err) + assert.Check(t, is.Equal(len(configs), 0)) testName0 := "test0" testName1 := "test1" @@ -57,8 +57,8 @@ func TestConfigList(t *testing.T) { // test by `config ls` entries, err := client.ConfigList(ctx, types.ConfigListOptions{}) - require.NoError(t, err) - assert.Equal(t, names(entries), testNames) + assert.NilError(t, err) + assert.Check(t, is.DeepEqual(names(entries), testNames)) testCases := []struct { filters filters.Args @@ -92,8 +92,8 @@ func TestConfigList(t *testing.T) { entries, err = client.ConfigList(ctx, types.ConfigListOptions{ Filters: tc.filters, }) - require.NoError(t, err) - assert.Equal(t, names(entries), tc.expected) + assert.NilError(t, err) + assert.Check(t, is.DeepEqual(names(entries), tc.expected)) } } @@ -106,8 +106,8 @@ func createConfig(ctx context.Context, t *testing.T, client client.APIClient, na }, Data: data, }) - require.NoError(t, err) - assert.NotEqual(t, config.ID, "") + assert.NilError(t, err) + assert.Check(t, config.ID != "") return config.ID } @@ -118,7 +118,7 @@ func TestConfigsCreateAndDelete(t *testing.T) { d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - require.NoError(t, err) + assert.NilError(t, err) ctx := context.Background() @@ -128,12 +128,12 @@ func TestConfigsCreateAndDelete(t *testing.T) { configID := createConfig(ctx, t, client, testName, []byte("TESTINGDATA"), nil) insp, _, err := client.ConfigInspectWithRaw(ctx, configID) - require.NoError(t, err) - assert.Equal(t, insp.Spec.Name, testName) + assert.NilError(t, err) + assert.Check(t, is.Equal(insp.Spec.Name, testName)) // This test case is ported from the original TestConfigsDelete err = client.ConfigRemove(ctx, configID) - require.NoError(t, err) + assert.NilError(t, err) insp, _, err = client.ConfigInspectWithRaw(ctx, configID) testutil.ErrorContains(t, err, "No such config") @@ -146,7 +146,7 @@ func TestConfigsUpdate(t *testing.T) { d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - require.NoError(t, err) + assert.NilError(t, err) ctx := context.Background() @@ -156,35 +156,35 @@ func TestConfigsUpdate(t *testing.T) { configID := createConfig(ctx, t, client, testName, []byte("TESTINGDATA"), nil) insp, _, err := client.ConfigInspectWithRaw(ctx, configID) - require.NoError(t, err) - assert.Equal(t, insp.ID, configID) + assert.NilError(t, err) + assert.Check(t, is.Equal(insp.ID, configID)) // test UpdateConfig with full ID insp.Spec.Labels = map[string]string{"test": "test1"} err = client.ConfigUpdate(ctx, configID, insp.Version, insp.Spec) - require.NoError(t, err) + assert.NilError(t, err) insp, _, err = client.ConfigInspectWithRaw(ctx, configID) - require.NoError(t, err) - assert.Equal(t, insp.Spec.Labels["test"], "test1") + assert.NilError(t, err) + assert.Check(t, is.Equal(insp.Spec.Labels["test"], "test1")) // test UpdateConfig with full name insp.Spec.Labels = map[string]string{"test": "test2"} err = client.ConfigUpdate(ctx, testName, insp.Version, insp.Spec) - require.NoError(t, err) + assert.NilError(t, err) insp, _, err = client.ConfigInspectWithRaw(ctx, configID) - require.NoError(t, err) - assert.Equal(t, insp.Spec.Labels["test"], "test2") + assert.NilError(t, err) + assert.Check(t, is.Equal(insp.Spec.Labels["test"], "test2")) // test UpdateConfig with prefix ID insp.Spec.Labels = map[string]string{"test": "test3"} err = client.ConfigUpdate(ctx, configID[:1], insp.Version, insp.Spec) - require.NoError(t, err) + assert.NilError(t, err) insp, _, err = client.ConfigInspectWithRaw(ctx, configID) - require.NoError(t, err) - assert.Equal(t, insp.Spec.Labels["test"], "test3") + assert.NilError(t, err) + assert.Check(t, is.Equal(insp.Spec.Labels["test"], "test3")) // test UpdateConfig in updating Data which is not supported in daemon // this test will produce an error in func UpdateConfig @@ -207,7 +207,7 @@ func TestTemplatedConfig(t *testing.T) { Data: []byte("this is a secret"), } referencedSecret, err := client.SecretCreate(ctx, referencedSecretSpec) - assert.NoError(t, err) + assert.Check(t, err) referencedConfigSpec := swarmtypes.ConfigSpec{ Annotations: swarmtypes.Annotations{ @@ -216,7 +216,7 @@ func TestTemplatedConfig(t *testing.T) { Data: []byte("this is a config"), } referencedConfig, err := client.ConfigCreate(ctx, referencedConfigSpec) - assert.NoError(t, err) + assert.Check(t, err) configSpec := swarmtypes.ConfigSpec{ Annotations: swarmtypes.Annotations{ @@ -231,7 +231,7 @@ func TestTemplatedConfig(t *testing.T) { } templatedConfig, err := client.ConfigCreate(ctx, configSpec) - assert.NoError(t, err) + assert.Check(t, err) serviceID := swarm.CreateService(t, d, swarm.ServiceWithConfig( @@ -309,8 +309,8 @@ func TestTemplatedConfig(t *testing.T) { func assertAttachedStream(t *testing.T, attach types.HijackedResponse, expect string) { buf := bytes.NewBuffer(nil) _, err := stdcopy.StdCopy(buf, buf, attach.Reader) - require.NoError(t, err) - assert.Contains(t, buf.String(), expect) + assert.NilError(t, err) + assert.Check(t, is.Contains(buf.String(), expect)) } func waitAndAssert(t *testing.T, timeout time.Duration, f func(*testing.T) bool) { @@ -336,7 +336,7 @@ func TestConfigInspect(t *testing.T) { d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - require.NoError(t, err) + assert.NilError(t, err) ctx := context.Background() @@ -344,11 +344,11 @@ func TestConfigInspect(t *testing.T) { configID := createConfig(ctx, t, client, testName, []byte("TESTINGDATA"), nil) insp, body, err := client.ConfigInspectWithRaw(ctx, configID) - require.NoError(t, err) - assert.Equal(t, insp.Spec.Name, testName) + assert.NilError(t, err) + assert.Check(t, is.Equal(insp.Spec.Name, testName)) var config swarmtypes.Config err = json.Unmarshal(body, &config) - require.NoError(t, err) - assert.Equal(t, config, insp) + assert.NilError(t, err) + assert.Check(t, is.DeepEqual(config, insp)) } diff --git a/components/engine/integration/container/copy_test.go b/components/engine/integration/container/copy_test.go index 43dc31f2f2c..766c0a17622 100644 --- a/components/engine/integration/container/copy_test.go +++ b/components/engine/integration/container/copy_test.go @@ -9,8 +9,9 @@ import ( "github.com/docker/docker/client" "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/internal/testutil" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/require" ) func TestCopyFromContainerPathDoesNotExist(t *testing.T) { @@ -21,7 +22,7 @@ func TestCopyFromContainerPathDoesNotExist(t *testing.T) { cid := container.Create(t, ctx, apiclient) _, _, err := apiclient.CopyFromContainer(ctx, cid, "/dne") - require.True(t, client.IsErrNotFound(err)) + assert.Assert(t, client.IsErrNotFound(err)) expected := fmt.Sprintf("No such container:path: %s:%s", cid, "/dne") testutil.ErrorContains(t, err, expected) } @@ -35,7 +36,7 @@ func TestCopyFromContainerPathIsNotDir(t *testing.T) { cid := container.Create(t, ctx, apiclient) _, _, err := apiclient.CopyFromContainer(ctx, cid, "/etc/passwd/") - require.Contains(t, err.Error(), "not a directory") + assert.Assert(t, is.Contains(err.Error(), "not a directory")) } func TestCopyToContainerPathDoesNotExist(t *testing.T) { @@ -47,7 +48,7 @@ func TestCopyToContainerPathDoesNotExist(t *testing.T) { cid := container.Create(t, ctx, apiclient) err := apiclient.CopyToContainer(ctx, cid, "/dne", nil, types.CopyToContainerOptions{}) - require.True(t, client.IsErrNotFound(err)) + assert.Assert(t, client.IsErrNotFound(err)) expected := fmt.Sprintf("No such container:path: %s:%s", cid, "/dne") testutil.ErrorContains(t, err, expected) } @@ -61,5 +62,5 @@ func TestCopyToContainerPathIsNotDir(t *testing.T) { cid := container.Create(t, ctx, apiclient) err := apiclient.CopyToContainer(ctx, cid, "/etc/passwd/", nil, types.CopyToContainerOptions{}) - require.Contains(t, err.Error(), "not a directory") + assert.Assert(t, is.Contains(err.Error(), "not a directory")) } diff --git a/components/engine/integration/container/daemon_linux_test.go b/components/engine/integration/container/daemon_linux_test.go index 1424e74009f..1b811f306f8 100644 --- a/components/engine/integration/container/daemon_linux_test.go +++ b/components/engine/integration/container/daemon_linux_test.go @@ -11,8 +11,8 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/integration/internal/container" + "github.com/gotestyourself/gotestyourself/assert" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/assert" "golang.org/x/sys/unix" ) @@ -35,7 +35,7 @@ func TestContainerStartOnDaemonRestart(t *testing.T) { defer d.Stop(t) client, err := d.NewClient() - assert.NoError(t, err, "error creating client") + assert.Check(t, err, "error creating client") ctx := context.Background() @@ -43,36 +43,36 @@ func TestContainerStartOnDaemonRestart(t *testing.T) { defer client.ContainerRemove(ctx, cID, types.ContainerRemoveOptions{Force: true}) err = client.ContainerStart(ctx, cID, types.ContainerStartOptions{}) - assert.NoError(t, err, "error starting test container") + assert.Check(t, err, "error starting test container") inspect, err := client.ContainerInspect(ctx, cID) - assert.NoError(t, err, "error getting inspect data") + assert.Check(t, err, "error getting inspect data") ppid := getContainerdShimPid(t, inspect) err = d.Kill() - assert.NoError(t, err, "failed to kill test daemon") + assert.Check(t, err, "failed to kill test daemon") err = unix.Kill(inspect.State.Pid, unix.SIGKILL) - assert.NoError(t, err, "failed to kill container process") + assert.Check(t, err, "failed to kill container process") err = unix.Kill(ppid, unix.SIGKILL) - assert.NoError(t, err, "failed to kill containerd-shim") + assert.Check(t, err, "failed to kill containerd-shim") d.Start(t, "--iptables=false") err = client.ContainerStart(ctx, cID, types.ContainerStartOptions{}) - assert.NoError(t, err, "failed to start test container") + assert.Check(t, err, "failed to start test container") } func getContainerdShimPid(t *testing.T, c types.ContainerJSON) int { statB, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/stat", c.State.Pid)) - assert.NoError(t, err, "error looking up containerd-shim pid") + assert.Check(t, err, "error looking up containerd-shim pid") // ppid is the 4th entry in `/proc/pid/stat` ppid, err := strconv.Atoi(strings.Fields(string(statB))[3]) - assert.NoError(t, err, "error converting ppid field to int") + assert.Check(t, err, "error converting ppid field to int") - assert.NotEqual(t, ppid, 1, "got unexpected ppid") + assert.Check(t, ppid != 1, "got unexpected ppid") return ppid } diff --git a/components/engine/integration/container/diff_test.go b/components/engine/integration/container/diff_test.go index de5ff4e21aa..1cc63ebddef 100644 --- a/components/engine/integration/container/diff_test.go +++ b/components/engine/integration/container/diff_test.go @@ -9,9 +9,9 @@ import ( "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" "github.com/docker/docker/pkg/archive" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/poll" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestDiff(t *testing.T) { @@ -38,6 +38,6 @@ func TestDiff(t *testing.T) { } items, err := client.ContainerDiff(ctx, cID) - require.NoError(t, err) - assert.Equal(t, expected, items) + assert.NilError(t, err) + assert.Check(t, is.DeepEqual(expected, items)) } diff --git a/components/engine/integration/container/exec_test.go b/components/engine/integration/container/exec_test.go index 06835678f05..1b710432d14 100644 --- a/components/engine/integration/container/exec_test.go +++ b/components/engine/integration/container/exec_test.go @@ -9,7 +9,8 @@ import ( "github.com/docker/docker/api/types/strslice" "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestExec(t *testing.T) { @@ -27,7 +28,7 @@ func TestExec(t *testing.T) { Cmd: strslice.StrSlice([]string{"sh", "-c", "env"}), }, ) - require.NoError(t, err) + assert.NilError(t, err) resp, err := client.ContainerExecAttach(ctx, id.ID, types.ExecStartCheck{ @@ -35,12 +36,12 @@ func TestExec(t *testing.T) { Tty: false, }, ) - require.NoError(t, err) + assert.NilError(t, err) defer resp.Close() r, err := ioutil.ReadAll(resp.Reader) - require.NoError(t, err) + assert.NilError(t, err) out := string(r) - require.NoError(t, err) - require.Contains(t, out, "PWD=/tmp", "exec command not running in expected /tmp working directory") - require.Contains(t, out, "FOO=BAR", "exec command not running with expected environment variable FOO") + assert.NilError(t, err) + assert.Assert(t, is.Contains(out, "PWD=/tmp"), "exec command not running in expected /tmp working directory") + assert.Assert(t, is.Contains(out, "FOO=BAR"), "exec command not running with expected environment variable FOO") } diff --git a/components/engine/integration/container/export_test.go b/components/engine/integration/container/export_test.go index 8f846b5a294..f7f0295ce55 100644 --- a/components/engine/integration/container/export_test.go +++ b/components/engine/integration/container/export_test.go @@ -13,10 +13,10 @@ import ( "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" "github.com/docker/docker/pkg/jsonmessage" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/poll" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) // export an image and try to import it into a new one @@ -32,12 +32,12 @@ func TestExportContainerAndImportImage(t *testing.T) { reference := "repo/testexp:v1" exportResp, err := client.ContainerExport(ctx, cID) - require.NoError(t, err) + assert.NilError(t, err) importResp, err := client.ImageImport(ctx, types.ImageImportSource{ Source: exportResp, SourceName: "-", }, reference, types.ImageImportOptions{}) - require.NoError(t, err) + assert.NilError(t, err) // If the import is successfully, then the message output should contain // the image ID and match with the output from `docker images`. @@ -45,13 +45,13 @@ func TestExportContainerAndImportImage(t *testing.T) { dec := json.NewDecoder(importResp) var jm jsonmessage.JSONMessage err = dec.Decode(&jm) - require.NoError(t, err) + assert.NilError(t, err) images, err := client.ImageList(ctx, types.ImageListOptions{ Filters: filters.NewArgs(filters.Arg("reference", reference)), }) - require.NoError(t, err) - assert.Equal(t, jm.Status, images[0].ID) + assert.NilError(t, err) + assert.Check(t, is.Equal(jm.Status, images[0].ID)) } // TestExportContainerAfterDaemonRestart checks that a container @@ -64,7 +64,7 @@ func TestExportContainerAfterDaemonRestart(t *testing.T) { d := daemon.New(t, "", "dockerd", daemon.Config{}) client, err := d.NewClient() - require.NoError(t, err) + assert.NilError(t, err) d.StartWithBusybox(t) defer d.Stop(t) @@ -75,10 +75,10 @@ func TestExportContainerAfterDaemonRestart(t *testing.T) { Cmd: []string{"top"}, } ctr, err := client.ContainerCreate(ctx, &cfg, nil, nil, "") - require.NoError(t, err) + assert.NilError(t, err) d.Restart(t) _, err = client.ContainerExport(ctx, ctr.ID) - assert.NoError(t, err) + assert.NilError(t, err) } diff --git a/components/engine/integration/container/inspect_test.go b/components/engine/integration/container/inspect_test.go index c7ea23b5179..03b9e45319a 100644 --- a/components/engine/integration/container/inspect_test.go +++ b/components/engine/integration/container/inspect_test.go @@ -9,10 +9,10 @@ import ( "github.com/docker/docker/client" "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/poll" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestInspectCpusetInConfigPre120(t *testing.T) { @@ -33,16 +33,16 @@ func TestInspectCpusetInConfigPre120(t *testing.T) { poll.WaitOn(t, container.IsInState(ctx, client, name, "exited"), poll.WithDelay(100*time.Millisecond)) _, body, err := client.ContainerInspectWithRaw(ctx, name, false) - require.NoError(t, err) + assert.NilError(t, err) var inspectJSON map[string]interface{} err = json.Unmarshal(body, &inspectJSON) - require.NoError(t, err, "unable to unmarshal body for version 1.19: %s", err) + assert.NilError(t, err, "unable to unmarshal body for version 1.19: %s", err) config, ok := inspectJSON["Config"] - assert.Equal(t, true, ok, "Unable to find 'Config'") + assert.Check(t, is.Equal(true, ok), "Unable to find 'Config'") cfg := config.(map[string]interface{}) _, ok = cfg["Cpuset"] - assert.Equal(t, true, ok, "API version 1.19 expected to include Cpuset in 'Config'") + assert.Check(t, is.Equal(true, ok), "API version 1.19 expected to include Cpuset in 'Config'") } diff --git a/components/engine/integration/container/kill_test.go b/components/engine/integration/container/kill_test.go index dbffc802a55..f4995539571 100644 --- a/components/engine/integration/container/kill_test.go +++ b/components/engine/integration/container/kill_test.go @@ -9,10 +9,10 @@ import ( "github.com/docker/docker/client" "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/poll" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestKillContainerInvalidSignal(t *testing.T) { @@ -22,11 +22,11 @@ func TestKillContainerInvalidSignal(t *testing.T) { id := container.Run(t, ctx, client) err := client.ContainerKill(ctx, id, "0") - require.EqualError(t, err, "Error response from daemon: Invalid signal: 0") + assert.Error(t, err, "Error response from daemon: Invalid signal: 0") poll.WaitOn(t, container.IsInState(ctx, client, id, "running"), poll.WithDelay(100*time.Millisecond)) err = client.ContainerKill(ctx, id, "SIG42") - require.EqualError(t, err, "Error response from daemon: Invalid signal: SIG42") + assert.Error(t, err, "Error response from daemon: Invalid signal: SIG42") poll.WaitOn(t, container.IsInState(ctx, client, id, "running"), poll.WithDelay(100*time.Millisecond)) } @@ -62,7 +62,7 @@ func TestKillContainer(t *testing.T) { ctx := context.Background() id := container.Run(t, ctx, client) err := client.ContainerKill(ctx, id, tc.signal) - require.NoError(t, err) + assert.NilError(t, err) poll.WaitOn(t, container.IsInState(ctx, client, id, tc.status), poll.WithDelay(100*time.Millisecond)) }) @@ -102,7 +102,7 @@ func TestKillWithStopSignalAndRestartPolicies(t *testing.T) { } }) err := client.ContainerKill(ctx, id, "TERM") - require.NoError(t, err) + assert.NilError(t, err) poll.WaitOn(t, container.IsInState(ctx, client, id, tc.status), poll.WithDelay(100*time.Millisecond)) }) @@ -116,8 +116,8 @@ func TestKillStoppedContainer(t *testing.T) { client := request.NewAPIClient(t) id := container.Create(t, ctx, client) err := client.ContainerKill(ctx, id, "SIGKILL") - require.Error(t, err) - require.Contains(t, err.Error(), "is not running") + assert.Assert(t, is.ErrorContains(err, "")) + assert.Assert(t, is.Contains(err.Error(), "is not running")) } func TestKillStoppedContainerAPIPre120(t *testing.T) { @@ -127,7 +127,7 @@ func TestKillStoppedContainerAPIPre120(t *testing.T) { client := request.NewAPIClient(t, client.WithVersion("1.19")) id := container.Create(t, ctx, client) err := client.ContainerKill(ctx, id, "SIGKILL") - require.NoError(t, err) + assert.NilError(t, err) } func TestKillDifferentUserContainer(t *testing.T) { @@ -144,7 +144,7 @@ func TestKillDifferentUserContainer(t *testing.T) { poll.WaitOn(t, container.IsInState(ctx, client, id, "running"), poll.WithDelay(100*time.Millisecond)) err := client.ContainerKill(ctx, id, "SIGKILL") - require.NoError(t, err) + assert.NilError(t, err) poll.WaitOn(t, container.IsInState(ctx, client, id, "exited"), poll.WithDelay(100*time.Millisecond)) } @@ -162,8 +162,8 @@ func TestInspectOomKilledTrue(t *testing.T) { poll.WaitOn(t, container.IsInState(ctx, client, cID, "exited"), poll.WithDelay(100*time.Millisecond)) inspect, err := client.ContainerInspect(ctx, cID) - require.NoError(t, err) - assert.Equal(t, true, inspect.State.OOMKilled) + assert.NilError(t, err) + assert.Check(t, is.Equal(true, inspect.State.OOMKilled)) } func TestInspectOomKilledFalse(t *testing.T) { @@ -178,6 +178,6 @@ func TestInspectOomKilledFalse(t *testing.T) { poll.WaitOn(t, container.IsInState(ctx, client, cID, "exited"), poll.WithDelay(100*time.Millisecond)) inspect, err := client.ContainerInspect(ctx, cID) - require.NoError(t, err) - assert.Equal(t, false, inspect.State.OOMKilled) + assert.NilError(t, err) + assert.Check(t, is.Equal(false, inspect.State.OOMKilled)) } diff --git a/components/engine/integration/container/links_linux_test.go b/components/engine/integration/container/links_linux_test.go index c844c4916fb..ed5966bc7b6 100644 --- a/components/engine/integration/container/links_linux_test.go +++ b/components/engine/integration/container/links_linux_test.go @@ -10,9 +10,9 @@ import ( "github.com/docker/docker/api/types/filters" "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestLinksEtcHostsContentMatch(t *testing.T) { @@ -27,11 +27,11 @@ func TestLinksEtcHostsContentMatch(t *testing.T) { cID := container.Run(t, ctx, client, container.WithNetworkMode("host")) res, err := container.Exec(ctx, client, cID, []string{"cat", "/etc/hosts"}) - require.NoError(t, err) - require.Empty(t, res.Stderr()) - require.Equal(t, 0, res.ExitCode) + assert.NilError(t, err) + assert.Assert(t, is.Len(res.Stderr(), 0)) + assert.Equal(t, 0, res.ExitCode) - assert.Equal(t, string(hosts), res.Stdout()) + assert.Check(t, is.Equal(string(hosts), res.Stdout())) } func TestLinksContainerNames(t *testing.T) { @@ -49,7 +49,7 @@ func TestLinksContainerNames(t *testing.T) { containers, err := client.ContainerList(ctx, types.ContainerListOptions{ Filters: f, }) - require.NoError(t, err) - assert.Equal(t, 1, len(containers)) - assert.Equal(t, []string{"/first", "/second/first"}, containers[0].Names) + assert.NilError(t, err) + assert.Check(t, is.Equal(1, len(containers))) + assert.Check(t, is.DeepEqual([]string{"/first", "/second/first"}, containers[0].Names)) } diff --git a/components/engine/integration/container/logs_test.go b/components/engine/integration/container/logs_test.go index 2d7306582fd..5a644e5c399 100644 --- a/components/engine/integration/container/logs_test.go +++ b/components/engine/integration/container/logs_test.go @@ -9,7 +9,7 @@ import ( "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" "github.com/docker/docker/pkg/stdcopy" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" ) // Regression test for #35370 @@ -25,8 +25,8 @@ func TestLogsFollowTailEmpty(t *testing.T) { if logs != nil { defer logs.Close() } - assert.NoError(t, err) + assert.Check(t, err) _, err = stdcopy.StdCopy(ioutil.Discard, ioutil.Discard, logs) - assert.NoError(t, err) + assert.Check(t, err) } diff --git a/components/engine/integration/container/mounts_linux_test.go b/components/engine/integration/container/mounts_linux_test.go index 71bdccc71be..33168ffc33d 100644 --- a/components/engine/integration/container/mounts_linux_test.go +++ b/components/engine/integration/container/mounts_linux_test.go @@ -16,10 +16,10 @@ import ( "github.com/docker/docker/integration/internal/request" "github.com/docker/docker/pkg/stdcopy" "github.com/docker/docker/pkg/system" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/fs" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestContainerShmNoLeak(t *testing.T) { @@ -130,14 +130,14 @@ func TestContainerNetworkMountsNoChown(t *testing.T) { } cli, err := client.NewEnvClient() - require.NoError(t, err) + assert.NilError(t, err) defer cli.Close() ctrCreate, err := cli.ContainerCreate(ctx, &config, &hostConfig, &network.NetworkingConfig{}, "") - require.NoError(t, err) + assert.NilError(t, err) // container will exit immediately because of no tty, but we only need the start sequence to test the condition err = cli.ContainerStart(ctx, ctrCreate.ID, types.ContainerStartOptions{}) - require.NoError(t, err) + assert.NilError(t, err) // Check that host-located bind mount network file did not change ownership when the container was started // Note: If the user specifies a mountpath from the host, we should not be @@ -150,8 +150,8 @@ func TestContainerNetworkMountsNoChown(t *testing.T) { // same line--we don't chown host file content. // See GitHub PR 34224 for details. statT, err := system.Stat(tmpNWFileMount) - require.NoError(t, err) - assert.Equal(t, uint32(0), statT.UID(), "bind mounted network file should not change ownership from root") + assert.NilError(t, err) + assert.Check(t, is.Equal(uint32(0), statT.UID()), "bind mounted network file should not change ownership from root") } func TestMountDaemonRoot(t *testing.T) { diff --git a/components/engine/integration/container/nat_test.go b/components/engine/integration/container/nat_test.go index e2bb0f9b072..3d51b9e0077 100644 --- a/components/engine/integration/container/nat_test.go +++ b/components/engine/integration/container/nat_test.go @@ -15,10 +15,10 @@ import ( "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" "github.com/docker/go-connections/nat" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/poll" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestNetworkNat(t *testing.T) { @@ -31,12 +31,12 @@ func TestNetworkNat(t *testing.T) { endpoint := getExternalAddress(t) conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", endpoint.String(), 8080)) - require.NoError(t, err) + assert.NilError(t, err) defer conn.Close() data, err := ioutil.ReadAll(conn) - require.NoError(t, err) - assert.Equal(t, msg, strings.TrimSpace(string(data))) + assert.NilError(t, err) + assert.Check(t, is.Equal(msg, strings.TrimSpace(string(data)))) } func TestNetworkLocalhostTCPNat(t *testing.T) { @@ -48,12 +48,12 @@ func TestNetworkLocalhostTCPNat(t *testing.T) { startServerContainer(t, msg, 8081) conn, err := net.Dial("tcp", "localhost:8081") - require.NoError(t, err) + assert.NilError(t, err) defer conn.Close() data, err := ioutil.ReadAll(conn) - require.NoError(t, err) - assert.Equal(t, msg, strings.TrimSpace(string(data))) + assert.NilError(t, err) + assert.Check(t, is.Equal(msg, strings.TrimSpace(string(data)))) } func TestNetworkLoopbackNat(t *testing.T) { @@ -74,14 +74,14 @@ func TestNetworkLoopbackNat(t *testing.T) { body, err := client.ContainerLogs(ctx, cID, types.ContainerLogsOptions{ ShowStdout: true, }) - require.NoError(t, err) + assert.NilError(t, err) defer body.Close() var b bytes.Buffer _, err = io.Copy(&b, body) - require.NoError(t, err) + assert.NilError(t, err) - assert.Equal(t, msg, strings.TrimSpace(b.String())) + assert.Check(t, is.Equal(msg, strings.TrimSpace(b.String()))) } func startServerContainer(t *testing.T, msg string, port int) string { @@ -108,11 +108,11 @@ func getExternalAddress(t *testing.T) net.IP { skip.If(t, err != nil, "Test not running with `make test-integration`. Interface eth0 not found: %s", err) ifaceAddrs, err := iface.Addrs() - require.NoError(t, err) - assert.NotEqual(t, 0, len(ifaceAddrs)) + assert.NilError(t, err) + assert.Check(t, 0 != len(ifaceAddrs)) ifaceIP, _, err := net.ParseCIDR(ifaceAddrs[0].String()) - require.NoError(t, err) + assert.NilError(t, err) return ifaceIP } diff --git a/components/engine/integration/container/pause_test.go b/components/engine/integration/container/pause_test.go index bf9f9c3d8ff..dd8356f853b 100644 --- a/components/engine/integration/container/pause_test.go +++ b/components/engine/integration/container/pause_test.go @@ -12,10 +12,10 @@ import ( "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" "github.com/docker/docker/internal/testutil" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/poll" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestPause(t *testing.T) { @@ -31,14 +31,14 @@ func TestPause(t *testing.T) { since := request.DaemonUnixTime(ctx, t, client, testEnv) err := client.ContainerPause(ctx, cID) - require.NoError(t, err) + assert.NilError(t, err) inspect, err := client.ContainerInspect(ctx, cID) - require.NoError(t, err) - assert.Equal(t, true, inspect.State.Paused) + assert.NilError(t, err) + assert.Check(t, is.Equal(true, inspect.State.Paused)) err = client.ContainerUnpause(ctx, cID) - require.NoError(t, err) + assert.NilError(t, err) until := request.DaemonUnixTime(ctx, t, client, testEnv) @@ -47,7 +47,7 @@ func TestPause(t *testing.T) { Until: until, Filters: filters.NewArgs(filters.Arg("container", cID)), }) - assert.Equal(t, []string{"pause", "unpause"}, getEventActions(t, messages, errs)) + assert.Check(t, is.DeepEqual([]string{"pause", "unpause"}, getEventActions(t, messages, errs))) } func TestPauseFailsOnWindowsServerContainers(t *testing.T) { @@ -75,10 +75,10 @@ func TestPauseStopPausedContainer(t *testing.T) { poll.WaitOn(t, container.IsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond)) err := client.ContainerPause(ctx, cID) - require.NoError(t, err) + assert.NilError(t, err) err = client.ContainerStop(ctx, cID, nil) - require.NoError(t, err) + assert.NilError(t, err) poll.WaitOn(t, container.IsStopped(ctx, client, cID), poll.WithDelay(100*time.Millisecond)) } @@ -88,7 +88,7 @@ func getEventActions(t *testing.T, messages <-chan events.Message, errs <-chan e for { select { case err := <-errs: - assert.True(t, err == nil || err == io.EOF) + assert.Check(t, err == nil || err == io.EOF) return actions case e := <-messages: actions = append(actions, e.Status) diff --git a/components/engine/integration/container/ps_test.go b/components/engine/integration/container/ps_test.go index 358276b36af..45bcaca239f 100644 --- a/components/engine/integration/container/ps_test.go +++ b/components/engine/integration/container/ps_test.go @@ -8,8 +8,8 @@ import ( "github.com/docker/docker/api/types/filters" "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestPsFilter(t *testing.T) { @@ -35,8 +35,8 @@ func TestPsFilter(t *testing.T) { All: true, Filters: f1, }) - require.NoError(t, err) - assert.Contains(t, containerIDs(q1), next) + assert.NilError(t, err) + assert.Check(t, is.Contains(containerIDs(q1), next)) f2 := filters.NewArgs() f2.Add("before", "top") @@ -44,6 +44,6 @@ func TestPsFilter(t *testing.T) { All: true, Filters: f2, }) - require.NoError(t, err) - assert.Contains(t, containerIDs(q2), prev) + assert.NilError(t, err) + assert.Check(t, is.Contains(containerIDs(q2), prev)) } diff --git a/components/engine/integration/container/remove_test.go b/components/engine/integration/container/remove_test.go index 98aacdd2056..bbc521b059e 100644 --- a/components/engine/integration/container/remove_test.go +++ b/components/engine/integration/container/remove_test.go @@ -11,11 +11,11 @@ import ( "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" "github.com/docker/docker/internal/testutil" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/fs" "github.com/gotestyourself/gotestyourself/poll" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func getPrefixAndSlashFromDaemonPlatform() (prefix, slash string) { @@ -42,12 +42,12 @@ func TestRemoveContainerWithRemovedVolume(t *testing.T) { poll.WaitOn(t, container.IsInState(ctx, client, cID, "exited"), poll.WithDelay(100*time.Millisecond)) err := os.RemoveAll(tempDir.Path()) - require.NoError(t, err) + assert.NilError(t, err) err = client.ContainerRemove(ctx, cID, types.ContainerRemoveOptions{ RemoveVolumes: true, }) - require.NoError(t, err) + assert.NilError(t, err) _, _, err = client.ContainerInspectWithRaw(ctx, cID, true) testutil.ErrorContains(t, err, "No such container") @@ -65,18 +65,18 @@ func TestRemoveContainerWithVolume(t *testing.T) { poll.WaitOn(t, container.IsInState(ctx, client, cID, "exited"), poll.WithDelay(100*time.Millisecond)) insp, _, err := client.ContainerInspectWithRaw(ctx, cID, true) - require.NoError(t, err) - assert.Equal(t, 1, len(insp.Mounts)) + assert.NilError(t, err) + assert.Check(t, is.Equal(1, len(insp.Mounts))) volName := insp.Mounts[0].Name err = client.ContainerRemove(ctx, cID, types.ContainerRemoveOptions{ RemoveVolumes: true, }) - require.NoError(t, err) + assert.NilError(t, err) volumes, err := client.VolumeList(ctx, filters.NewArgs(filters.Arg("name", volName))) - require.NoError(t, err) - assert.Equal(t, 0, len(volumes.Volumes)) + assert.NilError(t, err) + assert.Check(t, is.Equal(0, len(volumes.Volumes))) } func TestRemoveContainerRunning(t *testing.T) { @@ -100,7 +100,7 @@ func TestRemoveContainerForceRemoveRunning(t *testing.T) { err := client.ContainerRemove(ctx, cID, types.ContainerRemoveOptions{ Force: true, }) - require.NoError(t, err) + assert.NilError(t, err) } func TestRemoveInvalidContainer(t *testing.T) { diff --git a/components/engine/integration/container/rename_test.go b/components/engine/integration/container/rename_test.go index 3567aee1f54..a27fd78acce 100644 --- a/components/engine/integration/container/rename_test.go +++ b/components/engine/integration/container/rename_test.go @@ -11,10 +11,10 @@ import ( "github.com/docker/docker/integration/internal/request" "github.com/docker/docker/internal/testutil" "github.com/docker/docker/pkg/stringid" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/poll" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) // This test simulates the scenario mentioned in #31392: @@ -30,18 +30,18 @@ func TestRenameLinkedContainer(t *testing.T) { bID := container.Run(t, ctx, client, container.WithName("b0"), container.WithLinks("a0")) err := client.ContainerRename(ctx, aID, "a1") - require.NoError(t, err) + assert.NilError(t, err) container.Run(t, ctx, client, container.WithName("a0")) err = client.ContainerRemove(ctx, bID, types.ContainerRemoveOptions{Force: true}) - require.NoError(t, err) + assert.NilError(t, err) bID = container.Run(t, ctx, client, container.WithName("b0"), container.WithLinks("a0")) inspect, err := client.ContainerInspect(ctx, bID) - require.NoError(t, err) - assert.Equal(t, []string{"/a0:/b0/a0"}, inspect.HostConfig.Links) + assert.NilError(t, err) + assert.Check(t, is.DeepEqual([]string{"/a0:/b0/a0"}, inspect.HostConfig.Links)) } func TestRenameStoppedContainer(t *testing.T) { @@ -54,16 +54,16 @@ func TestRenameStoppedContainer(t *testing.T) { poll.WaitOn(t, container.IsInState(ctx, client, cID, "exited"), poll.WithDelay(100*time.Millisecond)) inspect, err := client.ContainerInspect(ctx, cID) - require.NoError(t, err) - assert.Equal(t, "/"+oldName, inspect.Name) + assert.NilError(t, err) + assert.Check(t, is.Equal("/"+oldName, inspect.Name)) newName := "new_name" + stringid.GenerateNonCryptoID() err = client.ContainerRename(ctx, oldName, newName) - require.NoError(t, err) + assert.NilError(t, err) inspect, err = client.ContainerInspect(ctx, cID) - require.NoError(t, err) - assert.Equal(t, "/"+newName, inspect.Name) + assert.NilError(t, err) + assert.Check(t, is.Equal("/"+newName, inspect.Name)) } func TestRenameRunningContainerAndReuse(t *testing.T) { @@ -77,11 +77,11 @@ func TestRenameRunningContainerAndReuse(t *testing.T) { newName := "new_name" + stringid.GenerateNonCryptoID() err := client.ContainerRename(ctx, oldName, newName) - require.NoError(t, err) + assert.NilError(t, err) inspect, err := client.ContainerInspect(ctx, cID) - require.NoError(t, err) - assert.Equal(t, "/"+newName, inspect.Name) + assert.NilError(t, err) + assert.Check(t, is.Equal("/"+newName, inspect.Name)) _, err = client.ContainerInspect(ctx, oldName) testutil.ErrorContains(t, err, "No such container: "+oldName) @@ -90,8 +90,8 @@ func TestRenameRunningContainerAndReuse(t *testing.T) { poll.WaitOn(t, container.IsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond)) inspect, err = client.ContainerInspect(ctx, cID) - require.NoError(t, err) - assert.Equal(t, "/"+oldName, inspect.Name) + assert.NilError(t, err) + assert.Check(t, is.Equal("/"+oldName, inspect.Name)) } func TestRenameInvalidName(t *testing.T) { @@ -107,8 +107,8 @@ func TestRenameInvalidName(t *testing.T) { testutil.ErrorContains(t, err, "Invalid container name") inspect, err := client.ContainerInspect(ctx, oldName) - require.NoError(t, err) - assert.Equal(t, cID, inspect.ID) + assert.NilError(t, err) + assert.Check(t, is.Equal(cID, inspect.ID)) } // Test case for GitHub issue 22466 @@ -124,7 +124,7 @@ func TestRenameAnonymousContainer(t *testing.T) { client := request.NewAPIClient(t) _, err := client.NetworkCreate(ctx, "network1", types.NetworkCreate{}) - require.NoError(t, err) + assert.NilError(t, err) cID := container.Run(t, ctx, client, func(c *container.TestContainerConfig) { c.NetworkingConfig.EndpointsConfig = map[string]*network.EndpointSettings{ "network1": {}, @@ -132,13 +132,13 @@ func TestRenameAnonymousContainer(t *testing.T) { c.HostConfig.NetworkMode = "network1" }) err = client.ContainerRename(ctx, cID, "container1") - require.NoError(t, err) + assert.NilError(t, err) // Stop/Start the container to get registered // FIXME(vdemeester) this is a really weird behavior as it fails otherwise err = client.ContainerStop(ctx, "container1", nil) - require.NoError(t, err) + assert.NilError(t, err) err = client.ContainerStart(ctx, "container1", types.ContainerStartOptions{}) - require.NoError(t, err) + assert.NilError(t, err) poll.WaitOn(t, container.IsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond)) @@ -155,8 +155,8 @@ func TestRenameAnonymousContainer(t *testing.T) { poll.WaitOn(t, container.IsInState(ctx, client, cID, "exited"), poll.WithDelay(100*time.Millisecond)) inspect, err := client.ContainerInspect(ctx, cID) - require.NoError(t, err) - assert.Equal(t, 0, inspect.State.ExitCode, "container %s exited with the wrong exitcode: %+v", cID, inspect) + assert.NilError(t, err) + assert.Check(t, is.Equal(0, inspect.State.ExitCode), "container %s exited with the wrong exitcode: %+v", cID, inspect) } // TODO: should be a unit test @@ -192,9 +192,9 @@ func TestRenameContainerWithLinkedContainer(t *testing.T) { poll.WaitOn(t, container.IsInState(ctx, client, app1ID, "running"), poll.WithDelay(100*time.Millisecond)) err := client.ContainerRename(ctx, "app1", "app2") - require.NoError(t, err) + assert.NilError(t, err) inspect, err := client.ContainerInspect(ctx, "app2/mysql") - require.NoError(t, err) - assert.Equal(t, db1ID, inspect.ID) + assert.NilError(t, err) + assert.Check(t, is.Equal(db1ID, inspect.ID)) } diff --git a/components/engine/integration/container/resize_test.go b/components/engine/integration/container/resize_test.go index 18438ea8253..149ac3afd16 100644 --- a/components/engine/integration/container/resize_test.go +++ b/components/engine/integration/container/resize_test.go @@ -11,9 +11,9 @@ import ( "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" "github.com/docker/docker/internal/testutil" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/poll" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestResize(t *testing.T) { @@ -29,7 +29,7 @@ func TestResize(t *testing.T) { Height: 40, Width: 40, }) - require.NoError(t, err) + assert.NilError(t, err) } func TestResizeWithInvalidSize(t *testing.T) { @@ -43,8 +43,8 @@ func TestResizeWithInvalidSize(t *testing.T) { endpoint := "/containers/" + cID + "/resize?h=foo&w=bar" res, _, err := req.Post(endpoint) - require.NoError(t, err) - assert.Equal(t, http.StatusBadRequest, res.StatusCode) + assert.NilError(t, err) + assert.Check(t, is.DeepEqual(http.StatusBadRequest, res.StatusCode)) } func TestResizeWhenContainerNotStarted(t *testing.T) { diff --git a/components/engine/integration/container/stats_test.go b/components/engine/integration/container/stats_test.go index 9c0b9484983..d10808f8f72 100644 --- a/components/engine/integration/container/stats_test.go +++ b/components/engine/integration/container/stats_test.go @@ -10,10 +10,10 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/poll" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestStats(t *testing.T) { @@ -24,20 +24,20 @@ func TestStats(t *testing.T) { ctx := context.Background() info, err := client.Info(ctx) - require.NoError(t, err) + assert.NilError(t, err) cID := container.Run(t, ctx, client) poll.WaitOn(t, container.IsInState(ctx, client, cID, "running"), poll.WithDelay(100*time.Millisecond)) resp, err := client.ContainerStats(ctx, cID, false) - require.NoError(t, err) + assert.NilError(t, err) defer resp.Body.Close() var v *types.Stats err = json.NewDecoder(resp.Body).Decode(&v) - require.NoError(t, err) - assert.Equal(t, int64(v.MemoryStats.Limit), info.MemTotal) + assert.NilError(t, err) + assert.Check(t, is.Equal(int64(v.MemoryStats.Limit), info.MemTotal)) err = json.NewDecoder(resp.Body).Decode(&v) - require.Error(t, err, io.EOF) + assert.Assert(t, is.ErrorContains(err, ""), io.EOF) } diff --git a/components/engine/integration/container/stop_test.go b/components/engine/integration/container/stop_test.go index 4ecd06dd2c3..2cc9b82512b 100644 --- a/components/engine/integration/container/stop_test.go +++ b/components/engine/integration/container/stop_test.go @@ -10,10 +10,10 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" + "github.com/gotestyourself/gotestyourself/assert" "github.com/gotestyourself/gotestyourself/icmd" "github.com/gotestyourself/gotestyourself/poll" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/require" ) func TestStopContainerWithRestartPolicyAlways(t *testing.T) { @@ -34,7 +34,7 @@ func TestStopContainerWithRestartPolicyAlways(t *testing.T) { for _, name := range names { err := client.ContainerStop(ctx, name, nil) - require.NoError(t, err) + assert.NilError(t, err) } for _, name := range names { @@ -54,7 +54,7 @@ func TestDeleteDevicemapper(t *testing.T) { poll.WaitOn(t, container.IsStopped(ctx, client, id), poll.WithDelay(100*time.Millisecond)) inspect, err := client.ContainerInspect(ctx, id) - require.NoError(t, err) + assert.NilError(t, err) deviceID := inspect.GraphDriver.Data["DeviceId"] @@ -67,5 +67,5 @@ func TestDeleteDevicemapper(t *testing.T) { result.Assert(t, icmd.Success) err = client.ContainerRemove(ctx, id, types.ContainerRemoveOptions{}) - require.NoError(t, err) + assert.NilError(t, err) } diff --git a/components/engine/integration/container/update_linux_test.go b/components/engine/integration/container/update_linux_test.go index c898dc1d3b8..a08417ea247 100644 --- a/components/engine/integration/container/update_linux_test.go +++ b/components/engine/integration/container/update_linux_test.go @@ -10,10 +10,10 @@ import ( containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/poll" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestUpdateMemory(t *testing.T) { @@ -44,26 +44,26 @@ func TestUpdateMemory(t *testing.T) { MemorySwap: setMemorySwap, }, }) - require.NoError(t, err) + assert.NilError(t, err) inspect, err := client.ContainerInspect(ctx, cID) - require.NoError(t, err) - assert.Equal(t, setMemory, inspect.HostConfig.Memory) - assert.Equal(t, setMemorySwap, inspect.HostConfig.MemorySwap) + assert.NilError(t, err) + assert.Check(t, is.Equal(setMemory, inspect.HostConfig.Memory)) + assert.Check(t, is.Equal(setMemorySwap, inspect.HostConfig.MemorySwap)) res, err := container.Exec(ctx, client, cID, []string{"cat", "/sys/fs/cgroup/memory/memory.limit_in_bytes"}) - require.NoError(t, err) - require.Empty(t, res.Stderr()) - require.Equal(t, 0, res.ExitCode) - assert.Equal(t, strconv.FormatInt(setMemory, 10), strings.TrimSpace(res.Stdout())) + assert.NilError(t, err) + assert.Assert(t, is.Len(res.Stderr(), 0)) + assert.Equal(t, 0, res.ExitCode) + assert.Check(t, is.Equal(strconv.FormatInt(setMemory, 10), strings.TrimSpace(res.Stdout()))) res, err = container.Exec(ctx, client, cID, []string{"cat", "/sys/fs/cgroup/memory/memory.memsw.limit_in_bytes"}) - require.NoError(t, err) - require.Empty(t, res.Stderr()) - require.Equal(t, 0, res.ExitCode) - assert.Equal(t, strconv.FormatInt(setMemorySwap, 10), strings.TrimSpace(res.Stdout())) + assert.NilError(t, err) + assert.Assert(t, is.Len(res.Stderr(), 0)) + assert.Equal(t, 0, res.ExitCode) + assert.Check(t, is.Equal(strconv.FormatInt(setMemorySwap, 10), strings.TrimSpace(res.Stdout()))) } func TestUpdateCPUQuota(t *testing.T) { @@ -93,15 +93,15 @@ func TestUpdateCPUQuota(t *testing.T) { } inspect, err := client.ContainerInspect(ctx, cID) - require.NoError(t, err) - assert.Equal(t, test.update, inspect.HostConfig.CPUQuota) + assert.NilError(t, err) + assert.Check(t, is.Equal(test.update, inspect.HostConfig.CPUQuota)) res, err := container.Exec(ctx, client, cID, []string{"/bin/cat", "/sys/fs/cgroup/cpu/cpu.cfs_quota_us"}) - require.NoError(t, err) - require.Empty(t, res.Stderr()) - require.Equal(t, 0, res.ExitCode) + assert.NilError(t, err) + assert.Assert(t, is.Len(res.Stderr(), 0)) + assert.Equal(t, 0, res.ExitCode) - assert.Equal(t, strconv.FormatInt(test.update, 10), strings.TrimSpace(res.Stdout())) + assert.Check(t, is.Equal(strconv.FormatInt(test.update, 10), strings.TrimSpace(res.Stdout()))) } } diff --git a/components/engine/integration/container/update_test.go b/components/engine/integration/container/update_test.go index 651e84cb222..03dcc635c67 100644 --- a/components/engine/integration/container/update_test.go +++ b/components/engine/integration/container/update_test.go @@ -9,9 +9,9 @@ import ( "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" "github.com/docker/docker/internal/testutil" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/poll" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestUpdateRestartPolicy(t *testing.T) { @@ -32,7 +32,7 @@ func TestUpdateRestartPolicy(t *testing.T) { MaximumRetryCount: 5, }, }) - require.NoError(t, err) + assert.NilError(t, err) timeout := 60 * time.Second if testEnv.OSType == "windows" { @@ -42,9 +42,9 @@ func TestUpdateRestartPolicy(t *testing.T) { poll.WaitOn(t, container.IsInState(ctx, client, cID, "exited"), poll.WithDelay(100*time.Millisecond), poll.WithTimeout(timeout)) inspect, err := client.ContainerInspect(ctx, cID) - require.NoError(t, err) - assert.Equal(t, inspect.RestartCount, 5) - assert.Equal(t, inspect.HostConfig.RestartPolicy.MaximumRetryCount, 5) + assert.NilError(t, err) + assert.Check(t, is.Equal(inspect.RestartCount, 5)) + assert.Check(t, is.Equal(inspect.HostConfig.RestartPolicy.MaximumRetryCount, 5)) } func TestUpdateRestartWithAutoRemove(t *testing.T) { diff --git a/components/engine/integration/image/commit_test.go b/components/engine/integration/image/commit_test.go index 39fc956db11..e13719b532c 100644 --- a/components/engine/integration/image/commit_test.go +++ b/components/engine/integration/image/commit_test.go @@ -7,8 +7,8 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestCommitInheritsEnv(t *testing.T) { @@ -22,13 +22,13 @@ func TestCommitInheritsEnv(t *testing.T) { Changes: []string{"ENV PATH=/bin"}, Reference: "test-commit-image", }) - require.NoError(t, err) + assert.NilError(t, err) image1, _, err := client.ImageInspectWithRaw(ctx, commitResp1.ID) - require.NoError(t, err) + assert.NilError(t, err) expectedEnv1 := []string{"PATH=/bin"} - assert.Equal(t, expectedEnv1, image1.Config.Env) + assert.Check(t, is.DeepEqual(expectedEnv1, image1.Config.Env)) cID2 := container.Create(t, ctx, client, container.WithImage(image1.ID)) @@ -36,10 +36,10 @@ func TestCommitInheritsEnv(t *testing.T) { Changes: []string{"ENV PATH=/usr/bin:$PATH"}, Reference: "test-commit-image", }) - require.NoError(t, err) + assert.NilError(t, err) image2, _, err := client.ImageInspectWithRaw(ctx, commitResp2.ID) - require.NoError(t, err) + assert.NilError(t, err) expectedEnv2 := []string{"PATH=/usr/bin:/bin"} - assert.Equal(t, expectedEnv2, image2.Config.Env) + assert.Check(t, is.DeepEqual(expectedEnv2, image2.Config.Env)) } diff --git a/components/engine/integration/image/remove_test.go b/components/engine/integration/image/remove_test.go index 825724bd039..c89f6f7a034 100644 --- a/components/engine/integration/image/remove_test.go +++ b/components/engine/integration/image/remove_test.go @@ -8,8 +8,8 @@ import ( "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" "github.com/docker/docker/internal/testutil" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestRemoveImageOrphaning(t *testing.T) { @@ -25,12 +25,12 @@ func TestRemoveImageOrphaning(t *testing.T) { Changes: []string{`ENTRYPOINT ["true"]`}, Reference: img, }) - require.NoError(t, err) + assert.NilError(t, err) // verifies that reference now points to first image resp, _, err := client.ImageInspectWithRaw(ctx, img) - require.NoError(t, err) - assert.Equal(t, resp.ID, commitResp1.ID) + assert.NilError(t, err) + assert.Check(t, is.Equal(resp.ID, commitResp1.ID)) // Create a container from created image, and commit a small change with same reference name cID2 := container.Create(t, ctx, client, container.WithImage(img), container.WithCmd("")) @@ -38,21 +38,21 @@ func TestRemoveImageOrphaning(t *testing.T) { Changes: []string{`LABEL Maintainer="Integration Tests"`}, Reference: img, }) - require.NoError(t, err) + assert.NilError(t, err) // verifies that reference now points to second image resp, _, err = client.ImageInspectWithRaw(ctx, img) - require.NoError(t, err) - assert.Equal(t, resp.ID, commitResp2.ID) + assert.NilError(t, err) + assert.Check(t, is.Equal(resp.ID, commitResp2.ID)) // try to remove the image, should not error out. _, err = client.ImageRemove(ctx, img, types.ImageRemoveOptions{}) - require.NoError(t, err) + assert.NilError(t, err) // check if the first image is still there resp, _, err = client.ImageInspectWithRaw(ctx, commitResp1.ID) - require.NoError(t, err) - assert.Equal(t, resp.ID, commitResp1.ID) + assert.NilError(t, err) + assert.Check(t, is.Equal(resp.ID, commitResp1.ID)) // check if the second image has been deleted _, _, err = client.ImageInspectWithRaw(ctx, commitResp2.ID) diff --git a/components/engine/integration/internal/container/container.go b/components/engine/integration/internal/container/container.go index 8d8fe28791a..0c76571769b 100644 --- a/components/engine/integration/internal/container/container.go +++ b/components/engine/integration/internal/container/container.go @@ -8,7 +8,7 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/network" "github.com/docker/docker/client" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) // TestContainerConfig holds container configuration struct that @@ -37,7 +37,7 @@ func Create(t *testing.T, ctx context.Context, client client.APIClient, ops ...f } c, err := client.ContainerCreate(ctx, config.Config, config.HostConfig, config.NetworkingConfig, config.Name) - require.NoError(t, err) + assert.NilError(t, err) return c.ID } @@ -48,7 +48,7 @@ func Run(t *testing.T, ctx context.Context, client client.APIClient, ops ...func id := Create(t, ctx, client, ops...) err := client.ContainerStart(ctx, id, types.ContainerStartOptions{}) - require.NoError(t, err) + assert.NilError(t, err) return id } diff --git a/components/engine/integration/internal/request/client.go b/components/engine/integration/internal/request/client.go index 34e589ec866..07dc2e33c35 100644 --- a/components/engine/integration/internal/request/client.go +++ b/components/engine/integration/internal/request/client.go @@ -9,14 +9,14 @@ import ( "github.com/docker/docker/client" "github.com/docker/docker/internal/test/environment" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) // NewAPIClient returns a docker API client configured from environment variables func NewAPIClient(t *testing.T, ops ...func(*client.Client) error) client.APIClient { ops = append([]func(*client.Client) error{client.FromEnv}, ops...) clt, err := client.NewClientWithOpts(ops...) - require.NoError(t, err) + assert.NilError(t, err) return clt } @@ -27,10 +27,10 @@ func DaemonTime(ctx context.Context, t *testing.T, client client.APIClient, test } info, err := client.Info(ctx) - require.NoError(t, err) + assert.NilError(t, err) dt, err := time.Parse(time.RFC3339Nano, info.SystemTime) - require.NoError(t, err, "invalid time format in GET /info response") + assert.NilError(t, err, "invalid time format in GET /info response") return dt } diff --git a/components/engine/integration/internal/swarm/service.go b/components/engine/integration/internal/swarm/service.go index a46b02e1469..0ec4d5175ef 100644 --- a/components/engine/integration/internal/swarm/service.go +++ b/components/engine/integration/internal/swarm/service.go @@ -11,7 +11,7 @@ import ( "github.com/docker/docker/client" "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/internal/test/environment" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) const ( @@ -35,7 +35,7 @@ func NewSwarm(t *testing.T, testEnv *environment.Execution) *daemon.Swarm { args := []string{"--iptables=false", "--swarm-default-advertise-addr=lo"} d.StartWithBusybox(t, args...) - require.NoError(t, d.Init(swarmtypes.InitRequest{})) + assert.NilError(t, d.Init(swarmtypes.InitRequest{})) return d } @@ -52,7 +52,7 @@ func CreateService(t *testing.T, d *daemon.Swarm, opts ...ServiceSpecOpt) string client := GetClient(t, d) resp, err := client.ServiceCreate(context.Background(), spec, types.ServiceCreateOptions{}) - require.NoError(t, err, "error creating service") + assert.NilError(t, err, "error creating service") return resp.ID } @@ -126,7 +126,7 @@ func GetRunningTasks(t *testing.T, d *daemon.Swarm, serviceID string) []swarmtyp Filters: filterArgs, } tasks, err := client.TaskList(context.Background(), options) - require.NoError(t, err) + assert.NilError(t, err) return tasks } @@ -136,11 +136,11 @@ func ExecTask(t *testing.T, d *daemon.Swarm, task swarmtypes.Task, config types. ctx := context.Background() resp, err := client.ContainerExecCreate(ctx, task.Status.ContainerStatus.ContainerID, config) - require.NoError(t, err, "error creating exec") + assert.NilError(t, err, "error creating exec") startCheck := types.ExecStartCheck{} attach, err := client.ContainerExecAttach(ctx, resp.ID, startCheck) - require.NoError(t, err, "error attaching to exec") + assert.NilError(t, err, "error attaching to exec") return attach } @@ -153,6 +153,6 @@ func ensureContainerSpec(spec *swarmtypes.ServiceSpec) { // GetClient creates a new client for the passed in swarm daemon. func GetClient(t *testing.T, d *daemon.Swarm) client.APIClient { client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - require.NoError(t, err) + assert.NilError(t, err) return client } diff --git a/components/engine/integration/network/delete_test.go b/components/engine/integration/network/delete_test.go index 0877d8bc8ca..e2af49de7eb 100644 --- a/components/engine/integration/network/delete_test.go +++ b/components/engine/integration/network/delete_test.go @@ -6,8 +6,8 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/integration/internal/request" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func containsNetwork(nws []types.NetworkResource, nw types.NetworkCreateResponse) bool { @@ -29,18 +29,18 @@ func createAmbiguousNetworks(t *testing.T) (types.NetworkCreateResponse, types.N ctx := context.Background() testNet, err := client.NetworkCreate(ctx, "testNet", types.NetworkCreate{}) - require.NoError(t, err) + assert.NilError(t, err) idPrefixNet, err := client.NetworkCreate(ctx, testNet.ID[:12], types.NetworkCreate{}) - require.NoError(t, err) + assert.NilError(t, err) fullIDNet, err := client.NetworkCreate(ctx, testNet.ID, types.NetworkCreate{}) - require.NoError(t, err) + assert.NilError(t, err) nws, err := client.NetworkList(ctx, types.NetworkListOptions{}) - require.NoError(t, err) + assert.NilError(t, err) - assert.Equal(t, true, containsNetwork(nws, testNet), "failed to create network testNet") - assert.Equal(t, true, containsNetwork(nws, idPrefixNet), "failed to create network idPrefixNet") - assert.Equal(t, true, containsNetwork(nws, fullIDNet), "failed to create network fullIDNet") + assert.Check(t, is.Equal(true, containsNetwork(nws, testNet)), "failed to create network testNet") + assert.Check(t, is.Equal(true, containsNetwork(nws, idPrefixNet)), "failed to create network idPrefixNet") + assert.Check(t, is.Equal(true, containsNetwork(nws, fullIDNet)), "failed to create network fullIDNet") return testNet, idPrefixNet, fullIDNet } @@ -56,17 +56,17 @@ func TestDockerNetworkDeletePreferID(t *testing.T) { // Delete the network using a prefix of the first network's ID as name. // This should the network name with the id-prefix, not the original network. err := client.NetworkRemove(ctx, testNet.ID[:12]) - require.NoError(t, err) + assert.NilError(t, err) // Delete the network using networkID. This should remove the original // network, not the network with the name equal to the networkID err = client.NetworkRemove(ctx, testNet.ID) - require.NoError(t, err) + assert.NilError(t, err) // networks "testNet" and "idPrefixNet" should be removed, but "fullIDNet" should still exist nws, err := client.NetworkList(ctx, types.NetworkListOptions{}) - require.NoError(t, err) - assert.Equal(t, false, containsNetwork(nws, testNet), "Network testNet not removed") - assert.Equal(t, false, containsNetwork(nws, idPrefixNet), "Network idPrefixNet not removed") - assert.Equal(t, true, containsNetwork(nws, fullIDNet), "Network fullIDNet not found") + assert.NilError(t, err) + assert.Check(t, is.Equal(false, containsNetwork(nws, testNet)), "Network testNet not removed") + assert.Check(t, is.Equal(false, containsNetwork(nws, idPrefixNet)), "Network idPrefixNet not removed") + assert.Check(t, is.Equal(true, containsNetwork(nws, fullIDNet)), "Network fullIDNet not found") } diff --git a/components/engine/integration/network/inspect_test.go b/components/engine/integration/network/inspect_test.go index df586224a19..3afdcf1ac48 100644 --- a/components/engine/integration/network/inspect_test.go +++ b/components/engine/integration/network/inspect_test.go @@ -11,8 +11,8 @@ import ( "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" "github.com/docker/docker/integration-cli/daemon" + "github.com/gotestyourself/gotestyourself/assert" "github.com/gotestyourself/gotestyourself/poll" - "github.com/stretchr/testify/require" "golang.org/x/net/context" ) @@ -24,7 +24,7 @@ func TestInspectNetwork(t *testing.T) { d := newSwarm(t) defer d.Stop(t) client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - require.NoError(t, err) + assert.NilError(t, err) overlayName := "overlay1" networkCreate := types.NetworkCreate{ @@ -33,7 +33,7 @@ func TestInspectNetwork(t *testing.T) { } netResp, err := client.NetworkCreate(context.Background(), overlayName, networkCreate) - require.NoError(t, err) + assert.NilError(t, err) overlayID := netResp.ID var instances uint64 = 4 @@ -44,7 +44,7 @@ func TestInspectNetwork(t *testing.T) { serviceResp, err := client.ServiceCreate(context.Background(), serviceSpec, types.ServiceCreateOptions{ QueryRegistry: false, }) - require.NoError(t, err) + assert.NilError(t, err) pollSettings := func(config *poll.Settings) { if runtime.GOARCH == "arm64" || runtime.GOARCH == "arm" { @@ -57,32 +57,32 @@ func TestInspectNetwork(t *testing.T) { poll.WaitOn(t, serviceRunningTasksCount(client, serviceID, instances), pollSettings) _, _, err = client.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{}) - require.NoError(t, err) + assert.NilError(t, err) // Test inspect verbose with full NetworkID networkVerbose, err := client.NetworkInspect(context.Background(), overlayID, types.NetworkInspectOptions{ Verbose: true, }) - require.NoError(t, err) - require.True(t, validNetworkVerbose(networkVerbose, serviceName, instances)) + assert.NilError(t, err) + assert.Assert(t, validNetworkVerbose(networkVerbose, serviceName, instances)) // Test inspect verbose with partial NetworkID networkVerbose, err = client.NetworkInspect(context.Background(), overlayID[0:11], types.NetworkInspectOptions{ Verbose: true, }) - require.NoError(t, err) - require.True(t, validNetworkVerbose(networkVerbose, serviceName, instances)) + assert.NilError(t, err) + assert.Assert(t, validNetworkVerbose(networkVerbose, serviceName, instances)) // Test inspect verbose with Network name and swarm scope networkVerbose, err = client.NetworkInspect(context.Background(), overlayName, types.NetworkInspectOptions{ Verbose: true, Scope: "swarm", }) - require.NoError(t, err) - require.True(t, validNetworkVerbose(networkVerbose, serviceName, instances)) + assert.NilError(t, err) + assert.Assert(t, validNetworkVerbose(networkVerbose, serviceName, instances)) err = client.ServiceRemove(context.Background(), serviceID) - require.NoError(t, err) + assert.NilError(t, err) poll.WaitOn(t, serviceIsRemoved(client, serviceID), pollSettings) poll.WaitOn(t, noTasks(client), pollSettings) @@ -90,19 +90,19 @@ func TestInspectNetwork(t *testing.T) { serviceResp, err = client.ServiceCreate(context.Background(), serviceSpec, types.ServiceCreateOptions{ QueryRegistry: false, }) - require.NoError(t, err) + assert.NilError(t, err) serviceID2 := serviceResp.ID poll.WaitOn(t, serviceRunningTasksCount(client, serviceID2, instances), pollSettings) err = client.ServiceRemove(context.Background(), serviceID2) - require.NoError(t, err) + assert.NilError(t, err) poll.WaitOn(t, serviceIsRemoved(client, serviceID2), pollSettings) poll.WaitOn(t, noTasks(client), pollSettings) err = client.NetworkRemove(context.Background(), overlayID) - require.NoError(t, err) + assert.NilError(t, err) poll.WaitOn(t, networkIsRemoved(client, overlayID), poll.WithTimeout(1*time.Minute), poll.WithDelay(10*time.Second)) } @@ -122,7 +122,7 @@ func newSwarm(t *testing.T) *daemon.Swarm { args := []string{"--iptables=false", "--swarm-default-advertise-addr=lo"} d.StartWithBusybox(t, args...) - require.NoError(t, d.Init(swarm.InitRequest{})) + assert.NilError(t, d.Init(swarm.InitRequest{})) return d } diff --git a/components/engine/integration/network/service_test.go b/components/engine/integration/network/service_test.go index f1c09509880..87e1fe00fdf 100644 --- a/components/engine/integration/network/service_test.go +++ b/components/engine/integration/network/service_test.go @@ -9,8 +9,8 @@ import ( "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" + "github.com/gotestyourself/gotestyourself/assert" "github.com/gotestyourself/gotestyourself/poll" - "github.com/stretchr/testify/require" "golang.org/x/net/context" ) @@ -19,7 +19,7 @@ func TestServiceWithPredefinedNetwork(t *testing.T) { d := newSwarm(t) defer d.Stop(t) client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - require.NoError(t, err) + assert.NilError(t, err) hostName := "host" var instances uint64 = 1 @@ -30,7 +30,7 @@ func TestServiceWithPredefinedNetwork(t *testing.T) { serviceResp, err := client.ServiceCreate(context.Background(), serviceSpec, types.ServiceCreateOptions{ QueryRegistry: false, }) - require.NoError(t, err) + assert.NilError(t, err) pollSettings := func(config *poll.Settings) { if runtime.GOARCH == "arm64" || runtime.GOARCH == "arm" { @@ -101,10 +101,10 @@ func TestServiceWithIngressNetwork(t *testing.T) { poll.WaitOn(t, serviceRunningCount(client, serviceID, instances), pollSettings) _, _, err = client.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{}) - require.NoError(t, err) + assert.NilError(t, err) err = client.ServiceRemove(context.Background(), serviceID) - require.NoError(t, err) + assert.NilError(t, err) poll.WaitOn(t, serviceIsRemoved(client, serviceID), pollSettings) poll.WaitOn(t, noTasks(client), pollSettings) diff --git a/components/engine/integration/plugin/authz/authz_plugin_test.go b/components/engine/integration/plugin/authz/authz_plugin_test.go index 667fc3d3ccb..5bca6c138dd 100644 --- a/components/engine/integration/plugin/authz/authz_plugin_test.go +++ b/components/engine/integration/plugin/authz/authz_plugin_test.go @@ -24,8 +24,8 @@ import ( "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/internal/test/environment" "github.com/docker/docker/pkg/authorization" + "github.com/gotestyourself/gotestyourself/assert" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/require" ) const ( @@ -55,15 +55,15 @@ func setupTestV1(t *testing.T) func() { teardown := setupTest(t) err := os.MkdirAll("/etc/docker/plugins", 0755) - require.Nil(t, err) + assert.NilError(t, err) fileName := fmt.Sprintf("/etc/docker/plugins/%s.spec", testAuthZPlugin) err = ioutil.WriteFile(fileName, []byte(server.URL), 0644) - require.Nil(t, err) + assert.NilError(t, err) return func() { err := os.RemoveAll("/etc/docker/plugins") - require.Nil(t, err) + assert.NilError(t, err) teardown() ctrl = nil @@ -87,7 +87,7 @@ func TestAuthZPluginAllowRequest(t *testing.T) { d.StartWithBusybox(t, "--authorization-plugin="+testAuthZPlugin) client, err := d.NewClient() - require.Nil(t, err) + assert.NilError(t, err) ctx := context.Background() @@ -98,9 +98,9 @@ func TestAuthZPluginAllowRequest(t *testing.T) { assertURIRecorded(t, ctrl.requestsURIs, fmt.Sprintf("/containers/%s/start", cID)) _, err = client.ServerVersion(ctx) - require.Nil(t, err) - require.Equal(t, 1, ctrl.versionReqCount) - require.Equal(t, 1, ctrl.versionResCount) + assert.NilError(t, err) + assert.Equal(t, 1, ctrl.versionReqCount) + assert.Equal(t, 1, ctrl.versionResCount) } func TestAuthZPluginTLS(t *testing.T) { @@ -126,13 +126,13 @@ func TestAuthZPluginTLS(t *testing.T) { ctrl.resRes.Allow = true client, err := newTLSAPIClient(testDaemonHTTPSAddr, cacertPath, clientCertPath, clientKeyPath) - require.Nil(t, err) + assert.NilError(t, err) _, err = client.ServerVersion(context.Background()) - require.Nil(t, err) + assert.NilError(t, err) - require.Equal(t, "client", ctrl.reqUser) - require.Equal(t, "client", ctrl.resUser) + assert.Equal(t, "client", ctrl.reqUser) + assert.Equal(t, "client", ctrl.resUser) } func newTLSAPIClient(host, cacertPath, certPath, keyPath string) (client.APIClient, error) { @@ -153,16 +153,16 @@ func TestAuthZPluginDenyRequest(t *testing.T) { ctrl.reqRes.Msg = unauthorizedMessage client, err := d.NewClient() - require.Nil(t, err) + assert.NilError(t, err) // Ensure command is blocked _, err = client.ServerVersion(context.Background()) - require.NotNil(t, err) - require.Equal(t, 1, ctrl.versionReqCount) - require.Equal(t, 0, ctrl.versionResCount) + assert.Assert(t, err != nil) + assert.Equal(t, 1, ctrl.versionReqCount) + assert.Equal(t, 0, ctrl.versionResCount) // Ensure unauthorized message appears in response - require.Equal(t, fmt.Sprintf("Error response from daemon: authorization denied by plugin %s: %s", testAuthZPlugin, unauthorizedMessage), err.Error()) + assert.Equal(t, fmt.Sprintf("Error response from daemon: authorization denied by plugin %s: %s", testAuthZPlugin, unauthorizedMessage), err.Error()) } // TestAuthZPluginAPIDenyResponse validates that when authorization @@ -174,17 +174,17 @@ func TestAuthZPluginAPIDenyResponse(t *testing.T) { ctrl.resRes.Msg = unauthorizedMessage daemonURL, err := url.Parse(d.Sock()) - require.Nil(t, err) + assert.NilError(t, err) conn, err := net.DialTimeout(daemonURL.Scheme, daemonURL.Path, time.Second*10) - require.Nil(t, err) + assert.NilError(t, err) client := httputil.NewClientConn(conn, nil) req, err := http.NewRequest("GET", "/version", nil) - require.Nil(t, err) + assert.NilError(t, err) resp, err := client.Do(req) - require.Nil(t, err) - require.Equal(t, http.StatusForbidden, resp.StatusCode) + assert.NilError(t, err) + assert.DeepEqual(t, http.StatusForbidden, resp.StatusCode) } func TestAuthZPluginDenyResponse(t *testing.T) { @@ -195,16 +195,16 @@ func TestAuthZPluginDenyResponse(t *testing.T) { ctrl.resRes.Msg = unauthorizedMessage client, err := d.NewClient() - require.Nil(t, err) + assert.NilError(t, err) // Ensure command is blocked _, err = client.ServerVersion(context.Background()) - require.NotNil(t, err) - require.Equal(t, 1, ctrl.versionReqCount) - require.Equal(t, 1, ctrl.versionResCount) + assert.Assert(t, err != nil) + assert.Equal(t, 1, ctrl.versionReqCount) + assert.Equal(t, 1, ctrl.versionResCount) // Ensure unauthorized message appears in response - require.Equal(t, fmt.Sprintf("Error response from daemon: authorization denied by plugin %s: %s", testAuthZPlugin, unauthorizedMessage), err.Error()) + assert.Equal(t, fmt.Sprintf("Error response from daemon: authorization denied by plugin %s: %s", testAuthZPlugin, unauthorizedMessage), err.Error()) } // TestAuthZPluginAllowEventStream verifies event stream propagates @@ -218,7 +218,7 @@ func TestAuthZPluginAllowEventStream(t *testing.T) { d.StartWithBusybox(t, "--authorization-plugin="+testAuthZPlugin) client, err := d.NewClient() - require.Nil(t, err) + assert.NilError(t, err) ctx := context.Background() @@ -231,7 +231,7 @@ func TestAuthZPluginAllowEventStream(t *testing.T) { for i := 0; i < 100; i++ { c, err := client.ContainerInspect(ctx, cID) - require.Nil(t, err) + assert.NilError(t, err) if c.State.Running { break } @@ -258,7 +258,7 @@ func TestAuthZPluginAllowEventStream(t *testing.T) { if err == io.EOF { t.Fatal("premature end of event stream") } - require.Nil(t, err) + assert.NilError(t, err) case <-time.After(30 * time.Second): // Fail the test t.Fatal("event stream timeout") @@ -279,10 +279,10 @@ func systemTime(t *testing.T, client client.APIClient, testEnv *environment.Exec ctx := context.Background() info, err := client.Info(ctx) - require.Nil(t, err) + assert.NilError(t, err) dt, err := time.Parse(time.RFC3339Nano, info.SystemTime) - require.Nil(t, err, "invalid time format in GET /info response") + assert.NilError(t, err, "invalid time format in GET /info response") return dt } @@ -303,12 +303,12 @@ func TestAuthZPluginErrorResponse(t *testing.T) { ctrl.resRes.Err = errorMessage client, err := d.NewClient() - require.Nil(t, err) + assert.NilError(t, err) // Ensure command is blocked _, err = client.ServerVersion(context.Background()) - require.NotNil(t, err) - require.Equal(t, fmt.Sprintf("Error response from daemon: plugin %s failed with error: %s: %s", testAuthZPlugin, authorization.AuthZApiResponse, errorMessage), err.Error()) + assert.Assert(t, err != nil) + assert.Equal(t, fmt.Sprintf("Error response from daemon: plugin %s failed with error: %s: %s", testAuthZPlugin, authorization.AuthZApiResponse, errorMessage), err.Error()) } func TestAuthZPluginErrorRequest(t *testing.T) { @@ -317,12 +317,12 @@ func TestAuthZPluginErrorRequest(t *testing.T) { ctrl.reqRes.Err = errorMessage client, err := d.NewClient() - require.Nil(t, err) + assert.NilError(t, err) // Ensure command is blocked _, err = client.ServerVersion(context.Background()) - require.NotNil(t, err) - require.Equal(t, fmt.Sprintf("Error response from daemon: plugin %s failed with error: %s: %s", testAuthZPlugin, authorization.AuthZApiRequest, errorMessage), err.Error()) + assert.Assert(t, err != nil) + assert.Equal(t, fmt.Sprintf("Error response from daemon: plugin %s failed with error: %s: %s", testAuthZPlugin, authorization.AuthZApiRequest, errorMessage), err.Error()) } func TestAuthZPluginEnsureNoDuplicatePluginRegistration(t *testing.T) { @@ -333,14 +333,14 @@ func TestAuthZPluginEnsureNoDuplicatePluginRegistration(t *testing.T) { ctrl.resRes.Allow = true client, err := d.NewClient() - require.Nil(t, err) + assert.NilError(t, err) _, err = client.ServerVersion(context.Background()) - require.Nil(t, err) + assert.NilError(t, err) // assert plugin is only called once.. - require.Equal(t, 1, ctrl.versionReqCount) - require.Equal(t, 1, ctrl.versionResCount) + assert.Equal(t, 1, ctrl.versionReqCount) + assert.Equal(t, 1, ctrl.versionResCount) } func TestAuthZPluginEnsureLoadImportWorking(t *testing.T) { @@ -350,36 +350,36 @@ func TestAuthZPluginEnsureLoadImportWorking(t *testing.T) { d.StartWithBusybox(t, "--authorization-plugin="+testAuthZPlugin, "--authorization-plugin="+testAuthZPlugin) client, err := d.NewClient() - require.Nil(t, err) + assert.NilError(t, err) ctx := context.Background() tmp, err := ioutil.TempDir("", "test-authz-load-import") - require.Nil(t, err) + assert.NilError(t, err) defer os.RemoveAll(tmp) savedImagePath := filepath.Join(tmp, "save.tar") err = imageSave(client, savedImagePath, "busybox") - require.Nil(t, err) + assert.NilError(t, err) err = imageLoad(client, savedImagePath) - require.Nil(t, err) + assert.NilError(t, err) exportedImagePath := filepath.Join(tmp, "export.tar") cID := container.Run(t, ctx, client) responseReader, err := client.ContainerExport(context.Background(), cID) - require.Nil(t, err) + assert.NilError(t, err) defer responseReader.Close() file, err := os.Create(exportedImagePath) - require.Nil(t, err) + assert.NilError(t, err) defer file.Close() _, err = io.Copy(file, responseReader) - require.Nil(t, err) + assert.NilError(t, err) err = imageImport(client, exportedImagePath) - require.Nil(t, err) + assert.NilError(t, err) } func imageSave(client client.APIClient, path, image string) error { @@ -442,16 +442,16 @@ func TestAuthZPluginHeader(t *testing.T) { d.StartWithBusybox(t, "--debug", "--authorization-plugin="+testAuthZPlugin) daemonURL, err := url.Parse(d.Sock()) - require.Nil(t, err) + assert.NilError(t, err) conn, err := net.DialTimeout(daemonURL.Scheme, daemonURL.Path, time.Second*10) - require.Nil(t, err) + assert.NilError(t, err) client := httputil.NewClientConn(conn, nil) req, err := http.NewRequest("GET", "/version", nil) - require.Nil(t, err) + assert.NilError(t, err) resp, err := client.Do(req) - require.Nil(t, err) - require.Equal(t, "application/json", resp.Header["Content-Type"][0]) + assert.NilError(t, err) + assert.Equal(t, "application/json", resp.Header["Content-Type"][0]) } // assertURIRecorded verifies that the given URI was sent and recorded diff --git a/components/engine/integration/plugin/authz/authz_plugin_v2_test.go b/components/engine/integration/plugin/authz/authz_plugin_v2_test.go index 5efa421e88f..fa3d37dc8c4 100644 --- a/components/engine/integration/plugin/authz/authz_plugin_v2_test.go +++ b/components/engine/integration/plugin/authz/authz_plugin_v2_test.go @@ -16,8 +16,8 @@ import ( "github.com/docker/docker/client" "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/requirement" + "github.com/gotestyourself/gotestyourself/assert" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/require" ) var ( @@ -44,13 +44,13 @@ func TestAuthZPluginV2AllowNonVolumeRequest(t *testing.T) { defer setupTestV2(t)() client, err := d.NewClient() - require.Nil(t, err) + assert.NilError(t, err) ctx := context.Background() // Install authz plugin err = pluginInstallGrantAllPermissions(client, authzPluginNameWithTag) - require.Nil(t, err) + assert.NilError(t, err) // start the daemon with the plugin and load busybox, --net=none build fails otherwise // because it needs to pull busybox d.Restart(t, "--authorization-plugin="+authzPluginNameWithTag) @@ -60,7 +60,7 @@ func TestAuthZPluginV2AllowNonVolumeRequest(t *testing.T) { cID := container.Run(t, ctx, client) _, err = client.ContainerInspect(ctx, cID) - require.Nil(t, err) + assert.NilError(t, err) } func TestAuthZPluginV2Disable(t *testing.T) { @@ -68,26 +68,26 @@ func TestAuthZPluginV2Disable(t *testing.T) { defer setupTestV2(t)() client, err := d.NewClient() - require.Nil(t, err) + assert.NilError(t, err) // Install authz plugin err = pluginInstallGrantAllPermissions(client, authzPluginNameWithTag) - require.Nil(t, err) + assert.NilError(t, err) d.Restart(t, "--authorization-plugin="+authzPluginNameWithTag) d.LoadBusybox(t) _, err = client.VolumeCreate(context.Background(), volumetypes.VolumesCreateBody{Driver: "local"}) - require.NotNil(t, err) - require.True(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) + assert.Assert(t, err != nil) + assert.Assert(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) // disable the plugin err = client.PluginDisable(context.Background(), authzPluginNameWithTag, types.PluginDisableOptions{}) - require.Nil(t, err) + assert.NilError(t, err) // now test to see if the docker api works. _, err = client.VolumeCreate(context.Background(), volumetypes.VolumesCreateBody{Driver: "local"}) - require.Nil(t, err) + assert.NilError(t, err) } func TestAuthZPluginV2RejectVolumeRequests(t *testing.T) { @@ -95,35 +95,35 @@ func TestAuthZPluginV2RejectVolumeRequests(t *testing.T) { defer setupTestV2(t)() client, err := d.NewClient() - require.Nil(t, err) + assert.NilError(t, err) // Install authz plugin err = pluginInstallGrantAllPermissions(client, authzPluginNameWithTag) - require.Nil(t, err) + assert.NilError(t, err) // restart the daemon with the plugin d.Restart(t, "--authorization-plugin="+authzPluginNameWithTag) _, err = client.VolumeCreate(context.Background(), volumetypes.VolumesCreateBody{Driver: "local"}) - require.NotNil(t, err) - require.True(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) + assert.Assert(t, err != nil) + assert.Assert(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) _, err = client.VolumeList(context.Background(), filters.Args{}) - require.NotNil(t, err) - require.True(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) + assert.Assert(t, err != nil) + assert.Assert(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) // The plugin will block the command before it can determine the volume does not exist err = client.VolumeRemove(context.Background(), "test", false) - require.NotNil(t, err) - require.True(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) + assert.Assert(t, err != nil) + assert.Assert(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) _, err = client.VolumeInspect(context.Background(), "test") - require.NotNil(t, err) - require.True(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) + assert.Assert(t, err != nil) + assert.Assert(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) _, err = client.VolumesPrune(context.Background(), filters.Args{}) - require.NotNil(t, err) - require.True(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) + assert.Assert(t, err != nil) + assert.Assert(t, strings.Contains(err.Error(), fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))) } func TestAuthZPluginV2BadManifestFailsDaemonStart(t *testing.T) { @@ -131,15 +131,15 @@ func TestAuthZPluginV2BadManifestFailsDaemonStart(t *testing.T) { defer setupTestV2(t)() client, err := d.NewClient() - require.Nil(t, err) + assert.NilError(t, err) // Install authz plugin with bad manifest err = pluginInstallGrantAllPermissions(client, authzPluginBadManifestName) - require.Nil(t, err) + assert.NilError(t, err) // start the daemon with the plugin, it will error err = d.RestartWithError("--authorization-plugin=" + authzPluginBadManifestName) - require.NotNil(t, err) + assert.Assert(t, err != nil) // restarting the daemon without requiring the plugin will succeed d.Start(t) @@ -150,7 +150,7 @@ func TestAuthZPluginV2NonexistentFailsDaemonStart(t *testing.T) { // start the daemon with a non-existent authz plugin, it will error err := d.RestartWithError("--authorization-plugin=" + nonexistentAuthzPluginName) - require.NotNil(t, err) + assert.Assert(t, err != nil) // restarting the daemon without requiring the plugin will succeed d.Start(t) diff --git a/components/engine/integration/plugin/logging/validation_test.go b/components/engine/integration/plugin/logging/validation_test.go index 66073216132..eb3fe7a029e 100644 --- a/components/engine/integration/plugin/logging/validation_test.go +++ b/components/engine/integration/plugin/logging/validation_test.go @@ -6,7 +6,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/integration-cli/daemon" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" ) // Regression test for #35553 @@ -20,12 +20,12 @@ func TestDaemonStartWithLogOpt(t *testing.T) { defer d.Stop(t) client, err := d.NewClient() - assert.NoError(t, err) + assert.Check(t, err) ctx := context.Background() createPlugin(t, client, "test", "dummy", asLogDriver) err = client.PluginEnable(ctx, "test", types.PluginEnableOptions{Timeout: 30}) - assert.NoError(t, err) + assert.Check(t, err) defer client.PluginRemove(ctx, "test", types.PluginRemoveOptions{Force: true}) d.Stop(t) diff --git a/components/engine/integration/secret/secret_test.go b/components/engine/integration/secret/secret_test.go index 8a292f005b2..91f70c49277 100644 --- a/components/engine/integration/secret/secret_test.go +++ b/components/engine/integration/secret/secret_test.go @@ -13,9 +13,9 @@ import ( "github.com/docker/docker/integration/internal/swarm" "github.com/docker/docker/internal/testutil" "github.com/docker/docker/pkg/stdcopy" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "golang.org/x/net/context" ) @@ -26,7 +26,7 @@ func TestSecretInspect(t *testing.T) { d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - require.NoError(t, err) + assert.NilError(t, err) ctx := context.Background() @@ -34,12 +34,12 @@ func TestSecretInspect(t *testing.T) { secretID := createSecret(ctx, t, client, testName, []byte("TESTINGDATA"), nil) secret, _, err := client.SecretInspectWithRaw(context.Background(), secretID) - require.NoError(t, err) - assert.Equal(t, secret.Spec.Name, testName) + assert.NilError(t, err) + assert.Check(t, is.Equal(secret.Spec.Name, testName)) secret, _, err = client.SecretInspectWithRaw(context.Background(), testName) - require.NoError(t, err) - assert.Equal(t, secretID, secretID) + assert.NilError(t, err) + assert.Check(t, is.Equal(secretID, secretID)) } func TestSecretList(t *testing.T) { @@ -49,7 +49,7 @@ func TestSecretList(t *testing.T) { d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - require.NoError(t, err) + assert.NilError(t, err) ctx := context.Background() @@ -75,8 +75,8 @@ func TestSecretList(t *testing.T) { // test by `secret ls` entries, err := client.SecretList(ctx, types.SecretListOptions{}) - require.NoError(t, err) - assert.Equal(t, names(entries), testNames) + assert.NilError(t, err) + assert.Check(t, is.DeepEqual(names(entries), testNames)) testCases := []struct { filters filters.Args @@ -110,8 +110,8 @@ func TestSecretList(t *testing.T) { entries, err = client.SecretList(ctx, types.SecretListOptions{ Filters: tc.filters, }) - require.NoError(t, err) - assert.Equal(t, names(entries), tc.expected) + assert.NilError(t, err) + assert.Check(t, is.DeepEqual(names(entries), tc.expected)) } } @@ -124,8 +124,8 @@ func createSecret(ctx context.Context, t *testing.T, client client.APIClient, na }, Data: data, }) - require.NoError(t, err) - assert.NotEqual(t, secret.ID, "") + assert.NilError(t, err) + assert.Check(t, secret.ID != "") return secret.ID } @@ -136,7 +136,7 @@ func TestSecretsCreateAndDelete(t *testing.T) { d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - require.NoError(t, err) + assert.NilError(t, err) ctx := context.Background() @@ -154,7 +154,7 @@ func TestSecretsCreateAndDelete(t *testing.T) { // Ported from original TestSecretsDelete err = client.SecretRemove(ctx, secretID) - require.NoError(t, err) + assert.NilError(t, err) _, _, err = client.SecretInspectWithRaw(ctx, secretID) testutil.ErrorContains(t, err, "No such secret") @@ -170,11 +170,11 @@ func TestSecretsCreateAndDelete(t *testing.T) { }) insp, _, err := client.SecretInspectWithRaw(ctx, secretID) - require.NoError(t, err) - assert.Equal(t, insp.Spec.Name, testName) - assert.Equal(t, len(insp.Spec.Labels), 2) - assert.Equal(t, insp.Spec.Labels["key1"], "value1") - assert.Equal(t, insp.Spec.Labels["key2"], "value2") + assert.NilError(t, err) + assert.Check(t, is.Equal(insp.Spec.Name, testName)) + assert.Check(t, is.Equal(len(insp.Spec.Labels), 2)) + assert.Check(t, is.Equal(insp.Spec.Labels["key1"], "value1")) + assert.Check(t, is.Equal(insp.Spec.Labels["key2"], "value2")) } func TestSecretsUpdate(t *testing.T) { @@ -184,44 +184,44 @@ func TestSecretsUpdate(t *testing.T) { d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - require.NoError(t, err) + assert.NilError(t, err) ctx := context.Background() testName := "test_secret" secretID := createSecret(ctx, t, client, testName, []byte("TESTINGDATA"), nil) - require.NoError(t, err) + assert.NilError(t, err) insp, _, err := client.SecretInspectWithRaw(ctx, secretID) - require.NoError(t, err) - assert.Equal(t, insp.ID, secretID) + assert.NilError(t, err) + assert.Check(t, is.Equal(insp.ID, secretID)) // test UpdateSecret with full ID insp.Spec.Labels = map[string]string{"test": "test1"} err = client.SecretUpdate(ctx, secretID, insp.Version, insp.Spec) - require.NoError(t, err) + assert.NilError(t, err) insp, _, err = client.SecretInspectWithRaw(ctx, secretID) - require.NoError(t, err) - assert.Equal(t, insp.Spec.Labels["test"], "test1") + assert.NilError(t, err) + assert.Check(t, is.Equal(insp.Spec.Labels["test"], "test1")) // test UpdateSecret with full name insp.Spec.Labels = map[string]string{"test": "test2"} err = client.SecretUpdate(ctx, testName, insp.Version, insp.Spec) - require.NoError(t, err) + assert.NilError(t, err) insp, _, err = client.SecretInspectWithRaw(ctx, secretID) - require.NoError(t, err) - assert.Equal(t, insp.Spec.Labels["test"], "test2") + assert.NilError(t, err) + assert.Check(t, is.Equal(insp.Spec.Labels["test"], "test2")) // test UpdateSecret with prefix ID insp.Spec.Labels = map[string]string{"test": "test3"} err = client.SecretUpdate(ctx, secretID[:1], insp.Version, insp.Spec) - require.NoError(t, err) + assert.NilError(t, err) insp, _, err = client.SecretInspectWithRaw(ctx, secretID) - require.NoError(t, err) - assert.Equal(t, insp.Spec.Labels["test"], "test3") + assert.NilError(t, err) + assert.Check(t, is.Equal(insp.Spec.Labels["test"], "test3")) // test UpdateSecret in updating Data which is not supported in daemon // this test will produce an error in func UpdateSecret @@ -244,7 +244,7 @@ func TestTemplatedSecret(t *testing.T) { Data: []byte("this is a secret"), } referencedSecret, err := client.SecretCreate(ctx, referencedSecretSpec) - assert.NoError(t, err) + assert.Check(t, err) referencedConfigSpec := swarmtypes.ConfigSpec{ Annotations: swarmtypes.Annotations{ @@ -253,7 +253,7 @@ func TestTemplatedSecret(t *testing.T) { Data: []byte("this is a config"), } referencedConfig, err := client.ConfigCreate(ctx, referencedConfigSpec) - assert.NoError(t, err) + assert.Check(t, err) secretSpec := swarmtypes.SecretSpec{ Annotations: swarmtypes.Annotations{ @@ -268,7 +268,7 @@ func TestTemplatedSecret(t *testing.T) { } templatedSecret, err := client.SecretCreate(ctx, secretSpec) - assert.NoError(t, err) + assert.Check(t, err) serviceID := swarm.CreateService(t, d, swarm.ServiceWithSecret( @@ -346,8 +346,8 @@ func TestTemplatedSecret(t *testing.T) { func assertAttachedStream(t *testing.T, attach types.HijackedResponse, expect string) { buf := bytes.NewBuffer(nil) _, err := stdcopy.StdCopy(buf, buf, attach.Reader) - require.NoError(t, err) - assert.Contains(t, buf.String(), expect) + assert.NilError(t, err) + assert.Check(t, is.Contains(buf.String(), expect)) } func waitAndAssert(t *testing.T, timeout time.Duration, f func(*testing.T) bool) { diff --git a/components/engine/integration/service/create_test.go b/components/engine/integration/service/create_test.go index eb66cfc2f1f..7170bda492e 100644 --- a/components/engine/integration/service/create_test.go +++ b/components/engine/integration/service/create_test.go @@ -11,9 +11,9 @@ import ( swarmtypes "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" "github.com/docker/docker/integration/internal/swarm" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/poll" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "golang.org/x/net/context" ) @@ -22,7 +22,7 @@ func TestCreateServiceMultipleTimes(t *testing.T) { d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - require.NoError(t, err) + assert.NilError(t, err) overlayName := "overlay1" networkCreate := types.NetworkCreate{ @@ -31,7 +31,7 @@ func TestCreateServiceMultipleTimes(t *testing.T) { } netResp, err := client.NetworkCreate(context.Background(), overlayName, networkCreate) - require.NoError(t, err) + assert.NilError(t, err) overlayID := netResp.ID var instances uint64 = 4 @@ -41,7 +41,7 @@ func TestCreateServiceMultipleTimes(t *testing.T) { serviceResp, err := client.ServiceCreate(context.Background(), serviceSpec, types.ServiceCreateOptions{ QueryRegistry: false, }) - require.NoError(t, err) + assert.NilError(t, err) pollSettings := func(config *poll.Settings) { // It takes about ~25s to finish the multi services creation in this case per the pratical observation on arm64/arm platform @@ -55,10 +55,10 @@ func TestCreateServiceMultipleTimes(t *testing.T) { poll.WaitOn(t, serviceRunningTasksCount(client, serviceID, instances), pollSettings) _, _, err = client.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{}) - require.NoError(t, err) + assert.NilError(t, err) err = client.ServiceRemove(context.Background(), serviceID) - require.NoError(t, err) + assert.NilError(t, err) poll.WaitOn(t, serviceIsRemoved(client, serviceID), pollSettings) poll.WaitOn(t, noTasks(client), pollSettings) @@ -66,19 +66,19 @@ func TestCreateServiceMultipleTimes(t *testing.T) { serviceResp, err = client.ServiceCreate(context.Background(), serviceSpec, types.ServiceCreateOptions{ QueryRegistry: false, }) - require.NoError(t, err) + assert.NilError(t, err) serviceID2 := serviceResp.ID poll.WaitOn(t, serviceRunningTasksCount(client, serviceID2, instances), pollSettings) err = client.ServiceRemove(context.Background(), serviceID2) - require.NoError(t, err) + assert.NilError(t, err) poll.WaitOn(t, serviceIsRemoved(client, serviceID2), pollSettings) poll.WaitOn(t, noTasks(client), pollSettings) err = client.NetworkRemove(context.Background(), overlayID) - require.NoError(t, err) + assert.NilError(t, err) poll.WaitOn(t, networkIsRemoved(client, overlayID), poll.WithTimeout(1*time.Minute), poll.WithDelay(10*time.Second)) } @@ -88,7 +88,7 @@ func TestCreateWithDuplicateNetworkNames(t *testing.T) { d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - require.NoError(t, err) + assert.NilError(t, err) name := "foo" networkCreate := types.NetworkCreate{ @@ -97,15 +97,15 @@ func TestCreateWithDuplicateNetworkNames(t *testing.T) { } n1, err := client.NetworkCreate(context.Background(), name, networkCreate) - require.NoError(t, err) + assert.NilError(t, err) n2, err := client.NetworkCreate(context.Background(), name, networkCreate) - require.NoError(t, err) + assert.NilError(t, err) // Dupliates with name but with different driver networkCreate.Driver = "overlay" n3, err := client.NetworkCreate(context.Background(), name, networkCreate) - require.NoError(t, err) + assert.NilError(t, err) // Create Service with the same name var instances uint64 = 1 @@ -114,30 +114,30 @@ func TestCreateWithDuplicateNetworkNames(t *testing.T) { serviceSpec.TaskTemplate.Networks = append(serviceSpec.TaskTemplate.Networks, swarmtypes.NetworkAttachmentConfig{Target: name}) service, err := client.ServiceCreate(context.Background(), serviceSpec, types.ServiceCreateOptions{}) - require.NoError(t, err) + assert.NilError(t, err) poll.WaitOn(t, serviceRunningTasksCount(client, service.ID, instances)) resp, _, err := client.ServiceInspectWithRaw(context.Background(), service.ID, types.ServiceInspectOptions{}) - require.NoError(t, err) - assert.Equal(t, n3.ID, resp.Spec.TaskTemplate.Networks[0].Target) + assert.NilError(t, err) + assert.Check(t, is.Equal(n3.ID, resp.Spec.TaskTemplate.Networks[0].Target)) // Remove Service err = client.ServiceRemove(context.Background(), service.ID) - require.NoError(t, err) + assert.NilError(t, err) // Make sure task has been destroyed. poll.WaitOn(t, serviceIsRemoved(client, service.ID)) // Remove networks err = client.NetworkRemove(context.Background(), n3.ID) - require.NoError(t, err) + assert.NilError(t, err) err = client.NetworkRemove(context.Background(), n2.ID) - require.NoError(t, err) + assert.NilError(t, err) err = client.NetworkRemove(context.Background(), n1.ID) - require.NoError(t, err) + assert.NilError(t, err) // Make sure networks have been destroyed. poll.WaitOn(t, networkIsRemoved(client, n3.ID), poll.WithTimeout(1*time.Minute), poll.WithDelay(10*time.Second)) @@ -150,7 +150,7 @@ func TestCreateServiceSecretFileMode(t *testing.T) { d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - require.NoError(t, err) + assert.NilError(t, err) ctx := context.Background() secretResp, err := client.SecretCreate(ctx, swarmtypes.SecretSpec{ @@ -159,7 +159,7 @@ func TestCreateServiceSecretFileMode(t *testing.T) { }, Data: []byte("TESTSECRET"), }) - require.NoError(t, err) + assert.NilError(t, err) var instances uint64 = 1 serviceSpec := swarmtypes.ServiceSpec{ @@ -194,7 +194,7 @@ func TestCreateServiceSecretFileMode(t *testing.T) { serviceResp, err := client.ServiceCreate(ctx, serviceSpec, types.ServiceCreateOptions{ QueryRegistry: false, }) - require.NoError(t, err) + assert.NilError(t, err) poll.WaitOn(t, serviceRunningTasksCount(client, serviceResp.ID, instances)) @@ -203,27 +203,27 @@ func TestCreateServiceSecretFileMode(t *testing.T) { tasks, err := client.TaskList(ctx, types.TaskListOptions{ Filters: filter, }) - require.NoError(t, err) - assert.Equal(t, len(tasks), 1) + assert.NilError(t, err) + assert.Check(t, is.Equal(len(tasks), 1)) body, err := client.ContainerLogs(ctx, tasks[0].Status.ContainerStatus.ContainerID, types.ContainerLogsOptions{ ShowStdout: true, }) - require.NoError(t, err) + assert.NilError(t, err) defer body.Close() content, err := ioutil.ReadAll(body) - require.NoError(t, err) - assert.Contains(t, string(content), "-rwxrwxrwx") + assert.NilError(t, err) + assert.Check(t, is.Contains(string(content), "-rwxrwxrwx")) err = client.ServiceRemove(ctx, serviceResp.ID) - require.NoError(t, err) + assert.NilError(t, err) poll.WaitOn(t, serviceIsRemoved(client, serviceResp.ID)) poll.WaitOn(t, noTasks(client)) err = client.SecretRemove(ctx, "TestSecret") - require.NoError(t, err) + assert.NilError(t, err) } func TestCreateServiceConfigFileMode(t *testing.T) { @@ -231,7 +231,7 @@ func TestCreateServiceConfigFileMode(t *testing.T) { d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - require.NoError(t, err) + assert.NilError(t, err) ctx := context.Background() configResp, err := client.ConfigCreate(ctx, swarmtypes.ConfigSpec{ @@ -240,7 +240,7 @@ func TestCreateServiceConfigFileMode(t *testing.T) { }, Data: []byte("TESTCONFIG"), }) - require.NoError(t, err) + assert.NilError(t, err) var instances uint64 = 1 serviceSpec := swarmtypes.ServiceSpec{ @@ -275,7 +275,7 @@ func TestCreateServiceConfigFileMode(t *testing.T) { serviceResp, err := client.ServiceCreate(ctx, serviceSpec, types.ServiceCreateOptions{ QueryRegistry: false, }) - require.NoError(t, err) + assert.NilError(t, err) poll.WaitOn(t, serviceRunningTasksCount(client, serviceResp.ID, instances)) @@ -284,27 +284,27 @@ func TestCreateServiceConfigFileMode(t *testing.T) { tasks, err := client.TaskList(ctx, types.TaskListOptions{ Filters: filter, }) - require.NoError(t, err) - assert.Equal(t, len(tasks), 1) + assert.NilError(t, err) + assert.Check(t, is.Equal(len(tasks), 1)) body, err := client.ContainerLogs(ctx, tasks[0].Status.ContainerStatus.ContainerID, types.ContainerLogsOptions{ ShowStdout: true, }) - require.NoError(t, err) + assert.NilError(t, err) defer body.Close() content, err := ioutil.ReadAll(body) - require.NoError(t, err) - assert.Contains(t, string(content), "-rwxrwxrwx") + assert.NilError(t, err) + assert.Check(t, is.Contains(string(content), "-rwxrwxrwx")) err = client.ServiceRemove(ctx, serviceResp.ID) - require.NoError(t, err) + assert.NilError(t, err) poll.WaitOn(t, serviceIsRemoved(client, serviceResp.ID)) poll.WaitOn(t, noTasks(client)) err = client.ConfigRemove(ctx, "TestConfig") - require.NoError(t, err) + assert.NilError(t, err) } func swarmServiceSpec(name string, replicas uint64) swarmtypes.ServiceSpec { diff --git a/components/engine/integration/service/inspect_test.go b/components/engine/integration/service/inspect_test.go index 8cd24bc31b6..3a5b99d3ac2 100644 --- a/components/engine/integration/service/inspect_test.go +++ b/components/engine/integration/service/inspect_test.go @@ -10,10 +10,10 @@ import ( swarmtypes "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" "github.com/docker/docker/integration/internal/swarm" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/poll" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "golang.org/x/net/context" ) @@ -23,7 +23,7 @@ func TestInspect(t *testing.T) { d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - require.NoError(t, err) + assert.NilError(t, err) var before = time.Now() var instances uint64 = 2 @@ -33,16 +33,16 @@ func TestInspect(t *testing.T) { resp, err := client.ServiceCreate(ctx, serviceSpec, types.ServiceCreateOptions{ QueryRegistry: false, }) - require.NoError(t, err) + assert.NilError(t, err) id := resp.ID poll.WaitOn(t, serviceContainerCount(client, id, instances)) service, _, err := client.ServiceInspectWithRaw(ctx, id, types.ServiceInspectOptions{}) - require.NoError(t, err) - assert.Equal(t, serviceSpec, service.Spec) - assert.Equal(t, uint64(11), service.Meta.Version.Index) - assert.Equal(t, id, service.ID) + assert.NilError(t, err) + assert.Check(t, is.DeepEqual(serviceSpec, service.Spec)) + assert.Check(t, is.Equal(uint64(11), service.Meta.Version.Index)) + assert.Check(t, is.Equal(id, service.ID)) assert.WithinDuration(t, before, service.CreatedAt, 30*time.Second) assert.WithinDuration(t, before, service.UpdatedAt, 30*time.Second) } diff --git a/components/engine/integration/service/network_test.go b/components/engine/integration/service/network_test.go index 09b0a1f12b1..6b8c891cd84 100644 --- a/components/engine/integration/service/network_test.go +++ b/components/engine/integration/service/network_test.go @@ -9,8 +9,8 @@ import ( "github.com/docker/docker/client" "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/swarm" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestDockerNetworkConnectAlias(t *testing.T) { @@ -18,7 +18,7 @@ func TestDockerNetworkConnectAlias(t *testing.T) { d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - require.NoError(t, err) + assert.NilError(t, err) ctx := context.Background() name := "test-alias" @@ -26,7 +26,7 @@ func TestDockerNetworkConnectAlias(t *testing.T) { Driver: "overlay", Attachable: true, }) - require.NoError(t, err) + assert.NilError(t, err) container.Create(t, ctx, client, container.WithName("ng1"), func(c *container.TestContainerConfig) { c.NetworkingConfig = &network.NetworkingConfig{ @@ -41,15 +41,15 @@ func TestDockerNetworkConnectAlias(t *testing.T) { "aaa", }, }) - require.NoError(t, err) + assert.NilError(t, err) err = client.ContainerStart(ctx, "ng1", types.ContainerStartOptions{}) - require.NoError(t, err) + assert.NilError(t, err) ng1, err := client.ContainerInspect(ctx, "ng1") - require.NoError(t, err) - assert.Equal(t, len(ng1.NetworkSettings.Networks[name].Aliases), 2) - assert.Equal(t, ng1.NetworkSettings.Networks[name].Aliases[0], "aaa") + assert.NilError(t, err) + assert.Check(t, is.Equal(len(ng1.NetworkSettings.Networks[name].Aliases), 2)) + assert.Check(t, is.Equal(ng1.NetworkSettings.Networks[name].Aliases[0], "aaa")) container.Create(t, ctx, client, container.WithName("ng2"), func(c *container.TestContainerConfig) { c.NetworkingConfig = &network.NetworkingConfig{ @@ -64,13 +64,13 @@ func TestDockerNetworkConnectAlias(t *testing.T) { "bbb", }, }) - require.NoError(t, err) + assert.NilError(t, err) err = client.ContainerStart(ctx, "ng2", types.ContainerStartOptions{}) - require.NoError(t, err) + assert.NilError(t, err) ng2, err := client.ContainerInspect(ctx, "ng2") - require.NoError(t, err) - assert.Equal(t, len(ng2.NetworkSettings.Networks[name].Aliases), 2) - assert.Equal(t, ng2.NetworkSettings.Networks[name].Aliases[0], "bbb") + assert.NilError(t, err) + assert.Check(t, is.Equal(len(ng2.NetworkSettings.Networks[name].Aliases), 2)) + assert.Check(t, is.Equal(ng2.NetworkSettings.Networks[name].Aliases[0], "bbb")) } diff --git a/components/engine/integration/session/session_test.go b/components/engine/integration/session/session_test.go index 310f544554d..de9319436e3 100644 --- a/components/engine/integration/session/session_test.go +++ b/components/engine/integration/session/session_test.go @@ -5,9 +5,9 @@ import ( "testing" req "github.com/docker/docker/integration-cli/request" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestSessionCreate(t *testing.T) { @@ -20,29 +20,29 @@ func TestSessionCreate(t *testing.T) { r.Header.Set("Upgrade", "h2c") return nil }) - require.NoError(t, err) - require.NoError(t, body.Close()) - assert.Equal(t, res.StatusCode, http.StatusSwitchingProtocols) - assert.Equal(t, res.Header.Get("Upgrade"), "h2c") + assert.NilError(t, err) + assert.NilError(t, body.Close()) + assert.Check(t, is.DeepEqual(res.StatusCode, http.StatusSwitchingProtocols)) + assert.Check(t, is.Equal(res.Header.Get("Upgrade"), "h2c")) } func TestSessionCreateWithBadUpgrade(t *testing.T) { skip.If(t, !testEnv.DaemonInfo.ExperimentalBuild) res, body, err := req.Post("/session") - require.NoError(t, err) - assert.Equal(t, res.StatusCode, http.StatusBadRequest) + assert.NilError(t, err) + assert.Check(t, is.DeepEqual(res.StatusCode, http.StatusBadRequest)) buf, err := req.ReadBody(body) - require.NoError(t, err) - assert.Contains(t, string(buf), "no upgrade") + assert.NilError(t, err) + assert.Check(t, is.Contains(string(buf), "no upgrade")) res, body, err = req.Post("/session", func(r *http.Request) error { r.Header.Set("Upgrade", "foo") return nil }) - require.NoError(t, err) - assert.Equal(t, res.StatusCode, http.StatusBadRequest) + assert.NilError(t, err) + assert.Check(t, is.DeepEqual(res.StatusCode, http.StatusBadRequest)) buf, err = req.ReadBody(body) - require.NoError(t, err) - assert.Contains(t, string(buf), "not supported") + assert.NilError(t, err) + assert.Check(t, is.Contains(string(buf), "not supported")) } diff --git a/components/engine/integration/system/event_test.go b/components/engine/integration/system/event_test.go index 688d7c27def..b270ffcb91f 100644 --- a/components/engine/integration/system/event_test.go +++ b/components/engine/integration/system/event_test.go @@ -17,8 +17,8 @@ import ( "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" "github.com/docker/docker/pkg/jsonmessage" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestEvents(t *testing.T) { @@ -33,7 +33,7 @@ func TestEvents(t *testing.T) { Cmd: strslice.StrSlice([]string{"echo", "hello"}), }, ) - require.NoError(t, err) + assert.NilError(t, err) filters := filters.NewArgs( filters.Arg("container", cID), @@ -49,15 +49,15 @@ func TestEvents(t *testing.T) { Tty: false, }, ) - require.NoError(t, err) + assert.NilError(t, err) select { case m := <-msg: - require.Equal(t, m.Type, "container") - require.Equal(t, m.Actor.ID, cID) - require.Equal(t, m.Action, "exec_die") - require.Equal(t, m.Actor.Attributes["execID"], id.ID) - require.Equal(t, m.Actor.Attributes["exitCode"], "0") + assert.Equal(t, m.Type, "container") + assert.Equal(t, m.Actor.ID, cID) + assert.Equal(t, m.Action, "exec_die") + assert.Equal(t, m.Actor.Attributes["execID"], id.ID) + assert.Equal(t, m.Actor.Attributes["exitCode"], "0") case err = <-errors: t.Fatal(err) case <-time.After(time.Second * 3): @@ -84,16 +84,16 @@ func TestEventsBackwardsCompatible(t *testing.T) { // The test here makes sure the response time is less than 3 sec. expectedTime := time.Now().Add(3 * time.Second) emptyResp, emptyBody, err := req.Get("/events") - require.NoError(t, err) + assert.NilError(t, err) defer emptyBody.Close() - assert.Equal(t, http.StatusOK, emptyResp.StatusCode) - assert.True(t, time.Now().Before(expectedTime), "timeout waiting for events api to respond, should have responded immediately") + assert.Check(t, is.DeepEqual(http.StatusOK, emptyResp.StatusCode)) + assert.Check(t, time.Now().Before(expectedTime), "timeout waiting for events api to respond, should have responded immediately") // We also test to make sure the `events.Message` is compatible with `JSONMessage` q := url.Values{} q.Set("since", ts) _, body, err := req.Get("/events?" + q.Encode()) - require.NoError(t, err) + assert.NilError(t, err) defer body.Close() dec := json.NewDecoder(body) @@ -112,8 +112,8 @@ func TestEventsBackwardsCompatible(t *testing.T) { } } - assert.NotNil(t, containerCreateEvent) - assert.Equal(t, "create", containerCreateEvent.Status) - assert.Equal(t, cID, containerCreateEvent.ID) - assert.Equal(t, "busybox", containerCreateEvent.From) + assert.Check(t, containerCreateEvent != nil) + assert.Check(t, is.Equal("create", containerCreateEvent.Status)) + assert.Check(t, is.Equal(cID, containerCreateEvent.ID)) + assert.Check(t, is.Equal("busybox", containerCreateEvent.From)) } diff --git a/components/engine/integration/system/info_linux_test.go b/components/engine/integration/system/info_linux_test.go index 8f0271e7a6f..ad8dc2f9e29 100644 --- a/components/engine/integration/system/info_linux_test.go +++ b/components/engine/integration/system/info_linux_test.go @@ -8,8 +8,8 @@ import ( req "github.com/docker/docker/integration-cli/request" "github.com/docker/docker/integration/internal/request" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -17,35 +17,35 @@ func TestInfoBinaryCommits(t *testing.T) { client := request.NewAPIClient(t) info, err := client.Info(context.Background()) - require.NoError(t, err) - - assert.NotNil(t, info.ContainerdCommit) - assert.NotEqual(t, "N/A", info.ContainerdCommit.ID) - assert.Equal(t, testEnv.DaemonInfo.ContainerdCommit.Expected, info.ContainerdCommit.Expected) - assert.Equal(t, info.ContainerdCommit.Expected, info.ContainerdCommit.ID) - - assert.NotNil(t, info.InitCommit) - assert.NotEqual(t, "N/A", info.InitCommit.ID) - assert.Equal(t, testEnv.DaemonInfo.InitCommit.Expected, info.InitCommit.Expected) - assert.Equal(t, info.InitCommit.Expected, info.InitCommit.ID) - - assert.NotNil(t, info.RuncCommit) - assert.NotEqual(t, "N/A", info.RuncCommit.ID) - assert.Equal(t, testEnv.DaemonInfo.RuncCommit.Expected, info.RuncCommit.Expected) - assert.Equal(t, info.RuncCommit.Expected, info.RuncCommit.ID) + assert.NilError(t, err) + + assert.Check(t, info.ContainerdCommit != nil) + assert.Check(t, "N/A" != info.ContainerdCommit.ID) + assert.Check(t, is.Equal(testEnv.DaemonInfo.ContainerdCommit.Expected, info.ContainerdCommit.Expected)) + assert.Check(t, is.Equal(info.ContainerdCommit.Expected, info.ContainerdCommit.ID)) + + assert.Check(t, info.InitCommit != nil) + assert.Check(t, "N/A" != info.InitCommit.ID) + assert.Check(t, is.Equal(testEnv.DaemonInfo.InitCommit.Expected, info.InitCommit.Expected)) + assert.Check(t, is.Equal(info.InitCommit.Expected, info.InitCommit.ID)) + + assert.Check(t, info.RuncCommit != nil) + assert.Check(t, "N/A" != info.RuncCommit.ID) + assert.Check(t, is.Equal(testEnv.DaemonInfo.RuncCommit.Expected, info.RuncCommit.Expected)) + assert.Check(t, is.Equal(info.RuncCommit.Expected, info.RuncCommit.ID)) } func TestInfoAPIVersioned(t *testing.T) { // Windows only supports 1.25 or later res, body, err := req.Get("/v1.20/info") - require.NoError(t, err) - assert.Equal(t, res.StatusCode, http.StatusOK) + assert.NilError(t, err) + assert.Check(t, is.DeepEqual(res.StatusCode, http.StatusOK)) b, err := req.ReadBody(body) - require.NoError(t, err) + assert.NilError(t, err) out := string(b) - assert.Contains(t, out, "ExecutionDriver") - assert.Contains(t, out, "not supported") + assert.Check(t, is.Contains(out, "ExecutionDriver")) + assert.Check(t, is.Contains(out, "not supported")) } diff --git a/components/engine/integration/system/info_test.go b/components/engine/integration/system/info_test.go index 47c46cb8719..480301038ac 100644 --- a/components/engine/integration/system/info_test.go +++ b/components/engine/integration/system/info_test.go @@ -5,8 +5,8 @@ import ( "testing" "github.com/docker/docker/integration/internal/request" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -14,7 +14,7 @@ func TestInfoAPI(t *testing.T) { client := request.NewAPIClient(t) info, err := client.Info(context.Background()) - require.NoError(t, err) + assert.NilError(t, err) // always shown fields stringsToCheck := []string{ @@ -37,6 +37,6 @@ func TestInfoAPI(t *testing.T) { out := fmt.Sprintf("%+v", info) for _, linePrefix := range stringsToCheck { - assert.Contains(t, out, linePrefix) + assert.Check(t, is.Contains(out, linePrefix)) } } diff --git a/components/engine/integration/system/login_test.go b/components/engine/integration/system/login_test.go index c075109d2ba..e8ef10c30c6 100644 --- a/components/engine/integration/system/login_test.go +++ b/components/engine/integration/system/login_test.go @@ -6,8 +6,9 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/integration/internal/request" "github.com/docker/docker/integration/internal/requirement" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/assert" "golang.org/x/net/context" ) @@ -23,5 +24,5 @@ func TestLoginFailsWithBadCredentials(t *testing.T) { } _, err := client.RegistryLogin(context.Background(), config) expected := "Error response from daemon: Get https://registry-1.docker.io/v2/: unauthorized: incorrect username or password" - assert.EqualError(t, err, expected) + assert.Check(t, is.Error(err, expected)) } diff --git a/components/engine/integration/system/version_test.go b/components/engine/integration/system/version_test.go index 04888a604a9..a676c31802f 100644 --- a/components/engine/integration/system/version_test.go +++ b/components/engine/integration/system/version_test.go @@ -4,8 +4,8 @@ import ( "testing" "github.com/docker/docker/integration/internal/request" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -13,11 +13,11 @@ func TestVersion(t *testing.T) { client := request.NewAPIClient(t) version, err := client.ServerVersion(context.Background()) - require.NoError(t, err) + assert.NilError(t, err) - assert.NotNil(t, version.APIVersion) - assert.NotNil(t, version.Version) - assert.NotNil(t, version.MinAPIVersion) - assert.Equal(t, testEnv.DaemonInfo.ExperimentalBuild, version.Experimental) - assert.Equal(t, testEnv.OSType, version.Os) + assert.Check(t, version.APIVersion != nil) + assert.Check(t, version.Version != nil) + assert.Check(t, version.MinAPIVersion != nil) + assert.Check(t, is.Equal(testEnv.DaemonInfo.ExperimentalBuild, version.Experimental)) + assert.Check(t, is.Equal(testEnv.OSType, version.Os)) } diff --git a/components/engine/integration/volume/volume_test.go b/components/engine/integration/volume/volume_test.go index 20dcfef9a69..2fe35cf5edb 100644 --- a/components/engine/integration/volume/volume_test.go +++ b/components/engine/integration/volume/volume_test.go @@ -13,8 +13,8 @@ import ( "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" "github.com/docker/docker/internal/testutil" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestVolumesCreateAndList(t *testing.T) { @@ -26,7 +26,7 @@ func TestVolumesCreateAndList(t *testing.T) { vol, err := client.VolumeCreate(ctx, volumetypes.VolumesCreateBody{ Name: name, }) - require.NoError(t, err) + assert.NilError(t, err) expected := types.Volume{ // Ignore timestamp of CreatedAt @@ -36,14 +36,14 @@ func TestVolumesCreateAndList(t *testing.T) { Name: name, Mountpoint: fmt.Sprintf("%s/volumes/%s/_data", testEnv.DaemonInfo.DockerRootDir, name), } - assert.Equal(t, vol, expected) + assert.Check(t, is.DeepEqual(vol, expected)) volumes, err := client.VolumeList(ctx, filters.Args{}) - require.NoError(t, err) + assert.NilError(t, err) - assert.Equal(t, len(volumes.Volumes), 1) - assert.NotNil(t, volumes.Volumes[0]) - assert.Equal(t, *volumes.Volumes[0], expected) + assert.Check(t, is.Equal(len(volumes.Volumes), 1)) + assert.Check(t, volumes.Volumes[0] != nil) + assert.Check(t, is.DeepEqual(*volumes.Volumes[0], expected)) } func TestVolumesRemove(t *testing.T) { @@ -56,7 +56,7 @@ func TestVolumesRemove(t *testing.T) { id := container.Create(t, ctx, client, container.WithVolume(prefix+"foo")) c, err := client.ContainerInspect(ctx, id) - require.NoError(t, err) + assert.NilError(t, err) vname := c.Mounts[0].Name err = client.VolumeRemove(ctx, vname, false) @@ -65,10 +65,10 @@ func TestVolumesRemove(t *testing.T) { err = client.ContainerRemove(ctx, id, types.ContainerRemoveOptions{ Force: true, }) - require.NoError(t, err) + assert.NilError(t, err) err = client.VolumeRemove(ctx, vname, false) - require.NoError(t, err) + assert.NilError(t, err) } func TestVolumesInspect(t *testing.T) { @@ -83,10 +83,10 @@ func TestVolumesInspect(t *testing.T) { _, err := client.VolumeCreate(ctx, volumetypes.VolumesCreateBody{ Name: name, }) - require.NoError(t, err) + assert.NilError(t, err) vol, err := client.VolumeInspect(ctx, name) - require.NoError(t, err) + assert.NilError(t, err) expected := types.Volume{ // Ignore timestamp of CreatedAt @@ -96,13 +96,13 @@ func TestVolumesInspect(t *testing.T) { Name: name, Mountpoint: fmt.Sprintf("%s/volumes/%s/_data", testEnv.DaemonInfo.DockerRootDir, name), } - assert.Equal(t, vol, expected) + assert.Check(t, is.DeepEqual(vol, expected)) // comparing CreatedAt field time for the new volume to now. Removing a minute from both to avoid false positive testCreatedAt, err := time.Parse(time.RFC3339, strings.TrimSpace(vol.CreatedAt)) - require.NoError(t, err) + assert.NilError(t, err) testCreatedAt = testCreatedAt.Truncate(time.Minute) - assert.Equal(t, testCreatedAt.Equal(now), true, "Time Volume is CreatedAt not equal to current time") + assert.Check(t, is.Equal(testCreatedAt.Equal(now), true), "Time Volume is CreatedAt not equal to current time") } func getPrefixAndSlashFromDaemonPlatform() (prefix, slash string) { diff --git a/components/engine/internal/test/environment/clean.go b/components/engine/internal/test/environment/clean.go index 065b46bee89..d83175c8451 100644 --- a/components/engine/internal/test/environment/clean.go +++ b/components/engine/internal/test/environment/clean.go @@ -7,13 +7,12 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/client" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" "golang.org/x/net/context" ) type testingT interface { - require.TestingT + assert.TestingT logT Fatalf(string, ...interface{}) } @@ -47,7 +46,7 @@ func unpauseAllContainers(t assert.TestingT, client client.ContainerAPIClient) { if len(containers) > 0 { for _, container := range containers { err := client.ContainerUnpause(ctx, container.ID) - assert.NoError(t, err, "failed to unpause container %s", container.ID) + assert.Check(t, err, "failed to unpause container %s", container.ID) } } } @@ -60,7 +59,7 @@ func getPausedContainers(ctx context.Context, t assert.TestingT, client client.C Quiet: true, All: true, }) - assert.NoError(t, err, "failed to list containers") + assert.Check(t, err, "failed to list containers") return containers } @@ -84,7 +83,7 @@ func deleteAllContainers(t assert.TestingT, apiclient client.ContainerAPIClient, if err == nil || client.IsErrNotFound(err) || alreadyExists.MatchString(err.Error()) || isErrNotFoundSwarmClassic(err) { continue } - assert.NoError(t, err, "failed to remove %s", container.ID) + assert.Check(t, err, "failed to remove %s", container.ID) } } @@ -93,13 +92,13 @@ func getAllContainers(ctx context.Context, t assert.TestingT, client client.Cont Quiet: true, All: true, }) - assert.NoError(t, err, "failed to list containers") + assert.Check(t, err, "failed to list containers") return containers } func deleteAllImages(t testingT, apiclient client.ImageAPIClient, protectedImages map[string]struct{}) { images, err := apiclient.ImageList(context.Background(), types.ImageListOptions{}) - assert.NoError(t, err, "failed to list images") + assert.Check(t, err, "failed to list images") ctx := context.Background() for _, image := range images { @@ -126,12 +125,12 @@ func removeImage(ctx context.Context, t assert.TestingT, apiclient client.ImageA if client.IsErrNotFound(err) { return } - assert.NoError(t, err, "failed to remove image %s", ref) + assert.Check(t, err, "failed to remove image %s", ref) } func deleteAllVolumes(t assert.TestingT, c client.VolumeAPIClient, protectedVolumes map[string]struct{}) { volumes, err := c.VolumeList(context.Background(), filters.Args{}) - assert.NoError(t, err, "failed to list volumes") + assert.Check(t, err, "failed to list volumes") for _, v := range volumes.Volumes { if _, ok := protectedVolumes[v.Name]; ok { @@ -142,13 +141,13 @@ func deleteAllVolumes(t assert.TestingT, c client.VolumeAPIClient, protectedVolu if isErrNotFoundSwarmClassic(err) { continue } - assert.NoError(t, err, "failed to remove volume %s", v.Name) + assert.Check(t, err, "failed to remove volume %s", v.Name) } } func deleteAllNetworks(t assert.TestingT, c client.NetworkAPIClient, daemonPlatform string, protectedNetworks map[string]struct{}) { networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{}) - assert.NoError(t, err, "failed to list networks") + assert.Check(t, err, "failed to list networks") for _, n := range networks { if n.Name == "bridge" || n.Name == "none" || n.Name == "host" { @@ -162,7 +161,7 @@ func deleteAllNetworks(t assert.TestingT, c client.NetworkAPIClient, daemonPlatf continue } err := c.NetworkRemove(context.Background(), n.ID) - assert.NoError(t, err, "failed to remove network %s", n.ID) + assert.Check(t, err, "failed to remove network %s", n.ID) } } @@ -172,14 +171,14 @@ func deleteAllPlugins(t assert.TestingT, c client.PluginAPIClient, protectedPlug if client.IsErrNotImplemented(err) { return } - assert.NoError(t, err, "failed to list plugins") + assert.Check(t, err, "failed to list plugins") for _, p := range plugins { if _, ok := protectedPlugins[p.Name]; ok { continue } err := c.PluginRemove(context.Background(), p.Name, types.PluginRemoveOptions{Force: true}) - assert.NoError(t, err, "failed to remove plugin %s", p.ID) + assert.Check(t, err, "failed to remove plugin %s", p.ID) } } diff --git a/components/engine/internal/test/environment/protect.go b/components/engine/internal/test/environment/protect.go index 482dde60b60..3b60763f6bc 100644 --- a/components/engine/internal/test/environment/protect.go +++ b/components/engine/internal/test/environment/protect.go @@ -6,7 +6,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" dclient "github.com/docker/docker/client" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) var frozenImages = []string{"busybox:1.27-glibc", "hello-world:frozen", "debian:jessie"} @@ -57,12 +57,12 @@ func ProtectContainers(t testingT, testEnv *Execution) { testEnv.ProtectContainer(t, containers...) } -func getExistingContainers(t require.TestingT, testEnv *Execution) []string { +func getExistingContainers(t assert.TestingT, testEnv *Execution) []string { client := testEnv.APIClient() containerList, err := client.ContainerList(context.Background(), types.ContainerListOptions{ All: true, }) - require.NoError(t, err, "failed to list containers") + assert.NilError(t, err, "failed to list containers") containers := []string{} for _, container := range containerList { @@ -89,7 +89,7 @@ func ProtectImages(t testingT, testEnv *Execution) { testEnv.ProtectImage(t, images...) } -func getExistingImages(t require.TestingT, testEnv *Execution) []string { +func getExistingImages(t assert.TestingT, testEnv *Execution) []string { client := testEnv.APIClient() filter := filters.NewArgs() filter.Add("dangling", "false") @@ -97,7 +97,7 @@ func getExistingImages(t require.TestingT, testEnv *Execution) []string { All: true, Filters: filter, }) - require.NoError(t, err, "failed to list images") + assert.NilError(t, err, "failed to list images") images := []string{} for _, image := range imageList { @@ -136,10 +136,10 @@ func ProtectNetworks(t testingT, testEnv *Execution) { testEnv.ProtectNetwork(t, networks...) } -func getExistingNetworks(t require.TestingT, testEnv *Execution) []string { +func getExistingNetworks(t assert.TestingT, testEnv *Execution) []string { client := testEnv.APIClient() networkList, err := client.NetworkList(context.Background(), types.NetworkListOptions{}) - require.NoError(t, err, "failed to list networks") + assert.NilError(t, err, "failed to list networks") networks := []string{} for _, network := range networkList { @@ -162,14 +162,14 @@ func ProtectPlugins(t testingT, testEnv *Execution) { testEnv.ProtectPlugin(t, plugins...) } -func getExistingPlugins(t require.TestingT, testEnv *Execution) []string { +func getExistingPlugins(t assert.TestingT, testEnv *Execution) []string { client := testEnv.APIClient() pluginList, err := client.PluginList(context.Background(), filters.Args{}) // Docker EE does not allow cluster-wide plugin management. if dclient.IsErrNotImplemented(err) { return []string{} } - require.NoError(t, err, "failed to list plugins") + assert.NilError(t, err, "failed to list plugins") plugins := []string{} for _, plugin := range pluginList { @@ -192,10 +192,10 @@ func ProtectVolumes(t testingT, testEnv *Execution) { testEnv.ProtectVolume(t, volumes...) } -func getExistingVolumes(t require.TestingT, testEnv *Execution) []string { +func getExistingVolumes(t assert.TestingT, testEnv *Execution) []string { client := testEnv.APIClient() volumeList, err := client.VolumeList(context.Background(), filters.Args{}) - require.NoError(t, err, "failed to list volumes") + assert.NilError(t, err, "failed to list volumes") volumes := []string{} for _, volume := range volumeList.Volumes { diff --git a/components/engine/internal/testutil/helpers.go b/components/engine/internal/testutil/helpers.go index 77224a00714..b1d8f44e3e9 100644 --- a/components/engine/internal/testutil/helpers.go +++ b/components/engine/internal/testutil/helpers.go @@ -3,15 +3,15 @@ package testutil // import "github.com/docker/docker/internal/testutil" import ( "io" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) // ErrorContains checks that the error is not nil, and contains the expected // substring. -func ErrorContains(t require.TestingT, err error, expectedError string, msgAndArgs ...interface{}) { - require.Error(t, err, msgAndArgs...) - assert.Contains(t, err.Error(), expectedError, msgAndArgs...) +func ErrorContains(t assert.TestingT, err error, expectedError string, msgAndArgs ...interface{}) { + assert.Assert(t, is.ErrorContains(err, ""), msgAndArgs) + assert.Check(t, is.Contains(err.Error(), expectedError), msgAndArgs) } // DevZero acts like /dev/zero but in an OS-independent fashion. diff --git a/components/engine/internal/testutil/stringutils_test.go b/components/engine/internal/testutil/stringutils_test.go index a0f95755c79..1dd09af95f3 100644 --- a/components/engine/internal/testutil/stringutils_test.go +++ b/components/engine/internal/testutil/stringutils_test.go @@ -3,13 +3,14 @@ package testutil // import "github.com/docker/docker/internal/testutil" import ( "testing" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func testLengthHelper(generator func(int) string, t *testing.T) { expectedLength := 20 s := generator(expectedLength) - assert.Equal(t, expectedLength, len(s)) + assert.Check(t, is.Equal(expectedLength, len(s))) } func testUniquenessHelper(generator func(int) string, t *testing.T) { @@ -17,9 +18,9 @@ func testUniquenessHelper(generator func(int) string, t *testing.T) { set := make(map[string]struct{}, repeats) for i := 0; i < repeats; i = i + 1 { str := generator(64) - assert.Equal(t, 64, len(str)) + assert.Check(t, is.Equal(64, len(str))) _, ok := set[str] - assert.False(t, ok, "Random number is repeated") + assert.Check(t, !ok, "Random number is repeated") set[str] = struct{}{} } } diff --git a/components/engine/libcontainerd/queue_test.go b/components/engine/libcontainerd/queue_test.go index 92ee22a9f31..df5332c128b 100644 --- a/components/engine/libcontainerd/queue_test.go +++ b/components/engine/libcontainerd/queue_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) func TestSerialization(t *testing.T) { @@ -16,15 +16,15 @@ func TestSerialization(t *testing.T) { q.append("aaa", func() { //simulate a long time task time.Sleep(10 * time.Millisecond) - require.EqualValues(t, serialization, 1) + assert.Equal(t, serialization, 1) serialization = 2 }) q.append("aaa", func() { - require.EqualValues(t, serialization, 2) + assert.Equal(t, serialization, 2) serialization = 3 }) q.append("aaa", func() { - require.EqualValues(t, serialization, 3) + assert.Equal(t, serialization, 3) serialization = 4 }) time.Sleep(20 * time.Millisecond) diff --git a/components/engine/opts/quotedstring_test.go b/components/engine/opts/quotedstring_test.go index e24257a5d42..21e6e4c85ae 100644 --- a/components/engine/opts/quotedstring_test.go +++ b/components/engine/opts/quotedstring_test.go @@ -3,27 +3,28 @@ package opts // import "github.com/docker/docker/opts" import ( "testing" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestQuotedStringSetWithQuotes(t *testing.T) { value := "" qs := NewQuotedString(&value) - assert.NoError(t, qs.Set(`"something"`)) - assert.Equal(t, "something", qs.String()) - assert.Equal(t, "something", value) + assert.Check(t, qs.Set(`"something"`)) + assert.Check(t, is.Equal("something", qs.String())) + assert.Check(t, is.Equal("something", value)) } func TestQuotedStringSetWithMismatchedQuotes(t *testing.T) { value := "" qs := NewQuotedString(&value) - assert.NoError(t, qs.Set(`"something'`)) - assert.Equal(t, `"something'`, qs.String()) + assert.Check(t, qs.Set(`"something'`)) + assert.Check(t, is.Equal(`"something'`, qs.String())) } func TestQuotedStringSetWithNoQuotes(t *testing.T) { value := "" qs := NewQuotedString(&value) - assert.NoError(t, qs.Set("something")) - assert.Equal(t, "something", qs.String()) + assert.Check(t, qs.Set("something")) + assert.Check(t, is.Equal("something", qs.String())) } diff --git a/components/engine/pkg/archive/archive_linux_test.go b/components/engine/pkg/archive/archive_linux_test.go index e48ef1aa11d..b397c8abfa4 100644 --- a/components/engine/pkg/archive/archive_linux_test.go +++ b/components/engine/pkg/archive/archive_linux_test.go @@ -8,7 +8,7 @@ import ( "testing" "github.com/docker/docker/pkg/system" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" "golang.org/x/sys/unix" ) @@ -24,35 +24,35 @@ import ( func setupOverlayTestDir(t *testing.T, src string) { // Create opaque directory containing single file and permission 0700 err := os.Mkdir(filepath.Join(src, "d1"), 0700) - require.NoError(t, err) + assert.NilError(t, err) err = system.Lsetxattr(filepath.Join(src, "d1"), "trusted.overlay.opaque", []byte("y"), 0) - require.NoError(t, err) + assert.NilError(t, err) err = ioutil.WriteFile(filepath.Join(src, "d1", "f1"), []byte{}, 0600) - require.NoError(t, err) + assert.NilError(t, err) // Create another opaque directory containing single file but with permission 0750 err = os.Mkdir(filepath.Join(src, "d2"), 0750) - require.NoError(t, err) + assert.NilError(t, err) err = system.Lsetxattr(filepath.Join(src, "d2"), "trusted.overlay.opaque", []byte("y"), 0) - require.NoError(t, err) + assert.NilError(t, err) err = ioutil.WriteFile(filepath.Join(src, "d2", "f1"), []byte{}, 0660) - require.NoError(t, err) + assert.NilError(t, err) // Create regular directory with deleted file err = os.Mkdir(filepath.Join(src, "d3"), 0700) - require.NoError(t, err) + assert.NilError(t, err) err = system.Mknod(filepath.Join(src, "d3", "f1"), unix.S_IFCHR, 0) - require.NoError(t, err) + assert.NilError(t, err) } func checkOpaqueness(t *testing.T, path string, opaque string) { xattrOpaque, err := system.Lgetxattr(path, "trusted.overlay.opaque") - require.NoError(t, err) + assert.NilError(t, err) if string(xattrOpaque) != opaque { t.Fatalf("Unexpected opaque value: %q, expected %q", string(xattrOpaque), opaque) @@ -62,7 +62,7 @@ func checkOpaqueness(t *testing.T, path string, opaque string) { func checkOverlayWhiteout(t *testing.T, path string) { stat, err := os.Stat(path) - require.NoError(t, err) + assert.NilError(t, err) statT, ok := stat.Sys().(*syscall.Stat_t) if !ok { @@ -75,7 +75,7 @@ func checkOverlayWhiteout(t *testing.T, path string) { func checkFileMode(t *testing.T, path string, perm os.FileMode) { stat, err := os.Stat(path) - require.NoError(t, err) + assert.NilError(t, err) if stat.Mode() != perm { t.Fatalf("Unexpected file mode for %s: %o, expected %o", path, stat.Mode(), perm) @@ -84,17 +84,17 @@ func checkFileMode(t *testing.T, path string, perm os.FileMode) { func TestOverlayTarUntar(t *testing.T) { oldmask, err := system.Umask(0) - require.NoError(t, err) + assert.NilError(t, err) defer system.Umask(oldmask) src, err := ioutil.TempDir("", "docker-test-overlay-tar-src") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(src) setupOverlayTestDir(t, src) dst, err := ioutil.TempDir("", "docker-test-overlay-tar-dst") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(dst) options := &TarOptions{ @@ -102,11 +102,11 @@ func TestOverlayTarUntar(t *testing.T) { WhiteoutFormat: OverlayWhiteoutFormat, } archive, err := TarWithOptions(src, options) - require.NoError(t, err) + assert.NilError(t, err) defer archive.Close() err = Untar(archive, dst, options) - require.NoError(t, err) + assert.NilError(t, err) checkFileMode(t, filepath.Join(dst, "d1"), 0700|os.ModeDir) checkFileMode(t, filepath.Join(dst, "d2"), 0750|os.ModeDir) @@ -123,31 +123,31 @@ func TestOverlayTarUntar(t *testing.T) { func TestOverlayTarAUFSUntar(t *testing.T) { oldmask, err := system.Umask(0) - require.NoError(t, err) + assert.NilError(t, err) defer system.Umask(oldmask) src, err := ioutil.TempDir("", "docker-test-overlay-tar-src") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(src) setupOverlayTestDir(t, src) dst, err := ioutil.TempDir("", "docker-test-overlay-tar-dst") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(dst) archive, err := TarWithOptions(src, &TarOptions{ Compression: Uncompressed, WhiteoutFormat: OverlayWhiteoutFormat, }) - require.NoError(t, err) + assert.NilError(t, err) defer archive.Close() err = Untar(archive, dst, &TarOptions{ Compression: Uncompressed, WhiteoutFormat: AUFSWhiteoutFormat, }) - require.NoError(t, err) + assert.NilError(t, err) checkFileMode(t, filepath.Join(dst, "d1"), 0700|os.ModeDir) checkFileMode(t, filepath.Join(dst, "d1", WhiteoutOpaqueDir), 0700) diff --git a/components/engine/pkg/archive/archive_test.go b/components/engine/pkg/archive/archive_test.go index 70db8d4a1bf..296b636a6eb 100644 --- a/components/engine/pkg/archive/archive_test.go +++ b/components/engine/pkg/archive/archive_test.go @@ -17,8 +17,8 @@ import ( "github.com/docker/docker/pkg/idtools" "github.com/docker/docker/pkg/ioutils" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) var tmp string @@ -263,7 +263,7 @@ func TestCmdStreamGood(t *testing.T) { func TestUntarPathWithInvalidDest(t *testing.T) { tempFolder, err := ioutil.TempDir("", "docker-archive-test") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(tempFolder) invalidDestFolder := filepath.Join(tempFolder, "invalidDest") // Create a src file @@ -282,7 +282,7 @@ func TestUntarPathWithInvalidDest(t *testing.T) { cmd := exec.Command("sh", "-c", "tar cf "+tarFileU+" "+srcFileU) _, err = cmd.CombinedOutput() - require.NoError(t, err) + assert.NilError(t, err) err = defaultUntarPath(tarFile, invalidDestFolder) if err == nil { @@ -304,7 +304,7 @@ func TestUntarPathWithInvalidSrc(t *testing.T) { func TestUntarPath(t *testing.T) { tmpFolder, err := ioutil.TempDir("", "docker-archive-test") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(tmpFolder) srcFile := filepath.Join(tmpFolder, "src") tarFile := filepath.Join(tmpFolder, "src.tar") @@ -325,7 +325,7 @@ func TestUntarPath(t *testing.T) { } cmd := exec.Command("sh", "-c", "tar cf "+tarFileU+" "+srcFileU) _, err = cmd.CombinedOutput() - require.NoError(t, err) + assert.NilError(t, err) err = defaultUntarPath(tarFile, destFolder) if err != nil { @@ -726,12 +726,12 @@ func TestTarUntar(t *testing.T) { func TestTarWithOptionsChownOptsAlwaysOverridesIdPair(t *testing.T) { origin, err := ioutil.TempDir("", "docker-test-tar-chown-opt") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(origin) filePath := filepath.Join(origin, "1") err = ioutil.WriteFile(filePath, []byte("hello world"), 0700) - require.NoError(t, err) + assert.NilError(t, err) idMaps := []idtools.IDMap{ 0: { @@ -759,7 +759,7 @@ func TestTarWithOptionsChownOptsAlwaysOverridesIdPair(t *testing.T) { } for _, testCase := range cases { reader, err := TarWithOptions(filePath, testCase.opts) - require.NoError(t, err) + assert.NilError(t, err) tr := tar.NewReader(reader) defer reader.Close() for { @@ -768,9 +768,9 @@ func TestTarWithOptionsChownOptsAlwaysOverridesIdPair(t *testing.T) { // end of tar archive break } - require.NoError(t, err) - assert.Equal(t, hdr.Uid, testCase.expectedUID, "Uid equals expected value") - assert.Equal(t, hdr.Gid, testCase.expectedGID, "Gid equals expected value") + assert.NilError(t, err) + assert.Check(t, is.Equal(hdr.Uid, testCase.expectedUID), "Uid equals expected value") + assert.Check(t, is.Equal(hdr.Gid, testCase.expectedGID), "Gid equals expected value") } } } @@ -1182,10 +1182,10 @@ func TestUntarInvalidSymlink(t *testing.T) { func TestTempArchiveCloseMultipleTimes(t *testing.T) { reader := ioutil.NopCloser(strings.NewReader("hello")) tempArchive, err := NewTempArchive(reader, "") - require.NoError(t, err) + assert.NilError(t, err) buf := make([]byte, 10) n, err := tempArchive.Read(buf) - require.NoError(t, err) + assert.NilError(t, err) if n != 5 { t.Fatalf("Expected to read 5 bytes. Read %d instead", n) } @@ -1244,7 +1244,7 @@ func TestReplaceFileTarWrapper(t *testing.T) { map[string]TarModifierFunc{testcase.filename: testcase.modifier}) actual := readFileFromArchive(t, resultArchive, testcase.filename, testcase.fileCount, testcase.doc) - assert.Equal(t, testcase.expected, actual, testcase.doc) + assert.Check(t, is.Equal(testcase.expected, actual), testcase.doc) } } @@ -1255,27 +1255,27 @@ func TestPrefixHeaderReadable(t *testing.T) { var testFile = []byte("\x1f\x8b\x08\x08\x44\x21\x68\x59\x00\x03\x74\x2e\x74\x61\x72\x00\x4b\xcb\xcf\x67\xa0\x35\x30\x80\x00\x86\x06\x10\x47\x01\xc1\x37\x40\x00\x54\xb6\xb1\xa1\xa9\x99\x09\x48\x25\x1d\x40\x69\x71\x49\x62\x91\x02\xe5\x76\xa1\x79\x84\x21\x91\xd6\x80\x72\xaf\x8f\x82\x51\x30\x0a\x46\x36\x00\x00\xf0\x1c\x1e\x95\x00\x06\x00\x00") tmpDir, err := ioutil.TempDir("", "prefix-test") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(tmpDir) err = Untar(bytes.NewReader(testFile), tmpDir, nil) - require.NoError(t, err) + assert.NilError(t, err) baseName := "foo" pth := strings.Repeat("a", 100-len(baseName)) + "/" + baseName _, err = os.Lstat(filepath.Join(tmpDir, pth)) - require.NoError(t, err) + assert.NilError(t, err) } func buildSourceArchive(t *testing.T, numberOfFiles int) (io.ReadCloser, func()) { srcDir, err := ioutil.TempDir("", "docker-test-srcDir") - require.NoError(t, err) + assert.NilError(t, err) _, err = prepareUntarSourceDirectory(numberOfFiles, srcDir, false) - require.NoError(t, err) + assert.NilError(t, err) sourceArchive, err := TarWithOptions(srcDir, &TarOptions{}) - require.NoError(t, err) + assert.NilError(t, err) return sourceArchive, func() { os.RemoveAll(srcDir) sourceArchive.Close() @@ -1291,7 +1291,7 @@ func createOrReplaceModifier(path string, header *tar.Header, content io.Reader) func createModifier(t *testing.T) TarModifierFunc { return func(path string, header *tar.Header, content io.Reader) (*tar.Header, []byte, error) { - assert.Nil(t, content) + assert.Check(t, is.Nil(content)) return createOrReplaceModifier(path, header, content) } } @@ -1309,17 +1309,17 @@ func appendModifier(path string, header *tar.Header, content io.Reader) (*tar.He func readFileFromArchive(t *testing.T, archive io.ReadCloser, name string, expectedCount int, doc string) string { destDir, err := ioutil.TempDir("", "docker-test-destDir") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(destDir) err = Untar(archive, destDir, nil) - require.NoError(t, err) + assert.NilError(t, err) files, _ := ioutil.ReadDir(destDir) - assert.Len(t, files, expectedCount, doc) + assert.Check(t, is.Len(files, expectedCount), doc) content, err := ioutil.ReadFile(filepath.Join(destDir, name)) - assert.NoError(t, err) + assert.Check(t, err) return string(content) } diff --git a/components/engine/pkg/archive/archive_unix_test.go b/components/engine/pkg/archive/archive_unix_test.go index 17de96e94d6..5d13c3542b7 100644 --- a/components/engine/pkg/archive/archive_unix_test.go +++ b/components/engine/pkg/archive/archive_unix_test.go @@ -13,8 +13,8 @@ import ( "testing" "github.com/docker/docker/pkg/system" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/sys/unix" ) @@ -72,18 +72,18 @@ func TestChmodTarEntry(t *testing.T) { func TestTarWithHardLink(t *testing.T) { origin, err := ioutil.TempDir("", "docker-test-tar-hardlink") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(origin) err = ioutil.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700) - require.NoError(t, err) + assert.NilError(t, err) err = os.Link(filepath.Join(origin, "1"), filepath.Join(origin, "2")) - require.NoError(t, err) + assert.NilError(t, err) var i1, i2 uint64 i1, err = getNlink(filepath.Join(origin, "1")) - require.NoError(t, err) + assert.NilError(t, err) // sanity check that we can hardlink if i1 != 2 { @@ -91,48 +91,48 @@ func TestTarWithHardLink(t *testing.T) { } dest, err := ioutil.TempDir("", "docker-test-tar-hardlink-dest") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(dest) // we'll do this in two steps to separate failure fh, err := Tar(origin, Uncompressed) - require.NoError(t, err) + assert.NilError(t, err) // ensure we can read the whole thing with no error, before writing back out buf, err := ioutil.ReadAll(fh) - require.NoError(t, err) + assert.NilError(t, err) bRdr := bytes.NewReader(buf) err = Untar(bRdr, dest, &TarOptions{Compression: Uncompressed}) - require.NoError(t, err) + assert.NilError(t, err) i1, err = getInode(filepath.Join(dest, "1")) - require.NoError(t, err) + assert.NilError(t, err) i2, err = getInode(filepath.Join(dest, "2")) - require.NoError(t, err) + assert.NilError(t, err) - assert.Equal(t, i1, i2) + assert.Check(t, is.Equal(i1, i2)) } func TestTarWithHardLinkAndRebase(t *testing.T) { tmpDir, err := ioutil.TempDir("", "docker-test-tar-hardlink-rebase") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(tmpDir) origin := filepath.Join(tmpDir, "origin") err = os.Mkdir(origin, 0700) - require.NoError(t, err) + assert.NilError(t, err) err = ioutil.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700) - require.NoError(t, err) + assert.NilError(t, err) err = os.Link(filepath.Join(origin, "1"), filepath.Join(origin, "2")) - require.NoError(t, err) + assert.NilError(t, err) var i1, i2 uint64 i1, err = getNlink(filepath.Join(origin, "1")) - require.NoError(t, err) + assert.NilError(t, err) // sanity check that we can hardlink if i1 != 2 { @@ -141,20 +141,20 @@ func TestTarWithHardLinkAndRebase(t *testing.T) { dest := filepath.Join(tmpDir, "dest") bRdr, err := TarResourceRebase(origin, "origin") - require.NoError(t, err) + assert.NilError(t, err) dstDir, srcBase := SplitPathDirEntry(origin) _, dstBase := SplitPathDirEntry(dest) content := RebaseArchiveEntries(bRdr, srcBase, dstBase) err = Untar(content, dstDir, &TarOptions{Compression: Uncompressed, NoLchown: true, NoOverwriteDirNonDir: true}) - require.NoError(t, err) + assert.NilError(t, err) i1, err = getInode(filepath.Join(dest, "1")) - require.NoError(t, err) + assert.NilError(t, err) i2, err = getInode(filepath.Join(dest, "2")) - require.NoError(t, err) + assert.NilError(t, err) - assert.Equal(t, i1, i2) + assert.Check(t, is.Equal(i1, i2)) } func getNlink(path string) (uint64, error) { @@ -184,37 +184,37 @@ func getInode(path string) (uint64, error) { func TestTarWithBlockCharFifo(t *testing.T) { origin, err := ioutil.TempDir("", "docker-test-tar-hardlink") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(origin) err = ioutil.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700) - require.NoError(t, err) + assert.NilError(t, err) err = system.Mknod(filepath.Join(origin, "2"), unix.S_IFBLK, int(system.Mkdev(int64(12), int64(5)))) - require.NoError(t, err) + assert.NilError(t, err) err = system.Mknod(filepath.Join(origin, "3"), unix.S_IFCHR, int(system.Mkdev(int64(12), int64(5)))) - require.NoError(t, err) + assert.NilError(t, err) err = system.Mknod(filepath.Join(origin, "4"), unix.S_IFIFO, int(system.Mkdev(int64(12), int64(5)))) - require.NoError(t, err) + assert.NilError(t, err) dest, err := ioutil.TempDir("", "docker-test-tar-hardlink-dest") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(dest) // we'll do this in two steps to separate failure fh, err := Tar(origin, Uncompressed) - require.NoError(t, err) + assert.NilError(t, err) // ensure we can read the whole thing with no error, before writing back out buf, err := ioutil.ReadAll(fh) - require.NoError(t, err) + assert.NilError(t, err) bRdr := bytes.NewReader(buf) err = Untar(bRdr, dest, &TarOptions{Compression: Uncompressed}) - require.NoError(t, err) + assert.NilError(t, err) changes, err := ChangesDirs(origin, dest) - require.NoError(t, err) + assert.NilError(t, err) if len(changes) > 0 { t.Fatalf("Tar with special device (block, char, fifo) should keep them (recreate them when untar) : %v", changes) @@ -224,17 +224,17 @@ func TestTarWithBlockCharFifo(t *testing.T) { // TestTarUntarWithXattr is Unix as Lsetxattr is not supported on Windows func TestTarUntarWithXattr(t *testing.T) { origin, err := ioutil.TempDir("", "docker-test-untar-origin") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(origin) err = ioutil.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0700) - require.NoError(t, err) + assert.NilError(t, err) err = ioutil.WriteFile(filepath.Join(origin, "2"), []byte("welcome!"), 0700) - require.NoError(t, err) + assert.NilError(t, err) err = ioutil.WriteFile(filepath.Join(origin, "3"), []byte("will be ignored"), 0700) - require.NoError(t, err) + assert.NilError(t, err) err = system.Lsetxattr(filepath.Join(origin, "2"), "security.capability", []byte{0x00}, 0) - require.NoError(t, err) + assert.NilError(t, err) for _, c := range []Compression{ Uncompressed, @@ -309,7 +309,7 @@ func TestCopyInfoDestinationPathSymlink(t *testing.T) { for _, info := range testData { p := filepath.Join(tmpDir, info.resource.path, info.file) ci, err := CopyInfoDestinationPath(p) - assert.NoError(t, err) - assert.Equal(t, info.expected, ci) + assert.Check(t, err) + assert.Check(t, is.DeepEqual(info.expected, ci)) } } diff --git a/components/engine/pkg/archive/changes_test.go b/components/engine/pkg/archive/changes_test.go index f316cd32037..2d316e77bec 100644 --- a/components/engine/pkg/archive/changes_test.go +++ b/components/engine/pkg/archive/changes_test.go @@ -11,7 +11,7 @@ import ( "time" "github.com/docker/docker/pkg/system" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) func max(x, y int) int { @@ -76,19 +76,19 @@ func provisionSampleDir(t *testing.T, root string, files []FileData) { p := path.Join(root, info.path) if info.filetype == Dir { err := os.MkdirAll(p, info.permissions) - require.NoError(t, err) + assert.NilError(t, err) } else if info.filetype == Regular { err := ioutil.WriteFile(p, []byte(info.contents), info.permissions) - require.NoError(t, err) + assert.NilError(t, err) } else if info.filetype == Symlink { err := os.Symlink(info.contents, p) - require.NoError(t, err) + assert.NilError(t, err) } if info.filetype != Symlink { // Set a consistent ctime, atime for all files and dirs err := system.Chtimes(p, now, now) - require.NoError(t, err) + assert.NilError(t, err) } } } @@ -118,14 +118,14 @@ func TestChangesWithNoChanges(t *testing.T) { t.Skip("symlinks on Windows") } rwLayer, err := ioutil.TempDir("", "docker-changes-test") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(rwLayer) layer, err := ioutil.TempDir("", "docker-changes-test-layer") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(layer) createSampleDir(t, layer) changes, err := Changes([]string{layer}, rwLayer) - require.NoError(t, err) + assert.NilError(t, err) if len(changes) != 0 { t.Fatalf("Changes with no difference should have detect no changes, but detected %d", len(changes)) } @@ -139,14 +139,14 @@ func TestChangesWithChanges(t *testing.T) { } // Mock the readonly layer layer, err := ioutil.TempDir("", "docker-changes-test-layer") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(layer) createSampleDir(t, layer) os.MkdirAll(path.Join(layer, "dir1/subfolder"), 0740) // Mock the RW layer rwLayer, err := ioutil.TempDir("", "docker-changes-test") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(rwLayer) // Create a folder in RW layer @@ -163,7 +163,7 @@ func TestChangesWithChanges(t *testing.T) { ioutil.WriteFile(newFile, []byte{}, 0740) changes, err := Changes([]string{layer}, rwLayer) - require.NoError(t, err) + assert.NilError(t, err) expectedChanges := []Change{ {"/dir1", ChangeModify}, @@ -183,7 +183,7 @@ func TestChangesWithChangesGH13590(t *testing.T) { t.Skip("symlinks on Windows") } baseLayer, err := ioutil.TempDir("", "docker-changes-test.") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(baseLayer) dir3 := path.Join(baseLayer, "dir1/dir2/dir3") @@ -193,7 +193,7 @@ func TestChangesWithChangesGH13590(t *testing.T) { ioutil.WriteFile(file, []byte("hello"), 0666) layer, err := ioutil.TempDir("", "docker-changes-test2.") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(layer) // Test creating a new file @@ -206,7 +206,7 @@ func TestChangesWithChangesGH13590(t *testing.T) { ioutil.WriteFile(file, []byte("bye"), 0666) changes, err := Changes([]string{baseLayer}, layer) - require.NoError(t, err) + assert.NilError(t, err) expectedChanges := []Change{ {"/dir1/dir2/dir3", ChangeModify}, @@ -216,7 +216,7 @@ func TestChangesWithChangesGH13590(t *testing.T) { // Now test changing a file layer, err = ioutil.TempDir("", "docker-changes-test3.") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(layer) if err := copyDir(baseLayer+"/dir1", layer+"/"); err != nil { @@ -227,7 +227,7 @@ func TestChangesWithChangesGH13590(t *testing.T) { ioutil.WriteFile(file, []byte("bye"), 0666) changes, err = Changes([]string{baseLayer}, layer) - require.NoError(t, err) + assert.NilError(t, err) expectedChanges = []Change{ {"/dir1/dir2/dir3/file.txt", ChangeModify}, @@ -243,15 +243,15 @@ func TestChangesDirsEmpty(t *testing.T) { t.Skip("symlinks on Windows") } src, err := ioutil.TempDir("", "docker-changes-test") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(src) createSampleDir(t, src) dst := src + "-copy" err = copyDir(src, dst) - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(dst) changes, err := ChangesDirs(dst, src) - require.NoError(t, err) + assert.NilError(t, err) if len(changes) != 0 { t.Fatalf("Reported changes for identical dirs: %v", changes) @@ -263,64 +263,64 @@ func TestChangesDirsEmpty(t *testing.T) { func mutateSampleDir(t *testing.T, root string) { // Remove a regular file err := os.RemoveAll(path.Join(root, "file1")) - require.NoError(t, err) + assert.NilError(t, err) // Remove a directory err = os.RemoveAll(path.Join(root, "dir1")) - require.NoError(t, err) + assert.NilError(t, err) // Remove a symlink err = os.RemoveAll(path.Join(root, "symlink1")) - require.NoError(t, err) + assert.NilError(t, err) // Rewrite a file err = ioutil.WriteFile(path.Join(root, "file2"), []byte("fileNN\n"), 0777) - require.NoError(t, err) + assert.NilError(t, err) // Replace a file err = os.RemoveAll(path.Join(root, "file3")) - require.NoError(t, err) + assert.NilError(t, err) err = ioutil.WriteFile(path.Join(root, "file3"), []byte("fileMM\n"), 0404) - require.NoError(t, err) + assert.NilError(t, err) // Touch file err = system.Chtimes(path.Join(root, "file4"), time.Now().Add(time.Second), time.Now().Add(time.Second)) - require.NoError(t, err) + assert.NilError(t, err) // Replace file with dir err = os.RemoveAll(path.Join(root, "file5")) - require.NoError(t, err) + assert.NilError(t, err) err = os.MkdirAll(path.Join(root, "file5"), 0666) - require.NoError(t, err) + assert.NilError(t, err) // Create new file err = ioutil.WriteFile(path.Join(root, "filenew"), []byte("filenew\n"), 0777) - require.NoError(t, err) + assert.NilError(t, err) // Create new dir err = os.MkdirAll(path.Join(root, "dirnew"), 0766) - require.NoError(t, err) + assert.NilError(t, err) // Create a new symlink err = os.Symlink("targetnew", path.Join(root, "symlinknew")) - require.NoError(t, err) + assert.NilError(t, err) // Change a symlink err = os.RemoveAll(path.Join(root, "symlink2")) - require.NoError(t, err) + assert.NilError(t, err) err = os.Symlink("target2change", path.Join(root, "symlink2")) - require.NoError(t, err) + assert.NilError(t, err) // Replace dir with file err = os.RemoveAll(path.Join(root, "dir2")) - require.NoError(t, err) + assert.NilError(t, err) err = ioutil.WriteFile(path.Join(root, "dir2"), []byte("dir2\n"), 0777) - require.NoError(t, err) + assert.NilError(t, err) // Touch dir err = system.Chtimes(path.Join(root, "dir3"), time.Now().Add(time.Second), time.Now().Add(time.Second)) - require.NoError(t, err) + assert.NilError(t, err) } func TestChangesDirsMutated(t *testing.T) { @@ -330,18 +330,18 @@ func TestChangesDirsMutated(t *testing.T) { t.Skip("symlinks on Windows") } src, err := ioutil.TempDir("", "docker-changes-test") - require.NoError(t, err) + assert.NilError(t, err) createSampleDir(t, src) dst := src + "-copy" err = copyDir(src, dst) - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(src) defer os.RemoveAll(dst) mutateSampleDir(t, dst) changes, err := ChangesDirs(dst, src) - require.NoError(t, err) + assert.NilError(t, err) sort.Sort(changesByPath(changes)) @@ -386,29 +386,29 @@ func TestApplyLayer(t *testing.T) { t.Skip("symlinks on Windows") } src, err := ioutil.TempDir("", "docker-changes-test") - require.NoError(t, err) + assert.NilError(t, err) createSampleDir(t, src) defer os.RemoveAll(src) dst := src + "-copy" err = copyDir(src, dst) - require.NoError(t, err) + assert.NilError(t, err) mutateSampleDir(t, dst) defer os.RemoveAll(dst) changes, err := ChangesDirs(dst, src) - require.NoError(t, err) + assert.NilError(t, err) layer, err := ExportChanges(dst, changes, nil, nil) - require.NoError(t, err) + assert.NilError(t, err) layerCopy, err := NewTempArchive(layer, "") - require.NoError(t, err) + assert.NilError(t, err) _, err = ApplyLayer(src, layerCopy) - require.NoError(t, err) + assert.NilError(t, err) changes2, err := ChangesDirs(src, dst) - require.NoError(t, err) + assert.NilError(t, err) if len(changes2) != 0 { t.Fatalf("Unexpected differences after reapplying mutation: %v", changes2) @@ -422,18 +422,18 @@ func TestChangesSizeWithHardlinks(t *testing.T) { t.Skip("hardlinks on Windows") } srcDir, err := ioutil.TempDir("", "docker-test-srcDir") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(srcDir) destDir, err := ioutil.TempDir("", "docker-test-destDir") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(destDir) creationSize, err := prepareUntarSourceDirectory(100, destDir, true) - require.NoError(t, err) + assert.NilError(t, err) changes, err := ChangesDirs(destDir, srcDir) - require.NoError(t, err) + assert.NilError(t, err) got := ChangesSize(destDir, changes) if got != int64(creationSize) { @@ -460,14 +460,14 @@ func TestChangesSizeWithOnlyDeleteChanges(t *testing.T) { func TestChangesSize(t *testing.T) { parentPath, err := ioutil.TempDir("", "docker-changes-test") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(parentPath) addition := path.Join(parentPath, "addition") err = ioutil.WriteFile(addition, []byte{0x01, 0x01, 0x01}, 0744) - require.NoError(t, err) + assert.NilError(t, err) modification := path.Join(parentPath, "modification") err = ioutil.WriteFile(modification, []byte{0x01, 0x01, 0x01}, 0744) - require.NoError(t, err) + assert.NilError(t, err) changes := []Change{ {Path: "addition", Kind: ChangeAdd}, diff --git a/components/engine/pkg/archive/copy_unix_test.go b/components/engine/pkg/archive/copy_unix_test.go index 3126d8b51ec..08b1702cf1c 100644 --- a/components/engine/pkg/archive/copy_unix_test.go +++ b/components/engine/pkg/archive/copy_unix_test.go @@ -16,7 +16,7 @@ import ( "strings" "testing" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) func removeAllPaths(paths ...string) { @@ -29,10 +29,10 @@ func getTestTempDirs(t *testing.T) (tmpDirA, tmpDirB string) { var err error tmpDirA, err = ioutil.TempDir("", "archive-copy-test") - require.NoError(t, err) + assert.NilError(t, err) tmpDirB, err = ioutil.TempDir("", "archive-copy-test") - require.NoError(t, err) + assert.NilError(t, err) return } @@ -119,7 +119,7 @@ func logDirContents(t *testing.T, dirPath string) { t.Logf("logging directory contents: %q", dirPath) err := filepath.Walk(dirPath, logWalkedPaths) - require.NoError(t, err) + assert.NilError(t, err) } func testCopyHelper(t *testing.T, srcPath, dstPath string) (err error) { @@ -293,7 +293,7 @@ func TestCopyCaseA(t *testing.T) { } err = fileContentsEqual(t, srcPath, dstPath) - require.NoError(t, err) + assert.NilError(t, err) os.Remove(dstPath) symlinkPath := filepath.Join(tmpDirA, "symlink3") @@ -305,14 +305,14 @@ func TestCopyCaseA(t *testing.T) { } err = fileContentsEqual(t, linkTarget, dstPath) - require.NoError(t, err) + assert.NilError(t, err) os.Remove(dstPath) if err = testCopyHelperFSym(t, symlinkPath1, dstPath); err != nil { t.Fatalf("unexpected error %T: %s", err, err) } err = fileContentsEqual(t, linkTarget, dstPath) - require.NoError(t, err) + assert.NilError(t, err) } // B. SRC specifies a file and DST (with trailing path separator) doesn't @@ -374,7 +374,7 @@ func TestCopyCaseC(t *testing.T) { } err = fileContentsEqual(t, srcPath, dstPath) - require.NoError(t, err) + assert.NilError(t, err) } // C. Symbol link following version: @@ -411,7 +411,7 @@ func TestCopyCaseCFSym(t *testing.T) { } err = fileContentsEqual(t, linkTarget, dstPath) - require.NoError(t, err) + assert.NilError(t, err) } // D. SRC specifies a file and DST exists as a directory. This should place @@ -441,7 +441,7 @@ func TestCopyCaseD(t *testing.T) { } err = fileContentsEqual(t, srcPath, dstPath) - require.NoError(t, err) + assert.NilError(t, err) // Now try again but using a trailing path separator for dstDir. @@ -460,7 +460,7 @@ func TestCopyCaseD(t *testing.T) { } err = fileContentsEqual(t, srcPath, dstPath) - require.NoError(t, err) + assert.NilError(t, err) } // D. Symbol link following version: @@ -492,7 +492,7 @@ func TestCopyCaseDFSym(t *testing.T) { } err = fileContentsEqual(t, linkTarget, dstPath) - require.NoError(t, err) + assert.NilError(t, err) // Now try again but using a trailing path separator for dstDir. @@ -511,7 +511,7 @@ func TestCopyCaseDFSym(t *testing.T) { } err = fileContentsEqual(t, linkTarget, dstPath) - require.NoError(t, err) + assert.NilError(t, err) } // E. SRC specifies a directory and DST does not exist. This should create a @@ -554,7 +554,7 @@ func TestCopyCaseE(t *testing.T) { } err = dirContentsEqual(t, dstDir, srcDir) - require.NoError(t, err) + assert.NilError(t, err) } // E. Symbol link following version: @@ -599,7 +599,7 @@ func TestCopyCaseEFSym(t *testing.T) { } err = dirContentsEqual(t, dstDir, linkTarget) - require.NoError(t, err) + assert.NilError(t, err) } // F. SRC specifies a directory and DST exists as a file. This should cause an @@ -658,7 +658,7 @@ func TestCopyCaseG(t *testing.T) { } err = dirContentsEqual(t, resultDir, srcDir) - require.NoError(t, err) + assert.NilError(t, err) // Now try again but using a trailing path separator for dstDir. @@ -677,7 +677,7 @@ func TestCopyCaseG(t *testing.T) { } err = dirContentsEqual(t, resultDir, srcDir) - require.NoError(t, err) + assert.NilError(t, err) } // G. Symbol link version: @@ -704,7 +704,7 @@ func TestCopyCaseGFSym(t *testing.T) { } err = dirContentsEqual(t, resultDir, linkTarget) - require.NoError(t, err) + assert.NilError(t, err) // Now try again but using a trailing path separator for dstDir. @@ -723,7 +723,7 @@ func TestCopyCaseGFSym(t *testing.T) { } err = dirContentsEqual(t, resultDir, linkTarget) - require.NoError(t, err) + assert.NilError(t, err) } // H. SRC specifies a directory's contents only and DST does not exist. This @@ -884,7 +884,7 @@ func TestCopyCaseJ(t *testing.T) { } err = dirContentsEqual(t, dstDir, srcDir) - require.NoError(t, err) + assert.NilError(t, err) // Now try again but using a trailing path separator for dstDir. @@ -903,7 +903,7 @@ func TestCopyCaseJ(t *testing.T) { } err = dirContentsEqual(t, dstDir, srcDir) - require.NoError(t, err) + assert.NilError(t, err) } // J. Symbol link following version: @@ -935,7 +935,7 @@ func TestCopyCaseJFSym(t *testing.T) { } err = dirContentsEqual(t, dstDir, linkTarget) - require.NoError(t, err) + assert.NilError(t, err) // Now try again but using a trailing path separator for dstDir. @@ -954,5 +954,5 @@ func TestCopyCaseJFSym(t *testing.T) { } err = dirContentsEqual(t, dstDir, linkTarget) - require.NoError(t, err) + assert.NilError(t, err) } diff --git a/components/engine/pkg/archive/wrap_test.go b/components/engine/pkg/archive/wrap_test.go index 6decf8fccb7..979536777ff 100644 --- a/components/engine/pkg/archive/wrap_test.go +++ b/components/engine/pkg/archive/wrap_test.go @@ -6,12 +6,12 @@ import ( "io" "testing" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) func TestGenerateEmptyFile(t *testing.T) { archive, err := Generate("emptyFile") - require.NoError(t, err) + assert.NilError(t, err) if archive == nil { t.Fatal("The generated archive should not be nil.") } @@ -28,7 +28,7 @@ func TestGenerateEmptyFile(t *testing.T) { if err == io.EOF { break } - require.NoError(t, err) + assert.NilError(t, err) buf := new(bytes.Buffer) buf.ReadFrom(tr) content := buf.String() @@ -52,7 +52,7 @@ func TestGenerateEmptyFile(t *testing.T) { func TestGenerateWithContent(t *testing.T) { archive, err := Generate("file", "content") - require.NoError(t, err) + assert.NilError(t, err) if archive == nil { t.Fatal("The generated archive should not be nil.") } @@ -69,7 +69,7 @@ func TestGenerateWithContent(t *testing.T) { if err == io.EOF { break } - require.NoError(t, err) + assert.NilError(t, err) buf := new(bytes.Buffer) buf.ReadFrom(tr) content := buf.String() diff --git a/components/engine/pkg/authorization/api_test.go b/components/engine/pkg/authorization/api_test.go index 90a984276de..84964d2c5e8 100644 --- a/components/engine/pkg/authorization/api_test.go +++ b/components/engine/pkg/authorization/api_test.go @@ -11,7 +11,8 @@ import ( "testing" "time" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestPeerCertificateMarshalJSON(t *testing.T) { @@ -32,21 +33,21 @@ func TestPeerCertificateMarshalJSON(t *testing.T) { } // generate private key privatekey, err := rsa.GenerateKey(rand.Reader, 2048) - require.NoError(t, err) + assert.NilError(t, err) publickey := &privatekey.PublicKey // create a self-signed certificate. template = parent var parent = template raw, err := x509.CreateCertificate(rand.Reader, template, parent, publickey, privatekey) - require.NoError(t, err) + assert.NilError(t, err) cert, err := x509.ParseCertificate(raw) - require.NoError(t, err) + assert.NilError(t, err) var certs = []*x509.Certificate{cert} addr := "www.authz.com/auth" req, err := http.NewRequest("GET", addr, nil) - require.NoError(t, err) + assert.NilError(t, err) req.RequestURI = addr req.TLS = &tls.ConnectionState{} @@ -58,15 +59,15 @@ func TestPeerCertificateMarshalJSON(t *testing.T) { t.Run("Marshalling :", func(t *testing.T) { raw, err = pcObj.MarshalJSON() - require.NotNil(t, raw) - require.Nil(t, err) + assert.Assert(t, raw != nil) + assert.NilError(t, err) }) t.Run("UnMarshalling :", func(t *testing.T) { err := pcObj.UnmarshalJSON(raw) - require.Nil(t, err) - require.Equal(t, "Earth", pcObj.Subject.Country[0]) - require.Equal(t, true, pcObj.IsCA) + assert.Assert(t, is.Nil(err)) + assert.Equal(t, "Earth", pcObj.Subject.Country[0]) + assert.Equal(t, true, pcObj.IsCA) }) diff --git a/components/engine/pkg/authorization/middleware_test.go b/components/engine/pkg/authorization/middleware_test.go index 3812d804e39..e32e4bf4279 100644 --- a/components/engine/pkg/authorization/middleware_test.go +++ b/components/engine/pkg/authorization/middleware_test.go @@ -7,7 +7,7 @@ import ( "testing" "github.com/docker/docker/pkg/plugingetter" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) func TestMiddleware(t *testing.T) { @@ -15,9 +15,9 @@ func TestMiddleware(t *testing.T) { var pluginGetter plugingetter.PluginGetter m := NewMiddleware(pluginNames, pluginGetter) authPlugins := m.getAuthzPlugins() - require.Equal(t, 2, len(authPlugins)) - require.EqualValues(t, pluginNames[0], authPlugins[0].Name()) - require.EqualValues(t, pluginNames[1], authPlugins[1].Name()) + assert.Equal(t, 2, len(authPlugins)) + assert.Equal(t, pluginNames[0], authPlugins[0].Name()) + assert.Equal(t, pluginNames[1], authPlugins[1].Name()) } func TestNewResponseModifier(t *testing.T) { @@ -25,17 +25,17 @@ func TestNewResponseModifier(t *testing.T) { modifier := NewResponseModifier(recorder) modifier.Header().Set("H1", "V1") modifier.Write([]byte("body")) - require.False(t, modifier.Hijacked()) + assert.Assert(t, !modifier.Hijacked()) modifier.WriteHeader(http.StatusInternalServerError) - require.NotNil(t, modifier.RawBody()) + assert.Assert(t, modifier.RawBody() != nil) raw, err := modifier.RawHeaders() - require.NotNil(t, raw) - require.Nil(t, err) + assert.Assert(t, raw != nil) + assert.NilError(t, err) headerData := strings.Split(strings.TrimSpace(string(raw)), ":") - require.EqualValues(t, "H1", strings.TrimSpace(headerData[0])) - require.EqualValues(t, "V1", strings.TrimSpace(headerData[1])) + assert.Equal(t, "H1", strings.TrimSpace(headerData[0])) + assert.Equal(t, "V1", strings.TrimSpace(headerData[1])) modifier.Flush() modifier.FlushAll() diff --git a/components/engine/pkg/authorization/middleware_unix_test.go b/components/engine/pkg/authorization/middleware_unix_test.go index 257832b3383..ddfe9d958f7 100644 --- a/components/engine/pkg/authorization/middleware_unix_test.go +++ b/components/engine/pkg/authorization/middleware_unix_test.go @@ -8,7 +8,8 @@ import ( "testing" "github.com/docker/docker/pkg/plugingetter" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -30,7 +31,7 @@ func TestMiddlewareWrapHandler(t *testing.T) { middleWare.SetPlugins([]string{"My Test Plugin"}) setAuthzPlugins(middleWare, authList) mdHandler := middleWare.WrapHandler(handler) - require.NotNil(t, mdHandler) + assert.Assert(t, mdHandler != nil) addr := "www.example.com/auth" req, _ := http.NewRequest("GET", addr, nil) @@ -46,7 +47,7 @@ func TestMiddlewareWrapHandler(t *testing.T) { Msg: "Server Auth Not Allowed", } if err := mdHandler(ctx, resp, req, map[string]string{}); err == nil { - require.Error(t, err) + assert.Assert(t, is.ErrorContains(err, "")) } }) @@ -57,7 +58,7 @@ func TestMiddlewareWrapHandler(t *testing.T) { Msg: "Server Auth Allowed", } if err := mdHandler(ctx, resp, req, map[string]string{}); err != nil { - require.NoError(t, err) + assert.NilError(t, err) } }) diff --git a/components/engine/pkg/fileutils/fileutils_test.go b/components/engine/pkg/fileutils/fileutils_test.go index 0a648d14669..b167538d5a1 100644 --- a/components/engine/pkg/fileutils/fileutils_test.go +++ b/components/engine/pkg/fileutils/fileutils_test.go @@ -10,8 +10,8 @@ import ( "strings" "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) // CopyFile with invalid src @@ -384,9 +384,9 @@ func TestMatches(t *testing.T) { for _, test := range tests { desc := fmt.Sprintf("pattern=%q text=%q", test.pattern, test.text) pm, err := NewPatternMatcher([]string{test.pattern}) - require.NoError(t, err, desc) + assert.NilError(t, err, desc) res, _ := pm.Matches(test.text) - assert.Equal(t, test.pass, res, desc) + assert.Check(t, is.Equal(test.pass, res), desc) } } diff --git a/components/engine/pkg/idtools/idtools_unix_test.go b/components/engine/pkg/idtools/idtools_unix_test.go index 931e332bb91..e493b9e8d51 100644 --- a/components/engine/pkg/idtools/idtools_unix_test.go +++ b/components/engine/pkg/idtools/idtools_unix_test.go @@ -10,9 +10,9 @@ import ( "path/filepath" "testing" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/skip" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "golang.org/x/sys/unix" ) @@ -89,7 +89,7 @@ func TestMkdirAllAndChown(t *testing.T) { func TestMkdirAllAndChownNew(t *testing.T) { RequiresRoot(t) dirName, err := ioutil.TempDir("", "mkdirnew") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(dirName) testTree := map[string]node{ @@ -99,32 +99,32 @@ func TestMkdirAllAndChownNew(t *testing.T) { "lib/x86_64": {45, 45}, "lib/x86_64/share": {1, 1}, } - require.NoError(t, buildTree(dirName, testTree)) + assert.NilError(t, buildTree(dirName, testTree)) // test adding a directory to a pre-existing dir; only the new dir is owned by the uid/gid err = MkdirAllAndChownNew(filepath.Join(dirName, "usr", "share"), 0755, IDPair{UID: 99, GID: 99}) - require.NoError(t, err) + assert.NilError(t, err) testTree["usr/share"] = node{99, 99} verifyTree, err := readTree(dirName, "") - require.NoError(t, err) - require.NoError(t, compareTrees(testTree, verifyTree)) + assert.NilError(t, err) + assert.NilError(t, compareTrees(testTree, verifyTree)) // test 2-deep new directories--both should be owned by the uid/gid pair err = MkdirAllAndChownNew(filepath.Join(dirName, "lib", "some", "other"), 0755, IDPair{UID: 101, GID: 101}) - require.NoError(t, err) + assert.NilError(t, err) testTree["lib/some"] = node{101, 101} testTree["lib/some/other"] = node{101, 101} verifyTree, err = readTree(dirName, "") - require.NoError(t, err) - require.NoError(t, compareTrees(testTree, verifyTree)) + assert.NilError(t, err) + assert.NilError(t, compareTrees(testTree, verifyTree)) // test a directory that already exists; should NOT be chowned err = MkdirAllAndChownNew(filepath.Join(dirName, "usr"), 0755, IDPair{UID: 102, GID: 102}) - require.NoError(t, err) + assert.NilError(t, err) verifyTree, err = readTree(dirName, "") - require.NoError(t, err) - require.NoError(t, compareTrees(testTree, verifyTree)) + assert.NilError(t, err) + assert.NilError(t, compareTrees(testTree, verifyTree)) } func TestMkdirAndChown(t *testing.T) { @@ -235,7 +235,7 @@ func compareTrees(left, right map[string]node) error { func delUser(t *testing.T, name string) { _, err := execCmd("userdel", name) - assert.NoError(t, err) + assert.Check(t, err) } func TestParseSubidFileWithNewlinesAndComments(t *testing.T) { @@ -283,9 +283,9 @@ func TestGetRootUIDGID(t *testing.T) { } uid, gid, err := GetRootUIDGID(uidMap, gidMap) - assert.NoError(t, err) - assert.Equal(t, os.Getegid(), uid) - assert.Equal(t, os.Getegid(), gid) + assert.Check(t, err) + assert.Check(t, is.Equal(os.Getegid(), uid)) + assert.Check(t, is.Equal(os.Getegid(), gid)) uidMapError := []IDMap{ { @@ -295,7 +295,7 @@ func TestGetRootUIDGID(t *testing.T) { }, } _, _, err = GetRootUIDGID(uidMapError, gidMap) - assert.EqualError(t, err, "Container ID 0 cannot be mapped to a host ID") + assert.Check(t, is.Error(err, "Container ID 0 cannot be mapped to a host ID")) } func TestToContainer(t *testing.T) { @@ -308,74 +308,74 @@ func TestToContainer(t *testing.T) { } containerID, err := toContainer(2, uidMap) - assert.NoError(t, err) - assert.Equal(t, uidMap[0].ContainerID, containerID) + assert.Check(t, err) + assert.Check(t, is.Equal(uidMap[0].ContainerID, containerID)) } func TestNewIDMappings(t *testing.T) { RequiresRoot(t) _, _, err := AddNamespaceRangesUser(tempUser) - assert.NoError(t, err) + assert.Check(t, err) defer delUser(t, tempUser) tempUser, err := user.Lookup(tempUser) - assert.NoError(t, err) + assert.Check(t, err) gids, err := tempUser.GroupIds() - assert.NoError(t, err) + assert.Check(t, err) group, err := user.LookupGroupId(string(gids[0])) - assert.NoError(t, err) + assert.Check(t, err) idMappings, err := NewIDMappings(tempUser.Username, group.Name) - assert.NoError(t, err) + assert.Check(t, err) rootUID, rootGID, err := GetRootUIDGID(idMappings.UIDs(), idMappings.GIDs()) - assert.NoError(t, err) + assert.Check(t, err) dirName, err := ioutil.TempDir("", "mkdirall") - assert.NoError(t, err, "Couldn't create temp directory") + assert.Check(t, err, "Couldn't create temp directory") defer os.RemoveAll(dirName) err = MkdirAllAndChown(dirName, 0700, IDPair{UID: rootUID, GID: rootGID}) - assert.NoError(t, err, "Couldn't change ownership of file path. Got error") - assert.True(t, CanAccess(dirName, idMappings.RootPair()), fmt.Sprintf("Unable to access %s directory with user UID:%d and GID:%d", dirName, rootUID, rootGID)) + assert.Check(t, err, "Couldn't change ownership of file path. Got error") + assert.Check(t, CanAccess(dirName, idMappings.RootPair()), fmt.Sprintf("Unable to access %s directory with user UID:%d and GID:%d", dirName, rootUID, rootGID)) } func TestLookupUserAndGroup(t *testing.T) { RequiresRoot(t) uid, gid, err := AddNamespaceRangesUser(tempUser) - assert.NoError(t, err) + assert.Check(t, err) defer delUser(t, tempUser) fetchedUser, err := LookupUser(tempUser) - assert.NoError(t, err) + assert.Check(t, err) fetchedUserByID, err := LookupUID(uid) - assert.NoError(t, err) - assert.Equal(t, fetchedUserByID, fetchedUser) + assert.Check(t, err) + assert.Check(t, is.DeepEqual(fetchedUserByID, fetchedUser)) fetchedGroup, err := LookupGroup(tempUser) - assert.NoError(t, err) + assert.Check(t, err) fetchedGroupByID, err := LookupGID(gid) - assert.NoError(t, err) - assert.Equal(t, fetchedGroupByID, fetchedGroup) + assert.Check(t, err) + assert.Check(t, is.DeepEqual(fetchedGroupByID, fetchedGroup)) } func TestLookupUserAndGroupThatDoesNotExist(t *testing.T) { fakeUser := "fakeuser" _, err := LookupUser(fakeUser) - assert.EqualError(t, err, "getent unable to find entry \""+fakeUser+"\" in passwd database") + assert.Check(t, is.Error(err, "getent unable to find entry \""+fakeUser+"\" in passwd database")) _, err = LookupUID(-1) - assert.Error(t, err) + assert.Check(t, is.ErrorContains(err, "")) fakeGroup := "fakegroup" _, err = LookupGroup(fakeGroup) - assert.EqualError(t, err, "getent unable to find entry \""+fakeGroup+"\" in group database") + assert.Check(t, is.Error(err, "getent unable to find entry \""+fakeGroup+"\" in group database")) _, err = LookupGID(-1) - assert.Error(t, err) + assert.Check(t, is.ErrorContains(err, "")) } // TestMkdirIsNotDir checks that mkdirAs() function (used by MkdirAll...) @@ -389,7 +389,7 @@ func TestMkdirIsNotDir(t *testing.T) { defer os.Remove(file.Name()) err = mkdirAs(file.Name(), 0755, 0, 0, false, false) - assert.EqualError(t, err, "mkdir "+file.Name()+": not a directory") + assert.Check(t, is.Error(err, "mkdir "+file.Name()+": not a directory")) } func RequiresRoot(t *testing.T) { diff --git a/components/engine/pkg/ioutils/readers_test.go b/components/engine/pkg/ioutils/readers_test.go index e322fdf840d..e009ab26f67 100644 --- a/components/engine/pkg/ioutils/readers_test.go +++ b/components/engine/pkg/ioutils/readers_test.go @@ -7,7 +7,8 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/net/context" ) @@ -36,7 +37,7 @@ func TestReaderErrWrapperReadOnError(t *testing.T) { called = true }) _, err := wrapper.Read([]byte{}) - assert.EqualError(t, err, "error reader always fail") + assert.Check(t, is.Error(err, "error reader always fail")) if !called { t.Fatalf("readErrWrapper should have call the anonymous function on failure") } diff --git a/components/engine/pkg/jsonmessage/jsonmessage_test.go b/components/engine/pkg/jsonmessage/jsonmessage_test.go index 2bad8a2025d..ab1d879c5a3 100644 --- a/components/engine/pkg/jsonmessage/jsonmessage_test.go +++ b/components/engine/pkg/jsonmessage/jsonmessage_test.go @@ -9,7 +9,8 @@ import ( "time" "github.com/docker/docker/pkg/term" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestError(t *testing.T) { @@ -198,7 +199,7 @@ func TestJSONMessageDisplayWithJSONError(t *testing.T) { jsonMessage = JSONMessage{Error: &JSONError{401, "Anything"}} err = jsonMessage.Display(data, &noTermInfo{}) - assert.EqualError(t, err, "authentication is required") + assert.Check(t, is.Error(err, "authentication is required")) } func TestDisplayJSONMessagesStreamInvalidJSON(t *testing.T) { diff --git a/components/engine/pkg/plugins/client_test.go b/components/engine/pkg/plugins/client_test.go index 10c8d8fd567..d420010f1a1 100644 --- a/components/engine/pkg/plugins/client_test.go +++ b/components/engine/pkg/plugins/client_test.go @@ -14,9 +14,9 @@ import ( "github.com/docker/docker/pkg/plugins/transport" "github.com/docker/go-connections/tlsconfig" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/pkg/errors" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) var ( @@ -88,7 +88,7 @@ func TestEchoInputOutput(t *testing.T) { t.Fatal(err) } - assert.Equal(t, m, output) + assert.Check(t, is.DeepEqual(m, output)) err = c.Call("Test.Echo", nil, nil) if err != nil { t.Fatal(err) @@ -205,7 +205,7 @@ func TestClientStream(t *testing.T) { if err := json.NewDecoder(body).Decode(&output); err != nil { t.Fatalf("Test.Echo: error reading plugin resp: %v", err) } - assert.Equal(t, m, output) + assert.Check(t, is.DeepEqual(m, output)) } func TestClientSendFile(t *testing.T) { @@ -233,7 +233,7 @@ func TestClientSendFile(t *testing.T) { if err := c.SendFile("Test.Echo", &buf, &output); err != nil { t.Fatal(err) } - assert.Equal(t, m, output) + assert.Check(t, is.DeepEqual(m, output)) } func TestClientWithRequestTimeout(t *testing.T) { @@ -248,7 +248,7 @@ func TestClientWithRequestTimeout(t *testing.T) { client := &Client{http: srv.Client(), requestFactory: &testRequestWrapper{srv}} _, err := client.callWithRetry("/Plugin.Hello", nil, false, WithRequestTimeout(timeout)) - require.Error(t, err, "expected error") + assert.Assert(t, is.ErrorContains(err, ""), "expected error") err = errors.Cause(err) @@ -256,7 +256,7 @@ func TestClientWithRequestTimeout(t *testing.T) { case *url.Error: err = e.Err } - require.Equal(t, context.DeadlineExceeded, err) + assert.DeepEqual(t, context.DeadlineExceeded, err) } type testRequestWrapper struct { diff --git a/components/engine/pkg/plugins/discovery_unix_test.go b/components/engine/pkg/plugins/discovery_unix_test.go index 9212946b2ed..2c718d8beed 100644 --- a/components/engine/pkg/plugins/discovery_unix_test.go +++ b/components/engine/pkg/plugins/discovery_unix_test.go @@ -11,7 +11,7 @@ import ( "reflect" "testing" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) func TestLocalSocket(t *testing.T) { @@ -91,7 +91,7 @@ func TestScan(t *testing.T) { r := newLocalRegistry() p, err := r.Plugin(name) - require.NoError(t, err) + assert.NilError(t, err) pluginNamesNotEmpty, err := Scan() if err != nil { diff --git a/components/engine/pkg/plugins/plugin_test.go b/components/engine/pkg/plugins/plugin_test.go index 1540a19a642..0efd5e3aa0d 100644 --- a/components/engine/pkg/plugins/plugin_test.go +++ b/components/engine/pkg/plugins/plugin_test.go @@ -14,8 +14,9 @@ import ( "github.com/docker/docker/pkg/plugins/transport" "github.com/docker/go-connections/tlsconfig" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/pkg/errors" - "github.com/stretchr/testify/assert" ) const ( @@ -78,11 +79,11 @@ func TestGet(t *testing.T) { // check negative case where plugin fruit doesn't implement banana _, err = Get("fruit", "banana") - assert.Equal(t, errors.Cause(err), ErrNotImplements) + assert.Check(t, is.DeepEqual(errors.Cause(err), ErrNotImplements)) // check negative case where plugin vegetable doesn't exist _, err = Get("vegetable", "potato") - assert.Equal(t, errors.Cause(err), ErrNotFound) + assert.Check(t, is.DeepEqual(errors.Cause(err), ErrNotFound)) } diff --git a/components/engine/pkg/plugins/transport/http_test.go b/components/engine/pkg/plugins/transport/http_test.go index 2e48b0fe0ac..081f60424d6 100644 --- a/components/engine/pkg/plugins/transport/http_test.go +++ b/components/engine/pkg/plugins/transport/http_test.go @@ -5,7 +5,8 @@ import ( "net/http" "testing" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestHTTPTransport(t *testing.T) { @@ -16,5 +17,5 @@ func TestHTTPTransport(t *testing.T) { if err != nil { t.Fatal(err) } - assert.Equal(t, "POST", request.Method) + assert.Check(t, is.Equal("POST", request.Method)) } diff --git a/components/engine/pkg/pools/pools_test.go b/components/engine/pkg/pools/pools_test.go index 2dbea36ae02..76015169d42 100644 --- a/components/engine/pkg/pools/pools_test.go +++ b/components/engine/pkg/pools/pools_test.go @@ -7,8 +7,8 @@ import ( "strings" "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestBufioReaderPoolGetWithNoReaderShouldCreateOne(t *testing.T) { @@ -95,16 +95,16 @@ func TestBufioWriterPoolPutAndGet(t *testing.T) { buf := new(bytes.Buffer) bw := bufio.NewWriter(buf) writer := BufioWriter32KPool.Get(bw) - require.NotNil(t, writer) + assert.Assert(t, writer != nil) written, err := writer.Write([]byte("foobar")) - require.NoError(t, err) - assert.Equal(t, 6, written) + assert.NilError(t, err) + assert.Check(t, is.Equal(6, written)) // Make sure we Flush all the way ? writer.Flush() bw.Flush() - assert.Len(t, buf.Bytes(), 6) + assert.Check(t, is.Len(buf.Bytes(), 6)) // Reset the buffer buf.Reset() BufioWriter32KPool.Put(writer) diff --git a/components/engine/pkg/reexec/reexec_test.go b/components/engine/pkg/reexec/reexec_test.go index e6bbe9f9a08..90aa01a390f 100644 --- a/components/engine/pkg/reexec/reexec_test.go +++ b/components/engine/pkg/reexec/reexec_test.go @@ -5,8 +5,7 @@ import ( "os/exec" "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) func init() { @@ -19,7 +18,7 @@ func init() { func TestRegister(t *testing.T) { defer func() { if r := recover(); r != nil { - require.Equal(t, `reexec func already registered under name "reexec"`, r) + assert.Equal(t, `reexec func already registered under name "reexec"`, r) } }() Register("reexec", func() {}) @@ -28,13 +27,13 @@ func TestRegister(t *testing.T) { func TestCommand(t *testing.T) { cmd := Command("reexec") w, err := cmd.StdinPipe() - require.NoError(t, err, "Error on pipe creation: %v", err) + assert.NilError(t, err, "Error on pipe creation: %v", err) defer w.Close() err = cmd.Start() - require.NoError(t, err, "Error on re-exec cmd: %v", err) + assert.NilError(t, err, "Error on re-exec cmd: %v", err) err = cmd.Wait() - require.EqualError(t, err, "exit status 2") + assert.Error(t, err, "exit status 2") } func TestNaiveSelf(t *testing.T) { @@ -44,10 +43,10 @@ func TestNaiveSelf(t *testing.T) { cmd := exec.Command(naiveSelf(), "-test.run=TestNaiveSelf") cmd.Env = append(os.Environ(), "TEST_CHECK=1") err := cmd.Start() - require.NoError(t, err, "Unable to start command") + assert.NilError(t, err, "Unable to start command") err = cmd.Wait() - require.EqualError(t, err, "exit status 2") + assert.Error(t, err, "exit status 2") os.Args[0] = "mkdir" - assert.NotEqual(t, naiveSelf(), os.Args[0]) + assert.Check(t, naiveSelf() != os.Args[0]) } diff --git a/components/engine/pkg/signal/signal_linux_test.go b/components/engine/pkg/signal/signal_linux_test.go index d7e8da25238..71c577ed64a 100644 --- a/components/engine/pkg/signal/signal_linux_test.go +++ b/components/engine/pkg/signal/signal_linux_test.go @@ -8,7 +8,8 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestCatchAll(t *testing.T) { @@ -34,7 +35,7 @@ func TestCatchAll(t *testing.T) { }() s := <-sigs - assert.EqualValues(t, s.String(), signal.String()) + assert.Check(t, is.Equal(s.String(), signal.String())) } } @@ -50,9 +51,9 @@ func TestStopCatch(t *testing.T) { syscall.Kill(syscall.Getpid(), signal) }() signalString := <-channel - assert.EqualValues(t, signalString.String(), signal.String()) + assert.Check(t, is.Equal(signalString.String(), signal.String())) StopCatch(channel) _, ok := <-channel - assert.EqualValues(t, ok, false) + assert.Check(t, is.Equal(ok, false)) } diff --git a/components/engine/pkg/signal/signal_test.go b/components/engine/pkg/signal/signal_test.go index 1add526d160..bbf3736fc8c 100644 --- a/components/engine/pkg/signal/signal_test.go +++ b/components/engine/pkg/signal/signal_test.go @@ -4,30 +4,31 @@ import ( "syscall" "testing" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestParseSignal(t *testing.T) { _, checkAtoiError := ParseSignal("0") - assert.EqualError(t, checkAtoiError, "Invalid signal: 0") + assert.Check(t, is.Error(checkAtoiError, "Invalid signal: 0")) _, error := ParseSignal("SIG") - assert.EqualError(t, error, "Invalid signal: SIG") + assert.Check(t, is.Error(error, "Invalid signal: SIG")) for sigStr := range SignalMap { responseSignal, error := ParseSignal(sigStr) - assert.NoError(t, error) + assert.Check(t, error) signal := SignalMap[sigStr] - assert.EqualValues(t, signal, responseSignal) + assert.Check(t, is.DeepEqual(signal, responseSignal)) } } func TestValidSignalForPlatform(t *testing.T) { isValidSignal := ValidSignalForPlatform(syscall.Signal(0)) - assert.EqualValues(t, false, isValidSignal) + assert.Check(t, is.Equal(false, isValidSignal)) for _, sigN := range SignalMap { isValidSignal = ValidSignalForPlatform(syscall.Signal(sigN)) - assert.EqualValues(t, true, isValidSignal) + assert.Check(t, is.Equal(true, isValidSignal)) } } diff --git a/components/engine/pkg/signal/trap_linux_test.go b/components/engine/pkg/signal/trap_linux_test.go index d32a4366f47..a3afe7a7b68 100644 --- a/components/engine/pkg/signal/trap_linux_test.go +++ b/components/engine/pkg/signal/trap_linux_test.go @@ -10,19 +10,19 @@ import ( "syscall" "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func buildTestBinary(t *testing.T, tmpdir string, prefix string) (string, string) { tmpDir, err := ioutil.TempDir(tmpdir, prefix) - require.NoError(t, err) + assert.NilError(t, err) exePath := tmpDir + "/" + prefix wd, _ := os.Getwd() testHelperCode := wd + "/testfiles/main.go" cmd := exec.Command("go", "build", "-o", exePath, testHelperCode) err = cmd.Run() - require.NoError(t, err) + assert.NilError(t, err) return exePath, tmpDir } @@ -48,14 +48,14 @@ func TestTrap(t *testing.T) { cmd.Env = append(cmd.Env, "IF_MULTIPLE=1") } err := cmd.Start() - require.NoError(t, err) + assert.NilError(t, err) err = cmd.Wait() if e, ok := err.(*exec.ExitError); ok { code := e.Sys().(syscall.WaitStatus).ExitStatus() if v.multiple { - assert.Equal(t, 128+int(v.signal.(syscall.Signal)), code) + assert.Check(t, is.DeepEqual(128+int(v.signal.(syscall.Signal)), code)) } else { - assert.Equal(t, 99, code) + assert.Check(t, is.Equal(99, code)) } continue } @@ -66,17 +66,17 @@ func TestTrap(t *testing.T) { func TestDumpStacks(t *testing.T) { directory, err := ioutil.TempDir("", "test-dump-tasks") - assert.NoError(t, err) + assert.Check(t, err) defer os.RemoveAll(directory) dumpPath, err := DumpStacks(directory) - assert.NoError(t, err) + assert.Check(t, err) readFile, _ := ioutil.ReadFile(dumpPath) fileData := string(readFile) - assert.Contains(t, fileData, "goroutine") + assert.Check(t, is.Contains(fileData, "goroutine")) } func TestDumpStacksWithEmptyInput(t *testing.T) { path, err := DumpStacks("") - assert.NoError(t, err) - assert.Equal(t, os.Stderr.Name(), path) + assert.Check(t, err) + assert.Check(t, is.Equal(os.Stderr.Name(), path)) } diff --git a/components/engine/pkg/streamformatter/streamformatter_test.go b/components/engine/pkg/streamformatter/streamformatter_test.go index 7259c54df8b..e655f9140ac 100644 --- a/components/engine/pkg/streamformatter/streamformatter_test.go +++ b/components/engine/pkg/streamformatter/streamformatter_test.go @@ -8,14 +8,14 @@ import ( "testing" "github.com/docker/docker/pkg/jsonmessage" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestRawProgressFormatterFormatStatus(t *testing.T) { sf := rawProgressFormatter{} res := sf.formatStatus("ID", "%s%d", "a", 1) - assert.Equal(t, "a1\r\n", string(res)) + assert.Check(t, is.Equal("a1\r\n", string(res))) } func TestRawProgressFormatterFormatProgress(t *testing.T) { @@ -27,28 +27,28 @@ func TestRawProgressFormatterFormatProgress(t *testing.T) { } res := sf.formatProgress("id", "action", jsonProgress, nil) out := string(res) - assert.True(t, strings.HasPrefix(out, "action [====")) - assert.Contains(t, out, "15B/30B") - assert.True(t, strings.HasSuffix(out, "\r")) + assert.Check(t, strings.HasPrefix(out, "action [====")) + assert.Check(t, is.Contains(out, "15B/30B")) + assert.Check(t, strings.HasSuffix(out, "\r")) } func TestFormatStatus(t *testing.T) { res := FormatStatus("ID", "%s%d", "a", 1) expected := `{"status":"a1","id":"ID"}` + streamNewline - assert.Equal(t, expected, string(res)) + assert.Check(t, is.Equal(expected, string(res))) } func TestFormatError(t *testing.T) { res := FormatError(errors.New("Error for formatter")) expected := `{"errorDetail":{"message":"Error for formatter"},"error":"Error for formatter"}` + "\r\n" - assert.Equal(t, expected, string(res)) + assert.Check(t, is.Equal(expected, string(res))) } func TestFormatJSONError(t *testing.T) { err := &jsonmessage.JSONError{Code: 50, Message: "Json error"} res := FormatError(err) expected := `{"errorDetail":{"code":50,"message":"Json error"},"error":"Json error"}` + streamNewline - assert.Equal(t, expected, string(res)) + assert.Check(t, is.Equal(expected, string(res))) } func TestJsonProgressFormatterFormatProgress(t *testing.T) { @@ -61,9 +61,9 @@ func TestJsonProgressFormatterFormatProgress(t *testing.T) { res := sf.formatProgress("id", "action", jsonProgress, &AuxFormatter{Writer: &bytes.Buffer{}}) msg := &jsonmessage.JSONMessage{} - require.NoError(t, json.Unmarshal(res, msg)) - assert.Equal(t, "id", msg.ID) - assert.Equal(t, "action", msg.Status) + assert.NilError(t, json.Unmarshal(res, msg)) + assert.Check(t, is.Equal("id", msg.ID)) + assert.Check(t, is.Equal("action", msg.Status)) // jsonProgress will always be in the format of: // [=========================> ] 15B/30B 412910h51m30s @@ -81,20 +81,20 @@ func TestJsonProgressFormatterFormatProgress(t *testing.T) { expectedProgress, expectedProgressShort, msg.ProgressMessage) } - assert.Equal(t, jsonProgress, msg.Progress) + assert.Check(t, is.DeepEqual(jsonProgress, msg.Progress)) } func TestJsonProgressFormatterFormatStatus(t *testing.T) { sf := jsonProgressFormatter{} res := sf.formatStatus("ID", "%s%d", "a", 1) - assert.Equal(t, `{"status":"a1","id":"ID"}`+streamNewline, string(res)) + assert.Check(t, is.Equal(`{"status":"a1","id":"ID"}`+streamNewline, string(res))) } func TestNewJSONProgressOutput(t *testing.T) { b := bytes.Buffer{} b.Write(FormatStatus("id", "Downloading")) _ = NewJSONProgressOutput(&b, false) - assert.Equal(t, `{"status":"Downloading","id":"id"}`+streamNewline, b.String()) + assert.Check(t, is.Equal(`{"status":"Downloading","id":"id"}`+streamNewline, b.String())) } func TestAuxFormatterEmit(t *testing.T) { @@ -104,6 +104,6 @@ func TestAuxFormatterEmit(t *testing.T) { Data string }{"Additional data"} err := aux.Emit(sampleAux) - require.NoError(t, err) - assert.Equal(t, `{"aux":{"Data":"Additional data"}}`+streamNewline, b.String()) + assert.NilError(t, err) + assert.Check(t, is.Equal(`{"aux":{"Data":"Additional data"}}`+streamNewline, b.String())) } diff --git a/components/engine/pkg/streamformatter/streamwriter_test.go b/components/engine/pkg/streamformatter/streamwriter_test.go index 332d66414ff..b74d6fb2d34 100644 --- a/components/engine/pkg/streamformatter/streamwriter_test.go +++ b/components/engine/pkg/streamformatter/streamwriter_test.go @@ -4,8 +4,8 @@ import ( "bytes" "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestStreamWriterStdout(t *testing.T) { @@ -14,11 +14,11 @@ func TestStreamWriterStdout(t *testing.T) { sw := NewStdoutWriter(buffer) size, err := sw.Write([]byte(content)) - require.NoError(t, err) - assert.Equal(t, len(content), size) + assert.NilError(t, err) + assert.Check(t, is.Equal(len(content), size)) expected := `{"stream":"content"}` + streamNewline - assert.Equal(t, expected, buffer.String()) + assert.Check(t, is.Equal(expected, buffer.String())) } func TestStreamWriterStderr(t *testing.T) { @@ -27,9 +27,9 @@ func TestStreamWriterStderr(t *testing.T) { sw := NewStderrWriter(buffer) size, err := sw.Write([]byte(content)) - require.NoError(t, err) - assert.Equal(t, len(content), size) + assert.NilError(t, err) + assert.Check(t, is.Equal(len(content), size)) expected := `{"stream":"\u001b[91mcontent\u001b[0m"}` + streamNewline - assert.Equal(t, expected, buffer.String()) + assert.Check(t, is.Equal(expected, buffer.String())) } diff --git a/components/engine/pkg/sysinfo/sysinfo_linux_test.go b/components/engine/pkg/sysinfo/sysinfo_linux_test.go index a798bf6e85d..e8a12a35c9a 100644 --- a/components/engine/pkg/sysinfo/sysinfo_linux_test.go +++ b/components/engine/pkg/sysinfo/sysinfo_linux_test.go @@ -7,18 +7,18 @@ import ( "path/filepath" "testing" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" "golang.org/x/sys/unix" ) func TestReadProcBool(t *testing.T) { tmpDir, err := ioutil.TempDir("", "test-sysinfo-proc") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(tmpDir) procFile := filepath.Join(tmpDir, "read-proc-bool") err = ioutil.WriteFile(procFile, []byte("1"), 0644) - require.NoError(t, err) + assert.NilError(t, err) if !readProcBool(procFile) { t.Fatal("expected proc bool to be true, got false") @@ -39,7 +39,7 @@ func TestReadProcBool(t *testing.T) { func TestCgroupEnabled(t *testing.T) { cgroupDir, err := ioutil.TempDir("", "cgroup-test") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(cgroupDir) if cgroupEnabled(cgroupDir, "test") { @@ -47,7 +47,7 @@ func TestCgroupEnabled(t *testing.T) { } err = ioutil.WriteFile(path.Join(cgroupDir, "test"), []byte{}, 0644) - require.NoError(t, err) + assert.NilError(t, err) if !cgroupEnabled(cgroupDir, "test") { t.Fatal("cgroupEnabled should be true") @@ -56,11 +56,11 @@ func TestCgroupEnabled(t *testing.T) { func TestNew(t *testing.T) { sysInfo := New(false) - require.NotNil(t, sysInfo) + assert.Assert(t, sysInfo != nil) checkSysInfo(t, sysInfo) sysInfo = New(true) - require.NotNil(t, sysInfo) + assert.Assert(t, sysInfo != nil) checkSysInfo(t, sysInfo) } @@ -69,10 +69,10 @@ func checkSysInfo(t *testing.T, sysInfo *SysInfo) { if err := unix.Prctl(unix.PR_GET_SECCOMP, 0, 0, 0, 0); err != unix.EINVAL { // Make sure the kernel has CONFIG_SECCOMP_FILTER. if err := unix.Prctl(unix.PR_SET_SECCOMP, unix.SECCOMP_MODE_FILTER, 0, 0, 0); err != unix.EINVAL { - require.True(t, sysInfo.Seccomp) + assert.Assert(t, sysInfo.Seccomp) } } else { - require.False(t, sysInfo.Seccomp) + assert.Assert(t, !sysInfo.Seccomp) } } @@ -83,7 +83,7 @@ func TestNewAppArmorEnabled(t *testing.T) { } sysInfo := New(true) - require.True(t, sysInfo.AppArmor) + assert.Assert(t, sysInfo.AppArmor) } func TestNewAppArmorDisabled(t *testing.T) { @@ -93,7 +93,7 @@ func TestNewAppArmorDisabled(t *testing.T) { } sysInfo := New(true) - require.False(t, sysInfo.AppArmor) + assert.Assert(t, !sysInfo.AppArmor) } func TestNumCPU(t *testing.T) { diff --git a/components/engine/pkg/system/stat_unix_test.go b/components/engine/pkg/system/stat_unix_test.go index 12687b33c11..fd68a966565 100644 --- a/components/engine/pkg/system/stat_unix_test.go +++ b/components/engine/pkg/system/stat_unix_test.go @@ -7,7 +7,7 @@ import ( "syscall" "testing" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) // TestFromStatT tests fromStatT for a tempfile @@ -17,10 +17,10 @@ func TestFromStatT(t *testing.T) { stat := &syscall.Stat_t{} err := syscall.Lstat(file, stat) - require.NoError(t, err) + assert.NilError(t, err) s, err := fromStatT(stat) - require.NoError(t, err) + assert.NilError(t, err) if stat.Mode != s.Mode() { t.Fatal("got invalid mode") diff --git a/components/engine/pkg/tarsum/tarsum_test.go b/components/engine/pkg/tarsum/tarsum_test.go index 466eda0aec5..35f08ebce95 100644 --- a/components/engine/pkg/tarsum/tarsum_test.go +++ b/components/engine/pkg/tarsum/tarsum_test.go @@ -17,8 +17,8 @@ import ( "strings" "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) type testLayer struct { @@ -225,13 +225,13 @@ func TestNewTarSumForLabel(t *testing.T) { func TestEmptyTar(t *testing.T) { // Test without gzip. ts, err := emptyTarSum(false) - require.NoError(t, err) + assert.NilError(t, err) zeroBlock := make([]byte, 1024) buf := new(bytes.Buffer) n, err := io.Copy(buf, ts) - require.NoError(t, err) + assert.NilError(t, err) if n != int64(len(zeroBlock)) || !bytes.Equal(buf.Bytes(), zeroBlock) { t.Fatalf("tarSum did not write the correct number of zeroed bytes: %d", n) @@ -246,16 +246,16 @@ func TestEmptyTar(t *testing.T) { // Test with gzip. ts, err = emptyTarSum(true) - require.NoError(t, err) + assert.NilError(t, err) buf.Reset() _, err = io.Copy(buf, ts) - require.NoError(t, err) + assert.NilError(t, err) bufgz := new(bytes.Buffer) gz := gzip.NewWriter(bufgz) n, err = io.Copy(gz, bytes.NewBuffer(zeroBlock)) - require.NoError(t, err) + assert.NilError(t, err) gz.Close() gzBytes := bufgz.Bytes() @@ -275,7 +275,7 @@ func TestEmptyTar(t *testing.T) { } resultSum = ts.Sum(nil) - assert.Equal(t, expectedSum, resultSum) + assert.Check(t, is.Equal(expectedSum, resultSum)) } var ( diff --git a/components/engine/pkg/term/ascii_test.go b/components/engine/pkg/term/ascii_test.go index e426de35b46..321d1b87de3 100644 --- a/components/engine/pkg/term/ascii_test.go +++ b/components/engine/pkg/term/ascii_test.go @@ -3,23 +3,23 @@ package term // import "github.com/docker/docker/pkg/term" import ( "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestToBytes(t *testing.T) { codes, err := ToBytes("ctrl-a,a") - require.NoError(t, err) - assert.Equal(t, []byte{1, 97}, codes) + assert.NilError(t, err) + assert.Check(t, is.DeepEqual([]byte{1, 97}, codes)) _, err = ToBytes("shift-z") - assert.Error(t, err) + assert.Check(t, is.ErrorContains(err, "")) codes, err = ToBytes("ctrl-@,ctrl-[,~,ctrl-o") - require.NoError(t, err) - assert.Equal(t, []byte{0, 27, 126, 15}, codes) + assert.NilError(t, err) + assert.Check(t, is.DeepEqual([]byte{0, 27, 126, 15}, codes)) codes, err = ToBytes("DEL,+") - require.NoError(t, err) - assert.Equal(t, []byte{127, 43}, codes) + assert.NilError(t, err) + assert.Check(t, is.DeepEqual([]byte{127, 43}, codes)) } diff --git a/components/engine/pkg/term/proxy_test.go b/components/engine/pkg/term/proxy_test.go index 01be1d55be0..9a53e2bc715 100644 --- a/components/engine/pkg/term/proxy_test.go +++ b/components/engine/pkg/term/proxy_test.go @@ -5,8 +5,8 @@ import ( "fmt" "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestEscapeProxyRead(t *testing.T) { @@ -15,75 +15,75 @@ func TestEscapeProxyRead(t *testing.T) { reader := NewEscapeProxy(bytes.NewReader(keys), escapeKeys) buf := make([]byte, len(keys)) nr, err := reader.Read(buf) - require.NoError(t, err) - require.EqualValues(t, nr, len(keys), fmt.Sprintf("nr %d should be equal to the number of %d", nr, len(keys))) - require.Equal(t, keys, buf, "keys & the read buffer should be equal") + assert.NilError(t, err) + assert.Equal(t, nr, len(keys), fmt.Sprintf("nr %d should be equal to the number of %d", nr, len(keys))) + assert.Assert(t, is.DeepEqual(keys, buf), "keys & the read buffer should be equal") keys, _ = ToBytes("") reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) buf = make([]byte, len(keys)) nr, err = reader.Read(buf) - require.Error(t, err, "Should throw error when no keys are to read") - require.EqualValues(t, nr, 0, "nr should be zero") - assert.Len(t, keys, 0) - assert.Len(t, buf, 0) + assert.Assert(t, is.ErrorContains(err, ""), "Should throw error when no keys are to read") + assert.Equal(t, nr, 0, "nr should be zero") + assert.Check(t, is.Len(keys, 0)) + assert.Check(t, is.Len(buf, 0)) escapeKeys, _ = ToBytes("ctrl-x,ctrl-@") keys, _ = ToBytes("DEL") reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) buf = make([]byte, len(keys)) nr, err = reader.Read(buf) - require.NoError(t, err) - require.EqualValues(t, nr, 1, fmt.Sprintf("nr %d should be equal to the number of 1", nr)) - require.Equal(t, keys, buf, "keys & the read buffer should be equal") + assert.NilError(t, err) + assert.Equal(t, nr, 1, fmt.Sprintf("nr %d should be equal to the number of 1", nr)) + assert.Assert(t, is.DeepEqual(keys, buf), "keys & the read buffer should be equal") escapeKeys, _ = ToBytes("ctrl-c") keys, _ = ToBytes("ctrl-c") reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) buf = make([]byte, len(keys)) nr, err = reader.Read(buf) - require.EqualError(t, err, "read escape sequence") - require.EqualValues(t, nr, 0, "nr should be equal to 0") - require.Equal(t, keys, buf, "keys & the read buffer should be equal") + assert.Error(t, err, "read escape sequence") + assert.Equal(t, nr, 0, "nr should be equal to 0") + assert.Assert(t, is.DeepEqual(keys, buf), "keys & the read buffer should be equal") escapeKeys, _ = ToBytes("ctrl-c,ctrl-z") keys, _ = ToBytes("ctrl-c,ctrl-z") reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) buf = make([]byte, 1) nr, err = reader.Read(buf) - require.NoError(t, err) - require.EqualValues(t, nr, 0, "nr should be equal to 0") - require.Equal(t, keys[0:1], buf, "keys & the read buffer should be equal") + assert.NilError(t, err) + assert.Equal(t, nr, 0, "nr should be equal to 0") + assert.Assert(t, is.DeepEqual(keys[0:1], buf), "keys & the read buffer should be equal") nr, err = reader.Read(buf) - require.EqualError(t, err, "read escape sequence") - require.EqualValues(t, nr, 0, "nr should be equal to 0") - require.Equal(t, keys[1:], buf, "keys & the read buffer should be equal") + assert.Error(t, err, "read escape sequence") + assert.Equal(t, nr, 0, "nr should be equal to 0") + assert.Assert(t, is.DeepEqual(keys[1:], buf), "keys & the read buffer should be equal") escapeKeys, _ = ToBytes("ctrl-c,ctrl-z") keys, _ = ToBytes("ctrl-c,DEL,+") reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) buf = make([]byte, 1) nr, err = reader.Read(buf) - require.NoError(t, err) - require.EqualValues(t, nr, 0, "nr should be equal to 0") - require.Equal(t, keys[0:1], buf, "keys & the read buffer should be equal") + assert.NilError(t, err) + assert.Equal(t, nr, 0, "nr should be equal to 0") + assert.Assert(t, is.DeepEqual(keys[0:1], buf), "keys & the read buffer should be equal") buf = make([]byte, len(keys)) nr, err = reader.Read(buf) - require.NoError(t, err) - require.EqualValues(t, nr, len(keys), fmt.Sprintf("nr should be equal to %d", len(keys))) - require.Equal(t, keys, buf, "keys & the read buffer should be equal") + assert.NilError(t, err) + assert.Equal(t, nr, len(keys), fmt.Sprintf("nr should be equal to %d", len(keys))) + assert.Assert(t, is.DeepEqual(keys, buf), "keys & the read buffer should be equal") escapeKeys, _ = ToBytes("ctrl-c,ctrl-z") keys, _ = ToBytes("ctrl-c,DEL") reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) buf = make([]byte, 1) nr, err = reader.Read(buf) - require.NoError(t, err) - require.EqualValues(t, nr, 0, "nr should be equal to 0") - require.Equal(t, keys[0:1], buf, "keys & the read buffer should be equal") + assert.NilError(t, err) + assert.Equal(t, nr, 0, "nr should be equal to 0") + assert.Assert(t, is.DeepEqual(keys[0:1], buf), "keys & the read buffer should be equal") buf = make([]byte, len(keys)) nr, err = reader.Read(buf) - require.NoError(t, err) - require.EqualValues(t, nr, len(keys), fmt.Sprintf("nr should be equal to %d", len(keys))) - require.Equal(t, keys, buf, "keys & the read buffer should be equal") + assert.NilError(t, err) + assert.Equal(t, nr, len(keys), fmt.Sprintf("nr should be equal to %d", len(keys))) + assert.Assert(t, is.DeepEqual(keys, buf), "keys & the read buffer should be equal") } diff --git a/components/engine/pkg/term/term_linux_test.go b/components/engine/pkg/term/term_linux_test.go index 6e42d3edd71..98d2b1a3f27 100644 --- a/components/engine/pkg/term/term_linux_test.go +++ b/components/engine/pkg/term/term_linux_test.go @@ -7,7 +7,7 @@ import ( "os" "testing" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) // RequiresRoot skips tests that require root, unless the test.root flag has @@ -31,85 +31,85 @@ func newTempFile() (*os.File, error) { func TestGetWinsize(t *testing.T) { tty, err := newTtyForTest(t) defer tty.Close() - require.NoError(t, err) + assert.NilError(t, err) winSize, err := GetWinsize(tty.Fd()) - require.NoError(t, err) - require.NotNil(t, winSize) - require.NotNil(t, winSize.Height) - require.NotNil(t, winSize.Width) + assert.NilError(t, err) + assert.Assert(t, winSize != nil) + assert.Assert(t, winSize.Height != nil) + assert.Assert(t, winSize.Width != nil) newSize := Winsize{Width: 200, Height: 200, x: winSize.x, y: winSize.y} err = SetWinsize(tty.Fd(), &newSize) - require.NoError(t, err) + assert.NilError(t, err) winSize, err = GetWinsize(tty.Fd()) - require.NoError(t, err) - require.Equal(t, *winSize, newSize) + assert.NilError(t, err) + assert.DeepEqual(t, *winSize, newSize) } func TestSetWinsize(t *testing.T) { tty, err := newTtyForTest(t) defer tty.Close() - require.NoError(t, err) + assert.NilError(t, err) winSize, err := GetWinsize(tty.Fd()) - require.NoError(t, err) - require.NotNil(t, winSize) + assert.NilError(t, err) + assert.Assert(t, winSize != nil) newSize := Winsize{Width: 200, Height: 200, x: winSize.x, y: winSize.y} err = SetWinsize(tty.Fd(), &newSize) - require.NoError(t, err) + assert.NilError(t, err) winSize, err = GetWinsize(tty.Fd()) - require.NoError(t, err) - require.Equal(t, *winSize, newSize) + assert.NilError(t, err) + assert.DeepEqual(t, *winSize, newSize) } func TestGetFdInfo(t *testing.T) { tty, err := newTtyForTest(t) defer tty.Close() - require.NoError(t, err) + assert.NilError(t, err) inFd, isTerminal := GetFdInfo(tty) - require.Equal(t, inFd, tty.Fd()) - require.Equal(t, isTerminal, true) + assert.Equal(t, inFd, tty.Fd()) + assert.Equal(t, isTerminal, true) tmpFile, err := newTempFile() - require.NoError(t, err) + assert.NilError(t, err) defer tmpFile.Close() inFd, isTerminal = GetFdInfo(tmpFile) - require.Equal(t, inFd, tmpFile.Fd()) - require.Equal(t, isTerminal, false) + assert.Equal(t, inFd, tmpFile.Fd()) + assert.Equal(t, isTerminal, false) } func TestIsTerminal(t *testing.T) { tty, err := newTtyForTest(t) defer tty.Close() - require.NoError(t, err) + assert.NilError(t, err) isTerminal := IsTerminal(tty.Fd()) - require.Equal(t, isTerminal, true) + assert.Equal(t, isTerminal, true) tmpFile, err := newTempFile() - require.NoError(t, err) + assert.NilError(t, err) defer tmpFile.Close() isTerminal = IsTerminal(tmpFile.Fd()) - require.Equal(t, isTerminal, false) + assert.Equal(t, isTerminal, false) } func TestSaveState(t *testing.T) { tty, err := newTtyForTest(t) defer tty.Close() - require.NoError(t, err) + assert.NilError(t, err) state, err := SaveState(tty.Fd()) - require.NoError(t, err) - require.NotNil(t, state) + assert.NilError(t, err) + assert.Assert(t, state != nil) tty, err = newTtyForTest(t) - require.NoError(t, err) + assert.NilError(t, err) defer tty.Close() err = RestoreTerminal(tty.Fd(), state) - require.NoError(t, err) + assert.NilError(t, err) } func TestDisableEcho(t *testing.T) { tty, err := newTtyForTest(t) defer tty.Close() - require.NoError(t, err) + assert.NilError(t, err) state, err := SetRawTerminal(tty.Fd()) defer RestoreTerminal(tty.Fd(), state) - require.NoError(t, err) - require.NotNil(t, state) + assert.NilError(t, err) + assert.Assert(t, state != nil) err = DisableEcho(tty.Fd(), state) - require.NoError(t, err) + assert.NilError(t, err) } diff --git a/components/engine/reference/store_test.go b/components/engine/reference/store_test.go index e423f5db2e6..24c0597a3ec 100644 --- a/components/engine/reference/store_test.go +++ b/components/engine/reference/store_test.go @@ -9,9 +9,9 @@ import ( "testing" "github.com/docker/distribution/reference" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" digest "github.com/opencontainers/go-digest" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) var ( @@ -64,10 +64,10 @@ func TestLoad(t *testing.T) { func TestSave(t *testing.T) { jsonFile, err := ioutil.TempFile("", "tag-store-test") - require.NoError(t, err) + assert.NilError(t, err) _, err = jsonFile.Write([]byte(`{}`)) - require.NoError(t, err) + assert.NilError(t, err) jsonFile.Close() defer os.RemoveAll(jsonFile.Name()) @@ -328,23 +328,23 @@ func TestAddDeleteGet(t *testing.T) { func TestInvalidTags(t *testing.T) { tmpDir, err := ioutil.TempDir("", "tag-store-test") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(tmpDir) store, err := NewReferenceStore(filepath.Join(tmpDir, "repositories.json")) - require.NoError(t, err) + assert.NilError(t, err) id := digest.Digest("sha256:470022b8af682154f57a2163d030eb369549549cba00edc69e1b99b46bb924d6") // sha256 as repo name ref, err := reference.ParseNormalizedNamed("sha256:abc") - require.NoError(t, err) + assert.NilError(t, err) err = store.AddTag(ref, id, true) - assert.Error(t, err) + assert.Check(t, is.ErrorContains(err, "")) // setting digest as a tag ref, err = reference.ParseNormalizedNamed("registry@sha256:367eb40fd0330a7e464777121e39d2f5b3e8e23a1e159342e53ab05c9e4d94e6") - require.NoError(t, err) + assert.NilError(t, err) err = store.AddTag(ref, id, true) - assert.Error(t, err) + assert.Check(t, is.ErrorContains(err, "")) } diff --git a/components/engine/registry/config_test.go b/components/engine/registry/config_test.go index 61b1c26d354..4df9cdb9480 100644 --- a/components/engine/registry/config_test.go +++ b/components/engine/registry/config_test.go @@ -6,7 +6,8 @@ import ( "strings" "testing" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestLoadAllowNondistributableArtifacts(t *testing.T) { @@ -311,9 +312,9 @@ func TestNewServiceConfig(t *testing.T) { for _, testCase := range testCases { _, err := newServiceConfig(testCase.opts) if testCase.errStr != "" { - assert.EqualError(t, err, testCase.errStr) + assert.Check(t, is.Error(err, testCase.errStr)) } else { - assert.Nil(t, err) + assert.Check(t, err) } } } @@ -347,8 +348,8 @@ func TestValidateIndexName(t *testing.T) { for _, testCase := range valid { result, err := ValidateIndexName(testCase.index) - if assert.NoError(t, err) { - assert.Equal(t, testCase.expect, result) + if assert.Check(t, err) { + assert.Check(t, is.Equal(testCase.expect, result)) } } @@ -375,6 +376,6 @@ func TestValidateIndexNameWithError(t *testing.T) { } for _, testCase := range invalid { _, err := ValidateIndexName(testCase.index) - assert.EqualError(t, err, testCase.err) + assert.Check(t, is.Error(err, testCase.err)) } } diff --git a/components/engine/registry/registry_test.go b/components/engine/registry/registry_test.go index 63753014693..b4420d558c2 100644 --- a/components/engine/registry/registry_test.go +++ b/components/engine/registry/registry_test.go @@ -12,7 +12,7 @@ import ( "github.com/docker/distribution/registry/client/transport" "github.com/docker/docker/api/types" registrytypes "github.com/docker/docker/api/types/registry" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" ) var ( @@ -757,12 +757,12 @@ func TestSearchRepositories(t *testing.T) { func TestTrustedLocation(t *testing.T) { for _, url := range []string{"http://example.com", "https://example.com:7777", "http://docker.io", "http://test.docker.com", "https://fakedocker.com"} { req, _ := http.NewRequest("GET", url, nil) - assert.False(t, trustedLocation(req)) + assert.Check(t, !trustedLocation(req)) } for _, url := range []string{"https://docker.io", "https://test.docker.com:80"} { req, _ := http.NewRequest("GET", url, nil) - assert.True(t, trustedLocation(req)) + assert.Check(t, trustedLocation(req)) } } diff --git a/components/engine/registry/resumable/resumablerequestreader_test.go b/components/engine/registry/resumable/resumablerequestreader_test.go index 9a08e3416e5..bd3d55885fb 100644 --- a/components/engine/registry/resumable/resumablerequestreader_test.go +++ b/components/engine/registry/resumable/resumablerequestreader_test.go @@ -10,8 +10,8 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestResumableRequestHeaderSimpleErrors(t *testing.T) { @@ -24,11 +24,11 @@ func TestResumableRequestHeaderSimpleErrors(t *testing.T) { var req *http.Request req, err := http.NewRequest("GET", ts.URL, nil) - require.NoError(t, err) + assert.NilError(t, err) resreq := &requestReader{} _, err = resreq.Read([]byte{}) - assert.EqualError(t, err, "client and request can't be nil") + assert.Check(t, is.Error(err, "client and request can't be nil")) resreq = &requestReader{ client: client, @@ -36,7 +36,7 @@ func TestResumableRequestHeaderSimpleErrors(t *testing.T) { totalSize: -1, } _, err = resreq.Read([]byte{}) - assert.EqualError(t, err, "failed to auto detect content length") + assert.Check(t, is.Error(err, "failed to auto detect content length")) } // Not too much failures, bails out after some wait @@ -45,7 +45,7 @@ func TestResumableRequestHeaderNotTooMuchFailures(t *testing.T) { var badReq *http.Request badReq, err := http.NewRequest("GET", "I'm not an url", nil) - require.NoError(t, err) + assert.NilError(t, err) resreq := &requestReader{ client: client, @@ -55,8 +55,8 @@ func TestResumableRequestHeaderNotTooMuchFailures(t *testing.T) { waitDuration: 10 * time.Millisecond, } read, err := resreq.Read([]byte{}) - require.NoError(t, err) - assert.Equal(t, 0, read) + assert.NilError(t, err) + assert.Check(t, is.Equal(0, read)) } // Too much failures, returns the error @@ -65,7 +65,7 @@ func TestResumableRequestHeaderTooMuchFailures(t *testing.T) { var badReq *http.Request badReq, err := http.NewRequest("GET", "I'm not an url", nil) - require.NoError(t, err) + assert.NilError(t, err) resreq := &requestReader{ client: client, @@ -77,8 +77,8 @@ func TestResumableRequestHeaderTooMuchFailures(t *testing.T) { expectedError := `Get I%27m%20not%20an%20url: unsupported protocol scheme ""` read, err := resreq.Read([]byte{}) - assert.EqualError(t, err, expectedError) - assert.Equal(t, 0, read) + assert.Check(t, is.Error(err, expectedError)) + assert.Check(t, is.Equal(0, read)) } type errorReaderCloser struct{} @@ -93,7 +93,7 @@ func (errorReaderCloser) Read(p []byte) (n int, err error) { func TestResumableRequestReaderWithReadError(t *testing.T) { var req *http.Request req, err := http.NewRequest("GET", "", nil) - require.NoError(t, err) + assert.NilError(t, err) client := &http.Client{} @@ -116,15 +116,15 @@ func TestResumableRequestReaderWithReadError(t *testing.T) { buf := make([]byte, 1) read, err := resreq.Read(buf) - require.NoError(t, err) + assert.NilError(t, err) - assert.Equal(t, 0, read) + assert.Check(t, is.Equal(0, read)) } func TestResumableRequestReaderWithEOFWith416Response(t *testing.T) { var req *http.Request req, err := http.NewRequest("GET", "", nil) - require.NoError(t, err) + assert.NilError(t, err) client := &http.Client{} @@ -147,7 +147,7 @@ func TestResumableRequestReaderWithEOFWith416Response(t *testing.T) { buf := make([]byte, 1) _, err = resreq.Read(buf) - assert.EqualError(t, err, io.EOF.Error()) + assert.Check(t, is.Error(err, io.EOF.Error())) } func TestResumableRequestReaderWithServerDoesntSupportByteRanges(t *testing.T) { @@ -160,7 +160,7 @@ func TestResumableRequestReaderWithServerDoesntSupportByteRanges(t *testing.T) { var req *http.Request req, err := http.NewRequest("GET", ts.URL, nil) - require.NoError(t, err) + assert.NilError(t, err) client := &http.Client{} @@ -173,7 +173,7 @@ func TestResumableRequestReaderWithServerDoesntSupportByteRanges(t *testing.T) { buf := make([]byte, 2) _, err = resreq.Read(buf) - assert.EqualError(t, err, "the server doesn't support byte ranges") + assert.Check(t, is.Error(err, "the server doesn't support byte ranges")) } func TestResumableRequestReaderWithZeroTotalSize(t *testing.T) { @@ -186,7 +186,7 @@ func TestResumableRequestReaderWithZeroTotalSize(t *testing.T) { var req *http.Request req, err := http.NewRequest("GET", ts.URL, nil) - require.NoError(t, err) + assert.NilError(t, err) client := &http.Client{} retries := uint32(5) @@ -195,10 +195,10 @@ func TestResumableRequestReaderWithZeroTotalSize(t *testing.T) { defer resreq.Close() data, err := ioutil.ReadAll(resreq) - require.NoError(t, err) + assert.NilError(t, err) resstr := strings.TrimSuffix(string(data), "\n") - assert.Equal(t, srvtxt, resstr) + assert.Check(t, is.Equal(srvtxt, resstr)) } func TestResumableRequestReader(t *testing.T) { @@ -211,7 +211,7 @@ func TestResumableRequestReader(t *testing.T) { var req *http.Request req, err := http.NewRequest("GET", ts.URL, nil) - require.NoError(t, err) + assert.NilError(t, err) client := &http.Client{} retries := uint32(5) @@ -221,10 +221,10 @@ func TestResumableRequestReader(t *testing.T) { defer resreq.Close() data, err := ioutil.ReadAll(resreq) - require.NoError(t, err) + assert.NilError(t, err) resstr := strings.TrimSuffix(string(data), "\n") - assert.Equal(t, srvtxt, resstr) + assert.Check(t, is.Equal(srvtxt, resstr)) } func TestResumableRequestReaderWithInitialResponse(t *testing.T) { @@ -237,21 +237,21 @@ func TestResumableRequestReaderWithInitialResponse(t *testing.T) { var req *http.Request req, err := http.NewRequest("GET", ts.URL, nil) - require.NoError(t, err) + assert.NilError(t, err) client := &http.Client{} retries := uint32(5) imgSize := int64(len(srvtxt)) res, err := client.Do(req) - require.NoError(t, err) + assert.NilError(t, err) resreq := NewRequestReaderWithInitialResponse(client, req, retries, imgSize, res) defer resreq.Close() data, err := ioutil.ReadAll(resreq) - require.NoError(t, err) + assert.NilError(t, err) resstr := strings.TrimSuffix(string(data), "\n") - assert.Equal(t, srvtxt, resstr) + assert.Check(t, is.Equal(srvtxt, resstr)) } diff --git a/components/engine/runconfig/config_test.go b/components/engine/runconfig/config_test.go index 63619fe53f3..58e3a9f7884 100644 --- a/components/engine/runconfig/config_test.go +++ b/components/engine/runconfig/config_test.go @@ -12,8 +12,8 @@ import ( "github.com/docker/docker/api/types/container" networktypes "github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/strslice" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) type f struct { @@ -149,21 +149,21 @@ func runDecodeContainerConfigTestCase(testcase decodeConfigTestcase) func(t *tes raw := marshal(t, testcase.wrapper, testcase.doc) config, hostConfig, _, err := decodeContainerConfig(bytes.NewReader(raw)) if testcase.expectedErr != "" { - if !assert.Error(t, err) { + if !assert.Check(t, is.ErrorContains(err, "")) { return } - assert.Contains(t, err.Error(), testcase.expectedErr) + assert.Check(t, is.Contains(err.Error(), testcase.expectedErr)) return } - assert.NoError(t, err) - assert.Equal(t, testcase.expectedConfig, config) - assert.Equal(t, testcase.expectedHostConfig, hostConfig) + assert.Check(t, err) + assert.Check(t, is.DeepEqual(testcase.expectedConfig, config)) + assert.Check(t, is.DeepEqual(testcase.expectedHostConfig, hostConfig)) } } func marshal(t *testing.T, w ContainerConfigWrapper, doc string) []byte { b, err := json.Marshal(w) - require.NoError(t, err, "%s: failed to encode config wrapper", doc) + assert.NilError(t, err, "%s: failed to encode config wrapper", doc) return b } diff --git a/components/engine/runconfig/hostconfig_test.go b/components/engine/runconfig/hostconfig_test.go index 48d902d4d72..d2482fbe7b8 100644 --- a/components/engine/runconfig/hostconfig_test.go +++ b/components/engine/runconfig/hostconfig_test.go @@ -10,7 +10,8 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/pkg/sysinfo" - "github.com/stretchr/testify/assert" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) // TODO Windows: This will need addressing for a Windows daemon. @@ -83,12 +84,12 @@ func TestIpcModeTest(t *testing.T) { } for ipcMode, state := range ipcModes { - assert.Equal(t, state.private, ipcMode.IsPrivate(), "IpcMode.IsPrivate() parsing failed for %q", ipcMode) - assert.Equal(t, state.host, ipcMode.IsHost(), "IpcMode.IsHost() parsing failed for %q", ipcMode) - assert.Equal(t, state.container, ipcMode.IsContainer(), "IpcMode.IsContainer() parsing failed for %q", ipcMode) - assert.Equal(t, state.shareable, ipcMode.IsShareable(), "IpcMode.IsShareable() parsing failed for %q", ipcMode) - assert.Equal(t, state.valid, ipcMode.Valid(), "IpcMode.Valid() parsing failed for %q", ipcMode) - assert.Equal(t, state.ctrName, ipcMode.Container(), "IpcMode.Container() parsing failed for %q", ipcMode) + assert.Check(t, is.Equal(state.private, ipcMode.IsPrivate()), "IpcMode.IsPrivate() parsing failed for %q", ipcMode) + assert.Check(t, is.Equal(state.host, ipcMode.IsHost()), "IpcMode.IsHost() parsing failed for %q", ipcMode) + assert.Check(t, is.Equal(state.container, ipcMode.IsContainer()), "IpcMode.IsContainer() parsing failed for %q", ipcMode) + assert.Check(t, is.Equal(state.shareable, ipcMode.IsShareable()), "IpcMode.IsShareable() parsing failed for %q", ipcMode) + assert.Check(t, is.Equal(state.valid, ipcMode.Valid()), "IpcMode.Valid() parsing failed for %q", ipcMode) + assert.Check(t, is.Equal(state.ctrName, ipcMode.Container()), "IpcMode.Container() parsing failed for %q", ipcMode) } } @@ -195,7 +196,7 @@ func TestDecodeHostConfig(t *testing.T) { t.Fatal(fmt.Errorf("Error parsing %s: %v", f, err)) } - assert.False(t, c.Privileged) + assert.Check(t, !c.Privileged) if l := len(c.Binds); l != 1 { t.Fatalf("Expected 1 bind, found %d\n", l) diff --git a/components/engine/volume/store/db_test.go b/components/engine/volume/store/db_test.go index 9c45cd13baf..0a2727e7490 100644 --- a/components/engine/volume/store/db_test.go +++ b/components/engine/volume/store/db_test.go @@ -8,33 +8,34 @@ import ( "time" "github.com/boltdb/bolt" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestSetGetMeta(t *testing.T) { t.Parallel() dir, err := ioutil.TempDir("", "test-set-get") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(dir) db, err := bolt.Open(filepath.Join(dir, "db"), 0600, &bolt.Options{Timeout: 1 * time.Second}) - require.NoError(t, err) + assert.NilError(t, err) store := &VolumeStore{db: db} _, err = store.getMeta("test") - require.Error(t, err) + assert.Assert(t, is.ErrorContains(err, "")) err = db.Update(func(tx *bolt.Tx) error { _, err := tx.CreateBucket(volumeBucketName) return err }) - require.NoError(t, err) + assert.NilError(t, err) meta, err := store.getMeta("test") - require.NoError(t, err) - require.Equal(t, volumeMetadata{}, meta) + assert.NilError(t, err) + assert.DeepEqual(t, volumeMetadata{}, meta) testMeta := volumeMetadata{ Name: "test", @@ -43,9 +44,9 @@ func TestSetGetMeta(t *testing.T) { Options: map[string]string{"foo": "bar"}, } err = store.setMeta("test", testMeta) - require.NoError(t, err) + assert.NilError(t, err) meta, err = store.getMeta("test") - require.NoError(t, err) - require.Equal(t, testMeta, meta) + assert.NilError(t, err) + assert.DeepEqual(t, testMeta, meta) } diff --git a/components/engine/volume/store/restore_test.go b/components/engine/volume/store/restore_test.go index 83efd36b63e..680735a384f 100644 --- a/components/engine/volume/store/restore_test.go +++ b/components/engine/volume/store/restore_test.go @@ -8,14 +8,14 @@ import ( "github.com/docker/docker/volume" volumedrivers "github.com/docker/docker/volume/drivers" volumetestutils "github.com/docker/docker/volume/testutils" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" ) func TestRestore(t *testing.T) { t.Parallel() dir, err := ioutil.TempDir("", "test-restore") - require.NoError(t, err) + assert.NilError(t, err) defer os.RemoveAll(dir) driverName := "test-restore" @@ -23,33 +23,33 @@ func TestRestore(t *testing.T) { defer volumedrivers.Unregister("test-restore") s, err := New(dir) - require.NoError(t, err) + assert.NilError(t, err) defer s.Shutdown() _, err = s.Create("test1", driverName, nil, nil) - require.NoError(t, err) + assert.NilError(t, err) testLabels := map[string]string{"a": "1"} testOpts := map[string]string{"foo": "bar"} _, err = s.Create("test2", driverName, testOpts, testLabels) - require.NoError(t, err) + assert.NilError(t, err) s.Shutdown() s, err = New(dir) - require.NoError(t, err) + assert.NilError(t, err) v, err := s.Get("test1") - require.NoError(t, err) + assert.NilError(t, err) dv := v.(volume.DetailedVolume) var nilMap map[string]string - require.Equal(t, nilMap, dv.Options()) - require.Equal(t, nilMap, dv.Labels()) + assert.DeepEqual(t, nilMap, dv.Options()) + assert.DeepEqual(t, nilMap, dv.Labels()) v, err = s.Get("test2") - require.NoError(t, err) + assert.NilError(t, err) dv = v.(volume.DetailedVolume) - require.Equal(t, testOpts, dv.Options()) - require.Equal(t, testLabels, dv.Labels()) + assert.DeepEqual(t, testOpts, dv.Options()) + assert.DeepEqual(t, testLabels, dv.Labels()) } diff --git a/components/engine/volume/store/store_test.go b/components/engine/volume/store/store_test.go index e53c728dd0a..c6d31364ac0 100644 --- a/components/engine/volume/store/store_test.go +++ b/components/engine/volume/store/store_test.go @@ -12,8 +12,8 @@ import ( "github.com/docker/docker/volume" "github.com/docker/docker/volume/drivers" volumetestutils "github.com/docker/docker/volume/testutils" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestCreate(t *testing.T) { @@ -332,15 +332,15 @@ func TestRefDerefRemove(t *testing.T) { defer cleanup(t) v, err := s.CreateWithRef("test", driverName, "test-ref", nil, nil) - require.NoError(t, err) + assert.NilError(t, err) err = s.Remove(v) - require.Error(t, err) - require.Equal(t, errVolumeInUse, err.(*OpErr).Err) + assert.Assert(t, is.ErrorContains(err, "")) + assert.Equal(t, errVolumeInUse, err.(*OpErr).Err) s.Dereference(v, "test-ref") err = s.Remove(v) - require.NoError(t, err) + assert.NilError(t, err) } func TestGet(t *testing.T) { @@ -351,21 +351,21 @@ func TestGet(t *testing.T) { defer cleanup(t) _, err := s.Get("not-exist") - require.Error(t, err) - require.Equal(t, errNoSuchVolume, err.(*OpErr).Err) + assert.Assert(t, is.ErrorContains(err, "")) + assert.Equal(t, errNoSuchVolume, err.(*OpErr).Err) v1, err := s.Create("test", driverName, nil, map[string]string{"a": "1"}) - require.NoError(t, err) + assert.NilError(t, err) v2, err := s.Get("test") - require.NoError(t, err) - require.Equal(t, v1, v2) + assert.NilError(t, err) + assert.DeepEqual(t, v1, v2) dv := v2.(volume.DetailedVolume) - require.Equal(t, "1", dv.Labels()["a"]) + assert.Equal(t, "1", dv.Labels()["a"]) err = s.Remove(v1) - require.NoError(t, err) + assert.NilError(t, err) } func TestGetWithRef(t *testing.T) { @@ -376,22 +376,22 @@ func TestGetWithRef(t *testing.T) { defer cleanup(t) _, err := s.GetWithRef("not-exist", driverName, "test-ref") - require.Error(t, err) + assert.Assert(t, is.ErrorContains(err, "")) v1, err := s.Create("test", driverName, nil, map[string]string{"a": "1"}) - require.NoError(t, err) + assert.NilError(t, err) v2, err := s.GetWithRef("test", driverName, "test-ref") - require.NoError(t, err) - require.Equal(t, v1, v2) + assert.NilError(t, err) + assert.DeepEqual(t, v1, v2) err = s.Remove(v2) - require.Error(t, err) - require.Equal(t, errVolumeInUse, err.(*OpErr).Err) + assert.Assert(t, is.ErrorContains(err, "")) + assert.Equal(t, errVolumeInUse, err.(*OpErr).Err) s.Dereference(v2, "test-ref") err = s.Remove(v2) - require.NoError(t, err) + assert.NilError(t, err) } func setupTest(t *testing.T, name string) (*VolumeStore, func(*testing.T)) { @@ -409,15 +409,15 @@ func newTestStore(t *testing.T) (*VolumeStore, func(*testing.T)) { t.Helper() dir, err := ioutil.TempDir("", "store-root") - require.NoError(t, err) + assert.NilError(t, err) cleanup := func(t *testing.T) { err := os.RemoveAll(dir) - assert.NoError(t, err) + assert.Check(t, err) } s, err := New(dir) - assert.NoError(t, err) + assert.Check(t, err) return s, func(t *testing.T) { s.Shutdown() cleanup(t) From cb1f6242ed4dc9d148ecc6b9400d4573c03741a9 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Fri, 22 Dec 2017 16:30:49 -0500 Subject: [PATCH 08/36] Post migration assertion fixes Signed-off-by: Daniel Nephin (cherry picked from commit c9e52bd0da0461e605a3678b85702f83081504a7) Signed-off-by: Sebastiaan van Stijn --- .../builder/dockerfile/buildargs_test.go | 7 +- .../dockerfile/parser/line_parsers_test.go | 10 +- .../remotecontext/git/gitutils_test.go | 21 ++-- components/engine/client/client_test.go | 15 ++- .../graphdriver/graphtest/graphtest_unix.go | 2 +- .../graphdriver/quota/projectquota_test.go | 2 +- .../engine/daemon/logger/adapter_test.go | 4 +- .../jsonfilelog/jsonlog/jsonlogbytes_test.go | 14 ++- components/engine/image/image_test.go | 5 +- components/engine/image/store_test.go | 107 +++++++++--------- components/engine/integration-cli/cli/cli.go | 2 + .../engine/integration/build/build_test.go | 2 +- .../engine/integration/container/diff_test.go | 3 +- .../integration/network/service_test.go | 16 +-- .../integration/service/inspect_test.go | 40 +++++-- .../integration/system/info_linux_test.go | 3 - .../engine/integration/system/version_test.go | 6 +- .../engine/internal/testutil/helpers.go | 12 +- components/engine/pkg/archive/archive_test.go | 7 +- components/engine/pkg/plugins/plugin_test.go | 7 +- components/engine/pkg/term/proxy_test.go | 18 +-- components/engine/pkg/term/term_linux_test.go | 10 +- components/engine/volume/store/store_test.go | 7 +- 23 files changed, 184 insertions(+), 136 deletions(-) diff --git a/components/engine/builder/dockerfile/buildargs_test.go b/components/engine/builder/dockerfile/buildargs_test.go index 1ce841b404a..ae00e3b650d 100644 --- a/components/engine/builder/dockerfile/buildargs_test.go +++ b/components/engine/builder/dockerfile/buildargs_test.go @@ -2,6 +2,7 @@ package dockerfile // import "github.com/docker/docker/builder/dockerfile" import ( "bytes" + "strings" "testing" "github.com/gotestyourself/gotestyourself/assert" @@ -78,9 +79,9 @@ func TestWarnOnUnusedBuildArgs(t *testing.T) { buffer := new(bytes.Buffer) buildArgs.WarnOnUnusedBuildArgs(buffer) out := buffer.String() - assert.NotContains(t, out, "ThisArgIsUsed") - assert.NotContains(t, out, "HTTPS_PROXY") - assert.NotContains(t, out, "HTTP_PROXY") + assert.Assert(t, !strings.Contains(out, "ThisArgIsUsed"), out) + assert.Assert(t, !strings.Contains(out, "HTTPS_PROXY"), out) + assert.Assert(t, !strings.Contains(out, "HTTP_PROXY"), out) assert.Check(t, is.Contains(out, "ThisArgIsNotUsed")) } diff --git a/components/engine/builder/dockerfile/parser/line_parsers_test.go b/components/engine/builder/dockerfile/parser/line_parsers_test.go index 20369cad0b0..50b8d03c231 100644 --- a/components/engine/builder/dockerfile/parser/line_parsers_test.go +++ b/components/engine/builder/dockerfile/parser/line_parsers_test.go @@ -3,6 +3,7 @@ package parser // import "github.com/docker/docker/builder/dockerfile/parser" import ( "testing" + "github.com/google/go-cmp/cmp" "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" ) @@ -16,9 +17,11 @@ func TestParseNameValOldFormat(t *testing.T) { Value: "foo", Next: &Node{Value: "bar"}, } - assert.Check(t, is.DeepEqual(expected, node)) + assert.DeepEqual(t, expected, node, cmpNodeOpt) } +var cmpNodeOpt = cmp.AllowUnexported(Node{}) + func TestParseNameValNewFormat(t *testing.T) { directive := Directive{} node, err := parseNameVal("foo=bar thing=star", "LABEL", &directive) @@ -36,7 +39,7 @@ func TestParseNameValNewFormat(t *testing.T) { }, }, } - assert.Check(t, is.DeepEqual(expected, node)) + assert.DeepEqual(t, expected, node, cmpNodeOpt) } func TestNodeFromLabels(t *testing.T) { @@ -62,8 +65,7 @@ func TestNodeFromLabels(t *testing.T) { } node := NodeFromLabels(labels) - assert.Check(t, is.DeepEqual(expected, node)) - + assert.DeepEqual(t, expected, node, cmpNodeOpt) } func TestParseNameValWithoutVal(t *testing.T) { diff --git a/components/engine/builder/remotecontext/git/gitutils_test.go b/components/engine/builder/remotecontext/git/gitutils_test.go index cb2adb8c291..a46675b22b6 100644 --- a/components/engine/builder/remotecontext/git/gitutils_test.go +++ b/components/engine/builder/remotecontext/git/gitutils_test.go @@ -13,6 +13,7 @@ import ( "strings" "testing" + "github.com/google/go-cmp/cmp" "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" ) @@ -20,35 +21,31 @@ import ( func TestParseRemoteURL(t *testing.T) { dir, err := parseRemoteURL("git://github.com/user/repo.git") assert.NilError(t, err) - assert.Check(t, len(dir) != 0) - assert.Check(t, is.DeepEqual(gitRepo{"git://github.com/user/repo.git", "master", ""}, dir)) + assert.Check(t, is.DeepEqual(gitRepo{"git://github.com/user/repo.git", "master", ""}, dir, cmpGitRepoOpt)) dir, err = parseRemoteURL("git://github.com/user/repo.git#mybranch:mydir/mysubdir/") assert.NilError(t, err) - assert.Check(t, len(dir) != 0) - assert.Check(t, is.DeepEqual(gitRepo{"git://github.com/user/repo.git", "mybranch", "mydir/mysubdir/"}, dir)) + assert.Check(t, is.DeepEqual(gitRepo{"git://github.com/user/repo.git", "mybranch", "mydir/mysubdir/"}, dir, cmpGitRepoOpt)) dir, err = parseRemoteURL("https://github.com/user/repo.git") assert.NilError(t, err) - assert.Check(t, len(dir) != 0) - assert.Check(t, is.DeepEqual(gitRepo{"https://github.com/user/repo.git", "master", ""}, dir)) + assert.Check(t, is.DeepEqual(gitRepo{"https://github.com/user/repo.git", "master", ""}, dir, cmpGitRepoOpt)) dir, err = parseRemoteURL("https://github.com/user/repo.git#mybranch:mydir/mysubdir/") assert.NilError(t, err) - assert.Check(t, len(dir) != 0) - assert.Check(t, is.DeepEqual(gitRepo{"https://github.com/user/repo.git", "mybranch", "mydir/mysubdir/"}, dir)) + assert.Check(t, is.DeepEqual(gitRepo{"https://github.com/user/repo.git", "mybranch", "mydir/mysubdir/"}, dir, cmpGitRepoOpt)) dir, err = parseRemoteURL("git@github.com:user/repo.git") assert.NilError(t, err) - assert.Check(t, len(dir) != 0) - assert.Check(t, is.DeepEqual(gitRepo{"git@github.com:user/repo.git", "master", ""}, dir)) + assert.Check(t, is.DeepEqual(gitRepo{"git@github.com:user/repo.git", "master", ""}, dir, cmpGitRepoOpt)) dir, err = parseRemoteURL("git@github.com:user/repo.git#mybranch:mydir/mysubdir/") assert.NilError(t, err) - assert.Check(t, len(dir) != 0) - assert.Check(t, is.DeepEqual(gitRepo{"git@github.com:user/repo.git", "mybranch", "mydir/mysubdir/"}, dir)) + assert.Check(t, is.DeepEqual(gitRepo{"git@github.com:user/repo.git", "mybranch", "mydir/mysubdir/"}, dir, cmpGitRepoOpt)) } +var cmpGitRepoOpt = cmp.AllowUnexported(gitRepo{}) + func TestCloneArgsSmartHttp(t *testing.T) { mux := http.NewServeMux() server := httptest.NewServer(mux) diff --git a/components/engine/client/client_test.go b/components/engine/client/client_test.go index 381a561c197..b72c6ba2a1f 100644 --- a/components/engine/client/client_test.go +++ b/components/engine/client/client_test.go @@ -89,8 +89,7 @@ func TestNewEnvClient(t *testing.T) { env.PatchAll(t, c.envs) apiclient, err := NewEnvClient() if c.expectedError != "" { - assert.Check(t, is.ErrorContains(err, ""), c.doc) - assert.Check(t, is.Equal(c.expectedError, err.Error()), c.doc) + assert.Check(t, is.Error(err, c.expectedError), c.doc) } else { assert.Check(t, err, c.doc) version := apiclient.ClientVersion() @@ -100,7 +99,7 @@ func TestNewEnvClient(t *testing.T) { if c.envs["DOCKER_TLS_VERIFY"] != "" { // pedantic checking that this is handled correctly tr := apiclient.client.Transport.(*http.Transport) - assert.Check(t, tr.TLSClientConfig != nil, c.doc) + assert.Assert(t, tr.TLSClientConfig != nil, c.doc) assert.Check(t, is.Equal(tr.TLSClientConfig.InsecureSkipVerify, false), c.doc) } } @@ -298,7 +297,7 @@ func TestClientRedirect(t *testing.T) { cases := []struct { httpMethod string - expectedErr error + expectedErr *url.Error statusCode int }{ {http.MethodGet, nil, 301}, @@ -311,7 +310,13 @@ func TestClientRedirect(t *testing.T) { req, err := http.NewRequest(tc.httpMethod, "/redirectme", nil) assert.Check(t, err) resp, err := client.Do(req) - assert.Check(t, is.DeepEqual(tc.expectedErr, err)) assert.Check(t, is.Equal(tc.statusCode, resp.StatusCode)) + if tc.expectedErr == nil { + assert.Check(t, is.Nil(err)) + } else { + urlError, ok := err.(*url.Error) + assert.Assert(t, ok, "%T is not *url.Error", err) + assert.Check(t, is.Equal(*tc.expectedErr, *urlError)) + } } } diff --git a/components/engine/daemon/graphdriver/graphtest/graphtest_unix.go b/components/engine/daemon/graphdriver/graphtest/graphtest_unix.go index 5ac3979752a..1e068535f3d 100644 --- a/components/engine/daemon/graphdriver/graphtest/graphtest_unix.go +++ b/components/engine/daemon/graphdriver/graphtest/graphtest_unix.go @@ -15,7 +15,7 @@ import ( "github.com/docker/docker/daemon/graphdriver" "github.com/docker/docker/daemon/graphdriver/quota" "github.com/docker/docker/pkg/stringid" - "github.com/docker/go-units" + units "github.com/docker/go-units" "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" "golang.org/x/sys/unix" diff --git a/components/engine/daemon/graphdriver/quota/projectquota_test.go b/components/engine/daemon/graphdriver/quota/projectquota_test.go index b7debf79e23..2f1bf593deb 100644 --- a/components/engine/daemon/graphdriver/quota/projectquota_test.go +++ b/components/engine/daemon/graphdriver/quota/projectquota_test.go @@ -148,5 +148,5 @@ func testRetrieveQuota(t *testing.T, ctrl *Control, homeDir, testDir, testSubDir var q Quota assert.NilError(t, ctrl.GetQuota(testSubDir, &q)) - assert.Check(t, is.Equal(testQuotaSize, q.Size)) + assert.Check(t, is.Equal(uint64(testQuotaSize), q.Size)) } diff --git a/components/engine/daemon/logger/adapter_test.go b/components/engine/daemon/logger/adapter_test.go index 7c1db6f575e..94d14eaef11 100644 --- a/components/engine/daemon/logger/adapter_test.go +++ b/components/engine/daemon/logger/adapter_test.go @@ -121,7 +121,7 @@ func TestAdapterReadLogs(t *testing.T) { } lr, ok := l.(LogReader) - assert.Check(t, ok != nil) + assert.Check(t, ok, "Logger does not implement LogReader") lw := lr.ReadLogs(ReadConfig{}) @@ -158,7 +158,7 @@ func TestAdapterReadLogs(t *testing.T) { select { case msg, ok := <-lw.Msg: - assert.Check(t, ok != nil, "message channel unexpectedly closed") + assert.Check(t, ok, "message channel unexpectedly closed") testMessageEqual(t, &x, msg) case <-time.After(10 * time.Second): t.Fatal("timeout reading logs") diff --git a/components/engine/daemon/logger/jsonfilelog/jsonlog/jsonlogbytes_test.go b/components/engine/daemon/logger/jsonfilelog/jsonlog/jsonlogbytes_test.go index d3e56df8cc2..b3bfe6b18c8 100644 --- a/components/engine/daemon/logger/jsonfilelog/jsonlog/jsonlogbytes_test.go +++ b/components/engine/daemon/logger/jsonfilelog/jsonlog/jsonlogbytes_test.go @@ -3,6 +3,7 @@ package jsonlog // import "github.com/docker/docker/daemon/logger/jsonfilelog/js import ( "bytes" "encoding/json" + "fmt" "regexp" "testing" "time" @@ -35,7 +36,16 @@ func TestJSONLogsMarshalJSONBuf(t *testing.T) { var buf bytes.Buffer err := jsonLog.MarshalJSONBuf(&buf) assert.NilError(t, err) - assert.Regexp(t, regexp.MustCompile(expression), buf.String()) - assert.Check(t, json.Unmarshal(buf.Bytes(), &map[string]interface{}{})) + + assert.Assert(t, regexP(buf.String(), expression)) + assert.NilError(t, json.Unmarshal(buf.Bytes(), &map[string]interface{}{})) + } +} + +func regexP(value string, pattern string) func() (bool, string) { + return func() (bool, string) { + re := regexp.MustCompile(pattern) + msg := fmt.Sprintf("%q did not match pattern %q", value, pattern) + return re.MatchString(value), msg } } diff --git a/components/engine/image/image_test.go b/components/engine/image/image_test.go index 265db0167c7..dfb438b4d31 100644 --- a/components/engine/image/image_test.go +++ b/components/engine/image/image_test.go @@ -9,6 +9,7 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/layer" + "github.com/google/go-cmp/cmp" "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" ) @@ -119,6 +120,6 @@ func TestNewChildImageFromImageWithRootFS(t *testing.T) { assert.Check(t, is.Len(newImage.History, 2)) assert.Check(t, is.Equal(childConfig.Comment, newImage.History[1].Comment)) - // RootFS should be copied not mutated - assert.Check(t, parent.RootFS.DiffIDs != newImage.RootFS.DiffIDs) + assert.Check(t, !cmp.Equal(parent.RootFS.DiffIDs, newImage.RootFS.DiffIDs), + "RootFS should be copied not mutated") } diff --git a/components/engine/image/store_test.go b/components/engine/image/store_test.go index 73737656f60..c06f2b1d549 100644 --- a/components/engine/image/store_test.go +++ b/components/engine/image/store_test.go @@ -4,10 +4,9 @@ import ( "runtime" "testing" - "github.com/docker/docker/internal/testutil" "github.com/docker/docker/layer" "github.com/gotestyourself/gotestyourself/assert" - is "github.com/gotestyourself/gotestyourself/assert/cmp" + "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/opencontainers/go-digest" ) @@ -16,57 +15,57 @@ func TestRestore(t *testing.T) { defer cleanup() id1, err := fs.Set([]byte(`{"comment": "abc", "rootfs": {"type": "layers"}}`)) - assert.Check(t, err) + assert.NilError(t, err) _, err = fs.Set([]byte(`invalid`)) - assert.Check(t, err) + assert.NilError(t, err) id2, err := fs.Set([]byte(`{"comment": "def", "rootfs": {"type": "layers", "diff_ids": ["2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"]}}`)) - assert.Check(t, err) + assert.NilError(t, err) err = fs.SetMetadata(id2, "parent", []byte(id1)) - assert.Check(t, err) + assert.NilError(t, err) mlgrMap := make(map[string]LayerGetReleaser) mlgrMap[runtime.GOOS] = &mockLayerGetReleaser{} is, err := NewImageStore(fs, mlgrMap) - assert.Check(t, err) + assert.NilError(t, err) - assert.Check(t, is.Len(is.Map(), 2)) + assert.Check(t, cmp.Len(is.Map(), 2)) img1, err := is.Get(ID(id1)) - assert.Check(t, err) - assert.Check(t, is.Equal(ID(id1), img1.computedID)) - assert.Check(t, is.Equal(string(id1), img1.computedID.String())) + assert.NilError(t, err) + assert.Check(t, cmp.Equal(ID(id1), img1.computedID)) + assert.Check(t, cmp.Equal(string(id1), img1.computedID.String())) img2, err := is.Get(ID(id2)) - assert.Check(t, err) - assert.Check(t, is.Equal("abc", img1.Comment)) - assert.Check(t, is.Equal("def", img2.Comment)) + assert.NilError(t, err) + assert.Check(t, cmp.Equal("abc", img1.Comment)) + assert.Check(t, cmp.Equal("def", img2.Comment)) _, err = is.GetParent(ID(id1)) - testutil.ErrorContains(t, err, "failed to read metadata") + assert.ErrorContains(t, err, "failed to read metadata") p, err := is.GetParent(ID(id2)) - assert.Check(t, err) - assert.Check(t, is.Equal(ID(id1), p)) + assert.NilError(t, err) + assert.Check(t, cmp.Equal(ID(id1), p)) children := is.Children(ID(id1)) - assert.Check(t, is.Len(children, 1)) - assert.Check(t, is.Equal(ID(id2), children[0])) - assert.Check(t, is.Len(is.Heads(), 1)) + assert.Check(t, cmp.Len(children, 1)) + assert.Check(t, cmp.Equal(ID(id2), children[0])) + assert.Check(t, cmp.Len(is.Heads(), 1)) sid1, err := is.Search(string(id1)[:10]) - assert.Check(t, err) - assert.Check(t, is.Equal(ID(id1), sid1)) + assert.NilError(t, err) + assert.Check(t, cmp.Equal(ID(id1), sid1)) sid1, err = is.Search(digest.Digest(id1).Hex()[:6]) - assert.Check(t, err) - assert.Check(t, is.Equal(ID(id1), sid1)) + assert.NilError(t, err) + assert.Check(t, cmp.Equal(ID(id1), sid1)) invalidPattern := digest.Digest(id1).Hex()[1:6] _, err = is.Search(invalidPattern) - testutil.ErrorContains(t, err, "No such image") + assert.ErrorContains(t, err, "No such image") } func TestAddDelete(t *testing.T) { @@ -74,34 +73,34 @@ func TestAddDelete(t *testing.T) { defer cleanup() id1, err := is.Create([]byte(`{"comment": "abc", "rootfs": {"type": "layers", "diff_ids": ["2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"]}}`)) - assert.Check(t, err) - assert.Check(t, is.Equal(ID("sha256:8d25a9c45df515f9d0fe8e4a6b1c64dd3b965a84790ddbcc7954bb9bc89eb993"), id1)) + assert.NilError(t, err) + assert.Check(t, cmp.Equal(ID("sha256:8d25a9c45df515f9d0fe8e4a6b1c64dd3b965a84790ddbcc7954bb9bc89eb993"), id1)) img, err := is.Get(id1) - assert.Check(t, err) - assert.Check(t, is.Equal("abc", img.Comment)) + assert.NilError(t, err) + assert.Check(t, cmp.Equal("abc", img.Comment)) id2, err := is.Create([]byte(`{"comment": "def", "rootfs": {"type": "layers", "diff_ids": ["2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"]}}`)) - assert.Check(t, err) + assert.NilError(t, err) err = is.SetParent(id2, id1) - assert.Check(t, err) + assert.NilError(t, err) pid1, err := is.GetParent(id2) - assert.Check(t, err) - assert.Check(t, is.Equal(pid1, id1)) + assert.NilError(t, err) + assert.Check(t, cmp.Equal(pid1, id1)) _, err = is.Delete(id1) - assert.Check(t, err) + assert.NilError(t, err) _, err = is.Get(id1) - testutil.ErrorContains(t, err, "failed to get digest") + assert.ErrorContains(t, err, "failed to get digest") _, err = is.Get(id2) - assert.Check(t, err) + assert.NilError(t, err) _, err = is.GetParent(id2) - testutil.ErrorContains(t, err, "failed to read metadata") + assert.ErrorContains(t, err, "failed to read metadata") } func TestSearchAfterDelete(t *testing.T) { @@ -109,17 +108,17 @@ func TestSearchAfterDelete(t *testing.T) { defer cleanup() id, err := is.Create([]byte(`{"comment": "abc", "rootfs": {"type": "layers"}}`)) - assert.Check(t, err) + assert.NilError(t, err) id1, err := is.Search(string(id)[:15]) - assert.Check(t, err) - assert.Check(t, is.Equal(id1, id)) + assert.NilError(t, err) + assert.Check(t, cmp.Equal(id1, id)) _, err = is.Delete(id) - assert.Check(t, err) + assert.NilError(t, err) _, err = is.Search(string(id)[:15]) - testutil.ErrorContains(t, err, "No such image") + assert.ErrorContains(t, err, "No such image") } func TestParentReset(t *testing.T) { @@ -127,20 +126,20 @@ func TestParentReset(t *testing.T) { defer cleanup() id, err := is.Create([]byte(`{"comment": "abc1", "rootfs": {"type": "layers"}}`)) - assert.Check(t, err) + assert.NilError(t, err) id2, err := is.Create([]byte(`{"comment": "abc2", "rootfs": {"type": "layers"}}`)) - assert.Check(t, err) + assert.NilError(t, err) id3, err := is.Create([]byte(`{"comment": "abc3", "rootfs": {"type": "layers"}}`)) - assert.Check(t, err) + assert.NilError(t, err) assert.Check(t, is.SetParent(id, id2)) - assert.Check(t, is.Len(is.Children(id2), 1)) + assert.Check(t, cmp.Len(is.Children(id2), 1)) assert.Check(t, is.SetParent(id, id3)) - assert.Check(t, is.Len(is.Children(id2), 0)) - assert.Check(t, is.Len(is.Children(id3), 1)) + assert.Check(t, cmp.Len(is.Children(id2), 0)) + assert.Check(t, cmp.Len(is.Children(id3), 1)) } func defaultImageStore(t *testing.T) (Store, func()) { @@ -149,7 +148,7 @@ func defaultImageStore(t *testing.T) (Store, func()) { mlgrMap := make(map[string]LayerGetReleaser) mlgrMap[runtime.GOOS] = &mockLayerGetReleaser{} store, err := NewImageStore(fsBackend, mlgrMap) - assert.Check(t, err) + assert.NilError(t, err) return store, cleanup } @@ -159,17 +158,17 @@ func TestGetAndSetLastUpdated(t *testing.T) { defer cleanup() id, err := store.Create([]byte(`{"comment": "abc1", "rootfs": {"type": "layers"}}`)) - assert.Check(t, err) + assert.NilError(t, err) updated, err := store.GetLastUpdated(id) - assert.Check(t, err) - assert.Check(t, is.Equal(updated.IsZero(), true)) + assert.NilError(t, err) + assert.Check(t, cmp.Equal(updated.IsZero(), true)) assert.Check(t, store.SetLastUpdated(id)) updated, err = store.GetLastUpdated(id) - assert.Check(t, err) - assert.Check(t, is.Equal(updated.IsZero(), false)) + assert.NilError(t, err) + assert.Check(t, cmp.Equal(updated.IsZero(), false)) } type mockLayerGetReleaser struct{} diff --git a/components/engine/integration-cli/cli/cli.go b/components/engine/integration-cli/cli/cli.go index eb03b2dd811..17f3fd52caf 100644 --- a/components/engine/integration-cli/cli/cli.go +++ b/components/engine/integration-cli/cli/cli.go @@ -8,6 +8,7 @@ import ( "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/integration-cli/environment" + "github.com/gotestyourself/gotestyourself/assert" "github.com/gotestyourself/gotestyourself/icmd" "github.com/pkg/errors" ) @@ -24,6 +25,7 @@ func SetTestEnvironment(env *environment.Execution) { type CmdOperator func(*icmd.Cmd) func() type testingT interface { + assert.TestingT Fatal(args ...interface{}) Fatalf(string, ...interface{}) } diff --git a/components/engine/integration/build/build_test.go b/components/engine/integration/build/build_test.go index daede7bc331..9d396da8655 100644 --- a/components/engine/integration/build/build_test.go +++ b/components/engine/integration/build/build_test.go @@ -298,7 +298,7 @@ COPY bar /` _, err = io.Copy(out, resp.Body) resp.Body.Close() assert.NilError(t, err) - require.NotContains(t, out.String(), "Using cache") + assert.Assert(t, !strings.Contains(out.String(), "Using cache")) } // docker/for-linux#135 diff --git a/components/engine/integration/container/diff_test.go b/components/engine/integration/container/diff_test.go index 1cc63ebddef..56fb983b1d6 100644 --- a/components/engine/integration/container/diff_test.go +++ b/components/engine/integration/container/diff_test.go @@ -10,7 +10,6 @@ import ( "github.com/docker/docker/integration/internal/request" "github.com/docker/docker/pkg/archive" "github.com/gotestyourself/gotestyourself/assert" - is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/poll" ) @@ -39,5 +38,5 @@ func TestDiff(t *testing.T) { items, err := client.ContainerDiff(ctx, cID) assert.NilError(t, err) - assert.Check(t, is.DeepEqual(expected, items)) + assert.DeepEqual(t, expected, items) } diff --git a/components/engine/integration/network/service_test.go b/components/engine/integration/network/service_test.go index 87e1fe00fdf..b8470a1e855 100644 --- a/components/engine/integration/network/service_test.go +++ b/components/engine/integration/network/service_test.go @@ -46,10 +46,10 @@ func TestServiceWithPredefinedNetwork(t *testing.T) { poll.WaitOn(t, serviceRunningCount(client, serviceID, instances), pollSettings) _, _, err = client.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{}) - require.NoError(t, err) + assert.NilError(t, err) err = client.ServiceRemove(context.Background(), serviceID) - require.NoError(t, err) + assert.NilError(t, err) poll.WaitOn(t, serviceIsRemoved(client, serviceID), pollSettings) poll.WaitOn(t, noTasks(client), pollSettings) @@ -64,7 +64,7 @@ func TestServiceWithIngressNetwork(t *testing.T) { defer d.Stop(t) client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - require.NoError(t, err) + assert.NilError(t, err) pollSettings := func(config *poll.Settings) { if runtime.GOARCH == "arm64" || runtime.GOARCH == "arm" { @@ -95,7 +95,7 @@ func TestServiceWithIngressNetwork(t *testing.T) { serviceResp, err := client.ServiceCreate(context.Background(), serviceSpec, types.ServiceCreateOptions{ QueryRegistry: false, }) - require.NoError(t, err) + assert.NilError(t, err) serviceID := serviceResp.ID poll.WaitOn(t, serviceRunningCount(client, serviceID, instances), pollSettings) @@ -115,11 +115,11 @@ func TestServiceWithIngressNetwork(t *testing.T) { Verbose: true, Scope: "swarm", }) - require.NoError(t, err, "Ingress network was removed after removing service!") - require.NotZero(t, len(netInfo.Containers), "No load balancing endpoints in ingress network") - require.NotZero(t, len(netInfo.Peers), "No peers (including self) in ingress network") + assert.NilError(t, err, "Ingress network was removed after removing service!") + assert.Assert(t, len(netInfo.Containers) != 0, "No load balancing endpoints in ingress network") + assert.Assert(t, len(netInfo.Peers) != 0, "No peers (including self) in ingress network") _, ok := netInfo.Containers["ingress-sbox"] - require.True(t, ok, "ingress-sbox not present in ingress network") + assert.Assert(t, ok, "ingress-sbox not present in ingress network") } func serviceRunningCount(client client.ServiceAPIClient, serviceID string, instances uint64) func(log poll.LogT) poll.Result { diff --git a/components/engine/integration/service/inspect_test.go b/components/engine/integration/service/inspect_test.go index 3a5b99d3ac2..d4d342e6439 100644 --- a/components/engine/integration/service/inspect_test.go +++ b/components/engine/integration/service/inspect_test.go @@ -10,6 +10,7 @@ import ( swarmtypes "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" "github.com/docker/docker/integration/internal/swarm" + "github.com/google/go-cmp/cmp" "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/gotestyourself/gotestyourself/poll" @@ -18,14 +19,14 @@ import ( ) func TestInspect(t *testing.T) { - skip.IfCondition(t, testEnv.IsRemoteDaemon()) + skip.If(t, testEnv.IsRemoteDaemon()) defer setupTest(t)() d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) assert.NilError(t, err) - var before = time.Now() + var now = time.Now() var instances uint64 = 2 serviceSpec := fullSwarmServiceSpec("test-service-inspect", instances) @@ -40,11 +41,36 @@ func TestInspect(t *testing.T) { service, _, err := client.ServiceInspectWithRaw(ctx, id, types.ServiceInspectOptions{}) assert.NilError(t, err) - assert.Check(t, is.DeepEqual(serviceSpec, service.Spec)) - assert.Check(t, is.Equal(uint64(11), service.Meta.Version.Index)) - assert.Check(t, is.Equal(id, service.ID)) - assert.WithinDuration(t, before, service.CreatedAt, 30*time.Second) - assert.WithinDuration(t, before, service.UpdatedAt, 30*time.Second) + + expected := swarmtypes.Service{ + ID: id, + Spec: serviceSpec, + Meta: swarmtypes.Meta{ + Version: swarmtypes.Version{Index: uint64(11)}, + CreatedAt: now, + UpdatedAt: now, + }, + } + assert.Check(t, is.DeepEqual(service, expected, cmpServiceOpts())) +} + +// TODO: use helpers from gotestyourself/assert/opt when available +func cmpServiceOpts() cmp.Option { + const threshold = 20 * time.Second + + metaTimeFields := func(path cmp.Path) bool { + switch path.String() { + case "Meta.CreatedAt", "Meta.UpdatedAt": + return true + } + return false + } + withinThreshold := cmp.Comparer(func(x, y time.Time) bool { + delta := x.Sub(y) + return delta < threshold && delta > -threshold + }) + + return cmp.FilterPath(metaTimeFields, withinThreshold) } func fullSwarmServiceSpec(name string, replicas uint64) swarmtypes.ServiceSpec { diff --git a/components/engine/integration/system/info_linux_test.go b/components/engine/integration/system/info_linux_test.go index ad8dc2f9e29..e8bf70f9b89 100644 --- a/components/engine/integration/system/info_linux_test.go +++ b/components/engine/integration/system/info_linux_test.go @@ -19,17 +19,14 @@ func TestInfoBinaryCommits(t *testing.T) { info, err := client.Info(context.Background()) assert.NilError(t, err) - assert.Check(t, info.ContainerdCommit != nil) assert.Check(t, "N/A" != info.ContainerdCommit.ID) assert.Check(t, is.Equal(testEnv.DaemonInfo.ContainerdCommit.Expected, info.ContainerdCommit.Expected)) assert.Check(t, is.Equal(info.ContainerdCommit.Expected, info.ContainerdCommit.ID)) - assert.Check(t, info.InitCommit != nil) assert.Check(t, "N/A" != info.InitCommit.ID) assert.Check(t, is.Equal(testEnv.DaemonInfo.InitCommit.Expected, info.InitCommit.Expected)) assert.Check(t, is.Equal(info.InitCommit.Expected, info.InitCommit.ID)) - assert.Check(t, info.RuncCommit != nil) assert.Check(t, "N/A" != info.RuncCommit.ID) assert.Check(t, is.Equal(testEnv.DaemonInfo.RuncCommit.Expected, info.RuncCommit.Expected)) assert.Check(t, is.Equal(info.RuncCommit.Expected, info.RuncCommit.ID)) diff --git a/components/engine/integration/system/version_test.go b/components/engine/integration/system/version_test.go index a676c31802f..38784e3ee94 100644 --- a/components/engine/integration/system/version_test.go +++ b/components/engine/integration/system/version_test.go @@ -15,9 +15,9 @@ func TestVersion(t *testing.T) { version, err := client.ServerVersion(context.Background()) assert.NilError(t, err) - assert.Check(t, version.APIVersion != nil) - assert.Check(t, version.Version != nil) - assert.Check(t, version.MinAPIVersion != nil) + assert.Check(t, version.APIVersion != "") + assert.Check(t, version.Version != "") + assert.Check(t, version.MinAPIVersion != "") assert.Check(t, is.Equal(testEnv.DaemonInfo.ExperimentalBuild, version.Experimental)) assert.Check(t, is.Equal(testEnv.OSType, version.Os)) } diff --git a/components/engine/internal/testutil/helpers.go b/components/engine/internal/testutil/helpers.go index b1d8f44e3e9..89cb552feaa 100644 --- a/components/engine/internal/testutil/helpers.go +++ b/components/engine/internal/testutil/helpers.go @@ -4,14 +4,20 @@ import ( "io" "github.com/gotestyourself/gotestyourself/assert" - is "github.com/gotestyourself/gotestyourself/assert/cmp" ) +type helperT interface { + Helper() +} + // ErrorContains checks that the error is not nil, and contains the expected // substring. +// Deprecated: use assert.Assert(t, cmp.ErrorContains(err, expected)) func ErrorContains(t assert.TestingT, err error, expectedError string, msgAndArgs ...interface{}) { - assert.Assert(t, is.ErrorContains(err, ""), msgAndArgs) - assert.Check(t, is.Contains(err.Error(), expectedError), msgAndArgs) + if ht, ok := t.(helperT); ok { + ht.Helper() + } + assert.ErrorContains(t, err, expectedError, msgAndArgs...) } // DevZero acts like /dev/zero but in an OS-independent fashion. diff --git a/components/engine/pkg/archive/archive_test.go b/components/engine/pkg/archive/archive_test.go index 296b636a6eb..e8d12dd72fa 100644 --- a/components/engine/pkg/archive/archive_test.go +++ b/components/engine/pkg/archive/archive_test.go @@ -10,6 +10,7 @@ import ( "os" "os/exec" "path/filepath" + "reflect" "runtime" "strings" "testing" @@ -1338,7 +1339,7 @@ func TestDisablePigz(t *testing.T) { // For the context canceller contextReaderCloserWrapper := outsideReaderCloserWrapper.Reader.(*ioutils.ReadCloserWrapper) - assert.IsType(t, &gzip.Reader{}, contextReaderCloserWrapper.Reader) + assert.Equal(t, reflect.TypeOf(contextReaderCloserWrapper.Reader), reflect.TypeOf(&gzip.Reader{})) } func TestPigz(t *testing.T) { @@ -1351,9 +1352,9 @@ func TestPigz(t *testing.T) { _, err := exec.LookPath("unpigz") if err == nil { t.Log("Tested whether Pigz is used, as it installed") - assert.IsType(t, &io.PipeReader{}, contextReaderCloserWrapper.Reader) + assert.Equal(t, reflect.TypeOf(contextReaderCloserWrapper.Reader), reflect.TypeOf(&io.PipeReader{})) } else { t.Log("Tested whether Pigz is not used, as it not installed") - assert.IsType(t, &gzip.Reader{}, contextReaderCloserWrapper.Reader) + assert.Equal(t, reflect.TypeOf(contextReaderCloserWrapper.Reader), reflect.TypeOf(&gzip.Reader{})) } } diff --git a/components/engine/pkg/plugins/plugin_test.go b/components/engine/pkg/plugins/plugin_test.go index 0efd5e3aa0d..ca8d5984007 100644 --- a/components/engine/pkg/plugins/plugin_test.go +++ b/components/engine/pkg/plugins/plugin_test.go @@ -15,7 +15,6 @@ import ( "github.com/docker/docker/pkg/plugins/transport" "github.com/docker/go-connections/tlsconfig" "github.com/gotestyourself/gotestyourself/assert" - is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/pkg/errors" ) @@ -55,7 +54,6 @@ func testActive(t *testing.T, p *Plugin) { t.Fatalf("%s:%d: deadlock in waitActive", filepath.Base(f), l) case <-done: } - } func TestGet(t *testing.T) { @@ -79,12 +77,11 @@ func TestGet(t *testing.T) { // check negative case where plugin fruit doesn't implement banana _, err = Get("fruit", "banana") - assert.Check(t, is.DeepEqual(errors.Cause(err), ErrNotImplements)) + assert.Equal(t, errors.Cause(err), ErrNotImplements) // check negative case where plugin vegetable doesn't exist _, err = Get("vegetable", "potato") - assert.Check(t, is.DeepEqual(errors.Cause(err), ErrNotFound)) - + assert.Equal(t, errors.Cause(err), ErrNotFound) } func TestPluginWithNoManifest(t *testing.T) { diff --git a/components/engine/pkg/term/proxy_test.go b/components/engine/pkg/term/proxy_test.go index 9a53e2bc715..759be51456c 100644 --- a/components/engine/pkg/term/proxy_test.go +++ b/components/engine/pkg/term/proxy_test.go @@ -17,7 +17,7 @@ func TestEscapeProxyRead(t *testing.T) { nr, err := reader.Read(buf) assert.NilError(t, err) assert.Equal(t, nr, len(keys), fmt.Sprintf("nr %d should be equal to the number of %d", nr, len(keys))) - assert.Assert(t, is.DeepEqual(keys, buf), "keys & the read buffer should be equal") + assert.DeepEqual(t, keys, buf) keys, _ = ToBytes("") reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) @@ -35,7 +35,7 @@ func TestEscapeProxyRead(t *testing.T) { nr, err = reader.Read(buf) assert.NilError(t, err) assert.Equal(t, nr, 1, fmt.Sprintf("nr %d should be equal to the number of 1", nr)) - assert.Assert(t, is.DeepEqual(keys, buf), "keys & the read buffer should be equal") + assert.DeepEqual(t, keys, buf) escapeKeys, _ = ToBytes("ctrl-c") keys, _ = ToBytes("ctrl-c") @@ -44,7 +44,7 @@ func TestEscapeProxyRead(t *testing.T) { nr, err = reader.Read(buf) assert.Error(t, err, "read escape sequence") assert.Equal(t, nr, 0, "nr should be equal to 0") - assert.Assert(t, is.DeepEqual(keys, buf), "keys & the read buffer should be equal") + assert.DeepEqual(t, keys, buf) escapeKeys, _ = ToBytes("ctrl-c,ctrl-z") keys, _ = ToBytes("ctrl-c,ctrl-z") @@ -53,11 +53,11 @@ func TestEscapeProxyRead(t *testing.T) { nr, err = reader.Read(buf) assert.NilError(t, err) assert.Equal(t, nr, 0, "nr should be equal to 0") - assert.Assert(t, is.DeepEqual(keys[0:1], buf), "keys & the read buffer should be equal") + assert.DeepEqual(t, keys[0:1], buf) nr, err = reader.Read(buf) assert.Error(t, err, "read escape sequence") assert.Equal(t, nr, 0, "nr should be equal to 0") - assert.Assert(t, is.DeepEqual(keys[1:], buf), "keys & the read buffer should be equal") + assert.DeepEqual(t, keys[1:], buf) escapeKeys, _ = ToBytes("ctrl-c,ctrl-z") keys, _ = ToBytes("ctrl-c,DEL,+") @@ -66,12 +66,12 @@ func TestEscapeProxyRead(t *testing.T) { nr, err = reader.Read(buf) assert.NilError(t, err) assert.Equal(t, nr, 0, "nr should be equal to 0") - assert.Assert(t, is.DeepEqual(keys[0:1], buf), "keys & the read buffer should be equal") + assert.DeepEqual(t, keys[0:1], buf) buf = make([]byte, len(keys)) nr, err = reader.Read(buf) assert.NilError(t, err) assert.Equal(t, nr, len(keys), fmt.Sprintf("nr should be equal to %d", len(keys))) - assert.Assert(t, is.DeepEqual(keys, buf), "keys & the read buffer should be equal") + assert.DeepEqual(t, keys, buf) escapeKeys, _ = ToBytes("ctrl-c,ctrl-z") keys, _ = ToBytes("ctrl-c,DEL") @@ -80,10 +80,10 @@ func TestEscapeProxyRead(t *testing.T) { nr, err = reader.Read(buf) assert.NilError(t, err) assert.Equal(t, nr, 0, "nr should be equal to 0") - assert.Assert(t, is.DeepEqual(keys[0:1], buf), "keys & the read buffer should be equal") + assert.DeepEqual(t, keys[0:1], buf) buf = make([]byte, len(keys)) nr, err = reader.Read(buf) assert.NilError(t, err) assert.Equal(t, nr, len(keys), fmt.Sprintf("nr should be equal to %d", len(keys))) - assert.Assert(t, is.DeepEqual(keys, buf), "keys & the read buffer should be equal") + assert.DeepEqual(t, keys, buf) } diff --git a/components/engine/pkg/term/term_linux_test.go b/components/engine/pkg/term/term_linux_test.go index 98d2b1a3f27..4f1d67586f1 100644 --- a/components/engine/pkg/term/term_linux_test.go +++ b/components/engine/pkg/term/term_linux_test.go @@ -7,6 +7,7 @@ import ( "os" "testing" + "github.com/google/go-cmp/cmp" "github.com/gotestyourself/gotestyourself/assert" ) @@ -35,16 +36,17 @@ func TestGetWinsize(t *testing.T) { winSize, err := GetWinsize(tty.Fd()) assert.NilError(t, err) assert.Assert(t, winSize != nil) - assert.Assert(t, winSize.Height != nil) - assert.Assert(t, winSize.Width != nil) + newSize := Winsize{Width: 200, Height: 200, x: winSize.x, y: winSize.y} err = SetWinsize(tty.Fd(), &newSize) assert.NilError(t, err) winSize, err = GetWinsize(tty.Fd()) assert.NilError(t, err) - assert.DeepEqual(t, *winSize, newSize) + assert.DeepEqual(t, *winSize, newSize, cmpWinsize) } +var cmpWinsize = cmp.AllowUnexported(Winsize{}) + func TestSetWinsize(t *testing.T) { tty, err := newTtyForTest(t) defer tty.Close() @@ -57,7 +59,7 @@ func TestSetWinsize(t *testing.T) { assert.NilError(t, err) winSize, err = GetWinsize(tty.Fd()) assert.NilError(t, err) - assert.DeepEqual(t, *winSize, newSize) + assert.DeepEqual(t, *winSize, newSize, cmpWinsize) } func TestGetFdInfo(t *testing.T) { diff --git a/components/engine/volume/store/store_test.go b/components/engine/volume/store/store_test.go index c6d31364ac0..faf4035e292 100644 --- a/components/engine/volume/store/store_test.go +++ b/components/engine/volume/store/store_test.go @@ -12,6 +12,7 @@ import ( "github.com/docker/docker/volume" "github.com/docker/docker/volume/drivers" volumetestutils "github.com/docker/docker/volume/testutils" + "github.com/google/go-cmp/cmp" "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" ) @@ -359,7 +360,7 @@ func TestGet(t *testing.T) { v2, err := s.Get("test") assert.NilError(t, err) - assert.DeepEqual(t, v1, v2) + assert.DeepEqual(t, v1, v2, cmpVolume) dv := v2.(volume.DetailedVolume) assert.Equal(t, "1", dv.Labels()["a"]) @@ -383,7 +384,7 @@ func TestGetWithRef(t *testing.T) { v2, err := s.GetWithRef("test", driverName, "test-ref") assert.NilError(t, err) - assert.DeepEqual(t, v1, v2) + assert.DeepEqual(t, v1, v2, cmpVolume) err = s.Remove(v2) assert.Assert(t, is.ErrorContains(err, "")) @@ -394,6 +395,8 @@ func TestGetWithRef(t *testing.T) { assert.NilError(t, err) } +var cmpVolume = cmp.AllowUnexported(volumetestutils.FakeVolume{}, volumeWrapper{}) + func setupTest(t *testing.T, name string) (*VolumeStore, func(*testing.T)) { t.Helper() s, cleanup := newTestStore(t) From dc814f391e5b80f726cec254cfbc6850a7424338 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Fri, 29 Dec 2017 15:13:13 -0500 Subject: [PATCH 09/36] Cleanup pkg/jsonmessage progress tests Signed-off-by: Daniel Nephin (cherry picked from commit 7d8815ea705e85a73248b5d9e468f9dc65277bb8) Signed-off-by: Sebastiaan van Stijn --- .../engine/pkg/jsonmessage/jsonmessage.go | 34 +++- .../pkg/jsonmessage/jsonmessage_test.go | 152 ++++++++++-------- .../streamformatter/streamformatter_test.go | 39 ++--- 3 files changed, 132 insertions(+), 93 deletions(-) diff --git a/components/engine/pkg/jsonmessage/jsonmessage.go b/components/engine/pkg/jsonmessage/jsonmessage.go index 368f128949d..b9f40d3ef1e 100644 --- a/components/engine/pkg/jsonmessage/jsonmessage.go +++ b/components/engine/pkg/jsonmessage/jsonmessage.go @@ -40,21 +40,17 @@ type JSONProgress struct { // If true, don't show xB/yB HideCounts bool `json:"hidecounts,omitempty"` Units string `json:"units,omitempty"` + nowFunc func() time.Time + winSize int } func (p *JSONProgress) String() string { var ( - width = 200 + width = p.width() pbBox string numbersBox string timeLeftBox string ) - - ws, err := term.GetWinsize(p.terminalFd) - if err == nil { - width = int(ws.Width) - } - if p.Current <= 0 && p.Total <= 0 { return "" } @@ -103,7 +99,7 @@ func (p *JSONProgress) String() string { } if p.Current > 0 && p.Start > 0 && percentage < 50 { - fromStart := time.Now().UTC().Sub(time.Unix(p.Start, 0)) + fromStart := p.now().Sub(time.Unix(p.Start, 0)) perEntry := fromStart / time.Duration(p.Current) left := time.Duration(p.Total-p.Current) * perEntry left = (left / time.Second) * time.Second @@ -115,6 +111,28 @@ func (p *JSONProgress) String() string { return pbBox + numbersBox + timeLeftBox } +// shim for testing +func (p *JSONProgress) now() time.Time { + if p.nowFunc == nil { + p.nowFunc = func() time.Time { + return time.Now().UTC() + } + } + return p.nowFunc() +} + +// shim for testing +func (p *JSONProgress) width() int { + if p.winSize != 0 { + return p.winSize + } + ws, err := term.GetWinsize(p.terminalFd) + if err == nil { + return int(ws.Width) + } + return 200 +} + // JSONMessage defines a message struct. It describes // the created time, where it from, status, ID of the // message. It's used for docker events. diff --git a/components/engine/pkg/jsonmessage/jsonmessage_test.go b/components/engine/pkg/jsonmessage/jsonmessage_test.go index ab1d879c5a3..f9ead207cab 100644 --- a/components/engine/pkg/jsonmessage/jsonmessage_test.go +++ b/components/engine/pkg/jsonmessage/jsonmessage_test.go @@ -15,84 +15,102 @@ import ( func TestError(t *testing.T) { je := JSONError{404, "Not found"} - if je.Error() != "Not found" { - t.Fatalf("Expected 'Not found' got '%s'", je.Error()) - } + assert.Assert(t, is.Error(&je, "Not found")) } -func TestProgress(t *testing.T) { - termsz, err := term.GetWinsize(0) - if err != nil { - // we can safely ignore the err here - termsz = nil - } - jp := JSONProgress{} - if jp.String() != "" { - t.Fatalf("Expected empty string, got '%s'", jp.String()) - } - - expected := " 1B" - jp2 := JSONProgress{Current: 1} - if jp2.String() != expected { - t.Fatalf("Expected %q, got %q", expected, jp2.String()) +func TestProgressString(t *testing.T) { + type expected struct { + short string + long string } - expectedStart := "[==========> ] 20B/100B" - if termsz != nil && termsz.Width <= 110 { - expectedStart = " 20B/100B" - } - jp3 := JSONProgress{Current: 20, Total: 100, Start: time.Now().Unix()} - // Just look at the start of the string - // (the remaining time is really hard to test -_-) - if jp3.String()[:len(expectedStart)] != expectedStart { - t.Fatalf("Expected to start with %q, got %q", expectedStart, jp3.String()) - } - - expected = "[=========================> ] 50B/100B" - if termsz != nil && termsz.Width <= 110 { - expected = " 50B/100B" - } - jp4 := JSONProgress{Current: 50, Total: 100} - if jp4.String() != expected { - t.Fatalf("Expected %q, got %q", expected, jp4.String()) + shortAndLong := func(short, long string) expected { + return expected{short: short, long: long} } - // this number can't be negative gh#7136 - expected = "[==================================================>] 50B" - if termsz != nil && termsz.Width <= 110 { - expected = " 50B" - } - jp5 := JSONProgress{Current: 50, Total: 40} - if jp5.String() != expected { - t.Fatalf("Expected %q, got %q", expected, jp5.String()) + start := time.Date(2017, 12, 3, 15, 10, 1, 0, time.UTC) + timeAfter := func(delta time.Duration) func() time.Time { + return func() time.Time { + return start.Add(delta) + } } - expected = "[=========================> ] 50/100 units" - if termsz != nil && termsz.Width <= 110 { - expected = " 50/100 units" - } - jp6 := JSONProgress{Current: 50, Total: 100, Units: "units"} - if jp6.String() != expected { - t.Fatalf("Expected %q, got %q", expected, jp6.String()) + var testcases = []struct { + name string + progress JSONProgress + expected expected + }{ + { + name: "no progress", + }, + { + name: "progress 1", + progress: JSONProgress{Current: 1}, + expected: shortAndLong(" 1B", " 1B"), + }, + { + name: "some progress with a start time", + progress: JSONProgress{ + Current: 20, + Total: 100, + Start: start.Unix(), + nowFunc: timeAfter(time.Second), + }, + expected: shortAndLong( + " 20B/100B 4s", + "[==========> ] 20B/100B 4s", + ), + }, + { + name: "some progress without a start time", + progress: JSONProgress{Current: 50, Total: 100}, + expected: shortAndLong( + " 50B/100B", + "[=========================> ] 50B/100B", + ), + }, + { + name: "current more than total is not negative gh#7136", + progress: JSONProgress{Current: 50, Total: 40}, + expected: shortAndLong( + " 50B", + "[==================================================>] 50B", + ), + }, + { + name: "with units", + progress: JSONProgress{Current: 50, Total: 100, Units: "units"}, + expected: shortAndLong( + "50/100 units", + "[=========================> ] 50/100 units", + ), + }, + { + name: "current more than total with units is not negative ", + progress: JSONProgress{Current: 50, Total: 40, Units: "units"}, + expected: shortAndLong( + "50 units", + "[==================================================>] 50 units", + ), + }, + { + name: "hide counts", + progress: JSONProgress{Current: 50, Total: 100, HideCounts: true}, + expected: shortAndLong( + "", + "[=========================> ] ", + ), + }, } - // this number can't be negative - expected = "[==================================================>] 50 units" - if termsz != nil && termsz.Width <= 110 { - expected = " 50 units" - } - jp7 := JSONProgress{Current: 50, Total: 40, Units: "units"} - if jp7.String() != expected { - t.Fatalf("Expected %q, got %q", expected, jp7.String()) - } + for _, testcase := range testcases { + t.Run(testcase.name, func(t *testing.T) { + testcase.progress.winSize = 100 + assert.Equal(t, testcase.progress.String(), testcase.expected.short) - expected = "[=========================> ] " - if termsz != nil && termsz.Width <= 110 { - expected = "" - } - jp8 := JSONProgress{Current: 50, Total: 100, HideCounts: true} - if jp8.String() != expected { - t.Fatalf("Expected %q, got %q", expected, jp8.String()) + testcase.progress.winSize = 200 + assert.Equal(t, testcase.progress.String(), testcase.expected.long) + }) } } diff --git a/components/engine/pkg/streamformatter/streamformatter_test.go b/components/engine/pkg/streamformatter/streamformatter_test.go index e655f9140ac..172d568bda0 100644 --- a/components/engine/pkg/streamformatter/streamformatter_test.go +++ b/components/engine/pkg/streamformatter/streamformatter_test.go @@ -8,6 +8,8 @@ import ( "testing" "github.com/docker/docker/pkg/jsonmessage" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" ) @@ -58,30 +60,31 @@ func TestJsonProgressFormatterFormatProgress(t *testing.T) { Total: 30, Start: 1, } - res := sf.formatProgress("id", "action", jsonProgress, &AuxFormatter{Writer: &bytes.Buffer{}}) + aux := "aux message" + res := sf.formatProgress("id", "action", jsonProgress, aux) msg := &jsonmessage.JSONMessage{} assert.NilError(t, json.Unmarshal(res, msg)) - assert.Check(t, is.Equal("id", msg.ID)) - assert.Check(t, is.Equal("action", msg.Status)) - // jsonProgress will always be in the format of: - // [=========================> ] 15B/30B 412910h51m30s - // The last entry '404933h7m11s' is the timeLeftBox. - // However, the timeLeftBox field may change as jsonProgress.String() depends on time.Now(). - // Therefore, we have to strip the timeLeftBox from the strings to do the comparison. - - // Compare the jsonProgress strings before the timeLeftBox - expectedProgress := "[=========================> ] 15B/30B" - // if terminal column is <= 110, expectedProgressShort is expected. - expectedProgressShort := " 15B/30B" - if !(strings.HasPrefix(msg.ProgressMessage, expectedProgress) || - strings.HasPrefix(msg.ProgressMessage, expectedProgressShort)) { - t.Fatalf("ProgressMessage without the timeLeftBox must be %s or %s, got: %s", - expectedProgress, expectedProgressShort, msg.ProgressMessage) + rawAux := json.RawMessage(`"` + aux + `"`) + expected := &jsonmessage.JSONMessage{ + ID: "id", + Status: "action", + Aux: &rawAux, + Progress: jsonProgress, } + assert.DeepEqual(t, msg, expected, cmpJSONMessageOpt()) +} - assert.Check(t, is.DeepEqual(jsonProgress, msg.Progress)) +func cmpJSONMessageOpt() cmp.Option { + progressMessagePath := func(path cmp.Path) bool { + return path.String() == "ProgressMessage" + } + return cmp.Options{ + cmpopts.IgnoreUnexported(jsonmessage.JSONProgress{}), + // Ignore deprecated property that is a derivative of Progress + cmp.FilterPath(progressMessagePath, cmp.Ignore()), + } } func TestJsonProgressFormatterFormatStatus(t *testing.T) { From f03b3e54d7c6dbef3fadb144dcc47b1beb19f6aa Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Thu, 15 Mar 2018 14:30:35 -0400 Subject: [PATCH 10/36] Update testing doc Signed-off-by: Daniel Nephin (cherry picked from commit 58de6277821698a2f97d1a0c83664ab34ff2e8d8) Signed-off-by: Sebastiaan van Stijn --- components/engine/TESTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/engine/TESTING.md b/components/engine/TESTING.md index 20f7c9254ee..1231e1c5f4d 100644 --- a/components/engine/TESTING.md +++ b/components/engine/TESTING.md @@ -8,11 +8,11 @@ questions you may have as an aspiring Moby contributor. Moby has two test suites (and one legacy test suite): * Unit tests - use standard `go test` and - [testify](https://github.com/stretchr/testify) assertions. They are located in + [gotestyourself/assert](https://godoc.org/github.com/gotestyourself/gotestyourself/assert) assertions. They are located in the package they test. Unit tests should be fast and test only their own package. * API integration tests - use standard `go test` and - [testify](https://github.com/stretchr/testify) assertions. They are located in + [gotestyourself/assert](https://godoc.org/github.com/gotestyourself/gotestyourself/assert) assertions. They are located in `./integration/` directories, where `component` is: container, image, volume, etc. These tests perform HTTP requests to an API endpoint and check the HTTP response and daemon state after the call. From 612f97278993b514bc88fe0066e8bba414138b5e Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Mon, 12 Mar 2018 14:48:49 -0700 Subject: [PATCH 11/36] integration/TestContainerShmNoLeak: use --iptables=false As mentioned in commit 9e31938, test cases that use t.Parallel() and start a docker daemon might step on each other toes as they try to configure iptables during startup, resulting in flaky tests. To avoid this, --iptables=false should be used while starting daemon. Fixes: eaa5192856c1 ("Make container resource mounts unbindable") Signed-off-by: Kir Kolyshkin (cherry picked from commit c125e10a0486623ba3badebf974ea6e582373151) Signed-off-by: Sebastiaan van Stijn --- components/engine/integration/container/mounts_linux_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/engine/integration/container/mounts_linux_test.go b/components/engine/integration/container/mounts_linux_test.go index 33168ffc33d..e15786f8a6c 100644 --- a/components/engine/integration/container/mounts_linux_test.go +++ b/components/engine/integration/container/mounts_linux_test.go @@ -30,7 +30,7 @@ func TestContainerShmNoLeak(t *testing.T) { if err != nil { t.Fatal(err) } - d.StartWithBusybox(t) + d.StartWithBusybox(t, "--iptables=false") defer d.Stop(t) ctx := context.Background() From 33df5137f74ba84c5dd57b4fde90c6d4cf1d7b0f Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Fri, 23 Feb 2018 15:56:03 +0100 Subject: [PATCH 12/36] Update e2e script Signed-off-by: Vincent Demeester (cherry picked from commit 4bb0f24716f45ac520e73a52d7d7ca2752cabd31) Signed-off-by: Sebastiaan van Stijn --- components/engine/hack/test/e2e-run.sh | 80 ++++++++++++++++++-------- 1 file changed, 55 insertions(+), 25 deletions(-) diff --git a/components/engine/hack/test/e2e-run.sh b/components/engine/hack/test/e2e-run.sh index 448f1208950..b80f7fc3124 100755 --- a/components/engine/hack/test/e2e-run.sh +++ b/components/engine/hack/test/e2e-run.sh @@ -1,41 +1,71 @@ #!/usr/bin/env bash -set -e +set -e -u -o pipefail -TESTFLAGS=${TESTFLAGS:-""} -# Currently only DockerSuite and DockerNetworkSuite have been adapted for E2E testing -TESTFLAGS_LEGACY=${TESTFLAGS_LEGACY:-""} -TIMEOUT=${TIMEOUT:-60m} +ARCH=$(uname -m) +if [ "$ARCH" == "x86_64" ]; then + ARCH="amd64" +fi -SCRIPTDIR="$(dirname ${BASH_SOURCE[0]})" +export DOCKER_ENGINE_GOARCH=${DOCKER_ENGINE_GOARCH:-${ARCH}} -export DOCKER_ENGINE_GOARCH=${DOCKER_ENGINE_GOARCH:-amd64} +# Set defaults +: ${TESTFLAGS:=} +: ${TESTDEBUG:=} + +integration_api_dirs=${TEST_INTEGRATION_DIR:-"$( + find ./integration -type d | + grep -vE '(^./integration($|/internal)|/testdata)')"} run_test_integration() { - run_test_integration_suites - run_test_integration_legacy_suites + [[ "$TESTFLAGS" != *-check.f* ]] && run_test_integration_suites + run_test_integration_legacy_suites } run_test_integration_suites() { - local flags="-test.timeout=${TIMEOUT} $TESTFLAGS" - for dir in /tests/integration/*; do - if ! ( - cd $dir - echo "Running $PWD" - ./test.main $flags - ); then exit 1; fi - done + local flags="-test.v -test.timeout=${TIMEOUT:=10m} $TESTFLAGS" + for dir in $integration_api_dirs; do + if ! ( + cd $dir + echo "Running $PWD" + test_env ./test.main $flags + ); then exit 1; fi + done } run_test_integration_legacy_suites() { - ( - flags="-check.timeout=${TIMEOUT} -test.timeout=360m $TESTFLAGS_LEGACY" - cd /tests/integration-cli - echo "Running $PWD" - ./test.main $flags - ) + ( + flags="-check.v -check.timeout=${TIMEOUT} -test.timeout=360m $TESTFLAGS" + cd test/integration-cli + echo "Running $PWD" + test_env ./test.main $flags + ) } -bash $SCRIPTDIR/ensure-emptyfs.sh +# use "env -i" to tightly control the environment variables that bleed into the tests +test_env() { + ( + set -e +u + [ -n "$TESTDEBUG" ] && set -x + env -i \ + DOCKER_API_VERSION="$DOCKER_API_VERSION" \ + DOCKER_INTEGRATION_DAEMON_DEST="$DOCKER_INTEGRATION_DAEMON_DEST" \ + DOCKER_TLS_VERIFY="$DOCKER_TEST_TLS_VERIFY" \ + DOCKER_CERT_PATH="$DOCKER_TEST_CERT_PATH" \ + DOCKER_ENGINE_GOARCH="$DOCKER_ENGINE_GOARCH" \ + DOCKER_GRAPHDRIVER="$DOCKER_GRAPHDRIVER" \ + DOCKER_USERLANDPROXY="$DOCKER_USERLANDPROXY" \ + DOCKER_HOST="$DOCKER_HOST" \ + DOCKER_REMAP_ROOT="$DOCKER_REMAP_ROOT" \ + DOCKER_REMOTE_DAEMON="$DOCKER_REMOTE_DAEMON" \ + DOCKERFILE="$DOCKERFILE" \ + GOPATH="$GOPATH" \ + GOTRACEBACK=all \ + HOME="$ABS_DEST/fake-HOME" \ + PATH="$PATH" \ + TEMP="$TEMP" \ + TEST_CLIENT_BINARY="$TEST_CLIENT_BINARY" \ + "$@" + ) +} -echo "Run integration tests" run_test_integration From 69f0e0e72014bd5da6e17d9972475c494f30c977 Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Wed, 14 Mar 2018 11:21:21 +0100 Subject: [PATCH 13/36] integration/*: make e2e run without failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … mainly by skipping if daemon is remote. Signed-off-by: Vincent Demeester (cherry picked from commit 6016e79d2552b21643f4bfd093ce76d8ef956d79) Signed-off-by: Sebastiaan van Stijn --- components/engine/hack/test/e2e-run.sh | 6 +-- .../engine/integration/build/build_test.go | 6 +++ .../integration/internal/swarm/service.go | 2 + .../integration/network/inspect_test.go | 45 ++++++------------- .../integration/network/service_test.go | 19 ++++---- .../integration/plugin/authz/main_test.go | 2 + .../plugin/logging/helpers_test.go | 2 - .../integration/plugin/logging/main_test.go | 31 +++++++++++++ .../plugin/logging/validation_test.go | 2 + .../internal/test/environment/environment.go | 9 ++++ 10 files changed, 78 insertions(+), 46 deletions(-) create mode 100644 components/engine/integration/plugin/logging/main_test.go diff --git a/components/engine/hack/test/e2e-run.sh b/components/engine/hack/test/e2e-run.sh index b80f7fc3124..b1470d6547d 100755 --- a/components/engine/hack/test/e2e-run.sh +++ b/components/engine/hack/test/e2e-run.sh @@ -13,8 +13,8 @@ export DOCKER_ENGINE_GOARCH=${DOCKER_ENGINE_GOARCH:-${ARCH}} : ${TESTDEBUG:=} integration_api_dirs=${TEST_INTEGRATION_DIR:-"$( - find ./integration -type d | - grep -vE '(^./integration($|/internal)|/testdata)')"} + find /tests/integration -type d | + grep -vE '(^/tests/integration($|/internal)|/testdata)')"} run_test_integration() { [[ "$TESTFLAGS" != *-check.f* ]] && run_test_integration_suites @@ -35,7 +35,7 @@ run_test_integration_suites() { run_test_integration_legacy_suites() { ( flags="-check.v -check.timeout=${TIMEOUT} -test.timeout=360m $TESTFLAGS" - cd test/integration-cli + cd /tests/integration-cli echo "Running $PWD" test_env ./test.main $flags ) diff --git a/components/engine/integration/build/build_test.go b/components/engine/integration/build/build_test.go index 9d396da8655..d8cb298cd46 100644 --- a/components/engine/integration/build/build_test.go +++ b/components/engine/integration/build/build_test.go @@ -5,6 +5,7 @@ import ( "bytes" "context" "encoding/json" + "fmt" "io" "io/ioutil" "strings" @@ -12,11 +13,13 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/versions" "github.com/docker/docker/integration-cli/cli/build/fakecontext" "github.com/docker/docker/integration/internal/request" "github.com/docker/docker/pkg/jsonmessage" "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" + "github.com/gotestyourself/gotestyourself/skip" ) func TestBuildWithRemoveAndForceRemove(t *testing.T) { @@ -304,6 +307,9 @@ COPY bar /` // docker/for-linux#135 // #35641 func TestBuildMultiStageLayerLeak(t *testing.T) { + fmt.Println(testEnv.DaemonAPIVersion()) + skip.IfCondition(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), + "Don't run on API lower than 1.38 as it has been fixed starting from that version") ctx := context.TODO() defer setupTest(t)() diff --git a/components/engine/integration/internal/swarm/service.go b/components/engine/integration/internal/swarm/service.go index 0ec4d5175ef..79705961a1b 100644 --- a/components/engine/integration/internal/swarm/service.go +++ b/components/engine/integration/internal/swarm/service.go @@ -12,6 +12,7 @@ import ( "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/internal/test/environment" "github.com/gotestyourself/gotestyourself/assert" + "github.com/gotestyourself/gotestyourself/skip" ) const ( @@ -21,6 +22,7 @@ const ( // NewSwarm creates a swarm daemon for testing func NewSwarm(t *testing.T, testEnv *environment.Execution) *daemon.Swarm { + skip.IfCondition(t, testEnv.IsRemoteDaemon()) d := &daemon.Swarm{ Daemon: daemon.New(t, "", dockerdBinary, daemon.Config{ Experimental: testEnv.DaemonInfo.ExperimentalBuild, diff --git a/components/engine/integration/network/inspect_test.go b/components/engine/integration/network/inspect_test.go index 3afdcf1ac48..ad4a344c49c 100644 --- a/components/engine/integration/network/inspect_test.go +++ b/components/engine/integration/network/inspect_test.go @@ -1,16 +1,15 @@ package network // import "github.com/docker/docker/integration/network" import ( - "fmt" "runtime" "testing" "time" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" - "github.com/docker/docker/api/types/swarm" + swarmtypes "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" - "github.com/docker/docker/integration-cli/daemon" + "github.com/docker/docker/integration/internal/swarm" "github.com/gotestyourself/gotestyourself/assert" "github.com/gotestyourself/gotestyourself/poll" "golang.org/x/net/context" @@ -21,7 +20,7 @@ const dockerdBinary = "dockerd" func TestInspectNetwork(t *testing.T) { defer setupTest(t)() - d := newSwarm(t) + d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) assert.NilError(t, err) @@ -38,8 +37,9 @@ func TestInspectNetwork(t *testing.T) { var instances uint64 = 4 serviceName := "TestService" + // FIXME(vdemeester) consolidate with swarm.CreateService serviceSpec := swarmServiceSpec(serviceName, instances) - serviceSpec.TaskTemplate.Networks = append(serviceSpec.TaskTemplate.Networks, swarm.NetworkAttachmentConfig{Target: overlayName}) + serviceSpec.TaskTemplate.Networks = append(serviceSpec.TaskTemplate.Networks, swarmtypes.NetworkAttachmentConfig{Target: overlayName}) serviceResp, err := client.ServiceCreate(context.Background(), serviceSpec, types.ServiceCreateOptions{ QueryRegistry: false, @@ -107,38 +107,19 @@ func TestInspectNetwork(t *testing.T) { poll.WaitOn(t, networkIsRemoved(client, overlayID), poll.WithTimeout(1*time.Minute), poll.WithDelay(10*time.Second)) } -func newSwarm(t *testing.T) *daemon.Swarm { - d := &daemon.Swarm{ - Daemon: daemon.New(t, "", dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }), - // TODO: better method of finding an unused port - Port: defaultSwarmPort, - } - // TODO: move to a NewSwarm constructor - d.ListenAddr = fmt.Sprintf("0.0.0.0:%d", d.Port) - - // avoid networking conflicts - args := []string{"--iptables=false", "--swarm-default-advertise-addr=lo"} - d.StartWithBusybox(t, args...) - - assert.NilError(t, d.Init(swarm.InitRequest{})) - return d -} - -func swarmServiceSpec(name string, replicas uint64) swarm.ServiceSpec { - return swarm.ServiceSpec{ - Annotations: swarm.Annotations{ +func swarmServiceSpec(name string, replicas uint64) swarmtypes.ServiceSpec { + return swarmtypes.ServiceSpec{ + Annotations: swarmtypes.Annotations{ Name: name, }, - TaskTemplate: swarm.TaskSpec{ - ContainerSpec: &swarm.ContainerSpec{ + TaskTemplate: swarmtypes.TaskSpec{ + ContainerSpec: &swarmtypes.ContainerSpec{ Image: "busybox:latest", Command: []string{"/bin/top"}, }, }, - Mode: swarm.ServiceMode{ - Replicated: &swarm.ReplicatedService{ + Mode: swarmtypes.ServiceMode{ + Replicated: &swarmtypes.ReplicatedService{ Replicas: &replicas, }, }, @@ -157,7 +138,7 @@ func serviceRunningTasksCount(client client.ServiceAPIClient, serviceID string, return poll.Error(err) case len(tasks) == int(instances): for _, task := range tasks { - if task.Status.State != swarm.TaskStateRunning { + if task.Status.State != swarmtypes.TaskStateRunning { return poll.Continue("waiting for tasks to enter run state") } } diff --git a/components/engine/integration/network/service_test.go b/components/engine/integration/network/service_test.go index b8470a1e855..a9fccf95221 100644 --- a/components/engine/integration/network/service_test.go +++ b/components/engine/integration/network/service_test.go @@ -7,8 +7,9 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" - "github.com/docker/docker/api/types/swarm" + swarmtypes "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" + "github.com/docker/docker/integration/internal/swarm" "github.com/gotestyourself/gotestyourself/assert" "github.com/gotestyourself/gotestyourself/poll" "golang.org/x/net/context" @@ -16,7 +17,7 @@ import ( func TestServiceWithPredefinedNetwork(t *testing.T) { defer setupTest(t)() - d := newSwarm(t) + d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) assert.NilError(t, err) @@ -25,7 +26,7 @@ func TestServiceWithPredefinedNetwork(t *testing.T) { var instances uint64 = 1 serviceName := "TestService" serviceSpec := swarmServiceSpec(serviceName, instances) - serviceSpec.TaskTemplate.Networks = append(serviceSpec.TaskTemplate.Networks, swarm.NetworkAttachmentConfig{Target: hostName}) + serviceSpec.TaskTemplate.Networks = append(serviceSpec.TaskTemplate.Networks, swarmtypes.NetworkAttachmentConfig{Target: hostName}) serviceResp, err := client.ServiceCreate(context.Background(), serviceSpec, types.ServiceCreateOptions{ QueryRegistry: false, @@ -60,7 +61,7 @@ const ingressNet = "ingress" func TestServiceWithIngressNetwork(t *testing.T) { defer setupTest(t)() - d := newSwarm(t) + d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) @@ -81,13 +82,13 @@ func TestServiceWithIngressNetwork(t *testing.T) { var instances uint64 = 1 serviceName := "TestIngressService" serviceSpec := swarmServiceSpec(serviceName, instances) - serviceSpec.TaskTemplate.Networks = append(serviceSpec.TaskTemplate.Networks, swarm.NetworkAttachmentConfig{Target: ingressNet}) - serviceSpec.EndpointSpec = &swarm.EndpointSpec{ - Ports: []swarm.PortConfig{ + serviceSpec.TaskTemplate.Networks = append(serviceSpec.TaskTemplate.Networks, swarmtypes.NetworkAttachmentConfig{Target: ingressNet}) + serviceSpec.EndpointSpec = &swarmtypes.EndpointSpec{ + Ports: []swarmtypes.PortConfig{ { - Protocol: swarm.PortConfigProtocolTCP, + Protocol: swarmtypes.PortConfigProtocolTCP, TargetPort: 80, - PublishMode: swarm.PortConfigPublishModeIngress, + PublishMode: swarmtypes.PortConfigPublishModeIngress, }, }, } diff --git a/components/engine/integration/plugin/authz/main_test.go b/components/engine/integration/plugin/authz/main_test.go index ea72a03f169..3d5f406b923 100644 --- a/components/engine/integration/plugin/authz/main_test.go +++ b/components/engine/integration/plugin/authz/main_test.go @@ -16,6 +16,7 @@ import ( "github.com/docker/docker/internal/test/environment" "github.com/docker/docker/pkg/authorization" "github.com/docker/docker/pkg/plugins" + "github.com/gotestyourself/gotestyourself/skip" ) var ( @@ -48,6 +49,7 @@ func TestMain(m *testing.M) { } func setupTest(t *testing.T) func() { + skip.IfCondition(t, testEnv.IsRemoteDaemon(), "cannot run daemon when remote daemon") environment.ProtectAll(t, testEnv) d = daemon.New(t, "", dockerdBinary, daemon.Config{ diff --git a/components/engine/integration/plugin/logging/helpers_test.go b/components/engine/integration/plugin/logging/helpers_test.go index 61b2f35f43d..371d43d831f 100644 --- a/components/engine/integration/plugin/logging/helpers_test.go +++ b/components/engine/integration/plugin/logging/helpers_test.go @@ -14,8 +14,6 @@ import ( "github.com/pkg/errors" ) -const dockerdBinary = "dockerd" - var pluginBuildLock = locker.New() func ensurePlugin(t *testing.T, name string) string { diff --git a/components/engine/integration/plugin/logging/main_test.go b/components/engine/integration/plugin/logging/main_test.go new file mode 100644 index 00000000000..b2446ca8c88 --- /dev/null +++ b/components/engine/integration/plugin/logging/main_test.go @@ -0,0 +1,31 @@ +package logging // import "github.com/docker/docker/integration/plugin/logging" + +import ( + "fmt" + "os" + "testing" + + "github.com/docker/docker/internal/test/environment" +) + +var ( + testEnv *environment.Execution +) + +const dockerdBinary = "dockerd" + +func TestMain(m *testing.M) { + var err error + testEnv, err = environment.New() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + err = environment.EnsureFrozenImagesLinux(testEnv) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + testEnv.Print() + os.Exit(m.Run()) +} diff --git a/components/engine/integration/plugin/logging/validation_test.go b/components/engine/integration/plugin/logging/validation_test.go index eb3fe7a029e..f0d6e9e8b24 100644 --- a/components/engine/integration/plugin/logging/validation_test.go +++ b/components/engine/integration/plugin/logging/validation_test.go @@ -7,12 +7,14 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/integration-cli/daemon" "github.com/gotestyourself/gotestyourself/assert" + "github.com/gotestyourself/gotestyourself/skip" ) // Regression test for #35553 // Ensure that a daemon with a log plugin set as the default logger for containers // does not keep the daemon from starting. func TestDaemonStartWithLogOpt(t *testing.T) { + skip.IfCondition(t, testEnv.IsRemoteDaemon(), "cannot run daemon when remote daemon") t.Parallel() d := daemon.New(t, "", dockerdBinary, daemon.Config{}) diff --git a/components/engine/internal/test/environment/environment.go b/components/engine/internal/test/environment/environment.go index 16f61463346..8e6e2c72fa4 100644 --- a/components/engine/internal/test/environment/environment.go +++ b/components/engine/internal/test/environment/environment.go @@ -121,6 +121,15 @@ func (e *Execution) IsRemoteDaemon() bool { return !e.IsLocalDaemon() } +// DaemonAPIVersion returns the negociated daemon api version +func (e *Execution) DaemonAPIVersion() string { + version, err := e.APIClient().ServerVersion(context.TODO()) + if err != nil { + return "" + } + return version.APIVersion +} + // Print the execution details to stdout // TODO: print everything func (e *Execution) Print() { From 23752adb2da2fa419f32d84614db4ebfaf9584ba Mon Sep 17 00:00:00 2001 From: Arash Deshmeh Date: Wed, 21 Mar 2018 17:47:49 -0400 Subject: [PATCH 14/36] use unique names for resources used by integration tests container/inspect_test, container/ps_test, container/stop_test Signed-off-by: Arash Deshmeh (cherry picked from commit 78e4be91332e2237c0fa14eb3ba0fb5b915c3256) Signed-off-by: Sebastiaan van Stijn --- .../engine/integration/container/inspect_test.go | 2 +- components/engine/integration/container/ps_test.go | 11 ++++++----- components/engine/integration/container/stop_test.go | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/components/engine/integration/container/inspect_test.go b/components/engine/integration/container/inspect_test.go index 03b9e45319a..0433522e686 100644 --- a/components/engine/integration/container/inspect_test.go +++ b/components/engine/integration/container/inspect_test.go @@ -22,7 +22,7 @@ func TestInspectCpusetInConfigPre120(t *testing.T) { client := request.NewAPIClient(t, client.WithVersion("1.19")) ctx := context.Background() - name := "cpusetinconfig-pre120" + name := "cpusetinconfig-pre120-" + t.Name() // Create container with up to-date-API container.Run(t, ctx, request.NewAPIClient(t), container.WithName(name), container.WithCmd("true"), diff --git a/components/engine/integration/container/ps_test.go b/components/engine/integration/container/ps_test.go index 45bcaca239f..4dacef16527 100644 --- a/components/engine/integration/container/ps_test.go +++ b/components/engine/integration/container/ps_test.go @@ -17,9 +17,10 @@ func TestPsFilter(t *testing.T) { client := request.NewAPIClient(t) ctx := context.Background() - prev := container.Create(t, ctx, client, container.WithName("prev")) - container.Create(t, ctx, client, container.WithName("top")) - next := container.Create(t, ctx, client, container.WithName("next")) + prev := container.Create(t, ctx, client, container.WithName("prev-"+t.Name())) + topContainerName := "top-" + t.Name() + container.Create(t, ctx, client, container.WithName(topContainerName)) + next := container.Create(t, ctx, client, container.WithName("next-"+t.Name())) containerIDs := func(containers []types.Container) []string { entries := []string{} @@ -30,7 +31,7 @@ func TestPsFilter(t *testing.T) { } f1 := filters.NewArgs() - f1.Add("since", "top") + f1.Add("since", topContainerName) q1, err := client.ContainerList(ctx, types.ContainerListOptions{ All: true, Filters: f1, @@ -39,7 +40,7 @@ func TestPsFilter(t *testing.T) { assert.Check(t, is.Contains(containerIDs(q1), next)) f2 := filters.NewArgs() - f2.Add("before", "top") + f2.Add("before", topContainerName) q2, err := client.ContainerList(ctx, types.ContainerListOptions{ All: true, Filters: f2, diff --git a/components/engine/integration/container/stop_test.go b/components/engine/integration/container/stop_test.go index 2cc9b82512b..04aec215942 100644 --- a/components/engine/integration/container/stop_test.go +++ b/components/engine/integration/container/stop_test.go @@ -21,7 +21,7 @@ func TestStopContainerWithRestartPolicyAlways(t *testing.T) { client := request.NewAPIClient(t) ctx := context.Background() - names := []string{"verifyRestart1", "verifyRestart2"} + names := []string{"verifyRestart1-" + t.Name(), "verifyRestart2-" + t.Name()} for _, name := range names { container.Run(t, ctx, client, container.WithName(name), container.WithCmd("false"), func(c *container.TestContainerConfig) { c.HostConfig.RestartPolicy.Name = "always" @@ -49,7 +49,7 @@ func TestDeleteDevicemapper(t *testing.T) { client := request.NewAPIClient(t) ctx := context.Background() - id := container.Run(t, ctx, client, container.WithName("foo"), container.WithCmd("echo")) + id := container.Run(t, ctx, client, container.WithName("foo-"+t.Name()), container.WithCmd("echo")) poll.WaitOn(t, container.IsStopped(ctx, client, id), poll.WithDelay(100*time.Millisecond)) From 34e1feb36b6897c0cbdabcc282f15608f716ca19 Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Tue, 27 Mar 2018 18:13:47 +0200 Subject: [PATCH 15/36] Skip some tests in certain condition to run with e2e image Signed-off-by: Vincent Demeester (cherry picked from commit e55d6fc8573580f6eea009cd7f1034aa912128ef) Signed-off-by: Sebastiaan van Stijn --- components/engine/hack/test/e2e-run.sh | 5 +++-- .../integration-cli/cli/build/fakegit/fakegit.go | 5 +++++ .../cli/build/fakestorage/storage.go | 15 ++++++++++++--- .../integration-cli/docker_api_containers_test.go | 4 +++- .../integration-cli/docker_api_images_test.go | 9 ++++++++- .../integration-cli/docker_api_logs_test.go | 7 +++---- .../integration-cli/docker_cli_build_test.go | 2 +- .../engine/integration-cli/docker_cli_cp_test.go | 2 +- .../integration-cli/docker_cli_events_test.go | 2 ++ .../docker_cli_external_graphdriver_unix_test.go | 4 ++-- .../docker_experimental_network_test.go | 6 +++--- components/engine/integration/build/build_test.go | 6 ++---- .../engine/integration/container/logs_test.go | 3 +++ .../integration/container/mounts_linux_test.go | 1 + .../engine/integration/container/ps_test.go | 11 +++++------ .../engine/integration/volume/volume_test.go | 7 ++++--- 16 files changed, 58 insertions(+), 31 deletions(-) diff --git a/components/engine/hack/test/e2e-run.sh b/components/engine/hack/test/e2e-run.sh index b1470d6547d..122d58f8ef9 100755 --- a/components/engine/hack/test/e2e-run.sh +++ b/components/engine/hack/test/e2e-run.sh @@ -22,7 +22,7 @@ run_test_integration() { } run_test_integration_suites() { - local flags="-test.v -test.timeout=${TIMEOUT:=10m} $TESTFLAGS" + local flags="-test.v -test.timeout=${TIMEOUT:-10m} $TESTFLAGS" for dir in $integration_api_dirs; do if ! ( cd $dir @@ -34,7 +34,7 @@ run_test_integration_suites() { run_test_integration_legacy_suites() { ( - flags="-check.v -check.timeout=${TIMEOUT} -test.timeout=360m $TESTFLAGS" + flags="-check.v -check.timeout=${TIMEOUT:-200m} -test.timeout=360m $TESTFLAGS" cd /tests/integration-cli echo "Running $PWD" test_env ./test.main $flags @@ -68,4 +68,5 @@ test_env() { ) } +sh /scripts/ensure-emptyfs.sh run_test_integration diff --git a/components/engine/integration-cli/cli/build/fakegit/fakegit.go b/components/engine/integration-cli/cli/build/fakegit/fakegit.go index b05bfc322bd..f7a22c9ee57 100644 --- a/components/engine/integration-cli/cli/build/fakegit/fakegit.go +++ b/components/engine/integration-cli/cli/build/fakegit/fakegit.go @@ -17,6 +17,7 @@ import ( type testingT interface { assert.TestingT logT + skipT Fatal(args ...interface{}) Fatalf(string, ...interface{}) } @@ -25,6 +26,10 @@ type logT interface { Logf(string, ...interface{}) } +type skipT interface { + Skip(reason string) +} + type gitServer interface { URL() string Close() error diff --git a/components/engine/integration-cli/cli/build/fakestorage/storage.go b/components/engine/integration-cli/cli/build/fakestorage/storage.go index bd49a33cfe6..0df602a863f 100644 --- a/components/engine/integration-cli/cli/build/fakestorage/storage.go +++ b/components/engine/integration-cli/cli/build/fakestorage/storage.go @@ -23,6 +23,7 @@ var testEnv *environment.Execution type testingT interface { assert.TestingT logT + skipT Fatal(args ...interface{}) Fatalf(string, ...interface{}) } @@ -31,6 +32,10 @@ type logT interface { Logf(string, ...interface{}) } +type skipT interface { + Skip(reason string) +} + // Fake is a static file server. It might be running locally or remotely // on test host. type Fake interface { @@ -51,10 +56,15 @@ func New(t testingT, dir string, modifiers ...func(*fakecontext.Fake) error) Fak t.Fatal("fakstorage package requires SetTestEnvironment() to be called before use.") } ctx := fakecontext.New(t, dir, modifiers...) - if testEnv.IsLocalDaemon() { + switch { + case testEnv.IsRemoteDaemon() && strings.HasPrefix(request.DaemonHost(), "unix:///"): + t.Skip(fmt.Sprintf("e2e run : daemon is remote but docker host points to a unix socket")) + case testEnv.IsLocalDaemon(): return newLocalFakeStorage(ctx) + default: + return newRemoteFileServer(t, ctx) } - return newRemoteFileServer(t, ctx) + return nil } // localFileStorage is a file storage on the running machine @@ -152,7 +162,6 @@ COPY . /static`); err != nil { if err != nil { t.Fatalf("unable to parse daemon host URL: %v", err) } - host, _, err := net.SplitHostPort(dockerHostURL.Host) if err != nil { t.Fatalf("unable to parse docker daemon host:port: %v", err) diff --git a/components/engine/integration-cli/docker_api_containers_test.go b/components/engine/integration-cli/docker_api_containers_test.go index 76dcedb6766..2da31ac3e11 100644 --- a/components/engine/integration-cli/docker_api_containers_test.go +++ b/components/engine/integration-cli/docker_api_containers_test.go @@ -1713,7 +1713,9 @@ func (s *DockerSuite) TestContainersAPICreateMountsValidation(c *check.C) { Type: "bind", Source: notExistPath, Target: destPath}}}, - msg: "bind source path does not exist", + msg: "source path does not exist", + // FIXME(vdemeester) fails into e2e, migrate to integration/container anyway + // msg: "bind mount source path does not exist: " + notExistPath, }, { config: containertypes.Config{ diff --git a/components/engine/integration-cli/docker_api_images_test.go b/components/engine/integration-cli/docker_api_images_test.go index 7c6c2353549..5e47858da65 100644 --- a/components/engine/integration-cli/docker_api_images_test.go +++ b/components/engine/integration-cli/docker_api_images_test.go @@ -115,7 +115,14 @@ func (s *DockerSuite) TestAPIImagesHistory(c *check.C) { c.Assert(err, checker.IsNil) c.Assert(historydata, checker.Not(checker.HasLen), 0) - c.Assert(historydata[0].Tags[0], checker.Equals, "test-api-images-history:latest") + var found bool + for _, tag := range historydata[0].Tags { + if tag == "test-api-images-history:latest" { + found = true + break + } + } + c.Assert(found, checker.True) } func (s *DockerSuite) TestAPIImagesImportBadSrc(c *check.C) { diff --git a/components/engine/integration-cli/docker_api_logs_test.go b/components/engine/integration-cli/docker_api_logs_test.go index 89c2865fc48..46ca5172c31 100644 --- a/components/engine/integration-cli/docker_api_logs_test.go +++ b/components/engine/integration-cli/docker_api_logs_test.go @@ -93,7 +93,6 @@ func (s *DockerSuite) TestLogsAPIContainerNotFound(c *check.C) { func (s *DockerSuite) TestLogsAPIUntilFutureFollow(c *check.C) { testRequires(c, DaemonIsLinux) - name := "logsuntilfuturefollow" dockerCmd(c, "run", "-d", "--name", name, "busybox", "/bin/sh", "-c", "while true; do date +%s; sleep 1; done") c.Assert(waitRun(name), checker.IsNil) @@ -103,7 +102,7 @@ func (s *DockerSuite) TestLogsAPIUntilFutureFollow(c *check.C) { c.Assert(err, checker.IsNil) until := daemonTime(c).Add(untilDur) - client, err := request.NewClient() + client, err := client.NewEnvClient() if err != nil { c.Fatal(err) } @@ -153,7 +152,7 @@ func (s *DockerSuite) TestLogsAPIUntil(c *check.C) { name := "logsuntil" dockerCmd(c, "run", "--name", name, "busybox", "/bin/sh", "-c", "for i in $(seq 1 3); do echo log$i; sleep 1; done") - client, err := request.NewClient() + client, err := client.NewEnvClient() if err != nil { c.Fatal(err) } @@ -190,7 +189,7 @@ func (s *DockerSuite) TestLogsAPIUntilDefaultValue(c *check.C) { name := "logsuntildefaultval" dockerCmd(c, "run", "--name", name, "busybox", "/bin/sh", "-c", "for i in $(seq 1 3); do echo log$i; done") - client, err := request.NewClient() + client, err := client.NewEnvClient() if err != nil { c.Fatal(err) } diff --git a/components/engine/integration-cli/docker_cli_build_test.go b/components/engine/integration-cli/docker_cli_build_test.go index 65c63abdb63..1e29c53907c 100644 --- a/components/engine/integration-cli/docker_cli_build_test.go +++ b/components/engine/integration-cli/docker_cli_build_test.go @@ -1050,7 +1050,7 @@ func (s *DockerSuite) TestBuildAddBadLinksVolume(c *check.C) { // Issue #5270 - ensure we throw a better error than "unexpected EOF" // when we can't access files in the context. func (s *DockerSuite) TestBuildWithInaccessibleFilesInContext(c *check.C) { - testRequires(c, DaemonIsLinux, UnixCli) // test uses chown/chmod: not available on windows + testRequires(c, DaemonIsLinux, UnixCli, SameHostDaemon) // test uses chown/chmod: not available on windows { name := "testbuildinaccessiblefiles" diff --git a/components/engine/integration-cli/docker_cli_cp_test.go b/components/engine/integration-cli/docker_cli_cp_test.go index 59248d04a29..b33be6b2099 100644 --- a/components/engine/integration-cli/docker_cli_cp_test.go +++ b/components/engine/integration-cli/docker_cli_cp_test.go @@ -379,7 +379,7 @@ func (s *DockerSuite) TestCpSymlinkComponent(c *check.C) { // Check that cp with unprivileged user doesn't return any error func (s *DockerSuite) TestCpUnprivilegedUser(c *check.C) { - testRequires(c, DaemonIsLinux) + testRequires(c, DaemonIsLinux, SameHostDaemon) testRequires(c, UnixCli) // uses chmod/su: not available on windows out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "touch "+cpTestName) diff --git a/components/engine/integration-cli/docker_cli_events_test.go b/components/engine/integration-cli/docker_cli_events_test.go index bb2978b1b6c..bc73badbdfe 100644 --- a/components/engine/integration-cli/docker_cli_events_test.go +++ b/components/engine/integration-cli/docker_cli_events_test.go @@ -563,6 +563,8 @@ func (s *DockerRegistrySuite) TestEventsImageFilterPush(c *check.C) { } func (s *DockerSuite) TestEventsFilterType(c *check.C) { + // FIXME(vdemeester) fails on e2e run + testRequires(c, SameHostDaemon) since := daemonUnixTime(c) name := "labelfiltertest" label := "io.docker.testing=image" diff --git a/components/engine/integration-cli/docker_cli_external_graphdriver_unix_test.go b/components/engine/integration-cli/docker_cli_external_graphdriver_unix_test.go index 3265336d68d..e356154049b 100644 --- a/components/engine/integration-cli/docker_cli_external_graphdriver_unix_test.go +++ b/components/engine/integration-cli/docker_cli_external_graphdriver_unix_test.go @@ -347,7 +347,7 @@ func (s *DockerExternalGraphdriverSuite) TearDownSuite(c *check.C) { } func (s *DockerExternalGraphdriverSuite) TestExternalGraphDriver(c *check.C) { - testRequires(c, ExperimentalDaemon) + testRequires(c, ExperimentalDaemon, SameHostDaemon) s.testExternalGraphDriver("test-external-graph-driver", "spec", c) s.testExternalGraphDriver("json-external-graph-driver", "json", c) @@ -395,7 +395,7 @@ func (s *DockerExternalGraphdriverSuite) testExternalGraphDriver(name string, ex } func (s *DockerExternalGraphdriverSuite) TestExternalGraphDriverPull(c *check.C) { - testRequires(c, Network, ExperimentalDaemon) + testRequires(c, Network, ExperimentalDaemon, SameHostDaemon) s.d.Start(c) diff --git a/components/engine/integration-cli/docker_experimental_network_test.go b/components/engine/integration-cli/docker_experimental_network_test.go index fb20331631a..a982036d134 100644 --- a/components/engine/integration-cli/docker_experimental_network_test.go +++ b/components/engine/integration-cli/docker_experimental_network_test.go @@ -55,7 +55,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkMacvlanPersistance(c *check.C) { func (s *DockerNetworkSuite) TestDockerNetworkIpvlanPersistance(c *check.C) { // verify the driver automatically provisions the 802.1q link (di-dummy0.70) - testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) + testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon, SameHostDaemon) // master dummy interface 'di' notation represent 'docker ipvlan' master := "di-dummy0" // simulate the master link the vlan tagged subinterface parent link will use @@ -87,7 +87,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkMacvlanSubIntCreate(c *check.C) { func (s *DockerNetworkSuite) TestDockerNetworkIpvlanSubIntCreate(c *check.C) { // verify the driver automatically provisions the 802.1q link (di-dummy0.50) - testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) + testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon, SameHostDaemon) // master dummy interface 'dm' abbreviation represents 'docker ipvlan' master := "di-dummy0" // simulate the master link the vlan tagged subinterface parent link will use @@ -119,7 +119,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkMacvlanOverlapParent(c *check.C) { func (s *DockerNetworkSuite) TestDockerNetworkIpvlanOverlapParent(c *check.C) { // verify the same parent interface cannot be used if already in use by an existing network - testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) + testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon, SameHostDaemon) // master dummy interface 'dm' abbreviation represents 'docker ipvlan' master := "di-dummy0" createMasterDummy(c, master) diff --git a/components/engine/integration/build/build_test.go b/components/engine/integration/build/build_test.go index d8cb298cd46..a3f283e69e9 100644 --- a/components/engine/integration/build/build_test.go +++ b/components/engine/integration/build/build_test.go @@ -5,7 +5,6 @@ import ( "bytes" "context" "encoding/json" - "fmt" "io" "io/ioutil" "strings" @@ -249,6 +248,7 @@ RUN cat somefile` // #35403 #36122 func TestBuildUncleanTarFilenames(t *testing.T) { + skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.37"), "broken in earlier versions") ctx := context.TODO() defer setupTest(t)() @@ -307,9 +307,7 @@ COPY bar /` // docker/for-linux#135 // #35641 func TestBuildMultiStageLayerLeak(t *testing.T) { - fmt.Println(testEnv.DaemonAPIVersion()) - skip.IfCondition(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.38"), - "Don't run on API lower than 1.38 as it has been fixed starting from that version") + skip.IfCondition(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.37"), "broken in earlier versions") ctx := context.TODO() defer setupTest(t)() diff --git a/components/engine/integration/container/logs_test.go b/components/engine/integration/container/logs_test.go index 5a644e5c399..6b6528a7edf 100644 --- a/components/engine/integration/container/logs_test.go +++ b/components/engine/integration/container/logs_test.go @@ -10,11 +10,14 @@ import ( "github.com/docker/docker/integration/internal/request" "github.com/docker/docker/pkg/stdcopy" "github.com/gotestyourself/gotestyourself/assert" + "github.com/gotestyourself/gotestyourself/skip" ) // Regression test for #35370 // Makes sure that when following we don't get an EOF error when there are no logs func TestLogsFollowTailEmpty(t *testing.T) { + // FIXME(vdemeester) fails on a e2e run on linux... + skip.IfCondition(t, testEnv.IsRemoteDaemon()) defer setupTest(t)() client := request.NewAPIClient(t) ctx := context.Background() diff --git a/components/engine/integration/container/mounts_linux_test.go b/components/engine/integration/container/mounts_linux_test.go index e15786f8a6c..cdde06a9eff 100644 --- a/components/engine/integration/container/mounts_linux_test.go +++ b/components/engine/integration/container/mounts_linux_test.go @@ -155,6 +155,7 @@ func TestContainerNetworkMountsNoChown(t *testing.T) { } func TestMountDaemonRoot(t *testing.T) { + skip.If(t, testEnv.DaemonInfo.OSType != "linux" || testEnv.IsRemoteDaemon()) t.Parallel() client := request.NewAPIClient(t) diff --git a/components/engine/integration/container/ps_test.go b/components/engine/integration/container/ps_test.go index 4dacef16527..2e8f3469d5d 100644 --- a/components/engine/integration/container/ps_test.go +++ b/components/engine/integration/container/ps_test.go @@ -17,10 +17,9 @@ func TestPsFilter(t *testing.T) { client := request.NewAPIClient(t) ctx := context.Background() - prev := container.Create(t, ctx, client, container.WithName("prev-"+t.Name())) - topContainerName := "top-" + t.Name() - container.Create(t, ctx, client, container.WithName(topContainerName)) - next := container.Create(t, ctx, client, container.WithName("next-"+t.Name())) + prev := container.Create(t, ctx, client) + top := container.Create(t, ctx, client) + next := container.Create(t, ctx, client) containerIDs := func(containers []types.Container) []string { entries := []string{} @@ -31,7 +30,7 @@ func TestPsFilter(t *testing.T) { } f1 := filters.NewArgs() - f1.Add("since", topContainerName) + f1.Add("since", top) q1, err := client.ContainerList(ctx, types.ContainerListOptions{ All: true, Filters: f1, @@ -40,7 +39,7 @@ func TestPsFilter(t *testing.T) { assert.Check(t, is.Contains(containerIDs(q1), next)) f2 := filters.NewArgs() - f2.Add("before", topContainerName) + f2.Add("before", top) q2, err := client.ContainerList(ctx, types.ContainerListOptions{ All: true, Filters: f2, diff --git a/components/engine/integration/volume/volume_test.go b/components/engine/integration/volume/volume_test.go index 2fe35cf5edb..4a747b6a6b1 100644 --- a/components/engine/integration/volume/volume_test.go +++ b/components/engine/integration/volume/volume_test.go @@ -13,6 +13,7 @@ import ( "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" "github.com/docker/docker/internal/testutil" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" ) @@ -36,14 +37,14 @@ func TestVolumesCreateAndList(t *testing.T) { Name: name, Mountpoint: fmt.Sprintf("%s/volumes/%s/_data", testEnv.DaemonInfo.DockerRootDir, name), } - assert.Check(t, is.DeepEqual(vol, expected)) + assert.Check(t, is.DeepEqual(vol, expected, cmpopts.EquateEmpty())) volumes, err := client.VolumeList(ctx, filters.Args{}) assert.NilError(t, err) assert.Check(t, is.Equal(len(volumes.Volumes), 1)) assert.Check(t, volumes.Volumes[0] != nil) - assert.Check(t, is.DeepEqual(*volumes.Volumes[0], expected)) + assert.Check(t, is.DeepEqual(*volumes.Volumes[0], expected, cmpopts.EquateEmpty())) } func TestVolumesRemove(t *testing.T) { @@ -96,7 +97,7 @@ func TestVolumesInspect(t *testing.T) { Name: name, Mountpoint: fmt.Sprintf("%s/volumes/%s/_data", testEnv.DaemonInfo.DockerRootDir, name), } - assert.Check(t, is.DeepEqual(vol, expected)) + assert.Check(t, is.DeepEqual(vol, expected, cmpopts.EquateEmpty())) // comparing CreatedAt field time for the new volume to now. Removing a minute from both to avoid false positive testCreatedAt, err := time.Parse(time.RFC3339, strings.TrimSpace(vol.CreatedAt)) From a29f2e130f686813d454532e025b0f7e24441ec0 Mon Sep 17 00:00:00 2001 From: Dennis Chen Date: Tue, 27 Feb 2018 06:28:29 +0000 Subject: [PATCH 16/36] Add `busybox:latest` into the frozen images Adding `busybox:latest` and `busybox:glibc` as the frozen images Signed-off-by: Dennis Chen (cherry picked from commit 3ae45c5f173d88ba621116f9e1b5611fe687e050) Signed-off-by: Sebastiaan van Stijn --- components/engine/Dockerfile | 3 ++- components/engine/Dockerfile.aarch64 | 3 ++- components/engine/Dockerfile.armhf | 3 ++- components/engine/Dockerfile.e2e | 3 ++- components/engine/Dockerfile.ppc64le | 3 ++- components/engine/Dockerfile.s390x | 3 ++- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/components/engine/Dockerfile b/components/engine/Dockerfile index 18a88e13417..221384d399f 100644 --- a/components/engine/Dockerfile +++ b/components/engine/Dockerfile @@ -182,7 +182,8 @@ RUN echo "source $PWD/hack/make/.integration-test-helpers" >> /etc/bash.bashrc COPY contrib/download-frozen-image-v2.sh /go/src/github.com/docker/docker/contrib/ RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \ buildpack-deps:jessie@sha256:dd86dced7c9cd2a724e779730f0a53f93b7ef42228d4344b25ce9a42a1486251 \ - busybox:1.27-glibc@sha256:8c8f261a462eead45ab8e610d3e8f7a1e4fd1cd9bed5bc0a0c386784ab105d8e \ + busybox:latest@sha256:bbc3a03235220b170ba48a157dd097dd1379299370e1ed99ce976df0355d24f0 \ + busybox:glibc@sha256:0b55a30394294ab23b9afd58fab94e61a923f5834fba7ddbae7f8e0c11ba85e6 \ debian:jessie@sha256:287a20c5f73087ab406e6b364833e3fb7b3ae63ca0eb3486555dc27ed32c6e60 \ hello-world:latest@sha256:be0cd392e45be79ffeffa6b05338b98ebb16c87b255f48e297ec7f98e123905c # See also ensureFrozenImagesLinux() in "integration-cli/fixtures_linux_daemon_test.go" (which needs to be updated when adding images to this list) diff --git a/components/engine/Dockerfile.aarch64 b/components/engine/Dockerfile.aarch64 index 389b00f109e..d68829e3e93 100644 --- a/components/engine/Dockerfile.aarch64 +++ b/components/engine/Dockerfile.aarch64 @@ -147,7 +147,8 @@ RUN ln -sv $PWD/contrib/completion/bash/docker /etc/bash_completion.d/docker COPY contrib/download-frozen-image-v2.sh /go/src/github.com/docker/docker/contrib/ RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \ buildpack-deps:jessie@sha256:dd86dced7c9cd2a724e779730f0a53f93b7ef42228d4344b25ce9a42a1486251 \ - busybox:1.27-glibc@sha256:8c8f261a462eead45ab8e610d3e8f7a1e4fd1cd9bed5bc0a0c386784ab105d8e \ + busybox:latest@sha256:bbc3a03235220b170ba48a157dd097dd1379299370e1ed99ce976df0355d24f0 \ + busybox:glibc@sha256:0b55a30394294ab23b9afd58fab94e61a923f5834fba7ddbae7f8e0c11ba85e6 \ debian:jessie@sha256:287a20c5f73087ab406e6b364833e3fb7b3ae63ca0eb3486555dc27ed32c6e60 \ hello-world:latest@sha256:be0cd392e45be79ffeffa6b05338b98ebb16c87b255f48e297ec7f98e123905c # See also ensureFrozenImagesLinux() in "integration-cli/fixtures_linux_daemon_test.go" (which needs to be updated when adding images to this list) diff --git a/components/engine/Dockerfile.armhf b/components/engine/Dockerfile.armhf index b640396aee2..b45ebdb289a 100644 --- a/components/engine/Dockerfile.armhf +++ b/components/engine/Dockerfile.armhf @@ -133,7 +133,8 @@ RUN ln -sv $PWD/contrib/completion/bash/docker /etc/bash_completion.d/docker COPY contrib/download-frozen-image-v2.sh /go/src/github.com/docker/docker/contrib/ RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \ buildpack-deps:jessie@sha256:dd86dced7c9cd2a724e779730f0a53f93b7ef42228d4344b25ce9a42a1486251 \ - busybox:1.27-glibc@sha256:8c8f261a462eead45ab8e610d3e8f7a1e4fd1cd9bed5bc0a0c386784ab105d8e \ + busybox:latest@sha256:bbc3a03235220b170ba48a157dd097dd1379299370e1ed99ce976df0355d24f0 \ + busybox:glibc@sha256:0b55a30394294ab23b9afd58fab94e61a923f5834fba7ddbae7f8e0c11ba85e6 \ debian:jessie@sha256:287a20c5f73087ab406e6b364833e3fb7b3ae63ca0eb3486555dc27ed32c6e60 \ hello-world:latest@sha256:be0cd392e45be79ffeffa6b05338b98ebb16c87b255f48e297ec7f98e123905c # See also ensureFrozenImagesLinux() in "integration-cli/fixtures_linux_daemon_test.go" (which needs to be updated when adding images to this list) diff --git a/components/engine/Dockerfile.e2e b/components/engine/Dockerfile.e2e index 07635acef9b..1e49157cd16 100644 --- a/components/engine/Dockerfile.e2e +++ b/components/engine/Dockerfile.e2e @@ -17,7 +17,8 @@ WORKDIR /go/src/github.com/docker/docker/ COPY contrib/download-frozen-image-v2.sh contrib/download-frozen-image-v2.sh RUN contrib/download-frozen-image-v2.sh /output/docker-frozen-images \ buildpack-deps:jessie@sha256:dd86dced7c9cd2a724e779730f0a53f93b7ef42228d4344b25ce9a42a1486251 \ - busybox:1.27-glibc@sha256:8c8f261a462eead45ab8e610d3e8f7a1e4fd1cd9bed5bc0a0c386784ab105d8e \ + busybox:latest@sha256:bbc3a03235220b170ba48a157dd097dd1379299370e1ed99ce976df0355d24f0 \ + busybox:glibc@sha256:0b55a30394294ab23b9afd58fab94e61a923f5834fba7ddbae7f8e0c11ba85e6 \ debian:jessie@sha256:287a20c5f73087ab406e6b364833e3fb7b3ae63ca0eb3486555dc27ed32c6e60 \ hello-world:latest@sha256:be0cd392e45be79ffeffa6b05338b98ebb16c87b255f48e297ec7f98e123905c diff --git a/components/engine/Dockerfile.ppc64le b/components/engine/Dockerfile.ppc64le index 97a2fa995f8..1736f990c8f 100644 --- a/components/engine/Dockerfile.ppc64le +++ b/components/engine/Dockerfile.ppc64le @@ -131,7 +131,8 @@ RUN ln -sv $PWD/contrib/completion/bash/docker /etc/bash_completion.d/docker COPY contrib/download-frozen-image-v2.sh /go/src/github.com/docker/docker/contrib/ RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \ buildpack-deps:jessie@sha256:dd86dced7c9cd2a724e779730f0a53f93b7ef42228d4344b25ce9a42a1486251 \ - busybox:1.27-glibc@sha256:8c8f261a462eead45ab8e610d3e8f7a1e4fd1cd9bed5bc0a0c386784ab105d8e \ + busybox:latest@sha256:bbc3a03235220b170ba48a157dd097dd1379299370e1ed99ce976df0355d24f0 \ + busybox:glibc@sha256:0b55a30394294ab23b9afd58fab94e61a923f5834fba7ddbae7f8e0c11ba85e6 \ debian:jessie@sha256:287a20c5f73087ab406e6b364833e3fb7b3ae63ca0eb3486555dc27ed32c6e60 \ hello-world:latest@sha256:be0cd392e45be79ffeffa6b05338b98ebb16c87b255f48e297ec7f98e123905c # See also ensureFrozenImagesLinux() in "integration-cli/fixtures_linux_daemon_test.go" (which needs to be updated when adding images to this list) diff --git a/components/engine/Dockerfile.s390x b/components/engine/Dockerfile.s390x index 2302750c9cc..552f43005af 100644 --- a/components/engine/Dockerfile.s390x +++ b/components/engine/Dockerfile.s390x @@ -125,7 +125,8 @@ RUN ln -sv $PWD/contrib/completion/bash/docker /etc/bash_completion.d/docker COPY contrib/download-frozen-image-v2.sh /go/src/github.com/docker/docker/contrib/ RUN ./contrib/download-frozen-image-v2.sh /docker-frozen-images \ buildpack-deps:jessie@sha256:dd86dced7c9cd2a724e779730f0a53f93b7ef42228d4344b25ce9a42a1486251 \ - busybox:1.27-glibc@sha256:8c8f261a462eead45ab8e610d3e8f7a1e4fd1cd9bed5bc0a0c386784ab105d8e \ + busybox:latest@sha256:bbc3a03235220b170ba48a157dd097dd1379299370e1ed99ce976df0355d24f0 \ + busybox:glibc@sha256:0b55a30394294ab23b9afd58fab94e61a923f5834fba7ddbae7f8e0c11ba85e6 \ debian:jessie@sha256:287a20c5f73087ab406e6b364833e3fb7b3ae63ca0eb3486555dc27ed32c6e60 \ hello-world:latest@sha256:be0cd392e45be79ffeffa6b05338b98ebb16c87b255f48e297ec7f98e123905c # See also ensureFrozenImagesLinux() in "integration-cli/fixtures_linux_daemon_test.go" (which needs to be updated when adding images to this list) From 2c0117e2680c46cdb2a9971a6fb35953e570e7f8 Mon Sep 17 00:00:00 2001 From: Dennis Chen Date: Tue, 27 Feb 2018 06:49:30 +0000 Subject: [PATCH 17/36] Network testing with `busybox:glibc` Using the `busybox:glibc` instead of `busybox:latest` to the network related test cases (`ping` issue). Signed-off-by: Dennis Chen (cherry picked from commit 0d31dee5ec724731607e277a415b1ca4ecb7b2c4) Signed-off-by: Sebastiaan van Stijn --- .../integration-cli/docker_api_swarm_test.go | 2 + .../docker_cli_network_unix_test.go | 14 ++--- .../integration-cli/docker_cli_run_test.go | 4 +- .../integration-cli/docker_cli_swarm_test.go | 6 +-- .../docker_experimental_network_test.go | 52 +++++++++---------- .../integration-cli/fixtures/load/frozen.go | 3 -- .../internal/test/environment/protect.go | 2 +- 7 files changed, 41 insertions(+), 42 deletions(-) diff --git a/components/engine/integration-cli/docker_api_swarm_test.go b/components/engine/integration-cli/docker_api_swarm_test.go index 2f54c3816e1..2ba69acdb89 100644 --- a/components/engine/integration-cli/docker_api_swarm_test.go +++ b/components/engine/integration-cli/docker_api_swarm_test.go @@ -910,6 +910,8 @@ func (s *DockerSwarmSuite) TestAPIDuplicateNetworks(c *check.C) { // Test case for 30178 func (s *DockerSwarmSuite) TestAPISwarmHealthcheckNone(c *check.C) { + // Issue #36386 can be a independent one, which is worth further investigation. + c.Skip("Root cause of Issue #36386 is needed") d := s.AddDaemon(c, true, true) out, err := d.Cmd("network", "create", "-d", "overlay", "lb") diff --git a/components/engine/integration-cli/docker_cli_network_unix_test.go b/components/engine/integration-cli/docker_cli_network_unix_test.go index 90e4f6c1f25..4e9edba5a5b 100644 --- a/components/engine/integration-cli/docker_cli_network_unix_test.go +++ b/components/engine/integration-cli/docker_cli_network_unix_test.go @@ -1541,10 +1541,10 @@ func (s *DockerSuite) TestUserDefinedNetworkConnectDisconnectAlias(c *check.C) { dockerCmd(c, "network", "create", "-d", "bridge", "net1") dockerCmd(c, "network", "create", "-d", "bridge", "net2") - cid, _ := dockerCmd(c, "run", "-d", "--net=net1", "--name=first", "--net-alias=foo", "busybox", "top") + cid, _ := dockerCmd(c, "run", "-d", "--net=net1", "--name=first", "--net-alias=foo", "busybox:glibc", "top") c.Assert(waitRun("first"), check.IsNil) - dockerCmd(c, "run", "-d", "--net=net1", "--name=second", "busybox", "top") + dockerCmd(c, "run", "-d", "--net=net1", "--name=second", "busybox:glibc", "top") c.Assert(waitRun("second"), check.IsNil) // ping first container and its alias @@ -1581,7 +1581,7 @@ func (s *DockerSuite) TestUserDefinedNetworkConnectDisconnectAlias(c *check.C) { c.Assert(err, check.IsNil) // verify the alias option is rejected when running on predefined network - out, _, err := dockerCmdWithError("run", "--rm", "--name=any", "--net-alias=any", "busybox", "top") + out, _, err := dockerCmdWithError("run", "--rm", "--name=any", "--net-alias=any", "busybox:glibc", "top") c.Assert(err, checker.NotNil, check.Commentf("out: %s", out)) c.Assert(out, checker.Contains, runconfig.ErrUnsupportedNetworkAndAlias.Error()) @@ -1595,10 +1595,10 @@ func (s *DockerSuite) TestUserDefinedNetworkConnectivity(c *check.C) { testRequires(c, DaemonIsLinux, NotUserNamespace) dockerCmd(c, "network", "create", "-d", "bridge", "br.net1") - dockerCmd(c, "run", "-d", "--net=br.net1", "--name=c1.net1", "busybox", "top") + dockerCmd(c, "run", "-d", "--net=br.net1", "--name=c1.net1", "busybox:glibc", "top") c.Assert(waitRun("c1.net1"), check.IsNil) - dockerCmd(c, "run", "-d", "--net=br.net1", "--name=c2.net1", "busybox", "top") + dockerCmd(c, "run", "-d", "--net=br.net1", "--name=c2.net1", "busybox:glibc", "top") c.Assert(waitRun("c2.net1"), check.IsNil) // ping first container by its unqualified name @@ -1643,9 +1643,9 @@ func (s *DockerSuite) TestDockerNetworkInternalMode(c *check.C) { nr := getNetworkResource(c, "internal") c.Assert(nr.Internal, checker.True) - dockerCmd(c, "run", "-d", "--net=internal", "--name=first", "busybox", "top") + dockerCmd(c, "run", "-d", "--net=internal", "--name=first", "busybox:glibc", "top") c.Assert(waitRun("first"), check.IsNil) - dockerCmd(c, "run", "-d", "--net=internal", "--name=second", "busybox", "top") + dockerCmd(c, "run", "-d", "--net=internal", "--name=second", "busybox:glibc", "top") c.Assert(waitRun("second"), check.IsNil) out, _, err := dockerCmdWithError("exec", "first", "ping", "-W", "4", "-c", "1", "www.google.com") c.Assert(err, check.NotNil) diff --git a/components/engine/integration-cli/docker_cli_run_test.go b/components/engine/integration-cli/docker_cli_run_test.go index 4f71cc0f452..35756b27126 100644 --- a/components/engine/integration-cli/docker_cli_run_test.go +++ b/components/engine/integration-cli/docker_cli_run_test.go @@ -294,7 +294,7 @@ func (s *DockerSuite) TestUserDefinedNetworkAlias(c *check.C) { testRequires(c, DaemonIsLinux, NotUserNamespace, NotArm) dockerCmd(c, "network", "create", "-d", "bridge", "net1") - cid1, _ := dockerCmd(c, "run", "-d", "--net=net1", "--name=first", "--net-alias=foo1", "--net-alias=foo2", "busybox", "top") + cid1, _ := dockerCmd(c, "run", "-d", "--net=net1", "--name=first", "--net-alias=foo1", "--net-alias=foo2", "busybox:glibc", "top") c.Assert(waitRun("first"), check.IsNil) // Check if default short-id alias is added automatically @@ -302,7 +302,7 @@ func (s *DockerSuite) TestUserDefinedNetworkAlias(c *check.C) { aliases := inspectField(c, id, "NetworkSettings.Networks.net1.Aliases") c.Assert(aliases, checker.Contains, stringid.TruncateID(id)) - cid2, _ := dockerCmd(c, "run", "-d", "--net=net1", "--name=second", "busybox", "top") + cid2, _ := dockerCmd(c, "run", "-d", "--net=net1", "--name=second", "busybox:glibc", "top") c.Assert(waitRun("second"), check.IsNil) // Check if default short-id alias is added automatically diff --git a/components/engine/integration-cli/docker_cli_swarm_test.go b/components/engine/integration-cli/docker_cli_swarm_test.go index 5ee3881bc25..4b3358255fd 100644 --- a/components/engine/integration-cli/docker_cli_swarm_test.go +++ b/components/engine/integration-cli/docker_cli_swarm_test.go @@ -345,13 +345,13 @@ func (s *DockerSwarmSuite) TestSwarmContainerEndpointOptions(c *check.C) { c.Assert(err, checker.IsNil, check.Commentf(out)) c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") - _, err = d.Cmd("run", "-d", "--net=foo", "--name=first", "--net-alias=first-alias", "busybox", "top") + _, err = d.Cmd("run", "-d", "--net=foo", "--name=first", "--net-alias=first-alias", "busybox:glibc", "top") c.Assert(err, checker.IsNil, check.Commentf(out)) - _, err = d.Cmd("run", "-d", "--net=foo", "--name=second", "busybox", "top") + _, err = d.Cmd("run", "-d", "--net=foo", "--name=second", "busybox:glibc", "top") c.Assert(err, checker.IsNil, check.Commentf(out)) - _, err = d.Cmd("run", "-d", "--net=foo", "--net-alias=third-alias", "busybox", "top") + _, err = d.Cmd("run", "-d", "--net=foo", "--net-alias=third-alias", "busybox:glibc", "top") c.Assert(err, checker.IsNil, check.Commentf(out)) // ping first container and its alias, also ping third and anonymous container by its alias diff --git a/components/engine/integration-cli/docker_experimental_network_test.go b/components/engine/integration-cli/docker_experimental_network_test.go index a982036d134..9f1a21cf4b5 100644 --- a/components/engine/integration-cli/docker_experimental_network_test.go +++ b/components/engine/integration-cli/docker_experimental_network_test.go @@ -143,8 +143,8 @@ func (s *DockerNetworkSuite) TestDockerNetworkMacvlanMultiSubnet(c *check.C) { // Ensure the network was created assertNwIsAvailable(c, "dualstackbridge") // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.100.0/24 and 2001:db8:abc2::/64 - dockerCmd(c, "run", "-d", "--net=dualstackbridge", "--name=first", "--ip", "172.28.100.20", "--ip6", "2001:db8:abc2::20", "busybox", "top") - dockerCmd(c, "run", "-d", "--net=dualstackbridge", "--name=second", "--ip", "172.28.100.21", "--ip6", "2001:db8:abc2::21", "busybox", "top") + dockerCmd(c, "run", "-d", "--net=dualstackbridge", "--name=first", "--ip", "172.28.100.20", "--ip6", "2001:db8:abc2::20", "busybox:glibc", "top") + dockerCmd(c, "run", "-d", "--net=dualstackbridge", "--name=second", "--ip", "172.28.100.21", "--ip6", "2001:db8:abc2::21", "busybox:glibc", "top") // Inspect and store the v4 address from specified container on the network dualstackbridge ip := inspectField(c, "first", "NetworkSettings.Networks.dualstackbridge.IPAddress") @@ -160,8 +160,8 @@ func (s *DockerNetworkSuite) TestDockerNetworkMacvlanMultiSubnet(c *check.C) { c.Assert(err, check.IsNil) // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.102.0/24 and 2001:db8:abc4::/64 - dockerCmd(c, "run", "-d", "--net=dualstackbridge", "--name=third", "--ip", "172.28.102.20", "--ip6", "2001:db8:abc4::20", "busybox", "top") - dockerCmd(c, "run", "-d", "--net=dualstackbridge", "--name=fourth", "--ip", "172.28.102.21", "--ip6", "2001:db8:abc4::21", "busybox", "top") + dockerCmd(c, "run", "-d", "--net=dualstackbridge", "--name=third", "--ip", "172.28.102.20", "--ip6", "2001:db8:abc4::20", "busybox:glibc", "top") + dockerCmd(c, "run", "-d", "--net=dualstackbridge", "--name=fourth", "--ip", "172.28.102.21", "--ip6", "2001:db8:abc4::21", "busybox:glibc", "top") // Inspect and store the v4 address from specified container on the network dualstackbridge ip = inspectField(c, "third", "NetworkSettings.Networks.dualstackbridge.IPAddress") @@ -198,8 +198,8 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanL2MultiSubnet(c *check.C) { // Ensure the network was created assertNwIsAvailable(c, "dualstackl2") // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.200.0/24 and 2001:db8:abc8::/64 - dockerCmd(c, "run", "-d", "--net=dualstackl2", "--name=first", "--ip", "172.28.200.20", "--ip6", "2001:db8:abc8::20", "busybox", "top") - dockerCmd(c, "run", "-d", "--net=dualstackl2", "--name=second", "--ip", "172.28.200.21", "--ip6", "2001:db8:abc8::21", "busybox", "top") + dockerCmd(c, "run", "-d", "--net=dualstackl2", "--name=first", "--ip", "172.28.200.20", "--ip6", "2001:db8:abc8::20", "busybox:glibc", "top") + dockerCmd(c, "run", "-d", "--net=dualstackl2", "--name=second", "--ip", "172.28.200.21", "--ip6", "2001:db8:abc8::21", "busybox:glibc", "top") // Inspect and store the v4 address from specified container on the network dualstackl2 ip := inspectField(c, "first", "NetworkSettings.Networks.dualstackl2.IPAddress") @@ -214,8 +214,8 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanL2MultiSubnet(c *check.C) { c.Assert(err, check.IsNil) // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.202.0/24 and 2001:db8:abc6::/64 - dockerCmd(c, "run", "-d", "--net=dualstackl2", "--name=third", "--ip", "172.28.202.20", "--ip6", "2001:db8:abc6::20", "busybox", "top") - dockerCmd(c, "run", "-d", "--net=dualstackl2", "--name=fourth", "--ip", "172.28.202.21", "--ip6", "2001:db8:abc6::21", "busybox", "top") + dockerCmd(c, "run", "-d", "--net=dualstackl2", "--name=third", "--ip", "172.28.202.20", "--ip6", "2001:db8:abc6::20", "busybox:glibc", "top") + dockerCmd(c, "run", "-d", "--net=dualstackl2", "--name=fourth", "--ip", "172.28.202.21", "--ip6", "2001:db8:abc6::21", "busybox:glibc", "top") // Inspect and store the v4 address from specified container on the network dualstackl2 ip = inspectField(c, "third", "NetworkSettings.Networks.dualstackl2.IPAddress") @@ -253,8 +253,8 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanL3MultiSubnet(c *check.C) { assertNwIsAvailable(c, "dualstackl3") // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.10.0/24 and 2001:db8:abc9::/64 - dockerCmd(c, "run", "-d", "--net=dualstackl3", "--name=first", "--ip", "172.28.10.20", "--ip6", "2001:db8:abc9::20", "busybox", "top") - dockerCmd(c, "run", "-d", "--net=dualstackl3", "--name=second", "--ip", "172.28.10.21", "--ip6", "2001:db8:abc9::21", "busybox", "top") + dockerCmd(c, "run", "-d", "--net=dualstackl3", "--name=first", "--ip", "172.28.10.20", "--ip6", "2001:db8:abc9::20", "busybox:glibc", "top") + dockerCmd(c, "run", "-d", "--net=dualstackl3", "--name=second", "--ip", "172.28.10.21", "--ip6", "2001:db8:abc9::21", "busybox:glibc", "top") // Inspect and store the v4 address from specified container on the network dualstackl3 ip := inspectField(c, "first", "NetworkSettings.Networks.dualstackl3.IPAddress") @@ -269,8 +269,8 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanL3MultiSubnet(c *check.C) { c.Assert(err, check.IsNil) // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.12.0/24 and 2001:db8:abc7::/64 - dockerCmd(c, "run", "-d", "--net=dualstackl3", "--name=third", "--ip", "172.28.12.20", "--ip6", "2001:db8:abc7::20", "busybox", "top") - dockerCmd(c, "run", "-d", "--net=dualstackl3", "--name=fourth", "--ip", "172.28.12.21", "--ip6", "2001:db8:abc7::21", "busybox", "top") + dockerCmd(c, "run", "-d", "--net=dualstackl3", "--name=third", "--ip", "172.28.12.20", "--ip6", "2001:db8:abc7::20", "busybox:glibc", "top") + dockerCmd(c, "run", "-d", "--net=dualstackl3", "--name=fourth", "--ip", "172.28.12.21", "--ip6", "2001:db8:abc7::21", "busybox:glibc", "top") // Inspect and store the v4 address from specified container on the network dualstackl3 ip = inspectField(c, "third", "NetworkSettings.Networks.dualstackl3.IPAddress") @@ -356,9 +356,9 @@ func (s *DockerSuite) TestDockerNetworkMacVlanBridgeNilParent(c *check.C) { assertNwIsAvailable(c, "dm-nil-parent") // start two containers on the same subnet - dockerCmd(c, "run", "-d", "--net=dm-nil-parent", "--name=first", "busybox", "top") + dockerCmd(c, "run", "-d", "--net=dm-nil-parent", "--name=first", "busybox:glibc", "top") c.Assert(waitRun("first"), check.IsNil) - dockerCmd(c, "run", "-d", "--net=dm-nil-parent", "--name=second", "busybox", "top") + dockerCmd(c, "run", "-d", "--net=dm-nil-parent", "--name=second", "busybox:glibc", "top") c.Assert(waitRun("second"), check.IsNil) // intra-network communications should succeed @@ -375,9 +375,9 @@ func (s *DockerSuite) TestDockerNetworkMacVlanBridgeInternalMode(c *check.C) { c.Assert(nr.Internal, checker.True) // start two containers on the same subnet - cli.DockerCmd(c, "run", "-d", "--net=dm-internal", "--name=first", "busybox", "top") + cli.DockerCmd(c, "run", "-d", "--net=dm-internal", "--name=first", "busybox:glibc", "top") c.Assert(waitRun("first"), check.IsNil) - cli.DockerCmd(c, "run", "-d", "--net=dm-internal", "--name=second", "busybox", "top") + cli.DockerCmd(c, "run", "-d", "--net=dm-internal", "--name=second", "busybox:glibc", "top") c.Assert(waitRun("second"), check.IsNil) // access outside of the network should fail @@ -395,9 +395,9 @@ func (s *DockerSuite) TestDockerNetworkIpvlanL2NilParent(c *check.C) { assertNwIsAvailable(c, "di-nil-parent") // start two containers on the same subnet - dockerCmd(c, "run", "-d", "--net=di-nil-parent", "--name=first", "busybox", "top") + dockerCmd(c, "run", "-d", "--net=di-nil-parent", "--name=first", "busybox:glibc", "top") c.Assert(waitRun("first"), check.IsNil) - dockerCmd(c, "run", "-d", "--net=di-nil-parent", "--name=second", "busybox", "top") + dockerCmd(c, "run", "-d", "--net=di-nil-parent", "--name=second", "busybox:glibc", "top") c.Assert(waitRun("second"), check.IsNil) // intra-network communications should succeed @@ -414,9 +414,9 @@ func (s *DockerSuite) TestDockerNetworkIpvlanL2InternalMode(c *check.C) { c.Assert(nr.Internal, checker.True) // start two containers on the same subnet - cli.DockerCmd(c, "run", "-d", "--net=di-internal", "--name=first", "busybox", "top") + cli.DockerCmd(c, "run", "-d", "--net=di-internal", "--name=first", "busybox:glibc", "top") c.Assert(waitRun("first"), check.IsNil) - cli.DockerCmd(c, "run", "-d", "--net=di-internal", "--name=second", "busybox", "top") + cli.DockerCmd(c, "run", "-d", "--net=di-internal", "--name=second", "busybox:glibc", "top") c.Assert(waitRun("second"), check.IsNil) // access outside of the network should fail @@ -434,9 +434,9 @@ func (s *DockerSuite) TestDockerNetworkIpvlanL3NilParent(c *check.C) { assertNwIsAvailable(c, "di-nil-parent-l3") // start two containers on separate subnets - dockerCmd(c, "run", "-d", "--ip=172.28.220.10", "--net=di-nil-parent-l3", "--name=first", "busybox", "top") + dockerCmd(c, "run", "-d", "--ip=172.28.220.10", "--net=di-nil-parent-l3", "--name=first", "busybox:glibc", "top") c.Assert(waitRun("first"), check.IsNil) - dockerCmd(c, "run", "-d", "--ip=172.28.230.10", "--net=di-nil-parent-l3", "--name=second", "busybox", "top") + dockerCmd(c, "run", "-d", "--ip=172.28.230.10", "--net=di-nil-parent-l3", "--name=second", "busybox:glibc", "top") c.Assert(waitRun("second"), check.IsNil) // intra-network communications should succeed @@ -454,9 +454,9 @@ func (s *DockerSuite) TestDockerNetworkIpvlanL3InternalMode(c *check.C) { c.Assert(nr.Internal, checker.True) // start two containers on separate subnets - cli.DockerCmd(c, "run", "-d", "--ip=172.28.220.10", "--net=di-internal-l3", "--name=first", "busybox", "top") + cli.DockerCmd(c, "run", "-d", "--ip=172.28.220.10", "--net=di-internal-l3", "--name=first", "busybox:glibc", "top") c.Assert(waitRun("first"), check.IsNil) - cli.DockerCmd(c, "run", "-d", "--ip=172.28.230.10", "--net=di-internal-l3", "--name=second", "busybox", "top") + cli.DockerCmd(c, "run", "-d", "--ip=172.28.230.10", "--net=di-internal-l3", "--name=second", "busybox:glibc", "top") c.Assert(waitRun("second"), check.IsNil) // access outside of the network should fail @@ -496,9 +496,9 @@ func (s *DockerSuite) TestDockerNetworkMacVlanSubinterface(c *check.C) { assertNwIsAvailable(c, netName) // start containers on 802.1q tagged '-o parent' sub-interface - dockerCmd(c, "run", "-d", "--net=dm-subinterface", "--name=first", "busybox", "top") + dockerCmd(c, "run", "-d", "--net=dm-subinterface", "--name=first", "busybox:glibc", "top") c.Assert(waitRun("first"), check.IsNil) - dockerCmd(c, "run", "-d", "--net=dm-subinterface", "--name=second", "busybox", "top") + dockerCmd(c, "run", "-d", "--net=dm-subinterface", "--name=second", "busybox:glibc", "top") c.Assert(waitRun("second"), check.IsNil) // verify containers can communicate _, _, err := dockerCmdWithError("exec", "second", "ping", "-c", "1", "first") diff --git a/components/engine/integration-cli/fixtures/load/frozen.go b/components/engine/integration-cli/fixtures/load/frozen.go index 7e104fe76c4..5701a216a20 100644 --- a/components/engine/integration-cli/fixtures/load/frozen.go +++ b/components/engine/integration-cli/fixtures/load/frozen.go @@ -37,9 +37,6 @@ func FrozenImagesLinux(client client.APIClient, images ...string) error { if img == "hello-world:frozen" { srcName = "hello-world:latest" } - if img == "busybox:1.27-glibc" { - img = "busybox:latest" - } loadImages = append(loadImages, struct{ srcName, destName string }{ srcName: srcName, destName: img, diff --git a/components/engine/internal/test/environment/protect.go b/components/engine/internal/test/environment/protect.go index 3b60763f6bc..3dfe606cea8 100644 --- a/components/engine/internal/test/environment/protect.go +++ b/components/engine/internal/test/environment/protect.go @@ -9,7 +9,7 @@ import ( "github.com/gotestyourself/gotestyourself/assert" ) -var frozenImages = []string{"busybox:1.27-glibc", "hello-world:frozen", "debian:jessie"} +var frozenImages = []string{"busybox:latest", "busybox:glibc", "hello-world:frozen", "debian:jessie"} type protectedElements struct { containers map[string]struct{} From 362aa8f58a65e41f3165210666abccfb68054fbe Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Wed, 28 Mar 2018 10:47:11 +0200 Subject: [PATCH 18/36] Migrate test-integration-cli experimental macvlan test to integration All `Macvlan` related test on `DockerSuite` and `DockerNetworkSuite` are migrated to `macvlan_test.go`. Also, as `macvlan` seems to be out of experimental, this removes the *skip* when the run is not experimental (and doesn't start a daemon with experimental either). The end goal being to remove the `experimental` builds. Signed-off-by: Vincent Demeester (cherry picked from commit ef5bc603266b9fa5df525319d67329ebc14a8ee7) Signed-off-by: Sebastiaan van Stijn --- .../docker_experimental_network_test.go | 193 ---------- .../integration/internal/container/ops.go | 27 ++ .../integration/network/macvlan_test.go | 354 ++++++++++++++++++ 3 files changed, 381 insertions(+), 193 deletions(-) create mode 100644 components/engine/integration/network/macvlan_test.go diff --git a/components/engine/integration-cli/docker_experimental_network_test.go b/components/engine/integration-cli/docker_experimental_network_test.go index 9f1a21cf4b5..5fcdafcabcc 100644 --- a/components/engine/integration-cli/docker_experimental_network_test.go +++ b/components/engine/integration-cli/docker_experimental_network_test.go @@ -34,25 +34,6 @@ func checkKernelMajorVersionGreaterOrEqualThen(kernelVersion int, majorVersion i return true } -func (s *DockerNetworkSuite) TestDockerNetworkMacvlanPersistance(c *check.C) { - // verify the driver automatically provisions the 802.1q link (dm-dummy0.60) - testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) - - // master dummy interface 'dm' abbreviation represents 'docker macvlan' - master := "dm-dummy0" - // simulate the master link the vlan tagged subinterface parent link will use - createMasterDummy(c, master) - // cleanup the master interface that also collects the slave dev - defer deleteInterface(c, master) - // create a network specifying the desired sub-interface name - dockerCmd(c, "network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.60", "dm-persist") - assertNwIsAvailable(c, "dm-persist") - // Restart docker daemon to test the config has persisted to disk - s.d.Restart(c) - // verify network is recreated from persistence - assertNwIsAvailable(c, "dm-persist") -} - func (s *DockerNetworkSuite) TestDockerNetworkIpvlanPersistance(c *check.C) { // verify the driver automatically provisions the 802.1q link (di-dummy0.70) testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon, SameHostDaemon) @@ -71,20 +52,6 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanPersistance(c *check.C) { assertNwIsAvailable(c, "di-persist") } -func (s *DockerNetworkSuite) TestDockerNetworkMacvlanSubIntCreate(c *check.C) { - // verify the driver automatically provisions the 802.1q link (dm-dummy0.50) - testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) - // master dummy interface 'dm' abbreviation represents 'docker macvlan' - master := "dm-dummy0" - // simulate the master link the vlan tagged subinterface parent link will use - createMasterDummy(c, master) - // cleanup the master interface which also collects the slave dev - defer deleteInterface(c, master) - // create a network specifying the desired sub-interface name - dockerCmd(c, "network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.50", "dm-subinterface") - assertNwIsAvailable(c, "dm-subinterface") -} - func (s *DockerNetworkSuite) TestDockerNetworkIpvlanSubIntCreate(c *check.C) { // verify the driver automatically provisions the 802.1q link (di-dummy0.50) testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon, SameHostDaemon) @@ -99,24 +66,6 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanSubIntCreate(c *check.C) { assertNwIsAvailable(c, "di-subinterface") } -func (s *DockerNetworkSuite) TestDockerNetworkMacvlanOverlapParent(c *check.C) { - // verify the same parent interface cannot be used if already in use by an existing network - testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) - // master dummy interface 'dm' abbreviation represents 'docker macvlan' - master := "dm-dummy0" - createMasterDummy(c, master) - // cleanup the master interface which also collects the slave dev - defer deleteInterface(c, master) - createVlanInterface(c, master, "dm-dummy0.40", "40") - // create a network using an existing parent interface - dockerCmd(c, "network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.40", "dm-subinterface") - assertNwIsAvailable(c, "dm-subinterface") - // attempt to create another network using the same parent iface that should fail - out, _, err := dockerCmdWithError("network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.40", "dm-parent-net-overlap") - // verify that the overlap returns an error - c.Assert(err, check.NotNil, check.Commentf(out)) -} - func (s *DockerNetworkSuite) TestDockerNetworkIpvlanOverlapParent(c *check.C) { // verify the same parent interface cannot be used if already in use by an existing network testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon, SameHostDaemon) @@ -135,61 +84,6 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanOverlapParent(c *check.C) { c.Assert(err, check.NotNil, check.Commentf(out)) } -func (s *DockerNetworkSuite) TestDockerNetworkMacvlanMultiSubnet(c *check.C) { - // create a dual stack multi-subnet Macvlan bridge mode network and validate connectivity between four containers, two on each subnet - testRequires(c, DaemonIsLinux, IPv6, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) - dockerCmd(c, "network", "create", "--driver=macvlan", "--ipv6", "--subnet=172.28.100.0/24", "--subnet=172.28.102.0/24", "--gateway=172.28.102.254", - "--subnet=2001:db8:abc2::/64", "--subnet=2001:db8:abc4::/64", "--gateway=2001:db8:abc4::254", "dualstackbridge") - // Ensure the network was created - assertNwIsAvailable(c, "dualstackbridge") - // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.100.0/24 and 2001:db8:abc2::/64 - dockerCmd(c, "run", "-d", "--net=dualstackbridge", "--name=first", "--ip", "172.28.100.20", "--ip6", "2001:db8:abc2::20", "busybox:glibc", "top") - dockerCmd(c, "run", "-d", "--net=dualstackbridge", "--name=second", "--ip", "172.28.100.21", "--ip6", "2001:db8:abc2::21", "busybox:glibc", "top") - - // Inspect and store the v4 address from specified container on the network dualstackbridge - ip := inspectField(c, "first", "NetworkSettings.Networks.dualstackbridge.IPAddress") - // Inspect and store the v6 address from specified container on the network dualstackbridge - ip6 := inspectField(c, "first", "NetworkSettings.Networks.dualstackbridge.GlobalIPv6Address") - - // verify ipv4 connectivity to the explicit --ipv address second to first - _, _, err := dockerCmdWithError("exec", "second", "ping", "-c", "1", strings.TrimSpace(ip)) - c.Assert(err, check.IsNil) - // verify ipv6 connectivity to the explicit --ipv6 address second to first - c.Skip("Temporarily skipping while investigating sporadic v6 CI issues") - _, _, err = dockerCmdWithError("exec", "second", "ping6", "-c", "1", strings.TrimSpace(ip6)) - c.Assert(err, check.IsNil) - - // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.102.0/24 and 2001:db8:abc4::/64 - dockerCmd(c, "run", "-d", "--net=dualstackbridge", "--name=third", "--ip", "172.28.102.20", "--ip6", "2001:db8:abc4::20", "busybox:glibc", "top") - dockerCmd(c, "run", "-d", "--net=dualstackbridge", "--name=fourth", "--ip", "172.28.102.21", "--ip6", "2001:db8:abc4::21", "busybox:glibc", "top") - - // Inspect and store the v4 address from specified container on the network dualstackbridge - ip = inspectField(c, "third", "NetworkSettings.Networks.dualstackbridge.IPAddress") - // Inspect and store the v6 address from specified container on the network dualstackbridge - ip6 = inspectField(c, "third", "NetworkSettings.Networks.dualstackbridge.GlobalIPv6Address") - - // verify ipv4 connectivity to the explicit --ipv address from third to fourth - _, _, err = dockerCmdWithError("exec", "fourth", "ping", "-c", "1", strings.TrimSpace(ip)) - c.Assert(err, check.IsNil) - // verify ipv6 connectivity to the explicit --ipv6 address from third to fourth - _, _, err = dockerCmdWithError("exec", "fourth", "ping6", "-c", "1", strings.TrimSpace(ip6)) - c.Assert(err, check.IsNil) - - // Inspect the v4 gateway to ensure the proper default GW was assigned - ip4gw := inspectField(c, "first", "NetworkSettings.Networks.dualstackbridge.Gateway") - c.Assert(strings.TrimSpace(ip4gw), check.Equals, "172.28.100.1") - // Inspect the v6 gateway to ensure the proper default GW was assigned - ip6gw := inspectField(c, "first", "NetworkSettings.Networks.dualstackbridge.IPv6Gateway") - c.Assert(strings.TrimSpace(ip6gw), check.Equals, "2001:db8:abc2::1") - - // Inspect the v4 gateway to ensure the proper explicitly assigned default GW was assigned - ip4gw = inspectField(c, "third", "NetworkSettings.Networks.dualstackbridge.Gateway") - c.Assert(strings.TrimSpace(ip4gw), check.Equals, "172.28.102.254") - // Inspect the v6 gateway to ensure the proper explicitly assigned default GW was assigned - ip6gw = inspectField(c, "third", "NetworkSettings.Networks.dualstackbridge.IPv6Gateway") - c.Assert(strings.TrimSpace(ip6gw), check.Equals, "2001:db8:abc4::254") -} - func (s *DockerNetworkSuite) TestDockerNetworkIpvlanL2MultiSubnet(c *check.C) { // create a dual stack multi-subnet Ipvlan L2 network and validate connectivity within the subnets, two on each subnet testRequires(c, DaemonIsLinux, IPv6, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) @@ -349,45 +243,6 @@ func (s *DockerNetworkSuite) TestDockerNetworkIpvlanAddressing(c *check.C) { c.Assert(out, checker.Contains, "default dev eth0") } -func (s *DockerSuite) TestDockerNetworkMacVlanBridgeNilParent(c *check.C) { - // macvlan bridge mode - dummy parent interface is provisioned dynamically - testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) - dockerCmd(c, "network", "create", "--driver=macvlan", "dm-nil-parent") - assertNwIsAvailable(c, "dm-nil-parent") - - // start two containers on the same subnet - dockerCmd(c, "run", "-d", "--net=dm-nil-parent", "--name=first", "busybox:glibc", "top") - c.Assert(waitRun("first"), check.IsNil) - dockerCmd(c, "run", "-d", "--net=dm-nil-parent", "--name=second", "busybox:glibc", "top") - c.Assert(waitRun("second"), check.IsNil) - - // intra-network communications should succeed - _, _, err := dockerCmdWithError("exec", "second", "ping", "-c", "1", "first") - c.Assert(err, check.IsNil) -} - -func (s *DockerSuite) TestDockerNetworkMacVlanBridgeInternalMode(c *check.C) { - // macvlan bridge mode --internal containers can communicate inside the network but not externally - testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) - cli.DockerCmd(c, "network", "create", "--driver=macvlan", "--internal", "dm-internal") - assertNwIsAvailable(c, "dm-internal") - nr := getNetworkResource(c, "dm-internal") - c.Assert(nr.Internal, checker.True) - - // start two containers on the same subnet - cli.DockerCmd(c, "run", "-d", "--net=dm-internal", "--name=first", "busybox:glibc", "top") - c.Assert(waitRun("first"), check.IsNil) - cli.DockerCmd(c, "run", "-d", "--net=dm-internal", "--name=second", "busybox:glibc", "top") - c.Assert(waitRun("second"), check.IsNil) - - // access outside of the network should fail - result := cli.Docker(cli.Args("exec", "first", "ping", "-c", "1", "-w", "1", "8.8.8.8"), cli.WithTimeout(time.Second)) - result.Assert(c, icmd.Expected{Timeout: true}) - - // intra-network communications should succeed - cli.DockerCmd(c, "exec", "second", "ping", "-c", "1", "first") -} - func (s *DockerSuite) TestDockerNetworkIpvlanL2NilParent(c *check.C) { // ipvlan l2 mode - dummy parent interface is provisioned dynamically testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) @@ -466,54 +321,6 @@ func (s *DockerSuite) TestDockerNetworkIpvlanL3InternalMode(c *check.C) { cli.DockerCmd(c, "exec", "second", "ping", "-c", "1", "first") } -func (s *DockerSuite) TestDockerNetworkMacVlanExistingParent(c *check.C) { - // macvlan bridge mode - empty parent interface containers can reach each other internally but not externally - testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) - netName := "dm-parent-exists" - createMasterDummy(c, "dm-dummy0") - defer deleteInterface(c, "dm-dummy0") - //out, err := createVlanInterface(c, "dm-parent", "dm-slave", "macvlan", "bridge") - // create a network using an existing parent interface - dockerCmd(c, "network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0", netName) - assertNwIsAvailable(c, netName) - // delete the network while preserving the parent link - dockerCmd(c, "network", "rm", netName) - assertNwNotAvailable(c, netName) - // verify the network delete did not delete the predefined link - linkExists(c, "dm-dummy0") -} - -func (s *DockerSuite) TestDockerNetworkMacVlanSubinterface(c *check.C) { - // macvlan bridge mode - empty parent interface containers can reach each other internally but not externally - testRequires(c, DaemonIsLinux, macvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) - netName := "dm-subinterface" - createMasterDummy(c, "dm-dummy0") - // delete the parent interface which also collects the slave - defer deleteInterface(c, "dm-dummy0") - createVlanInterface(c, "dm-dummy0", "dm-dummy0.20", "20") - // create a network using an existing parent interface - dockerCmd(c, "network", "create", "--driver=macvlan", "-o", "parent=dm-dummy0.20", netName) - assertNwIsAvailable(c, netName) - - // start containers on 802.1q tagged '-o parent' sub-interface - dockerCmd(c, "run", "-d", "--net=dm-subinterface", "--name=first", "busybox:glibc", "top") - c.Assert(waitRun("first"), check.IsNil) - dockerCmd(c, "run", "-d", "--net=dm-subinterface", "--name=second", "busybox:glibc", "top") - c.Assert(waitRun("second"), check.IsNil) - // verify containers can communicate - _, _, err := dockerCmdWithError("exec", "second", "ping", "-c", "1", "first") - c.Assert(err, check.IsNil) - - // remove the containers - dockerCmd(c, "rm", "-f", "first") - dockerCmd(c, "rm", "-f", "second") - // delete the network while preserving the parent link - dockerCmd(c, "network", "rm", netName) - assertNwNotAvailable(c, netName) - // verify the network delete did not delete the predefined sub-interface - linkExists(c, "dm-dummy0.20") -} - func createMasterDummy(c *check.C, master string) { // ip link add type dummy icmd.RunCommand("ip", "link", "add", master, "type", "dummy").Assert(c, icmd.Success) diff --git a/components/engine/integration/internal/container/ops.go b/components/engine/integration/internal/container/ops.go index b4ad66f93dd..afbb695e7df 100644 --- a/components/engine/integration/internal/container/ops.go +++ b/components/engine/integration/internal/container/ops.go @@ -4,6 +4,7 @@ import ( "fmt" containertypes "github.com/docker/docker/api/types/container" + networktypes "github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/strslice" "github.com/docker/go-connections/nat" ) @@ -83,3 +84,29 @@ func WithBind(src, target string) func(*TestContainerConfig) { c.HostConfig.Binds = append(c.HostConfig.Binds, fmt.Sprintf("%s:%s", src, target)) } } + +// WithIPv4 sets the specified ip for the specified network of the container +func WithIPv4(network, ip string) func(*TestContainerConfig) { + return func(c *TestContainerConfig) { + if v, ok := c.NetworkingConfig.EndpointsConfig[network]; !ok || v == nil { + c.NetworkingConfig.EndpointsConfig[network] = &networktypes.EndpointSettings{} + } + if c.NetworkingConfig.EndpointsConfig[network].IPAMConfig == nil { + c.NetworkingConfig.EndpointsConfig[network].IPAMConfig = &networktypes.EndpointIPAMConfig{} + } + c.NetworkingConfig.EndpointsConfig[network].IPAMConfig.IPv4Address = ip + } +} + +// WithIPv6 sets the specified ip6 for the specified network of the container +func WithIPv6(network, ip string) func(*TestContainerConfig) { + return func(c *TestContainerConfig) { + if v, ok := c.NetworkingConfig.EndpointsConfig[network]; !ok || v == nil { + c.NetworkingConfig.EndpointsConfig[network] = &networktypes.EndpointSettings{} + } + if c.NetworkingConfig.EndpointsConfig[network].IPAMConfig == nil { + c.NetworkingConfig.EndpointsConfig[network].IPAMConfig = &networktypes.EndpointIPAMConfig{} + } + c.NetworkingConfig.EndpointsConfig[network].IPAMConfig.IPv6Address = ip + } +} diff --git a/components/engine/integration/network/macvlan_test.go b/components/engine/integration/network/macvlan_test.go new file mode 100644 index 00000000000..46945ada288 --- /dev/null +++ b/components/engine/integration/network/macvlan_test.go @@ -0,0 +1,354 @@ +package network + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/network" + "github.com/docker/docker/client" + "github.com/docker/docker/integration-cli/daemon" + "github.com/docker/docker/integration/internal/container" + "github.com/docker/docker/pkg/parsers/kernel" + "github.com/gotestyourself/gotestyourself/assert" + "github.com/gotestyourself/gotestyourself/assert/cmp" + "github.com/gotestyourself/gotestyourself/icmd" + "github.com/gotestyourself/gotestyourself/skip" +) + +func TestDockerNetworkMacvlanPersistance(t *testing.T) { + // verify the driver automatically provisions the 802.1q link (dm-dummy0.60) + skip.If(t, testEnv.DaemonInfo.OSType != "linux") + skip.If(t, testEnv.IsRemoteDaemon()) + skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") + + d := daemon.New(t, "", "dockerd", daemon.Config{}) + d.StartWithBusybox(t) + defer d.Stop(t) + + master := "dm-dummy0" + createMasterDummy(t, master) + defer deleteInterface(t, master) + + client, err := d.NewClient() + assert.NilError(t, err) + + _, err = client.NetworkCreate(context.Background(), "dm-persist", types.NetworkCreate{ + Driver: "macvlan", + Options: map[string]string{ + "parent": "dm-dummy0.60", + }, + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "dm-persist")) + d.Restart(t) + assert.Check(t, isNetworkAvailable(client, "dm-persist")) +} + +func TestDockerNetworkMacvlanOverlapParent(t *testing.T) { + // verify the same parent interface cannot be used if already in use by an existing network + skip.If(t, testEnv.DaemonInfo.OSType != "linux") + skip.If(t, testEnv.IsRemoteDaemon()) + skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") + + d := daemon.New(t, "", "dockerd", daemon.Config{}) + d.StartWithBusybox(t) + defer d.Stop(t) + + master := "dm-dummy0" + createMasterDummy(t, master) + defer deleteInterface(t, master) + + client, err := d.NewClient() + assert.NilError(t, err) + + _, err = client.NetworkCreate(context.Background(), "dm-subinterface", types.NetworkCreate{ + Driver: "macvlan", + Options: map[string]string{ + "parent": "dm-dummy0.40", + }, + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "dm-subinterface")) + + _, err = client.NetworkCreate(context.Background(), "dm-parent-net-overlap", types.NetworkCreate{ + Driver: "macvlan", + Options: map[string]string{ + "parent": "dm-dummy0.40", + }, + }) + assert.Check(t, err != nil) + // delete the network while preserving the parent link + err = client.NetworkRemove(context.Background(), "dm-subinterface") + assert.NilError(t, err) + + assert.Check(t, isNetworkNotAvailable(client, "dm-subinterface")) + // verify the network delete did not delete the predefined link + linkExists(t, "dm-dummy0") +} + +func TestDockerNetworkMacvlanSubinterface(t *testing.T) { + // verify the same parent interface cannot be used if already in use by an existing network + skip.If(t, testEnv.DaemonInfo.OSType != "linux") + skip.If(t, testEnv.IsRemoteDaemon()) + skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") + + d := daemon.New(t, "", "dockerd", daemon.Config{}) + d.StartWithBusybox(t) + defer d.Stop(t) + + master := "dm-dummy0" + createMasterDummy(t, master) + defer deleteInterface(t, master) + createVlanInterface(t, master, "dm-dummy0.20", "20") + + client, err := d.NewClient() + assert.NilError(t, err) + + _, err = client.NetworkCreate(context.Background(), "dm-subinterface", types.NetworkCreate{ + Driver: "macvlan", + Options: map[string]string{ + "parent": "dm-dummy0.20", + }, + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "dm-subinterface")) + + // delete the network while preserving the parent link + err = client.NetworkRemove(context.Background(), "dm-subinterface") + assert.NilError(t, err) + + assert.Check(t, isNetworkNotAvailable(client, "dm-subinterface")) + // verify the network delete did not delete the predefined link + linkExists(t, "dm-dummy0.20") +} + +func TestDockerNetworkMacvlanBridgeNilParent(t *testing.T) { + // macvlan bridge mode - dummy parent interface is provisioned dynamically + skip.If(t, testEnv.DaemonInfo.OSType != "linux") + skip.If(t, testEnv.IsRemoteDaemon()) + skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") + + d := daemon.New(t, "", "dockerd", daemon.Config{}) + d.StartWithBusybox(t) + defer d.Stop(t) + client, err := d.NewClient() + assert.NilError(t, err) + + _, err = client.NetworkCreate(context.Background(), "dm-nil-parent", types.NetworkCreate{ + Driver: "macvlan", + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "dm-nil-parent")) + + ctx := context.Background() + container.Run(t, ctx, client, container.WithNetworkMode("dm-nil-parent"), container.WithName(t.Name()+"first")) + id2 := container.Run(t, ctx, client, container.WithNetworkMode("dm-nil-parent"), container.WithName(t.Name()+"second")) + + _, err = container.Exec(ctx, client, id2, []string{"ping", "-c", "1", t.Name() + "first"}) + assert.Check(t, err == nil) +} + +func TestDockerNetworkMacvlanBridgeInternal(t *testing.T) { + // macvlan bridge mode - dummy parent interface is provisioned dynamically + skip.If(t, testEnv.DaemonInfo.OSType != "linux") + skip.If(t, testEnv.IsRemoteDaemon()) + skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") + + d := daemon.New(t, "", "dockerd", daemon.Config{}) + d.StartWithBusybox(t) + defer d.Stop(t) + client, err := d.NewClient() + assert.NilError(t, err) + + _, err = client.NetworkCreate(context.Background(), "dm-internal", types.NetworkCreate{ + Driver: "macvlan", + Internal: true, + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "dm-internal")) + + ctx := context.Background() + id1 := container.Run(t, ctx, client, container.WithNetworkMode("dm-internal"), container.WithName(t.Name()+"first")) + id2 := container.Run(t, ctx, client, container.WithNetworkMode("dm-internal"), container.WithName(t.Name()+"second")) + + timeoutCtx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + _, err = container.Exec(timeoutCtx, client, id1, []string{"ping", "-c", "1", "-w", "1", "8.8.8.8"}) + // FIXME(vdemeester) check the time of error ? + assert.Check(t, err != nil) + assert.Check(t, timeoutCtx.Err() == context.DeadlineExceeded) + + _, err = container.Exec(ctx, client, id2, []string{"ping", "-c", "1", t.Name() + "first"}) + assert.Check(t, err == nil) +} + +func TestDockerNetworkMacvlanMultiSubnet(t *testing.T) { + skip.If(t, testEnv.DaemonInfo.OSType != "linux") + skip.If(t, testEnv.IsRemoteDaemon()) + skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") + t.Skip("Temporarily skipping while investigating sporadic v6 CI issues") + + d := daemon.New(t, "", "dockerd", daemon.Config{}) + d.StartWithBusybox(t) + defer d.Stop(t) + client, err := d.NewClient() + assert.NilError(t, err) + + _, err = client.NetworkCreate(context.Background(), "dualstackbridge", types.NetworkCreate{ + Driver: "macvlan", + EnableIPv6: true, + IPAM: &network.IPAM{ + Config: []network.IPAMConfig{ + { + Subnet: "172.28.100.0/24", + AuxAddress: map[string]string{}, + }, + { + Subnet: "172.28.102.0/24", + Gateway: "172.28.102.54", + AuxAddress: map[string]string{}, + }, + { + Subnet: "2001:db8:abc2::/64", + AuxAddress: map[string]string{}, + }, + { + Subnet: "2001:db8:abc4::/64", + Gateway: "2001:db8:abc4::254", + AuxAddress: map[string]string{}, + }, + }, + }, + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "dualstackbridge")) + + // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.100.0/24 and 2001:db8:abc2::/64 + ctx := context.Background() + id1 := container.Run(t, ctx, client, + container.WithNetworkMode("dualstackbridge"), + container.WithName(t.Name()+"first"), + container.WithIPv4("dualstackbridge", "172.28.100.20"), + container.WithIPv6("dualstackbridge", "2001:db8:abc2::20"), + ) + id2 := container.Run(t, ctx, client, + container.WithNetworkMode("dualstackbridge"), + container.WithName(t.Name()+"second"), + container.WithIPv4("dualstackbridge", "172.28.100.21"), + container.WithIPv6("dualstackbridge", "2001:db8:abc2::21"), + ) + c1, err := client.ContainerInspect(ctx, id1) + assert.NilError(t, err) + + // verify ipv4 connectivity to the explicit --ipv address second to first + _, err = container.Exec(ctx, client, id2, []string{"ping", "-c", "1", c1.NetworkSettings.Networks["dualstackbridge"].IPAddress}) + assert.NilError(t, err) + // verify ipv6 connectivity to the explicit --ipv6 address second to first + _, err = container.Exec(ctx, client, id2, []string{"ping6", "-c", "1", c1.NetworkSettings.Networks["dualstackbridge"].GlobalIPv6Address}) + assert.NilError(t, err) + + // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.102.0/24 and 2001:db8:abc4::/64 + id3 := container.Run(t, ctx, client, + container.WithNetworkMode("dualstackbridge"), + container.WithName(t.Name()+"third"), + container.WithIPv4("dualstackbridge", "172.28.102.20"), + container.WithIPv6("dualstackbridge", "2001:db8:abc4::20"), + ) + id4 := container.Run(t, ctx, client, + container.WithNetworkMode("dualstackbridge"), + container.WithName(t.Name()+"fourth"), + container.WithIPv4("dualstackbridge", "172.28.102.21"), + container.WithIPv6("dualstackbridge", "2001:db8:abc4::21"), + ) + c3, err := client.ContainerInspect(ctx, id3) + assert.NilError(t, err) + + // verify ipv4 connectivity to the explicit --ipv address from third to fourth + _, err = container.Exec(ctx, client, id4, []string{"ping", "-c", "1", c3.NetworkSettings.Networks["dualstackbridge"].IPAddress}) + assert.NilError(t, err) + // verify ipv6 connectivity to the explicit --ipv6 address from third to fourth + _, err = container.Exec(ctx, client, id4, []string{"ping6", "-c", "1", c3.NetworkSettings.Networks["dualstackbridge"].GlobalIPv6Address}) + assert.NilError(t, err) + + // Inspect the v4 gateway to ensure the proper default GW was assigned + assert.Equal(t, c1.NetworkSettings.Networks["dualstackbridge"].Gateway, "172.28.100.1") + // Inspect the v6 gateway to ensure the proper default GW was assigned + assert.Equal(t, c1.NetworkSettings.Networks["dualstackbridge"].IPv6Gateway, "2001:db8:abc2::1") + // Inspect the v4 gateway to ensure the proper explicitly assigned default GW was assigned + assert.Equal(t, c3.NetworkSettings.Networks["dualstackbridge"].Gateway, "172.28.102.254") + // Inspect the v6 gateway to ensure the proper explicitly assigned default GW was assigned + assert.Equal(t, c3.NetworkSettings.Networks["dualstackbridge"].IPv6Gateway, "2001:db8.abc4::254") +} + +func isNetworkAvailable(c client.NetworkAPIClient, name string) cmp.Comparison { + return func() cmp.Result { + networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{}) + if err != nil { + return cmp.ResultFromError(err) + } + for _, network := range networks { + if network.Name == name { + return cmp.ResultSuccess + } + } + return cmp.ResultFailure(fmt.Sprintf("could not find network %s", name)) + } +} + +func isNetworkNotAvailable(c client.NetworkAPIClient, name string) cmp.Comparison { + return func() cmp.Result { + networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{}) + if err != nil { + return cmp.ResultFromError(err) + } + for _, network := range networks { + if network.Name == name { + return cmp.ResultFailure(fmt.Sprintf("network %s is still present", name)) + } + } + return cmp.ResultSuccess + } +} + +func createMasterDummy(t *testing.T, master string) { + // ip link add type dummy + icmd.RunCommand("ip", "link", "add", master, "type", "dummy").Assert(t, icmd.Success) + icmd.RunCommand("ip", "link", "set", master, "up").Assert(t, icmd.Success) +} + +func createVlanInterface(t *testing.T, master, slave, id string) { + // ip link add link name . type vlan id + icmd.RunCommand("ip", "link", "add", "link", master, "name", slave, "type", "vlan", "id", id).Assert(t, icmd.Success) + // ip link set up + icmd.RunCommand("ip", "link", "set", slave, "up").Assert(t, icmd.Success) +} + +func deleteInterface(t *testing.T, ifName string) { + icmd.RunCommand("ip", "link", "delete", ifName).Assert(t, icmd.Success) + icmd.RunCommand("iptables", "-t", "nat", "--flush").Assert(t, icmd.Success) + icmd.RunCommand("iptables", "--flush").Assert(t, icmd.Success) +} + +func linkExists(t *testing.T, master string) { + // verify the specified link exists, ip link show + icmd.RunCommand("ip", "link", "show", master).Assert(t, icmd.Success) +} + +// ensure Kernel version is >= v3.9 for macvlan support +func macvlanKernelSupport() bool { + return checkKernelMajorVersionGreaterOrEqualThen(3, 9) +} + +func checkKernelMajorVersionGreaterOrEqualThen(kernelVersion int, majorVersion int) bool { + kv, err := kernel.GetKernelVersion() + if err != nil { + return false + } + if kv.Kernel < kernelVersion || (kv.Kernel == kernelVersion && kv.Major < majorVersion) { + return false + } + return true +} From 1776b7beed35b8654589e59254a6b1ad93701eaa Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Tue, 10 Apr 2018 16:29:48 +0200 Subject: [PATCH 19/36] =?UTF-8?q?Move=20integration-cli=20daemon=20package?= =?UTF-8?q?=20to=20internal/test=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … and do not use the `docker` cli in it. One of the reason of this move is to not make `integration` package using legacy `integration-cli` package. Next move will be to support swarm within this package *and* provide some helper function using the api (compared to the one using cli in `integration-cli/daemon` package). Signed-off-by: Vincent Demeester (cherry picked from commit f0d277fe84a72b29c0d2d541c20d5a9c4d7e4884) Signed-off-by: Sebastiaan van Stijn --- .../engine/integration-cli/check_test.go | 7 +- .../engine/integration-cli/daemon/daemon.go | 605 +---------------- .../container/daemon_linux_test.go | 4 +- .../integration/container/export_test.go | 4 +- .../container/mounts_linux_test.go | 4 +- .../integration/container/restart_test.go | 4 +- .../integration/network/inspect_test.go | 1 - .../integration/network/macvlan_test.go | 14 +- .../integration/plugin/authz/main_test.go | 8 +- .../integration/plugin/logging/main_test.go | 2 - .../plugin/logging/validation_test.go | 4 +- .../integration/plugin/volumes/main_test.go | 2 - .../integration/plugin/volumes/mounts_test.go | 4 +- .../engine/integration/secret/main_test.go | 2 - .../engine/integration/service/main_test.go | 2 - .../system/cgroupdriver_systemd_test.go | 4 +- .../engine/internal/test/daemon/daemon.go | 618 ++++++++++++++++++ .../test}/daemon/daemon_unix.go | 7 +- .../test}/daemon/daemon_windows.go | 5 +- components/engine/internal/test/daemon/ops.go | 13 + 20 files changed, 677 insertions(+), 637 deletions(-) create mode 100644 components/engine/internal/test/daemon/daemon.go rename components/engine/{integration-cli => internal/test}/daemon/daemon_unix.go (78%) rename components/engine/{integration-cli => internal/test}/daemon/daemon_windows.go (74%) create mode 100644 components/engine/internal/test/daemon/ops.go diff --git a/components/engine/integration-cli/check_test.go b/components/engine/integration-cli/check_test.go index 18d3d3780a1..a455893d8c5 100644 --- a/components/engine/integration-cli/check_test.go +++ b/components/engine/integration-cli/check_test.go @@ -21,6 +21,7 @@ import ( "github.com/docker/docker/integration-cli/environment" "github.com/docker/docker/integration-cli/fixtures/plugin" "github.com/docker/docker/integration-cli/registry" + testdaemon "github.com/docker/docker/internal/test/daemon" ienv "github.com/docker/docker/internal/test/environment" "github.com/docker/docker/pkg/reexec" "github.com/go-check/check" @@ -100,7 +101,7 @@ func (s *DockerSuite) OnTimeout(c *check.C) { daemonPid := int(rawPid) if daemonPid > 0 { - daemon.SignalDaemonDump(daemonPid) + testdaemon.SignalDaemonDump(daemonPid) } } @@ -285,7 +286,7 @@ func (s *DockerDaemonSuite) TearDownTest(c *check.C) { } func (s *DockerDaemonSuite) TearDownSuite(c *check.C) { - filepath.Walk(daemon.SockRoot, func(path string, fi os.FileInfo, err error) error { + filepath.Walk(testdaemon.SockRoot, func(path string, fi os.FileInfo, err error) error { if err != nil { // ignore errors here // not cleaning up sockets is not really an error @@ -296,7 +297,7 @@ func (s *DockerDaemonSuite) TearDownSuite(c *check.C) { } return nil }) - os.RemoveAll(daemon.SockRoot) + os.RemoveAll(testdaemon.SockRoot) } const defaultSwarmPort = 2477 diff --git a/components/engine/integration-cli/daemon/daemon.go b/components/engine/integration-cli/daemon/daemon.go index 9ca54236f48..4ef1dafe79a 100644 --- a/components/engine/integration-cli/daemon/daemon.go +++ b/components/engine/integration-cli/daemon/daemon.go @@ -1,33 +1,17 @@ package daemon // import "github.com/docker/docker/integration-cli/daemon" import ( - "encoding/json" "fmt" - "io" - "io/ioutil" - "net/http" - "os" "os/exec" - "path/filepath" - "strconv" "strings" "time" - "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/events" - "github.com/docker/docker/client" "github.com/docker/docker/integration-cli/checker" - "github.com/docker/docker/integration-cli/request" - "github.com/docker/docker/opts" - "github.com/docker/docker/pkg/ioutils" - "github.com/docker/docker/pkg/stringid" - "github.com/docker/go-connections/sockets" - "github.com/docker/go-connections/tlsconfig" + "github.com/docker/docker/internal/test/daemon" "github.com/go-check/check" "github.com/gotestyourself/gotestyourself/assert" "github.com/gotestyourself/gotestyourself/icmd" "github.com/pkg/errors" - "golang.org/x/net/context" ) type testingT interface { @@ -40,32 +24,10 @@ type logT interface { Logf(string, ...interface{}) } -// SockRoot holds the path of the default docker integration daemon socket -var SockRoot = filepath.Join(os.TempDir(), "docker-integration") - -var errDaemonNotStarted = errors.New("daemon not started") - // Daemon represents a Docker daemon for the testing framework. type Daemon struct { - GlobalFlags []string - Root string - Folder string - Wait chan error - UseDefaultHost bool - UseDefaultTLSHost bool - - id string - logFile *os.File - stdin io.WriteCloser - stdout, stderr io.ReadCloser - cmd *exec.Cmd - storageDriver string - userlandProxy bool - execRoot string - experimental bool - dockerBinary string - dockerdBinary string - log logT + *daemon.Daemon + dockerBinary string } // Config holds docker daemon integration configuration @@ -73,502 +35,22 @@ type Config struct { Experimental bool } -type clientConfig struct { - transport *http.Transport - scheme string - addr string -} - // New returns a Daemon instance to be used for testing. // This will create a directory such as d123456789 in the folder specified by $DOCKER_INTEGRATION_DAEMON_DEST or $DEST. // The daemon will not automatically start. func New(t testingT, dockerBinary string, dockerdBinary string, config Config) *Daemon { - dest := os.Getenv("DOCKER_INTEGRATION_DAEMON_DEST") - if dest == "" { - dest = os.Getenv("DEST") - } - if dest == "" { - t.Fatalf("Please set the DOCKER_INTEGRATION_DAEMON_DEST or the DEST environment variable") - } - - if err := os.MkdirAll(SockRoot, 0700); err != nil { - t.Fatalf("could not create daemon socket root") - } - - id := fmt.Sprintf("d%s", stringid.TruncateID(stringid.GenerateRandomID())) - dir := filepath.Join(dest, id) - daemonFolder, err := filepath.Abs(dir) - if err != nil { - t.Fatalf("Could not make %q an absolute path", dir) - } - daemonRoot := filepath.Join(daemonFolder, "root") - - if err := os.MkdirAll(daemonRoot, 0755); err != nil { - t.Fatalf("Could not create daemon root %q", dir) + ops := []func(*daemon.Daemon){ + daemon.WithDockerdBinary(dockerdBinary), } - - userlandProxy := true - if env := os.Getenv("DOCKER_USERLANDPROXY"); env != "" { - if val, err := strconv.ParseBool(env); err != nil { - userlandProxy = val - } + if config.Experimental { + ops = append(ops, daemon.WithExperimental) } + d := daemon.New(t, ops...) return &Daemon{ - id: id, - Folder: daemonFolder, - Root: daemonRoot, - storageDriver: os.Getenv("DOCKER_GRAPHDRIVER"), - userlandProxy: userlandProxy, - execRoot: filepath.Join(os.TempDir(), "docker-execroot", id), - dockerBinary: dockerBinary, - dockerdBinary: dockerdBinary, - experimental: config.Experimental, - log: t, - } -} - -// RootDir returns the root directory of the daemon. -func (d *Daemon) RootDir() string { - return d.Root -} - -// ID returns the generated id of the daemon -func (d *Daemon) ID() string { - return d.id -} - -// StorageDriver returns the configured storage driver of the daemon -func (d *Daemon) StorageDriver() string { - return d.storageDriver -} - -// CleanupExecRoot cleans the daemon exec root (network namespaces, ...) -func (d *Daemon) CleanupExecRoot(c *check.C) { - cleanupExecRoot(c, d.execRoot) -} - -func (d *Daemon) getClientConfig() (*clientConfig, error) { - var ( - transport *http.Transport - scheme string - addr string - proto string - ) - if d.UseDefaultTLSHost { - option := &tlsconfig.Options{ - CAFile: "fixtures/https/ca.pem", - CertFile: "fixtures/https/client-cert.pem", - KeyFile: "fixtures/https/client-key.pem", - } - tlsConfig, err := tlsconfig.Client(*option) - if err != nil { - return nil, err - } - transport = &http.Transport{ - TLSClientConfig: tlsConfig, - } - addr = fmt.Sprintf("%s:%d", opts.DefaultHTTPHost, opts.DefaultTLSHTTPPort) - scheme = "https" - proto = "tcp" - } else if d.UseDefaultHost { - addr = opts.DefaultUnixSocket - proto = "unix" - scheme = "http" - transport = &http.Transport{} - } else { - addr = d.sockPath() - proto = "unix" - scheme = "http" - transport = &http.Transport{} - } - - if err := sockets.ConfigureTransport(transport, proto, addr); err != nil { - return nil, err - } - transport.DisableKeepAlives = true - - return &clientConfig{ - transport: transport, - scheme: scheme, - addr: addr, - }, nil -} - -// Start starts the daemon and return once it is ready to receive requests. -func (d *Daemon) Start(t testingT, args ...string) { - if err := d.StartWithError(args...); err != nil { - t.Fatalf("Error starting daemon with arguments: %v", args) - } -} - -// StartWithError starts the daemon and return once it is ready to receive requests. -// It returns an error in case it couldn't start. -func (d *Daemon) StartWithError(args ...string) error { - logFile, err := os.OpenFile(filepath.Join(d.Folder, "docker.log"), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600) - if err != nil { - return errors.Wrapf(err, "[%s] Could not create %s/docker.log", d.id, d.Folder) - } - - return d.StartWithLogFile(logFile, args...) -} - -// StartWithLogFile will start the daemon and attach its streams to a given file. -func (d *Daemon) StartWithLogFile(out *os.File, providedArgs ...string) error { - dockerdBinary, err := exec.LookPath(d.dockerdBinary) - if err != nil { - return errors.Wrapf(err, "[%s] could not find docker binary in $PATH", d.id) - } - args := append(d.GlobalFlags, - "--containerd", "/var/run/docker/containerd/docker-containerd.sock", - "--data-root", d.Root, - "--exec-root", d.execRoot, - "--pidfile", fmt.Sprintf("%s/docker.pid", d.Folder), - fmt.Sprintf("--userland-proxy=%t", d.userlandProxy), - ) - if d.experimental { - args = append(args, "--experimental", "--init") - } - if !(d.UseDefaultHost || d.UseDefaultTLSHost) { - args = append(args, []string{"--host", d.Sock()}...) - } - if root := os.Getenv("DOCKER_REMAP_ROOT"); root != "" { - args = append(args, []string{"--userns-remap", root}...) - } - - // If we don't explicitly set the log-level or debug flag(-D) then - // turn on debug mode - foundLog := false - foundSd := false - for _, a := range providedArgs { - if strings.Contains(a, "--log-level") || strings.Contains(a, "-D") || strings.Contains(a, "--debug") { - foundLog = true - } - if strings.Contains(a, "--storage-driver") { - foundSd = true - } - } - if !foundLog { - args = append(args, "--debug") - } - if d.storageDriver != "" && !foundSd { - args = append(args, "--storage-driver", d.storageDriver) - } - - args = append(args, providedArgs...) - d.cmd = exec.Command(dockerdBinary, args...) - d.cmd.Env = append(os.Environ(), "DOCKER_SERVICE_PREFER_OFFLINE_IMAGE=1") - d.cmd.Stdout = out - d.cmd.Stderr = out - d.logFile = out - - if err := d.cmd.Start(); err != nil { - return errors.Errorf("[%s] could not start daemon container: %v", d.id, err) - } - - wait := make(chan error) - - go func() { - wait <- d.cmd.Wait() - d.log.Logf("[%s] exiting daemon", d.id) - close(wait) - }() - - d.Wait = wait - - tick := time.Tick(500 * time.Millisecond) - // make sure daemon is ready to receive requests - startTime := time.Now().Unix() - for { - d.log.Logf("[%s] waiting for daemon to start", d.id) - if time.Now().Unix()-startTime > 5 { - // After 5 seconds, give up - return errors.Errorf("[%s] Daemon exited and never started", d.id) - } - select { - case <-time.After(2 * time.Second): - return errors.Errorf("[%s] timeout: daemon does not respond", d.id) - case <-tick: - clientConfig, err := d.getClientConfig() - if err != nil { - return err - } - - client := &http.Client{ - Transport: clientConfig.transport, - } - - req, err := http.NewRequest("GET", "/_ping", nil) - if err != nil { - return errors.Wrapf(err, "[%s] could not create new request", d.id) - } - req.URL.Host = clientConfig.addr - req.URL.Scheme = clientConfig.scheme - resp, err := client.Do(req) - if err != nil { - continue - } - resp.Body.Close() - if resp.StatusCode != http.StatusOK { - d.log.Logf("[%s] received status != 200 OK: %s\n", d.id, resp.Status) - } - d.log.Logf("[%s] daemon started\n", d.id) - d.Root, err = d.queryRootDir() - if err != nil { - return errors.Errorf("[%s] error querying daemon for root directory: %v", d.id, err) - } - return nil - case <-d.Wait: - return errors.Errorf("[%s] Daemon exited during startup", d.id) - } - } -} - -// StartWithBusybox will first start the daemon with Daemon.Start() -// then save the busybox image from the main daemon and load it into this Daemon instance. -func (d *Daemon) StartWithBusybox(t testingT, arg ...string) { - d.Start(t, arg...) - d.LoadBusybox(t) -} - -// Kill will send a SIGKILL to the daemon -func (d *Daemon) Kill() error { - if d.cmd == nil || d.Wait == nil { - return errDaemonNotStarted - } - - defer func() { - d.logFile.Close() - d.cmd = nil - }() - - if err := d.cmd.Process.Kill(); err != nil { - return err - } - - return os.Remove(fmt.Sprintf("%s/docker.pid", d.Folder)) -} - -// Pid returns the pid of the daemon -func (d *Daemon) Pid() int { - return d.cmd.Process.Pid -} - -// Interrupt stops the daemon by sending it an Interrupt signal -func (d *Daemon) Interrupt() error { - return d.Signal(os.Interrupt) -} - -// Signal sends the specified signal to the daemon if running -func (d *Daemon) Signal(signal os.Signal) error { - if d.cmd == nil || d.Wait == nil { - return errDaemonNotStarted - } - return d.cmd.Process.Signal(signal) -} - -// DumpStackAndQuit sends SIGQUIT to the daemon, which triggers it to dump its -// stack to its log file and exit -// This is used primarily for gathering debug information on test timeout -func (d *Daemon) DumpStackAndQuit() { - if d.cmd == nil || d.cmd.Process == nil { - return - } - SignalDaemonDump(d.cmd.Process.Pid) -} - -// Stop will send a SIGINT every second and wait for the daemon to stop. -// If it times out, a SIGKILL is sent. -// Stop will not delete the daemon directory. If a purged daemon is needed, -// instantiate a new one with NewDaemon. -// If an error occurs while starting the daemon, the test will fail. -func (d *Daemon) Stop(t testingT) { - err := d.StopWithError() - if err != nil { - if err != errDaemonNotStarted { - t.Fatalf("Error while stopping the daemon %s : %v", d.id, err) - } else { - t.Logf("Daemon %s is not started", d.id) - } - } -} - -// StopWithError will send a SIGINT every second and wait for the daemon to stop. -// If it timeouts, a SIGKILL is sent. -// Stop will not delete the daemon directory. If a purged daemon is needed, -// instantiate a new one with NewDaemon. -func (d *Daemon) StopWithError() error { - if d.cmd == nil || d.Wait == nil { - return errDaemonNotStarted - } - - defer func() { - d.logFile.Close() - d.cmd = nil - }() - - i := 1 - tick := time.Tick(time.Second) - - if err := d.cmd.Process.Signal(os.Interrupt); err != nil { - if strings.Contains(err.Error(), "os: process already finished") { - return errDaemonNotStarted - } - return errors.Errorf("could not send signal: %v", err) - } -out1: - for { - select { - case err := <-d.Wait: - return err - case <-time.After(20 * time.Second): - // time for stopping jobs and run onShutdown hooks - d.log.Logf("[%s] daemon started", d.id) - break out1 - } - } - -out2: - for { - select { - case err := <-d.Wait: - return err - case <-tick: - i++ - if i > 5 { - d.log.Logf("tried to interrupt daemon for %d times, now try to kill it", i) - break out2 - } - d.log.Logf("Attempt #%d: daemon is still running with pid %d", i, d.cmd.Process.Pid) - if err := d.cmd.Process.Signal(os.Interrupt); err != nil { - return errors.Errorf("could not send signal: %v", err) - } - } - } - - if err := d.cmd.Process.Kill(); err != nil { - d.log.Logf("Could not kill daemon: %v", err) - return err + Daemon: d, + dockerBinary: dockerBinary, } - - d.cmd.Wait() - - return os.Remove(fmt.Sprintf("%s/docker.pid", d.Folder)) -} - -// Restart will restart the daemon by first stopping it and the starting it. -// If an error occurs while starting the daemon, the test will fail. -func (d *Daemon) Restart(t testingT, args ...string) { - d.Stop(t) - d.handleUserns() - d.Start(t, args...) -} - -// RestartWithError will restart the daemon by first stopping it and then starting it. -func (d *Daemon) RestartWithError(arg ...string) error { - if err := d.StopWithError(); err != nil { - return err - } - d.handleUserns() - return d.StartWithError(arg...) -} - -func (d *Daemon) handleUserns() { - // in the case of tests running a user namespace-enabled daemon, we have resolved - // d.Root to be the actual final path of the graph dir after the "uid.gid" of - // remapped root is added--we need to subtract it from the path before calling - // start or else we will continue making subdirectories rather than truly restarting - // with the same location/root: - if root := os.Getenv("DOCKER_REMAP_ROOT"); root != "" { - d.Root = filepath.Dir(d.Root) - } -} - -// LoadBusybox image into the daemon -func (d *Daemon) LoadBusybox(t testingT) { - clientHost, err := client.NewEnvClient() - assert.NilError(t, err, "failed to create client") - defer clientHost.Close() - - ctx := context.Background() - reader, err := clientHost.ImageSave(ctx, []string{"busybox:latest"}) - assert.NilError(t, err, "failed to download busybox") - defer reader.Close() - - client, err := d.NewClient() - assert.NilError(t, err, "failed to create client") - defer client.Close() - - resp, err := client.ImageLoad(ctx, reader, true) - assert.NilError(t, err, "failed to load busybox") - defer resp.Body.Close() -} - -func (d *Daemon) queryRootDir() (string, error) { - // update daemon root by asking /info endpoint (to support user - // namespaced daemon with root remapped uid.gid directory) - clientConfig, err := d.getClientConfig() - if err != nil { - return "", err - } - - client := &http.Client{ - Transport: clientConfig.transport, - } - - req, err := http.NewRequest("GET", "/info", nil) - if err != nil { - return "", err - } - req.Header.Set("Content-Type", "application/json") - req.URL.Host = clientConfig.addr - req.URL.Scheme = clientConfig.scheme - - resp, err := client.Do(req) - if err != nil { - return "", err - } - body := ioutils.NewReadCloserWrapper(resp.Body, func() error { - return resp.Body.Close() - }) - - type Info struct { - DockerRootDir string - } - var b []byte - var i Info - b, err = request.ReadBody(body) - if err == nil && resp.StatusCode == http.StatusOK { - // read the docker root dir - if err = json.Unmarshal(b, &i); err == nil { - return i.DockerRootDir, nil - } - } - return "", err -} - -// Sock returns the socket path of the daemon -func (d *Daemon) Sock() string { - return fmt.Sprintf("unix://" + d.sockPath()) -} - -func (d *Daemon) sockPath() string { - return filepath.Join(SockRoot, d.id+".sock") -} - -// WaitRun waits for a container to be running for 10s -func (d *Daemon) WaitRun(contID string) error { - args := []string{"--host", d.Sock()} - return WaitInspectWithArgs(d.dockerBinary, contID, "{{.State.Running}}", "true", 10*time.Second, args...) -} - -// Info returns the info struct for this daemon -func (d *Daemon) Info(t assert.TestingT) types.Info { - apiclient, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - assert.NilError(t, err) - info, err := apiclient.Info(context.Background()) - assert.NilError(t, err) - return info } // Cmd executes a docker CLI command against this daemon. @@ -594,11 +76,6 @@ func (d *Daemon) PrependHostArg(args []string) []string { return append([]string{"--host", d.Sock()}, args...) } -// LogFileName returns the path the daemon's log file -func (d *Daemon) LogFileName() string { - return d.logFile.Name() -} - // GetIDByName returns the ID of an object (container, volume, …) given its name func (d *Daemon) GetIDByName(name string) (string, error) { return d.inspectFieldWithError(name, "Id") @@ -616,11 +93,6 @@ func (d *Daemon) ActiveContainers() (ids []string) { return } -// ReadLogFile returns the content of the daemon log file -func (d *Daemon) ReadLogFile() ([]byte, error) { - return ioutil.ReadFile(d.logFile.Name()) -} - // InspectField returns the field filter by 'filter' func (d *Daemon) InspectField(name, filter string) (string, error) { return d.inspectFilter(name, filter) @@ -672,59 +144,10 @@ func (d *Daemon) CheckActiveContainerCount(c *check.C) (interface{}, check.Comme return len(strings.Split(strings.TrimSpace(out), "\n")), check.Commentf("output: %q", string(out)) } -// ReloadConfig asks the daemon to reload its configuration -func (d *Daemon) ReloadConfig() error { - if d.cmd == nil || d.cmd.Process == nil { - return errors.New("daemon is not running") - } - - errCh := make(chan error) - started := make(chan struct{}) - go func() { - _, body, err := request.DoOnHost(d.Sock(), "/events", request.Method(http.MethodGet)) - close(started) - if err != nil { - errCh <- err - } - defer body.Close() - dec := json.NewDecoder(body) - for { - var e events.Message - if err := dec.Decode(&e); err != nil { - errCh <- err - return - } - if e.Type != events.DaemonEventType { - continue - } - if e.Action != "reload" { - continue - } - close(errCh) // notify that we are done - return - } - }() - - <-started - if err := signalDaemonReload(d.cmd.Process.Pid); err != nil { - return errors.Errorf("error signaling daemon reload: %v", err) - } - select { - case err := <-errCh: - if err != nil { - return errors.Errorf("error waiting for daemon reload event: %v", err) - } - case <-time.After(30 * time.Second): - return errors.New("timeout waiting for daemon reload event") - } - return nil -} - -// NewClient creates new client based on daemon's socket path -func (d *Daemon) NewClient() (*client.Client, error) { - return client.NewClientWithOpts( - client.FromEnv, - client.WithHost(d.Sock())) +// WaitRun waits for a container to be running for 10s +func (d *Daemon) WaitRun(contID string) error { + args := []string{"--host", d.Sock()} + return WaitInspectWithArgs(d.dockerBinary, contID, "{{.State.Running}}", "true", 10*time.Second, args...) } // WaitInspectWithArgs waits for the specified expression to be equals to the specified expected string in the given time. diff --git a/components/engine/integration/container/daemon_linux_test.go b/components/engine/integration/container/daemon_linux_test.go index 1b811f306f8..f79d76b5b44 100644 --- a/components/engine/integration/container/daemon_linux_test.go +++ b/components/engine/integration/container/daemon_linux_test.go @@ -9,8 +9,8 @@ import ( "testing" "github.com/docker/docker/api/types" - "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/integration/internal/container" + "github.com/docker/docker/internal/test/daemon" "github.com/gotestyourself/gotestyourself/assert" "github.com/gotestyourself/gotestyourself/skip" "golang.org/x/sys/unix" @@ -30,7 +30,7 @@ func TestContainerStartOnDaemonRestart(t *testing.T) { skip.If(t, testEnv.IsRemoteDaemon(), "cannot start daemon on remote test run") t.Parallel() - d := daemon.New(t, "", "dockerd", daemon.Config{}) + d := daemon.New(t) d.StartWithBusybox(t, "--iptables=false") defer d.Stop(t) diff --git a/components/engine/integration/container/export_test.go b/components/engine/integration/container/export_test.go index f7f0295ce55..272feff75d2 100644 --- a/components/engine/integration/container/export_test.go +++ b/components/engine/integration/container/export_test.go @@ -9,9 +9,9 @@ import ( "github.com/docker/docker/api/types" containerTypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" - "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" + "github.com/docker/docker/internal/test/daemon" "github.com/docker/docker/pkg/jsonmessage" "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" @@ -62,7 +62,7 @@ func TestExportContainerAfterDaemonRestart(t *testing.T) { skip.If(t, testEnv.DaemonInfo.OSType != "linux") skip.If(t, testEnv.IsRemoteDaemon()) - d := daemon.New(t, "", "dockerd", daemon.Config{}) + d := daemon.New(t) client, err := d.NewClient() assert.NilError(t, err) diff --git a/components/engine/integration/container/mounts_linux_test.go b/components/engine/integration/container/mounts_linux_test.go index cdde06a9eff..2674a2901fb 100644 --- a/components/engine/integration/container/mounts_linux_test.go +++ b/components/engine/integration/container/mounts_linux_test.go @@ -12,8 +12,8 @@ import ( "github.com/docker/docker/api/types/mount" "github.com/docker/docker/api/types/network" "github.com/docker/docker/client" - "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/integration/internal/request" + "github.com/docker/docker/internal/test/daemon" "github.com/docker/docker/pkg/stdcopy" "github.com/docker/docker/pkg/system" "github.com/gotestyourself/gotestyourself/assert" @@ -25,7 +25,7 @@ import ( func TestContainerShmNoLeak(t *testing.T) { skip.If(t, testEnv.IsRemoteDaemon(), "cannot start daemon on remote test run") t.Parallel() - d := daemon.New(t, "docker", "dockerd", daemon.Config{}) + d := daemon.New(t) client, err := d.NewClient() if err != nil { t.Fatal(err) diff --git a/components/engine/integration/container/restart_test.go b/components/engine/integration/container/restart_test.go index 7a2576e219f..d6deea730e6 100644 --- a/components/engine/integration/container/restart_test.go +++ b/components/engine/integration/container/restart_test.go @@ -8,7 +8,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" - "github.com/docker/docker/integration-cli/daemon" + "github.com/docker/docker/internal/test/daemon" "github.com/gotestyourself/gotestyourself/skip" ) @@ -55,7 +55,7 @@ func TestDaemonRestartKillContainers(t *testing.T) { t.Parallel() - d := daemon.New(t, "", "dockerd", daemon.Config{}) + d := daemon.New(t) client, err := d.NewClient() if err != nil { t.Fatal(err) diff --git a/components/engine/integration/network/inspect_test.go b/components/engine/integration/network/inspect_test.go index ad4a344c49c..22d18b74743 100644 --- a/components/engine/integration/network/inspect_test.go +++ b/components/engine/integration/network/inspect_test.go @@ -16,7 +16,6 @@ import ( ) const defaultSwarmPort = 2477 -const dockerdBinary = "dockerd" func TestInspectNetwork(t *testing.T) { defer setupTest(t)() diff --git a/components/engine/integration/network/macvlan_test.go b/components/engine/integration/network/macvlan_test.go index 46945ada288..146f67ee572 100644 --- a/components/engine/integration/network/macvlan_test.go +++ b/components/engine/integration/network/macvlan_test.go @@ -9,8 +9,8 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/network" "github.com/docker/docker/client" - "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/integration/internal/container" + "github.com/docker/docker/internal/test/daemon" "github.com/docker/docker/pkg/parsers/kernel" "github.com/gotestyourself/gotestyourself/assert" "github.com/gotestyourself/gotestyourself/assert/cmp" @@ -24,7 +24,7 @@ func TestDockerNetworkMacvlanPersistance(t *testing.T) { skip.If(t, testEnv.IsRemoteDaemon()) skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") - d := daemon.New(t, "", "dockerd", daemon.Config{}) + d := daemon.New(t) d.StartWithBusybox(t) defer d.Stop(t) @@ -53,7 +53,7 @@ func TestDockerNetworkMacvlanOverlapParent(t *testing.T) { skip.If(t, testEnv.IsRemoteDaemon()) skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") - d := daemon.New(t, "", "dockerd", daemon.Config{}) + d := daemon.New(t) d.StartWithBusybox(t) defer d.Stop(t) @@ -95,7 +95,7 @@ func TestDockerNetworkMacvlanSubinterface(t *testing.T) { skip.If(t, testEnv.IsRemoteDaemon()) skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") - d := daemon.New(t, "", "dockerd", daemon.Config{}) + d := daemon.New(t) d.StartWithBusybox(t) defer d.Stop(t) @@ -131,7 +131,7 @@ func TestDockerNetworkMacvlanBridgeNilParent(t *testing.T) { skip.If(t, testEnv.IsRemoteDaemon()) skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") - d := daemon.New(t, "", "dockerd", daemon.Config{}) + d := daemon.New(t) d.StartWithBusybox(t) defer d.Stop(t) client, err := d.NewClient() @@ -157,7 +157,7 @@ func TestDockerNetworkMacvlanBridgeInternal(t *testing.T) { skip.If(t, testEnv.IsRemoteDaemon()) skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") - d := daemon.New(t, "", "dockerd", daemon.Config{}) + d := daemon.New(t) d.StartWithBusybox(t) defer d.Stop(t) client, err := d.NewClient() @@ -191,7 +191,7 @@ func TestDockerNetworkMacvlanMultiSubnet(t *testing.T) { skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") t.Skip("Temporarily skipping while investigating sporadic v6 CI issues") - d := daemon.New(t, "", "dockerd", daemon.Config{}) + d := daemon.New(t) d.StartWithBusybox(t) defer d.Stop(t) client, err := d.NewClient() diff --git a/components/engine/integration/plugin/authz/main_test.go b/components/engine/integration/plugin/authz/main_test.go index 3d5f406b923..1958ce376ad 100644 --- a/components/engine/integration/plugin/authz/main_test.go +++ b/components/engine/integration/plugin/authz/main_test.go @@ -12,7 +12,7 @@ import ( "strings" "testing" - "github.com/docker/docker/integration-cli/daemon" + "github.com/docker/docker/internal/test/daemon" "github.com/docker/docker/internal/test/environment" "github.com/docker/docker/pkg/authorization" "github.com/docker/docker/pkg/plugins" @@ -25,8 +25,6 @@ var ( server *httptest.Server ) -const dockerdBinary = "dockerd" - func TestMain(m *testing.M) { var err error testEnv, err = environment.New() @@ -52,9 +50,7 @@ func setupTest(t *testing.T) func() { skip.IfCondition(t, testEnv.IsRemoteDaemon(), "cannot run daemon when remote daemon") environment.ProtectAll(t, testEnv) - d = daemon.New(t, "", dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }) + d = daemon.New(t, daemon.WithExperimental) return func() { if d != nil { diff --git a/components/engine/integration/plugin/logging/main_test.go b/components/engine/integration/plugin/logging/main_test.go index b2446ca8c88..e1292a5718d 100644 --- a/components/engine/integration/plugin/logging/main_test.go +++ b/components/engine/integration/plugin/logging/main_test.go @@ -12,8 +12,6 @@ var ( testEnv *environment.Execution ) -const dockerdBinary = "dockerd" - func TestMain(m *testing.M) { var err error testEnv, err = environment.New() diff --git a/components/engine/integration/plugin/logging/validation_test.go b/components/engine/integration/plugin/logging/validation_test.go index f0d6e9e8b24..7f67aea75c9 100644 --- a/components/engine/integration/plugin/logging/validation_test.go +++ b/components/engine/integration/plugin/logging/validation_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/docker/docker/api/types" - "github.com/docker/docker/integration-cli/daemon" + "github.com/docker/docker/internal/test/daemon" "github.com/gotestyourself/gotestyourself/assert" "github.com/gotestyourself/gotestyourself/skip" ) @@ -17,7 +17,7 @@ func TestDaemonStartWithLogOpt(t *testing.T) { skip.IfCondition(t, testEnv.IsRemoteDaemon(), "cannot run daemon when remote daemon") t.Parallel() - d := daemon.New(t, "", dockerdBinary, daemon.Config{}) + d := daemon.New(t) d.Start(t, "--iptables=false") defer d.Stop(t) diff --git a/components/engine/integration/plugin/volumes/main_test.go b/components/engine/integration/plugin/volumes/main_test.go index e3aa260f8d8..5a5678d9c45 100644 --- a/components/engine/integration/plugin/volumes/main_test.go +++ b/components/engine/integration/plugin/volumes/main_test.go @@ -12,8 +12,6 @@ var ( testEnv *environment.Execution ) -const dockerdBinary = "dockerd" - func TestMain(m *testing.M) { var err error testEnv, err = environment.New() diff --git a/components/engine/integration/plugin/volumes/mounts_test.go b/components/engine/integration/plugin/volumes/mounts_test.go index 2c464f6607a..d57fcfd36fc 100644 --- a/components/engine/integration/plugin/volumes/mounts_test.go +++ b/components/engine/integration/plugin/volumes/mounts_test.go @@ -7,8 +7,8 @@ import ( "testing" "github.com/docker/docker/api/types" - "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/integration-cli/fixtures/plugin" + "github.com/docker/docker/internal/test/daemon" "github.com/gotestyourself/gotestyourself/assert" ) @@ -17,7 +17,7 @@ import ( func TestPluginWithDevMounts(t *testing.T) { t.Parallel() - d := daemon.New(t, "", dockerdBinary, daemon.Config{}) + d := daemon.New(t) d.Start(t, "--iptables=false") defer d.Stop(t) diff --git a/components/engine/integration/secret/main_test.go b/components/engine/integration/secret/main_test.go index 6a5b0985d48..14d7d364b46 100644 --- a/components/engine/integration/secret/main_test.go +++ b/components/engine/integration/secret/main_test.go @@ -10,8 +10,6 @@ import ( var testEnv *environment.Execution -const dockerdBinary = "dockerd" - func TestMain(m *testing.M) { var err error testEnv, err = environment.New() diff --git a/components/engine/integration/service/main_test.go b/components/engine/integration/service/main_test.go index d887403e516..28fd19df4de 100644 --- a/components/engine/integration/service/main_test.go +++ b/components/engine/integration/service/main_test.go @@ -10,8 +10,6 @@ import ( var testEnv *environment.Execution -const dockerdBinary = "dockerd" - func TestMain(m *testing.M) { var err error testEnv, err = environment.New() diff --git a/components/engine/integration/system/cgroupdriver_systemd_test.go b/components/engine/integration/system/cgroupdriver_systemd_test.go index c1f864a1c70..12e716c66c4 100644 --- a/components/engine/integration/system/cgroupdriver_systemd_test.go +++ b/components/engine/integration/system/cgroupdriver_systemd_test.go @@ -7,7 +7,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" - "github.com/docker/docker/integration-cli/daemon" + "github.com/docker/docker/internal/test/daemon" "github.com/gotestyourself/gotestyourself/assert" ) @@ -33,7 +33,7 @@ func TestCgroupDriverSystemdMemoryLimit(t *testing.T) { t.Skip("systemd not available") } - d := daemon.New(t, "docker", "dockerd", daemon.Config{}) + d := daemon.New(t) client, err := d.NewClient() assert.NilError(t, err) d.StartWithBusybox(t, "--exec-opt", "native.cgroupdriver=systemd", "--iptables=false") diff --git a/components/engine/internal/test/daemon/daemon.go b/components/engine/internal/test/daemon/daemon.go new file mode 100644 index 00000000000..739e134659c --- /dev/null +++ b/components/engine/internal/test/daemon/daemon.go @@ -0,0 +1,618 @@ +package daemon // import "github.com/docker/docker/internal/test/daemon" + +import ( + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "os" + "os/exec" + "path/filepath" + "strconv" + "strings" + "time" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/events" + "github.com/docker/docker/client" + "github.com/docker/docker/integration-cli/request" + "github.com/docker/docker/opts" + "github.com/docker/docker/pkg/ioutils" + "github.com/docker/docker/pkg/stringid" + "github.com/docker/go-connections/sockets" + "github.com/docker/go-connections/tlsconfig" + "github.com/gotestyourself/gotestyourself/assert" + "github.com/pkg/errors" +) + +type testingT interface { + assert.TestingT + logT + Fatalf(string, ...interface{}) +} + +type logT interface { + Logf(string, ...interface{}) +} + +const defaultDockerdBinary = "dockerd" + +var errDaemonNotStarted = errors.New("daemon not started") + +// SockRoot holds the path of the default docker integration daemon socket +var SockRoot = filepath.Join(os.TempDir(), "docker-integration") + +type clientConfig struct { + transport *http.Transport + scheme string + addr string +} + +// Daemon represents a Docker daemon for the testing framework +type Daemon struct { + GlobalFlags []string + Root string + Folder string + Wait chan error + UseDefaultHost bool + UseDefaultTLSHost bool + + id string + logFile *os.File + cmd *exec.Cmd + storageDriver string + userlandProxy bool + execRoot string + experimental bool + dockerdBinary string + log logT +} + +// New returns a Daemon instance to be used for testing. +// This will create a directory such as d123456789 in the folder specified by $DOCKER_INTEGRATION_DAEMON_DEST or $DEST. +// The daemon will not automatically start. +func New(t testingT, ops ...func(*Daemon)) *Daemon { + dest := os.Getenv("DOCKER_INTEGRATION_DAEMON_DEST") + if dest == "" { + dest = os.Getenv("DEST") + } + assert.Check(t, dest != "", "Please set the DOCKER_INTEGRATION_DAEMON_DEST or the DEST environment variable") + + storageDriver := os.Getenv("DOCKER_GRAPHDRIVER") + + assert.NilError(t, os.MkdirAll(SockRoot, 0700), "could not create daemon socket root") + + id := fmt.Sprintf("d%s", stringid.TruncateID(stringid.GenerateRandomID())) + dir := filepath.Join(dest, id) + daemonFolder, err := filepath.Abs(dir) + assert.NilError(t, err, "Could not make %q an absolute path", dir) + daemonRoot := filepath.Join(daemonFolder, "root") + + assert.NilError(t, os.MkdirAll(daemonRoot, 0755), "Could not create daemon root %q", dir) + + userlandProxy := true + if env := os.Getenv("DOCKER_USERLANDPROXY"); env != "" { + if val, err := strconv.ParseBool(env); err != nil { + userlandProxy = val + } + } + d := &Daemon{ + id: id, + Folder: daemonFolder, + Root: daemonRoot, + storageDriver: storageDriver, + userlandProxy: userlandProxy, + execRoot: filepath.Join(os.TempDir(), "docker-execroot", id), + dockerdBinary: defaultDockerdBinary, + log: t, + } + + for _, op := range ops { + op(d) + } + + return d +} + +// RootDir returns the root directory of the daemon. +func (d *Daemon) RootDir() string { + return d.Root +} + +// ID returns the generated id of the daemon +func (d *Daemon) ID() string { + return d.id +} + +// StorageDriver returns the configured storage driver of the daemon +func (d *Daemon) StorageDriver() string { + return d.storageDriver +} + +// Sock returns the socket path of the daemon +func (d *Daemon) Sock() string { + return fmt.Sprintf("unix://" + d.sockPath()) +} + +func (d *Daemon) sockPath() string { + return filepath.Join(SockRoot, d.id+".sock") +} + +// LogFileName returns the path the daemon's log file +func (d *Daemon) LogFileName() string { + return d.logFile.Name() +} + +// ReadLogFile returns the content of the daemon log file +func (d *Daemon) ReadLogFile() ([]byte, error) { + return ioutil.ReadFile(d.logFile.Name()) +} + +// NewClient creates new client based on daemon's socket path +func (d *Daemon) NewClient() (*client.Client, error) { + return client.NewClientWithOpts( + client.FromEnv, + client.WithHost(d.Sock())) +} + +// CleanupExecRoot cleans the daemon exec root (network namespaces, ...) +func (d *Daemon) CleanupExecRoot(t testingT) { + cleanupExecRoot(t, d.execRoot) +} + +// Start starts the daemon and return once it is ready to receive requests. +func (d *Daemon) Start(t testingT, args ...string) { + if err := d.StartWithError(args...); err != nil { + t.Fatalf("Error starting daemon with arguments: %v", args) + } +} + +// StartWithError starts the daemon and return once it is ready to receive requests. +// It returns an error in case it couldn't start. +func (d *Daemon) StartWithError(args ...string) error { + logFile, err := os.OpenFile(filepath.Join(d.Folder, "docker.log"), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600) + if err != nil { + return errors.Wrapf(err, "[%s] Could not create %s/docker.log", d.id, d.Folder) + } + + return d.StartWithLogFile(logFile, args...) +} + +// StartWithLogFile will start the daemon and attach its streams to a given file. +func (d *Daemon) StartWithLogFile(out *os.File, providedArgs ...string) error { + dockerdBinary, err := exec.LookPath(d.dockerdBinary) + if err != nil { + return errors.Wrapf(err, "[%s] could not find docker binary in $PATH", d.id) + } + args := append(d.GlobalFlags, + "--containerd", "/var/run/docker/containerd/docker-containerd.sock", + "--data-root", d.Root, + "--exec-root", d.execRoot, + "--pidfile", fmt.Sprintf("%s/docker.pid", d.Folder), + fmt.Sprintf("--userland-proxy=%t", d.userlandProxy), + ) + if d.experimental { + args = append(args, "--experimental", "--init") + } + if !(d.UseDefaultHost || d.UseDefaultTLSHost) { + args = append(args, []string{"--host", d.Sock()}...) + } + if root := os.Getenv("DOCKER_REMAP_ROOT"); root != "" { + args = append(args, []string{"--userns-remap", root}...) + } + + // If we don't explicitly set the log-level or debug flag(-D) then + // turn on debug mode + foundLog := false + foundSd := false + for _, a := range providedArgs { + if strings.Contains(a, "--log-level") || strings.Contains(a, "-D") || strings.Contains(a, "--debug") { + foundLog = true + } + if strings.Contains(a, "--storage-driver") { + foundSd = true + } + } + if !foundLog { + args = append(args, "--debug") + } + if d.storageDriver != "" && !foundSd { + args = append(args, "--storage-driver", d.storageDriver) + } + + args = append(args, providedArgs...) + d.cmd = exec.Command(dockerdBinary, args...) + d.cmd.Env = append(os.Environ(), "DOCKER_SERVICE_PREFER_OFFLINE_IMAGE=1") + d.cmd.Stdout = out + d.cmd.Stderr = out + d.logFile = out + + if err := d.cmd.Start(); err != nil { + return errors.Errorf("[%s] could not start daemon container: %v", d.id, err) + } + + wait := make(chan error) + + go func() { + wait <- d.cmd.Wait() + d.log.Logf("[%s] exiting daemon", d.id) + close(wait) + }() + + d.Wait = wait + + tick := time.Tick(500 * time.Millisecond) + // make sure daemon is ready to receive requests + startTime := time.Now().Unix() + for { + d.log.Logf("[%s] waiting for daemon to start", d.id) + if time.Now().Unix()-startTime > 5 { + // After 5 seconds, give up + return errors.Errorf("[%s] Daemon exited and never started", d.id) + } + select { + case <-time.After(2 * time.Second): + return errors.Errorf("[%s] timeout: daemon does not respond", d.id) + case <-tick: + clientConfig, err := d.getClientConfig() + if err != nil { + return err + } + + client := &http.Client{ + Transport: clientConfig.transport, + } + + req, err := http.NewRequest("GET", "/_ping", nil) + if err != nil { + return errors.Wrapf(err, "[%s] could not create new request", d.id) + } + req.URL.Host = clientConfig.addr + req.URL.Scheme = clientConfig.scheme + resp, err := client.Do(req) + if err != nil { + continue + } + resp.Body.Close() + if resp.StatusCode != http.StatusOK { + d.log.Logf("[%s] received status != 200 OK: %s\n", d.id, resp.Status) + } + d.log.Logf("[%s] daemon started\n", d.id) + d.Root, err = d.queryRootDir() + if err != nil { + return errors.Errorf("[%s] error querying daemon for root directory: %v", d.id, err) + } + return nil + case <-d.Wait: + return errors.Errorf("[%s] Daemon exited during startup", d.id) + } + } +} + +// StartWithBusybox will first start the daemon with Daemon.Start() +// then save the busybox image from the main daemon and load it into this Daemon instance. +func (d *Daemon) StartWithBusybox(t testingT, arg ...string) { + d.Start(t, arg...) + d.LoadBusybox(t) +} + +// Kill will send a SIGKILL to the daemon +func (d *Daemon) Kill() error { + if d.cmd == nil || d.Wait == nil { + return errDaemonNotStarted + } + + defer func() { + d.logFile.Close() + d.cmd = nil + }() + + if err := d.cmd.Process.Kill(); err != nil { + return err + } + + return os.Remove(fmt.Sprintf("%s/docker.pid", d.Folder)) +} + +// Pid returns the pid of the daemon +func (d *Daemon) Pid() int { + return d.cmd.Process.Pid +} + +// Interrupt stops the daemon by sending it an Interrupt signal +func (d *Daemon) Interrupt() error { + return d.Signal(os.Interrupt) +} + +// Signal sends the specified signal to the daemon if running +func (d *Daemon) Signal(signal os.Signal) error { + if d.cmd == nil || d.Wait == nil { + return errDaemonNotStarted + } + return d.cmd.Process.Signal(signal) +} + +// DumpStackAndQuit sends SIGQUIT to the daemon, which triggers it to dump its +// stack to its log file and exit +// This is used primarily for gathering debug information on test timeout +func (d *Daemon) DumpStackAndQuit() { + if d.cmd == nil || d.cmd.Process == nil { + return + } + SignalDaemonDump(d.cmd.Process.Pid) +} + +// Stop will send a SIGINT every second and wait for the daemon to stop. +// If it times out, a SIGKILL is sent. +// Stop will not delete the daemon directory. If a purged daemon is needed, +// instantiate a new one with NewDaemon. +// If an error occurs while starting the daemon, the test will fail. +func (d *Daemon) Stop(t testingT) { + err := d.StopWithError() + if err != nil { + if err != errDaemonNotStarted { + t.Fatalf("Error while stopping the daemon %s : %v", d.id, err) + } else { + t.Logf("Daemon %s is not started", d.id) + } + } +} + +// StopWithError will send a SIGINT every second and wait for the daemon to stop. +// If it timeouts, a SIGKILL is sent. +// Stop will not delete the daemon directory. If a purged daemon is needed, +// instantiate a new one with NewDaemon. +func (d *Daemon) StopWithError() error { + if d.cmd == nil || d.Wait == nil { + return errDaemonNotStarted + } + + defer func() { + d.logFile.Close() + d.cmd = nil + }() + + i := 1 + tick := time.Tick(time.Second) + + if err := d.cmd.Process.Signal(os.Interrupt); err != nil { + if strings.Contains(err.Error(), "os: process already finished") { + return errDaemonNotStarted + } + return errors.Errorf("could not send signal: %v", err) + } +out1: + for { + select { + case err := <-d.Wait: + return err + case <-time.After(20 * time.Second): + // time for stopping jobs and run onShutdown hooks + d.log.Logf("[%s] daemon started", d.id) + break out1 + } + } + +out2: + for { + select { + case err := <-d.Wait: + return err + case <-tick: + i++ + if i > 5 { + d.log.Logf("tried to interrupt daemon for %d times, now try to kill it", i) + break out2 + } + d.log.Logf("Attempt #%d: daemon is still running with pid %d", i, d.cmd.Process.Pid) + if err := d.cmd.Process.Signal(os.Interrupt); err != nil { + return errors.Errorf("could not send signal: %v", err) + } + } + } + + if err := d.cmd.Process.Kill(); err != nil { + d.log.Logf("Could not kill daemon: %v", err) + return err + } + + d.cmd.Wait() + + return os.Remove(fmt.Sprintf("%s/docker.pid", d.Folder)) +} + +// Restart will restart the daemon by first stopping it and the starting it. +// If an error occurs while starting the daemon, the test will fail. +func (d *Daemon) Restart(t testingT, args ...string) { + d.Stop(t) + d.handleUserns() + d.Start(t, args...) +} + +// RestartWithError will restart the daemon by first stopping it and then starting it. +func (d *Daemon) RestartWithError(arg ...string) error { + if err := d.StopWithError(); err != nil { + return err + } + d.handleUserns() + return d.StartWithError(arg...) +} + +func (d *Daemon) handleUserns() { + // in the case of tests running a user namespace-enabled daemon, we have resolved + // d.Root to be the actual final path of the graph dir after the "uid.gid" of + // remapped root is added--we need to subtract it from the path before calling + // start or else we will continue making subdirectories rather than truly restarting + // with the same location/root: + if root := os.Getenv("DOCKER_REMAP_ROOT"); root != "" { + d.Root = filepath.Dir(d.Root) + } +} + +// ReloadConfig asks the daemon to reload its configuration +func (d *Daemon) ReloadConfig() error { + if d.cmd == nil || d.cmd.Process == nil { + return errors.New("daemon is not running") + } + + errCh := make(chan error) + started := make(chan struct{}) + go func() { + _, body, err := request.DoOnHost(d.Sock(), "/events", request.Method(http.MethodGet)) + close(started) + if err != nil { + errCh <- err + } + defer body.Close() + dec := json.NewDecoder(body) + for { + var e events.Message + if err := dec.Decode(&e); err != nil { + errCh <- err + return + } + if e.Type != events.DaemonEventType { + continue + } + if e.Action != "reload" { + continue + } + close(errCh) // notify that we are done + return + } + }() + + <-started + if err := signalDaemonReload(d.cmd.Process.Pid); err != nil { + return errors.Errorf("error signaling daemon reload: %v", err) + } + select { + case err := <-errCh: + if err != nil { + return errors.Errorf("error waiting for daemon reload event: %v", err) + } + case <-time.After(30 * time.Second): + return errors.New("timeout waiting for daemon reload event") + } + return nil +} + +// LoadBusybox image into the daemon +func (d *Daemon) LoadBusybox(t assert.TestingT) { + clientHost, err := client.NewEnvClient() + assert.NilError(t, err, "failed to create client") + defer clientHost.Close() + + ctx := context.Background() + reader, err := clientHost.ImageSave(ctx, []string{"busybox:latest"}) + assert.NilError(t, err, "failed to download busybox") + defer reader.Close() + + client, err := d.NewClient() + assert.NilError(t, err, "failed to create client") + defer client.Close() + + resp, err := client.ImageLoad(ctx, reader, true) + assert.NilError(t, err, "failed to load busybox") + defer resp.Body.Close() +} + +func (d *Daemon) getClientConfig() (*clientConfig, error) { + var ( + transport *http.Transport + scheme string + addr string + proto string + ) + if d.UseDefaultTLSHost { + option := &tlsconfig.Options{ + CAFile: "fixtures/https/ca.pem", + CertFile: "fixtures/https/client-cert.pem", + KeyFile: "fixtures/https/client-key.pem", + } + tlsConfig, err := tlsconfig.Client(*option) + if err != nil { + return nil, err + } + transport = &http.Transport{ + TLSClientConfig: tlsConfig, + } + addr = fmt.Sprintf("%s:%d", opts.DefaultHTTPHost, opts.DefaultTLSHTTPPort) + scheme = "https" + proto = "tcp" + } else if d.UseDefaultHost { + addr = opts.DefaultUnixSocket + proto = "unix" + scheme = "http" + transport = &http.Transport{} + } else { + addr = d.sockPath() + proto = "unix" + scheme = "http" + transport = &http.Transport{} + } + + if err := sockets.ConfigureTransport(transport, proto, addr); err != nil { + return nil, err + } + transport.DisableKeepAlives = true + + return &clientConfig{ + transport: transport, + scheme: scheme, + addr: addr, + }, nil +} + +func (d *Daemon) queryRootDir() (string, error) { + // update daemon root by asking /info endpoint (to support user + // namespaced daemon with root remapped uid.gid directory) + clientConfig, err := d.getClientConfig() + if err != nil { + return "", err + } + + client := &http.Client{ + Transport: clientConfig.transport, + } + + req, err := http.NewRequest("GET", "/info", nil) + if err != nil { + return "", err + } + req.Header.Set("Content-Type", "application/json") + req.URL.Host = clientConfig.addr + req.URL.Scheme = clientConfig.scheme + + resp, err := client.Do(req) + if err != nil { + return "", err + } + body := ioutils.NewReadCloserWrapper(resp.Body, func() error { + return resp.Body.Close() + }) + + type Info struct { + DockerRootDir string + } + var b []byte + var i Info + b, err = request.ReadBody(body) + if err == nil && resp.StatusCode == http.StatusOK { + // read the docker root dir + if err = json.Unmarshal(b, &i); err == nil { + return i.DockerRootDir, nil + } + } + return "", err +} + +// Info returns the info struct for this daemon +func (d *Daemon) Info(t assert.TestingT) types.Info { + apiclient, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) + assert.NilError(t, err) + info, err := apiclient.Info(context.Background()) + assert.NilError(t, err) + return info +} diff --git a/components/engine/integration-cli/daemon/daemon_unix.go b/components/engine/internal/test/daemon/daemon_unix.go similarity index 78% rename from components/engine/integration-cli/daemon/daemon_unix.go rename to components/engine/internal/test/daemon/daemon_unix.go index 97548c31034..c0aa26c9f8b 100644 --- a/components/engine/integration-cli/daemon/daemon_unix.go +++ b/components/engine/internal/test/daemon/daemon_unix.go @@ -1,16 +1,15 @@ // +build !windows -package daemon // import "github.com/docker/docker/integration-cli/daemon" +package daemon // import "github.com/docker/docker/internal/test/daemon" import ( "os" "path/filepath" - "github.com/go-check/check" "golang.org/x/sys/unix" ) -func cleanupExecRoot(c *check.C, execRoot string) { +func cleanupExecRoot(t testingT, execRoot string) { // Cleanup network namespaces in the exec root of this // daemon because this exec root is specific to this // daemon instance and has no chance of getting @@ -19,7 +18,7 @@ func cleanupExecRoot(c *check.C, execRoot string) { netnsPath := filepath.Join(execRoot, "netns") filepath.Walk(netnsPath, func(path string, info os.FileInfo, err error) error { if err := unix.Unmount(path, unix.MNT_FORCE); err != nil { - c.Logf("unmount of %s failed: %v", path, err) + t.Logf("unmount of %s failed: %v", path, err) } os.Remove(path) return nil diff --git a/components/engine/integration-cli/daemon/daemon_windows.go b/components/engine/internal/test/daemon/daemon_windows.go similarity index 74% rename from components/engine/integration-cli/daemon/daemon_windows.go rename to components/engine/internal/test/daemon/daemon_windows.go index 63f6b03239b..8ec554fbc4c 100644 --- a/components/engine/integration-cli/daemon/daemon_windows.go +++ b/components/engine/internal/test/daemon/daemon_windows.go @@ -1,10 +1,9 @@ -package daemon // import "github.com/docker/docker/integration-cli/daemon" +package daemon // import "github.com/docker/docker/internal/test/daemon" import ( "fmt" "strconv" - "github.com/go-check/check" "golang.org/x/sys/windows" ) @@ -22,5 +21,5 @@ func signalDaemonReload(pid int) error { return fmt.Errorf("daemon reload not supported") } -func cleanupExecRoot(c *check.C, execRoot string) { +func cleanupExecRoot(t testingT, execRoot string) { } diff --git a/components/engine/internal/test/daemon/ops.go b/components/engine/internal/test/daemon/ops.go new file mode 100644 index 00000000000..0c49749414a --- /dev/null +++ b/components/engine/internal/test/daemon/ops.go @@ -0,0 +1,13 @@ +package daemon + +// WithExperimental sets the daemon in experimental mode +func WithExperimental(d *Daemon) { + d.experimental = true +} + +// WithDockerdBinary sets the dockerd binary to the specified one +func WithDockerdBinary(dockerdBinary string) func(*Daemon) { + return func(d *Daemon) { + d.dockerdBinary = dockerdBinary + } +} From 16e1ab0f89aeba680d15da2b91ec87b5ed091133 Mon Sep 17 00:00:00 2001 From: selansen Date: Fri, 9 Mar 2018 17:03:59 -0500 Subject: [PATCH 20/36] Fix for Flaky test TestServiceWithPredefinedNetwork TestServiceWithPredefinedNetwork test case was failing at times. To fix the issue, added new API to check for services after we clean up all services. Tested multiple times and this sould fix flaky issue. Signed-off-by: selansen (cherry picked from commit dabffd806c98ab13dbc25e57bee21c5291b9a50c) Signed-off-by: Sebastiaan van Stijn --- .../integration/network/service_test.go | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/components/engine/integration/network/service_test.go b/components/engine/integration/network/service_test.go index a9fccf95221..ea7391180aa 100644 --- a/components/engine/integration/network/service_test.go +++ b/components/engine/integration/network/service_test.go @@ -6,7 +6,6 @@ import ( "time" "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/filters" swarmtypes "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" "github.com/docker/docker/integration/internal/swarm" @@ -51,10 +50,6 @@ func TestServiceWithPredefinedNetwork(t *testing.T) { err = client.ServiceRemove(context.Background(), serviceID) assert.NilError(t, err) - - poll.WaitOn(t, serviceIsRemoved(client, serviceID), pollSettings) - poll.WaitOn(t, noTasks(client), pollSettings) - } const ingressNet = "ingress" @@ -108,7 +103,7 @@ func TestServiceWithIngressNetwork(t *testing.T) { assert.NilError(t, err) poll.WaitOn(t, serviceIsRemoved(client, serviceID), pollSettings) - poll.WaitOn(t, noTasks(client), pollSettings) + poll.WaitOn(t, noServices(client), pollSettings) // Ensure that "ingress" is not removed or corrupted time.Sleep(10 * time.Second) @@ -125,8 +120,6 @@ func TestServiceWithIngressNetwork(t *testing.T) { func serviceRunningCount(client client.ServiceAPIClient, serviceID string, instances uint64) func(log poll.LogT) poll.Result { return func(log poll.LogT) poll.Result { - filter := filters.NewArgs() - filter.Add("service", serviceID) services, err := client.ServiceList(context.Background(), types.ServiceListOptions{}) if err != nil { return poll.Error(err) @@ -160,3 +153,17 @@ func swarmIngressReady(client client.NetworkAPIClient) func(log poll.LogT) poll. return poll.Success() } } + +func noServices(client client.ServiceAPIClient) func(log poll.LogT) poll.Result { + return func(log poll.LogT) poll.Result { + services, err := client.ServiceList(context.Background(), types.ServiceListOptions{}) + switch { + case err != nil: + return poll.Error(err) + case len(services) == 0: + return poll.Success() + default: + return poll.Continue("Service count at %d waiting for 0", len(services)) + } + } +} From 176c10200c098206d852c054e9723841f7870803 Mon Sep 17 00:00:00 2001 From: Dennis Chen Date: Tue, 27 Mar 2018 03:36:55 +0000 Subject: [PATCH 21/36] Add default pollSettings adjustment routines Add the default function per resource to override the `pollSettings` which will be re-used where it's needed. Signed-off-by: Dennis Chen (cherry picked from commit ee6959addc5664a5c55765f2c721f84414ea4779) Signed-off-by: Sebastiaan van Stijn --- .../integration/internal/swarm/service.go | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/components/engine/integration/internal/swarm/service.go b/components/engine/integration/internal/swarm/service.go index 79705961a1b..28d367c6601 100644 --- a/components/engine/integration/internal/swarm/service.go +++ b/components/engine/integration/internal/swarm/service.go @@ -3,7 +3,9 @@ package swarm import ( "context" "fmt" + "runtime" "testing" + "time" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" @@ -12,6 +14,7 @@ import ( "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/internal/test/environment" "github.com/gotestyourself/gotestyourself/assert" + "github.com/gotestyourself/gotestyourself/poll" "github.com/gotestyourself/gotestyourself/skip" ) @@ -20,6 +23,37 @@ const ( defaultSwarmPort = 2477 ) +// ServicePoll tweaks the pollSettings for `service` +func ServicePoll(config *poll.Settings) { + // Override the default pollSettings for `service` resource here ... + + if runtime.GOARCH == "arm64" || runtime.GOARCH == "arm" { + config.Timeout = 1 * time.Minute + config.Delay = 100 * time.Millisecond + } +} + +// NetworkPoll tweaks the pollSettings for `network` +func NetworkPoll(config *poll.Settings) { + // Override the default pollSettings for `network` resource here ... + config.Timeout = 30 * time.Second + config.Delay = 100 * time.Millisecond + + if runtime.GOARCH == "arm64" || runtime.GOARCH == "arm" { + config.Timeout = 50 * time.Second + } +} + +// ContainerPoll tweaks the pollSettings for `container` +func ContainerPoll(config *poll.Settings) { + // Override the default pollSettings for `container` resource here ... + + if runtime.GOARCH == "arm64" || runtime.GOARCH == "arm" { + config.Timeout = 30 * time.Second + config.Delay = 100 * time.Millisecond + } +} + // NewSwarm creates a swarm daemon for testing func NewSwarm(t *testing.T, testEnv *environment.Execution) *daemon.Swarm { skip.IfCondition(t, testEnv.IsRemoteDaemon()) From e0b31bfb7b9eda60ac98638924d07bb4f718cc65 Mon Sep 17 00:00:00 2001 From: Dennis Chen Date: Tue, 27 Mar 2018 04:06:46 +0000 Subject: [PATCH 22/36] Using the default PollSettings function Using the default PollSettings functions to adjust the timeout value instead of changing the value each time when needed. Signed-off-by: Dennis Chen (cherry picked from commit b8912feeffcdfd489c9fc1212277840adac2719c) Signed-off-by: Sebastiaan van Stijn --- .../integration/network/inspect_test.go | 20 ++++-------- .../integration/network/service_test.go | 31 +++---------------- .../engine/integration/service/create_test.go | 31 +++++++------------ 3 files changed, 22 insertions(+), 60 deletions(-) diff --git a/components/engine/integration/network/inspect_test.go b/components/engine/integration/network/inspect_test.go index 22d18b74743..3f23c61ae25 100644 --- a/components/engine/integration/network/inspect_test.go +++ b/components/engine/integration/network/inspect_test.go @@ -1,7 +1,6 @@ package network // import "github.com/docker/docker/integration/network" import ( - "runtime" "testing" "time" @@ -45,15 +44,8 @@ func TestInspectNetwork(t *testing.T) { }) assert.NilError(t, err) - pollSettings := func(config *poll.Settings) { - if runtime.GOARCH == "arm64" || runtime.GOARCH == "arm" { - config.Timeout = 30 * time.Second - config.Delay = 100 * time.Millisecond - } - } - serviceID := serviceResp.ID - poll.WaitOn(t, serviceRunningTasksCount(client, serviceID, instances), pollSettings) + poll.WaitOn(t, serviceRunningTasksCount(client, serviceID, instances), swarm.ServicePoll) _, _, err = client.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{}) assert.NilError(t, err) @@ -83,8 +75,8 @@ func TestInspectNetwork(t *testing.T) { err = client.ServiceRemove(context.Background(), serviceID) assert.NilError(t, err) - poll.WaitOn(t, serviceIsRemoved(client, serviceID), pollSettings) - poll.WaitOn(t, noTasks(client), pollSettings) + poll.WaitOn(t, serviceIsRemoved(client, serviceID), swarm.ServicePoll) + poll.WaitOn(t, noTasks(client), swarm.ServicePoll) serviceResp, err = client.ServiceCreate(context.Background(), serviceSpec, types.ServiceCreateOptions{ QueryRegistry: false, @@ -92,13 +84,13 @@ func TestInspectNetwork(t *testing.T) { assert.NilError(t, err) serviceID2 := serviceResp.ID - poll.WaitOn(t, serviceRunningTasksCount(client, serviceID2, instances), pollSettings) + poll.WaitOn(t, serviceRunningTasksCount(client, serviceID2, instances), swarm.ServicePoll) err = client.ServiceRemove(context.Background(), serviceID2) assert.NilError(t, err) - poll.WaitOn(t, serviceIsRemoved(client, serviceID2), pollSettings) - poll.WaitOn(t, noTasks(client), pollSettings) + poll.WaitOn(t, serviceIsRemoved(client, serviceID2), swarm.ServicePoll) + poll.WaitOn(t, noTasks(client), swarm.ServicePoll) err = client.NetworkRemove(context.Background(), overlayID) assert.NilError(t, err) diff --git a/components/engine/integration/network/service_test.go b/components/engine/integration/network/service_test.go index ea7391180aa..1b729d11570 100644 --- a/components/engine/integration/network/service_test.go +++ b/components/engine/integration/network/service_test.go @@ -1,7 +1,6 @@ package network // import "github.com/docker/docker/integration/network" import ( - "runtime" "testing" "time" @@ -32,18 +31,8 @@ func TestServiceWithPredefinedNetwork(t *testing.T) { }) assert.NilError(t, err) - pollSettings := func(config *poll.Settings) { - if runtime.GOARCH == "arm64" || runtime.GOARCH == "arm" { - config.Timeout = 50 * time.Second - config.Delay = 100 * time.Millisecond - } else { - config.Timeout = 30 * time.Second - config.Delay = 100 * time.Millisecond - } - } - serviceID := serviceResp.ID - poll.WaitOn(t, serviceRunningCount(client, serviceID, instances), pollSettings) + poll.WaitOn(t, serviceRunningCount(client, serviceID, instances), swarm.ServicePoll) _, _, err = client.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{}) assert.NilError(t, err) @@ -62,17 +51,7 @@ func TestServiceWithIngressNetwork(t *testing.T) { client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) assert.NilError(t, err) - pollSettings := func(config *poll.Settings) { - if runtime.GOARCH == "arm64" || runtime.GOARCH == "arm" { - config.Timeout = 50 * time.Second - config.Delay = 100 * time.Millisecond - } else { - config.Timeout = 30 * time.Second - config.Delay = 100 * time.Millisecond - } - } - - poll.WaitOn(t, swarmIngressReady(client), pollSettings) + poll.WaitOn(t, swarmIngressReady(client), swarm.NetworkPoll) var instances uint64 = 1 serviceName := "TestIngressService" @@ -94,7 +73,7 @@ func TestServiceWithIngressNetwork(t *testing.T) { assert.NilError(t, err) serviceID := serviceResp.ID - poll.WaitOn(t, serviceRunningCount(client, serviceID, instances), pollSettings) + poll.WaitOn(t, serviceRunningCount(client, serviceID, instances), swarm.ServicePoll) _, _, err = client.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{}) assert.NilError(t, err) @@ -102,8 +81,8 @@ func TestServiceWithIngressNetwork(t *testing.T) { err = client.ServiceRemove(context.Background(), serviceID) assert.NilError(t, err) - poll.WaitOn(t, serviceIsRemoved(client, serviceID), pollSettings) - poll.WaitOn(t, noServices(client), pollSettings) + poll.WaitOn(t, serviceIsRemoved(client, serviceID), swarm.ServicePoll) + poll.WaitOn(t, noServices(client), swarm.ServicePoll) // Ensure that "ingress" is not removed or corrupted time.Sleep(10 * time.Second) diff --git a/components/engine/integration/service/create_test.go b/components/engine/integration/service/create_test.go index 7170bda492e..9522b059ef5 100644 --- a/components/engine/integration/service/create_test.go +++ b/components/engine/integration/service/create_test.go @@ -2,7 +2,6 @@ package service // import "github.com/docker/docker/integration/service" import ( "io/ioutil" - "runtime" "testing" "time" @@ -43,16 +42,8 @@ func TestCreateServiceMultipleTimes(t *testing.T) { }) assert.NilError(t, err) - pollSettings := func(config *poll.Settings) { - // It takes about ~25s to finish the multi services creation in this case per the pratical observation on arm64/arm platform - if runtime.GOARCH == "arm64" || runtime.GOARCH == "arm" { - config.Timeout = 30 * time.Second - config.Delay = 100 * time.Millisecond - } - } - serviceID := serviceResp.ID - poll.WaitOn(t, serviceRunningTasksCount(client, serviceID, instances), pollSettings) + poll.WaitOn(t, serviceRunningTasksCount(client, serviceID, instances), swarm.ServicePoll) _, _, err = client.ServiceInspectWithRaw(context.Background(), serviceID, types.ServiceInspectOptions{}) assert.NilError(t, err) @@ -60,8 +51,8 @@ func TestCreateServiceMultipleTimes(t *testing.T) { err = client.ServiceRemove(context.Background(), serviceID) assert.NilError(t, err) - poll.WaitOn(t, serviceIsRemoved(client, serviceID), pollSettings) - poll.WaitOn(t, noTasks(client), pollSettings) + poll.WaitOn(t, serviceIsRemoved(client, serviceID), swarm.ServicePoll) + poll.WaitOn(t, noTasks(client), swarm.ServicePoll) serviceResp, err = client.ServiceCreate(context.Background(), serviceSpec, types.ServiceCreateOptions{ QueryRegistry: false, @@ -69,13 +60,13 @@ func TestCreateServiceMultipleTimes(t *testing.T) { assert.NilError(t, err) serviceID2 := serviceResp.ID - poll.WaitOn(t, serviceRunningTasksCount(client, serviceID2, instances), pollSettings) + poll.WaitOn(t, serviceRunningTasksCount(client, serviceID2, instances), swarm.ServicePoll) err = client.ServiceRemove(context.Background(), serviceID2) assert.NilError(t, err) - poll.WaitOn(t, serviceIsRemoved(client, serviceID2), pollSettings) - poll.WaitOn(t, noTasks(client), pollSettings) + poll.WaitOn(t, serviceIsRemoved(client, serviceID2), swarm.ServicePoll) + poll.WaitOn(t, noTasks(client), swarm.ServicePoll) err = client.NetworkRemove(context.Background(), overlayID) assert.NilError(t, err) @@ -116,7 +107,7 @@ func TestCreateWithDuplicateNetworkNames(t *testing.T) { service, err := client.ServiceCreate(context.Background(), serviceSpec, types.ServiceCreateOptions{}) assert.NilError(t, err) - poll.WaitOn(t, serviceRunningTasksCount(client, service.ID, instances)) + poll.WaitOn(t, serviceRunningTasksCount(client, service.ID, instances), swarm.ServicePoll) resp, _, err := client.ServiceInspectWithRaw(context.Background(), service.ID, types.ServiceInspectOptions{}) assert.NilError(t, err) @@ -127,7 +118,7 @@ func TestCreateWithDuplicateNetworkNames(t *testing.T) { assert.NilError(t, err) // Make sure task has been destroyed. - poll.WaitOn(t, serviceIsRemoved(client, service.ID)) + poll.WaitOn(t, serviceIsRemoved(client, service.ID), swarm.ServicePoll) // Remove networks err = client.NetworkRemove(context.Background(), n3.ID) @@ -196,7 +187,7 @@ func TestCreateServiceSecretFileMode(t *testing.T) { }) assert.NilError(t, err) - poll.WaitOn(t, serviceRunningTasksCount(client, serviceResp.ID, instances)) + poll.WaitOn(t, serviceRunningTasksCount(client, serviceResp.ID, instances), swarm.ServicePoll) filter := filters.NewArgs() filter.Add("service", serviceResp.ID) @@ -219,8 +210,8 @@ func TestCreateServiceSecretFileMode(t *testing.T) { err = client.ServiceRemove(ctx, serviceResp.ID) assert.NilError(t, err) - poll.WaitOn(t, serviceIsRemoved(client, serviceResp.ID)) - poll.WaitOn(t, noTasks(client)) + poll.WaitOn(t, serviceIsRemoved(client, serviceResp.ID), swarm.ServicePoll) + poll.WaitOn(t, noTasks(client), swarm.ServicePoll) err = client.SecretRemove(ctx, "TestSecret") assert.NilError(t, err) From 174c840b969c688258c1d5c7ca4fd3b3cf73d136 Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Wed, 11 Apr 2018 12:10:17 +0200 Subject: [PATCH 23/36] Make internal/test/daemon.Daemon swarm aware This remove the daemon.Swarm construction by make the new test Daemon struct aware of swarm. Signed-off-by: Vincent Demeester (cherry picked from commit 83d18cf4e3e84055f7034816eed2a10c04e777ca) Signed-off-by: Sebastiaan van Stijn --- .../engine/integration-cli/check_test.go | 22 +- .../engine/integration-cli/daemon/daemon.go | 21 +- .../integration-cli/daemon/daemon_swarm.go | 494 +----------------- .../integration-cli/daemon_swarm_hack_test.go | 4 +- .../docker_api_swarm_node_test.go | 13 +- .../docker_api_swarm_service_test.go | 19 +- .../integration-cli/docker_api_swarm_test.go | 240 +++++---- .../docker_cli_prune_unix_test.go | 2 +- .../docker_cli_service_logs_test.go | 2 +- .../integration-cli/docker_cli_swarm_test.go | 67 ++- .../integration/internal/swarm/service.go | 32 +- .../engine/internal/test/daemon/config.go | 66 +++ .../engine/internal/test/daemon/daemon.go | 38 +- .../engine/internal/test/daemon/node.go | 69 +++ components/engine/internal/test/daemon/ops.go | 14 + .../engine/internal/test/daemon/secret.go | 68 +++ .../engine/internal/test/daemon/service.go | 108 ++++ .../engine/internal/test/daemon/swarm.go | 139 +++++ 18 files changed, 721 insertions(+), 697 deletions(-) create mode 100644 components/engine/internal/test/daemon/config.go create mode 100644 components/engine/internal/test/daemon/node.go create mode 100644 components/engine/internal/test/daemon/secret.go create mode 100644 components/engine/internal/test/daemon/service.go create mode 100644 components/engine/internal/test/daemon/swarm.go diff --git a/components/engine/integration-cli/check_test.go b/components/engine/integration-cli/check_test.go index a455893d8c5..0cae1503f88 100644 --- a/components/engine/integration-cli/check_test.go +++ b/components/engine/integration-cli/check_test.go @@ -311,7 +311,7 @@ func init() { type DockerSwarmSuite struct { server *httptest.Server ds *DockerSuite - daemons []*daemon.Swarm + daemons []*daemon.Daemon daemonsLock sync.Mutex // protect access to daemons portIndex int } @@ -328,14 +328,10 @@ func (s *DockerSwarmSuite) SetUpTest(c *check.C) { testRequires(c, DaemonIsLinux, SameHostDaemon) } -func (s *DockerSwarmSuite) AddDaemon(c *check.C, joinSwarm, manager bool) *daemon.Swarm { - d := &daemon.Swarm{ - Daemon: daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }), - Port: defaultSwarmPort + s.portIndex, - } - d.ListenAddr = fmt.Sprintf("0.0.0.0:%d", d.Port) +func (s *DockerSwarmSuite) AddDaemon(c *check.C, joinSwarm, manager bool) *daemon.Daemon { + d := daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ + Experimental: testEnv.DaemonInfo.ExperimentalBuild, + }, testdaemon.WithSwarmPort(defaultSwarmPort+s.portIndex)) args := []string{"--iptables=false", "--swarm-default-advertise-addr=lo"} // avoid networking conflicts d.StartWithBusybox(c, args...) @@ -346,12 +342,12 @@ func (s *DockerSwarmSuite) AddDaemon(c *check.C, joinSwarm, manager bool) *daemo if manager { token = tokens.Manager } - c.Assert(d.Join(swarm.JoinRequest{ - RemoteAddrs: []string{s.daemons[0].ListenAddr}, + d.SwarmJoin(c, swarm.JoinRequest{ + RemoteAddrs: []string{s.daemons[0].SwarmListenAddr()}, JoinToken: token, - }), check.IsNil) + }) } else { - c.Assert(d.Init(swarm.InitRequest{}), check.IsNil) + d.SwarmInit(c, swarm.InitRequest{}) } } diff --git a/components/engine/integration-cli/daemon/daemon.go b/components/engine/integration-cli/daemon/daemon.go index 4ef1dafe79a..0ec9e892b22 100644 --- a/components/engine/integration-cli/daemon/daemon.go +++ b/components/engine/integration-cli/daemon/daemon.go @@ -38,10 +38,8 @@ type Config struct { // New returns a Daemon instance to be used for testing. // This will create a directory such as d123456789 in the folder specified by $DOCKER_INTEGRATION_DAEMON_DEST or $DEST. // The daemon will not automatically start. -func New(t testingT, dockerBinary string, dockerdBinary string, config Config) *Daemon { - ops := []func(*daemon.Daemon){ - daemon.WithDockerdBinary(dockerdBinary), - } +func New(t testingT, dockerBinary string, dockerdBinary string, config Config, ops ...func(*daemon.Daemon)) *Daemon { + ops = append(ops, daemon.WithDockerdBinary(dockerdBinary)) if config.Experimental { ops = append(ops, daemon.WithExperimental) } @@ -150,6 +148,21 @@ func (d *Daemon) WaitRun(contID string) error { return WaitInspectWithArgs(d.dockerBinary, contID, "{{.State.Running}}", "true", 10*time.Second, args...) } +// CmdRetryOutOfSequence tries the specified command against the current daemon for 10 times +func (d *Daemon) CmdRetryOutOfSequence(args ...string) (string, error) { + for i := 0; ; i++ { + out, err := d.Cmd(args...) + if err != nil { + if strings.Contains(out, "update out of sequence") { + if i < 10 { + continue + } + } + } + return out, err + } +} + // WaitInspectWithArgs waits for the specified expression to be equals to the specified expected string in the given time. // Deprecated: use cli.WaitCmd instead func WaitInspectWithArgs(dockerBinary, name, expr, expected string, timeout time.Duration, arg ...string) error { diff --git a/components/engine/integration-cli/daemon/daemon_swarm.go b/components/engine/integration-cli/daemon/daemon_swarm.go index be0ddef99e8..cf75724a32f 100644 --- a/components/engine/integration-cli/daemon/daemon_swarm.go +++ b/components/engine/integration-cli/daemon/daemon_swarm.go @@ -3,7 +3,6 @@ package daemon // import "github.com/docker/docker/integration-cli/daemon" import ( "fmt" "strings" - "time" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" @@ -12,178 +11,12 @@ import ( "github.com/docker/docker/integration-cli/checker" "github.com/go-check/check" "github.com/gotestyourself/gotestyourself/assert" - "github.com/pkg/errors" "golang.org/x/net/context" ) -// Swarm is a test daemon with helpers for participating in a swarm. -type Swarm struct { - *Daemon - swarm.Info - Port int - ListenAddr string -} - -// Init initializes a new swarm cluster. -func (d *Swarm) Init(req swarm.InitRequest) error { - if req.ListenAddr == "" { - req.ListenAddr = d.ListenAddr - } - cli, err := d.NewClient() - if err != nil { - return fmt.Errorf("initializing swarm: failed to create client %v", err) - } - defer cli.Close() - _, err = cli.SwarmInit(context.Background(), req) - if err != nil { - return fmt.Errorf("initializing swarm: %v", err) - } - info, err := d.SwarmInfo() - if err != nil { - return err - } - d.Info = info - return nil -} - -// Join joins a daemon to an existing cluster. -func (d *Swarm) Join(req swarm.JoinRequest) error { - if req.ListenAddr == "" { - req.ListenAddr = d.ListenAddr - } - cli, err := d.NewClient() - if err != nil { - return fmt.Errorf("joining swarm: failed to create client %v", err) - } - defer cli.Close() - err = cli.SwarmJoin(context.Background(), req) - if err != nil { - return fmt.Errorf("joining swarm: %v", err) - } - info, err := d.SwarmInfo() - if err != nil { - return err - } - d.Info = info - return nil -} - -// Leave forces daemon to leave current cluster. -func (d *Swarm) Leave(force bool) error { - cli, err := d.NewClient() - if err != nil { - return fmt.Errorf("leaving swarm: failed to create client %v", err) - } - defer cli.Close() - err = cli.SwarmLeave(context.Background(), force) - if err != nil { - err = fmt.Errorf("leaving swarm: %v", err) - } - return err -} - -// SwarmInfo returns the swarm information of the daemon -func (d *Swarm) SwarmInfo() (swarm.Info, error) { - cli, err := d.NewClient() - if err != nil { - return swarm.Info{}, fmt.Errorf("get swarm info: %v", err) - } - - info, err := cli.Info(context.Background()) - if err != nil { - return swarm.Info{}, fmt.Errorf("get swarm info: %v", err) - } - - return info.Swarm, nil -} - -// Unlock tries to unlock a locked swarm -func (d *Swarm) Unlock(req swarm.UnlockRequest) error { - cli, err := d.NewClient() - if err != nil { - return fmt.Errorf("unlocking swarm: failed to create client %v", err) - } - defer cli.Close() - err = cli.SwarmUnlock(context.Background(), req) - if err != nil { - err = errors.Wrap(err, "unlocking swarm") - } - return err -} - -// ServiceConstructor defines a swarm service constructor function -type ServiceConstructor func(*swarm.Service) - -// NodeConstructor defines a swarm node constructor -type NodeConstructor func(*swarm.Node) - -// SecretConstructor defines a swarm secret constructor -type SecretConstructor func(*swarm.Secret) - -// ConfigConstructor defines a swarm config constructor -type ConfigConstructor func(*swarm.Config) - -// SpecConstructor defines a swarm spec constructor -type SpecConstructor func(*swarm.Spec) - -// CreateServiceWithOptions creates a swarm service given the specified service constructors -// and auth config -func (d *Swarm) CreateServiceWithOptions(c *check.C, opts types.ServiceCreateOptions, f ...ServiceConstructor) string { - var service swarm.Service - for _, fn := range f { - fn(&service) - } - - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - - res, err := cli.ServiceCreate(ctx, service.Spec, opts) - c.Assert(err, checker.IsNil) - return res.ID -} - -// CreateService creates a swarm service given the specified service constructor -func (d *Swarm) CreateService(c *check.C, f ...ServiceConstructor) string { - return d.CreateServiceWithOptions(c, types.ServiceCreateOptions{}, f...) -} - -// GetService returns the swarm service corresponding to the specified id -func (d *Swarm) GetService(c *check.C, id string) *swarm.Service { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - service, _, err := cli.ServiceInspectWithRaw(context.Background(), id, types.ServiceInspectOptions{}) - c.Assert(err, checker.IsNil) - return &service -} - -// GetServiceTasks returns the swarm tasks for the specified service -func (d *Swarm) GetServiceTasks(c *check.C, service string) []swarm.Task { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - filterArgs := filters.NewArgs() - filterArgs.Add("desired-state", "running") - filterArgs.Add("service", service) - - options := types.TaskListOptions{ - Filters: filterArgs, - } - - tasks, err := cli.TaskList(context.Background(), options) - c.Assert(err, checker.IsNil) - return tasks -} - // CheckServiceTasksInState returns the number of tasks with a matching state, // and optional message substring. -func (d *Swarm) CheckServiceTasksInState(service string, state swarm.TaskState, message string) func(*check.C) (interface{}, check.CommentInterface) { +func (d *Daemon) CheckServiceTasksInState(service string, state swarm.TaskState, message string) func(*check.C) (interface{}, check.CommentInterface) { return func(c *check.C) (interface{}, check.CommentInterface) { tasks := d.GetServiceTasks(c, service) var count int @@ -200,7 +33,7 @@ func (d *Swarm) CheckServiceTasksInState(service string, state swarm.TaskState, // CheckServiceTasksInStateWithError returns the number of tasks with a matching state, // and optional message substring. -func (d *Swarm) CheckServiceTasksInStateWithError(service string, state swarm.TaskState, errorMessage string) func(*check.C) (interface{}, check.CommentInterface) { +func (d *Daemon) CheckServiceTasksInStateWithError(service string, state swarm.TaskState, errorMessage string) func(*check.C) (interface{}, check.CommentInterface) { return func(c *check.C) (interface{}, check.CommentInterface) { tasks := d.GetServiceTasks(c, service) var count int @@ -216,12 +49,12 @@ func (d *Swarm) CheckServiceTasksInStateWithError(service string, state swarm.Ta } // CheckServiceRunningTasks returns the number of running tasks for the specified service -func (d *Swarm) CheckServiceRunningTasks(service string) func(*check.C) (interface{}, check.CommentInterface) { +func (d *Daemon) CheckServiceRunningTasks(service string) func(*check.C) (interface{}, check.CommentInterface) { return d.CheckServiceTasksInState(service, swarm.TaskStateRunning, "") } // CheckServiceUpdateState returns the current update state for the specified service -func (d *Swarm) CheckServiceUpdateState(service string) func(*check.C) (interface{}, check.CommentInterface) { +func (d *Daemon) CheckServiceUpdateState(service string) func(*check.C) (interface{}, check.CommentInterface) { return func(c *check.C) (interface{}, check.CommentInterface) { service := d.GetService(c, service) if service.UpdateStatus == nil { @@ -232,7 +65,7 @@ func (d *Swarm) CheckServiceUpdateState(service string) func(*check.C) (interfac } // CheckPluginRunning returns the runtime state of the plugin -func (d *Swarm) CheckPluginRunning(plugin string) func(c *check.C) (interface{}, check.CommentInterface) { +func (d *Daemon) CheckPluginRunning(plugin string) func(c *check.C) (interface{}, check.CommentInterface) { return func(c *check.C) (interface{}, check.CommentInterface) { apiclient, err := d.NewClient() assert.NilError(c, err) @@ -246,7 +79,7 @@ func (d *Swarm) CheckPluginRunning(plugin string) func(c *check.C) (interface{}, } // CheckPluginImage returns the runtime state of the plugin -func (d *Swarm) CheckPluginImage(plugin string) func(c *check.C) (interface{}, check.CommentInterface) { +func (d *Daemon) CheckPluginImage(plugin string) func(c *check.C) (interface{}, check.CommentInterface) { return func(c *check.C) (interface{}, check.CommentInterface) { apiclient, err := d.NewClient() assert.NilError(c, err) @@ -260,7 +93,7 @@ func (d *Swarm) CheckPluginImage(plugin string) func(c *check.C) (interface{}, c } // CheckServiceTasks returns the number of tasks for the specified service -func (d *Swarm) CheckServiceTasks(service string) func(*check.C) (interface{}, check.CommentInterface) { +func (d *Daemon) CheckServiceTasks(service string) func(*check.C) (interface{}, check.CommentInterface) { return func(c *check.C) (interface{}, check.CommentInterface) { tasks := d.GetServiceTasks(c, service) return len(tasks), nil @@ -268,7 +101,7 @@ func (d *Swarm) CheckServiceTasks(service string) func(*check.C) (interface{}, c } // CheckRunningTaskNetworks returns the number of times each network is referenced from a task. -func (d *Swarm) CheckRunningTaskNetworks(c *check.C) (interface{}, check.CommentInterface) { +func (d *Daemon) CheckRunningTaskNetworks(c *check.C) (interface{}, check.CommentInterface) { cli, err := d.NewClient() c.Assert(err, checker.IsNil) defer cli.Close() @@ -293,7 +126,7 @@ func (d *Swarm) CheckRunningTaskNetworks(c *check.C) (interface{}, check.Comment } // CheckRunningTaskImages returns the times each image is running as a task. -func (d *Swarm) CheckRunningTaskImages(c *check.C) (interface{}, check.CommentInterface) { +func (d *Daemon) CheckRunningTaskImages(c *check.C) (interface{}, check.CommentInterface) { cli, err := d.NewClient() c.Assert(err, checker.IsNil) defer cli.Close() @@ -318,7 +151,7 @@ func (d *Swarm) CheckRunningTaskImages(c *check.C) (interface{}, check.CommentIn } // CheckNodeReadyCount returns the number of ready node on the swarm -func (d *Swarm) CheckNodeReadyCount(c *check.C) (interface{}, check.CommentInterface) { +func (d *Daemon) CheckNodeReadyCount(c *check.C) (interface{}, check.CommentInterface) { nodes := d.ListNodes(c) var readyCount int for _, node := range nodes { @@ -329,303 +162,21 @@ func (d *Swarm) CheckNodeReadyCount(c *check.C) (interface{}, check.CommentInter return readyCount, nil } -// GetTask returns the swarm task identified by the specified id -func (d *Swarm) GetTask(c *check.C, id string) swarm.Task { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - task, _, err := cli.TaskInspectWithRaw(context.Background(), id) - c.Assert(err, checker.IsNil) - return task -} - -// UpdateService updates a swarm service with the specified service constructor -func (d *Swarm) UpdateService(c *check.C, service *swarm.Service, f ...ServiceConstructor) { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - for _, fn := range f { - fn(service) - } - - _, err = cli.ServiceUpdate(context.Background(), service.ID, service.Version, service.Spec, types.ServiceUpdateOptions{}) - c.Assert(err, checker.IsNil) -} - -// RemoveService removes the specified service -func (d *Swarm) RemoveService(c *check.C, id string) { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - err = cli.ServiceRemove(context.Background(), id) - c.Assert(err, checker.IsNil) -} - -// GetNode returns a swarm node identified by the specified id -func (d *Swarm) GetNode(c *check.C, id string) *swarm.Node { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - node, _, err := cli.NodeInspectWithRaw(context.Background(), id) - c.Assert(err, checker.IsNil) - c.Assert(node.ID, checker.Equals, id) - return &node -} - -// RemoveNode removes the specified node -func (d *Swarm) RemoveNode(c *check.C, id string, force bool) { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - options := types.NodeRemoveOptions{ - Force: force, - } - err = cli.NodeRemove(context.Background(), id, options) - c.Assert(err, checker.IsNil) -} - -// UpdateNode updates a swarm node with the specified node constructor -func (d *Swarm) UpdateNode(c *check.C, id string, f ...NodeConstructor) { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - for i := 0; ; i++ { - node := d.GetNode(c, id) - for _, fn := range f { - fn(node) - } - - err = cli.NodeUpdate(context.Background(), node.ID, node.Version, node.Spec) - if i < 10 && err != nil && strings.Contains(err.Error(), "update out of sequence") { - time.Sleep(100 * time.Millisecond) - continue - } - c.Assert(err, checker.IsNil) - return - } -} - -// ListNodes returns the list of the current swarm nodes -func (d *Swarm) ListNodes(c *check.C) []swarm.Node { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - nodes, err := cli.NodeList(context.Background(), types.NodeListOptions{}) - c.Assert(err, checker.IsNil) - - return nodes -} - -// ListServices returns the list of the current swarm services -func (d *Swarm) ListServices(c *check.C) []swarm.Service { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - services, err := cli.ServiceList(context.Background(), types.ServiceListOptions{}) - c.Assert(err, checker.IsNil) - return services -} - -// CreateSecret creates a secret given the specified spec -func (d *Swarm) CreateSecret(c *check.C, secretSpec swarm.SecretSpec) string { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - scr, err := cli.SecretCreate(context.Background(), secretSpec) - c.Assert(err, checker.IsNil) - - return scr.ID -} - -// ListSecrets returns the list of the current swarm secrets -func (d *Swarm) ListSecrets(c *check.C) []swarm.Secret { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - secrets, err := cli.SecretList(context.Background(), types.SecretListOptions{}) - c.Assert(err, checker.IsNil) - return secrets -} - -// GetSecret returns a swarm secret identified by the specified id -func (d *Swarm) GetSecret(c *check.C, id string) *swarm.Secret { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - secret, _, err := cli.SecretInspectWithRaw(context.Background(), id) - c.Assert(err, checker.IsNil) - return &secret -} - -// DeleteSecret removes the swarm secret identified by the specified id -func (d *Swarm) DeleteSecret(c *check.C, id string) { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - err = cli.SecretRemove(context.Background(), id) - c.Assert(err, checker.IsNil) -} - -// UpdateSecret updates the swarm secret identified by the specified id -// Currently, only label update is supported. -func (d *Swarm) UpdateSecret(c *check.C, id string, f ...SecretConstructor) { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - secret := d.GetSecret(c, id) - for _, fn := range f { - fn(secret) - } - - err = cli.SecretUpdate(context.Background(), secret.ID, secret.Version, secret.Spec) - - c.Assert(err, checker.IsNil) -} - -// CreateConfig creates a config given the specified spec -func (d *Swarm) CreateConfig(c *check.C, configSpec swarm.ConfigSpec) string { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - scr, err := cli.ConfigCreate(context.Background(), configSpec) - c.Assert(err, checker.IsNil) - return scr.ID -} - -// ListConfigs returns the list of the current swarm configs -func (d *Swarm) ListConfigs(c *check.C) []swarm.Config { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - configs, err := cli.ConfigList(context.Background(), types.ConfigListOptions{}) - c.Assert(err, checker.IsNil) - return configs -} - -// GetConfig returns a swarm config identified by the specified id -func (d *Swarm) GetConfig(c *check.C, id string) *swarm.Config { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - config, _, err := cli.ConfigInspectWithRaw(context.Background(), id) - c.Assert(err, checker.IsNil) - return &config -} - -// DeleteConfig removes the swarm config identified by the specified id -func (d *Swarm) DeleteConfig(c *check.C, id string) { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - err = cli.ConfigRemove(context.Background(), id) - c.Assert(err, checker.IsNil) -} - -// UpdateConfig updates the swarm config identified by the specified id -// Currently, only label update is supported. -func (d *Swarm) UpdateConfig(c *check.C, id string, f ...ConfigConstructor) { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - config := d.GetConfig(c, id) - for _, fn := range f { - fn(config) - } - - err = cli.ConfigUpdate(context.Background(), config.ID, config.Version, config.Spec) - c.Assert(err, checker.IsNil) -} - -// GetSwarm returns the current swarm object -func (d *Swarm) GetSwarm(c *check.C) swarm.Swarm { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - sw, err := cli.SwarmInspect(context.Background()) - c.Assert(err, checker.IsNil) - return sw -} - -// UpdateSwarm updates the current swarm object with the specified spec constructors -func (d *Swarm) UpdateSwarm(c *check.C, f ...SpecConstructor) { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - sw := d.GetSwarm(c) - for _, fn := range f { - fn(&sw.Spec) - } - - err = cli.SwarmUpdate(context.Background(), sw.Version, sw.Spec, swarm.UpdateFlags{}) - c.Assert(err, checker.IsNil) -} - -// RotateTokens update the swarm to rotate tokens -func (d *Swarm) RotateTokens(c *check.C) { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - sw, err := cli.SwarmInspect(context.Background()) - c.Assert(err, checker.IsNil) - - flags := swarm.UpdateFlags{ - RotateManagerToken: true, - RotateWorkerToken: true, - } - - err = cli.SwarmUpdate(context.Background(), sw.Version, sw.Spec, flags) - c.Assert(err, checker.IsNil) -} - -// JoinTokens returns the current swarm join tokens -func (d *Swarm) JoinTokens(c *check.C) swarm.JoinTokens { - cli, err := d.NewClient() - c.Assert(err, checker.IsNil) - defer cli.Close() - - sw, err := cli.SwarmInspect(context.Background()) - c.Assert(err, checker.IsNil) - return sw.JoinTokens -} - // CheckLocalNodeState returns the current swarm node state -func (d *Swarm) CheckLocalNodeState(c *check.C) (interface{}, check.CommentInterface) { - info, err := d.SwarmInfo() - c.Assert(err, checker.IsNil) +func (d *Daemon) CheckLocalNodeState(c *check.C) (interface{}, check.CommentInterface) { + info := d.SwarmInfo(c) return info.LocalNodeState, nil } // CheckControlAvailable returns the current swarm control available -func (d *Swarm) CheckControlAvailable(c *check.C) (interface{}, check.CommentInterface) { - info, err := d.SwarmInfo() - c.Assert(err, checker.IsNil) +func (d *Daemon) CheckControlAvailable(c *check.C) (interface{}, check.CommentInterface) { + info := d.SwarmInfo(c) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive) return info.ControlAvailable, nil } // CheckLeader returns whether there is a leader on the swarm or not -func (d *Swarm) CheckLeader(c *check.C) (interface{}, check.CommentInterface) { +func (d *Daemon) CheckLeader(c *check.C) (interface{}, check.CommentInterface) { cli, err := d.NewClient() c.Assert(err, checker.IsNil) defer cli.Close() @@ -644,18 +195,3 @@ func (d *Swarm) CheckLeader(c *check.C) (interface{}, check.CommentInterface) { } return fmt.Errorf("no leader"), check.Commentf("could not find leader") } - -// CmdRetryOutOfSequence tries the specified command against the current daemon for 10 times -func (d *Swarm) CmdRetryOutOfSequence(args ...string) (string, error) { - for i := 0; ; i++ { - out, err := d.Cmd(args...) - if err != nil { - if strings.Contains(out, "update out of sequence") { - if i < 10 { - continue - } - } - } - return out, err - } -} diff --git a/components/engine/integration-cli/daemon_swarm_hack_test.go b/components/engine/integration-cli/daemon_swarm_hack_test.go index e1fb333f82e..7a23e84bfcf 100644 --- a/components/engine/integration-cli/daemon_swarm_hack_test.go +++ b/components/engine/integration-cli/daemon_swarm_hack_test.go @@ -5,11 +5,11 @@ import ( "github.com/go-check/check" ) -func (s *DockerSwarmSuite) getDaemon(c *check.C, nodeID string) *daemon.Swarm { +func (s *DockerSwarmSuite) getDaemon(c *check.C, nodeID string) *daemon.Daemon { s.daemonsLock.Lock() defer s.daemonsLock.Unlock() for _, d := range s.daemons { - if d.NodeID == nodeID { + if d.NodeID() == nodeID { return d } } diff --git a/components/engine/integration-cli/docker_api_swarm_node_test.go b/components/engine/integration-cli/docker_api_swarm_node_test.go index 98f80552cfc..6f939ea460b 100644 --- a/components/engine/integration-cli/docker_api_swarm_node_test.go +++ b/components/engine/integration-cli/docker_api_swarm_node_test.go @@ -21,8 +21,8 @@ func (s *DockerSwarmSuite) TestAPISwarmListNodes(c *check.C) { loop0: for _, n := range nodes { - for _, d := range []*daemon.Swarm{d1, d2, d3} { - if n.ID == d.NodeID { + for _, d := range []*daemon.Daemon{d1, d2, d3} { + if n.ID == d.NodeID() { continue loop0 } } @@ -53,8 +53,7 @@ func (s *DockerSwarmSuite) TestAPISwarmNodeRemove(c *check.C) { c.Assert(len(nodes), checker.Equals, 3, check.Commentf("nodes: %#v", nodes)) // Getting the info so we can take the NodeID - d2Info, err := d2.SwarmInfo() - c.Assert(err, checker.IsNil) + d2Info := d2.SwarmInfo(c) // forceful removal of d2 should work d1.RemoveNode(c, d2Info.NodeID, true) @@ -88,14 +87,14 @@ func (s *DockerSwarmSuite) TestAPISwarmNodeDrainPause(c *check.C) { waitAndAssert(c, defaultReconciliationTimeout, reducedCheck(sumAsIntegers, d1.CheckActiveContainerCount, d2.CheckActiveContainerCount), checker.Equals, instances) // drain d2, all containers should move to d1 - d1.UpdateNode(c, d2.NodeID, func(n *swarm.Node) { + d1.UpdateNode(c, d2.NodeID(), func(n *swarm.Node) { n.Spec.Availability = swarm.NodeAvailabilityDrain }) waitAndAssert(c, defaultReconciliationTimeout, d1.CheckActiveContainerCount, checker.Equals, instances) waitAndAssert(c, defaultReconciliationTimeout, d2.CheckActiveContainerCount, checker.Equals, 0) // set d2 back to active - d1.UpdateNode(c, d2.NodeID, func(n *swarm.Node) { + d1.UpdateNode(c, d2.NodeID(), func(n *swarm.Node) { n.Spec.Availability = swarm.NodeAvailabilityActive }) @@ -115,7 +114,7 @@ func (s *DockerSwarmSuite) TestAPISwarmNodeDrainPause(c *check.C) { d2ContainerCount := len(d2.ActiveContainers()) // set d2 to paused, scale service up, only d1 gets new tasks - d1.UpdateNode(c, d2.NodeID, func(n *swarm.Node) { + d1.UpdateNode(c, d2.NodeID(), func(n *swarm.Node) { n.Spec.Availability = swarm.NodeAvailabilityPause }) diff --git a/components/engine/integration-cli/docker_api_swarm_service_test.go b/components/engine/integration-cli/docker_api_swarm_service_test.go index 845453d7573..f715265f637 100644 --- a/components/engine/integration-cli/docker_api_swarm_service_test.go +++ b/components/engine/integration-cli/docker_api_swarm_service_test.go @@ -15,12 +15,13 @@ import ( "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/integration-cli/fixtures/plugin" + testdaemon "github.com/docker/docker/internal/test/daemon" "github.com/go-check/check" "golang.org/x/net/context" "golang.org/x/sys/unix" ) -func setPortConfig(portConfig []swarm.PortConfig) daemon.ServiceConstructor { +func setPortConfig(portConfig []swarm.PortConfig) testdaemon.ServiceConstructor { return func(s *swarm.Service) { if s.Spec.EndpointSpec == nil { s.Spec.EndpointSpec = &swarm.EndpointSpec{} @@ -140,7 +141,7 @@ func (s *DockerSwarmSuite) TestAPISwarmServicesCreateGlobal(c *check.C) { func (s *DockerSwarmSuite) TestAPISwarmServicesUpdate(c *check.C) { const nodeCount = 3 - var daemons [nodeCount]*daemon.Swarm + var daemons [nodeCount]*daemon.Daemon for i := 0; i < nodeCount; i++ { daemons[i] = s.AddDaemon(c, true, i == 0) } @@ -309,7 +310,7 @@ func (s *DockerSwarmSuite) TestAPISwarmServicesUpdateStartFirst(c *check.C) { func (s *DockerSwarmSuite) TestAPISwarmServicesFailedUpdate(c *check.C) { const nodeCount = 3 - var daemons [nodeCount]*daemon.Swarm + var daemons [nodeCount]*daemon.Daemon for i := 0; i < nodeCount; i++ { daemons[i] = s.AddDaemon(c, true, i == 0) } @@ -349,7 +350,7 @@ func (s *DockerSwarmSuite) TestAPISwarmServicesFailedUpdate(c *check.C) { func (s *DockerSwarmSuite) TestAPISwarmServiceConstraintRole(c *check.C) { const nodeCount = 3 - var daemons [nodeCount]*daemon.Swarm + var daemons [nodeCount]*daemon.Daemon for i := 0; i < nodeCount; i++ { daemons[i] = s.AddDaemon(c, true, i == 0) } @@ -401,7 +402,7 @@ func (s *DockerSwarmSuite) TestAPISwarmServiceConstraintRole(c *check.C) { func (s *DockerSwarmSuite) TestAPISwarmServiceConstraintLabel(c *check.C) { const nodeCount = 3 - var daemons [nodeCount]*daemon.Swarm + var daemons [nodeCount]*daemon.Daemon for i := 0; i < nodeCount; i++ { daemons[i] = s.AddDaemon(c, true, i == 0) } @@ -496,7 +497,7 @@ func (s *DockerSwarmSuite) TestAPISwarmServiceConstraintLabel(c *check.C) { func (s *DockerSwarmSuite) TestAPISwarmServicePlacementPrefs(c *check.C) { const nodeCount = 3 - var daemons [nodeCount]*daemon.Swarm + var daemons [nodeCount]*daemon.Daemon for i := 0; i < nodeCount; i++ { daemons[i] = s.AddDaemon(c, true, i == 0) } @@ -551,9 +552,9 @@ func (s *DockerSwarmSuite) TestAPISwarmServicesStateReporting(c *check.C) { waitAndAssert(c, defaultReconciliationTimeout, reducedCheck(sumAsIntegers, d1.CheckActiveContainerCount, d2.CheckActiveContainerCount, d3.CheckActiveContainerCount), checker.Equals, instances) - getContainers := func() map[string]*daemon.Swarm { - m := make(map[string]*daemon.Swarm) - for _, d := range []*daemon.Swarm{d1, d2, d3} { + getContainers := func() map[string]*daemon.Daemon { + m := make(map[string]*daemon.Daemon) + for _, d := range []*daemon.Daemon{d1, d2, d3} { for _, id := range d.ActiveContainers() { m[id] = d } diff --git a/components/engine/integration-cli/docker_api_swarm_test.go b/components/engine/integration-cli/docker_api_swarm_test.go index 2ba69acdb89..69fcdd3e82a 100644 --- a/components/engine/integration-cli/docker_api_swarm_test.go +++ b/components/engine/integration-cli/docker_api_swarm_test.go @@ -23,6 +23,7 @@ import ( "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/integration-cli/request" + testdaemon "github.com/docker/docker/internal/test/daemon" "github.com/docker/swarmkit/ca" "github.com/go-check/check" "github.com/gotestyourself/gotestyourself/assert" @@ -35,30 +36,30 @@ var defaultReconciliationTimeout = 30 * time.Second func (s *DockerSwarmSuite) TestAPISwarmInit(c *check.C) { // todo: should find a better way to verify that components are running than /info d1 := s.AddDaemon(c, true, true) - info, err := d1.SwarmInfo() - c.Assert(err, checker.IsNil) + info := d1.SwarmInfo(c) c.Assert(info.ControlAvailable, checker.True) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive) c.Assert(info.Cluster.RootRotationInProgress, checker.False) d2 := s.AddDaemon(c, true, false) - info, err = d2.SwarmInfo() - c.Assert(err, checker.IsNil) + info = d2.SwarmInfo(c) c.Assert(info.ControlAvailable, checker.False) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive) // Leaving cluster - c.Assert(d2.Leave(false), checker.IsNil) + c.Assert(d2.SwarmLeave(false), checker.IsNil) - info, err = d2.SwarmInfo() - c.Assert(err, checker.IsNil) + info = d2.SwarmInfo(c) c.Assert(info.ControlAvailable, checker.False) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive) - c.Assert(d2.Join(swarm.JoinRequest{JoinToken: d1.JoinTokens(c).Worker, RemoteAddrs: []string{d1.ListenAddr}}), checker.IsNil) + d2.SwarmJoin(c, swarm.JoinRequest{ + ListenAddr: d1.SwarmListenAddr(), + JoinToken: d1.JoinTokens(c).Worker, + RemoteAddrs: []string{d1.SwarmListenAddr()}, + }) - info, err = d2.SwarmInfo() - c.Assert(err, checker.IsNil) + info = d2.SwarmInfo(c) c.Assert(info.ControlAvailable, checker.False) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive) @@ -69,93 +70,100 @@ func (s *DockerSwarmSuite) TestAPISwarmInit(c *check.C) { d1.Start(c) d2.Start(c) - info, err = d1.SwarmInfo() - c.Assert(err, checker.IsNil) + info = d1.SwarmInfo(c) c.Assert(info.ControlAvailable, checker.True) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive) - info, err = d2.SwarmInfo() - c.Assert(err, checker.IsNil) + info = d2.SwarmInfo(c) c.Assert(info.ControlAvailable, checker.False) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive) } func (s *DockerSwarmSuite) TestAPISwarmJoinToken(c *check.C) { d1 := s.AddDaemon(c, false, false) - c.Assert(d1.Init(swarm.InitRequest{}), checker.IsNil) + d1.SwarmInit(c, swarm.InitRequest{}) // todo: error message differs depending if some components of token are valid d2 := s.AddDaemon(c, false, false) - err := d2.Join(swarm.JoinRequest{RemoteAddrs: []string{d1.ListenAddr}}) + c2 := d2.NewClientT(c) + err := c2.SwarmJoin(context.Background(), swarm.JoinRequest{ + ListenAddr: d2.SwarmListenAddr(), + RemoteAddrs: []string{d1.SwarmListenAddr()}, + }) c.Assert(err, checker.NotNil) c.Assert(err.Error(), checker.Contains, "join token is necessary") - info, err := d2.SwarmInfo() - c.Assert(err, checker.IsNil) + info := d2.SwarmInfo(c) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive) - err = d2.Join(swarm.JoinRequest{JoinToken: "foobaz", RemoteAddrs: []string{d1.ListenAddr}}) + err = c2.SwarmJoin(context.Background(), swarm.JoinRequest{ + ListenAddr: d2.SwarmListenAddr(), + JoinToken: "foobaz", + RemoteAddrs: []string{d1.SwarmListenAddr()}, + }) c.Assert(err, checker.NotNil) c.Assert(err.Error(), checker.Contains, "invalid join token") - info, err = d2.SwarmInfo() - c.Assert(err, checker.IsNil) + info = d2.SwarmInfo(c) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive) workerToken := d1.JoinTokens(c).Worker - c.Assert(d2.Join(swarm.JoinRequest{JoinToken: workerToken, RemoteAddrs: []string{d1.ListenAddr}}), checker.IsNil) - info, err = d2.SwarmInfo() - c.Assert(err, checker.IsNil) + d2.SwarmJoin(c, swarm.JoinRequest{ + ListenAddr: d2.SwarmListenAddr(), + JoinToken: workerToken, + RemoteAddrs: []string{d1.SwarmListenAddr()}, + }) + info = d2.SwarmInfo(c) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive) - c.Assert(d2.Leave(false), checker.IsNil) - info, err = d2.SwarmInfo() - c.Assert(err, checker.IsNil) + c.Assert(d2.SwarmLeave(false), checker.IsNil) + info = d2.SwarmInfo(c) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive) // change tokens d1.RotateTokens(c) - err = d2.Join(swarm.JoinRequest{JoinToken: workerToken, RemoteAddrs: []string{d1.ListenAddr}}) + err = c2.SwarmJoin(context.Background(), swarm.JoinRequest{ + ListenAddr: d2.SwarmListenAddr(), + JoinToken: workerToken, + RemoteAddrs: []string{d1.SwarmListenAddr()}, + }) c.Assert(err, checker.NotNil) c.Assert(err.Error(), checker.Contains, "join token is necessary") - info, err = d2.SwarmInfo() - c.Assert(err, checker.IsNil) + info = d2.SwarmInfo(c) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive) workerToken = d1.JoinTokens(c).Worker - c.Assert(d2.Join(swarm.JoinRequest{JoinToken: workerToken, RemoteAddrs: []string{d1.ListenAddr}}), checker.IsNil) - info, err = d2.SwarmInfo() - c.Assert(err, checker.IsNil) + d2.SwarmJoin(c, swarm.JoinRequest{JoinToken: workerToken, RemoteAddrs: []string{d1.SwarmListenAddr()}}) + info = d2.SwarmInfo(c) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive) - c.Assert(d2.Leave(false), checker.IsNil) - info, err = d2.SwarmInfo() - c.Assert(err, checker.IsNil) + c.Assert(d2.SwarmLeave(false), checker.IsNil) + info = d2.SwarmInfo(c) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive) // change spec, don't change tokens d1.UpdateSwarm(c, func(s *swarm.Spec) {}) - err = d2.Join(swarm.JoinRequest{RemoteAddrs: []string{d1.ListenAddr}}) + err = c2.SwarmJoin(context.Background(), swarm.JoinRequest{ + ListenAddr: d2.SwarmListenAddr(), + RemoteAddrs: []string{d1.SwarmListenAddr()}, + }) c.Assert(err, checker.NotNil) c.Assert(err.Error(), checker.Contains, "join token is necessary") - info, err = d2.SwarmInfo() - c.Assert(err, checker.IsNil) + info = d2.SwarmInfo(c) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive) - c.Assert(d2.Join(swarm.JoinRequest{JoinToken: workerToken, RemoteAddrs: []string{d1.ListenAddr}}), checker.IsNil) - info, err = d2.SwarmInfo() - c.Assert(err, checker.IsNil) + d2.SwarmJoin(c, swarm.JoinRequest{JoinToken: workerToken, RemoteAddrs: []string{d1.SwarmListenAddr()}}) + info = d2.SwarmInfo(c) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive) - c.Assert(d2.Leave(false), checker.IsNil) - info, err = d2.SwarmInfo() - c.Assert(err, checker.IsNil) + c.Assert(d2.SwarmLeave(false), checker.IsNil) + info = d2.SwarmInfo(c) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive) } func (s *DockerSwarmSuite) TestUpdateSwarmAddExternalCA(c *check.C) { d1 := s.AddDaemon(c, false, false) - c.Assert(d1.Init(swarm.InitRequest{}), checker.IsNil) + d1.SwarmInit(c, swarm.InitRequest{}) d1.UpdateSwarm(c, func(s *swarm.Spec) { s.CAConfig.ExternalCAs = []*swarm.ExternalCA{ { @@ -169,8 +177,7 @@ func (s *DockerSwarmSuite) TestUpdateSwarmAddExternalCA(c *check.C) { }, } }) - info, err := d1.SwarmInfo() - c.Assert(err, checker.IsNil) + info := d1.SwarmInfo(c) c.Assert(info.Cluster.Spec.CAConfig.ExternalCAs, checker.HasLen, 2) c.Assert(info.Cluster.Spec.CAConfig.ExternalCAs[0].CACert, checker.Equals, "") c.Assert(info.Cluster.Spec.CAConfig.ExternalCAs[1].CACert, checker.Equals, "cacert") @@ -182,28 +189,32 @@ func (s *DockerSwarmSuite) TestAPISwarmCAHash(c *check.C) { splitToken := strings.Split(d1.JoinTokens(c).Worker, "-") splitToken[2] = "1kxftv4ofnc6mt30lmgipg6ngf9luhwqopfk1tz6bdmnkubg0e" replacementToken := strings.Join(splitToken, "-") - err := d2.Join(swarm.JoinRequest{JoinToken: replacementToken, RemoteAddrs: []string{d1.ListenAddr}}) + c2 := d2.NewClientT(c) + err := c2.SwarmJoin(context.Background(), swarm.JoinRequest{ + ListenAddr: d2.SwarmListenAddr(), + JoinToken: replacementToken, + RemoteAddrs: []string{d1.SwarmListenAddr()}, + }) c.Assert(err, checker.NotNil) c.Assert(err.Error(), checker.Contains, "remote CA does not match fingerprint") } func (s *DockerSwarmSuite) TestAPISwarmPromoteDemote(c *check.C) { d1 := s.AddDaemon(c, false, false) - c.Assert(d1.Init(swarm.InitRequest{}), checker.IsNil) + d1.SwarmInit(c, swarm.InitRequest{}) d2 := s.AddDaemon(c, true, false) - info, err := d2.SwarmInfo() - c.Assert(err, checker.IsNil) + info := d2.SwarmInfo(c) c.Assert(info.ControlAvailable, checker.False) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive) - d1.UpdateNode(c, d2.NodeID, func(n *swarm.Node) { + d1.UpdateNode(c, d2.NodeID(), func(n *swarm.Node) { n.Spec.Role = swarm.NodeRoleManager }) waitAndAssert(c, defaultReconciliationTimeout, d2.CheckControlAvailable, checker.True) - d1.UpdateNode(c, d2.NodeID, func(n *swarm.Node) { + d1.UpdateNode(c, d2.NodeID(), func(n *swarm.Node) { n.Spec.Role = swarm.NodeRoleWorker }) @@ -228,7 +239,7 @@ func (s *DockerSwarmSuite) TestAPISwarmPromoteDemote(c *check.C) { }, checker.Equals, "swarm-worker") // Demoting last node should fail - node := d1.GetNode(c, d1.NodeID) + node := d1.GetNode(c, d1.NodeID()) node.Spec.Role = swarm.NodeRoleWorker url := fmt.Sprintf("/nodes/%s/update?version=%d", node.ID, node.Version.Index) res, body, err := request.DoOnHost(d1.Sock(), url, request.Method("POST"), request.JSONBody(node.Spec)) @@ -246,13 +257,12 @@ func (s *DockerSwarmSuite) TestAPISwarmPromoteDemote(c *check.C) { if !strings.Contains(string(b), "last manager of the swarm") { c.Assert(string(b), checker.Contains, "this would result in a loss of quorum") } - info, err = d1.SwarmInfo() - c.Assert(err, checker.IsNil) + info = d1.SwarmInfo(c) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive) c.Assert(info.ControlAvailable, checker.True) // Promote already demoted node - d1.UpdateNode(c, d2.NodeID, func(n *swarm.Node) { + d1.UpdateNode(c, d2.NodeID(), func(n *swarm.Node) { n.Spec.Role = swarm.NodeRoleManager }) @@ -278,7 +288,7 @@ func (s *DockerSwarmSuite) TestAPISwarmLeaderProxy(c *check.C) { // 3 services should be started now, because the requests were proxied to leader // query each node and make sure it returns 3 services - for _, d := range []*daemon.Swarm{d1, d2, d3} { + for _, d := range []*daemon.Daemon{d1, d2, d3} { services := d.ListServices(c) c.Assert(services, checker.HasLen, 3) } @@ -291,23 +301,23 @@ func (s *DockerSwarmSuite) TestAPISwarmLeaderElection(c *check.C) { d3 := s.AddDaemon(c, true, true) // assert that the first node we made is the leader, and the other two are followers - c.Assert(d1.GetNode(c, d1.NodeID).ManagerStatus.Leader, checker.True) - c.Assert(d1.GetNode(c, d2.NodeID).ManagerStatus.Leader, checker.False) - c.Assert(d1.GetNode(c, d3.NodeID).ManagerStatus.Leader, checker.False) + c.Assert(d1.GetNode(c, d1.NodeID()).ManagerStatus.Leader, checker.True) + c.Assert(d1.GetNode(c, d2.NodeID()).ManagerStatus.Leader, checker.False) + c.Assert(d1.GetNode(c, d3.NodeID()).ManagerStatus.Leader, checker.False) d1.Stop(c) var ( - leader *daemon.Swarm // keep track of leader - followers []*daemon.Swarm // keep track of followers + leader *daemon.Daemon // keep track of leader + followers []*daemon.Daemon // keep track of followers ) - checkLeader := func(nodes ...*daemon.Swarm) checkF { + checkLeader := func(nodes ...*daemon.Daemon) checkF { return func(c *check.C) (interface{}, check.CommentInterface) { // clear these out before each run leader = nil followers = nil for _, d := range nodes { - if d.GetNode(c, d.NodeID).ManagerStatus.Leader { + if d.GetNode(c, d.NodeID()).ManagerStatus.Leader { leader = d } else { followers = append(followers, d) @@ -344,7 +354,7 @@ func (s *DockerSwarmSuite) TestAPISwarmLeaderElection(c *check.C) { c.Assert(leader, checker.NotNil) c.Assert(followers, checker.HasLen, 2) // and that after we added d1 back, the leader hasn't changed - c.Assert(leader.NodeID, checker.Equals, stableleader.NodeID) + c.Assert(leader.NodeID(), checker.Equals, stableleader.NodeID()) } func (s *DockerSwarmSuite) TestAPISwarmRaftQuorum(c *check.C) { @@ -400,8 +410,8 @@ func (s *DockerSwarmSuite) TestAPISwarmLeaveRemovesContainer(c *check.C) { waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, instances+1) - c.Assert(d.Leave(false), checker.NotNil) - c.Assert(d.Leave(true), checker.IsNil) + c.Assert(d.SwarmLeave(false), checker.NotNil) + c.Assert(d.SwarmLeave(true), checker.IsNil) waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 1) @@ -420,17 +430,18 @@ func (s *DockerSwarmSuite) TestAPISwarmLeaveOnPendingJoin(c *check.C) { c.Assert(err, checker.IsNil) id = strings.TrimSpace(id) - err = d2.Join(swarm.JoinRequest{ + c2 := d2.NewClientT(c) + err = c2.SwarmJoin(context.Background(), swarm.JoinRequest{ + ListenAddr: d2.SwarmListenAddr(), RemoteAddrs: []string{"123.123.123.123:1234"}, }) c.Assert(err, check.NotNil) c.Assert(err.Error(), checker.Contains, "Timeout was reached") - info, err := d2.SwarmInfo() - c.Assert(err, checker.IsNil) + info := d2.SwarmInfo(c) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStatePending) - c.Assert(d2.Leave(true), checker.IsNil) + c.Assert(d2.SwarmLeave(true), checker.IsNil) waitAndAssert(c, defaultReconciliationTimeout, d2.CheckActiveContainerCount, checker.Equals, 1) @@ -443,7 +454,9 @@ func (s *DockerSwarmSuite) TestAPISwarmLeaveOnPendingJoin(c *check.C) { func (s *DockerSwarmSuite) TestAPISwarmRestoreOnPendingJoin(c *check.C) { testRequires(c, Network) d := s.AddDaemon(c, false, false) - err := d.Join(swarm.JoinRequest{ + client := d.NewClientT(c) + err := client.SwarmJoin(context.Background(), swarm.JoinRequest{ + ListenAddr: d.SwarmListenAddr(), RemoteAddrs: []string{"123.123.123.123:1234"}, }) c.Assert(err, check.NotNil) @@ -454,8 +467,7 @@ func (s *DockerSwarmSuite) TestAPISwarmRestoreOnPendingJoin(c *check.C) { d.Stop(c) d.Start(c) - info, err := d.SwarmInfo() - c.Assert(err, checker.IsNil) + info := d.SwarmInfo(c) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive) } @@ -539,7 +551,7 @@ func (s *DockerSwarmSuite) TestAPISwarmForceNewCluster(c *check.C) { waitAndAssert(c, defaultReconciliationTimeout, reducedCheck(sumAsIntegers, d1.CheckActiveContainerCount, d2.CheckActiveContainerCount), checker.Equals, instances) // drain d2, all containers should move to d1 - d1.UpdateNode(c, d2.NodeID, func(n *swarm.Node) { + d1.UpdateNode(c, d2.NodeID(), func(n *swarm.Node) { n.Spec.Availability = swarm.NodeAvailabilityDrain }) waitAndAssert(c, defaultReconciliationTimeout, d1.CheckActiveContainerCount, checker.Equals, instances) @@ -547,16 +559,15 @@ func (s *DockerSwarmSuite) TestAPISwarmForceNewCluster(c *check.C) { d2.Stop(c) - c.Assert(d1.Init(swarm.InitRequest{ + d1.SwarmInit(c, swarm.InitRequest{ ForceNewCluster: true, Spec: swarm.Spec{}, - }), checker.IsNil) + }) waitAndAssert(c, defaultReconciliationTimeout, d1.CheckActiveContainerCount, checker.Equals, instances) d3 := s.AddDaemon(c, true, true) - info, err := d3.SwarmInfo() - c.Assert(err, checker.IsNil) + info := d3.SwarmInfo(c) c.Assert(info.ControlAvailable, checker.True) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive) @@ -622,7 +633,7 @@ func serviceForUpdate(s *swarm.Service) { s.Spec.Name = "updatetest" } -func setInstances(replicas int) daemon.ServiceConstructor { +func setInstances(replicas int) testdaemon.ServiceConstructor { ureplicas := uint64(replicas) return func(s *swarm.Service) { s.Spec.Mode = swarm.ServiceMode{ @@ -633,7 +644,7 @@ func setInstances(replicas int) daemon.ServiceConstructor { } } -func setUpdateOrder(order string) daemon.ServiceConstructor { +func setUpdateOrder(order string) testdaemon.ServiceConstructor { return func(s *swarm.Service) { if s.Spec.UpdateConfig == nil { s.Spec.UpdateConfig = &swarm.UpdateConfig{} @@ -642,7 +653,7 @@ func setUpdateOrder(order string) daemon.ServiceConstructor { } } -func setRollbackOrder(order string) daemon.ServiceConstructor { +func setRollbackOrder(order string) testdaemon.ServiceConstructor { return func(s *swarm.Service) { if s.Spec.RollbackConfig == nil { s.Spec.RollbackConfig = &swarm.UpdateConfig{} @@ -651,7 +662,7 @@ func setRollbackOrder(order string) daemon.ServiceConstructor { } } -func setImage(image string) daemon.ServiceConstructor { +func setImage(image string) testdaemon.ServiceConstructor { return func(s *swarm.Service) { if s.Spec.TaskTemplate.ContainerSpec == nil { s.Spec.TaskTemplate.ContainerSpec = &swarm.ContainerSpec{} @@ -660,25 +671,25 @@ func setImage(image string) daemon.ServiceConstructor { } } -func setFailureAction(failureAction string) daemon.ServiceConstructor { +func setFailureAction(failureAction string) testdaemon.ServiceConstructor { return func(s *swarm.Service) { s.Spec.UpdateConfig.FailureAction = failureAction } } -func setMaxFailureRatio(maxFailureRatio float32) daemon.ServiceConstructor { +func setMaxFailureRatio(maxFailureRatio float32) testdaemon.ServiceConstructor { return func(s *swarm.Service) { s.Spec.UpdateConfig.MaxFailureRatio = maxFailureRatio } } -func setParallelism(parallelism uint64) daemon.ServiceConstructor { +func setParallelism(parallelism uint64) testdaemon.ServiceConstructor { return func(s *swarm.Service) { s.Spec.UpdateConfig.Parallelism = parallelism } } -func setConstraints(constraints []string) daemon.ServiceConstructor { +func setConstraints(constraints []string) testdaemon.ServiceConstructor { return func(s *swarm.Service) { if s.Spec.TaskTemplate.Placement == nil { s.Spec.TaskTemplate.Placement = &swarm.Placement{} @@ -687,7 +698,7 @@ func setConstraints(constraints []string) daemon.ServiceConstructor { } } -func setPlacementPrefs(prefs []swarm.PlacementPreference) daemon.ServiceConstructor { +func setPlacementPrefs(prefs []swarm.PlacementPreference) testdaemon.ServiceConstructor { return func(s *swarm.Service) { if s.Spec.TaskTemplate.Placement == nil { s.Spec.TaskTemplate.Placement = &swarm.Placement{} @@ -702,18 +713,19 @@ func setGlobalMode(s *swarm.Service) { } } -func checkClusterHealth(c *check.C, cl []*daemon.Swarm, managerCount, workerCount int) { +func checkClusterHealth(c *check.C, cl []*daemon.Daemon, managerCount, workerCount int) { var totalMCount, totalWCount int for _, d := range cl { var ( info swarm.Info - err error ) // check info in a waitAndAssert, because if the cluster doesn't have a leader, `info` will return an error checkInfo := func(c *check.C) (interface{}, check.CommentInterface) { - info, err = d.SwarmInfo() + client := d.NewClientT(c) + daemonInfo, err := client.Info(context.Background()) + info = daemonInfo.Swarm return err, check.Commentf("cluster not ready in time") } waitAndAssert(c, defaultReconciliationTimeout, checkInfo, checker.IsNil) @@ -733,7 +745,7 @@ func checkClusterHealth(c *check.C, cl []*daemon.Swarm, managerCount, workerCoun } nn := d.GetNode(c, n.ID) n = *nn - return n.Status.State == swarm.NodeStateReady, check.Commentf("state of node %s, reported by %s", n.ID, d.Info.NodeID) + return n.Status.State == swarm.NodeStateReady, check.Commentf("state of node %s, reported by %s", n.ID, d.NodeID()) } waitAndAssert(c, defaultReconciliationTimeout, waitReady, checker.True) @@ -743,18 +755,18 @@ func checkClusterHealth(c *check.C, cl []*daemon.Swarm, managerCount, workerCoun } nn := d.GetNode(c, n.ID) n = *nn - return n.Spec.Availability == swarm.NodeAvailabilityActive, check.Commentf("availability of node %s, reported by %s", n.ID, d.Info.NodeID) + return n.Spec.Availability == swarm.NodeAvailabilityActive, check.Commentf("availability of node %s, reported by %s", n.ID, d.NodeID()) } waitAndAssert(c, defaultReconciliationTimeout, waitActive, checker.True) if n.Spec.Role == swarm.NodeRoleManager { - c.Assert(n.ManagerStatus, checker.NotNil, check.Commentf("manager status of node %s (manager), reported by %s", n.ID, d.Info.NodeID)) + c.Assert(n.ManagerStatus, checker.NotNil, check.Commentf("manager status of node %s (manager), reported by %s", n.ID, d.NodeID())) if n.ManagerStatus.Leader { leaderFound = true } mCount++ } else { - c.Assert(n.ManagerStatus, checker.IsNil, check.Commentf("manager status of node %s (worker), reported by %s", n.ID, d.Info.NodeID)) + c.Assert(n.ManagerStatus, checker.IsNil, check.Commentf("manager status of node %s (worker), reported by %s", n.ID, d.NodeID())) wCount++ } } @@ -769,11 +781,10 @@ func checkClusterHealth(c *check.C, cl []*daemon.Swarm, managerCount, workerCoun func (s *DockerSwarmSuite) TestAPISwarmRestartCluster(c *check.C) { mCount, wCount := 5, 1 - var nodes []*daemon.Swarm + var nodes []*daemon.Daemon for i := 0; i < mCount; i++ { manager := s.AddDaemon(c, true, true) - info, err := manager.SwarmInfo() - c.Assert(err, checker.IsNil) + info := manager.SwarmInfo(c) c.Assert(info.ControlAvailable, checker.True) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive) nodes = append(nodes, manager) @@ -781,8 +792,7 @@ func (s *DockerSwarmSuite) TestAPISwarmRestartCluster(c *check.C) { for i := 0; i < wCount; i++ { worker := s.AddDaemon(c, true, false) - info, err := worker.SwarmInfo() - c.Assert(err, checker.IsNil) + info := worker.SwarmInfo(c) c.Assert(info.ControlAvailable, checker.False) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive) nodes = append(nodes, worker) @@ -795,7 +805,7 @@ func (s *DockerSwarmSuite) TestAPISwarmRestartCluster(c *check.C) { errs := make(chan error, len(nodes)) for _, d := range nodes { - go func(daemon *daemon.Swarm) { + go func(daemon *daemon.Daemon) { defer wg.Done() if err := daemon.StopWithError(); err != nil { errs <- err @@ -820,7 +830,7 @@ func (s *DockerSwarmSuite) TestAPISwarmRestartCluster(c *check.C) { errs := make(chan error, len(nodes)) for _, d := range nodes { - go func(daemon *daemon.Swarm) { + go func(daemon *daemon.Daemon) { defer wg.Done() if err := daemon.StartWithError("--iptables=false"); err != nil { errs <- err @@ -859,7 +869,7 @@ func (s *DockerSwarmSuite) TestAPISwarmServicesUpdateWithName(c *check.C) { // Unlocking an unlocked swarm results in an error func (s *DockerSwarmSuite) TestAPISwarmUnlockNotLocked(c *check.C) { d := s.AddDaemon(c, true, true) - err := d.Unlock(swarm.UnlockRequest{UnlockKey: "wrong-key"}) + err := d.SwarmUnlock(swarm.UnlockRequest{UnlockKey: "wrong-key"}) c.Assert(err, checker.NotNil) c.Assert(err.Error(), checker.Contains, "swarm is not locked") } @@ -870,7 +880,10 @@ func (s *DockerSwarmSuite) TestAPISwarmErrorHandling(c *check.C) { c.Assert(err, checker.IsNil) defer ln.Close() d := s.AddDaemon(c, false, false) - err = d.Init(swarm.InitRequest{}) + client := d.NewClientT(c) + _, err = client.SwarmInit(context.Background(), swarm.InitRequest{ + ListenAddr: d.SwarmListenAddr(), + }) c.Assert(err, checker.NotNil) c.Assert(err.Error(), checker.Contains, "address already in use") } @@ -940,13 +953,13 @@ func (s *DockerSwarmSuite) TestSwarmRepeatedRootRotation(c *check.C) { m := s.AddDaemon(c, true, true) w := s.AddDaemon(c, true, false) - info, err := m.SwarmInfo() - c.Assert(err, checker.IsNil) + info := m.SwarmInfo(c) currentTrustRoot := info.Cluster.TLSInfo.TrustRoot // rotate multiple times for i := 0; i < 4; i++ { + var err error var cert, key []byte if i%2 != 0 { cert, _, key, err = initca.New(&csr.CertificateRequest{ @@ -966,8 +979,7 @@ func (s *DockerSwarmSuite) TestSwarmRepeatedRootRotation(c *check.C) { // poll to make sure update succeeds var clusterTLSInfo swarm.TLSInfo for j := 0; j < 18; j++ { - info, err := m.SwarmInfo() - c.Assert(err, checker.IsNil) + info := m.SwarmInfo(c) // the desired CA cert and key is always redacted c.Assert(info.Cluster.Spec.CAConfig.SigningCAKey, checker.Equals, "") @@ -989,8 +1001,8 @@ func (s *DockerSwarmSuite) TestSwarmRepeatedRootRotation(c *check.C) { // could take another second or two for the nodes to trust the new roots after they've all gotten // new TLS certificates for j := 0; j < 18; j++ { - mInfo := m.GetNode(c, m.NodeID).Description.TLSInfo - wInfo := m.GetNode(c, w.NodeID).Description.TLSInfo + mInfo := m.GetNode(c, m.NodeID()).Description.TLSInfo + wInfo := m.GetNode(c, w.NodeID()).Description.TLSInfo if mInfo.TrustRoot == clusterTLSInfo.TrustRoot && wInfo.TrustRoot == clusterTLSInfo.TrustRoot { break @@ -1000,8 +1012,8 @@ func (s *DockerSwarmSuite) TestSwarmRepeatedRootRotation(c *check.C) { time.Sleep(250 * time.Millisecond) } - c.Assert(m.GetNode(c, m.NodeID).Description.TLSInfo, checker.DeepEquals, clusterTLSInfo) - c.Assert(m.GetNode(c, w.NodeID).Description.TLSInfo, checker.DeepEquals, clusterTLSInfo) + c.Assert(m.GetNode(c, m.NodeID()).Description.TLSInfo, checker.DeepEquals, clusterTLSInfo) + c.Assert(m.GetNode(c, w.NodeID()).Description.TLSInfo, checker.DeepEquals, clusterTLSInfo) currentTrustRoot = clusterTLSInfo.TrustRoot } } diff --git a/components/engine/integration-cli/docker_cli_prune_unix_test.go b/components/engine/integration-cli/docker_cli_prune_unix_test.go index 763a72de165..bc5bdc835e2 100644 --- a/components/engine/integration-cli/docker_cli_prune_unix_test.go +++ b/components/engine/integration-cli/docker_cli_prune_unix_test.go @@ -16,7 +16,7 @@ import ( "github.com/go-check/check" ) -func pruneNetworkAndVerify(c *check.C, d *daemon.Swarm, kept, pruned []string) { +func pruneNetworkAndVerify(c *check.C, d *daemon.Daemon, kept, pruned []string) { _, err := d.Cmd("network", "prune", "--force") c.Assert(err, checker.IsNil) diff --git a/components/engine/integration-cli/docker_cli_service_logs_test.go b/components/engine/integration-cli/docker_cli_service_logs_test.go index b3f58271f1a..c26a7455a51 100644 --- a/components/engine/integration-cli/docker_cli_service_logs_test.go +++ b/components/engine/integration-cli/docker_cli_service_logs_test.go @@ -53,7 +53,7 @@ func (s *DockerSwarmSuite) TestServiceLogs(c *check.C) { // countLogLines returns a closure that can be used with waitAndAssert to // verify that a minimum number of expected container log messages have been // output. -func countLogLines(d *daemon.Swarm, name string) func(*check.C) (interface{}, check.CommentInterface) { +func countLogLines(d *daemon.Daemon, name string) func(*check.C) (interface{}, check.CommentInterface) { return func(c *check.C) (interface{}, check.CommentInterface) { result := icmd.RunCmd(d.Command("service", "logs", "-t", "--raw", name)) result.Assert(c, icmd.Expected{}) diff --git a/components/engine/integration-cli/docker_cli_swarm_test.go b/components/engine/integration-cli/docker_cli_swarm_test.go index 4b3358255fd..9a45664cba8 100644 --- a/components/engine/integration-cli/docker_cli_swarm_test.go +++ b/components/engine/integration-cli/docker_cli_swarm_test.go @@ -57,7 +57,7 @@ func (s *DockerSwarmSuite) TestSwarmUpdate(c *check.C) { // passing an external CA (this is without starting a root rotation) does not fail cli.Docker(cli.Args("swarm", "update", "--external-ca", "protocol=cfssl,url=https://something.org", "--external-ca", "protocol=cfssl,url=https://somethingelse.org,cacert=fixtures/https/ca.pem"), - cli.Daemon(d.Daemon)).Assert(c, icmd.Success) + cli.Daemon(d)).Assert(c, icmd.Success) expected, err := ioutil.ReadFile("fixtures/https/ca.pem") c.Assert(err, checker.IsNil) @@ -73,7 +73,7 @@ func (s *DockerSwarmSuite) TestSwarmUpdate(c *check.C) { result := cli.Docker(cli.Args("swarm", "update", "--external-ca", fmt.Sprintf("protocol=cfssl,url=https://something.org,cacert=%s", tempFile.Path())), - cli.Daemon(d.Daemon)) + cli.Daemon(d)) result.Assert(c, icmd.Expected{ ExitCode: 125, Err: "must be in PEM format", @@ -94,7 +94,7 @@ func (s *DockerSwarmSuite) TestSwarmInit(c *check.C) { result := cli.Docker(cli.Args("swarm", "init", "--cert-expiry", "30h", "--dispatcher-heartbeat", "11s", "--external-ca", fmt.Sprintf("protocol=cfssl,url=https://somethingelse.org,cacert=%s", tempFile.Path())), - cli.Daemon(d.Daemon)) + cli.Daemon(d)) result.Assert(c, icmd.Expected{ ExitCode: 125, Err: "must be in PEM format", @@ -103,7 +103,7 @@ func (s *DockerSwarmSuite) TestSwarmInit(c *check.C) { cli.Docker(cli.Args("swarm", "init", "--cert-expiry", "30h", "--dispatcher-heartbeat", "11s", "--external-ca", "protocol=cfssl,url=https://something.org", "--external-ca", "protocol=cfssl,url=https://somethingelse.org,cacert=fixtures/https/ca.pem"), - cli.Daemon(d.Daemon)).Assert(c, icmd.Success) + cli.Daemon(d)).Assert(c, icmd.Success) expected, err := ioutil.ReadFile("fixtures/https/ca.pem") c.Assert(err, checker.IsNil) @@ -115,8 +115,8 @@ func (s *DockerSwarmSuite) TestSwarmInit(c *check.C) { c.Assert(spec.CAConfig.ExternalCAs[0].CACert, checker.Equals, "") c.Assert(spec.CAConfig.ExternalCAs[1].CACert, checker.Equals, string(expected)) - c.Assert(d.Leave(true), checker.IsNil) - cli.Docker(cli.Args("swarm", "init"), cli.Daemon(d.Daemon)).Assert(c, icmd.Success) + c.Assert(d.SwarmLeave(true), checker.IsNil) + cli.Docker(cli.Args("swarm", "init"), cli.Daemon(d)).Assert(c, icmd.Success) spec = getSpec() c.Assert(spec.CAConfig.NodeCertExpiry, checker.Equals, 90*24*time.Hour) @@ -126,12 +126,12 @@ func (s *DockerSwarmSuite) TestSwarmInit(c *check.C) { func (s *DockerSwarmSuite) TestSwarmInitIPv6(c *check.C) { testRequires(c, IPv6) d1 := s.AddDaemon(c, false, false) - cli.Docker(cli.Args("swarm", "init", "--listen-add", "::1"), cli.Daemon(d1.Daemon)).Assert(c, icmd.Success) + cli.Docker(cli.Args("swarm", "init", "--listen-add", "::1"), cli.Daemon(d1)).Assert(c, icmd.Success) d2 := s.AddDaemon(c, false, false) - cli.Docker(cli.Args("swarm", "join", "::1"), cli.Daemon(d2.Daemon)).Assert(c, icmd.Success) + cli.Docker(cli.Args("swarm", "join", "::1"), cli.Daemon(d2)).Assert(c, icmd.Success) - out := cli.Docker(cli.Args("info"), cli.Daemon(d2.Daemon)).Assert(c, icmd.Success).Combined() + out := cli.Docker(cli.Args("info"), cli.Daemon(d2)).Assert(c, icmd.Success).Combined() c.Assert(out, checker.Contains, "Swarm: active") } @@ -145,13 +145,12 @@ func (s *DockerSwarmSuite) TestSwarmInitUnspecifiedAdvertiseAddr(c *check.C) { func (s *DockerSwarmSuite) TestSwarmIncompatibleDaemon(c *check.C) { // init swarm mode and stop a daemon d := s.AddDaemon(c, true, true) - info, err := d.SwarmInfo() - c.Assert(err, checker.IsNil) + info := d.SwarmInfo(c) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive) d.Stop(c) // start a daemon with --cluster-store and --cluster-advertise - err = d.StartWithError("--cluster-store=consul://consuladdr:consulport/some/path", "--cluster-advertise=1.1.1.1:2375") + err := d.StartWithError("--cluster-store=consul://consuladdr:consulport/some/path", "--cluster-advertise=1.1.1.1:2375") c.Assert(err, checker.NotNil) content, err := d.ReadLogFile() c.Assert(err, checker.IsNil) @@ -426,7 +425,7 @@ func (s *DockerSwarmSuite) TestOverlayAttachableOnSwarmLeave(c *check.C) { c.Assert(err, checker.IsNil, check.Commentf(out)) // Leave the swarm - err = d.Leave(true) + err = d.SwarmLeave(true) c.Assert(err, checker.IsNil) // Check the container is disconnected @@ -989,13 +988,12 @@ func (s *DockerSwarmSuite) TestDNSConfigUpdate(c *check.C) { c.Assert(strings.TrimSpace(out), checker.Equals, "{[1.2.3.4] [example.com] [timeout:3]}") } -func getNodeStatus(c *check.C, d *daemon.Swarm) swarm.LocalNodeState { - info, err := d.SwarmInfo() - c.Assert(err, checker.IsNil) +func getNodeStatus(c *check.C, d *daemon.Daemon) swarm.LocalNodeState { + info := d.SwarmInfo(c) return info.LocalNodeState } -func checkKeyIsEncrypted(d *daemon.Swarm) func(*check.C) (interface{}, check.CommentInterface) { +func checkKeyIsEncrypted(d *daemon.Daemon) func(*check.C) (interface{}, check.CommentInterface) { return func(c *check.C) (interface{}, check.CommentInterface) { keyBytes, err := ioutil.ReadFile(filepath.Join(d.Folder, "root", "swarm", "certificates", "swarm-node.key")) if err != nil { @@ -1011,7 +1009,7 @@ func checkKeyIsEncrypted(d *daemon.Swarm) func(*check.C) (interface{}, check.Com } } -func checkSwarmLockedToUnlocked(c *check.C, d *daemon.Swarm, unlockKey string) { +func checkSwarmLockedToUnlocked(c *check.C, d *daemon.Daemon, unlockKey string) { // Wait for the PEM file to become unencrypted waitAndAssert(c, defaultReconciliationTimeout, checkKeyIsEncrypted(d), checker.Equals, false) @@ -1019,7 +1017,7 @@ func checkSwarmLockedToUnlocked(c *check.C, d *daemon.Swarm, unlockKey string) { c.Assert(getNodeStatus(c, d), checker.Equals, swarm.LocalNodeStateActive) } -func checkSwarmUnlockedToLocked(c *check.C, d *daemon.Swarm) { +func checkSwarmUnlockedToLocked(c *check.C, d *daemon.Daemon) { // Wait for the PEM file to become encrypted waitAndAssert(c, defaultReconciliationTimeout, checkKeyIsEncrypted(d), checker.Equals, true) @@ -1117,8 +1115,7 @@ func (s *DockerSwarmSuite) TestSwarmLeaveLocked(c *check.C) { // It starts off locked d.Restart(c, "--swarm-default-advertise-addr=lo") - info, err := d.SwarmInfo() - c.Assert(err, checker.IsNil) + info := d.SwarmInfo(c) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateLocked) outs, _ = d.Cmd("node", "ls") @@ -1132,15 +1129,13 @@ func (s *DockerSwarmSuite) TestSwarmLeaveLocked(c *check.C) { outs, err = d.Cmd("swarm", "leave", "--force") c.Assert(err, checker.IsNil, check.Commentf("out: %v", outs)) - info, err = d.SwarmInfo() - c.Assert(err, checker.IsNil) + info = d.SwarmInfo(c) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive) outs, err = d.Cmd("swarm", "init") c.Assert(err, checker.IsNil, check.Commentf("out: %v", outs)) - info, err = d.SwarmInfo() - c.Assert(err, checker.IsNil) + info = d.SwarmInfo(c) c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive) } @@ -1176,7 +1171,7 @@ func (s *DockerSwarmSuite) TestSwarmLockUnlockCluster(c *check.C) { c.Assert(outs, checker.Equals, unlockKey+"\n") // The ones that got the cluster update should be set to locked - for _, d := range []*daemon.Swarm{d1, d3} { + for _, d := range []*daemon.Daemon{d1, d3} { checkSwarmUnlockedToLocked(c, d) cmd := d.Command("swarm", "unlock") @@ -1197,7 +1192,7 @@ func (s *DockerSwarmSuite) TestSwarmLockUnlockCluster(c *check.C) { c.Assert(err, checker.IsNil, check.Commentf("out: %v", outs)) // the ones that got the update are now set to unlocked - for _, d := range []*daemon.Swarm{d1, d3} { + for _, d := range []*daemon.Daemon{d1, d3} { checkSwarmLockedToUnlocked(c, d, unlockKey) } @@ -1247,7 +1242,7 @@ func (s *DockerSwarmSuite) TestSwarmJoinPromoteLocked(c *check.C) { c.Assert(getNodeStatus(c, d2), checker.Equals, swarm.LocalNodeStateActive) // promote worker - outs, err = d1.Cmd("node", "promote", d2.Info.NodeID) + outs, err = d1.Cmd("node", "promote", d2.NodeID()) c.Assert(err, checker.IsNil) c.Assert(outs, checker.Contains, "promoted to a manager in the swarm") @@ -1255,7 +1250,7 @@ func (s *DockerSwarmSuite) TestSwarmJoinPromoteLocked(c *check.C) { d3 := s.AddDaemon(c, true, true) // both new nodes are locked - for _, d := range []*daemon.Swarm{d2, d3} { + for _, d := range []*daemon.Daemon{d2, d3} { checkSwarmUnlockedToLocked(c, d) cmd := d.Command("swarm", "unlock") @@ -1265,7 +1260,7 @@ func (s *DockerSwarmSuite) TestSwarmJoinPromoteLocked(c *check.C) { } // demote manager back to worker - workers are not locked - outs, err = d1.Cmd("node", "demote", d3.Info.NodeID) + outs, err = d1.Cmd("node", "demote", d3.NodeID()) c.Assert(err, checker.IsNil) c.Assert(outs, checker.Contains, "demoted in the swarm") @@ -1409,7 +1404,7 @@ func (s *DockerSwarmSuite) TestSwarmClusterRotateUnlockKey(c *check.C) { d2.Restart(c) d3.Restart(c) - for _, d := range []*daemon.Swarm{d2, d3} { + for _, d := range []*daemon.Daemon{d2, d3} { c.Assert(getNodeStatus(c, d), checker.Equals, swarm.LocalNodeStateLocked) outs, _ := d.Cmd("node", "ls") @@ -1521,7 +1516,7 @@ func (s *DockerSwarmSuite) TestSwarmManagerAddress(c *check.C) { d3 := s.AddDaemon(c, true, false) // Manager Addresses will always show Node 1's address - expectedOutput := fmt.Sprintf("Manager Addresses:\n 127.0.0.1:%d\n", d1.Port) + expectedOutput := fmt.Sprintf("Manager Addresses:\n 127.0.0.1:%d\n", d1.SwarmPort) out, err := d1.Cmd("info") c.Assert(err, checker.IsNil) @@ -1641,7 +1636,7 @@ func (s *DockerSwarmSuite) TestSwarmJoinWithDrain(c *check.C) { d1 := s.AddDaemon(c, false, false) - out, err = d1.Cmd("swarm", "join", "--availability=drain", "--token", token, d.ListenAddr) + out, err = d1.Cmd("swarm", "join", "--availability=drain", "--token", token, d.SwarmListenAddr()) c.Assert(err, checker.IsNil) c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") @@ -1835,7 +1830,7 @@ func (s *DockerSwarmSuite) TestSwarmJoinLeave(c *check.C) { // Verify that back to back join/leave does not cause panics d1 := s.AddDaemon(c, false, false) for i := 0; i < 10; i++ { - out, err = d1.Cmd("swarm", "join", "--token", token, d.ListenAddr) + out, err = d1.Cmd("swarm", "join", "--token", token, d.SwarmListenAddr()) c.Assert(err, checker.IsNil) c.Assert(strings.TrimSpace(out), checker.Not(checker.Equals), "") @@ -1846,7 +1841,7 @@ func (s *DockerSwarmSuite) TestSwarmJoinLeave(c *check.C) { const defaultRetryCount = 10 -func waitForEvent(c *check.C, d *daemon.Swarm, since string, filter string, event string, retry int) string { +func waitForEvent(c *check.C, d *daemon.Daemon, since string, filter string, event string, retry int) string { if retry < 1 { c.Fatalf("retry count %d is invalid. It should be no less than 1", retry) return "" @@ -1982,7 +1977,7 @@ func (s *DockerSwarmSuite) TestSwarmClusterEventsNode(c *check.C) { s.AddDaemon(c, true, true) d3 := s.AddDaemon(c, true, true) - d3ID := d3.NodeID + d3ID := d3.NodeID() waitForEvent(c, d1, "0", "-f scope=swarm", "node create "+d3ID, defaultRetryCount) t1 := daemonUnixTime(c) diff --git a/components/engine/integration/internal/swarm/service.go b/components/engine/integration/internal/swarm/service.go index 28d367c6601..031995f87a6 100644 --- a/components/engine/integration/internal/swarm/service.go +++ b/components/engine/integration/internal/swarm/service.go @@ -2,7 +2,6 @@ package swarm import ( "context" - "fmt" "runtime" "testing" "time" @@ -11,18 +10,13 @@ import ( "github.com/docker/docker/api/types/filters" swarmtypes "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" - "github.com/docker/docker/integration-cli/daemon" + "github.com/docker/docker/internal/test/daemon" "github.com/docker/docker/internal/test/environment" "github.com/gotestyourself/gotestyourself/assert" "github.com/gotestyourself/gotestyourself/poll" "github.com/gotestyourself/gotestyourself/skip" ) -const ( - dockerdBinary = "dockerd" - defaultSwarmPort = 2477 -) - // ServicePoll tweaks the pollSettings for `service` func ServicePoll(config *poll.Settings) { // Override the default pollSettings for `service` resource here ... @@ -55,23 +49,17 @@ func ContainerPoll(config *poll.Settings) { } // NewSwarm creates a swarm daemon for testing -func NewSwarm(t *testing.T, testEnv *environment.Execution) *daemon.Swarm { +func NewSwarm(t *testing.T, testEnv *environment.Execution, ops ...func(*daemon.Daemon)) *daemon.Daemon { skip.IfCondition(t, testEnv.IsRemoteDaemon()) - d := &daemon.Swarm{ - Daemon: daemon.New(t, "", dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }), - // TODO: better method of finding an unused port - Port: defaultSwarmPort, + if testEnv.DaemonInfo.ExperimentalBuild { + ops = append(ops, daemon.WithExperimental) } - // TODO: move to a NewSwarm constructor - d.ListenAddr = fmt.Sprintf("0.0.0.0:%d", d.Port) - + d := daemon.New(t, ops...) // avoid networking conflicts args := []string{"--iptables=false", "--swarm-default-advertise-addr=lo"} d.StartWithBusybox(t, args...) - assert.NilError(t, d.Init(swarmtypes.InitRequest{})) + d.SwarmInit(t, swarmtypes.InitRequest{}) return d } @@ -79,7 +67,7 @@ func NewSwarm(t *testing.T, testEnv *environment.Execution) *daemon.Swarm { type ServiceSpecOpt func(*swarmtypes.ServiceSpec) // CreateService creates a service on the passed in swarm daemon. -func CreateService(t *testing.T, d *daemon.Swarm, opts ...ServiceSpecOpt) string { +func CreateService(t *testing.T, d *daemon.Daemon, opts ...ServiceSpecOpt) string { spec := defaultServiceSpec() for _, o := range opts { o(&spec) @@ -151,7 +139,7 @@ func ServiceWithName(name string) ServiceSpecOpt { } // GetRunningTasks gets the list of running tasks for a service -func GetRunningTasks(t *testing.T, d *daemon.Swarm, serviceID string) []swarmtypes.Task { +func GetRunningTasks(t *testing.T, d *daemon.Daemon, serviceID string) []swarmtypes.Task { client := GetClient(t, d) filterArgs := filters.NewArgs() @@ -167,7 +155,7 @@ func GetRunningTasks(t *testing.T, d *daemon.Swarm, serviceID string) []swarmtyp } // ExecTask runs the passed in exec config on the given task -func ExecTask(t *testing.T, d *daemon.Swarm, task swarmtypes.Task, config types.ExecConfig) types.HijackedResponse { +func ExecTask(t *testing.T, d *daemon.Daemon, task swarmtypes.Task, config types.ExecConfig) types.HijackedResponse { client := GetClient(t, d) ctx := context.Background() @@ -187,7 +175,7 @@ func ensureContainerSpec(spec *swarmtypes.ServiceSpec) { } // GetClient creates a new client for the passed in swarm daemon. -func GetClient(t *testing.T, d *daemon.Swarm) client.APIClient { +func GetClient(t *testing.T, d *daemon.Daemon) client.APIClient { client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) assert.NilError(t, err) return client diff --git a/components/engine/internal/test/daemon/config.go b/components/engine/internal/test/daemon/config.go new file mode 100644 index 00000000000..4ecc41b5140 --- /dev/null +++ b/components/engine/internal/test/daemon/config.go @@ -0,0 +1,66 @@ +package daemon + +import ( + "context" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/swarm" + "github.com/gotestyourself/gotestyourself/assert" +) + +// ConfigConstructor defines a swarm config constructor +type ConfigConstructor func(*swarm.Config) + +// CreateConfig creates a config given the specified spec +func (d *Daemon) CreateConfig(t assert.TestingT, configSpec swarm.ConfigSpec) string { + cli := d.NewClientT(t) + defer cli.Close() + + scr, err := cli.ConfigCreate(context.Background(), configSpec) + assert.NilError(t, err) + return scr.ID +} + +// ListConfigs returns the list of the current swarm configs +func (d *Daemon) ListConfigs(t assert.TestingT) []swarm.Config { + cli := d.NewClientT(t) + defer cli.Close() + + configs, err := cli.ConfigList(context.Background(), types.ConfigListOptions{}) + assert.NilError(t, err) + return configs +} + +// GetConfig returns a swarm config identified by the specified id +func (d *Daemon) GetConfig(t assert.TestingT, id string) *swarm.Config { + cli := d.NewClientT(t) + defer cli.Close() + + config, _, err := cli.ConfigInspectWithRaw(context.Background(), id) + assert.NilError(t, err) + return &config +} + +// DeleteConfig removes the swarm config identified by the specified id +func (d *Daemon) DeleteConfig(t assert.TestingT, id string) { + cli := d.NewClientT(t) + defer cli.Close() + + err := cli.ConfigRemove(context.Background(), id) + assert.NilError(t, err) +} + +// UpdateConfig updates the swarm config identified by the specified id +// Currently, only label update is supported. +func (d *Daemon) UpdateConfig(t assert.TestingT, id string, f ...ConfigConstructor) { + cli := d.NewClientT(t) + defer cli.Close() + + config := d.GetConfig(t, id) + for _, fn := range f { + fn(config) + } + + err := cli.ConfigUpdate(context.Background(), config.ID, config.Version, config.Spec) + assert.NilError(t, err) +} diff --git a/components/engine/internal/test/daemon/daemon.go b/components/engine/internal/test/daemon/daemon.go index 739e134659c..7324503278b 100644 --- a/components/engine/internal/test/daemon/daemon.go +++ b/components/engine/internal/test/daemon/daemon.go @@ -67,6 +67,13 @@ type Daemon struct { experimental bool dockerdBinary string log logT + + // swarm related field + swarmListenAddr string + SwarmPort int // FIXME(vdemeester) should probably not be exported + + // cached information + CachedInfo types.Info } // New returns a Daemon instance to be used for testing. @@ -98,14 +105,16 @@ func New(t testingT, ops ...func(*Daemon)) *Daemon { } } d := &Daemon{ - id: id, - Folder: daemonFolder, - Root: daemonRoot, - storageDriver: storageDriver, - userlandProxy: userlandProxy, - execRoot: filepath.Join(os.TempDir(), "docker-execroot", id), - dockerdBinary: defaultDockerdBinary, - log: t, + id: id, + Folder: daemonFolder, + Root: daemonRoot, + storageDriver: storageDriver, + userlandProxy: userlandProxy, + execRoot: filepath.Join(os.TempDir(), "docker-execroot", id), + dockerdBinary: defaultDockerdBinary, + swarmListenAddr: defaultSwarmListenAddr, + SwarmPort: defaultSwarmPort, + log: t, } for _, op := range ops { @@ -150,12 +159,23 @@ func (d *Daemon) ReadLogFile() ([]byte, error) { } // NewClient creates new client based on daemon's socket path +// FIXME(vdemeester): replace NewClient with NewClientT func (d *Daemon) NewClient() (*client.Client, error) { return client.NewClientWithOpts( client.FromEnv, client.WithHost(d.Sock())) } +// NewClientT creates new client based on daemon's socket path +// FIXME(vdemeester): replace NewClient with NewClientT +func (d *Daemon) NewClientT(t assert.TestingT) *client.Client { + c, err := client.NewClientWithOpts( + client.FromEnv, + client.WithHost(d.Sock())) + assert.NilError(t, err, "cannot create daemon client") + return c +} + // CleanupExecRoot cleans the daemon exec root (network namespaces, ...) func (d *Daemon) CleanupExecRoot(t testingT) { cleanupExecRoot(t, d.execRoot) @@ -610,7 +630,7 @@ func (d *Daemon) queryRootDir() (string, error) { // Info returns the info struct for this daemon func (d *Daemon) Info(t assert.TestingT) types.Info { - apiclient, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) + apiclient, err := d.NewClient() assert.NilError(t, err) info, err := apiclient.Info(context.Background()) assert.NilError(t, err) diff --git a/components/engine/internal/test/daemon/node.go b/components/engine/internal/test/daemon/node.go new file mode 100644 index 00000000000..9955208b475 --- /dev/null +++ b/components/engine/internal/test/daemon/node.go @@ -0,0 +1,69 @@ +package daemon + +import ( + "context" + "strings" + "time" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/swarm" + "github.com/gotestyourself/gotestyourself/assert" +) + +// NodeConstructor defines a swarm node constructor +type NodeConstructor func(*swarm.Node) + +// GetNode returns a swarm node identified by the specified id +func (d *Daemon) GetNode(t assert.TestingT, id string) *swarm.Node { + cli := d.NewClientT(t) + defer cli.Close() + + node, _, err := cli.NodeInspectWithRaw(context.Background(), id) + assert.NilError(t, err) + assert.Check(t, node.ID == id) + return &node +} + +// RemoveNode removes the specified node +func (d *Daemon) RemoveNode(t assert.TestingT, id string, force bool) { + cli := d.NewClientT(t) + defer cli.Close() + + options := types.NodeRemoveOptions{ + Force: force, + } + err := cli.NodeRemove(context.Background(), id, options) + assert.NilError(t, err) +} + +// UpdateNode updates a swarm node with the specified node constructor +func (d *Daemon) UpdateNode(t assert.TestingT, id string, f ...NodeConstructor) { + cli := d.NewClientT(t) + defer cli.Close() + + for i := 0; ; i++ { + node := d.GetNode(t, id) + for _, fn := range f { + fn(node) + } + + err := cli.NodeUpdate(context.Background(), node.ID, node.Version, node.Spec) + if i < 10 && err != nil && strings.Contains(err.Error(), "update out of sequence") { + time.Sleep(100 * time.Millisecond) + continue + } + assert.NilError(t, err) + return + } +} + +// ListNodes returns the list of the current swarm nodes +func (d *Daemon) ListNodes(t assert.TestingT) []swarm.Node { + cli := d.NewClientT(t) + defer cli.Close() + + nodes, err := cli.NodeList(context.Background(), types.NodeListOptions{}) + assert.NilError(t, err) + + return nodes +} diff --git a/components/engine/internal/test/daemon/ops.go b/components/engine/internal/test/daemon/ops.go index 0c49749414a..0176c19d93c 100644 --- a/components/engine/internal/test/daemon/ops.go +++ b/components/engine/internal/test/daemon/ops.go @@ -11,3 +11,17 @@ func WithDockerdBinary(dockerdBinary string) func(*Daemon) { d.dockerdBinary = dockerdBinary } } + +// WithSwarmPort sets the swarm port to use for swarm mode +func WithSwarmPort(port int) func(*Daemon) { + return func(d *Daemon) { + d.SwarmPort = port + } +} + +// WithSwarmListenAddr sets the swarm listen addr to use for swarm mode +func WithSwarmListenAddr(listenAddr string) func(*Daemon) { + return func(d *Daemon) { + d.swarmListenAddr = listenAddr + } +} diff --git a/components/engine/internal/test/daemon/secret.go b/components/engine/internal/test/daemon/secret.go new file mode 100644 index 00000000000..075aedc2e0f --- /dev/null +++ b/components/engine/internal/test/daemon/secret.go @@ -0,0 +1,68 @@ +package daemon + +import ( + "context" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/swarm" + "github.com/gotestyourself/gotestyourself/assert" +) + +// SecretConstructor defines a swarm secret constructor +type SecretConstructor func(*swarm.Secret) + +// CreateSecret creates a secret given the specified spec +func (d *Daemon) CreateSecret(t assert.TestingT, secretSpec swarm.SecretSpec) string { + cli := d.NewClientT(t) + defer cli.Close() + + scr, err := cli.SecretCreate(context.Background(), secretSpec) + assert.NilError(t, err) + + return scr.ID +} + +// ListSecrets returns the list of the current swarm secrets +func (d *Daemon) ListSecrets(t assert.TestingT) []swarm.Secret { + cli := d.NewClientT(t) + defer cli.Close() + + secrets, err := cli.SecretList(context.Background(), types.SecretListOptions{}) + assert.NilError(t, err) + return secrets +} + +// GetSecret returns a swarm secret identified by the specified id +func (d *Daemon) GetSecret(t assert.TestingT, id string) *swarm.Secret { + cli := d.NewClientT(t) + defer cli.Close() + + secret, _, err := cli.SecretInspectWithRaw(context.Background(), id) + assert.NilError(t, err) + return &secret +} + +// DeleteSecret removes the swarm secret identified by the specified id +func (d *Daemon) DeleteSecret(t assert.TestingT, id string) { + cli := d.NewClientT(t) + defer cli.Close() + + err := cli.SecretRemove(context.Background(), id) + assert.NilError(t, err) +} + +// UpdateSecret updates the swarm secret identified by the specified id +// Currently, only label update is supported. +func (d *Daemon) UpdateSecret(t assert.TestingT, id string, f ...SecretConstructor) { + cli := d.NewClientT(t) + defer cli.Close() + + secret := d.GetSecret(t, id) + for _, fn := range f { + fn(secret) + } + + err := cli.SecretUpdate(context.Background(), secret.ID, secret.Version, secret.Spec) + + assert.NilError(t, err) +} diff --git a/components/engine/internal/test/daemon/service.go b/components/engine/internal/test/daemon/service.go new file mode 100644 index 00000000000..26e6004ae11 --- /dev/null +++ b/components/engine/internal/test/daemon/service.go @@ -0,0 +1,108 @@ +package daemon + +import ( + "context" + "time" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/swarm" + "github.com/gotestyourself/gotestyourself/assert" +) + +// ServiceConstructor defines a swarm service constructor function +type ServiceConstructor func(*swarm.Service) + +// CreateServiceWithOptions creates a swarm service given the specified service constructors +// and auth config +func (d *Daemon) CreateServiceWithOptions(t assert.TestingT, opts types.ServiceCreateOptions, f ...ServiceConstructor) string { + var service swarm.Service + for _, fn := range f { + fn(&service) + } + + cli := d.NewClientT(t) + defer cli.Close() + + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + + res, err := cli.ServiceCreate(ctx, service.Spec, opts) + assert.NilError(t, err) + return res.ID +} + +// CreateService creates a swarm service given the specified service constructor +func (d *Daemon) CreateService(t assert.TestingT, f ...ServiceConstructor) string { + return d.CreateServiceWithOptions(t, types.ServiceCreateOptions{}, f...) +} + +// GetService returns the swarm service corresponding to the specified id +func (d *Daemon) GetService(t assert.TestingT, id string) *swarm.Service { + cli := d.NewClientT(t) + defer cli.Close() + + service, _, err := cli.ServiceInspectWithRaw(context.Background(), id, types.ServiceInspectOptions{}) + assert.NilError(t, err) + return &service +} + +// GetServiceTasks returns the swarm tasks for the specified service +func (d *Daemon) GetServiceTasks(t assert.TestingT, service string) []swarm.Task { + cli := d.NewClientT(t) + defer cli.Close() + + filterArgs := filters.NewArgs() + filterArgs.Add("desired-state", "running") + filterArgs.Add("service", service) + + options := types.TaskListOptions{ + Filters: filterArgs, + } + + tasks, err := cli.TaskList(context.Background(), options) + assert.NilError(t, err) + return tasks +} + +// UpdateService updates a swarm service with the specified service constructor +func (d *Daemon) UpdateService(t assert.TestingT, service *swarm.Service, f ...ServiceConstructor) { + cli := d.NewClientT(t) + defer cli.Close() + + for _, fn := range f { + fn(service) + } + + _, err := cli.ServiceUpdate(context.Background(), service.ID, service.Version, service.Spec, types.ServiceUpdateOptions{}) + assert.NilError(t, err) +} + +// RemoveService removes the specified service +func (d *Daemon) RemoveService(t assert.TestingT, id string) { + cli := d.NewClientT(t) + defer cli.Close() + + err := cli.ServiceRemove(context.Background(), id) + assert.NilError(t, err) +} + +// ListServices returns the list of the current swarm services +func (d *Daemon) ListServices(t assert.TestingT) []swarm.Service { + cli := d.NewClientT(t) + defer cli.Close() + + services, err := cli.ServiceList(context.Background(), types.ServiceListOptions{}) + assert.NilError(t, err) + return services +} + +// GetTask returns the swarm task identified by the specified id +func (d *Daemon) GetTask(t assert.TestingT, id string) swarm.Task { + cli := d.NewClientT(t) + defer cli.Close() + + task, _, err := cli.TaskInspectWithRaw(context.Background(), id) + assert.NilError(t, err) + return task +} diff --git a/components/engine/internal/test/daemon/swarm.go b/components/engine/internal/test/daemon/swarm.go new file mode 100644 index 00000000000..f0cf3734680 --- /dev/null +++ b/components/engine/internal/test/daemon/swarm.go @@ -0,0 +1,139 @@ +package daemon + +import ( + "context" + "fmt" + + "github.com/docker/docker/api/types/swarm" + "github.com/gotestyourself/gotestyourself/assert" + "github.com/pkg/errors" +) + +const ( + defaultSwarmPort = 2477 + defaultSwarmListenAddr = "0.0.0.0" +) + +// SpecConstructor defines a swarm spec constructor +type SpecConstructor func(*swarm.Spec) + +// SwarmListenAddr returns the listen-addr used for the daemon +func (d *Daemon) SwarmListenAddr() string { + return fmt.Sprintf("%s:%d", d.swarmListenAddr, d.SwarmPort) +} + +// NodeID returns the swarm mode node ID +func (d *Daemon) NodeID() string { + return d.CachedInfo.Swarm.NodeID +} + +// SwarmInit initializes a new swarm cluster. +func (d *Daemon) SwarmInit(t assert.TestingT, req swarm.InitRequest) { + if req.ListenAddr == "" { + req.ListenAddr = fmt.Sprintf("%s:%d", d.swarmListenAddr, d.SwarmPort) + } + cli := d.NewClientT(t) + defer cli.Close() + _, err := cli.SwarmInit(context.Background(), req) + assert.NilError(t, err, "initializing swarm") + d.CachedInfo = d.Info(t) +} + +// SwarmJoin joins a daemon to an existing cluster. +func (d *Daemon) SwarmJoin(t assert.TestingT, req swarm.JoinRequest) { + if req.ListenAddr == "" { + req.ListenAddr = fmt.Sprintf("%s:%d", d.swarmListenAddr, d.SwarmPort) + } + cli := d.NewClientT(t) + defer cli.Close() + err := cli.SwarmJoin(context.Background(), req) + assert.NilError(t, err, "initializing swarm") + d.CachedInfo = d.Info(t) +} + +// SwarmLeave forces daemon to leave current cluster. +func (d *Daemon) SwarmLeave(force bool) error { + cli, err := d.NewClient() + if err != nil { + return fmt.Errorf("leaving swarm: failed to create client %v", err) + } + defer cli.Close() + err = cli.SwarmLeave(context.Background(), force) + if err != nil { + err = fmt.Errorf("leaving swarm: %v", err) + } + return err +} + +// SwarmInfo returns the swarm information of the daemon +func (d *Daemon) SwarmInfo(t assert.TestingT) swarm.Info { + cli := d.NewClientT(t) + info, err := cli.Info(context.Background()) + assert.NilError(t, err, "get swarm info") + return info.Swarm +} + +// SwarmUnlock tries to unlock a locked swarm +func (d *Daemon) SwarmUnlock(req swarm.UnlockRequest) error { + cli, err := d.NewClient() + if err != nil { + return fmt.Errorf("unlocking swarm: failed to create client %v", err) + } + defer cli.Close() + err = cli.SwarmUnlock(context.Background(), req) + if err != nil { + err = errors.Wrap(err, "unlocking swarm") + } + return err +} + +// GetSwarm returns the current swarm object +func (d *Daemon) GetSwarm(t assert.TestingT) swarm.Swarm { + cli := d.NewClientT(t) + defer cli.Close() + + sw, err := cli.SwarmInspect(context.Background()) + assert.NilError(t, err) + return sw +} + +// UpdateSwarm updates the current swarm object with the specified spec constructors +func (d *Daemon) UpdateSwarm(t assert.TestingT, f ...SpecConstructor) { + cli := d.NewClientT(t) + defer cli.Close() + + sw := d.GetSwarm(t) + for _, fn := range f { + fn(&sw.Spec) + } + + err := cli.SwarmUpdate(context.Background(), sw.Version, sw.Spec, swarm.UpdateFlags{}) + assert.NilError(t, err) +} + +// RotateTokens update the swarm to rotate tokens +func (d *Daemon) RotateTokens(t assert.TestingT) { + cli := d.NewClientT(t) + defer cli.Close() + + sw, err := cli.SwarmInspect(context.Background()) + assert.NilError(t, err) + + flags := swarm.UpdateFlags{ + RotateManagerToken: true, + RotateWorkerToken: true, + } + + err = cli.SwarmUpdate(context.Background(), sw.Version, sw.Spec, flags) + assert.NilError(t, err) +} + +// JoinTokens returns the current swarm join tokens +func (d *Daemon) JoinTokens(t assert.TestingT) swarm.JoinTokens { + cli := d.NewClientT(t) + defer cli.Close() + + sw, err := cli.SwarmInspect(context.Background()) + assert.NilError(t, err) + return sw.JoinTokens +} From cb93f50ae01ca4b204e71bbd1f3fdad5113fa037 Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Wed, 11 Apr 2018 11:14:47 +0200 Subject: [PATCH 24/36] Migrate test-integration-cli experimental ipvlan test to integration All `Ipvlan` related test on `DockerSuite` and `DockerNetworkSuite` are migrated to `ipvlan_test.go`. The end goal being to remove the `experimental` builds. Signed-off-by: Vincent Demeester (cherry picked from commit 24f934751120ea420b7ba4d2e314df805f3eff06) Signed-off-by: Sebastiaan van Stijn --- .../docker_experimental_network_test.go | 340 ----------- .../integration/internal/container/ops.go | 6 + .../engine/integration/network/ipvlan_test.go | 543 ++++++++++++++++++ .../integration/network/macvlan_test.go | 55 +- 4 files changed, 603 insertions(+), 341 deletions(-) delete mode 100644 components/engine/integration-cli/docker_experimental_network_test.go create mode 100644 components/engine/integration/network/ipvlan_test.go diff --git a/components/engine/integration-cli/docker_experimental_network_test.go b/components/engine/integration-cli/docker_experimental_network_test.go deleted file mode 100644 index 5fcdafcabcc..00000000000 --- a/components/engine/integration-cli/docker_experimental_network_test.go +++ /dev/null @@ -1,340 +0,0 @@ -// +build !windows - -package main - -import ( - "strings" - "time" - - "github.com/docker/docker/integration-cli/checker" - "github.com/docker/docker/integration-cli/cli" - "github.com/docker/docker/pkg/parsers/kernel" - "github.com/go-check/check" - "github.com/gotestyourself/gotestyourself/icmd" -) - -// ensure Kernel version is >= v3.9 for macvlan support -func macvlanKernelSupport() bool { - return checkKernelMajorVersionGreaterOrEqualThen(3, 9) -} - -// ensure Kernel version is >= v4.2 for ipvlan support -func ipvlanKernelSupport() bool { - return checkKernelMajorVersionGreaterOrEqualThen(4, 2) -} - -func checkKernelMajorVersionGreaterOrEqualThen(kernelVersion int, majorVersion int) bool { - kv, err := kernel.GetKernelVersion() - if err != nil { - return false - } - if kv.Kernel < kernelVersion || (kv.Kernel == kernelVersion && kv.Major < majorVersion) { - return false - } - return true -} - -func (s *DockerNetworkSuite) TestDockerNetworkIpvlanPersistance(c *check.C) { - // verify the driver automatically provisions the 802.1q link (di-dummy0.70) - testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon, SameHostDaemon) - // master dummy interface 'di' notation represent 'docker ipvlan' - master := "di-dummy0" - // simulate the master link the vlan tagged subinterface parent link will use - createMasterDummy(c, master) - // cleanup the master interface that also collects the slave dev - defer deleteInterface(c, master) - // create a network specifying the desired sub-interface name - dockerCmd(c, "network", "create", "--driver=ipvlan", "-o", "parent=di-dummy0.70", "di-persist") - assertNwIsAvailable(c, "di-persist") - // Restart docker daemon to test the config has persisted to disk - s.d.Restart(c) - // verify network is recreated from persistence - assertNwIsAvailable(c, "di-persist") -} - -func (s *DockerNetworkSuite) TestDockerNetworkIpvlanSubIntCreate(c *check.C) { - // verify the driver automatically provisions the 802.1q link (di-dummy0.50) - testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon, SameHostDaemon) - // master dummy interface 'dm' abbreviation represents 'docker ipvlan' - master := "di-dummy0" - // simulate the master link the vlan tagged subinterface parent link will use - createMasterDummy(c, master) - // cleanup the master interface which also collects the slave dev - defer deleteInterface(c, master) - // create a network specifying the desired sub-interface name - dockerCmd(c, "network", "create", "--driver=ipvlan", "-o", "parent=di-dummy0.60", "di-subinterface") - assertNwIsAvailable(c, "di-subinterface") -} - -func (s *DockerNetworkSuite) TestDockerNetworkIpvlanOverlapParent(c *check.C) { - // verify the same parent interface cannot be used if already in use by an existing network - testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon, SameHostDaemon) - // master dummy interface 'dm' abbreviation represents 'docker ipvlan' - master := "di-dummy0" - createMasterDummy(c, master) - // cleanup the master interface which also collects the slave dev - defer deleteInterface(c, master) - createVlanInterface(c, master, "di-dummy0.30", "30") - // create a network using an existing parent interface - dockerCmd(c, "network", "create", "--driver=ipvlan", "-o", "parent=di-dummy0.30", "di-subinterface") - assertNwIsAvailable(c, "di-subinterface") - // attempt to create another network using the same parent iface that should fail - out, _, err := dockerCmdWithError("network", "create", "--driver=ipvlan", "-o", "parent=di-dummy0.30", "di-parent-net-overlap") - // verify that the overlap returns an error - c.Assert(err, check.NotNil, check.Commentf(out)) -} - -func (s *DockerNetworkSuite) TestDockerNetworkIpvlanL2MultiSubnet(c *check.C) { - // create a dual stack multi-subnet Ipvlan L2 network and validate connectivity within the subnets, two on each subnet - testRequires(c, DaemonIsLinux, IPv6, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) - dockerCmd(c, "network", "create", "--driver=ipvlan", "--ipv6", "--subnet=172.28.200.0/24", "--subnet=172.28.202.0/24", "--gateway=172.28.202.254", - "--subnet=2001:db8:abc8::/64", "--subnet=2001:db8:abc6::/64", "--gateway=2001:db8:abc6::254", "dualstackl2") - // Ensure the network was created - assertNwIsAvailable(c, "dualstackl2") - // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.200.0/24 and 2001:db8:abc8::/64 - dockerCmd(c, "run", "-d", "--net=dualstackl2", "--name=first", "--ip", "172.28.200.20", "--ip6", "2001:db8:abc8::20", "busybox:glibc", "top") - dockerCmd(c, "run", "-d", "--net=dualstackl2", "--name=second", "--ip", "172.28.200.21", "--ip6", "2001:db8:abc8::21", "busybox:glibc", "top") - - // Inspect and store the v4 address from specified container on the network dualstackl2 - ip := inspectField(c, "first", "NetworkSettings.Networks.dualstackl2.IPAddress") - // Inspect and store the v6 address from specified container on the network dualstackl2 - ip6 := inspectField(c, "first", "NetworkSettings.Networks.dualstackl2.GlobalIPv6Address") - - // verify ipv4 connectivity to the explicit --ipv address second to first - _, _, err := dockerCmdWithError("exec", "second", "ping", "-c", "1", strings.TrimSpace(ip)) - c.Assert(err, check.IsNil) - // verify ipv6 connectivity to the explicit --ipv6 address second to first - _, _, err = dockerCmdWithError("exec", "second", "ping6", "-c", "1", strings.TrimSpace(ip6)) - c.Assert(err, check.IsNil) - - // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.202.0/24 and 2001:db8:abc6::/64 - dockerCmd(c, "run", "-d", "--net=dualstackl2", "--name=third", "--ip", "172.28.202.20", "--ip6", "2001:db8:abc6::20", "busybox:glibc", "top") - dockerCmd(c, "run", "-d", "--net=dualstackl2", "--name=fourth", "--ip", "172.28.202.21", "--ip6", "2001:db8:abc6::21", "busybox:glibc", "top") - - // Inspect and store the v4 address from specified container on the network dualstackl2 - ip = inspectField(c, "third", "NetworkSettings.Networks.dualstackl2.IPAddress") - // Inspect and store the v6 address from specified container on the network dualstackl2 - ip6 = inspectField(c, "third", "NetworkSettings.Networks.dualstackl2.GlobalIPv6Address") - - // verify ipv4 connectivity to the explicit --ipv address from third to fourth - _, _, err = dockerCmdWithError("exec", "fourth", "ping", "-c", "1", strings.TrimSpace(ip)) - c.Assert(err, check.IsNil) - // verify ipv6 connectivity to the explicit --ipv6 address from third to fourth - _, _, err = dockerCmdWithError("exec", "fourth", "ping6", "-c", "1", strings.TrimSpace(ip6)) - c.Assert(err, check.IsNil) - - // Inspect the v4 gateway to ensure the proper default GW was assigned - ip4gw := inspectField(c, "first", "NetworkSettings.Networks.dualstackl2.Gateway") - c.Assert(strings.TrimSpace(ip4gw), check.Equals, "172.28.200.1") - // Inspect the v6 gateway to ensure the proper default GW was assigned - ip6gw := inspectField(c, "first", "NetworkSettings.Networks.dualstackl2.IPv6Gateway") - c.Assert(strings.TrimSpace(ip6gw), check.Equals, "2001:db8:abc8::1") - - // Inspect the v4 gateway to ensure the proper explicitly assigned default GW was assigned - ip4gw = inspectField(c, "third", "NetworkSettings.Networks.dualstackl2.Gateway") - c.Assert(strings.TrimSpace(ip4gw), check.Equals, "172.28.202.254") - // Inspect the v6 gateway to ensure the proper explicitly assigned default GW was assigned - ip6gw = inspectField(c, "third", "NetworkSettings.Networks.dualstackl2.IPv6Gateway") - c.Assert(strings.TrimSpace(ip6gw), check.Equals, "2001:db8:abc6::254") -} - -func (s *DockerNetworkSuite) TestDockerNetworkIpvlanL3MultiSubnet(c *check.C) { - // create a dual stack multi-subnet Ipvlan L3 network and validate connectivity between all four containers per L3 mode - testRequires(c, DaemonIsLinux, IPv6, ipvlanKernelSupport, NotUserNamespace, NotArm, IPv6, ExperimentalDaemon) - dockerCmd(c, "network", "create", "--driver=ipvlan", "--ipv6", "--subnet=172.28.10.0/24", "--subnet=172.28.12.0/24", "--gateway=172.28.12.254", - "--subnet=2001:db8:abc9::/64", "--subnet=2001:db8:abc7::/64", "--gateway=2001:db8:abc7::254", "-o", "ipvlan_mode=l3", "dualstackl3") - // Ensure the network was created - assertNwIsAvailable(c, "dualstackl3") - - // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.10.0/24 and 2001:db8:abc9::/64 - dockerCmd(c, "run", "-d", "--net=dualstackl3", "--name=first", "--ip", "172.28.10.20", "--ip6", "2001:db8:abc9::20", "busybox:glibc", "top") - dockerCmd(c, "run", "-d", "--net=dualstackl3", "--name=second", "--ip", "172.28.10.21", "--ip6", "2001:db8:abc9::21", "busybox:glibc", "top") - - // Inspect and store the v4 address from specified container on the network dualstackl3 - ip := inspectField(c, "first", "NetworkSettings.Networks.dualstackl3.IPAddress") - // Inspect and store the v6 address from specified container on the network dualstackl3 - ip6 := inspectField(c, "first", "NetworkSettings.Networks.dualstackl3.GlobalIPv6Address") - - // verify ipv4 connectivity to the explicit --ipv address second to first - _, _, err := dockerCmdWithError("exec", "second", "ping", "-c", "1", strings.TrimSpace(ip)) - c.Assert(err, check.IsNil) - // verify ipv6 connectivity to the explicit --ipv6 address second to first - _, _, err = dockerCmdWithError("exec", "second", "ping6", "-c", "1", strings.TrimSpace(ip6)) - c.Assert(err, check.IsNil) - - // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.12.0/24 and 2001:db8:abc7::/64 - dockerCmd(c, "run", "-d", "--net=dualstackl3", "--name=third", "--ip", "172.28.12.20", "--ip6", "2001:db8:abc7::20", "busybox:glibc", "top") - dockerCmd(c, "run", "-d", "--net=dualstackl3", "--name=fourth", "--ip", "172.28.12.21", "--ip6", "2001:db8:abc7::21", "busybox:glibc", "top") - - // Inspect and store the v4 address from specified container on the network dualstackl3 - ip = inspectField(c, "third", "NetworkSettings.Networks.dualstackl3.IPAddress") - // Inspect and store the v6 address from specified container on the network dualstackl3 - ip6 = inspectField(c, "third", "NetworkSettings.Networks.dualstackl3.GlobalIPv6Address") - - // verify ipv4 connectivity to the explicit --ipv address from third to fourth - _, _, err = dockerCmdWithError("exec", "fourth", "ping", "-c", "1", strings.TrimSpace(ip)) - c.Assert(err, check.IsNil) - // verify ipv6 connectivity to the explicit --ipv6 address from third to fourth - _, _, err = dockerCmdWithError("exec", "fourth", "ping6", "-c", "1", strings.TrimSpace(ip6)) - c.Assert(err, check.IsNil) - - // Inspect and store the v4 address from specified container on the network dualstackl3 - ip = inspectField(c, "second", "NetworkSettings.Networks.dualstackl3.IPAddress") - // Inspect and store the v6 address from specified container on the network dualstackl3 - ip6 = inspectField(c, "second", "NetworkSettings.Networks.dualstackl3.GlobalIPv6Address") - - // Verify connectivity across disparate subnets which is unique to L3 mode only - _, _, err = dockerCmdWithError("exec", "third", "ping", "-c", "1", strings.TrimSpace(ip)) - c.Assert(err, check.IsNil) - _, _, err = dockerCmdWithError("exec", "third", "ping6", "-c", "1", strings.TrimSpace(ip6)) - c.Assert(err, check.IsNil) - - // Inspect the v4 gateway to ensure no next hop is assigned in L3 mode - ip4gw := inspectField(c, "first", "NetworkSettings.Networks.dualstackl3.Gateway") - c.Assert(strings.TrimSpace(ip4gw), check.Equals, "") - // Inspect the v6 gateway to ensure the explicitly specified default GW is ignored per L3 mode enabled - ip6gw := inspectField(c, "third", "NetworkSettings.Networks.dualstackl3.IPv6Gateway") - c.Assert(strings.TrimSpace(ip6gw), check.Equals, "") -} - -func (s *DockerNetworkSuite) TestDockerNetworkIpvlanAddressing(c *check.C) { - // Ensure the default gateways, next-hops and default dev devices are properly set - testRequires(c, DaemonIsLinux, IPv6, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) - dockerCmd(c, "network", "create", "--driver=macvlan", "--ipv6", "--subnet=172.28.130.0/24", - "--subnet=2001:db8:abca::/64", "--gateway=2001:db8:abca::254", "-o", "macvlan_mode=bridge", "dualstackbridge") - assertNwIsAvailable(c, "dualstackbridge") - dockerCmd(c, "run", "-d", "--net=dualstackbridge", "--name=first", "busybox", "top") - // Validate macvlan bridge mode defaults gateway sets the default IPAM next-hop inferred from the subnet - out, _, err := dockerCmdWithError("exec", "first", "ip", "route") - c.Assert(err, check.IsNil) - c.Assert(out, checker.Contains, "default via 172.28.130.1 dev eth0") - // Validate macvlan bridge mode sets the v6 gateway to the user specified default gateway/next-hop - out, _, err = dockerCmdWithError("exec", "first", "ip", "-6", "route") - c.Assert(err, check.IsNil) - c.Assert(out, checker.Contains, "default via 2001:db8:abca::254 dev eth0") - - // Verify ipvlan l2 mode sets the proper default gateway routes via netlink - // for either an explicitly set route by the user or inferred via default IPAM - dockerCmd(c, "network", "create", "--driver=ipvlan", "--ipv6", "--subnet=172.28.140.0/24", "--gateway=172.28.140.254", - "--subnet=2001:db8:abcb::/64", "-o", "ipvlan_mode=l2", "dualstackl2") - assertNwIsAvailable(c, "dualstackl2") - dockerCmd(c, "run", "-d", "--net=dualstackl2", "--name=second", "busybox", "top") - // Validate ipvlan l2 mode defaults gateway sets the default IPAM next-hop inferred from the subnet - out, _, err = dockerCmdWithError("exec", "second", "ip", "route") - c.Assert(err, check.IsNil) - c.Assert(out, checker.Contains, "default via 172.28.140.254 dev eth0") - // Validate ipvlan l2 mode sets the v6 gateway to the user specified default gateway/next-hop - out, _, err = dockerCmdWithError("exec", "second", "ip", "-6", "route") - c.Assert(err, check.IsNil) - c.Assert(out, checker.Contains, "default via 2001:db8:abcb::1 dev eth0") - - // Validate ipvlan l3 mode sets the v4 gateway to dev eth0 and disregards any explicit or inferred next-hops - dockerCmd(c, "network", "create", "--driver=ipvlan", "--ipv6", "--subnet=172.28.160.0/24", "--gateway=172.28.160.254", - "--subnet=2001:db8:abcd::/64", "--gateway=2001:db8:abcd::254", "-o", "ipvlan_mode=l3", "dualstackl3") - assertNwIsAvailable(c, "dualstackl3") - dockerCmd(c, "run", "-d", "--net=dualstackl3", "--name=third", "busybox", "top") - // Validate ipvlan l3 mode sets the v4 gateway to dev eth0 and disregards any explicit or inferred next-hops - out, _, err = dockerCmdWithError("exec", "third", "ip", "route") - c.Assert(err, check.IsNil) - c.Assert(out, checker.Contains, "default dev eth0") - // Validate ipvlan l3 mode sets the v6 gateway to dev eth0 and disregards any explicit or inferred next-hops - out, _, err = dockerCmdWithError("exec", "third", "ip", "-6", "route") - c.Assert(err, check.IsNil) - c.Assert(out, checker.Contains, "default dev eth0") -} - -func (s *DockerSuite) TestDockerNetworkIpvlanL2NilParent(c *check.C) { - // ipvlan l2 mode - dummy parent interface is provisioned dynamically - testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) - dockerCmd(c, "network", "create", "--driver=ipvlan", "di-nil-parent") - assertNwIsAvailable(c, "di-nil-parent") - - // start two containers on the same subnet - dockerCmd(c, "run", "-d", "--net=di-nil-parent", "--name=first", "busybox:glibc", "top") - c.Assert(waitRun("first"), check.IsNil) - dockerCmd(c, "run", "-d", "--net=di-nil-parent", "--name=second", "busybox:glibc", "top") - c.Assert(waitRun("second"), check.IsNil) - - // intra-network communications should succeed - _, _, err := dockerCmdWithError("exec", "second", "ping", "-c", "1", "first") - c.Assert(err, check.IsNil) -} - -func (s *DockerSuite) TestDockerNetworkIpvlanL2InternalMode(c *check.C) { - // ipvlan l2 mode --internal containers can communicate inside the network but not externally - testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) - cli.DockerCmd(c, "network", "create", "--driver=ipvlan", "--internal", "di-internal") - assertNwIsAvailable(c, "di-internal") - nr := getNetworkResource(c, "di-internal") - c.Assert(nr.Internal, checker.True) - - // start two containers on the same subnet - cli.DockerCmd(c, "run", "-d", "--net=di-internal", "--name=first", "busybox:glibc", "top") - c.Assert(waitRun("first"), check.IsNil) - cli.DockerCmd(c, "run", "-d", "--net=di-internal", "--name=second", "busybox:glibc", "top") - c.Assert(waitRun("second"), check.IsNil) - - // access outside of the network should fail - result := cli.Docker(cli.Args("exec", "first", "ping", "-c", "1", "-w", "1", "8.8.8.8"), cli.WithTimeout(time.Second)) - result.Assert(c, icmd.Expected{Timeout: true}) - // intra-network communications should succeed - cli.DockerCmd(c, "exec", "second", "ping", "-c", "1", "first") -} - -func (s *DockerSuite) TestDockerNetworkIpvlanL3NilParent(c *check.C) { - // ipvlan l3 mode - dummy parent interface is provisioned dynamically - testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) - dockerCmd(c, "network", "create", "--driver=ipvlan", "--subnet=172.28.230.0/24", - "--subnet=172.28.220.0/24", "-o", "ipvlan_mode=l3", "di-nil-parent-l3") - assertNwIsAvailable(c, "di-nil-parent-l3") - - // start two containers on separate subnets - dockerCmd(c, "run", "-d", "--ip=172.28.220.10", "--net=di-nil-parent-l3", "--name=first", "busybox:glibc", "top") - c.Assert(waitRun("first"), check.IsNil) - dockerCmd(c, "run", "-d", "--ip=172.28.230.10", "--net=di-nil-parent-l3", "--name=second", "busybox:glibc", "top") - c.Assert(waitRun("second"), check.IsNil) - - // intra-network communications should succeed - _, _, err := dockerCmdWithError("exec", "second", "ping", "-c", "1", "first") - c.Assert(err, check.IsNil) -} - -func (s *DockerSuite) TestDockerNetworkIpvlanL3InternalMode(c *check.C) { - // ipvlan l3 mode --internal containers can communicate inside the network but not externally - testRequires(c, DaemonIsLinux, ipvlanKernelSupport, NotUserNamespace, NotArm, ExperimentalDaemon) - cli.DockerCmd(c, "network", "create", "--driver=ipvlan", "--subnet=172.28.230.0/24", - "--subnet=172.28.220.0/24", "-o", "ipvlan_mode=l3", "--internal", "di-internal-l3") - assertNwIsAvailable(c, "di-internal-l3") - nr := getNetworkResource(c, "di-internal-l3") - c.Assert(nr.Internal, checker.True) - - // start two containers on separate subnets - cli.DockerCmd(c, "run", "-d", "--ip=172.28.220.10", "--net=di-internal-l3", "--name=first", "busybox:glibc", "top") - c.Assert(waitRun("first"), check.IsNil) - cli.DockerCmd(c, "run", "-d", "--ip=172.28.230.10", "--net=di-internal-l3", "--name=second", "busybox:glibc", "top") - c.Assert(waitRun("second"), check.IsNil) - - // access outside of the network should fail - result := cli.Docker(cli.Args("exec", "first", "ping", "-c", "1", "-w", "1", "8.8.8.8"), cli.WithTimeout(time.Second)) - result.Assert(c, icmd.Expected{Timeout: true}) - // intra-network communications should succeed - cli.DockerCmd(c, "exec", "second", "ping", "-c", "1", "first") -} - -func createMasterDummy(c *check.C, master string) { - // ip link add type dummy - icmd.RunCommand("ip", "link", "add", master, "type", "dummy").Assert(c, icmd.Success) - icmd.RunCommand("ip", "link", "set", master, "up").Assert(c, icmd.Success) -} - -func createVlanInterface(c *check.C, master, slave, id string) { - // ip link add link name . type vlan id - icmd.RunCommand("ip", "link", "add", "link", master, "name", slave, "type", "vlan", "id", id).Assert(c, icmd.Success) - // ip link set up - icmd.RunCommand("ip", "link", "set", slave, "up").Assert(c, icmd.Success) -} - -func linkExists(c *check.C, master string) { - // verify the specified link exists, ip link show - icmd.RunCommand("ip", "link", "show", master).Assert(c, icmd.Success) -} diff --git a/components/engine/integration/internal/container/ops.go b/components/engine/integration/internal/container/ops.go index afbb695e7df..b7d1a7bda95 100644 --- a/components/engine/integration/internal/container/ops.go +++ b/components/engine/integration/internal/container/ops.go @@ -88,6 +88,9 @@ func WithBind(src, target string) func(*TestContainerConfig) { // WithIPv4 sets the specified ip for the specified network of the container func WithIPv4(network, ip string) func(*TestContainerConfig) { return func(c *TestContainerConfig) { + if c.NetworkingConfig.EndpointsConfig == nil { + c.NetworkingConfig.EndpointsConfig = map[string]*networktypes.EndpointSettings{} + } if v, ok := c.NetworkingConfig.EndpointsConfig[network]; !ok || v == nil { c.NetworkingConfig.EndpointsConfig[network] = &networktypes.EndpointSettings{} } @@ -101,6 +104,9 @@ func WithIPv4(network, ip string) func(*TestContainerConfig) { // WithIPv6 sets the specified ip6 for the specified network of the container func WithIPv6(network, ip string) func(*TestContainerConfig) { return func(c *TestContainerConfig) { + if c.NetworkingConfig.EndpointsConfig == nil { + c.NetworkingConfig.EndpointsConfig = map[string]*networktypes.EndpointSettings{} + } if v, ok := c.NetworkingConfig.EndpointsConfig[network]; !ok || v == nil { c.NetworkingConfig.EndpointsConfig[network] = &networktypes.EndpointSettings{} } diff --git a/components/engine/integration/network/ipvlan_test.go b/components/engine/integration/network/ipvlan_test.go new file mode 100644 index 00000000000..a741d8b7f8e --- /dev/null +++ b/components/engine/integration/network/ipvlan_test.go @@ -0,0 +1,543 @@ +package network + +import ( + "strings" + "testing" + "time" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/network" + dclient "github.com/docker/docker/client" + "github.com/docker/docker/integration-cli/daemon" + "github.com/docker/docker/integration/internal/container" + "github.com/gotestyourself/gotestyourself/assert" + "github.com/gotestyourself/gotestyourself/skip" + "golang.org/x/net/context" +) + +func TestDockerNetworkIpvlanPersistance(t *testing.T) { + // verify the driver automatically provisions the 802.1q link (di-dummy0.70) + skip.If(t, testEnv.DaemonInfo.OSType != "linux") + skip.If(t, testEnv.IsRemoteDaemon()) + skip.If(t, !ipvlanKernelSupport(), "Kernel doesn't support ipvlan") + + d := daemon.New(t, "", "dockerd", daemon.Config{ + Experimental: true, + }) + d.StartWithBusybox(t) + defer d.Stop(t) + + // master dummy interface 'di' notation represent 'docker ipvlan' + master := "di-dummy0" + createMasterDummy(t, master) + defer deleteInterface(t, master) + + client, err := d.NewClient() + assert.NilError(t, err) + + // create a network specifying the desired sub-interface name + _, err = client.NetworkCreate(context.Background(), "di-persist", types.NetworkCreate{ + Driver: "ipvlan", + Options: map[string]string{ + "parent": "di-dummy0.70", + }, + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "di-persist")) + // Restart docker daemon to test the config has persisted to disk + d.Restart(t) + assert.Check(t, isNetworkAvailable(client, "di-persist")) +} + +func TestDockerNetworkIpvlan(t *testing.T) { + skip.If(t, testEnv.DaemonInfo.OSType != "linux") + skip.If(t, testEnv.IsRemoteDaemon()) + skip.If(t, !ipvlanKernelSupport(), "Kernel doesn't support ipvlan") + + for _, tc := range []struct { + name string + test func(dclient.APIClient) func(*testing.T) + }{ + { + name: "Subinterface", + test: testIpvlanSubinterface, + }, { + name: "OverlapParent", + test: testIpvlanOverlapParent, + }, { + name: "L2NilParent", + test: testIpvlanL2NilParent, + }, { + name: "L2InternalMode", + test: testIpvlanL2InternalMode, + }, { + name: "L3NilParent", + test: testIpvlanL3NilParent, + }, { + name: "L3InternalMode", + test: testIpvlanL3InternalMode, + }, { + name: "L2MultiSubnet", + test: testIpvlanL2MultiSubnet, + }, { + name: "L3MultiSubnet", + test: testIpvlanL3MultiSubnet, + }, { + name: "Addressing", + test: testIpvlanAddressing, + }, + } { + d := daemon.New(t, "", "dockerd", daemon.Config{ + Experimental: true, + }) + d.StartWithBusybox(t) + + client, err := d.NewClient() + assert.NilError(t, err) + + t.Run(tc.name, tc.test(client)) + + d.Stop(t) + // FIXME(vdemeester) clean network + } +} + +func testIpvlanSubinterface(client dclient.APIClient) func(*testing.T) { + return func(t *testing.T) { + master := "di-dummy0" + createMasterDummy(t, master) + defer deleteInterface(t, master) + + _, err := client.NetworkCreate(context.Background(), "di-subinterface", types.NetworkCreate{ + Driver: "ipvlan", + Options: map[string]string{ + "parent": "di-dummy0.60", + }, + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "di-subinterface")) + + // delete the network while preserving the parent link + err = client.NetworkRemove(context.Background(), "di-subinterface") + assert.NilError(t, err) + + assert.Check(t, isNetworkNotAvailable(client, "di-subinterface")) + // verify the network delete did not delete the predefined link + linkExists(t, "di-dummy0") + } +} + +func testIpvlanOverlapParent(client dclient.APIClient) func(*testing.T) { + return func(t *testing.T) { + // verify the same parent interface cannot be used if already in use by an existing network + master := "di-dummy0" + createMasterDummy(t, master) + defer deleteInterface(t, master) + createVlanInterface(t, master, "di-dummy0.30", "30") + + _, err := client.NetworkCreate(context.Background(), "di-subinterface", types.NetworkCreate{ + Driver: "ipvlan", + Options: map[string]string{ + "parent": "di-dummy0.30", + }, + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "di-subinterface")) + + _, err = client.NetworkCreate(context.Background(), "di-subinterface", types.NetworkCreate{ + Driver: "ipvlan", + Options: map[string]string{ + "parent": "di-dummy0.30", + }, + }) + // verify that the overlap returns an error + assert.Check(t, err != nil) + } +} + +func testIpvlanL2NilParent(client dclient.APIClient) func(*testing.T) { + return func(t *testing.T) { + // ipvlan l2 mode - dummy parent interface is provisioned dynamically + _, err := client.NetworkCreate(context.Background(), "di-nil-parent", types.NetworkCreate{ + Driver: "ipvlan", + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "di-nil-parent")) + + ctx := context.Background() + id1 := container.Run(t, ctx, client, container.WithNetworkMode("di-nil-parent")) + id2 := container.Run(t, ctx, client, container.WithNetworkMode("di-nil-parent")) + + t.Log(time.Now()) + + _, err = container.Exec(ctx, client, id2, []string{"ping", "-c", "1", id1}) + assert.NilError(t, err) + t.Log(time.Now()) + } +} + +func testIpvlanL2InternalMode(client dclient.APIClient) func(*testing.T) { + return func(t *testing.T) { + _, err := client.NetworkCreate(context.Background(), "di-internal", types.NetworkCreate{ + Driver: "ipvlan", + Internal: true, + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "di-internal")) + + ctx := context.Background() + id1 := container.Run(t, ctx, client, container.WithNetworkMode("di-internal")) + id2 := container.Run(t, ctx, client, container.WithNetworkMode("di-internal")) + + timeoutCtx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + _, err = container.Exec(timeoutCtx, client, id1, []string{"ping", "-c", "1", "-w", "1", "8.8.8.8"}) + // FIXME(vdemeester) check the time of error ? + assert.Check(t, err != nil) + assert.Check(t, timeoutCtx.Err() == context.DeadlineExceeded) + + _, err = container.Exec(ctx, client, id2, []string{"ping", "-c", "1", id1}) + assert.NilError(t, err) + } +} + +func testIpvlanL3NilParent(client dclient.APIClient) func(*testing.T) { + return func(t *testing.T) { + _, err := client.NetworkCreate(context.Background(), "di-nil-parent-l3", types.NetworkCreate{ + Driver: "ipvlan", + Options: map[string]string{ + "ipvlan_mode": "l3", + }, + IPAM: &network.IPAM{ + Config: []network.IPAMConfig{ + { + Subnet: "172.28.230.0/24", + AuxAddress: map[string]string{}, + }, + { + Subnet: "172.28.220.0/24", + AuxAddress: map[string]string{}, + }, + }, + }, + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "di-nil-parent-l3")) + + ctx := context.Background() + id1 := container.Run(t, ctx, client, + container.WithNetworkMode("di-nil-parent-l3"), + container.WithIPv4("di-nil-parent-l3", "172.28.220.10"), + ) + id2 := container.Run(t, ctx, client, + container.WithNetworkMode("di-nil-parent-l3"), + container.WithIPv4("di-nil-parent-l3", "172.28.230.10"), + ) + + _, err = container.Exec(ctx, client, id2, []string{"ping", "-c", "1", id1}) + assert.NilError(t, err) + } +} + +func testIpvlanL3InternalMode(client dclient.APIClient) func(*testing.T) { + return func(t *testing.T) { + _, err := client.NetworkCreate(context.Background(), "di-internal-l3", types.NetworkCreate{ + Driver: "ipvlan", + Internal: true, + Options: map[string]string{ + "ipvlan_mode": "l3", + }, + IPAM: &network.IPAM{ + Config: []network.IPAMConfig{ + { + Subnet: "172.28.230.0/24", + AuxAddress: map[string]string{}, + }, + { + Subnet: "172.28.220.0/24", + AuxAddress: map[string]string{}, + }, + }, + }, + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "di-internal-l3")) + + ctx := context.Background() + id1 := container.Run(t, ctx, client, + container.WithNetworkMode("di-internal-l3"), + container.WithIPv4("di-internal-l3", "172.28.220.10"), + ) + id2 := container.Run(t, ctx, client, + container.WithNetworkMode("di-internal-l3"), + container.WithIPv4("di-internal-l3", "172.28.230.10"), + ) + + timeoutCtx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + _, err = container.Exec(timeoutCtx, client, id1, []string{"ping", "-c", "1", "-w", "1", "8.8.8.8"}) + // FIXME(vdemeester) check the time of error ? + assert.Check(t, err != nil) + assert.Check(t, timeoutCtx.Err() == context.DeadlineExceeded) + + _, err = container.Exec(ctx, client, id2, []string{"ping", "-c", "1", id1}) + assert.NilError(t, err) + } +} + +func testIpvlanL2MultiSubnet(client dclient.APIClient) func(*testing.T) { + return func(t *testing.T) { + _, err := client.NetworkCreate(context.Background(), "dualstackl2", types.NetworkCreate{ + Driver: "ipvlan", + EnableIPv6: true, + IPAM: &network.IPAM{ + Config: []network.IPAMConfig{ + { + Subnet: "172.28.200.0/24", + AuxAddress: map[string]string{}, + }, + { + Subnet: "172.28.202.0/24", + Gateway: "172.28.202.254", + AuxAddress: map[string]string{}, + }, + { + Subnet: "2001:db8:abc8::/64", + AuxAddress: map[string]string{}, + }, + { + Subnet: "2001:db8:abc6::/64", + Gateway: "2001:db8:abc6::254", + AuxAddress: map[string]string{}, + }, + }, + }, + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "dualstackl2")) + + // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.100.0/24 and 2001:db8:abc2::/64 + ctx := context.Background() + id1 := container.Run(t, ctx, client, + container.WithNetworkMode("dualstackl2"), + container.WithIPv4("dualstackl2", "172.28.200.20"), + container.WithIPv6("dualstackl2", "2001:db8:abc8::20"), + ) + id2 := container.Run(t, ctx, client, + container.WithNetworkMode("dualstackl2"), + container.WithIPv4("dualstackl2", "172.28.200.21"), + container.WithIPv6("dualstackl2", "2001:db8:abc8::21"), + ) + c1, err := client.ContainerInspect(ctx, id1) + assert.NilError(t, err) + + // verify ipv4 connectivity to the explicit --ipv address second to first + _, err = container.Exec(ctx, client, id2, []string{"ping", "-c", "1", c1.NetworkSettings.Networks["dualstackl2"].IPAddress}) + assert.NilError(t, err) + // verify ipv6 connectivity to the explicit --ipv6 address second to first + _, err = container.Exec(ctx, client, id2, []string{"ping6", "-c", "1", c1.NetworkSettings.Networks["dualstackl2"].GlobalIPv6Address}) + assert.NilError(t, err) + + // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.102.0/24 and 2001:db8:abc4::/64 + id3 := container.Run(t, ctx, client, + container.WithNetworkMode("dualstackl2"), + container.WithIPv4("dualstackl2", "172.28.202.20"), + container.WithIPv6("dualstackl2", "2001:db8:abc6::20"), + ) + id4 := container.Run(t, ctx, client, + container.WithNetworkMode("dualstackl2"), + container.WithIPv4("dualstackl2", "172.28.202.21"), + container.WithIPv6("dualstackl2", "2001:db8:abc6::21"), + ) + c3, err := client.ContainerInspect(ctx, id3) + assert.NilError(t, err) + + // verify ipv4 connectivity to the explicit --ipv address from third to fourth + _, err = container.Exec(ctx, client, id4, []string{"ping", "-c", "1", c3.NetworkSettings.Networks["dualstackl2"].IPAddress}) + assert.NilError(t, err) + // verify ipv6 connectivity to the explicit --ipv6 address from third to fourth + _, err = container.Exec(ctx, client, id4, []string{"ping6", "-c", "1", c3.NetworkSettings.Networks["dualstackl2"].GlobalIPv6Address}) + assert.NilError(t, err) + + // Inspect the v4 gateway to ensure the proper default GW was assigned + assert.Equal(t, c1.NetworkSettings.Networks["dualstackl2"].Gateway, "172.28.200.1") + // Inspect the v6 gateway to ensure the proper default GW was assigned + assert.Equal(t, c1.NetworkSettings.Networks["dualstackl2"].IPv6Gateway, "2001:db8:abc8::1") + // Inspect the v4 gateway to ensure the proper explicitly assigned default GW was assigned + assert.Equal(t, c3.NetworkSettings.Networks["dualstackl2"].Gateway, "172.28.202.254") + // Inspect the v6 gateway to ensure the proper explicitly assigned default GW was assigned + assert.Equal(t, c3.NetworkSettings.Networks["dualstackl2"].IPv6Gateway, "2001:db8:abc6::254") + } +} + +func testIpvlanL3MultiSubnet(client dclient.APIClient) func(*testing.T) { + return func(t *testing.T) { + _, err := client.NetworkCreate(context.Background(), "dualstackl3", types.NetworkCreate{ + Driver: "ipvlan", + EnableIPv6: true, + Options: map[string]string{ + "ipvlan_mode": "l3", + }, + IPAM: &network.IPAM{ + Config: []network.IPAMConfig{ + { + Subnet: "172.28.10.0/24", + AuxAddress: map[string]string{}, + }, + { + Subnet: "172.28.12.0/24", + Gateway: "172.28.12.254", + AuxAddress: map[string]string{}, + }, + { + Subnet: "2001:db8:abc9::/64", + AuxAddress: map[string]string{}, + }, + { + Subnet: "2001:db8:abc7::/64", + Gateway: "2001:db8:abc7::254", + AuxAddress: map[string]string{}, + }, + }, + }, + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "dualstackl3")) + + // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.100.0/24 and 2001:db8:abc2::/64 + ctx := context.Background() + id1 := container.Run(t, ctx, client, + container.WithNetworkMode("dualstackl3"), + container.WithIPv4("dualstackl3", "172.28.10.20"), + container.WithIPv6("dualstackl3", "2001:db8:abc9::20"), + ) + id2 := container.Run(t, ctx, client, + container.WithNetworkMode("dualstackl3"), + container.WithIPv4("dualstackl3", "172.28.10.21"), + container.WithIPv6("dualstackl3", "2001:db8:abc9::21"), + ) + c1, err := client.ContainerInspect(ctx, id1) + assert.NilError(t, err) + + // verify ipv4 connectivity to the explicit --ipv address second to first + _, err = container.Exec(ctx, client, id2, []string{"ping", "-c", "1", c1.NetworkSettings.Networks["dualstackl3"].IPAddress}) + assert.NilError(t, err) + // verify ipv6 connectivity to the explicit --ipv6 address second to first + _, err = container.Exec(ctx, client, id2, []string{"ping6", "-c", "1", c1.NetworkSettings.Networks["dualstackl3"].GlobalIPv6Address}) + assert.NilError(t, err) + + // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.102.0/24 and 2001:db8:abc4::/64 + id3 := container.Run(t, ctx, client, + container.WithNetworkMode("dualstackl3"), + container.WithIPv4("dualstackl3", "172.28.12.20"), + container.WithIPv6("dualstackl3", "2001:db8:abc7::20"), + ) + id4 := container.Run(t, ctx, client, + container.WithNetworkMode("dualstackl3"), + container.WithIPv4("dualstackl3", "172.28.12.21"), + container.WithIPv6("dualstackl3", "2001:db8:abc7::21"), + ) + c3, err := client.ContainerInspect(ctx, id3) + assert.NilError(t, err) + + // verify ipv4 connectivity to the explicit --ipv address from third to fourth + _, err = container.Exec(ctx, client, id4, []string{"ping", "-c", "1", c3.NetworkSettings.Networks["dualstackl3"].IPAddress}) + assert.NilError(t, err) + // verify ipv6 connectivity to the explicit --ipv6 address from third to fourth + _, err = container.Exec(ctx, client, id4, []string{"ping6", "-c", "1", c3.NetworkSettings.Networks["dualstackl3"].GlobalIPv6Address}) + assert.NilError(t, err) + + // Inspect the v4 gateway to ensure no next hop is assigned in L3 mode + assert.Equal(t, c1.NetworkSettings.Networks["dualstackl3"].Gateway, "") + // Inspect the v6 gateway to ensure the explicitly specified default GW is ignored per L3 mode enabled + assert.Equal(t, c1.NetworkSettings.Networks["dualstackl3"].IPv6Gateway, "") + // Inspect the v4 gateway to ensure no next hop is assigned in L3 mode + assert.Equal(t, c3.NetworkSettings.Networks["dualstackl3"].Gateway, "") + // Inspect the v6 gateway to ensure the explicitly specified default GW is ignored per L3 mode enabled + assert.Equal(t, c3.NetworkSettings.Networks["dualstackl3"].IPv6Gateway, "") + } +} + +func testIpvlanAddressing(client dclient.APIClient) func(*testing.T) { + return func(t *testing.T) { + // Verify ipvlan l2 mode sets the proper default gateway routes via netlink + // for either an explicitly set route by the user or inferred via default IPAM + _, err := client.NetworkCreate(context.Background(), "dualstackl2", types.NetworkCreate{ + Driver: "ipvlan", + EnableIPv6: true, + Options: map[string]string{ + "ipvlan_mode": "l2", + }, + IPAM: &network.IPAM{ + Config: []network.IPAMConfig{ + { + Subnet: "172.28.140.0/24", + Gateway: "172.28.140.254", + AuxAddress: map[string]string{}, + }, + { + Subnet: "2001:db8:abcb::/64", + AuxAddress: map[string]string{}, + }, + }, + }, + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "dualstackl2")) + + ctx := context.Background() + id1 := container.Run(t, ctx, client, + container.WithNetworkMode("dualstackl2"), + ) + // Validate ipvlan l2 mode defaults gateway sets the default IPAM next-hop inferred from the subnet + result, err := container.Exec(ctx, client, id1, []string{"ip", "route"}) + assert.NilError(t, err) + assert.Check(t, strings.Contains(result.Combined(), "default via 172.28.140.254 dev eth0")) + // Validate ipvlan l2 mode sets the v6 gateway to the user specified default gateway/next-hop + result, err = container.Exec(ctx, client, id1, []string{"ip", "-6", "route"}) + assert.NilError(t, err) + assert.Check(t, strings.Contains(result.Combined(), "default via 2001:db8:abcb::1 dev eth0")) + + // Validate ipvlan l3 mode sets the v4 gateway to dev eth0 and disregards any explicit or inferred next-hops + _, err = client.NetworkCreate(context.Background(), "dualstackl3", types.NetworkCreate{ + Driver: "ipvlan", + EnableIPv6: true, + Options: map[string]string{ + "ipvlan_mode": "l3", + }, + IPAM: &network.IPAM{ + Config: []network.IPAMConfig{ + { + Subnet: "172.28.160.0/24", + Gateway: "172.28.160.254", + AuxAddress: map[string]string{}, + }, + { + Subnet: "2001:db8:abcd::/64", + Gateway: "2001:db8:abcd::254", + AuxAddress: map[string]string{}, + }, + }, + }, + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "dualstackl3")) + + id2 := container.Run(t, ctx, client, + container.WithNetworkMode("dualstackl3"), + ) + // Validate ipvlan l3 mode sets the v4 gateway to dev eth0 and disregards any explicit or inferred next-hops + result, err = container.Exec(ctx, client, id2, []string{"ip", "route"}) + assert.NilError(t, err) + assert.Check(t, strings.Contains(result.Combined(), "default dev eth0")) + // Validate ipvlan l3 mode sets the v6 gateway to dev eth0 and disregards any explicit or inferred next-hops + result, err = container.Exec(ctx, client, id2, []string{"ip", "-6", "route"}) + assert.NilError(t, err) + assert.Check(t, strings.Contains(result.Combined(), "default dev eth0")) + } +} + +// ensure Kernel version is >= v4.2 for ipvlan support +func ipvlanKernelSupport() bool { + return checkKernelMajorVersionGreaterOrEqualThen(4, 2) +} diff --git a/components/engine/integration/network/macvlan_test.go b/components/engine/integration/network/macvlan_test.go index 146f67ee572..727c2ef3813 100644 --- a/components/engine/integration/network/macvlan_test.go +++ b/components/engine/integration/network/macvlan_test.go @@ -3,6 +3,7 @@ package network import ( "context" "fmt" + "strings" "testing" "time" @@ -163,6 +164,8 @@ func TestDockerNetworkMacvlanBridgeInternal(t *testing.T) { client, err := d.NewClient() assert.NilError(t, err) + t.Log(icmd.RunCommand("ip", "addr").Combined()) + _, err = client.NetworkCreate(context.Background(), "dm-internal", types.NetworkCreate{ Driver: "macvlan", Internal: true, @@ -189,7 +192,7 @@ func TestDockerNetworkMacvlanMultiSubnet(t *testing.T) { skip.If(t, testEnv.DaemonInfo.OSType != "linux") skip.If(t, testEnv.IsRemoteDaemon()) skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") - t.Skip("Temporarily skipping while investigating sporadic v6 CI issues") + // t.Skip("Temporarily skipping while investigating sporadic v6 CI issues") d := daemon.New(t) d.StartWithBusybox(t) @@ -283,6 +286,56 @@ func TestDockerNetworkMacvlanMultiSubnet(t *testing.T) { assert.Equal(t, c3.NetworkSettings.Networks["dualstackbridge"].IPv6Gateway, "2001:db8.abc4::254") } +func TestDockerNetworkMacvlanAddressing(t *testing.T) { + // Ensure the default gateways, next-hops and default dev devices are properly set + skip.If(t, testEnv.DaemonInfo.OSType != "linux") + skip.If(t, testEnv.IsRemoteDaemon()) + skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") + + d := daemon.New(t, "", "dockerd", daemon.Config{}) + d.StartWithBusybox(t) + defer d.Stop(t) + client, err := d.NewClient() + assert.NilError(t, err) + _, err = client.NetworkCreate(context.Background(), "dualstackbridge", types.NetworkCreate{ + Driver: "macvlan", + EnableIPv6: true, + Options: map[string]string{ + "macvlan_mode": "bridge", + }, + IPAM: &network.IPAM{ + Config: []network.IPAMConfig{ + { + Subnet: "172.28.130.0/24", + AuxAddress: map[string]string{}, + }, + { + Subnet: "2001:db8:abca::/64", + Gateway: "2001:db8:abca::254", + AuxAddress: map[string]string{}, + }, + }, + }, + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "dualstackbridge")) + + ctx := context.Background() + id1 := container.Run(t, ctx, client, + container.WithNetworkMode("dualstackbridge"), + container.WithName(t.Name()+"first"), + ) + + // Validate macvlan bridge mode defaults gateway sets the default IPAM next-hop inferred from the subnet + result, err := container.Exec(ctx, client, id1, []string{"ip", "route"}) + assert.NilError(t, err) + assert.Check(t, strings.Contains(result.Combined(), "default via 172.28.130.1 dev eth0")) + // Validate macvlan bridge mode sets the v6 gateway to the user specified default gateway/next-hop + result, err = container.Exec(ctx, client, id1, []string{"ip", "-6", "route"}) + assert.NilError(t, err) + assert.Check(t, strings.Contains(result.Combined(), "default via 2001:db8:abca::254 dev eth0")) +} + func isNetworkAvailable(c client.NetworkAPIClient, name string) cmp.Comparison { return func() cmp.Result { networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{}) From 997850a2f23e8a388522871e03f65aaa19ed210d Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Wed, 11 Apr 2018 11:14:54 +0200 Subject: [PATCH 25/36] Refactor macvlan tests a bit Signed-off-by: Vincent Demeester (cherry picked from commit 0ab6116ce868a0fc671a49a89696e3a1ce35e26d) Signed-off-by: Sebastiaan van Stijn --- .../integration/network/macvlan_test.go | 507 +++++++++--------- 1 file changed, 245 insertions(+), 262 deletions(-) diff --git a/components/engine/integration/network/macvlan_test.go b/components/engine/integration/network/macvlan_test.go index 727c2ef3813..31848bca99d 100644 --- a/components/engine/integration/network/macvlan_test.go +++ b/components/engine/integration/network/macvlan_test.go @@ -48,292 +48,275 @@ func TestDockerNetworkMacvlanPersistance(t *testing.T) { assert.Check(t, isNetworkAvailable(client, "dm-persist")) } -func TestDockerNetworkMacvlanOverlapParent(t *testing.T) { - // verify the same parent interface cannot be used if already in use by an existing network +func TestDockerNetworkMacvlan(t *testing.T) { skip.If(t, testEnv.DaemonInfo.OSType != "linux") skip.If(t, testEnv.IsRemoteDaemon()) skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") - d := daemon.New(t) - d.StartWithBusybox(t) - defer d.Stop(t) - - master := "dm-dummy0" - createMasterDummy(t, master) - defer deleteInterface(t, master) - - client, err := d.NewClient() - assert.NilError(t, err) - - _, err = client.NetworkCreate(context.Background(), "dm-subinterface", types.NetworkCreate{ - Driver: "macvlan", - Options: map[string]string{ - "parent": "dm-dummy0.40", - }, - }) - assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dm-subinterface")) - - _, err = client.NetworkCreate(context.Background(), "dm-parent-net-overlap", types.NetworkCreate{ - Driver: "macvlan", - Options: map[string]string{ - "parent": "dm-dummy0.40", + for _, tc := range []struct { + name string + test func(client.APIClient) func(*testing.T) + }{ + { + name: "Subinterface", + test: testMacvlanSubinterface, + }, { + name: "OverlapParent", + test: testMacvlanOverlapParent, + }, { + name: "NilParent", + test: testMacvlanNilParent, + }, { + name: "InternalMode", + test: testMacvlanInternalMode, + }, { + name: "Addressing", + test: testMacvlanAddressing, }, - }) - assert.Check(t, err != nil) - // delete the network while preserving the parent link - err = client.NetworkRemove(context.Background(), "dm-subinterface") - assert.NilError(t, err) - - assert.Check(t, isNetworkNotAvailable(client, "dm-subinterface")) - // verify the network delete did not delete the predefined link - linkExists(t, "dm-dummy0") -} - -func TestDockerNetworkMacvlanSubinterface(t *testing.T) { - // verify the same parent interface cannot be used if already in use by an existing network - skip.If(t, testEnv.DaemonInfo.OSType != "linux") - skip.If(t, testEnv.IsRemoteDaemon()) - skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") - - d := daemon.New(t) - d.StartWithBusybox(t) - defer d.Stop(t) - - master := "dm-dummy0" - createMasterDummy(t, master) - defer deleteInterface(t, master) - createVlanInterface(t, master, "dm-dummy0.20", "20") - - client, err := d.NewClient() - assert.NilError(t, err) + } { + d := daemon.New(t) + d.StartWithBusybox(t) - _, err = client.NetworkCreate(context.Background(), "dm-subinterface", types.NetworkCreate{ - Driver: "macvlan", - Options: map[string]string{ - "parent": "dm-dummy0.20", - }, - }) - assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dm-subinterface")) + client, err := d.NewClient() + assert.NilError(t, err) - // delete the network while preserving the parent link - err = client.NetworkRemove(context.Background(), "dm-subinterface") - assert.NilError(t, err) + t.Run(tc.name, tc.test(client)) - assert.Check(t, isNetworkNotAvailable(client, "dm-subinterface")) - // verify the network delete did not delete the predefined link - linkExists(t, "dm-dummy0.20") + d.Stop(t) + // FIXME(vdemeester) clean network + } } -func TestDockerNetworkMacvlanBridgeNilParent(t *testing.T) { - // macvlan bridge mode - dummy parent interface is provisioned dynamically - skip.If(t, testEnv.DaemonInfo.OSType != "linux") - skip.If(t, testEnv.IsRemoteDaemon()) - skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") - - d := daemon.New(t) - d.StartWithBusybox(t) - defer d.Stop(t) - client, err := d.NewClient() - assert.NilError(t, err) - - _, err = client.NetworkCreate(context.Background(), "dm-nil-parent", types.NetworkCreate{ - Driver: "macvlan", - }) - assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dm-nil-parent")) - - ctx := context.Background() - container.Run(t, ctx, client, container.WithNetworkMode("dm-nil-parent"), container.WithName(t.Name()+"first")) - id2 := container.Run(t, ctx, client, container.WithNetworkMode("dm-nil-parent"), container.WithName(t.Name()+"second")) - - _, err = container.Exec(ctx, client, id2, []string{"ping", "-c", "1", t.Name() + "first"}) - assert.Check(t, err == nil) +func testMacvlanOverlapParent(client client.APIClient) func(*testing.T) { + return func(t *testing.T) { + // verify the same parent interface cannot be used if already in use by an existing network + master := "dm-dummy0" + createMasterDummy(t, master) + defer deleteInterface(t, master) + + _, err := client.NetworkCreate(context.Background(), "dm-subinterface", types.NetworkCreate{ + Driver: "macvlan", + Options: map[string]string{ + "parent": "dm-dummy0.40", + }, + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "dm-subinterface")) + + _, err = client.NetworkCreate(context.Background(), "dm-parent-net-overlap", types.NetworkCreate{ + Driver: "macvlan", + Options: map[string]string{ + "parent": "dm-dummy0.40", + }, + }) + assert.Check(t, err != nil) + // delete the network while preserving the parent link + err = client.NetworkRemove(context.Background(), "dm-subinterface") + assert.NilError(t, err) + + assert.Check(t, isNetworkNotAvailable(client, "dm-subinterface")) + // verify the network delete did not delete the predefined link + linkExists(t, "dm-dummy0") + } } -func TestDockerNetworkMacvlanBridgeInternal(t *testing.T) { - // macvlan bridge mode - dummy parent interface is provisioned dynamically - skip.If(t, testEnv.DaemonInfo.OSType != "linux") - skip.If(t, testEnv.IsRemoteDaemon()) - skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") - - d := daemon.New(t) - d.StartWithBusybox(t) - defer d.Stop(t) - client, err := d.NewClient() - assert.NilError(t, err) - - t.Log(icmd.RunCommand("ip", "addr").Combined()) - - _, err = client.NetworkCreate(context.Background(), "dm-internal", types.NetworkCreate{ - Driver: "macvlan", - Internal: true, - }) - assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dm-internal")) - - ctx := context.Background() - id1 := container.Run(t, ctx, client, container.WithNetworkMode("dm-internal"), container.WithName(t.Name()+"first")) - id2 := container.Run(t, ctx, client, container.WithNetworkMode("dm-internal"), container.WithName(t.Name()+"second")) +func testMacvlanSubinterface(client client.APIClient) func(*testing.T) { + return func(t *testing.T) { + // verify the same parent interface cannot be used if already in use by an existing network + master := "dm-dummy0" + createMasterDummy(t, master) + defer deleteInterface(t, master) + createVlanInterface(t, master, "dm-dummy0.20", "20") + + _, err := client.NetworkCreate(context.Background(), "dm-subinterface", types.NetworkCreate{ + Driver: "macvlan", + Options: map[string]string{ + "parent": "dm-dummy0.20", + }, + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "dm-subinterface")) - timeoutCtx, cancel := context.WithTimeout(context.Background(), 1*time.Second) - defer cancel() - _, err = container.Exec(timeoutCtx, client, id1, []string{"ping", "-c", "1", "-w", "1", "8.8.8.8"}) - // FIXME(vdemeester) check the time of error ? - assert.Check(t, err != nil) - assert.Check(t, timeoutCtx.Err() == context.DeadlineExceeded) + // delete the network while preserving the parent link + err = client.NetworkRemove(context.Background(), "dm-subinterface") + assert.NilError(t, err) - _, err = container.Exec(ctx, client, id2, []string{"ping", "-c", "1", t.Name() + "first"}) - assert.Check(t, err == nil) + assert.Check(t, isNetworkNotAvailable(client, "dm-subinterface")) + // verify the network delete did not delete the predefined link + linkExists(t, "dm-dummy0.20") + } } -func TestDockerNetworkMacvlanMultiSubnet(t *testing.T) { - skip.If(t, testEnv.DaemonInfo.OSType != "linux") - skip.If(t, testEnv.IsRemoteDaemon()) - skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") - // t.Skip("Temporarily skipping while investigating sporadic v6 CI issues") +func testMacvlanNilParent(client client.APIClient) func(*testing.T) { + return func(t *testing.T) { + // macvlan bridge mode - dummy parent interface is provisioned dynamically + _, err := client.NetworkCreate(context.Background(), "dm-nil-parent", types.NetworkCreate{ + Driver: "macvlan", + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "dm-nil-parent")) + + ctx := context.Background() + id1 := container.Run(t, ctx, client, container.WithNetworkMode("dm-nil-parent")) + id2 := container.Run(t, ctx, client, container.WithNetworkMode("dm-nil-parent")) + + _, err = container.Exec(ctx, client, id2, []string{"ping", "-c", "1", id1}) + assert.Check(t, err == nil) + } +} - d := daemon.New(t) - d.StartWithBusybox(t) - defer d.Stop(t) - client, err := d.NewClient() - assert.NilError(t, err) +func testMacvlanInternalMode(client client.APIClient) func(*testing.T) { + return func(t *testing.T) { + // macvlan bridge mode - dummy parent interface is provisioned dynamically + _, err := client.NetworkCreate(context.Background(), "dm-internal", types.NetworkCreate{ + Driver: "macvlan", + Internal: true, + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "dm-internal")) + + ctx := context.Background() + id1 := container.Run(t, ctx, client, container.WithNetworkMode("dm-internal")) + id2 := container.Run(t, ctx, client, container.WithNetworkMode("dm-internal")) + + timeoutCtx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + _, err = container.Exec(timeoutCtx, client, id1, []string{"ping", "-c", "1", "-w", "1", "8.8.8.8"}) + // FIXME(vdemeester) check the time of error ? + assert.Check(t, err != nil) + assert.Check(t, timeoutCtx.Err() == context.DeadlineExceeded) + + _, err = container.Exec(ctx, client, id2, []string{"ping", "-c", "1", id1}) + assert.Check(t, err == nil) + } +} - _, err = client.NetworkCreate(context.Background(), "dualstackbridge", types.NetworkCreate{ - Driver: "macvlan", - EnableIPv6: true, - IPAM: &network.IPAM{ - Config: []network.IPAMConfig{ - { - Subnet: "172.28.100.0/24", - AuxAddress: map[string]string{}, - }, - { - Subnet: "172.28.102.0/24", - Gateway: "172.28.102.54", - AuxAddress: map[string]string{}, - }, - { - Subnet: "2001:db8:abc2::/64", - AuxAddress: map[string]string{}, - }, - { - Subnet: "2001:db8:abc4::/64", - Gateway: "2001:db8:abc4::254", - AuxAddress: map[string]string{}, +func testMacvlanMultiSubnet(client client.APIClient) func(*testing.T) { + return func(t *testing.T) { + // t.Skip("Temporarily skipping while investigating sporadic v6 CI issues") + _, err := client.NetworkCreate(context.Background(), "dualstackbridge", types.NetworkCreate{ + Driver: "macvlan", + EnableIPv6: true, + IPAM: &network.IPAM{ + Config: []network.IPAMConfig{ + { + Subnet: "172.28.100.0/24", + AuxAddress: map[string]string{}, + }, + { + Subnet: "172.28.102.0/24", + Gateway: "172.28.102.254", + AuxAddress: map[string]string{}, + }, + { + Subnet: "2001:db8:abc2::/64", + AuxAddress: map[string]string{}, + }, + { + Subnet: "2001:db8:abc4::/64", + Gateway: "2001:db8:abc4::254", + AuxAddress: map[string]string{}, + }, }, }, - }, - }) - assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dualstackbridge")) - - // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.100.0/24 and 2001:db8:abc2::/64 - ctx := context.Background() - id1 := container.Run(t, ctx, client, - container.WithNetworkMode("dualstackbridge"), - container.WithName(t.Name()+"first"), - container.WithIPv4("dualstackbridge", "172.28.100.20"), - container.WithIPv6("dualstackbridge", "2001:db8:abc2::20"), - ) - id2 := container.Run(t, ctx, client, - container.WithNetworkMode("dualstackbridge"), - container.WithName(t.Name()+"second"), - container.WithIPv4("dualstackbridge", "172.28.100.21"), - container.WithIPv6("dualstackbridge", "2001:db8:abc2::21"), - ) - c1, err := client.ContainerInspect(ctx, id1) - assert.NilError(t, err) - - // verify ipv4 connectivity to the explicit --ipv address second to first - _, err = container.Exec(ctx, client, id2, []string{"ping", "-c", "1", c1.NetworkSettings.Networks["dualstackbridge"].IPAddress}) - assert.NilError(t, err) - // verify ipv6 connectivity to the explicit --ipv6 address second to first - _, err = container.Exec(ctx, client, id2, []string{"ping6", "-c", "1", c1.NetworkSettings.Networks["dualstackbridge"].GlobalIPv6Address}) - assert.NilError(t, err) - - // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.102.0/24 and 2001:db8:abc4::/64 - id3 := container.Run(t, ctx, client, - container.WithNetworkMode("dualstackbridge"), - container.WithName(t.Name()+"third"), - container.WithIPv4("dualstackbridge", "172.28.102.20"), - container.WithIPv6("dualstackbridge", "2001:db8:abc4::20"), - ) - id4 := container.Run(t, ctx, client, - container.WithNetworkMode("dualstackbridge"), - container.WithName(t.Name()+"fourth"), - container.WithIPv4("dualstackbridge", "172.28.102.21"), - container.WithIPv6("dualstackbridge", "2001:db8:abc4::21"), - ) - c3, err := client.ContainerInspect(ctx, id3) - assert.NilError(t, err) - - // verify ipv4 connectivity to the explicit --ipv address from third to fourth - _, err = container.Exec(ctx, client, id4, []string{"ping", "-c", "1", c3.NetworkSettings.Networks["dualstackbridge"].IPAddress}) - assert.NilError(t, err) - // verify ipv6 connectivity to the explicit --ipv6 address from third to fourth - _, err = container.Exec(ctx, client, id4, []string{"ping6", "-c", "1", c3.NetworkSettings.Networks["dualstackbridge"].GlobalIPv6Address}) - assert.NilError(t, err) - - // Inspect the v4 gateway to ensure the proper default GW was assigned - assert.Equal(t, c1.NetworkSettings.Networks["dualstackbridge"].Gateway, "172.28.100.1") - // Inspect the v6 gateway to ensure the proper default GW was assigned - assert.Equal(t, c1.NetworkSettings.Networks["dualstackbridge"].IPv6Gateway, "2001:db8:abc2::1") - // Inspect the v4 gateway to ensure the proper explicitly assigned default GW was assigned - assert.Equal(t, c3.NetworkSettings.Networks["dualstackbridge"].Gateway, "172.28.102.254") - // Inspect the v6 gateway to ensure the proper explicitly assigned default GW was assigned - assert.Equal(t, c3.NetworkSettings.Networks["dualstackbridge"].IPv6Gateway, "2001:db8.abc4::254") + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "dualstackbridge")) + + // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.100.0/24 and 2001:db8:abc2::/64 + ctx := context.Background() + id1 := container.Run(t, ctx, client, + container.WithNetworkMode("dualstackbridge"), + container.WithIPv4("dualstackbridge", "172.28.100.20"), + container.WithIPv6("dualstackbridge", "2001:db8:abc2::20"), + ) + id2 := container.Run(t, ctx, client, + container.WithNetworkMode("dualstackbridge"), + container.WithIPv4("dualstackbridge", "172.28.100.21"), + container.WithIPv6("dualstackbridge", "2001:db8:abc2::21"), + ) + c1, err := client.ContainerInspect(ctx, id1) + assert.NilError(t, err) + + // verify ipv4 connectivity to the explicit --ipv address second to first + _, err = container.Exec(ctx, client, id2, []string{"ping", "-c", "1", c1.NetworkSettings.Networks["dualstackbridge"].IPAddress}) + assert.NilError(t, err) + // verify ipv6 connectivity to the explicit --ipv6 address second to first + _, err = container.Exec(ctx, client, id2, []string{"ping6", "-c", "1", c1.NetworkSettings.Networks["dualstackbridge"].GlobalIPv6Address}) + assert.NilError(t, err) + + // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.102.0/24 and 2001:db8:abc4::/64 + id3 := container.Run(t, ctx, client, + container.WithNetworkMode("dualstackbridge"), + container.WithIPv4("dualstackbridge", "172.28.102.20"), + container.WithIPv6("dualstackbridge", "2001:db8:abc4::20"), + ) + id4 := container.Run(t, ctx, client, + container.WithNetworkMode("dualstackbridge"), + container.WithIPv4("dualstackbridge", "172.28.102.21"), + container.WithIPv6("dualstackbridge", "2001:db8:abc4::21"), + ) + c3, err := client.ContainerInspect(ctx, id3) + assert.NilError(t, err) + + // verify ipv4 connectivity to the explicit --ipv address from third to fourth + _, err = container.Exec(ctx, client, id4, []string{"ping", "-c", "1", c3.NetworkSettings.Networks["dualstackbridge"].IPAddress}) + assert.NilError(t, err) + // verify ipv6 connectivity to the explicit --ipv6 address from third to fourth + _, err = container.Exec(ctx, client, id4, []string{"ping6", "-c", "1", c3.NetworkSettings.Networks["dualstackbridge"].GlobalIPv6Address}) + assert.NilError(t, err) + + // Inspect the v4 gateway to ensure the proper default GW was assigned + assert.Equal(t, c1.NetworkSettings.Networks["dualstackbridge"].Gateway, "172.28.100.1") + // Inspect the v6 gateway to ensure the proper default GW was assigned + assert.Equal(t, c1.NetworkSettings.Networks["dualstackbridge"].IPv6Gateway, "2001:db8:abc2::1") + // Inspect the v4 gateway to ensure the proper explicitly assigned default GW was assigned + assert.Equal(t, c3.NetworkSettings.Networks["dualstackbridge"].Gateway, "172.28.102.254") + // Inspect the v6 gateway to ensure the proper explicitly assigned default GW was assigned + assert.Equal(t, c3.NetworkSettings.Networks["dualstackbridge"].IPv6Gateway, "2001:db8.abc4::254") + } } -func TestDockerNetworkMacvlanAddressing(t *testing.T) { - // Ensure the default gateways, next-hops and default dev devices are properly set - skip.If(t, testEnv.DaemonInfo.OSType != "linux") - skip.If(t, testEnv.IsRemoteDaemon()) - skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") - - d := daemon.New(t, "", "dockerd", daemon.Config{}) - d.StartWithBusybox(t) - defer d.Stop(t) - client, err := d.NewClient() - assert.NilError(t, err) - _, err = client.NetworkCreate(context.Background(), "dualstackbridge", types.NetworkCreate{ - Driver: "macvlan", - EnableIPv6: true, - Options: map[string]string{ - "macvlan_mode": "bridge", - }, - IPAM: &network.IPAM{ - Config: []network.IPAMConfig{ - { - Subnet: "172.28.130.0/24", - AuxAddress: map[string]string{}, - }, - { - Subnet: "2001:db8:abca::/64", - Gateway: "2001:db8:abca::254", - AuxAddress: map[string]string{}, +func testMacvlanAddressing(client client.APIClient) func(*testing.T) { + return func(t *testing.T) { + // Ensure the default gateways, next-hops and default dev devices are properly set + _, err := client.NetworkCreate(context.Background(), "dualstackbridge", types.NetworkCreate{ + Driver: "macvlan", + EnableIPv6: true, + Options: map[string]string{ + "macvlan_mode": "bridge", + }, + IPAM: &network.IPAM{ + Config: []network.IPAMConfig{ + { + Subnet: "172.28.130.0/24", + AuxAddress: map[string]string{}, + }, + { + Subnet: "2001:db8:abca::/64", + Gateway: "2001:db8:abca::254", + AuxAddress: map[string]string{}, + }, }, }, - }, - }) - assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dualstackbridge")) - - ctx := context.Background() - id1 := container.Run(t, ctx, client, - container.WithNetworkMode("dualstackbridge"), - container.WithName(t.Name()+"first"), - ) - - // Validate macvlan bridge mode defaults gateway sets the default IPAM next-hop inferred from the subnet - result, err := container.Exec(ctx, client, id1, []string{"ip", "route"}) - assert.NilError(t, err) - assert.Check(t, strings.Contains(result.Combined(), "default via 172.28.130.1 dev eth0")) - // Validate macvlan bridge mode sets the v6 gateway to the user specified default gateway/next-hop - result, err = container.Exec(ctx, client, id1, []string{"ip", "-6", "route"}) - assert.NilError(t, err) - assert.Check(t, strings.Contains(result.Combined(), "default via 2001:db8:abca::254 dev eth0")) + }) + assert.NilError(t, err) + assert.Check(t, isNetworkAvailable(client, "dualstackbridge")) + + ctx := context.Background() + id1 := container.Run(t, ctx, client, + container.WithNetworkMode("dualstackbridge"), + ) + + // Validate macvlan bridge mode defaults gateway sets the default IPAM next-hop inferred from the subnet + result, err := container.Exec(ctx, client, id1, []string{"ip", "route"}) + assert.NilError(t, err) + assert.Check(t, strings.Contains(result.Combined(), "default via 172.28.130.1 dev eth0")) + // Validate macvlan bridge mode sets the v6 gateway to the user specified default gateway/next-hop + result, err = container.Exec(ctx, client, id1, []string{"ip", "-6", "route"}) + assert.NilError(t, err) + assert.Check(t, strings.Contains(result.Combined(), "default via 2001:db8:abca::254 dev eth0")) + } } func isNetworkAvailable(c client.NetworkAPIClient, name string) cmp.Comparison { From fa038125252b1b215df81ce9eccc383801315c00 Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Wed, 11 Apr 2018 11:14:58 +0200 Subject: [PATCH 26/36] =?UTF-8?q?Move=20ipvlan=20and=20macvlan=20tests=20o?= =?UTF-8?q?n=20their=20own=20folder=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … making each folder/suites quicker to run Signed-off-by: Vincent Demeester (cherry picked from commit a3323d2e4349b7e8d449c6e571ca3d4aa3e53d63) Signed-off-by: Sebastiaan van Stijn --- .../engine/integration/network/helpers.go | 85 +++++++++++++ .../network/{ => ipvlan}/ipvlan_test.go | 50 ++++---- .../integration/network/ipvlan/main_test.go | 33 +++++ .../network/{ => macvlan}/macvlan_test.go | 113 ++++-------------- .../integration/network/macvlan/main_test.go | 33 +++++ 5 files changed, 197 insertions(+), 117 deletions(-) create mode 100644 components/engine/integration/network/helpers.go rename components/engine/integration/network/{ => ipvlan}/ipvlan_test.go (93%) create mode 100644 components/engine/integration/network/ipvlan/main_test.go rename components/engine/integration/network/{ => macvlan}/macvlan_test.go (74%) create mode 100644 components/engine/integration/network/macvlan/main_test.go diff --git a/components/engine/integration/network/helpers.go b/components/engine/integration/network/helpers.go new file mode 100644 index 00000000000..df609dd4104 --- /dev/null +++ b/components/engine/integration/network/helpers.go @@ -0,0 +1,85 @@ +package network + +import ( + "context" + "fmt" + "testing" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/client" + "github.com/docker/docker/pkg/parsers/kernel" + "github.com/gotestyourself/gotestyourself/assert/cmp" + "github.com/gotestyourself/gotestyourself/icmd" +) + +// CreateMasterDummy creates a dummy network interface +func CreateMasterDummy(t *testing.T, master string) { + // ip link add type dummy + icmd.RunCommand("ip", "link", "add", master, "type", "dummy").Assert(t, icmd.Success) + icmd.RunCommand("ip", "link", "set", master, "up").Assert(t, icmd.Success) +} + +// CreateVlanInterface creates a vlan network interface +func CreateVlanInterface(t *testing.T, master, slave, id string) { + // ip link add link name . type vlan id + icmd.RunCommand("ip", "link", "add", "link", master, "name", slave, "type", "vlan", "id", id).Assert(t, icmd.Success) + // ip link set up + icmd.RunCommand("ip", "link", "set", slave, "up").Assert(t, icmd.Success) +} + +// DeleteInterface deletes a network interface +func DeleteInterface(t *testing.T, ifName string) { + icmd.RunCommand("ip", "link", "delete", ifName).Assert(t, icmd.Success) + icmd.RunCommand("iptables", "-t", "nat", "--flush").Assert(t, icmd.Success) + icmd.RunCommand("iptables", "--flush").Assert(t, icmd.Success) +} + +// LinkExists verifies that a link exists +func LinkExists(t *testing.T, master string) { + // verify the specified link exists, ip link show + icmd.RunCommand("ip", "link", "show", master).Assert(t, icmd.Success) +} + +// IsNetworkAvailable provides a comparison to check if a docker network is available +func IsNetworkAvailable(c client.NetworkAPIClient, name string) cmp.Comparison { + return func() cmp.Result { + networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{}) + if err != nil { + return cmp.ResultFromError(err) + } + for _, network := range networks { + if network.Name == name { + return cmp.ResultSuccess + } + } + return cmp.ResultFailure(fmt.Sprintf("could not find network %s", name)) + } +} + +// IsNetworkNotAvailable provides a comparison to check if a docker network is not available +func IsNetworkNotAvailable(c client.NetworkAPIClient, name string) cmp.Comparison { + return func() cmp.Result { + networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{}) + if err != nil { + return cmp.ResultFromError(err) + } + for _, network := range networks { + if network.Name == name { + return cmp.ResultFailure(fmt.Sprintf("network %s is still present", name)) + } + } + return cmp.ResultSuccess + } +} + +// CheckKernelMajorVersionGreaterOrEqualThen returns whether the kernel version is greater or equal than the one provided +func CheckKernelMajorVersionGreaterOrEqualThen(kernelVersion int, majorVersion int) bool { + kv, err := kernel.GetKernelVersion() + if err != nil { + return false + } + if kv.Kernel < kernelVersion || (kv.Kernel == kernelVersion && kv.Major < majorVersion) { + return false + } + return true +} diff --git a/components/engine/integration/network/ipvlan_test.go b/components/engine/integration/network/ipvlan/ipvlan_test.go similarity index 93% rename from components/engine/integration/network/ipvlan_test.go rename to components/engine/integration/network/ipvlan/ipvlan_test.go index a741d8b7f8e..9de78f41bb5 100644 --- a/components/engine/integration/network/ipvlan_test.go +++ b/components/engine/integration/network/ipvlan/ipvlan_test.go @@ -1,4 +1,4 @@ -package network +package ipvlan import ( "strings" @@ -10,6 +10,7 @@ import ( dclient "github.com/docker/docker/client" "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/integration/internal/container" + n "github.com/docker/docker/integration/network" "github.com/gotestyourself/gotestyourself/assert" "github.com/gotestyourself/gotestyourself/skip" "golang.org/x/net/context" @@ -29,8 +30,8 @@ func TestDockerNetworkIpvlanPersistance(t *testing.T) { // master dummy interface 'di' notation represent 'docker ipvlan' master := "di-dummy0" - createMasterDummy(t, master) - defer deleteInterface(t, master) + n.CreateMasterDummy(t, master) + defer n.DeleteInterface(t, master) client, err := d.NewClient() assert.NilError(t, err) @@ -43,10 +44,10 @@ func TestDockerNetworkIpvlanPersistance(t *testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "di-persist")) + assert.Check(t, n.IsNetworkAvailable(client, "di-persist")) // Restart docker daemon to test the config has persisted to disk d.Restart(t) - assert.Check(t, isNetworkAvailable(client, "di-persist")) + assert.Check(t, n.IsNetworkAvailable(client, "di-persist")) } func TestDockerNetworkIpvlan(t *testing.T) { @@ -105,8 +106,8 @@ func TestDockerNetworkIpvlan(t *testing.T) { func testIpvlanSubinterface(client dclient.APIClient) func(*testing.T) { return func(t *testing.T) { master := "di-dummy0" - createMasterDummy(t, master) - defer deleteInterface(t, master) + n.CreateMasterDummy(t, master) + defer n.DeleteInterface(t, master) _, err := client.NetworkCreate(context.Background(), "di-subinterface", types.NetworkCreate{ Driver: "ipvlan", @@ -115,15 +116,15 @@ func testIpvlanSubinterface(client dclient.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "di-subinterface")) + assert.Check(t, n.IsNetworkAvailable(client, "di-subinterface")) // delete the network while preserving the parent link err = client.NetworkRemove(context.Background(), "di-subinterface") assert.NilError(t, err) - assert.Check(t, isNetworkNotAvailable(client, "di-subinterface")) + assert.Check(t, n.IsNetworkNotAvailable(client, "di-subinterface")) // verify the network delete did not delete the predefined link - linkExists(t, "di-dummy0") + n.LinkExists(t, "di-dummy0") } } @@ -131,9 +132,9 @@ func testIpvlanOverlapParent(client dclient.APIClient) func(*testing.T) { return func(t *testing.T) { // verify the same parent interface cannot be used if already in use by an existing network master := "di-dummy0" - createMasterDummy(t, master) - defer deleteInterface(t, master) - createVlanInterface(t, master, "di-dummy0.30", "30") + n.CreateMasterDummy(t, master) + defer n.DeleteInterface(t, master) + n.CreateVlanInterface(t, master, "di-dummy0.30", "30") _, err := client.NetworkCreate(context.Background(), "di-subinterface", types.NetworkCreate{ Driver: "ipvlan", @@ -142,7 +143,7 @@ func testIpvlanOverlapParent(client dclient.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "di-subinterface")) + assert.Check(t, n.IsNetworkAvailable(client, "di-subinterface")) _, err = client.NetworkCreate(context.Background(), "di-subinterface", types.NetworkCreate{ Driver: "ipvlan", @@ -162,17 +163,14 @@ func testIpvlanL2NilParent(client dclient.APIClient) func(*testing.T) { Driver: "ipvlan", }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "di-nil-parent")) + assert.Check(t, n.IsNetworkAvailable(client, "di-nil-parent")) ctx := context.Background() id1 := container.Run(t, ctx, client, container.WithNetworkMode("di-nil-parent")) id2 := container.Run(t, ctx, client, container.WithNetworkMode("di-nil-parent")) - t.Log(time.Now()) - _, err = container.Exec(ctx, client, id2, []string{"ping", "-c", "1", id1}) assert.NilError(t, err) - t.Log(time.Now()) } } @@ -183,7 +181,7 @@ func testIpvlanL2InternalMode(client dclient.APIClient) func(*testing.T) { Internal: true, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "di-internal")) + assert.Check(t, n.IsNetworkAvailable(client, "di-internal")) ctx := context.Background() id1 := container.Run(t, ctx, client, container.WithNetworkMode("di-internal")) @@ -222,7 +220,7 @@ func testIpvlanL3NilParent(client dclient.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "di-nil-parent-l3")) + assert.Check(t, n.IsNetworkAvailable(client, "di-nil-parent-l3")) ctx := context.Background() id1 := container.Run(t, ctx, client, @@ -261,7 +259,7 @@ func testIpvlanL3InternalMode(client dclient.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "di-internal-l3")) + assert.Check(t, n.IsNetworkAvailable(client, "di-internal-l3")) ctx := context.Background() id1 := container.Run(t, ctx, client, @@ -314,7 +312,7 @@ func testIpvlanL2MultiSubnet(client dclient.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dualstackl2")) + assert.Check(t, n.IsNetworkAvailable(client, "dualstackl2")) // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.100.0/24 and 2001:db8:abc2::/64 ctx := context.Background() @@ -402,7 +400,7 @@ func testIpvlanL3MultiSubnet(client dclient.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dualstackl3")) + assert.Check(t, n.IsNetworkAvailable(client, "dualstackl3")) // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.100.0/24 and 2001:db8:abc2::/64 ctx := context.Background() @@ -483,7 +481,7 @@ func testIpvlanAddressing(client dclient.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dualstackl2")) + assert.Check(t, n.IsNetworkAvailable(client, "dualstackl2")) ctx := context.Background() id1 := container.Run(t, ctx, client, @@ -521,7 +519,7 @@ func testIpvlanAddressing(client dclient.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dualstackl3")) + assert.Check(t, n.IsNetworkAvailable(client, "dualstackl3")) id2 := container.Run(t, ctx, client, container.WithNetworkMode("dualstackl3"), @@ -539,5 +537,5 @@ func testIpvlanAddressing(client dclient.APIClient) func(*testing.T) { // ensure Kernel version is >= v4.2 for ipvlan support func ipvlanKernelSupport() bool { - return checkKernelMajorVersionGreaterOrEqualThen(4, 2) + return n.CheckKernelMajorVersionGreaterOrEqualThen(4, 2) } diff --git a/components/engine/integration/network/ipvlan/main_test.go b/components/engine/integration/network/ipvlan/main_test.go new file mode 100644 index 00000000000..2d5f62453c4 --- /dev/null +++ b/components/engine/integration/network/ipvlan/main_test.go @@ -0,0 +1,33 @@ +package ipvlan // import "github.com/docker/docker/integration/network/ipvlan" + +import ( + "fmt" + "os" + "testing" + + "github.com/docker/docker/internal/test/environment" +) + +var testEnv *environment.Execution + +func TestMain(m *testing.M) { + var err error + testEnv, err = environment.New() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + err = environment.EnsureFrozenImagesLinux(testEnv) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + testEnv.Print() + os.Exit(m.Run()) +} + +func setupTest(t *testing.T) func() { + environment.ProtectAll(t, testEnv) + return func() { testEnv.Clean(t) } +} diff --git a/components/engine/integration/network/macvlan_test.go b/components/engine/integration/network/macvlan/macvlan_test.go similarity index 74% rename from components/engine/integration/network/macvlan_test.go rename to components/engine/integration/network/macvlan/macvlan_test.go index 31848bca99d..7358af873b4 100644 --- a/components/engine/integration/network/macvlan_test.go +++ b/components/engine/integration/network/macvlan/macvlan_test.go @@ -1,8 +1,7 @@ -package network +package macvlan import ( "context" - "fmt" "strings" "testing" "time" @@ -11,11 +10,9 @@ import ( "github.com/docker/docker/api/types/network" "github.com/docker/docker/client" "github.com/docker/docker/integration/internal/container" + n "github.com/docker/docker/integration/network" "github.com/docker/docker/internal/test/daemon" - "github.com/docker/docker/pkg/parsers/kernel" "github.com/gotestyourself/gotestyourself/assert" - "github.com/gotestyourself/gotestyourself/assert/cmp" - "github.com/gotestyourself/gotestyourself/icmd" "github.com/gotestyourself/gotestyourself/skip" ) @@ -30,8 +27,8 @@ func TestDockerNetworkMacvlanPersistance(t *testing.T) { defer d.Stop(t) master := "dm-dummy0" - createMasterDummy(t, master) - defer deleteInterface(t, master) + n.CreateMasterDummy(t, master) + defer n.DeleteInterface(t, master) client, err := d.NewClient() assert.NilError(t, err) @@ -43,9 +40,9 @@ func TestDockerNetworkMacvlanPersistance(t *testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dm-persist")) + assert.Check(t, n.IsNetworkAvailable(client, "dm-persist")) d.Restart(t) - assert.Check(t, isNetworkAvailable(client, "dm-persist")) + assert.Check(t, n.IsNetworkAvailable(client, "dm-persist")) } func TestDockerNetworkMacvlan(t *testing.T) { @@ -91,8 +88,8 @@ func testMacvlanOverlapParent(client client.APIClient) func(*testing.T) { return func(t *testing.T) { // verify the same parent interface cannot be used if already in use by an existing network master := "dm-dummy0" - createMasterDummy(t, master) - defer deleteInterface(t, master) + n.CreateMasterDummy(t, master) + defer n.DeleteInterface(t, master) _, err := client.NetworkCreate(context.Background(), "dm-subinterface", types.NetworkCreate{ Driver: "macvlan", @@ -101,7 +98,7 @@ func testMacvlanOverlapParent(client client.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dm-subinterface")) + assert.Check(t, n.IsNetworkAvailable(client, "dm-subinterface")) _, err = client.NetworkCreate(context.Background(), "dm-parent-net-overlap", types.NetworkCreate{ Driver: "macvlan", @@ -114,9 +111,9 @@ func testMacvlanOverlapParent(client client.APIClient) func(*testing.T) { err = client.NetworkRemove(context.Background(), "dm-subinterface") assert.NilError(t, err) - assert.Check(t, isNetworkNotAvailable(client, "dm-subinterface")) + assert.Check(t, n.IsNetworkNotAvailable(client, "dm-subinterface")) // verify the network delete did not delete the predefined link - linkExists(t, "dm-dummy0") + n.LinkExists(t, "dm-dummy0") } } @@ -124,9 +121,9 @@ func testMacvlanSubinterface(client client.APIClient) func(*testing.T) { return func(t *testing.T) { // verify the same parent interface cannot be used if already in use by an existing network master := "dm-dummy0" - createMasterDummy(t, master) - defer deleteInterface(t, master) - createVlanInterface(t, master, "dm-dummy0.20", "20") + n.CreateMasterDummy(t, master) + defer n.DeleteInterface(t, master) + n.CreateVlanInterface(t, master, "dm-dummy0.20", "20") _, err := client.NetworkCreate(context.Background(), "dm-subinterface", types.NetworkCreate{ Driver: "macvlan", @@ -135,15 +132,15 @@ func testMacvlanSubinterface(client client.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dm-subinterface")) + assert.Check(t, n.IsNetworkAvailable(client, "dm-subinterface")) // delete the network while preserving the parent link err = client.NetworkRemove(context.Background(), "dm-subinterface") assert.NilError(t, err) - assert.Check(t, isNetworkNotAvailable(client, "dm-subinterface")) + assert.Check(t, n.IsNetworkNotAvailable(client, "dm-subinterface")) // verify the network delete did not delete the predefined link - linkExists(t, "dm-dummy0.20") + n.LinkExists(t, "dm-dummy0.20") } } @@ -154,7 +151,7 @@ func testMacvlanNilParent(client client.APIClient) func(*testing.T) { Driver: "macvlan", }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dm-nil-parent")) + assert.Check(t, n.IsNetworkAvailable(client, "dm-nil-parent")) ctx := context.Background() id1 := container.Run(t, ctx, client, container.WithNetworkMode("dm-nil-parent")) @@ -173,7 +170,7 @@ func testMacvlanInternalMode(client client.APIClient) func(*testing.T) { Internal: true, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dm-internal")) + assert.Check(t, n.IsNetworkAvailable(client, "dm-internal")) ctx := context.Background() id1 := container.Run(t, ctx, client, container.WithNetworkMode("dm-internal")) @@ -193,7 +190,6 @@ func testMacvlanInternalMode(client client.APIClient) func(*testing.T) { func testMacvlanMultiSubnet(client client.APIClient) func(*testing.T) { return func(t *testing.T) { - // t.Skip("Temporarily skipping while investigating sporadic v6 CI issues") _, err := client.NetworkCreate(context.Background(), "dualstackbridge", types.NetworkCreate{ Driver: "macvlan", EnableIPv6: true, @@ -221,7 +217,7 @@ func testMacvlanMultiSubnet(client client.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dualstackbridge")) + assert.Check(t, n.IsNetworkAvailable(client, "dualstackbridge")) // start dual stack containers and verify the user specified --ip and --ip6 addresses on subnets 172.28.100.0/24 and 2001:db8:abc2::/64 ctx := context.Background() @@ -301,7 +297,7 @@ func testMacvlanAddressing(client client.APIClient) func(*testing.T) { }, }) assert.NilError(t, err) - assert.Check(t, isNetworkAvailable(client, "dualstackbridge")) + assert.Check(t, n.IsNetworkAvailable(client, "dualstackbridge")) ctx := context.Background() id1 := container.Run(t, ctx, client, @@ -319,72 +315,7 @@ func testMacvlanAddressing(client client.APIClient) func(*testing.T) { } } -func isNetworkAvailable(c client.NetworkAPIClient, name string) cmp.Comparison { - return func() cmp.Result { - networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{}) - if err != nil { - return cmp.ResultFromError(err) - } - for _, network := range networks { - if network.Name == name { - return cmp.ResultSuccess - } - } - return cmp.ResultFailure(fmt.Sprintf("could not find network %s", name)) - } -} - -func isNetworkNotAvailable(c client.NetworkAPIClient, name string) cmp.Comparison { - return func() cmp.Result { - networks, err := c.NetworkList(context.Background(), types.NetworkListOptions{}) - if err != nil { - return cmp.ResultFromError(err) - } - for _, network := range networks { - if network.Name == name { - return cmp.ResultFailure(fmt.Sprintf("network %s is still present", name)) - } - } - return cmp.ResultSuccess - } -} - -func createMasterDummy(t *testing.T, master string) { - // ip link add type dummy - icmd.RunCommand("ip", "link", "add", master, "type", "dummy").Assert(t, icmd.Success) - icmd.RunCommand("ip", "link", "set", master, "up").Assert(t, icmd.Success) -} - -func createVlanInterface(t *testing.T, master, slave, id string) { - // ip link add link name . type vlan id - icmd.RunCommand("ip", "link", "add", "link", master, "name", slave, "type", "vlan", "id", id).Assert(t, icmd.Success) - // ip link set up - icmd.RunCommand("ip", "link", "set", slave, "up").Assert(t, icmd.Success) -} - -func deleteInterface(t *testing.T, ifName string) { - icmd.RunCommand("ip", "link", "delete", ifName).Assert(t, icmd.Success) - icmd.RunCommand("iptables", "-t", "nat", "--flush").Assert(t, icmd.Success) - icmd.RunCommand("iptables", "--flush").Assert(t, icmd.Success) -} - -func linkExists(t *testing.T, master string) { - // verify the specified link exists, ip link show - icmd.RunCommand("ip", "link", "show", master).Assert(t, icmd.Success) -} - // ensure Kernel version is >= v3.9 for macvlan support func macvlanKernelSupport() bool { - return checkKernelMajorVersionGreaterOrEqualThen(3, 9) -} - -func checkKernelMajorVersionGreaterOrEqualThen(kernelVersion int, majorVersion int) bool { - kv, err := kernel.GetKernelVersion() - if err != nil { - return false - } - if kv.Kernel < kernelVersion || (kv.Kernel == kernelVersion && kv.Major < majorVersion) { - return false - } - return true + return n.CheckKernelMajorVersionGreaterOrEqualThen(3, 9) } diff --git a/components/engine/integration/network/macvlan/main_test.go b/components/engine/integration/network/macvlan/main_test.go new file mode 100644 index 00000000000..31cf111b22a --- /dev/null +++ b/components/engine/integration/network/macvlan/main_test.go @@ -0,0 +1,33 @@ +package macvlan // import "github.com/docker/docker/integration/network/macvlan" + +import ( + "fmt" + "os" + "testing" + + "github.com/docker/docker/internal/test/environment" +) + +var testEnv *environment.Execution + +func TestMain(m *testing.M) { + var err error + testEnv, err = environment.New() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + err = environment.EnsureFrozenImagesLinux(testEnv) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + testEnv.Print() + os.Exit(m.Run()) +} + +func setupTest(t *testing.T) func() { + environment.ProtectAll(t, testEnv) + return func() { testEnv.Clean(t) } +} From f160c829fbdc7e5b93949123abd19ebe9f42f517 Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Fri, 13 Apr 2018 10:45:34 +0200 Subject: [PATCH 27/36] Move and refactor integration-cli/registry to internal/test - Move the code from `integration-cli` to `internal/test`. - Use `testingT` and `assert` when creating the registry. Signed-off-by: Vincent Demeester (cherry picked from commit 66de2e6e3b6d927a3396743cd7c363aa9f7b776e) Signed-off-by: Sebastiaan van Stijn --- .../engine/integration-cli/check_test.go | 29 +++--- .../docker_api_swarm_service_test.go | 3 +- .../docker_cli_registry_user_agent_test.go | 2 +- .../docker_cli_v2_only_test.go | 2 +- .../integration-cli/docker_utils_test.go | 17 ---- .../integration-cli/registry/requirement.go | 12 --- .../integration-cli/requirements_test.go | 10 ++ .../engine/internal/test/registry/ops.go | 26 +++++ .../test}/registry/registry.go | 97 ++++++++++++------- .../test}/registry/registry_mock.go | 2 +- 10 files changed, 119 insertions(+), 81 deletions(-) delete mode 100644 components/engine/integration-cli/registry/requirement.go create mode 100644 components/engine/internal/test/registry/ops.go rename components/engine/{integration-cli => internal/test}/registry/registry.go (67%) rename components/engine/{integration-cli => internal/test}/registry/registry_mock.go (94%) diff --git a/components/engine/integration-cli/check_test.go b/components/engine/integration-cli/check_test.go index 0cae1503f88..6bab50f9074 100644 --- a/components/engine/integration-cli/check_test.go +++ b/components/engine/integration-cli/check_test.go @@ -20,9 +20,9 @@ import ( "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/integration-cli/environment" "github.com/docker/docker/integration-cli/fixtures/plugin" - "github.com/docker/docker/integration-cli/registry" testdaemon "github.com/docker/docker/internal/test/daemon" ienv "github.com/docker/docker/internal/test/environment" + "github.com/docker/docker/internal/test/registry" "github.com/docker/docker/pkg/reexec" "github.com/go-check/check" "golang.org/x/net/context" @@ -30,7 +30,7 @@ import ( const ( // the private registry to use for tests - privateRegistryURL = "127.0.0.1:5000" + privateRegistryURL = registry.DefaultURL // path to containerd's ctr binary ctrBinary = "docker-containerd-ctr" @@ -126,8 +126,9 @@ func (s *DockerRegistrySuite) OnTimeout(c *check.C) { } func (s *DockerRegistrySuite) SetUpTest(c *check.C) { - testRequires(c, DaemonIsLinux, registry.Hosting, SameHostDaemon) - s.reg = setupRegistry(c, false, "", "") + testRequires(c, DaemonIsLinux, RegistryHosting, SameHostDaemon) + s.reg = registry.NewV2(c) + s.reg.WaitReady(c) s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ Experimental: testEnv.DaemonInfo.ExperimentalBuild, }) @@ -160,8 +161,9 @@ func (s *DockerSchema1RegistrySuite) OnTimeout(c *check.C) { } func (s *DockerSchema1RegistrySuite) SetUpTest(c *check.C) { - testRequires(c, DaemonIsLinux, registry.Hosting, NotArm64, SameHostDaemon) - s.reg = setupRegistry(c, true, "", "") + testRequires(c, DaemonIsLinux, RegistryHosting, NotArm64, SameHostDaemon) + s.reg = registry.NewV2(c, registry.Schema1) + s.reg.WaitReady(c) s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ Experimental: testEnv.DaemonInfo.ExperimentalBuild, }) @@ -194,8 +196,9 @@ func (s *DockerRegistryAuthHtpasswdSuite) OnTimeout(c *check.C) { } func (s *DockerRegistryAuthHtpasswdSuite) SetUpTest(c *check.C) { - testRequires(c, DaemonIsLinux, registry.Hosting, SameHostDaemon) - s.reg = setupRegistry(c, false, "htpasswd", "") + testRequires(c, DaemonIsLinux, RegistryHosting, SameHostDaemon) + s.reg = registry.NewV2(c, registry.Htpasswd) + s.reg.WaitReady(c) s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ Experimental: testEnv.DaemonInfo.ExperimentalBuild, }) @@ -230,7 +233,7 @@ func (s *DockerRegistryAuthTokenSuite) OnTimeout(c *check.C) { } func (s *DockerRegistryAuthTokenSuite) SetUpTest(c *check.C) { - testRequires(c, DaemonIsLinux, registry.Hosting, SameHostDaemon) + testRequires(c, DaemonIsLinux, RegistryHosting, SameHostDaemon) s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ Experimental: testEnv.DaemonInfo.ExperimentalBuild, }) @@ -252,7 +255,8 @@ func (s *DockerRegistryAuthTokenSuite) setupRegistryWithTokenService(c *check.C, if s == nil { c.Fatal("registry suite isn't initialized") } - s.reg = setupRegistry(c, false, "token", tokenURL) + s.reg = registry.NewV2(c, registry.Token(tokenURL)) + s.reg.WaitReady(c) } func init() { @@ -405,8 +409,9 @@ func (ps *DockerPluginSuite) getPluginRepoWithTag() string { } func (ps *DockerPluginSuite) SetUpSuite(c *check.C) { - testRequires(c, DaemonIsLinux, registry.Hosting) - ps.registry = setupRegistry(c, false, "", "") + testRequires(c, DaemonIsLinux, RegistryHosting) + ps.registry = registry.NewV2(c) + ps.registry.WaitReady(c) ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) defer cancel() diff --git a/components/engine/integration-cli/docker_api_swarm_service_test.go b/components/engine/integration-cli/docker_api_swarm_service_test.go index f715265f637..e816d4f567a 100644 --- a/components/engine/integration-cli/docker_api_swarm_service_test.go +++ b/components/engine/integration-cli/docker_api_swarm_service_test.go @@ -16,6 +16,7 @@ import ( "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/integration-cli/fixtures/plugin" testdaemon "github.com/docker/docker/internal/test/daemon" + "github.com/docker/docker/internal/test/registry" "github.com/go-check/check" "golang.org/x/net/context" "golang.org/x/sys/unix" @@ -615,7 +616,7 @@ func (s *DockerSwarmSuite) TestAPISwarmServicesStateReporting(c *check.C) { func (s *DockerSwarmSuite) TestAPISwarmServicesPlugin(c *check.C) { testRequires(c, ExperimentalDaemon, DaemonIsLinux, IsAmd64) - reg := setupRegistry(c, false, "", "") + reg := registry.NewV2(c) defer reg.Close() repo := path.Join(privateRegistryURL, "swarm", "test:v1") diff --git a/components/engine/integration-cli/docker_cli_registry_user_agent_test.go b/components/engine/integration-cli/docker_cli_registry_user_agent_test.go index 6cbe6e7e667..7ee3c3d1ba0 100644 --- a/components/engine/integration-cli/docker_cli_registry_user_agent_test.go +++ b/components/engine/integration-cli/docker_cli_registry_user_agent_test.go @@ -7,7 +7,7 @@ import ( "os" "regexp" - "github.com/docker/docker/integration-cli/registry" + "github.com/docker/docker/internal/test/registry" "github.com/go-check/check" ) diff --git a/components/engine/integration-cli/docker_cli_v2_only_test.go b/components/engine/integration-cli/docker_cli_v2_only_test.go index 3757341025d..df0c01a517c 100644 --- a/components/engine/integration-cli/docker_cli_v2_only_test.go +++ b/components/engine/integration-cli/docker_cli_v2_only_test.go @@ -6,7 +6,7 @@ import ( "net/http" "os" - "github.com/docker/docker/integration-cli/registry" + "github.com/docker/docker/internal/test/registry" "github.com/go-check/check" ) diff --git a/components/engine/integration-cli/docker_utils_test.go b/components/engine/integration-cli/docker_utils_test.go index 1475558239c..a5fb437e4c9 100644 --- a/components/engine/integration-cli/docker_utils_test.go +++ b/components/engine/integration-cli/docker_utils_test.go @@ -18,7 +18,6 @@ import ( "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/cli" "github.com/docker/docker/integration-cli/daemon" - "github.com/docker/docker/integration-cli/registry" "github.com/docker/docker/integration-cli/request" "github.com/go-check/check" "github.com/gotestyourself/gotestyourself/icmd" @@ -284,22 +283,6 @@ func parseEventTime(t time.Time) string { return fmt.Sprintf("%d.%09d", t.Unix(), int64(t.Nanosecond())) } -func setupRegistry(c *check.C, schema1 bool, auth, tokenURL string) *registry.V2 { - reg, err := registry.NewV2(schema1, auth, tokenURL, privateRegistryURL) - c.Assert(err, check.IsNil) - - // Wait for registry to be ready to serve requests. - for i := 0; i != 50; i++ { - if err = reg.Ping(); err == nil { - break - } - time.Sleep(100 * time.Millisecond) - } - - c.Assert(err, check.IsNil, check.Commentf("Timeout waiting for test registry to become available: %v", err)) - return reg -} - // appendBaseEnv appends the minimum set of environment variables to exec the // docker cli binary for testing with correct configuration to the given env // list. diff --git a/components/engine/integration-cli/registry/requirement.go b/components/engine/integration-cli/registry/requirement.go deleted file mode 100644 index 8cd428cc264..00000000000 --- a/components/engine/integration-cli/registry/requirement.go +++ /dev/null @@ -1,12 +0,0 @@ -package registry // import "github.com/docker/docker/integration-cli/registry" - -import "os/exec" - -// Hosting returns wether the host can host a registry (v2) or not -func Hosting() bool { - // for now registry binary is built only if we're running inside - // container through `make test`. Figure that out by testing if - // registry binary is in PATH. - _, err := exec.LookPath(v2binary) - return err == nil -} diff --git a/components/engine/integration-cli/requirements_test.go b/components/engine/integration-cli/requirements_test.go index b0a95d42f81..3ae24b204ce 100644 --- a/components/engine/integration-cli/requirements_test.go +++ b/components/engine/integration-cli/requirements_test.go @@ -14,6 +14,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/client" "github.com/docker/docker/integration-cli/requirement" + "github.com/docker/docker/internal/test/registry" ) func ArchitectureIsNot(arch string) bool { @@ -183,6 +184,15 @@ func IsolationIsProcess() bool { return IsolationIs("process") } +// RegistryHosting returns wether the host can host a registry (v2) or not +func RegistryHosting() bool { + // for now registry binary is built only if we're running inside + // container through `make test`. Figure that out by testing if + // registry binary is in PATH. + _, err := exec.LookPath(registry.V2binary) + return err == nil +} + // testRequires checks if the environment satisfies the requirements // for the test to run or skips the tests. func testRequires(c requirement.SkipT, requirements ...requirement.Test) { diff --git a/components/engine/internal/test/registry/ops.go b/components/engine/internal/test/registry/ops.go new file mode 100644 index 00000000000..c004f37424f --- /dev/null +++ b/components/engine/internal/test/registry/ops.go @@ -0,0 +1,26 @@ +package registry + +// Schema1 sets the registry to serve v1 api +func Schema1(c *Config) { + c.schema1 = true +} + +// Htpasswd sets the auth method with htpasswd +func Htpasswd(c *Config) { + c.auth = "htpasswd" +} + +// Token sets the auth method to token, with the specified token url +func Token(tokenURL string) func(*Config) { + return func(c *Config) { + c.auth = "token" + c.tokenURL = tokenURL + } +} + +// URL sets the registry url +func URL(registryURL string) func(*Config) { + return func(c *Config) { + c.registryURL = registryURL + } +} diff --git a/components/engine/integration-cli/registry/registry.go b/components/engine/internal/test/registry/registry.go similarity index 67% rename from components/engine/integration-cli/registry/registry.go rename to components/engine/internal/test/registry/registry.go index b09887584ab..a801beea292 100644 --- a/components/engine/integration-cli/registry/registry.go +++ b/components/engine/internal/test/registry/registry.go @@ -1,4 +1,4 @@ -package registry // import "github.com/docker/docker/integration-cli/registry" +package registry // import "github.com/docker/docker/internal/test/registry" import ( "fmt" @@ -7,16 +7,23 @@ import ( "os" "os/exec" "path/filepath" + "time" + "github.com/gotestyourself/gotestyourself/assert" "github.com/opencontainers/go-digest" ) const ( - v2binary = "registry-v2" - v2binarySchema1 = "registry-v2-schema1" + // V2binary is the name of the registry v2 binary + V2binary = "registry-v2" + // V2binarySchema1 is the name of the registry that serve schema1 + V2binarySchema1 = "registry-v2-schema1" + // DefaultURL is the default url that will be used by the registry (if not specified otherwise) + DefaultURL = "127.0.0.1:5000" ) type testingT interface { + assert.TestingT logT Fatal(...interface{}) Fatalf(string, ...interface{}) @@ -37,12 +44,24 @@ type V2 struct { email string } +// Config contains the test registry configuration +type Config struct { + schema1 bool + auth string + tokenURL string + registryURL string +} + // NewV2 creates a v2 registry server -func NewV2(schema1 bool, auth, tokenURL, registryURL string) (*V2, error) { - tmp, err := ioutil.TempDir("", "registry-test-") - if err != nil { - return nil, err +func NewV2(t testingT, ops ...func(*Config)) *V2 { + c := &Config{ + registryURL: DefaultURL, } + for _, op := range ops { + op(c) + } + tmp, err := ioutil.TempDir("", "registry-test-") + assert.NilError(t, err) template := `version: 0.1 loglevel: debug storage: @@ -57,7 +76,7 @@ http: password string email string ) - switch auth { + switch c.auth { case "htpasswd": htpasswdPath := filepath.Join(tmp, "htpasswd") // generated with: htpasswd -Bbn testuser testpassword @@ -65,9 +84,8 @@ http: username = "testuser" password = "testpassword" email = "test@test.org" - if err := ioutil.WriteFile(htpasswdPath, []byte(userpasswd), os.FileMode(0644)); err != nil { - return nil, err - } + err := ioutil.WriteFile(htpasswdPath, []byte(userpasswd), os.FileMode(0644)) + assert.NilError(t, err) authTemplate = fmt.Sprintf(`auth: htpasswd: realm: basic-realm @@ -80,39 +98,51 @@ http: service: "registry" issuer: "auth-registry" rootcertbundle: "fixtures/registry/cert.pem" -`, tokenURL) +`, c.tokenURL) } confPath := filepath.Join(tmp, "config.yaml") config, err := os.Create(confPath) - if err != nil { - return nil, err - } + assert.NilError(t, err) defer config.Close() - if _, err := fmt.Fprintf(config, template, tmp, registryURL, authTemplate); err != nil { + if _, err := fmt.Fprintf(config, template, tmp, c.registryURL, authTemplate); err != nil { + // FIXME(vdemeester) use a defer/clean func os.RemoveAll(tmp) - return nil, err + t.Fatal(err) } - binary := v2binary - if schema1 { - binary = v2binarySchema1 + binary := V2binary + if c.schema1 { + binary = V2binarySchema1 } cmd := exec.Command(binary, confPath) if err := cmd.Start(); err != nil { + // FIXME(vdemeester) use a defer/clean func os.RemoveAll(tmp) - return nil, err + t.Fatal(err) } return &V2{ cmd: cmd, dir: tmp, - auth: auth, + auth: c.auth, username: username, password: password, email: email, - registryURL: registryURL, - }, nil + registryURL: c.registryURL, + } +} + +// WaitReady waits for the registry to be ready to serve requests (or fail after a while) +func (r *V2) WaitReady(t testingT) { + var err error + for i := 0; i != 50; i++ { + if err = r.Ping(); err == nil { + return + } + time.Sleep(100 * time.Millisecond) + } + t.Fatalf("timeout waiting for test registry to become available: %v", err) } // Ping sends an http request to the current registry, and fail if it doesn't respond correctly @@ -152,30 +182,24 @@ func (r *V2) getBlobFilename(blobDigest digest.Digest) string { } // ReadBlobContents read the file corresponding to the specified digest -func (r *V2) ReadBlobContents(t testingT, blobDigest digest.Digest) []byte { +func (r *V2) ReadBlobContents(t assert.TestingT, blobDigest digest.Digest) []byte { // Load the target manifest blob. manifestBlob, err := ioutil.ReadFile(r.getBlobFilename(blobDigest)) - if err != nil { - t.Fatalf("unable to read blob: %s", err) - } - + assert.NilError(t, err, "unable to read blob") return manifestBlob } // WriteBlobContents write the file corresponding to the specified digest with the given content -func (r *V2) WriteBlobContents(t testingT, blobDigest digest.Digest, data []byte) { - if err := ioutil.WriteFile(r.getBlobFilename(blobDigest), data, os.FileMode(0644)); err != nil { - t.Fatalf("unable to write malicious data blob: %s", err) - } +func (r *V2) WriteBlobContents(t assert.TestingT, blobDigest digest.Digest, data []byte) { + err := ioutil.WriteFile(r.getBlobFilename(blobDigest), data, os.FileMode(0644)) + assert.NilError(t, err, "unable to write malicious data blob") } // TempMoveBlobData moves the existing data file aside, so that we can replace it with a // malicious blob of data for example. func (r *V2) TempMoveBlobData(t testingT, blobDigest digest.Digest) (undo func()) { tempFile, err := ioutil.TempFile("", "registry-temp-blob-") - if err != nil { - t.Fatalf("unable to get temporary blob file: %s", err) - } + assert.NilError(t, err, "unable to get temporary blob file") tempFile.Close() blobFilename := r.getBlobFilename(blobDigest) @@ -183,6 +207,7 @@ func (r *V2) TempMoveBlobData(t testingT, blobDigest digest.Digest) (undo func() // Move the existing data file aside, so that we can replace it with a // another blob of data. if err := os.Rename(blobFilename, tempFile.Name()); err != nil { + // FIXME(vdemeester) use a defer/clean func os.Remove(tempFile.Name()) t.Fatalf("unable to move data blob: %s", err) } diff --git a/components/engine/integration-cli/registry/registry_mock.go b/components/engine/internal/test/registry/registry_mock.go similarity index 94% rename from components/engine/integration-cli/registry/registry_mock.go rename to components/engine/internal/test/registry/registry_mock.go index c2b4897aad2..77c4ac1bd4b 100644 --- a/components/engine/integration-cli/registry/registry_mock.go +++ b/components/engine/internal/test/registry/registry_mock.go @@ -1,4 +1,4 @@ -package registry // import "github.com/docker/docker/integration-cli/registry" +package registry // import "github.com/docker/docker/internal/test/registry" import ( "net/http" From b11c120bdfdd2a2a1ba141533d9ef4bfad68fd59 Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Mon, 16 Apr 2018 10:48:58 +0200 Subject: [PATCH 28/36] Clean some integration-cli/fixtures package/files - Move go package used by both `integration-cli` and `integration` to `internal/test/fixtures`. - Remove fixtures that are not used anymore (moved to `docker/cli` a while ago) : deploy, notary, secrets. Signed-off-by: Vincent Demeester (cherry picked from commit 5f56503f583f21d655394f755f71849381bd58c7) Signed-off-by: Sebastiaan van Stijn --- .../engine/integration-cli/check_test.go | 2 +- .../docker_api_swarm_service_test.go | 2 +- .../docker_cli_plugins_test.go | 2 +- .../docker_cli_save_load_test.go | 2 +- .../fixtures/deploy/default.yaml | 9 ------ .../fixtures/deploy/remove.yaml | 11 ------- .../fixtures/deploy/secrets.yaml | 20 ------------- .../fixtures/notary/delgkey1.crt | 21 -------------- .../fixtures/notary/delgkey1.key | 27 ------------------ .../fixtures/notary/delgkey2.crt | 21 -------------- .../fixtures/notary/delgkey2.key | 27 ------------------ .../fixtures/notary/delgkey3.crt | 21 -------------- .../fixtures/notary/delgkey3.key | 27 ------------------ .../fixtures/notary/delgkey4.crt | 21 -------------- .../fixtures/notary/delgkey4.key | 27 ------------------ .../integration-cli/fixtures/notary/gen.sh | 18 ------------ .../fixtures/notary/localhost.cert | 19 ------------ .../fixtures/notary/localhost.key | 27 ------------------ .../integration-cli/fixtures/secrets/default | 1 - .../fixtures_linux_daemon_test.go | 2 +- .../load => testdata}/emptyLayer.tar | Bin .../plugin/logging/helpers_test.go | 2 +- .../plugin/volumes/helpers_test.go | 2 +- .../integration/plugin/volumes/mounts_test.go | 2 +- .../internal/test/environment/environment.go | 2 +- .../test}/fixtures/load/frozen.go | 2 +- .../test}/fixtures/plugin/basic/basic.go | 0 .../test}/fixtures/plugin/plugin.go | 7 +++-- 28 files changed, 14 insertions(+), 310 deletions(-) delete mode 100644 components/engine/integration-cli/fixtures/deploy/default.yaml delete mode 100644 components/engine/integration-cli/fixtures/deploy/remove.yaml delete mode 100644 components/engine/integration-cli/fixtures/deploy/secrets.yaml delete mode 100644 components/engine/integration-cli/fixtures/notary/delgkey1.crt delete mode 100644 components/engine/integration-cli/fixtures/notary/delgkey1.key delete mode 100644 components/engine/integration-cli/fixtures/notary/delgkey2.crt delete mode 100644 components/engine/integration-cli/fixtures/notary/delgkey2.key delete mode 100644 components/engine/integration-cli/fixtures/notary/delgkey3.crt delete mode 100644 components/engine/integration-cli/fixtures/notary/delgkey3.key delete mode 100644 components/engine/integration-cli/fixtures/notary/delgkey4.crt delete mode 100644 components/engine/integration-cli/fixtures/notary/delgkey4.key delete mode 100755 components/engine/integration-cli/fixtures/notary/gen.sh delete mode 100644 components/engine/integration-cli/fixtures/notary/localhost.cert delete mode 100644 components/engine/integration-cli/fixtures/notary/localhost.key delete mode 100644 components/engine/integration-cli/fixtures/secrets/default rename components/engine/integration-cli/{fixtures/load => testdata}/emptyLayer.tar (100%) rename components/engine/{integration-cli => internal/test}/fixtures/load/frozen.go (98%) rename components/engine/{integration-cli => internal/test}/fixtures/plugin/basic/basic.go (100%) rename components/engine/{integration-cli => internal/test}/fixtures/plugin/plugin.go (94%) diff --git a/components/engine/integration-cli/check_test.go b/components/engine/integration-cli/check_test.go index 6bab50f9074..de1b3c65c01 100644 --- a/components/engine/integration-cli/check_test.go +++ b/components/engine/integration-cli/check_test.go @@ -19,9 +19,9 @@ import ( "github.com/docker/docker/integration-cli/cli/build/fakestorage" "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/integration-cli/environment" - "github.com/docker/docker/integration-cli/fixtures/plugin" testdaemon "github.com/docker/docker/internal/test/daemon" ienv "github.com/docker/docker/internal/test/environment" + "github.com/docker/docker/internal/test/fixtures/plugin" "github.com/docker/docker/internal/test/registry" "github.com/docker/docker/pkg/reexec" "github.com/go-check/check" diff --git a/components/engine/integration-cli/docker_api_swarm_service_test.go b/components/engine/integration-cli/docker_api_swarm_service_test.go index e816d4f567a..cdedc369481 100644 --- a/components/engine/integration-cli/docker_api_swarm_service_test.go +++ b/components/engine/integration-cli/docker_api_swarm_service_test.go @@ -14,8 +14,8 @@ import ( "github.com/docker/docker/api/types/swarm/runtime" "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/daemon" - "github.com/docker/docker/integration-cli/fixtures/plugin" testdaemon "github.com/docker/docker/internal/test/daemon" + "github.com/docker/docker/internal/test/fixtures/plugin" "github.com/docker/docker/internal/test/registry" "github.com/go-check/check" "golang.org/x/net/context" diff --git a/components/engine/integration-cli/docker_cli_plugins_test.go b/components/engine/integration-cli/docker_cli_plugins_test.go index 8a936e3e446..483222540bf 100644 --- a/components/engine/integration-cli/docker_cli_plugins_test.go +++ b/components/engine/integration-cli/docker_cli_plugins_test.go @@ -14,7 +14,7 @@ import ( "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/cli" "github.com/docker/docker/integration-cli/daemon" - "github.com/docker/docker/integration-cli/fixtures/plugin" + "github.com/docker/docker/internal/test/fixtures/plugin" "github.com/go-check/check" "golang.org/x/net/context" ) diff --git a/components/engine/integration-cli/docker_cli_save_load_test.go b/components/engine/integration-cli/docker_cli_save_load_test.go index 3e6dc2dd391..d7cbc84752a 100644 --- a/components/engine/integration-cli/docker_cli_save_load_test.go +++ b/components/engine/integration-cli/docker_cli_save_load_test.go @@ -332,7 +332,7 @@ func listTar(f io.Reader) ([]string, error) { func (s *DockerSuite) TestLoadZeroSizeLayer(c *check.C) { testRequires(c, DaemonIsLinux) - dockerCmd(c, "load", "-i", "fixtures/load/emptyLayer.tar") + dockerCmd(c, "load", "-i", "testdata/emptyLayer.tar") } func (s *DockerSuite) TestSaveLoadParents(c *check.C) { diff --git a/components/engine/integration-cli/fixtures/deploy/default.yaml b/components/engine/integration-cli/fixtures/deploy/default.yaml deleted file mode 100644 index f30c04f8f16..00000000000 --- a/components/engine/integration-cli/fixtures/deploy/default.yaml +++ /dev/null @@ -1,9 +0,0 @@ - -version: "3" -services: - web: - image: busybox@sha256:e4f93f6ed15a0cdd342f5aae387886fba0ab98af0a102da6276eaf24d6e6ade0 - command: top - db: - image: busybox@sha256:e4f93f6ed15a0cdd342f5aae387886fba0ab98af0a102da6276eaf24d6e6ade0 - command: "tail -f /dev/null" diff --git a/components/engine/integration-cli/fixtures/deploy/remove.yaml b/components/engine/integration-cli/fixtures/deploy/remove.yaml deleted file mode 100644 index 4337581bf84..00000000000 --- a/components/engine/integration-cli/fixtures/deploy/remove.yaml +++ /dev/null @@ -1,11 +0,0 @@ - -version: "3.1" -services: - web: - image: busybox:latest - command: top - secrets: - - special -secrets: - special: - file: fixtures/secrets/default diff --git a/components/engine/integration-cli/fixtures/deploy/secrets.yaml b/components/engine/integration-cli/fixtures/deploy/secrets.yaml deleted file mode 100644 index 6ac92cddeed..00000000000 --- a/components/engine/integration-cli/fixtures/deploy/secrets.yaml +++ /dev/null @@ -1,20 +0,0 @@ - -version: "3.1" -services: - web: - image: busybox@sha256:e4f93f6ed15a0cdd342f5aae387886fba0ab98af0a102da6276eaf24d6e6ade0 - command: top - secrets: - - special - - source: super - target: foo.txt - mode: 0400 - - star -secrets: - special: - file: fixtures/secrets/default - super: - file: fixtures/secrets/default - star: - external: - name: outside diff --git a/components/engine/integration-cli/fixtures/notary/delgkey1.crt b/components/engine/integration-cli/fixtures/notary/delgkey1.crt deleted file mode 100644 index 2218f23c89b..00000000000 --- a/components/engine/integration-cli/fixtures/notary/delgkey1.crt +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDhTCCAm2gAwIBAgIJAP2EcMN2UXPcMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV -BAYTAlVTMQswCQYDVQQIEwJDQTEVMBMGA1UEBxMMU2FuRnJhbmNpc2NvMQ8wDQYD -VQQKEwZEb2NrZXIxEzARBgNVBAMTCmRlbGVnYXRpb24wHhcNMTYwOTI4MTc0ODQ4 -WhcNMjYwNjI4MTc0ODQ4WjBXMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFTAT -BgNVBAcTDFNhbkZyYW5jaXNjbzEPMA0GA1UEChMGRG9ja2VyMRMwEQYDVQQDEwpk -ZWxlZ2F0aW9uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvgewhaYs -Ke5s2AM7xxKrT4A6n7hW17qSnBjonCcPcwTFmYqIOdxWjYITgJuHrTwB4ZhBqWS7 -tTsUUu6hWLMeB7Uo5/GEQAAZspKkT9G/rNKF9lbWK9PPhGGkeR01c/Q932m92Hsn -fCQ0Pp/OzD3nVTh0v9HKk+PObNMOCcqG87eYs4ylPRxs0RrE/rP+bEGssKQSbeCZ -wazDnO+kiatVgKQZ2CK23iFdRE1z2rzqVDeaFWdvBqrRdWnkOZClhlLgEQ5nK2yV -B6tSqOiI3MmHyHzIkGOQJp2/s7Pe0ckEkzsjTsJW8oKHlBBl6pRxHIKzNN4VFbeB -vvYvrogrDrC/owIDAQABo1QwUjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIF -oDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUFoHfukRa6qGk1ncON64Z -ASKlZdkwDQYJKoZIhvcNAQELBQADggEBAEq9Adpd03CPmpbRtTAJGAkjjLFr60sV -2r+/l/m9R31ZCN9ymM9nxToQ8zfMdeAh/nnPcErziil2gDVqXueCNDkRj09tmDIE -Q1Oc92uyNZNgcECow77cKZCTZSTku+qsJrYaykH5vSnia8ltcKj8inJedIcpBR+p -608HEQvF0Eg5eaLPJwH48BCb0Gqdri1dJgrNnqptz7MDr8M+u7tHVulbAd3YxLlq -JH1W2bkVUx6esbn/MUE5HL5iTuOYREEINvBSmLdmmFkampmCnCB/bDEyJeL9bAkt -ZPIi0UNSnqFKLSP1Vf8AGLXt6iO7+1OGvtsDXEEYdXVOMsSXZtUuT7A= ------END CERTIFICATE----- diff --git a/components/engine/integration-cli/fixtures/notary/delgkey1.key b/components/engine/integration-cli/fixtures/notary/delgkey1.key deleted file mode 100644 index cb37efc94a4..00000000000 --- a/components/engine/integration-cli/fixtures/notary/delgkey1.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAvgewhaYsKe5s2AM7xxKrT4A6n7hW17qSnBjonCcPcwTFmYqI -OdxWjYITgJuHrTwB4ZhBqWS7tTsUUu6hWLMeB7Uo5/GEQAAZspKkT9G/rNKF9lbW -K9PPhGGkeR01c/Q932m92HsnfCQ0Pp/OzD3nVTh0v9HKk+PObNMOCcqG87eYs4yl -PRxs0RrE/rP+bEGssKQSbeCZwazDnO+kiatVgKQZ2CK23iFdRE1z2rzqVDeaFWdv -BqrRdWnkOZClhlLgEQ5nK2yVB6tSqOiI3MmHyHzIkGOQJp2/s7Pe0ckEkzsjTsJW -8oKHlBBl6pRxHIKzNN4VFbeBvvYvrogrDrC/owIDAQABAoIBAB/o8KZwsgfUhqh7 -WoViSCwQb0e0z7hoFwhpUl4uXPTGf1v6HEgDDPG0PwwgkdbwNaypQZVtWevj4NTQ -R326jjdjH1xbfQa2PZpz722L3jDqJR6plEtFxRoIv3KrCffPsrgabIu2mnnJJpDB -ixtW5cq0sT4ov2i4H0i85CWWwbSY/G/MHsvCuK9PhoCj9uToVqrf1KrAESE5q4fh -mPSYUL99KVnj7SZkUz+79rc8sLLPVks3szZACMlm1n05ZTj/d6Nd2ZZUO45DllIj -1XJghfWmnChrB/P/KYXgQ3Y9BofIAw1ra2y3wOZeqRFNsbmojcGldfdtN/iQzhEj -uk4ThokCgYEA9FTmv36N8qSPWuqX/KzkixDQ8WrDGohcB54kK98Wx4ijXx3i38SY -tFjO8YUS9GVo1+UgmRjZbzVX7xeum6+TdBBwOjNOxEQ4tzwiQBWDdGpli8BccdJ2 -OOIVxSslWhiUWfpYloXVetrR88iHbT882g795pbonDaJdXSLnij4UW8CgYEAxxrr -QFpsmOEZvI/yPSOGdG7A1RIsCeH+cEOf4cKghs7+aCtAHlIweztNOrqirl3oKI1r -I0zQl46WsaW8S/y99v9lmmnZbWwqLa4vIu0NWs0zaZdzKZw3xljMhgp4Ge69hHa2 -utCtAxcX+7q/yLlHoTiYwKdxX54iLkheCB8csw0CgYEAleEG820kkjXUIodJ2JwO -Tihwo8dEC6CeI6YktizRgnEVFqH0rCOjMO5Rc+KX8AfNOrK5PnD54LguSuKSH7qi -j04OKgWTSd43lF90+y63RtCFnibQDpp2HwrBJAQFk7EEP/XMJfnPLN/SbuMSADgM -kg8kPTFRW5Iw3DYz9z9WpE0CgYAkn6/8Q2XMbUOFqti9JEa8Lg8sYk5VdwuNbPMA -3QMYKQUk9ieyLB4c3Nik3+XCuyVUKEc31A5egmz3umu7cn8i6vGuiJ/k/8t2YZ7s -Bry5Ihu95Yzab5DW3Eiqs0xKQN79ebS9AluAwQO5Wy2h52rknfuDHIm/M+BHsSoS -xl5KFQKBgQCokCsYuX1z2GojHw369/R2aX3ovCGuHqy4k7fWxUrpHTHvth2+qNPr -84qLJ9rLWoZE5sUiZ5YdwCgW877EdfkT+v4aaBX79ixso5VdqgJ/PdnoNntah/Vq -njQiW1skn6/P5V/eyimN2n0VsyBr/zMDEtYTRP/Tb1zi/njFLQkZEA== ------END RSA PRIVATE KEY----- diff --git a/components/engine/integration-cli/fixtures/notary/delgkey2.crt b/components/engine/integration-cli/fixtures/notary/delgkey2.crt deleted file mode 100644 index bec084790a5..00000000000 --- a/components/engine/integration-cli/fixtures/notary/delgkey2.crt +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDhTCCAm2gAwIBAgIJAIq8naKlYAQfMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV -BAYTAlVTMQswCQYDVQQIEwJDQTEVMBMGA1UEBxMMU2FuRnJhbmNpc2NvMQ8wDQYD -VQQKEwZEb2NrZXIxEzARBgNVBAMTCmRlbGVnYXRpb24wHhcNMTYwOTI4MTc0ODQ4 -WhcNMjYwNjI4MTc0ODQ4WjBXMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFTAT -BgNVBAcTDFNhbkZyYW5jaXNjbzEPMA0GA1UEChMGRG9ja2VyMRMwEQYDVQQDEwpk -ZWxlZ2F0aW9uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyY2EWYTW -5VHipw08t675upmD6a+akiuZ1z+XpuOxZCgjZ0aHfoOe8wGKg3Ohz7UCBdD5Mob/ -L/qvRlsCaqPHGZKIyyX1HDO4mpuQQFBhYxt+ZAO3AaawEUOw2rwwMDEjLnDDTSZM -z8jxCMvsJjBDqgb8g3z+AmjducQ/OH6llldgHIBY8ioRbROCL2PGgqywWq2fThav -c70YMxtKviBGDNCouYeQ8JMK/PuLwPNDXNQAagFHVARXiUv/ILHk7ImYnSGJUcuk -JTUGN2MBnpY0eakg7i+4za8sjjqOdn+2I6aVzlGJDSiRP72nkg/cE4BqMl9FrMwK -9iS8xa9yMDLUvwIDAQABo1QwUjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIF -oDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUvQzzFmh3Sv3HcdExY3wx -/1u6JLAwDQYJKoZIhvcNAQELBQADggEBAJcmDme2Xj/HPUPwaN/EyCmjhY73EiHO -x6Pm16tscg5JGn5A+u3CZ1DmxUYl8Hp6MaW/sWzdtL0oKJg76pynadCWh5EacFR8 -u+2GV/IcN9mSX6JQzvrqbjSqo5/FehqBD+W5h3euwwApWA3STAadYeyEfmdOA3SQ -W1vzrA1y7i8qgTqeJ7UX1sEAXlIhBK2zPYaMB+en+ZOiPyNxJYj6IDdGdD2paC9L -6H9wKC+GAUTSdCWp89HP7ETSXEGr94AXkrwU+qNsiN+OyK8ke0EMngEPh5IQoplw -/7zEZCth3oKxvR1/4S5LmTVaHI2ZlbU4q9bnY72G4tw8YQr2gcBGo4w= ------END CERTIFICATE----- diff --git a/components/engine/integration-cli/fixtures/notary/delgkey2.key b/components/engine/integration-cli/fixtures/notary/delgkey2.key deleted file mode 100644 index 5ccabe908fb..00000000000 --- a/components/engine/integration-cli/fixtures/notary/delgkey2.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEogIBAAKCAQEAyY2EWYTW5VHipw08t675upmD6a+akiuZ1z+XpuOxZCgjZ0aH -foOe8wGKg3Ohz7UCBdD5Mob/L/qvRlsCaqPHGZKIyyX1HDO4mpuQQFBhYxt+ZAO3 -AaawEUOw2rwwMDEjLnDDTSZMz8jxCMvsJjBDqgb8g3z+AmjducQ/OH6llldgHIBY -8ioRbROCL2PGgqywWq2fThavc70YMxtKviBGDNCouYeQ8JMK/PuLwPNDXNQAagFH -VARXiUv/ILHk7ImYnSGJUcukJTUGN2MBnpY0eakg7i+4za8sjjqOdn+2I6aVzlGJ -DSiRP72nkg/cE4BqMl9FrMwK9iS8xa9yMDLUvwIDAQABAoIBAHmffvzx7ydESWwa -zcfdu26BkptiTvjjfJrqEd4wSewxWGPKqJqMXE8xX99A2KTZClZuKuH1mmnecQQY -iRXGrK9ewFMuHYGeKEiLlPlqR8ohXhyGLVm+t0JDwaXMp5t9G0i73O5iLTm5fNGd -FGxa9YnVW20Q8MqNczbVGH1D1zInhxzzOyFzBd4bBBJ8PdrUdyLpd7+RxY2ghnbT -p9ZANR2vk5zmDLJgZx72n/u+miJWuhY6p0v3Vq4z/HHgdhf+K6vpDdzTcYlA0rO4 -c/c+RKED3ZadGUD5QoLsmEN0e3FVSMPN1kt4ZRTqWfH8f2X4mLz33aBryTjktP6+ -1rX6ThECgYEA74wc1Tq23B5R0/GaMm1AK3Ko2zzTD8wK7NSCElh2dls02B+GzrEB -aE3A2GMQSuzb+EA0zkipwANBaqs3ZemH5G1pu4hstQsXCMd4jAJn0TmTXlplXBCf -PSc8ZUU6XcJENRr9Q7O9/TGlgahX+z0ndxYx/CMCsSu7XsMg4IZsbAcCgYEA12Vb -wKOVG15GGp7pMshr+2rQfVimARUP4gf3JnQmenktI4PfdnMW3a4L3DEHfLhIerwT -6lRp/NpxSADmuT4h1UO1l2lc+gmTVPw0Vbl6VwHpgS5Kfu4ZyM6n3S66f/dE4nu7 -hQF9yZz7vn5Agghak4p6a1wC1gdMzR1tvxFzk4kCgYByBMTskWfcWeok8Yitm+bB -R3Ar+kWT7VD97SCETusD5uG+RTNLSmEbHnc+B9kHcLo67YS0800pAeOvPBPARGnU -RmffRU5I1iB+o0MzkSmNItSMQoagTaEd4IEUyuC/I+qHRHNsOC+kRm86ycAm67LP -MhdUpe1wGxqyPjp15EXTHQKBgDKzFu+3EWfJvvKRKQ7dAh3BvKVkcl6a2Iw5l8Ej -YdM+JpPPfI/i8yTmzL/dgoem0Nii4IUtrWzo9fUe0TAVId2S/HFRSaNJEbbVTnRH -HjbQqmfPv5U08jjD+9siHp/0UfCFc1QRT8xe+RqTmReCY9+KntoaZEiAm2FEZgqt -TukRAoGAf7QqbTP5/UH1KSkX89F5qy/6GS3pw6TLj9Ufm/l/NO8Um8gag6YhEKWR -7HpkpCqjfWj8Av8ESR9cqddPGrbdqXFm9z7dCjlAd5T3Q3h/h+v+JzLQWbsI6WOb -SsOSWNyE006ZZdIiFwO6GfxpLI24sVtYKgyob6Q71oxSqfnrnT0= ------END RSA PRIVATE KEY----- diff --git a/components/engine/integration-cli/fixtures/notary/delgkey3.crt b/components/engine/integration-cli/fixtures/notary/delgkey3.crt deleted file mode 100644 index f434b45fc8e..00000000000 --- a/components/engine/integration-cli/fixtures/notary/delgkey3.crt +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDhTCCAm2gAwIBAgIJAKHt/jxiWqMtMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV -BAYTAlVTMQswCQYDVQQIEwJDQTEVMBMGA1UEBxMMU2FuRnJhbmNpc2NvMQ8wDQYD -VQQKEwZEb2NrZXIxEzARBgNVBAMTCmRlbGVnYXRpb24wHhcNMTYwOTI4MTc0ODQ5 -WhcNMjYwNjI4MTc0ODQ5WjBXMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFTAT -BgNVBAcTDFNhbkZyYW5jaXNjbzEPMA0GA1UEChMGRG9ja2VyMRMwEQYDVQQDEwpk -ZWxlZ2F0aW9uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqfbJk2Dk -C9FJVjV2+Q2CQrJphG3vFc1Qlu9jgVA5RhGmF9jJzetsclsV/95nBhinIGcSmPQA -l318G7Bz/cG/6O2n5+hj+S1+YOvQweReZj3d4kCeS86SOyLNTpMD9gsF0S8nR1RN -h0jD4t1vxAVeGD1o61U8/k0O5eDoeOfOSWZagKk5PhyrMZgNip4IrG46umCkFlrw -zMMcgQdwTQXywPqkr/LmYpqT1WpMlzHYTQEY8rKorIJQbPtHVYdr4UxYnNmk6fbU -biEP1DQlwjBWcFTsDLqXKP/K+e3O0/e/hMB0y7Tj9fZ7Viw0t5IKXZPsxMhwknUT -9vmPzIJO6NiniwIDAQABo1QwUjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIF -oDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUdTXRP1EzxQ+UDZSoheVo -Mobud1cwDQYJKoZIhvcNAQELBQADggEBADV9asTWWdbmpkeRuKyi0xGho39ONK88 -xxkFlco766BVgemo/rGQj3oPuw6M6SzHFoJ6JUPjmLiAQDIGEU/2/b6LcOuLjP+4 -YejCcDTY3lSW/HMNoAmzr2foo/LngNGfe/qhVFUqV7GjFT9+XzFFBfIZ1cQiL2ed -kc8rgQxFPwWXFCSwaENWeFnMDugkd+7xanoAHq8GsJpg5fTruDTmJkUqC2RNiMLn -WM7QaqW7+lmUnMnc1IBoz0hFhgoiadWM/1RQxx51zTVw6Au1koIm4ZXu5a+/WyC8 -K1+HyUbc0AVaDaRBpRSOR9aHRwLGh6WQ4aUZQNyJroc999qfYrDEEV8= ------END CERTIFICATE----- diff --git a/components/engine/integration-cli/fixtures/notary/delgkey3.key b/components/engine/integration-cli/fixtures/notary/delgkey3.key deleted file mode 100644 index a61d18cc3d4..00000000000 --- a/components/engine/integration-cli/fixtures/notary/delgkey3.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpQIBAAKCAQEAqfbJk2DkC9FJVjV2+Q2CQrJphG3vFc1Qlu9jgVA5RhGmF9jJ -zetsclsV/95nBhinIGcSmPQAl318G7Bz/cG/6O2n5+hj+S1+YOvQweReZj3d4kCe -S86SOyLNTpMD9gsF0S8nR1RNh0jD4t1vxAVeGD1o61U8/k0O5eDoeOfOSWZagKk5 -PhyrMZgNip4IrG46umCkFlrwzMMcgQdwTQXywPqkr/LmYpqT1WpMlzHYTQEY8rKo -rIJQbPtHVYdr4UxYnNmk6fbUbiEP1DQlwjBWcFTsDLqXKP/K+e3O0/e/hMB0y7Tj -9fZ7Viw0t5IKXZPsxMhwknUT9vmPzIJO6NiniwIDAQABAoIBAQCAr/ed3A2umO7T -FDYZik3nXBiiiW4t7r+nGGgZ3/kNgY1lnuHlROxehXLZwbX1mrLnyML/BjhwezV9 -7ZNVPd6laVPpNj6DyxtWHRZ5yARlm1Al39E7CpQTrF0QsiWcpGnqIa62xjDRTpnq -askV/Q5qggyvqmE9FnFCQpEiAjlhvp7F0kVHVJm9s3MK3zSyR0UTZ3cpYus2Jr2z -OotHgAMHq5Hgb3dvxOeE2xRMeYAVDujbkNzXm2SddAtiRdLhWDh7JIr3zXhp0HyN -4rLOyhlgz00oIGeDt/C0q3fRmghr3iZOG+7m2sUx0FD1Ru1dI9v2A+jYmIVNW6+x -YJk5PzxJAoGBANDj7AGdcHSci/LDBPoTTUiz3uucAd27/IJma/iy8mdbVfOAb0Fy -PRSPvoozlpZyOxg2J4eH/o4QxQR4lVKtnLKZLNHK2tg3LarwyBX1LiI3vVlB+DT1 -AmV8i5bJAckDhqFeEH5qdWZFi03oZsSXWEqX5iMYCrdK5lTZggcrFZeHAoGBANBL -fkk3knAdcVfTYpmHx18GBi2AsCWTd20KD49YBdbVy0Y2Jaa1EJAmGWpTUKdYx40R -H5CuGgcAviXQz3bugdTU1I3tAclBtpJNU7JkhuE+Epz0CM/6WERJrE0YxcGQA5ui -6fOguFyiXD1/85jrDBOKy74aoS7lYz9r/a6eqmjdAoGBAJpm/nmrIAZx+Ff2ouUe -A1Ar9Ch/Zjm5zEmu3zwzOU4AiyWz14iuoktifNq2iyalRNz+mnVpplToPFizsNwu -C9dPtXtU0DJlhtIFrD/evLz6KnGhe4/ZUm4lgyBvb2xfuNHqL5Lhqelwmil6EQxb -Oh3Y7XkfOjyFln89TwlxZUJdAoGAJRMa4kta7EvBTeGZLjyltvsqhFTghX+vBSCC -ToBbYbbiHJgssXSPAylU4sD7nR3HPwuqM6VZip+OOMrm8oNXZpuPTce+xqTEq1vK -JvmPrG3RAFDLdMFZjqYSXhKnuGE60yv3Ol8EEbDwfB3XLQPBPYU56Jdy0xcPSE2f -dMJXEJ0CgYEAisZw0nXw6lFeYecu642EGuU0wv1O9i21p7eho9QwOcsoTl4Q9l+M -M8iBv+qTHO+D19l4JbkGvy2H2diKoYduUFACcuiFYs8fjrT+4Z6DyOQAQGAf6Ylw -BFbU15k6KbA9v4mZDfd1tY9x62L/XO55ZxYG+J+q0e26tEThgD8cEog= ------END RSA PRIVATE KEY----- diff --git a/components/engine/integration-cli/fixtures/notary/delgkey4.crt b/components/engine/integration-cli/fixtures/notary/delgkey4.crt deleted file mode 100644 index c8cbe46bdfa..00000000000 --- a/components/engine/integration-cli/fixtures/notary/delgkey4.crt +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDhTCCAm2gAwIBAgIJANae++ZkUEWMMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV -BAYTAlVTMQswCQYDVQQIEwJDQTEVMBMGA1UEBxMMU2FuRnJhbmNpc2NvMQ8wDQYD -VQQKEwZEb2NrZXIxEzARBgNVBAMTCmRlbGVnYXRpb24wHhcNMTYwOTI4MTc0ODQ5 -WhcNMjYwNjI4MTc0ODQ5WjBXMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFTAT -BgNVBAcTDFNhbkZyYW5jaXNjbzEPMA0GA1UEChMGRG9ja2VyMRMwEQYDVQQDEwpk -ZWxlZ2F0aW9uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqULAjgba -Y2I10WfqdmYnPfEqEe6iMDbzcgECb2xKafXcI4ltkQj1iO4zBTs0Ft9EzXFc5ZBh -pTjZrL6vrIa0y/CH2BiIHBJ0wRHx/40HXp4DSj3HZpVOlEMI3npRfBGNIBllUaRN -PWG7zL7DcKMIepBfPXyjBsxzH3yNiISq0W5hSiy+ImhSo3aipJUHHcp9Z9NgvpNC -3QvnxsGKRnECmDRDlxkq+FQu9Iqs/HWFYWgyfcsw+YTrWZq3qVnnqUouHO//c9PG -Ry3sZSDU97MwvkjvWys1e01Xvd3AbHx08YAsxih58i/OBKe81eD9NuZDP2KrjTxI -5xkXKhj6DV2NnQIDAQABo1QwUjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIF -oDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUDt95hiqbQvi0KcvZGAUu -VisnztQwDQYJKoZIhvcNAQELBQADggEBAGi7qHai7MWbfeu6SlXhzIP3AIMa8TMi -lp/+mvPUFPswIVqYJ71MAN8uA7CTH3z50a2vYupGeOEtZqVJeRf+xgOEpwycncxp -Qz6wc6TWPVIoT5q1Hqxw1RD2MyKL+Y+QBDYwFxFkthpDMlX48I9frcqoJUWFxBF2 -lnRr/cE7BbPE3sMbXV3wGPlH7+eUf+CgzXJo2HB6THzagyEgNrDiz/0rCQa1ipFd -mNU3D/U6BFGmJNxhvSOtXX9escg8yjr05YwwzokHS2K4jE0ZuJPBd50C/Rvo3Mf4 -0h7/2Q95e7d42zPe9WYPu2F8KTWsf4r+6ddhKrKhYzXIcTAfHIOiO+U= ------END CERTIFICATE----- diff --git a/components/engine/integration-cli/fixtures/notary/delgkey4.key b/components/engine/integration-cli/fixtures/notary/delgkey4.key deleted file mode 100644 index f473cc495a7..00000000000 --- a/components/engine/integration-cli/fixtures/notary/delgkey4.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAqULAjgbaY2I10WfqdmYnPfEqEe6iMDbzcgECb2xKafXcI4lt -kQj1iO4zBTs0Ft9EzXFc5ZBhpTjZrL6vrIa0y/CH2BiIHBJ0wRHx/40HXp4DSj3H -ZpVOlEMI3npRfBGNIBllUaRNPWG7zL7DcKMIepBfPXyjBsxzH3yNiISq0W5hSiy+ -ImhSo3aipJUHHcp9Z9NgvpNC3QvnxsGKRnECmDRDlxkq+FQu9Iqs/HWFYWgyfcsw -+YTrWZq3qVnnqUouHO//c9PGRy3sZSDU97MwvkjvWys1e01Xvd3AbHx08YAsxih5 -8i/OBKe81eD9NuZDP2KrjTxI5xkXKhj6DV2NnQIDAQABAoIBAGK0ZKnuYSiXux60 -5MvK4pOCsa/nY3mOcgVHhW4IzpRgJdIrcFOlz9ncXrBsSAIWjX7o3u2Ydvjs4DOW -t8d6frB3QiDInYcRVDjLCD6otWV97Bk9Ua0G4N4hAWkMF7ysV4oihS1JDSoAdo39 -qOdki6s9yeyHZGKwk2oHLlowU5TxQMBA8DHmxqBII1HTm+8xRz45bcEqRXydYSUn -P1JuSU9jFqdylxU+Nrq6ehslMQ3y7qNWQyiLGxu6EmR+vgrzSU0s3iAOqCHthaOS -VBBXPL3DNEYUS+0QGnGrACuJhanOMBfdiO6Orelx6ZzWZm38PNGv0yBt0WCM+8/A -TtQNGkECgYEA1LqR6AH9XikUQ0+rM4526BgVuYqtjw21h4Lj9alaA+YTQntBBJOv -iAcUpnJiV4T8jzAMLeqpK8R/rbxRnK5S9jOV2gr+puk4L6tH46cgahBUESDigDp8 -6vK8ur6ubBcXNPh3AT6rsPj+Ph2EU3raqiYdouvCdga/OCYZb+jr6UkCgYEAy7Cr -l8WssI/8/ORcQ4MFJFNyfz/Y2beNXyLd1PX0H+wRSiGcKzeUuTHNtzFFpMbrK/nx -ZOPCT2ROdHsBHzp1L+WquCb0fyMVSiYiXBU+VCFDbUU5tBr3ycTc7VwuFPENOiha -IdlWgew/aW110FQHIaqe9g+htRe+mXe++faZtbUCgYB/MSJmNzJX53XvHSZ/CBJ+ -iVAMBSfq3caJRLCqRNzGcf1YBbwFUYxlZ95n+wJj0+byckcF+UW3HqE8rtmZNf3y -qTtTCLnj8JQgpGeybU4LPMIXD7N9+fqQvBwuCC7gABpnGJyHCQK9KNNTLnDdPRqb -G3ki3ZYC3dvdZaJV8E2FyQKBgQCMa5Mf4kqWvezueo+QizZ0QILibqWUEhIH0AWV -1qkhiKCytlDvCjYhJdBnxjP40Jk3i+t6XfmKud/MNTAk0ywOhQoYQeKz8v+uSnPN -f2ekn/nXzq1lGGJSWsDjcXTjQvqXaVIZm7cjgjaE+80IfaUc9H75qvUT3vaq3f5u -XC7DMQKBgQDMAzCCpWlEPbZoFMl6F49+7jG0/TiqM/WRUSQnNtufPMbrR9Je4QM1 -L1UCANCPaHFOncKYer15NfIV1ctt5MZKImevDsUaQO8CUlO+dzd5H8KvHw9E29gA -B22v8k3jIjsYeRL+UJ/sBnWHgxdAe/NEM+TdlP2oP9D1gTifutPqAg== ------END RSA PRIVATE KEY----- diff --git a/components/engine/integration-cli/fixtures/notary/gen.sh b/components/engine/integration-cli/fixtures/notary/gen.sh deleted file mode 100755 index 8d6381cec4c..00000000000 --- a/components/engine/integration-cli/fixtures/notary/gen.sh +++ /dev/null @@ -1,18 +0,0 @@ -for selfsigned in delgkey1 delgkey2 delgkey3 delgkey4; do - subj='/C=US/ST=CA/L=SanFrancisco/O=Docker/CN=delegation' - - openssl genrsa -out "${selfsigned}.key" 2048 - openssl req -new -key "${selfsigned}.key" -out "${selfsigned}.csr" -sha256 -subj "${subj}" - cat > "${selfsigned}.cnf" < Date: Fri, 30 Mar 2018 13:10:02 +0200 Subject: [PATCH 29/36] Migrate test-integration-cli experimental build tests to integration All `docker build` tests that require an `ExperimentalDaemon` are migrated to `integration/build` package and start an experimental daemon to test on it. The end goal being to remove the `experimental` builds. Signed-off-by: Vincent Demeester (cherry picked from commit 183076e89df64928bd2e94ad0da9725b482367cd) Signed-off-by: Sebastiaan van Stijn --- .../integration-cli/docker_api_build_test.go | 103 -------------- .../integration-cli/docker_cli_build_test.go | 70 ---------- .../integration/build/build_session_test.go | 132 ++++++++++++++++++ .../integration/build/build_squash_test.go | 108 ++++++++++++++ 4 files changed, 240 insertions(+), 173 deletions(-) create mode 100644 components/engine/integration/build/build_session_test.go create mode 100644 components/engine/integration/build/build_squash_test.go diff --git a/components/engine/integration-cli/docker_api_build_test.go b/components/engine/integration-cli/docker_api_build_test.go index cae7c1afe74..93469f1d47b 100644 --- a/components/engine/integration-cli/docker_api_build_test.go +++ b/components/engine/integration-cli/docker_api_build_test.go @@ -20,10 +20,7 @@ import ( "github.com/go-check/check" "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" - "github.com/moby/buildkit/session" - "github.com/moby/buildkit/session/filesync" "golang.org/x/net/context" - "golang.org/x/sync/errgroup" ) func (s *DockerSuite) TestBuildAPIDockerFileRemote(c *check.C) { @@ -515,106 +512,6 @@ ADD file /file` } } -func (s *DockerSuite) TestBuildWithSession(c *check.C) { - testRequires(c, ExperimentalDaemon) - - dockerfile := ` - FROM busybox - COPY file / - RUN cat /file - ` - - fctx := fakecontext.New(c, "", - fakecontext.WithFile("file", "some content"), - ) - defer fctx.Close() - - out := testBuildWithSession(c, fctx.Dir, dockerfile) - assert.Check(c, is.Contains(out, "some content")) - - fctx.Add("second", "contentcontent") - - dockerfile += ` - COPY second / - RUN cat /second - ` - - out = testBuildWithSession(c, fctx.Dir, dockerfile) - assert.Check(c, is.Equal(strings.Count(out, "Using cache"), 2)) - assert.Check(c, is.Contains(out, "contentcontent")) - - client := testEnv.APIClient() - du, err := client.DiskUsage(context.TODO()) - assert.Check(c, err) - assert.Check(c, du.BuilderSize > 10) - - out = testBuildWithSession(c, fctx.Dir, dockerfile) - assert.Check(c, is.Equal(strings.Count(out, "Using cache"), 4)) - - du2, err := client.DiskUsage(context.TODO()) - assert.Check(c, err) - assert.Check(c, is.Equal(du.BuilderSize, du2.BuilderSize)) - - // rebuild with regular tar, confirm cache still applies - fctx.Add("Dockerfile", dockerfile) - res, body, err := request.Post( - "/build", - request.RawContent(fctx.AsTarReader(c)), - request.ContentType("application/x-tar")) - assert.NilError(c, err) - assert.Check(c, is.DeepEqual(http.StatusOK, res.StatusCode)) - - outBytes, err := request.ReadBody(body) - assert.NilError(c, err) - assert.Check(c, is.Contains(string(outBytes), "Successfully built")) - assert.Check(c, is.Equal(strings.Count(string(outBytes), "Using cache"), 4)) - - _, err = client.BuildCachePrune(context.TODO()) - assert.Check(c, err) - - du, err = client.DiskUsage(context.TODO()) - assert.Check(c, err) - assert.Check(c, is.Equal(du.BuilderSize, int64(0))) -} - -func testBuildWithSession(c *check.C, dir, dockerfile string) (outStr string) { - client := testEnv.APIClient() - sess, err := session.NewSession("foo1", "foo") - assert.Check(c, err) - - fsProvider := filesync.NewFSSyncProvider([]filesync.SyncedDir{ - {Dir: dir}, - }) - sess.Allow(fsProvider) - - g, ctx := errgroup.WithContext(context.Background()) - - g.Go(func() error { - return sess.Run(ctx, client.DialSession) - }) - - g.Go(func() error { - res, body, err := request.Post("/build?remote=client-session&session="+sess.ID(), func(req *http.Request) error { - req.Body = ioutil.NopCloser(strings.NewReader(dockerfile)) - return nil - }) - if err != nil { - return err - } - assert.Check(c, is.DeepEqual(res.StatusCode, http.StatusOK)) - out, err := request.ReadBody(body) - assert.NilError(c, err) - assert.Check(c, is.Contains(string(out), "Successfully built")) - sess.Close() - outStr = string(out) - return nil - }) - - err = g.Wait() - assert.Check(c, err) - return -} - func (s *DockerSuite) TestBuildScratchCopy(c *check.C) { testRequires(c, DaemonIsLinux) dockerfile := `FROM scratch diff --git a/components/engine/integration-cli/docker_cli_build_test.go b/components/engine/integration-cli/docker_cli_build_test.go index 1e29c53907c..030f386c418 100644 --- a/components/engine/integration-cli/docker_cli_build_test.go +++ b/components/engine/integration-cli/docker_cli_build_test.go @@ -5598,46 +5598,6 @@ func (s *DockerSuite) TestBuildWithExtraHostInvalidFormat(c *check.C) { } -func (s *DockerSuite) TestBuildSquashParent(c *check.C) { - testRequires(c, ExperimentalDaemon) - dockerFile := ` - FROM busybox - RUN echo hello > /hello - RUN echo world >> /hello - RUN echo hello > /remove_me - ENV HELLO world - RUN rm /remove_me - ` - // build and get the ID that we can use later for history comparison - name := "test" - buildImageSuccessfully(c, name, build.WithDockerfile(dockerFile)) - origID := getIDByName(c, name) - - // build with squash - buildImageSuccessfully(c, name, cli.WithFlags("--squash"), build.WithDockerfile(dockerFile)) - id := getIDByName(c, name) - - out, _ := dockerCmd(c, "run", "--rm", id, "/bin/sh", "-c", "cat /hello") - c.Assert(strings.TrimSpace(out), checker.Equals, "hello\nworld") - - dockerCmd(c, "run", "--rm", id, "/bin/sh", "-c", "[ ! -f /remove_me ]") - dockerCmd(c, "run", "--rm", id, "/bin/sh", "-c", `[ "$(echo $HELLO)" == "world" ]`) - - // make sure the ID produced is the ID of the tag we specified - inspectID := inspectImage(c, "test", ".ID") - c.Assert(inspectID, checker.Equals, id) - - origHistory, _ := dockerCmd(c, "history", origID) - testHistory, _ := dockerCmd(c, "history", "test") - - splitOrigHistory := strings.Split(strings.TrimSpace(origHistory), "\n") - splitTestHistory := strings.Split(strings.TrimSpace(testHistory), "\n") - c.Assert(len(splitTestHistory), checker.Equals, len(splitOrigHistory)+1) - - out = inspectImage(c, id, "len .RootFS.Layers") - c.Assert(strings.TrimSpace(out), checker.Equals, "2") -} - func (s *DockerSuite) TestBuildContChar(c *check.C) { name := "testbuildcontchar" @@ -6237,33 +6197,3 @@ func (s *DockerSuite) TestBuildIidFileCleanupOnFail(c *check.C) { c.Assert(err, check.NotNil) c.Assert(os.IsNotExist(err), check.Equals, true) } - -// FIXME(vdemeester) should migrate to docker/cli tests -func (s *DockerSuite) TestBuildIidFileSquash(c *check.C) { - testRequires(c, ExperimentalDaemon) - tmpDir, err := ioutil.TempDir("", "TestBuildIidFileSquash") - if err != nil { - c.Fatal(err) - } - defer os.RemoveAll(tmpDir) - tmpIidFile := filepath.Join(tmpDir, "iidsquash") - - name := "testbuildiidfilesquash" - // Use a Dockerfile with multiple stages to ensure we get the last one - cli.BuildCmd(c, name, - // This could be minimalBaseImage except - // https://github.com/moby/moby/issues/33823 requires - // `touch` to workaround. - build.WithDockerfile(`FROM busybox -ENV FOO FOO -ENV BAR BAR -RUN touch /foop -`), - cli.WithFlags("--iidfile", tmpIidFile, "--squash")) - - id, err := ioutil.ReadFile(tmpIidFile) - c.Assert(err, check.IsNil) - d, err := digest.Parse(string(id)) - c.Assert(err, check.IsNil) - c.Assert(d.String(), checker.Equals, getIDByName(c, name)) -} diff --git a/components/engine/integration/build/build_session_test.go b/components/engine/integration/build/build_session_test.go new file mode 100644 index 00000000000..1fde6a0f9aa --- /dev/null +++ b/components/engine/integration/build/build_session_test.go @@ -0,0 +1,132 @@ +package build + +import ( + "context" + "io/ioutil" + "net/http" + "strings" + "testing" + + dclient "github.com/docker/docker/client" + "github.com/docker/docker/integration-cli/cli/build/fakecontext" + "github.com/docker/docker/integration-cli/daemon" + "github.com/docker/docker/integration-cli/request" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" + "github.com/moby/buildkit/session" + "github.com/moby/buildkit/session/filesync" + "golang.org/x/sync/errgroup" +) + +func TestBuildWithSession(t *testing.T) { + d := daemon.New(t, "", "dockerd", daemon.Config{ + Experimental: true, + }) + d.StartWithBusybox(t) + defer d.Stop(t) + + client, err := d.NewClient() + assert.NilError(t, err) + + dockerfile := ` + FROM busybox + COPY file / + RUN cat /file + ` + + fctx := fakecontext.New(t, "", + fakecontext.WithFile("file", "some content"), + ) + defer fctx.Close() + + out := testBuildWithSession(t, client, d.Sock(), fctx.Dir, dockerfile) + assert.Check(t, is.Contains(out, "some content")) + + fctx.Add("second", "contentcontent") + + dockerfile += ` + COPY second / + RUN cat /second + ` + + out = testBuildWithSession(t, client, d.Sock(), fctx.Dir, dockerfile) + assert.Check(t, is.Equal(strings.Count(out, "Using cache"), 2)) + assert.Check(t, is.Contains(out, "contentcontent")) + + du, err := client.DiskUsage(context.TODO()) + assert.Check(t, err) + assert.Check(t, du.BuilderSize > 10) + + out = testBuildWithSession(t, client, d.Sock(), fctx.Dir, dockerfile) + assert.Check(t, is.Equal(strings.Count(out, "Using cache"), 4)) + + du2, err := client.DiskUsage(context.TODO()) + assert.Check(t, err) + assert.Check(t, is.Equal(du.BuilderSize, du2.BuilderSize)) + + // rebuild with regular tar, confirm cache still applies + fctx.Add("Dockerfile", dockerfile) + // FIXME(vdemeester) use sock here + res, body, err := request.DoOnHost(d.Sock(), + "/build", + request.Method(http.MethodPost), + request.RawContent(fctx.AsTarReader(t)), + request.ContentType("application/x-tar")) + assert.NilError(t, err) + assert.Check(t, is.DeepEqual(http.StatusOK, res.StatusCode)) + + outBytes, err := request.ReadBody(body) + assert.NilError(t, err) + assert.Check(t, is.Contains(string(outBytes), "Successfully built")) + assert.Check(t, is.Equal(strings.Count(string(outBytes), "Using cache"), 4)) + + _, err = client.BuildCachePrune(context.TODO()) + assert.Check(t, err) + + du, err = client.DiskUsage(context.TODO()) + assert.Check(t, err) + assert.Check(t, is.Equal(du.BuilderSize, int64(0))) +} + +func testBuildWithSession(t *testing.T, client dclient.APIClient, daemonSock string, dir, dockerfile string) (outStr string) { + sess, err := session.NewSession("foo1", "foo") + assert.Check(t, err) + + fsProvider := filesync.NewFSSyncProvider([]filesync.SyncedDir{ + {Dir: dir}, + }) + sess.Allow(fsProvider) + + g, ctx := errgroup.WithContext(context.Background()) + + g.Go(func() error { + return sess.Run(ctx, client.DialSession) + }) + + g.Go(func() error { + // FIXME use sock here + res, body, err := request.DoOnHost( + daemonSock, + "/build?remote=client-session&session="+sess.ID(), + request.Method(http.MethodPost), + func(req *http.Request) error { + req.Body = ioutil.NopCloser(strings.NewReader(dockerfile)) + return nil + }, + ) + if err != nil { + return err + } + assert.Check(t, is.DeepEqual(res.StatusCode, http.StatusOK)) + out, err := request.ReadBody(body) + assert.NilError(t, err) + assert.Check(t, is.Contains(string(out), "Successfully built")) + sess.Close() + outStr = string(out) + return nil + }) + + err = g.Wait() + assert.Check(t, err) + return +} diff --git a/components/engine/integration/build/build_squash_test.go b/components/engine/integration/build/build_squash_test.go new file mode 100644 index 00000000000..7f264f14773 --- /dev/null +++ b/components/engine/integration/build/build_squash_test.go @@ -0,0 +1,108 @@ +package build + +import ( + "bytes" + "context" + "io" + "io/ioutil" + "strings" + "testing" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/integration-cli/cli/build/fakecontext" + "github.com/docker/docker/integration-cli/daemon" + "github.com/docker/docker/integration/internal/container" + "github.com/docker/docker/pkg/stdcopy" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" +) + +func TestBuildSquashParent(t *testing.T) { + d := daemon.New(t, "", "dockerd", daemon.Config{ + Experimental: true, + }) + d.StartWithBusybox(t) + defer d.Stop(t) + + client, err := d.NewClient() + assert.NilError(t, err) + + dockerfile := ` + FROM busybox + RUN echo hello > /hello + RUN echo world >> /hello + RUN echo hello > /remove_me + ENV HELLO world + RUN rm /remove_me + ` + + // build and get the ID that we can use later for history comparison + ctx := context.Background() + source := fakecontext.New(t, "", fakecontext.WithDockerfile(dockerfile)) + defer source.Close() + + name := "test" + resp, err := client.ImageBuild(ctx, + source.AsTarReader(t), + types.ImageBuildOptions{ + Remove: true, + ForceRemove: true, + Tags: []string{name}, + }) + assert.NilError(t, err) + _, err = io.Copy(ioutil.Discard, resp.Body) + resp.Body.Close() + assert.NilError(t, err) + + inspect, _, err := client.ImageInspectWithRaw(ctx, name) + assert.NilError(t, err) + origID := inspect.ID + + // build with squash + resp, err = client.ImageBuild(ctx, + source.AsTarReader(t), + types.ImageBuildOptions{ + Remove: true, + ForceRemove: true, + Squash: true, + Tags: []string{name}, + }) + assert.NilError(t, err) + _, err = io.Copy(ioutil.Discard, resp.Body) + resp.Body.Close() + assert.NilError(t, err) + + cid := container.Run(t, ctx, client, + container.WithImage(name), + container.WithCmd("/bin/sh", "-c", "cat /hello"), + ) + reader, err := client.ContainerLogs(ctx, cid, types.ContainerLogsOptions{ + ShowStdout: true, + }) + assert.NilError(t, err) + + actualStdout := new(bytes.Buffer) + actualStderr := ioutil.Discard + _, err = stdcopy.StdCopy(actualStdout, actualStderr, reader) + assert.NilError(t, err) + assert.Check(t, is.Equal(strings.TrimSpace(actualStdout.String()), "hello\nworld")) + + container.Run(t, ctx, client, + container.WithImage(name), + container.WithCmd("/bin/sh", "-c", "[ ! -f /remove_me ]"), + ) + container.Run(t, ctx, client, + container.WithImage(name), + container.WithCmd("/bin/sh", "-c", `[ "$(echo $HELLO)" == "world" ]`), + ) + + origHistory, err := client.ImageHistory(ctx, origID) + assert.NilError(t, err) + testHistory, err := client.ImageHistory(ctx, name) + assert.NilError(t, err) + + inspect, _, err = client.ImageInspectWithRaw(ctx, name) + assert.NilError(t, err) + assert.Check(t, is.Len(testHistory, len(origHistory)+1)) + assert.Check(t, is.Len(inspect.RootFS.Layers, 2)) +} From 49acaa1f039bdcaffa3714939b9c5b7c1839eae5 Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Fri, 13 Apr 2018 17:02:56 +0200 Subject: [PATCH 30/36] Small daemon refactoring and add swarm init/join helpers Signed-off-by: Vincent Demeester (cherry picked from commit 239a8a518904dfb51fe62087d8702519c20ce808) Signed-off-by: Sebastiaan van Stijn --- .../engine/integration-cli/check_test.go | 45 ++++++------------- .../engine/integration-cli/daemon/daemon.go | 11 +---- .../integration-cli/docker_cli_daemon_test.go | 23 +++------- ...cker_cli_external_graphdriver_unix_test.go | 5 +-- ...er_cli_external_volume_driver_unix_test.go | 5 +-- .../integration-cli/docker_cli_info_test.go | 21 +++------ .../docker_cli_network_unix_test.go | 5 +-- .../docker_cli_plugins_test.go | 2 +- .../docker_hub_pull_suite_test.go | 5 +-- .../integration/build/build_session_test.go | 6 +-- .../integration/build/build_squash_test.go | 6 +-- .../engine/integration/config/config_test.go | 20 ++++----- .../integration/internal/swarm/service.go | 23 +++------- .../integration/network/inspect_test.go | 4 +- .../integration/network/ipvlan/ipvlan_test.go | 10 ++--- .../integration/network/service_test.go | 9 ++-- .../engine/integration/secret/secret_test.go | 26 +++++------ .../engine/integration/service/create_test.go | 16 +++---- .../integration/service/inspect_test.go | 4 +- .../integration/service/network_test.go | 7 ++- components/engine/internal/test/daemon/ops.go | 11 +++++ .../engine/internal/test/daemon/service.go | 6 +-- .../engine/internal/test/daemon/swarm.go | 26 +++++++++++ 23 files changed, 129 insertions(+), 167 deletions(-) diff --git a/components/engine/integration-cli/check_test.go b/components/engine/integration-cli/check_test.go index de1b3c65c01..e9d1d5d2c08 100644 --- a/components/engine/integration-cli/check_test.go +++ b/components/engine/integration-cli/check_test.go @@ -13,7 +13,6 @@ import ( "testing" "time" - "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/cli" "github.com/docker/docker/integration-cli/cli/build/fakestorage" @@ -129,9 +128,7 @@ func (s *DockerRegistrySuite) SetUpTest(c *check.C) { testRequires(c, DaemonIsLinux, RegistryHosting, SameHostDaemon) s.reg = registry.NewV2(c) s.reg.WaitReady(c) - s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }) + s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) } func (s *DockerRegistrySuite) TearDownTest(c *check.C) { @@ -164,9 +161,7 @@ func (s *DockerSchema1RegistrySuite) SetUpTest(c *check.C) { testRequires(c, DaemonIsLinux, RegistryHosting, NotArm64, SameHostDaemon) s.reg = registry.NewV2(c, registry.Schema1) s.reg.WaitReady(c) - s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }) + s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) } func (s *DockerSchema1RegistrySuite) TearDownTest(c *check.C) { @@ -199,9 +194,7 @@ func (s *DockerRegistryAuthHtpasswdSuite) SetUpTest(c *check.C) { testRequires(c, DaemonIsLinux, RegistryHosting, SameHostDaemon) s.reg = registry.NewV2(c, registry.Htpasswd) s.reg.WaitReady(c) - s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }) + s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) } func (s *DockerRegistryAuthHtpasswdSuite) TearDownTest(c *check.C) { @@ -234,9 +227,7 @@ func (s *DockerRegistryAuthTokenSuite) OnTimeout(c *check.C) { func (s *DockerRegistryAuthTokenSuite) SetUpTest(c *check.C) { testRequires(c, DaemonIsLinux, RegistryHosting, SameHostDaemon) - s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }) + s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) } func (s *DockerRegistryAuthTokenSuite) TearDownTest(c *check.C) { @@ -276,9 +267,7 @@ func (s *DockerDaemonSuite) OnTimeout(c *check.C) { func (s *DockerDaemonSuite) SetUpTest(c *check.C) { testRequires(c, DaemonIsLinux, SameHostDaemon) - s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }) + s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) } func (s *DockerDaemonSuite) TearDownTest(c *check.C) { @@ -333,26 +322,18 @@ func (s *DockerSwarmSuite) SetUpTest(c *check.C) { } func (s *DockerSwarmSuite) AddDaemon(c *check.C, joinSwarm, manager bool) *daemon.Daemon { - d := daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }, testdaemon.WithSwarmPort(defaultSwarmPort+s.portIndex)) - args := []string{"--iptables=false", "--swarm-default-advertise-addr=lo"} // avoid networking conflicts - d.StartWithBusybox(c, args...) - + d := daemon.New(c, dockerBinary, dockerdBinary, + testdaemon.WithEnvironment(testEnv.Execution), + testdaemon.WithSwarmPort(defaultSwarmPort+s.portIndex), + ) if joinSwarm { if len(s.daemons) > 0 { - tokens := s.daemons[0].JoinTokens(c) - token := tokens.Worker - if manager { - token = tokens.Manager - } - d.SwarmJoin(c, swarm.JoinRequest{ - RemoteAddrs: []string{s.daemons[0].SwarmListenAddr()}, - JoinToken: token, - }) + d.StartAndSwarmJoin(c, s.daemons[0].Daemon, manager) } else { - d.SwarmInit(c, swarm.InitRequest{}) + d.StartAndSwarmInit(c) } + } else { + d.StartWithBusybox(c, "--iptables=false", "--swarm-default-advertise-addr=lo") } s.portIndex++ diff --git a/components/engine/integration-cli/daemon/daemon.go b/components/engine/integration-cli/daemon/daemon.go index 0ec9e892b22..3087416ee07 100644 --- a/components/engine/integration-cli/daemon/daemon.go +++ b/components/engine/integration-cli/daemon/daemon.go @@ -30,21 +30,12 @@ type Daemon struct { dockerBinary string } -// Config holds docker daemon integration configuration -type Config struct { - Experimental bool -} - // New returns a Daemon instance to be used for testing. // This will create a directory such as d123456789 in the folder specified by $DOCKER_INTEGRATION_DAEMON_DEST or $DEST. // The daemon will not automatically start. -func New(t testingT, dockerBinary string, dockerdBinary string, config Config, ops ...func(*daemon.Daemon)) *Daemon { +func New(t testingT, dockerBinary string, dockerdBinary string, ops ...func(*daemon.Daemon)) *Daemon { ops = append(ops, daemon.WithDockerdBinary(dockerdBinary)) - if config.Experimental { - ops = append(ops, daemon.WithExperimental) - } d := daemon.New(t, ops...) - return &Daemon{ Daemon: d, dockerBinary: dockerBinary, diff --git a/components/engine/integration-cli/docker_cli_daemon_test.go b/components/engine/integration-cli/docker_cli_daemon_test.go index 2646de3fb77..975f06d2b4d 100644 --- a/components/engine/integration-cli/docker_cli_daemon_test.go +++ b/components/engine/integration-cli/docker_cli_daemon_test.go @@ -32,6 +32,7 @@ import ( "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/cli" "github.com/docker/docker/integration-cli/daemon" + testdaemon "github.com/docker/docker/internal/test/daemon" "github.com/docker/docker/opts" "github.com/docker/docker/pkg/mount" "github.com/docker/docker/pkg/stringid" @@ -1432,9 +1433,7 @@ func (s *DockerDaemonSuite) TestDaemonRestartWithSocketAsVolume(c *check.C) { // os.Kill should kill daemon ungracefully, leaving behind container mounts. // A subsequent daemon restart should clean up said mounts. func (s *DockerDaemonSuite) TestCleanupMountsAfterDaemonAndContainerKill(c *check.C) { - d := daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }) + d := daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) d.StartWithBusybox(c) out, err := d.Cmd("run", "-d", "busybox", "top") @@ -1472,9 +1471,7 @@ func (s *DockerDaemonSuite) TestCleanupMountsAfterDaemonAndContainerKill(c *chec // os.Interrupt should perform a graceful daemon shutdown and hence cleanup mounts. func (s *DockerDaemonSuite) TestCleanupMountsAfterGracefulShutdown(c *check.C) { - d := daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }) + d := daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) d.StartWithBusybox(c) out, err := d.Cmd("run", "-d", "busybox", "top") @@ -1693,9 +1690,7 @@ func (s *DockerDaemonSuite) TestDaemonRestartLocalVolumes(c *check.C) { // FIXME(vdemeester) should be a unit test func (s *DockerDaemonSuite) TestDaemonCorruptedLogDriverAddress(c *check.C) { - d := daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }) + d := daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) c.Assert(d.StartWithError("--log-driver=syslog", "--log-opt", "syslog-address=corrupted:42"), check.NotNil) expected := "syslog-address should be in form proto://address" icmd.RunCommand("grep", expected, d.LogFileName()).Assert(c, icmd.Success) @@ -1703,9 +1698,7 @@ func (s *DockerDaemonSuite) TestDaemonCorruptedLogDriverAddress(c *check.C) { // FIXME(vdemeester) should be a unit test func (s *DockerDaemonSuite) TestDaemonCorruptedFluentdAddress(c *check.C) { - d := daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }) + d := daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) c.Assert(d.StartWithError("--log-driver=fluentd", "--log-opt", "fluentd-address=corrupted:c"), check.NotNil) expected := "invalid fluentd-address corrupted:c: " icmd.RunCommand("grep", expected, d.LogFileName()).Assert(c, icmd.Success) @@ -3080,9 +3073,7 @@ func (s *DockerDaemonSuite) TestDaemonIpcModeShareableFromConfig(c *check.C) { } func testDaemonStartIpcMode(c *check.C, from, mode string, valid bool) { - d := daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }) + d := daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) c.Logf("Checking IpcMode %s set from %s\n", mode, from) var serr error switch from { @@ -3183,7 +3174,7 @@ func (s *DockerDaemonSuite) TestDaemonRestartIpcMode(c *check.C) { // the daemon from starting func (s *DockerDaemonSuite) TestFailedPluginRemove(c *check.C) { testRequires(c, DaemonIsLinux, IsAmd64, SameHostDaemon) - d := daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{}) + d := daemon.New(c, dockerBinary, dockerdBinary) d.Start(c) cli, err := client.NewClient(d.Sock(), api.DefaultVersion, nil, nil) c.Assert(err, checker.IsNil) diff --git a/components/engine/integration-cli/docker_cli_external_graphdriver_unix_test.go b/components/engine/integration-cli/docker_cli_external_graphdriver_unix_test.go index e356154049b..a52e58b2d26 100644 --- a/components/engine/integration-cli/docker_cli_external_graphdriver_unix_test.go +++ b/components/engine/integration-cli/docker_cli_external_graphdriver_unix_test.go @@ -15,6 +15,7 @@ import ( "github.com/docker/docker/daemon/graphdriver" "github.com/docker/docker/daemon/graphdriver/vfs" "github.com/docker/docker/integration-cli/daemon" + testdaemon "github.com/docker/docker/internal/test/daemon" "github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/plugins" "github.com/go-check/check" @@ -52,9 +53,7 @@ type graphEventsCounter struct { } func (s *DockerExternalGraphdriverSuite) SetUpTest(c *check.C) { - s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }) + s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) } func (s *DockerExternalGraphdriverSuite) OnTimeout(c *check.C) { diff --git a/components/engine/integration-cli/docker_cli_external_volume_driver_unix_test.go b/components/engine/integration-cli/docker_cli_external_volume_driver_unix_test.go index ff3d50fb034..1553abda287 100644 --- a/components/engine/integration-cli/docker_cli_external_volume_driver_unix_test.go +++ b/components/engine/integration-cli/docker_cli_external_volume_driver_unix_test.go @@ -18,6 +18,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/daemon" + testdaemon "github.com/docker/docker/internal/test/daemon" "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/volume" "github.com/go-check/check" @@ -51,9 +52,7 @@ type DockerExternalVolumeSuite struct { func (s *DockerExternalVolumeSuite) SetUpTest(c *check.C) { testRequires(c, SameHostDaemon) - s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }) + s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) s.ec = &eventCounter{} } diff --git a/components/engine/integration-cli/docker_cli_info_test.go b/components/engine/integration-cli/docker_cli_info_test.go index 35a2532196a..65091029eec 100644 --- a/components/engine/integration-cli/docker_cli_info_test.go +++ b/components/engine/integration-cli/docker_cli_info_test.go @@ -8,6 +8,7 @@ import ( "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/daemon" + testdaemon "github.com/docker/docker/internal/test/daemon" "github.com/go-check/check" ) @@ -71,9 +72,7 @@ func (s *DockerSuite) TestInfoFormat(c *check.C) { func (s *DockerSuite) TestInfoDiscoveryBackend(c *check.C) { testRequires(c, SameHostDaemon, DaemonIsLinux) - d := daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }) + d := daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) discoveryBackend := "consul://consuladdr:consulport/some/path" discoveryAdvertise := "1.1.1.1:2375" d.Start(c, fmt.Sprintf("--cluster-store=%s", discoveryBackend), fmt.Sprintf("--cluster-advertise=%s", discoveryAdvertise)) @@ -90,9 +89,7 @@ func (s *DockerSuite) TestInfoDiscoveryBackend(c *check.C) { func (s *DockerSuite) TestInfoDiscoveryInvalidAdvertise(c *check.C) { testRequires(c, SameHostDaemon, DaemonIsLinux) - d := daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }) + d := daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) discoveryBackend := "consul://consuladdr:consulport/some/path" // --cluster-advertise with an invalid string is an error @@ -109,9 +106,7 @@ func (s *DockerSuite) TestInfoDiscoveryInvalidAdvertise(c *check.C) { func (s *DockerSuite) TestInfoDiscoveryAdvertiseInterfaceName(c *check.C) { testRequires(c, SameHostDaemon, Network, DaemonIsLinux) - d := daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }) + d := daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) discoveryBackend := "consul://consuladdr:consulport/some/path" discoveryAdvertise := "eth0" @@ -182,9 +177,7 @@ func (s *DockerSuite) TestInfoDisplaysStoppedContainers(c *check.C) { func (s *DockerSuite) TestInfoDebug(c *check.C) { testRequires(c, SameHostDaemon, DaemonIsLinux) - d := daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }) + d := daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) d.Start(c, "--debug") defer d.Stop(c) @@ -205,9 +198,7 @@ func (s *DockerSuite) TestInsecureRegistries(c *check.C) { registryCIDR := "192.168.1.0/24" registryHost := "insecurehost.com:5000" - d := daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }) + d := daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) d.Start(c, "--insecure-registry="+registryCIDR, "--insecure-registry="+registryHost) defer d.Stop(c) diff --git a/components/engine/integration-cli/docker_cli_network_unix_test.go b/components/engine/integration-cli/docker_cli_network_unix_test.go index 4e9edba5a5b..cb0f39a7604 100644 --- a/components/engine/integration-cli/docker_cli_network_unix_test.go +++ b/components/engine/integration-cli/docker_cli_network_unix_test.go @@ -18,6 +18,7 @@ import ( "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/cli" "github.com/docker/docker/integration-cli/daemon" + testdaemon "github.com/docker/docker/internal/test/daemon" "github.com/docker/docker/pkg/stringid" "github.com/docker/docker/runconfig" "github.com/docker/libnetwork/driverapi" @@ -49,9 +50,7 @@ type DockerNetworkSuite struct { } func (s *DockerNetworkSuite) SetUpTest(c *check.C) { - s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }) + s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) } func (s *DockerNetworkSuite) TearDownTest(c *check.C) { diff --git a/components/engine/integration-cli/docker_cli_plugins_test.go b/components/engine/integration-cli/docker_cli_plugins_test.go index 483222540bf..346a2cfed77 100644 --- a/components/engine/integration-cli/docker_cli_plugins_test.go +++ b/components/engine/integration-cli/docker_cli_plugins_test.go @@ -473,7 +473,7 @@ func (s *DockerSuite) TestPluginUpgrade(c *check.C) { func (s *DockerSuite) TestPluginMetricsCollector(c *check.C) { testRequires(c, DaemonIsLinux, Network, SameHostDaemon, IsAmd64) - d := daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{}) + d := daemon.New(c, dockerBinary, dockerdBinary) d.Start(c) defer d.Stop(c) diff --git a/components/engine/integration-cli/docker_hub_pull_suite_test.go b/components/engine/integration-cli/docker_hub_pull_suite_test.go index a8d6aedad35..125b8c10aa7 100644 --- a/components/engine/integration-cli/docker_hub_pull_suite_test.go +++ b/components/engine/integration-cli/docker_hub_pull_suite_test.go @@ -7,6 +7,7 @@ import ( "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/daemon" + testdaemon "github.com/docker/docker/internal/test/daemon" "github.com/go-check/check" ) @@ -40,9 +41,7 @@ func newDockerHubPullSuite() *DockerHubPullSuite { // SetUpSuite starts the suite daemon. func (s *DockerHubPullSuite) SetUpSuite(c *check.C) { testRequires(c, DaemonIsLinux, SameHostDaemon) - s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{ - Experimental: testEnv.DaemonInfo.ExperimentalBuild, - }) + s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) s.d.Start(c) } diff --git a/components/engine/integration/build/build_session_test.go b/components/engine/integration/build/build_session_test.go index 1fde6a0f9aa..af1a5367699 100644 --- a/components/engine/integration/build/build_session_test.go +++ b/components/engine/integration/build/build_session_test.go @@ -9,8 +9,8 @@ import ( dclient "github.com/docker/docker/client" "github.com/docker/docker/integration-cli/cli/build/fakecontext" - "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/integration-cli/request" + "github.com/docker/docker/internal/test/daemon" "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/moby/buildkit/session" @@ -19,9 +19,7 @@ import ( ) func TestBuildWithSession(t *testing.T) { - d := daemon.New(t, "", "dockerd", daemon.Config{ - Experimental: true, - }) + d := daemon.New(t, daemon.WithExperimental) d.StartWithBusybox(t) defer d.Stop(t) diff --git a/components/engine/integration/build/build_squash_test.go b/components/engine/integration/build/build_squash_test.go index 7f264f14773..e8097fd811b 100644 --- a/components/engine/integration/build/build_squash_test.go +++ b/components/engine/integration/build/build_squash_test.go @@ -10,17 +10,15 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/integration-cli/cli/build/fakecontext" - "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/integration/internal/container" + "github.com/docker/docker/internal/test/daemon" "github.com/docker/docker/pkg/stdcopy" "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" ) func TestBuildSquashParent(t *testing.T) { - d := daemon.New(t, "", "dockerd", daemon.Config{ - Experimental: true, - }) + d := daemon.New(t, daemon.WithExperimental) d.StartWithBusybox(t) defer d.Stop(t) diff --git a/components/engine/integration/config/config_test.go b/components/engine/integration/config/config_test.go index 91cd7ff9bba..cff66093dfe 100644 --- a/components/engine/integration/config/config_test.go +++ b/components/engine/integration/config/config_test.go @@ -26,8 +26,8 @@ func TestConfigList(t *testing.T) { defer setupTest(t)() d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) - client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - assert.NilError(t, err) + client := d.NewClientT(t) + defer client.Close() ctx := context.Background() @@ -117,8 +117,8 @@ func TestConfigsCreateAndDelete(t *testing.T) { defer setupTest(t)() d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) - client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - assert.NilError(t, err) + client := d.NewClientT(t) + defer client.Close() ctx := context.Background() @@ -145,8 +145,8 @@ func TestConfigsUpdate(t *testing.T) { defer setupTest(t)() d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) - client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - assert.NilError(t, err) + client := d.NewClientT(t) + defer client.Close() ctx := context.Background() @@ -196,9 +196,9 @@ func TestConfigsUpdate(t *testing.T) { func TestTemplatedConfig(t *testing.T) { d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) - + client := d.NewClientT(t) + defer client.Close() ctx := context.Background() - client := swarm.GetClient(t, d) referencedSecretSpec := swarmtypes.SecretSpec{ Annotations: swarmtypes.Annotations{ @@ -335,8 +335,8 @@ func TestConfigInspect(t *testing.T) { defer setupTest(t)() d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) - client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - assert.NilError(t, err) + client := d.NewClientT(t) + defer client.Close() ctx := context.Background() diff --git a/components/engine/integration/internal/swarm/service.go b/components/engine/integration/internal/swarm/service.go index 031995f87a6..3f5032976be 100644 --- a/components/engine/integration/internal/swarm/service.go +++ b/components/engine/integration/internal/swarm/service.go @@ -9,7 +9,6 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" swarmtypes "github.com/docker/docker/api/types/swarm" - "github.com/docker/docker/client" "github.com/docker/docker/internal/test/daemon" "github.com/docker/docker/internal/test/environment" "github.com/gotestyourself/gotestyourself/assert" @@ -55,11 +54,7 @@ func NewSwarm(t *testing.T, testEnv *environment.Execution, ops ...func(*daemon. ops = append(ops, daemon.WithExperimental) } d := daemon.New(t, ops...) - // avoid networking conflicts - args := []string{"--iptables=false", "--swarm-default-advertise-addr=lo"} - d.StartWithBusybox(t, args...) - - d.SwarmInit(t, swarmtypes.InitRequest{}) + d.StartAndSwarmInit(t) return d } @@ -73,7 +68,8 @@ func CreateService(t *testing.T, d *daemon.Daemon, opts ...ServiceSpecOpt) strin o(&spec) } - client := GetClient(t, d) + client := d.NewClientT(t) + defer client.Close() resp, err := client.ServiceCreate(context.Background(), spec, types.ServiceCreateOptions{}) assert.NilError(t, err, "error creating service") @@ -140,7 +136,8 @@ func ServiceWithName(name string) ServiceSpecOpt { // GetRunningTasks gets the list of running tasks for a service func GetRunningTasks(t *testing.T, d *daemon.Daemon, serviceID string) []swarmtypes.Task { - client := GetClient(t, d) + client := d.NewClientT(t) + defer client.Close() filterArgs := filters.NewArgs() filterArgs.Add("desired-state", "running") @@ -156,7 +153,8 @@ func GetRunningTasks(t *testing.T, d *daemon.Daemon, serviceID string) []swarmty // ExecTask runs the passed in exec config on the given task func ExecTask(t *testing.T, d *daemon.Daemon, task swarmtypes.Task, config types.ExecConfig) types.HijackedResponse { - client := GetClient(t, d) + client := d.NewClientT(t) + defer client.Close() ctx := context.Background() resp, err := client.ContainerExecCreate(ctx, task.Status.ContainerStatus.ContainerID, config) @@ -173,10 +171,3 @@ func ensureContainerSpec(spec *swarmtypes.ServiceSpec) { spec.TaskTemplate.ContainerSpec = &swarmtypes.ContainerSpec{} } } - -// GetClient creates a new client for the passed in swarm daemon. -func GetClient(t *testing.T, d *daemon.Daemon) client.APIClient { - client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - assert.NilError(t, err) - return client -} diff --git a/components/engine/integration/network/inspect_test.go b/components/engine/integration/network/inspect_test.go index 3f23c61ae25..8142ecdef2f 100644 --- a/components/engine/integration/network/inspect_test.go +++ b/components/engine/integration/network/inspect_test.go @@ -20,8 +20,8 @@ func TestInspectNetwork(t *testing.T) { defer setupTest(t)() d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) - client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - assert.NilError(t, err) + client := d.NewClientT(t) + defer client.Close() overlayName := "overlay1" networkCreate := types.NetworkCreate{ diff --git a/components/engine/integration/network/ipvlan/ipvlan_test.go b/components/engine/integration/network/ipvlan/ipvlan_test.go index 9de78f41bb5..d42917db277 100644 --- a/components/engine/integration/network/ipvlan/ipvlan_test.go +++ b/components/engine/integration/network/ipvlan/ipvlan_test.go @@ -8,9 +8,9 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/network" dclient "github.com/docker/docker/client" - "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/integration/internal/container" n "github.com/docker/docker/integration/network" + "github.com/docker/docker/internal/test/daemon" "github.com/gotestyourself/gotestyourself/assert" "github.com/gotestyourself/gotestyourself/skip" "golang.org/x/net/context" @@ -22,9 +22,7 @@ func TestDockerNetworkIpvlanPersistance(t *testing.T) { skip.If(t, testEnv.IsRemoteDaemon()) skip.If(t, !ipvlanKernelSupport(), "Kernel doesn't support ipvlan") - d := daemon.New(t, "", "dockerd", daemon.Config{ - Experimental: true, - }) + d := daemon.New(t, daemon.WithExperimental) d.StartWithBusybox(t) defer d.Stop(t) @@ -88,9 +86,7 @@ func TestDockerNetworkIpvlan(t *testing.T) { test: testIpvlanAddressing, }, } { - d := daemon.New(t, "", "dockerd", daemon.Config{ - Experimental: true, - }) + d := daemon.New(t, daemon.WithExperimental) d.StartWithBusybox(t) client, err := d.NewClient() diff --git a/components/engine/integration/network/service_test.go b/components/engine/integration/network/service_test.go index 1b729d11570..937c0f169f7 100644 --- a/components/engine/integration/network/service_test.go +++ b/components/engine/integration/network/service_test.go @@ -17,8 +17,8 @@ func TestServiceWithPredefinedNetwork(t *testing.T) { defer setupTest(t)() d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) - client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - assert.NilError(t, err) + client := d.NewClientT(t) + defer client.Close() hostName := "host" var instances uint64 = 1 @@ -47,9 +47,8 @@ func TestServiceWithIngressNetwork(t *testing.T) { defer setupTest(t)() d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) - - client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - assert.NilError(t, err) + client := d.NewClientT(t) + defer client.Close() poll.WaitOn(t, swarmIngressReady(client), swarm.NetworkPoll) diff --git a/components/engine/integration/secret/secret_test.go b/components/engine/integration/secret/secret_test.go index 91f70c49277..873dbdc6b16 100644 --- a/components/engine/integration/secret/secret_test.go +++ b/components/engine/integration/secret/secret_test.go @@ -25,8 +25,8 @@ func TestSecretInspect(t *testing.T) { defer setupTest(t)() d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) - client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - assert.NilError(t, err) + client := d.NewClientT(t) + defer client.Close() ctx := context.Background() @@ -48,9 +48,8 @@ func TestSecretList(t *testing.T) { defer setupTest(t)() d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) - client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - assert.NilError(t, err) - + client := d.NewClientT(t) + defer client.Close() ctx := context.Background() testName0 := "test0" @@ -135,16 +134,15 @@ func TestSecretsCreateAndDelete(t *testing.T) { defer setupTest(t)() d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) - client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - assert.NilError(t, err) - + client := d.NewClientT(t) + defer client.Close() ctx := context.Background() testName := "test_secret" secretID := createSecret(ctx, t, client, testName, []byte("TESTINGDATA"), nil) // create an already existin secret, daemon should return a status code of 409 - _, err = client.SecretCreate(ctx, swarmtypes.SecretSpec{ + _, err := client.SecretCreate(ctx, swarmtypes.SecretSpec{ Annotations: swarmtypes.Annotations{ Name: testName, }, @@ -183,14 +181,12 @@ func TestSecretsUpdate(t *testing.T) { defer setupTest(t)() d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) - client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - assert.NilError(t, err) - + client := d.NewClientT(t) + defer client.Close() ctx := context.Background() testName := "test_secret" secretID := createSecret(ctx, t, client, testName, []byte("TESTINGDATA"), nil) - assert.NilError(t, err) insp, _, err := client.SecretInspectWithRaw(ctx, secretID) assert.NilError(t, err) @@ -233,9 +229,9 @@ func TestSecretsUpdate(t *testing.T) { func TestTemplatedSecret(t *testing.T) { d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) - + client := d.NewClientT(t) + defer client.Close() ctx := context.Background() - client := swarm.GetClient(t, d) referencedSecretSpec := swarmtypes.SecretSpec{ Annotations: swarmtypes.Annotations{ diff --git a/components/engine/integration/service/create_test.go b/components/engine/integration/service/create_test.go index 9522b059ef5..767d78b3685 100644 --- a/components/engine/integration/service/create_test.go +++ b/components/engine/integration/service/create_test.go @@ -20,8 +20,8 @@ func TestCreateServiceMultipleTimes(t *testing.T) { defer setupTest(t)() d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) - client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - assert.NilError(t, err) + client := d.NewClientT(t) + defer client.Close() overlayName := "overlay1" networkCreate := types.NetworkCreate{ @@ -78,8 +78,8 @@ func TestCreateWithDuplicateNetworkNames(t *testing.T) { defer setupTest(t)() d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) - client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - assert.NilError(t, err) + client := d.NewClientT(t) + defer client.Close() name := "foo" networkCreate := types.NetworkCreate{ @@ -140,8 +140,8 @@ func TestCreateServiceSecretFileMode(t *testing.T) { defer setupTest(t)() d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) - client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - assert.NilError(t, err) + client := d.NewClientT(t) + defer client.Close() ctx := context.Background() secretResp, err := client.SecretCreate(ctx, swarmtypes.SecretSpec{ @@ -221,8 +221,8 @@ func TestCreateServiceConfigFileMode(t *testing.T) { defer setupTest(t)() d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) - client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - assert.NilError(t, err) + client := d.NewClientT(t) + defer client.Close() ctx := context.Background() configResp, err := client.ConfigCreate(ctx, swarmtypes.ConfigSpec{ diff --git a/components/engine/integration/service/inspect_test.go b/components/engine/integration/service/inspect_test.go index d4d342e6439..e437f35888b 100644 --- a/components/engine/integration/service/inspect_test.go +++ b/components/engine/integration/service/inspect_test.go @@ -23,8 +23,8 @@ func TestInspect(t *testing.T) { defer setupTest(t)() d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) - client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - assert.NilError(t, err) + client := d.NewClientT(t) + defer client.Close() var now = time.Now() var instances uint64 = 2 diff --git a/components/engine/integration/service/network_test.go b/components/engine/integration/service/network_test.go index 6b8c891cd84..7db171a1253 100644 --- a/components/engine/integration/service/network_test.go +++ b/components/engine/integration/service/network_test.go @@ -6,7 +6,6 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/network" - "github.com/docker/docker/client" "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/swarm" "github.com/gotestyourself/gotestyourself/assert" @@ -17,12 +16,12 @@ func TestDockerNetworkConnectAlias(t *testing.T) { defer setupTest(t)() d := swarm.NewSwarm(t, testEnv) defer d.Stop(t) - client, err := client.NewClientWithOpts(client.WithHost((d.Sock()))) - assert.NilError(t, err) + client := d.NewClientT(t) + defer client.Close() ctx := context.Background() name := "test-alias" - _, err = client.NetworkCreate(ctx, name, types.NetworkCreate{ + _, err := client.NetworkCreate(ctx, name, types.NetworkCreate{ Driver: "overlay", Attachable: true, }) diff --git a/components/engine/internal/test/daemon/ops.go b/components/engine/internal/test/daemon/ops.go index 0176c19d93c..288fe880705 100644 --- a/components/engine/internal/test/daemon/ops.go +++ b/components/engine/internal/test/daemon/ops.go @@ -1,5 +1,7 @@ package daemon +import "github.com/docker/docker/internal/test/environment" + // WithExperimental sets the daemon in experimental mode func WithExperimental(d *Daemon) { d.experimental = true @@ -25,3 +27,12 @@ func WithSwarmListenAddr(listenAddr string) func(*Daemon) { d.swarmListenAddr = listenAddr } } + +// WithEnvironment sets options from internal/test/environment.Execution struct +func WithEnvironment(e environment.Execution) func(*Daemon) { + return func(d *Daemon) { + if e.DaemonInfo.ExperimentalBuild { + d.experimental = true + } + } +} diff --git a/components/engine/internal/test/daemon/service.go b/components/engine/internal/test/daemon/service.go index 26e6004ae11..a0541e97162 100644 --- a/components/engine/internal/test/daemon/service.go +++ b/components/engine/internal/test/daemon/service.go @@ -13,9 +13,7 @@ import ( // ServiceConstructor defines a swarm service constructor function type ServiceConstructor func(*swarm.Service) -// CreateServiceWithOptions creates a swarm service given the specified service constructors -// and auth config -func (d *Daemon) CreateServiceWithOptions(t assert.TestingT, opts types.ServiceCreateOptions, f ...ServiceConstructor) string { +func (d *Daemon) createServiceWithOptions(t assert.TestingT, opts types.ServiceCreateOptions, f ...ServiceConstructor) string { var service swarm.Service for _, fn := range f { fn(&service) @@ -34,7 +32,7 @@ func (d *Daemon) CreateServiceWithOptions(t assert.TestingT, opts types.ServiceC // CreateService creates a swarm service given the specified service constructor func (d *Daemon) CreateService(t assert.TestingT, f ...ServiceConstructor) string { - return d.CreateServiceWithOptions(t, types.ServiceCreateOptions{}, f...) + return d.createServiceWithOptions(t, types.ServiceCreateOptions{}, f...) } // GetService returns the swarm service corresponding to the specified id diff --git a/components/engine/internal/test/daemon/swarm.go b/components/engine/internal/test/daemon/swarm.go index f0cf3734680..f66c447ccba 100644 --- a/components/engine/internal/test/daemon/swarm.go +++ b/components/engine/internal/test/daemon/swarm.go @@ -14,6 +14,32 @@ const ( defaultSwarmListenAddr = "0.0.0.0" ) +// StartAndSwarmInit starts the daemon (with busybox) and init the swarm +func (d *Daemon) StartAndSwarmInit(t testingT) { + // avoid networking conflicts + args := []string{"--iptables=false", "--swarm-default-advertise-addr=lo"} + d.StartWithBusybox(t, args...) + + d.SwarmInit(t, swarm.InitRequest{}) +} + +// StartAndSwarmJoin starts the daemon (with busybox) and join the specified swarm as worker or manager +func (d *Daemon) StartAndSwarmJoin(t testingT, leader *Daemon, manager bool) { + // avoid networking conflicts + args := []string{"--iptables=false", "--swarm-default-advertise-addr=lo"} + d.StartWithBusybox(t, args...) + + tokens := leader.JoinTokens(t) + token := tokens.Worker + if manager { + token = tokens.Manager + } + d.SwarmJoin(t, swarm.JoinRequest{ + RemoteAddrs: []string{leader.SwarmListenAddr()}, + JoinToken: token, + }) +} + // SpecConstructor defines a swarm spec constructor type SpecConstructor func(*swarm.Spec) From f70c483990a0d3a4b59523f11fac87a239866dc6 Mon Sep 17 00:00:00 2001 From: Yong Tang Date: Sat, 14 Apr 2018 16:52:02 +0000 Subject: [PATCH 31/36] Some enhancement in integration tests This fix converts some `client.ContainerCreate` to `container.Create`, and removes some unneeded `name` fields when test containers are created. Signed-off-by: Yong Tang (cherry picked from commit ab9bb47b05b1dde445a5e4ba78ae97303208dc8b) Signed-off-by: Sebastiaan van Stijn --- .../integration/container/create_test.go | 4 ++-- .../integration/container/export_test.go | 10 ++------- .../system/cgroupdriver_systemd_test.go | 22 ++++++------------- 3 files changed, 11 insertions(+), 25 deletions(-) diff --git a/components/engine/integration/container/create_test.go b/components/engine/integration/container/create_test.go index 5bacd01e452..521584d88a3 100644 --- a/components/engine/integration/container/create_test.go +++ b/components/engine/integration/container/create_test.go @@ -46,7 +46,7 @@ func TestCreateFailsWhenIdentifierDoesNotExist(t *testing.T) { &container.Config{Image: tc.image}, &container.HostConfig{}, &network.NetworkingConfig{}, - "foo", + "", ) testutil.ErrorContains(t, err, tc.expectedError) }) @@ -86,7 +86,7 @@ func TestCreateWithInvalidEnv(t *testing.T) { }, &container.HostConfig{}, &network.NetworkingConfig{}, - "foo", + "", ) testutil.ErrorContains(t, err, tc.expectedError) }) diff --git a/components/engine/integration/container/export_test.go b/components/engine/integration/container/export_test.go index 272feff75d2..1b7eff44be7 100644 --- a/components/engine/integration/container/export_test.go +++ b/components/engine/integration/container/export_test.go @@ -7,7 +7,6 @@ import ( "time" "github.com/docker/docker/api/types" - containerTypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/integration/internal/request" @@ -70,15 +69,10 @@ func TestExportContainerAfterDaemonRestart(t *testing.T) { defer d.Stop(t) ctx := context.Background() - cfg := containerTypes.Config{ - Image: "busybox", - Cmd: []string{"top"}, - } - ctr, err := client.ContainerCreate(ctx, &cfg, nil, nil, "") - assert.NilError(t, err) + ctrID := container.Create(t, ctx, client) d.Restart(t) - _, err = client.ContainerExport(ctx, ctr.ID) + _, err = client.ContainerExport(ctx, ctrID) assert.NilError(t, err) } diff --git a/components/engine/integration/system/cgroupdriver_systemd_test.go b/components/engine/integration/system/cgroupdriver_systemd_test.go index 12e716c66c4..0b4e7eeeeb1 100644 --- a/components/engine/integration/system/cgroupdriver_systemd_test.go +++ b/components/engine/integration/system/cgroupdriver_systemd_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/container" + "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/internal/test/daemon" "github.com/gotestyourself/gotestyourself/assert" @@ -40,25 +40,17 @@ func TestCgroupDriverSystemdMemoryLimit(t *testing.T) { defer d.Stop(t) const mem = 64 * 1024 * 1024 // 64 MB - cfg := container.Config{ - Image: "busybox", - Cmd: []string{"top"}, - } - hostcfg := container.HostConfig{ - Resources: container.Resources{ - Memory: mem, - }, - } ctx := context.Background() - ctr, err := client.ContainerCreate(ctx, &cfg, &hostcfg, nil, "") - assert.NilError(t, err) - defer client.ContainerRemove(ctx, ctr.ID, types.ContainerRemoveOptions{Force: true}) + ctrID := container.Create(t, ctx, client, func(c *container.TestContainerConfig) { + c.HostConfig.Resources.Memory = mem + }) + defer client.ContainerRemove(ctx, ctrID, types.ContainerRemoveOptions{Force: true}) - err = client.ContainerStart(ctx, ctr.ID, types.ContainerStartOptions{}) + err = client.ContainerStart(ctx, ctrID, types.ContainerStartOptions{}) assert.NilError(t, err) - s, err := client.ContainerInspect(ctx, ctr.ID) + s, err := client.ContainerInspect(ctx, ctrID) assert.NilError(t, err) assert.Equal(t, s.HostConfig.Memory, mem) } From 7974841233b7d8e7196df9844ede734d731a31f3 Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Mon, 16 Apr 2018 14:39:13 +0200 Subject: [PATCH 32/36] Move fakecontext, fakegit and fakestorage to internal/test Signed-off-by: Vincent Demeester (cherry picked from commit 062564084a22f71cf5807ae5dfad7d29afb12e04) Signed-off-by: Sebastiaan van Stijn --- .../engine/integration-cli/check_test.go | 2 +- .../engine/integration-cli/cli/build/build.go | 2 +- .../integration-cli/docker_api_build_test.go | 6 +- .../integration-cli/docker_cli_build_test.go | 6 +- .../docker_cli_build_unix_test.go | 2 +- .../integration-cli/docker_cli_create_test.go | 2 +- .../integration-cli/docker_cli_run_test.go | 2 +- .../integration/build/build_session_test.go | 2 +- .../integration/build/build_squash_test.go | 2 +- .../engine/integration/build/build_test.go | 2 +- .../test}/fakecontext/context.go | 4 +- .../test}/fakegit/fakegit.go | 6 +- .../test}/fakestorage/fixtures.go | 20 ++++- .../test}/fakestorage/storage.go | 73 ++++++++++++------- 14 files changed, 83 insertions(+), 48 deletions(-) rename components/engine/{integration-cli/cli/build => internal/test}/fakecontext/context.go (94%) rename components/engine/{integration-cli/cli/build => internal/test}/fakegit/fakegit.go (93%) rename components/engine/{integration-cli/cli/build => internal/test}/fakestorage/fixtures.go (73%) rename components/engine/{integration-cli/cli/build => internal/test}/fakestorage/storage.go (65%) diff --git a/components/engine/integration-cli/check_test.go b/components/engine/integration-cli/check_test.go index e9d1d5d2c08..52d284ac9fd 100644 --- a/components/engine/integration-cli/check_test.go +++ b/components/engine/integration-cli/check_test.go @@ -15,11 +15,11 @@ import ( "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/cli" - "github.com/docker/docker/integration-cli/cli/build/fakestorage" "github.com/docker/docker/integration-cli/daemon" "github.com/docker/docker/integration-cli/environment" testdaemon "github.com/docker/docker/internal/test/daemon" ienv "github.com/docker/docker/internal/test/environment" + "github.com/docker/docker/internal/test/fakestorage" "github.com/docker/docker/internal/test/fixtures/plugin" "github.com/docker/docker/internal/test/registry" "github.com/docker/docker/pkg/reexec" diff --git a/components/engine/integration-cli/cli/build/build.go b/components/engine/integration-cli/cli/build/build.go index dd36ecc2127..71048d0d6dd 100644 --- a/components/engine/integration-cli/cli/build/build.go +++ b/components/engine/integration-cli/cli/build/build.go @@ -4,7 +4,7 @@ import ( "io" "strings" - "github.com/docker/docker/integration-cli/cli/build/fakecontext" + "github.com/docker/docker/internal/test/fakecontext" "github.com/gotestyourself/gotestyourself/icmd" ) diff --git a/components/engine/integration-cli/docker_api_build_test.go b/components/engine/integration-cli/docker_api_build_test.go index 93469f1d47b..389b20db803 100644 --- a/components/engine/integration-cli/docker_api_build_test.go +++ b/components/engine/integration-cli/docker_api_build_test.go @@ -13,10 +13,10 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/integration-cli/checker" - "github.com/docker/docker/integration-cli/cli/build/fakecontext" - "github.com/docker/docker/integration-cli/cli/build/fakegit" - "github.com/docker/docker/integration-cli/cli/build/fakestorage" "github.com/docker/docker/integration-cli/request" + "github.com/docker/docker/internal/test/fakecontext" + "github.com/docker/docker/internal/test/fakegit" + "github.com/docker/docker/internal/test/fakestorage" "github.com/go-check/check" "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" diff --git a/components/engine/integration-cli/docker_cli_build_test.go b/components/engine/integration-cli/docker_cli_build_test.go index 030f386c418..cd57d591f20 100644 --- a/components/engine/integration-cli/docker_cli_build_test.go +++ b/components/engine/integration-cli/docker_cli_build_test.go @@ -20,9 +20,9 @@ import ( "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/cli" "github.com/docker/docker/integration-cli/cli/build" - "github.com/docker/docker/integration-cli/cli/build/fakecontext" - "github.com/docker/docker/integration-cli/cli/build/fakegit" - "github.com/docker/docker/integration-cli/cli/build/fakestorage" + "github.com/docker/docker/internal/test/fakecontext" + "github.com/docker/docker/internal/test/fakegit" + "github.com/docker/docker/internal/test/fakestorage" "github.com/docker/docker/internal/testutil" "github.com/docker/docker/pkg/archive" "github.com/go-check/check" diff --git a/components/engine/integration-cli/docker_cli_build_unix_test.go b/components/engine/integration-cli/docker_cli_build_unix_test.go index d857bd2f2c2..f2d598ef585 100644 --- a/components/engine/integration-cli/docker_cli_build_unix_test.go +++ b/components/engine/integration-cli/docker_cli_build_unix_test.go @@ -18,7 +18,7 @@ import ( "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/cli" "github.com/docker/docker/integration-cli/cli/build" - "github.com/docker/docker/integration-cli/cli/build/fakecontext" + "github.com/docker/docker/internal/test/fakecontext" units "github.com/docker/go-units" "github.com/go-check/check" "github.com/gotestyourself/gotestyourself/icmd" diff --git a/components/engine/integration-cli/docker_cli_create_test.go b/components/engine/integration-cli/docker_cli_create_test.go index 120b62bc0f4..bf7096123bd 100644 --- a/components/engine/integration-cli/docker_cli_create_test.go +++ b/components/engine/integration-cli/docker_cli_create_test.go @@ -11,7 +11,7 @@ import ( "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/cli" "github.com/docker/docker/integration-cli/cli/build" - "github.com/docker/docker/integration-cli/cli/build/fakecontext" + "github.com/docker/docker/internal/test/fakecontext" "github.com/docker/docker/pkg/stringid" "github.com/docker/go-connections/nat" "github.com/go-check/check" diff --git a/components/engine/integration-cli/docker_cli_run_test.go b/components/engine/integration-cli/docker_cli_run_test.go index 35756b27126..d3cd9d7867b 100644 --- a/components/engine/integration-cli/docker_cli_run_test.go +++ b/components/engine/integration-cli/docker_cli_run_test.go @@ -25,7 +25,7 @@ import ( "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/cli" "github.com/docker/docker/integration-cli/cli/build" - "github.com/docker/docker/integration-cli/cli/build/fakecontext" + "github.com/docker/docker/internal/test/fakecontext" "github.com/docker/docker/internal/testutil" "github.com/docker/docker/pkg/mount" "github.com/docker/docker/pkg/parsers/kernel" diff --git a/components/engine/integration/build/build_session_test.go b/components/engine/integration/build/build_session_test.go index af1a5367699..391b83ba304 100644 --- a/components/engine/integration/build/build_session_test.go +++ b/components/engine/integration/build/build_session_test.go @@ -8,9 +8,9 @@ import ( "testing" dclient "github.com/docker/docker/client" - "github.com/docker/docker/integration-cli/cli/build/fakecontext" "github.com/docker/docker/integration-cli/request" "github.com/docker/docker/internal/test/daemon" + "github.com/docker/docker/internal/test/fakecontext" "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" "github.com/moby/buildkit/session" diff --git a/components/engine/integration/build/build_squash_test.go b/components/engine/integration/build/build_squash_test.go index e8097fd811b..faac658d7d1 100644 --- a/components/engine/integration/build/build_squash_test.go +++ b/components/engine/integration/build/build_squash_test.go @@ -9,9 +9,9 @@ import ( "testing" "github.com/docker/docker/api/types" - "github.com/docker/docker/integration-cli/cli/build/fakecontext" "github.com/docker/docker/integration/internal/container" "github.com/docker/docker/internal/test/daemon" + "github.com/docker/docker/internal/test/fakecontext" "github.com/docker/docker/pkg/stdcopy" "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" diff --git a/components/engine/integration/build/build_test.go b/components/engine/integration/build/build_test.go index a3f283e69e9..a9f79156f7b 100644 --- a/components/engine/integration/build/build_test.go +++ b/components/engine/integration/build/build_test.go @@ -13,8 +13,8 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/versions" - "github.com/docker/docker/integration-cli/cli/build/fakecontext" "github.com/docker/docker/integration/internal/request" + "github.com/docker/docker/internal/test/fakecontext" "github.com/docker/docker/pkg/jsonmessage" "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" diff --git a/components/engine/integration-cli/cli/build/fakecontext/context.go b/components/engine/internal/test/fakecontext/context.go similarity index 94% rename from components/engine/integration-cli/cli/build/fakecontext/context.go rename to components/engine/internal/test/fakecontext/context.go index b945a8ff179..196c694bd96 100644 --- a/components/engine/integration-cli/cli/build/fakecontext/context.go +++ b/components/engine/internal/test/fakecontext/context.go @@ -1,4 +1,4 @@ -package fakecontext // import "github.com/docker/docker/integration-cli/cli/build/fakecontext" +package fakecontext // import "github.com/docker/docker/internal/test/fakecontext" import ( "bytes" @@ -73,7 +73,7 @@ func WithFiles(files map[string]string) func(*Fake) error { func WithBinaryFiles(files map[string]*bytes.Buffer) func(*Fake) error { return func(fakeContext *Fake) error { for file, content := range files { - if err := fakeContext.Add(file, string(content.Bytes())); err != nil { + if err := fakeContext.Add(file, content.String()); err != nil { return err } } diff --git a/components/engine/integration-cli/cli/build/fakegit/fakegit.go b/components/engine/internal/test/fakegit/fakegit.go similarity index 93% rename from components/engine/integration-cli/cli/build/fakegit/fakegit.go rename to components/engine/internal/test/fakegit/fakegit.go index f7a22c9ee57..45b99608f36 100644 --- a/components/engine/integration-cli/cli/build/fakegit/fakegit.go +++ b/components/engine/internal/test/fakegit/fakegit.go @@ -1,4 +1,4 @@ -package fakegit // import "github.com/docker/docker/integration-cli/cli/build/fakegit" +package fakegit // import "github.com/docker/docker/internal/test/fakegit" import ( "fmt" @@ -9,8 +9,8 @@ import ( "os/exec" "path/filepath" - "github.com/docker/docker/integration-cli/cli/build/fakecontext" - "github.com/docker/docker/integration-cli/cli/build/fakestorage" + "github.com/docker/docker/internal/test/fakecontext" + "github.com/docker/docker/internal/test/fakestorage" "github.com/gotestyourself/gotestyourself/assert" ) diff --git a/components/engine/integration-cli/cli/build/fakestorage/fixtures.go b/components/engine/internal/test/fakestorage/fixtures.go similarity index 73% rename from components/engine/integration-cli/cli/build/fakestorage/fixtures.go rename to components/engine/internal/test/fakestorage/fixtures.go index ad10a5ed8a2..f8e80527f0e 100644 --- a/components/engine/integration-cli/cli/build/fakestorage/fixtures.go +++ b/components/engine/internal/test/fakestorage/fixtures.go @@ -1,13 +1,17 @@ -package fakestorage // import "github.com/docker/docker/integration-cli/cli/build/fakestorage" +package fakestorage // import "github.com/docker/docker/internal/test/fakestorage" import ( + "context" + "io" "io/ioutil" "os" "os/exec" "path/filepath" "sync" - "github.com/docker/docker/integration-cli/cli" + "github.com/docker/docker/api/types" + "github.com/docker/docker/pkg/archive" + "github.com/gotestyourself/gotestyourself/assert" ) var ensureHTTPServerOnce sync.Once @@ -70,5 +74,15 @@ func ensureHTTPServerImage(t testingT) { t.Fatalf("could not build http server: %v", string(out)) } - cli.DockerCmd(t, "build", "-q", "-t", "httpserver", tmp) + c := testEnv.APIClient() + reader, err := archive.TarWithOptions(tmp, &archive.TarOptions{}) + assert.NilError(t, err) + resp, err := c.ImageBuild(context.Background(), reader, types.ImageBuildOptions{ + Remove: true, + ForceRemove: true, + Tags: []string{"httpserver"}, + }) + assert.NilError(t, err) + _, err = io.Copy(ioutil.Discard, resp.Body) + assert.NilError(t, err) } diff --git a/components/engine/integration-cli/cli/build/fakestorage/storage.go b/components/engine/internal/test/fakestorage/storage.go similarity index 65% rename from components/engine/integration-cli/cli/build/fakestorage/storage.go rename to components/engine/internal/test/fakestorage/storage.go index 0df602a863f..ca3410ca854 100644 --- a/components/engine/integration-cli/cli/build/fakestorage/storage.go +++ b/components/engine/internal/test/fakestorage/storage.go @@ -1,20 +1,24 @@ -package fakestorage // import "github.com/docker/docker/integration-cli/cli/build/fakestorage" +package fakestorage // import "github.com/docker/docker/internal/test/fakestorage" import ( + "context" "fmt" - "net" + "io" + "io/ioutil" "net/http" "net/http/httptest" "net/url" "os" "strings" - "github.com/docker/docker/integration-cli/cli" - "github.com/docker/docker/integration-cli/cli/build" - "github.com/docker/docker/integration-cli/cli/build/fakecontext" + "github.com/docker/docker/api/types" + containertypes "github.com/docker/docker/api/types/container" + "github.com/docker/docker/client" "github.com/docker/docker/integration-cli/request" "github.com/docker/docker/internal/test/environment" + "github.com/docker/docker/internal/test/fakecontext" "github.com/docker/docker/internal/testutil" + "github.com/docker/go-connections/nat" "github.com/gotestyourself/gotestyourself/assert" ) @@ -62,7 +66,7 @@ func New(t testingT, dir string, modifiers ...func(*fakecontext.Fake) error) Fak case testEnv.IsLocalDaemon(): return newLocalFakeStorage(ctx) default: - return newRemoteFileServer(t, ctx) + return newRemoteFileServer(t, ctx, testEnv.APIClient()) } return nil } @@ -101,6 +105,7 @@ type remoteFileServer struct { host string // hostname/port web server is listening to on docker host e.g. 0.0.0.0:43712 container string image string + client client.APIClient ctx *fakecontext.Fake } @@ -121,18 +126,26 @@ func (f *remoteFileServer) Close() error { f.ctx.Close() } if f.image != "" { - if err := cli.Docker(cli.Args("rmi", "-f", f.image)).Error; err != nil { + if _, err := f.client.ImageRemove(context.Background(), f.image, types.ImageRemoveOptions{ + Force: true, + }); err != nil { fmt.Fprintf(os.Stderr, "Error closing remote file server : %v\n", err) } } + if err := f.client.Close(); err != nil { + fmt.Fprintf(os.Stderr, "Error closing remote file server : %v\n", err) + } }() if f.container == "" { return nil } - return cli.Docker(cli.Args("rm", "-fv", f.container)).Error + return f.client.ContainerRemove(context.Background(), f.container, types.ContainerRemoveOptions{ + Force: true, + RemoveVolumes: true, + }) } -func newRemoteFileServer(t testingT, ctx *fakecontext.Fake) *remoteFileServer { +func newRemoteFileServer(t testingT, ctx *fakecontext.Fake, c client.APIClient) *remoteFileServer { var ( image = fmt.Sprintf("fileserver-img-%s", strings.ToLower(testutil.GenerateRandomAlphaOnlyString(10))) container = fmt.Sprintf("fileserver-cnt-%s", strings.ToLower(testutil.GenerateRandomAlphaOnlyString(10))) @@ -145,31 +158,39 @@ func newRemoteFileServer(t testingT, ctx *fakecontext.Fake) *remoteFileServer { COPY . /static`); err != nil { t.Fatal(err) } - cli.BuildCmd(t, image, build.WithoutCache, build.WithExternalBuildContext(ctx)) + resp, err := c.ImageBuild(context.Background(), ctx.AsTarReader(t), types.ImageBuildOptions{ + NoCache: true, + Tags: []string{image}, + }) + assert.NilError(t, err) + _, err = io.Copy(ioutil.Discard, resp.Body) + assert.NilError(t, err) // Start the container - cli.DockerCmd(t, "run", "-d", "-P", "--name", container, image) + b, err := c.ContainerCreate(context.Background(), &containertypes.Config{ + Image: image, + }, &containertypes.HostConfig{}, nil, container) + assert.NilError(t, err) + err = c.ContainerStart(context.Background(), b.ID, types.ContainerStartOptions{}) + assert.NilError(t, err) // Find out the system assigned port - out := cli.DockerCmd(t, "port", container, "80/tcp").Combined() - fileserverHostPort := strings.Trim(out, "\n") - _, port, err := net.SplitHostPort(fileserverHostPort) - if err != nil { - t.Fatalf("unable to parse file server host:port: %v", err) - } - - dockerHostURL, err := url.Parse(request.DaemonHost()) - if err != nil { - t.Fatalf("unable to parse daemon host URL: %v", err) - } - host, _, err := net.SplitHostPort(dockerHostURL.Host) - if err != nil { - t.Fatalf("unable to parse docker daemon host:port: %v", err) + i, err := c.ContainerInspect(context.Background(), b.ID) + assert.NilError(t, err) + newP, err := nat.NewPort("tcp", "80") + assert.NilError(t, err) + ports, exists := i.NetworkSettings.Ports[newP] + if !exists || len(ports) != 1 { + t.Fatalf("unable to find port 80/tcp for %s", container) } + host := ports[0].HostIP + port := ports[0].HostPort return &remoteFileServer{ container: container, image: image, host: fmt.Sprintf("%s:%s", host, port), - ctx: ctx} + ctx: ctx, + client: c, + } } From 04b5ed6c102182383f2e229041a4777f969dea19 Mon Sep 17 00:00:00 2001 From: Yong Tang Date: Wed, 11 Apr 2018 00:42:03 +0000 Subject: [PATCH 33/36] Migrate image tag tests from integration-cli to api tests This fix migrates image tag tests from integration-cli to api tests. Signed-off-by: Yong Tang (cherry picked from commit 9bcb960508a6066811cffcca1e35ca44d7f1cf94) Signed-off-by: Sebastiaan van Stijn --- .../integration-cli/docker_cli_tag_test.go | 139 ------------------ .../engine/integration/image/tag_test.go | 139 ++++++++++++++++++ 2 files changed, 139 insertions(+), 139 deletions(-) delete mode 100644 components/engine/integration-cli/docker_cli_tag_test.go create mode 100644 components/engine/integration/image/tag_test.go diff --git a/components/engine/integration-cli/docker_cli_tag_test.go b/components/engine/integration-cli/docker_cli_tag_test.go deleted file mode 100644 index 278e348f4ec..00000000000 --- a/components/engine/integration-cli/docker_cli_tag_test.go +++ /dev/null @@ -1,139 +0,0 @@ -package main - -import ( - "strings" - - "github.com/docker/docker/integration-cli/checker" - "github.com/docker/docker/internal/testutil" - "github.com/go-check/check" -) - -// tagging a named image in a new unprefixed repo should work -func (s *DockerSuite) TestTagUnprefixedRepoByName(c *check.C) { - dockerCmd(c, "tag", "busybox:latest", "testfoobarbaz") -} - -// tagging an image by ID in a new unprefixed repo should work -func (s *DockerSuite) TestTagUnprefixedRepoByID(c *check.C) { - imageID := inspectField(c, "busybox", "Id") - dockerCmd(c, "tag", imageID, "testfoobarbaz") -} - -// ensure we don't allow the use of invalid repository names; these tag operations should fail -func (s *DockerSuite) TestTagInvalidUnprefixedRepo(c *check.C) { - invalidRepos := []string{"fo$z$", "Foo@3cc", "Foo$3", "Foo*3", "Fo^3", "Foo!3", "F)xcz(", "fo%asd", "FOO/bar"} - - for _, repo := range invalidRepos { - out, _, err := dockerCmdWithError("tag", "busybox", repo) - c.Assert(err, checker.NotNil, check.Commentf("tag busybox %v should have failed : %v", repo, out)) - } -} - -// ensure we don't allow the use of invalid tags; these tag operations should fail -func (s *DockerSuite) TestTagInvalidPrefixedRepo(c *check.C) { - longTag := testutil.GenerateRandomAlphaOnlyString(121) - - invalidTags := []string{"repo:fo$z$", "repo:Foo@3cc", "repo:Foo$3", "repo:Foo*3", "repo:Fo^3", "repo:Foo!3", "repo:%goodbye", "repo:#hashtagit", "repo:F)xcz(", "repo:-foo", "repo:..", longTag} - - for _, repotag := range invalidTags { - out, _, err := dockerCmdWithError("tag", "busybox", repotag) - c.Assert(err, checker.NotNil, check.Commentf("tag busybox %v should have failed : %v", repotag, out)) - } -} - -// ensure we allow the use of valid tags -func (s *DockerSuite) TestTagValidPrefixedRepo(c *check.C) { - validRepos := []string{"fooo/bar", "fooaa/test", "foooo:t", "HOSTNAME.DOMAIN.COM:443/foo/bar"} - - for _, repo := range validRepos { - _, _, err := dockerCmdWithError("tag", "busybox:latest", repo) - if err != nil { - c.Errorf("tag busybox %v should have worked: %s", repo, err) - continue - } - deleteImages(repo) - } -} - -// tag an image with an existed tag name without -f option should work -func (s *DockerSuite) TestTagExistedNameWithoutForce(c *check.C) { - dockerCmd(c, "tag", "busybox:latest", "busybox:test") -} - -func (s *DockerSuite) TestTagWithPrefixHyphen(c *check.C) { - // test repository name begin with '-' - out, _, err := dockerCmdWithError("tag", "busybox:latest", "-busybox:test") - c.Assert(err, checker.NotNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "Error parsing reference", check.Commentf("tag a name begin with '-' should failed")) - - // test namespace name begin with '-' - out, _, err = dockerCmdWithError("tag", "busybox:latest", "-test/busybox:test") - c.Assert(err, checker.NotNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "Error parsing reference", check.Commentf("tag a name begin with '-' should failed")) - - // test index name begin with '-' - out, _, err = dockerCmdWithError("tag", "busybox:latest", "-index:5000/busybox:test") - c.Assert(err, checker.NotNil, check.Commentf(out)) - c.Assert(out, checker.Contains, "Error parsing reference", check.Commentf("tag a name begin with '-' should failed")) -} - -// ensure tagging using official names works -// ensure all tags result in the same name -func (s *DockerSuite) TestTagOfficialNames(c *check.C) { - names := []string{ - "docker.io/busybox", - "index.docker.io/busybox", - "library/busybox", - "docker.io/library/busybox", - "index.docker.io/library/busybox", - } - - for _, name := range names { - out, exitCode, err := dockerCmdWithError("tag", "busybox:latest", name+":latest") - if err != nil || exitCode != 0 { - c.Errorf("tag busybox %v should have worked: %s, %s", name, err, out) - continue - } - - // ensure we don't have multiple tag names. - out, _, err = dockerCmdWithError("images") - if err != nil { - c.Errorf("listing images failed with errors: %v, %s", err, out) - } else if strings.Contains(out, name) { - c.Errorf("images should not have listed '%s'", name) - deleteImages(name + ":latest") - } - } - - for _, name := range names { - _, exitCode, err := dockerCmdWithError("tag", name+":latest", "fooo/bar:latest") - if err != nil || exitCode != 0 { - c.Errorf("tag %v fooo/bar should have worked: %s", name, err) - continue - } - deleteImages("fooo/bar:latest") - } -} - -// ensure tags can not match digests -func (s *DockerSuite) TestTagMatchesDigest(c *check.C) { - digest := "busybox@sha256:abcdef76720241213f5303bda7704ec4c2ef75613173910a56fb1b6e20251507" - // test setting tag fails - _, _, err := dockerCmdWithError("tag", "busybox:latest", digest) - if err == nil { - c.Fatal("digest tag a name should have failed") - } - // check that no new image matches the digest - _, _, err = dockerCmdWithError("inspect", digest) - if err == nil { - c.Fatal("inspecting by digest should have failed") - } -} - -func (s *DockerSuite) TestTagInvalidRepoName(c *check.C) { - // test setting tag fails - _, _, err := dockerCmdWithError("tag", "busybox:latest", "sha256:sometag") - if err == nil { - c.Fatal("tagging with image named \"sha256\" should have failed") - } -} diff --git a/components/engine/integration/image/tag_test.go b/components/engine/integration/image/tag_test.go new file mode 100644 index 00000000000..c396c07c5cf --- /dev/null +++ b/components/engine/integration/image/tag_test.go @@ -0,0 +1,139 @@ +package image // import "github.com/docker/docker/integration/image" + +import ( + "context" + "fmt" + "testing" + + "github.com/docker/docker/integration/internal/request" + "github.com/docker/docker/internal/testutil" + "github.com/gotestyourself/gotestyourself/assert" + is "github.com/gotestyourself/gotestyourself/assert/cmp" +) + +// tagging a named image in a new unprefixed repo should work +func TestTagUnprefixedRepoByNameOrName(t *testing.T) { + defer setupTest(t)() + client := request.NewAPIClient(t) + ctx := context.Background() + + // By name + err := client.ImageTag(ctx, "busybox:latest", "testfoobarbaz") + assert.NilError(t, err) + + // By ID + insp, _, err := client.ImageInspectWithRaw(ctx, "busybox") + assert.NilError(t, err) + err = client.ImageTag(ctx, insp.ID, "testfoobarbaz") + assert.NilError(t, err) +} + +// ensure we don't allow the use of invalid repository names or tags; these tag operations should fail +// TODO (yongtang): Migrate to unit tests +func TestTagInvalidReference(t *testing.T) { + defer setupTest(t)() + client := request.NewAPIClient(t) + ctx := context.Background() + + invalidRepos := []string{"fo$z$", "Foo@3cc", "Foo$3", "Foo*3", "Fo^3", "Foo!3", "F)xcz(", "fo%asd", "FOO/bar"} + + for _, repo := range invalidRepos { + err := client.ImageTag(ctx, "busybox", repo) + testutil.ErrorContains(t, err, "not a valid repository/tag") + } + + longTag := testutil.GenerateRandomAlphaOnlyString(121) + + invalidTags := []string{"repo:fo$z$", "repo:Foo@3cc", "repo:Foo$3", "repo:Foo*3", "repo:Fo^3", "repo:Foo!3", "repo:%goodbye", "repo:#hashtagit", "repo:F)xcz(", "repo:-foo", "repo:..", longTag} + + for _, repotag := range invalidTags { + err := client.ImageTag(ctx, "busybox", repotag) + testutil.ErrorContains(t, err, "not a valid repository/tag") + } + + // test repository name begin with '-' + err := client.ImageTag(ctx, "busybox:latest", "-busybox:test") + testutil.ErrorContains(t, err, "Error parsing reference") + + // test namespace name begin with '-' + err = client.ImageTag(ctx, "busybox:latest", "-test/busybox:test") + testutil.ErrorContains(t, err, "Error parsing reference") + + // test index name begin with '-' + err = client.ImageTag(ctx, "busybox:latest", "-index:5000/busybox:test") + testutil.ErrorContains(t, err, "Error parsing reference") + + // test setting tag fails + err = client.ImageTag(ctx, "busybox:latest", "sha256:sometag") + testutil.ErrorContains(t, err, "refusing to create an ambiguous tag using digest algorithm as name") +} + +// ensure we allow the use of valid tags +func TestTagValidPrefixedRepo(t *testing.T) { + defer setupTest(t)() + client := request.NewAPIClient(t) + ctx := context.Background() + + validRepos := []string{"fooo/bar", "fooaa/test", "foooo:t", "HOSTNAME.DOMAIN.COM:443/foo/bar"} + + for _, repo := range validRepos { + err := client.ImageTag(ctx, "busybox", repo) + assert.NilError(t, err) + } +} + +// tag an image with an existed tag name without -f option should work +func TestTagExistedNameWithoutForce(t *testing.T) { + defer setupTest(t)() + client := request.NewAPIClient(t) + ctx := context.Background() + + err := client.ImageTag(ctx, "busybox:latest", "busybox:test") + assert.NilError(t, err) +} + +// ensure tagging using official names works +// ensure all tags result in the same name +func TestTagOfficialNames(t *testing.T) { + defer setupTest(t)() + client := request.NewAPIClient(t) + ctx := context.Background() + + names := []string{ + "docker.io/busybox", + "index.docker.io/busybox", + "library/busybox", + "docker.io/library/busybox", + "index.docker.io/library/busybox", + } + + for _, name := range names { + err := client.ImageTag(ctx, "busybox", name+":latest") + assert.NilError(t, err) + + // ensure we don't have multiple tag names. + insp, _, err := client.ImageInspectWithRaw(ctx, "busybox") + assert.NilError(t, err) + assert.Assert(t, !is.Contains(insp.RepoTags, name)().Success()) + } + + for _, name := range names { + err := client.ImageTag(ctx, name+":latest", "fooo/bar:latest") + assert.NilError(t, err) + } +} + +// ensure tags can not match digests +func TestTagMatchesDigest(t *testing.T) { + defer setupTest(t)() + client := request.NewAPIClient(t) + ctx := context.Background() + + digest := "busybox@sha256:abcdef76720241213f5303bda7704ec4c2ef75613173910a56fb1b6e20251507" + // test setting tag fails + err := client.ImageTag(ctx, "busybox:latest", digest) + testutil.ErrorContains(t, err, "refusing to create a tag with a digest reference") + // check that no new image matches the digest + _, _, err = client.ImageInspectWithRaw(ctx, digest) + testutil.ErrorContains(t, err, fmt.Sprintf("No such image: %s", digest)) +} From faccf7d3a7438210f02c359e478c707bfed52002 Mon Sep 17 00:00:00 2001 From: Anda Xu Date: Tue, 10 Apr 2018 16:54:39 -0700 Subject: [PATCH 34/36] remove the retries for service update Signed-off-by: Anda Xu (cherry picked from commit 7380935331f0c35315003578258f6c1f47c1a586) Signed-off-by: Sebastiaan van Stijn --- .../integration-cli/docker_cli_service_update_test.go | 8 ++++---- .../engine/integration-cli/docker_cli_swarm_test.go | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/components/engine/integration-cli/docker_cli_service_update_test.go b/components/engine/integration-cli/docker_cli_service_update_test.go index 7b590a0f4e5..a281327afe0 100644 --- a/components/engine/integration-cli/docker_cli_service_update_test.go +++ b/components/engine/integration-cli/docker_cli_service_update_test.go @@ -69,7 +69,7 @@ func (s *DockerSwarmSuite) TestServiceUpdateSecrets(c *check.C) { c.Assert(err, checker.IsNil, check.Commentf(out)) // add secret - out, err = d.CmdRetryOutOfSequence("service", "update", "--detach", "test", "--secret-add", fmt.Sprintf("source=%s,target=%s", testName, testTarget)) + out, err = d.Cmd("service", "update", "--detach", "test", "--secret-add", fmt.Sprintf("source=%s,target=%s", testName, testTarget)) c.Assert(err, checker.IsNil, check.Commentf(out)) out, err = d.Cmd("service", "inspect", "--format", "{{ json .Spec.TaskTemplate.ContainerSpec.Secrets }}", serviceName) @@ -84,7 +84,7 @@ func (s *DockerSwarmSuite) TestServiceUpdateSecrets(c *check.C) { c.Assert(refs[0].File.Name, checker.Equals, testTarget) // remove - out, err = d.CmdRetryOutOfSequence("service", "update", "--detach", "test", "--secret-rm", testName) + out, err = d.Cmd("service", "update", "--detach", "test", "--secret-rm", testName) c.Assert(err, checker.IsNil, check.Commentf(out)) out, err = d.Cmd("service", "inspect", "--format", "{{ json .Spec.TaskTemplate.ContainerSpec.Secrets }}", serviceName) @@ -111,7 +111,7 @@ func (s *DockerSwarmSuite) TestServiceUpdateConfigs(c *check.C) { c.Assert(err, checker.IsNil, check.Commentf(out)) // add config - out, err = d.CmdRetryOutOfSequence("service", "update", "--detach", "test", "--config-add", fmt.Sprintf("source=%s,target=%s", testName, testTarget)) + out, err = d.Cmd("service", "update", "--detach", "test", "--config-add", fmt.Sprintf("source=%s,target=%s", testName, testTarget)) c.Assert(err, checker.IsNil, check.Commentf(out)) out, err = d.Cmd("service", "inspect", "--format", "{{ json .Spec.TaskTemplate.ContainerSpec.Configs }}", serviceName) @@ -126,7 +126,7 @@ func (s *DockerSwarmSuite) TestServiceUpdateConfigs(c *check.C) { c.Assert(refs[0].File.Name, checker.Equals, testTarget) // remove - out, err = d.CmdRetryOutOfSequence("service", "update", "--detach", "test", "--config-rm", testName) + out, err = d.Cmd("service", "update", "--detach", "test", "--config-rm", testName) c.Assert(err, checker.IsNil, check.Commentf(out)) out, err = d.Cmd("service", "inspect", "--format", "{{ json .Spec.TaskTemplate.ContainerSpec.Configs }}", serviceName) diff --git a/components/engine/integration-cli/docker_cli_swarm_test.go b/components/engine/integration-cli/docker_cli_swarm_test.go index 9a45664cba8..0d115555740 100644 --- a/components/engine/integration-cli/docker_cli_swarm_test.go +++ b/components/engine/integration-cli/docker_cli_swarm_test.go @@ -282,10 +282,10 @@ func (s *DockerSwarmSuite) TestSwarmPublishAdd(c *check.C) { out, err = d.Cmd("service", "update", "--detach", "--publish-add", "80:80", name) c.Assert(err, checker.IsNil) - out, err = d.CmdRetryOutOfSequence("service", "update", "--detach", "--publish-add", "80:80", name) + out, err = d.Cmd("service", "update", "--detach", "--publish-add", "80:80", name) c.Assert(err, checker.IsNil) - out, err = d.CmdRetryOutOfSequence("service", "update", "--detach", "--publish-add", "80:80", "--publish-add", "80:20", name) + out, err = d.Cmd("service", "update", "--detach", "--publish-add", "80:80", "--publish-add", "80:20", name) c.Assert(err, checker.NotNil) out, err = d.Cmd("service", "inspect", "--format", "{{ .Spec.EndpointSpec.Ports }}", name) From 608b278d01807a8e2eeccc417d27e101cc32aac8 Mon Sep 17 00:00:00 2001 From: Dennis Chen Date: Fri, 30 Mar 2018 09:44:35 +0000 Subject: [PATCH 35/36] Fix a misused network object name A minor nit. `test01` never been created and used in `TestDockerNetworkInspectCustomSpecified()` function, so correct it. Signed-off-by: Dennis Chen (cherry picked from commit f041953d04bffa2be05466173f02dd016c68286d) Signed-off-by: Sebastiaan van Stijn --- .../engine/integration-cli/docker_cli_network_unix_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/engine/integration-cli/docker_cli_network_unix_test.go b/components/engine/integration-cli/docker_cli_network_unix_test.go index cb0f39a7604..f3ecd621871 100644 --- a/components/engine/integration-cli/docker_cli_network_unix_test.go +++ b/components/engine/integration-cli/docker_cli_network_unix_test.go @@ -738,7 +738,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkInspectCustomSpecified(c *check.C) c.Assert(nr.IPAM.Config[0].Gateway, checker.Equals, "172.28.5.254") c.Assert(nr.Internal, checker.False) dockerCmd(c, "network", "rm", "br0") - assertNwNotAvailable(c, "test01") + assertNwNotAvailable(c, "br0") } func (s *DockerNetworkSuite) TestDockerNetworkIPAMInvalidCombinations(c *check.C) { From 72f31848f84c2e1138caa4c5dece53c34cab8281 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Mon, 2 Apr 2018 16:23:08 -0400 Subject: [PATCH 36/36] Don't make container mount unbindable Signed-off-by: Michael Crosby (cherry picked from commit 4c000662feb3c8e3d63cbcb044a47f627cd9bb45) Signed-off-by: Sebastiaan van Stijn --- .../daemon/container_operations_unix.go | 13 +--- .../container/mounts_linux_test.go | 74 ------------------- 2 files changed, 1 insertion(+), 86 deletions(-) diff --git a/components/engine/daemon/container_operations_unix.go b/components/engine/daemon/container_operations_unix.go index 4e92b6392e2..bc7ee452332 100644 --- a/components/engine/daemon/container_operations_unix.go +++ b/components/engine/daemon/container_operations_unix.go @@ -293,7 +293,6 @@ func (daemon *Daemon) createSecretsDir(c *container.Container) error { if err := mount.Mount("tmpfs", dir, "tmpfs", "nodev,nosuid,noexec,"+tmpfsOwnership); err != nil { return errors.Wrap(err, "unable to setup secret mount") } - return nil } @@ -400,15 +399,5 @@ func (daemon *Daemon) setupContainerMountsRoot(c *container.Container) error { if err != nil { return err } - - if err := idtools.MkdirAllAndChown(p, 0700, daemon.idMappings.RootPair()); err != nil { - return err - } - - if err := mount.MakeUnbindable(p); err != nil { - // Setting unbindable is a precaution and is not neccessary for correct operation. - // Do not error out if this fails. - logrus.WithError(err).WithField("resource", p).WithField("container", c.ID).Warn("Error setting container resource mounts to unbindable, this may cause mount leakages, preventing removal of this container.") - } - return nil + return idtools.MkdirAllAndChown(p, 0700, daemon.idMappings.RootPair()) } diff --git a/components/engine/integration/container/mounts_linux_test.go b/components/engine/integration/container/mounts_linux_test.go index 2674a2901fb..38aa98355a4 100644 --- a/components/engine/integration/container/mounts_linux_test.go +++ b/components/engine/integration/container/mounts_linux_test.go @@ -1,7 +1,6 @@ package container // import "github.com/docker/docker/integration/container" import ( - "bytes" "context" "fmt" "path/filepath" @@ -13,8 +12,6 @@ import ( "github.com/docker/docker/api/types/network" "github.com/docker/docker/client" "github.com/docker/docker/integration/internal/request" - "github.com/docker/docker/internal/test/daemon" - "github.com/docker/docker/pkg/stdcopy" "github.com/docker/docker/pkg/system" "github.com/gotestyourself/gotestyourself/assert" is "github.com/gotestyourself/gotestyourself/assert/cmp" @@ -22,77 +19,6 @@ import ( "github.com/gotestyourself/gotestyourself/skip" ) -func TestContainerShmNoLeak(t *testing.T) { - skip.If(t, testEnv.IsRemoteDaemon(), "cannot start daemon on remote test run") - t.Parallel() - d := daemon.New(t) - client, err := d.NewClient() - if err != nil { - t.Fatal(err) - } - d.StartWithBusybox(t, "--iptables=false") - defer d.Stop(t) - - ctx := context.Background() - cfg := container.Config{ - Image: "busybox", - Cmd: []string{"top"}, - } - - ctr, err := client.ContainerCreate(ctx, &cfg, nil, nil, "") - if err != nil { - t.Fatal(err) - } - defer client.ContainerRemove(ctx, ctr.ID, types.ContainerRemoveOptions{Force: true}) - - if err := client.ContainerStart(ctx, ctr.ID, types.ContainerStartOptions{}); err != nil { - t.Fatal(err) - } - - // this should recursively bind mount everything in the test daemons root - // except of course we are hoping that the previous containers /dev/shm mount did not leak into this new container - hc := container.HostConfig{ - Mounts: []mount.Mount{ - { - Type: mount.TypeBind, - Source: d.Root, - Target: "/testdaemonroot", - }, - }, - } - cfg.Cmd = []string{"/bin/sh", "-c", fmt.Sprintf("mount | grep testdaemonroot | grep containers | grep %s", ctr.ID)} - cfg.AttachStdout = true - cfg.AttachStderr = true - ctrLeak, err := client.ContainerCreate(ctx, &cfg, &hc, nil, "") - if err != nil { - t.Fatal(err) - } - - attach, err := client.ContainerAttach(ctx, ctrLeak.ID, types.ContainerAttachOptions{ - Stream: true, - Stdout: true, - Stderr: true, - }) - if err != nil { - t.Fatal(err) - } - - if err := client.ContainerStart(ctx, ctrLeak.ID, types.ContainerStartOptions{}); err != nil { - t.Fatal(err) - } - - buf := bytes.NewBuffer(nil) - - if _, err := stdcopy.StdCopy(buf, buf, attach.Reader); err != nil { - t.Fatal(err) - } - - out := bytes.TrimSpace(buf.Bytes()) - if !bytes.Equal(out, []byte{}) { - t.Fatalf("mount leaked: %s", string(out)) - } -} - func TestContainerNetworkMountsNoChown(t *testing.T) { // chown only applies to Linux bind mounted volumes; must be same host to verify skip.If(t, testEnv.DaemonInfo.OSType != "linux" || testEnv.IsRemoteDaemon())