From c95330420cd1d7e97bf71d6464b2193a8b5896ba Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 28 Jun 2019 11:31:03 +0200 Subject: [PATCH 01/59] Integration: remove unneeded platform check for IPVLAN tests These tests require a local daemon, and are not built on Windows Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 1e4bd2623a37b8083a7c5f8a93068be2c63f491c) Signed-off-by: Sebastiaan van Stijn --- integration/network/ipvlan/ipvlan_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/integration/network/ipvlan/ipvlan_test.go b/integration/network/ipvlan/ipvlan_test.go index a02b0db2a6b84..569a4b7db95a3 100644 --- a/integration/network/ipvlan/ipvlan_test.go +++ b/integration/network/ipvlan/ipvlan_test.go @@ -22,7 +22,6 @@ import ( func TestDockerNetworkIpvlanPersistance(t *testing.T) { // verify the driver automatically provisions the 802.1q link (di-dummy0.70) - skip.If(t, testEnv.DaemonInfo.OSType == "windows") skip.If(t, testEnv.IsRemoteDaemon) skip.If(t, !ipvlanKernelSupport(t), "Kernel doesn't support ipvlan") @@ -50,7 +49,6 @@ func TestDockerNetworkIpvlanPersistance(t *testing.T) { } func TestDockerNetworkIpvlan(t *testing.T) { - skip.If(t, testEnv.DaemonInfo.OSType == "windows") skip.If(t, testEnv.IsRemoteDaemon) skip.If(t, !ipvlanKernelSupport(t), "Kernel doesn't support ipvlan") From 0c8bc0b57a66c079ac02fdc204127e28acf5f03b Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 28 Jun 2019 11:36:09 +0200 Subject: [PATCH 02/59] Integration: remove "experimental" option for IPVLAN test-daemons IPVLAN no longer is experimental since 3ab093d5670e8d59f6ae0c4604b8fcabf1582854, so there's no need to set this option. Signed-off-by: Sebastiaan van Stijn (cherry picked from commit dae9bac6757af3027b06a983b8448ffa962cc071) Signed-off-by: Sebastiaan van Stijn --- integration/network/ipvlan/ipvlan_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integration/network/ipvlan/ipvlan_test.go b/integration/network/ipvlan/ipvlan_test.go index 569a4b7db95a3..1fea14338da4a 100644 --- a/integration/network/ipvlan/ipvlan_test.go +++ b/integration/network/ipvlan/ipvlan_test.go @@ -25,7 +25,7 @@ func TestDockerNetworkIpvlanPersistance(t *testing.T) { skip.If(t, testEnv.IsRemoteDaemon) skip.If(t, !ipvlanKernelSupport(t), "Kernel doesn't support ipvlan") - d := daemon.New(t, daemon.WithExperimental) + d := daemon.New(t) d.StartWithBusybox(t) defer d.Stop(t) @@ -85,7 +85,7 @@ func TestDockerNetworkIpvlan(t *testing.T) { test: testIpvlanAddressing, }, } { - d := daemon.New(t, daemon.WithExperimental) + d := daemon.New(t) d.StartWithBusybox(t) c := d.NewClientT(t) From 0378afaf5faf7e66ac880848c191da7ba6f2444d Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 28 Jun 2019 12:01:53 +0200 Subject: [PATCH 03/59] Integration: IPVlan add missing import comment Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 93b28677bffcdaf299969c4ff1603b7d07b45fbc) Signed-off-by: Sebastiaan van Stijn --- integration/network/ipvlan/ipvlan_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/network/ipvlan/ipvlan_test.go b/integration/network/ipvlan/ipvlan_test.go index 1fea14338da4a..e8cfb14d6eff0 100644 --- a/integration/network/ipvlan/ipvlan_test.go +++ b/integration/network/ipvlan/ipvlan_test.go @@ -1,6 +1,6 @@ // +build !windows -package ipvlan +package ipvlan // import "github.com/docker/docker/integration/network/ipvlan" import ( "context" From 1710bba5c337aa3d997c7fa3b64ebf2b971ffb8e Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Thu, 11 Jul 2019 10:10:37 +0200 Subject: [PATCH 04/59] Integration: exclude IPVlan test-suite on Windows Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 4060a7026c0ffa2983ab1fa41d43da4937ef63c6) Signed-off-by: Sebastiaan van Stijn --- integration/network/ipvlan/main_test.go | 2 ++ integration/network/ipvlan/main_windows_test.go | 1 + 2 files changed, 3 insertions(+) create mode 100644 integration/network/ipvlan/main_windows_test.go diff --git a/integration/network/ipvlan/main_test.go b/integration/network/ipvlan/main_test.go index 2d5f62453c4ba..0936647959dc8 100644 --- a/integration/network/ipvlan/main_test.go +++ b/integration/network/ipvlan/main_test.go @@ -1,3 +1,5 @@ +// +build !windows + package ipvlan // import "github.com/docker/docker/integration/network/ipvlan" import ( diff --git a/integration/network/ipvlan/main_windows_test.go b/integration/network/ipvlan/main_windows_test.go new file mode 100644 index 0000000000000..d016a04b66905 --- /dev/null +++ b/integration/network/ipvlan/main_windows_test.go @@ -0,0 +1 @@ +package ipvlan // import "github.com/docker/docker/integration/network/ipvlan" From 8c8de170d2e5ec6a78f3d9decb2ba1138d5fd658 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 28 Jun 2019 11:48:00 +0200 Subject: [PATCH 05/59] Integration: remove redundant kernel version check for MACVlan The daemon requires kernel 3.10 or up to start, so there's no need to check if the daemon is kernel 3.8 or up. Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 691eb142561818b0ca2255e2e340cbea6b91d80c) Signed-off-by: Sebastiaan van Stijn --- integration/network/macvlan/macvlan_test.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/integration/network/macvlan/macvlan_test.go b/integration/network/macvlan/macvlan_test.go index cb1f70a78f59e..12ff8c91b08dc 100644 --- a/integration/network/macvlan/macvlan_test.go +++ b/integration/network/macvlan/macvlan_test.go @@ -20,7 +20,6 @@ import ( func TestDockerNetworkMacvlanPersistance(t *testing.T) { // verify the driver automatically provisions the 802.1q link (dm-dummy0.60) skip.If(t, testEnv.IsRemoteDaemon) - skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") d := daemon.New(t) d.StartWithBusybox(t) @@ -43,7 +42,6 @@ func TestDockerNetworkMacvlanPersistance(t *testing.T) { func TestDockerNetworkMacvlan(t *testing.T) { skip.If(t, testEnv.IsRemoteDaemon) - skip.If(t, !macvlanKernelSupport(), "Kernel doesn't support macvlan") for _, tc := range []struct { name string @@ -271,8 +269,3 @@ func testMacvlanAddressing(client client.APIClient) func(*testing.T) { assert.Check(t, strings.Contains(result.Combined(), "default via 2001:db8:abca::254 dev eth0")) } } - -// ensure Kernel version is >= v3.9 for macvlan support -func macvlanKernelSupport() bool { - return n.CheckKernelMajorVersionGreaterOrEqualThen(3, 9) -} From edeff03134084cee40e7d199ef573a0e1bde2f9e Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 28 Jun 2019 11:58:11 +0200 Subject: [PATCH 06/59] Integration: MACVlan add missing import comment and build-tag Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 316e16618f8c794b8e56e223ed0bed15e1f4be24) Signed-off-by: Sebastiaan van Stijn --- integration/network/macvlan/macvlan_test.go | 2 +- integration/network/macvlan/main_test.go | 2 ++ integration/network/macvlan/main_windows_test.go | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 integration/network/macvlan/main_windows_test.go diff --git a/integration/network/macvlan/macvlan_test.go b/integration/network/macvlan/macvlan_test.go index 12ff8c91b08dc..b734cad82e8c8 100644 --- a/integration/network/macvlan/macvlan_test.go +++ b/integration/network/macvlan/macvlan_test.go @@ -1,6 +1,6 @@ // +build !windows -package macvlan +package macvlan // import "github.com/docker/docker/integration/network/macvlan" import ( "context" diff --git a/integration/network/macvlan/main_test.go b/integration/network/macvlan/main_test.go index 31cf111b22af7..15bdc323b5ecf 100644 --- a/integration/network/macvlan/main_test.go +++ b/integration/network/macvlan/main_test.go @@ -1,3 +1,5 @@ +// +build !windows + package macvlan // import "github.com/docker/docker/integration/network/macvlan" import ( diff --git a/integration/network/macvlan/main_windows_test.go b/integration/network/macvlan/main_windows_test.go new file mode 100644 index 0000000000000..367cd2c540679 --- /dev/null +++ b/integration/network/macvlan/main_windows_test.go @@ -0,0 +1 @@ +package macvlan // import "github.com/docker/docker/integration/network/macvlan" From f76cb3e6d54eb0582c0366a18ed49b2410090bdf Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 8 Jul 2019 18:31:34 +0200 Subject: [PATCH 07/59] integration-cli: remove ExecSupport check All current versions of Docker support exec, so no need to check for this. Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 7204341950c6c8f0a66f9bb0b082217dc0ce6ddb) Signed-off-by: Sebastiaan van Stijn --- integration-cli/docker_api_exec_test.go | 2 -- integration-cli/docker_cli_exec_test.go | 2 -- integration-cli/docker_cli_exec_unix_test.go | 2 +- integration-cli/docker_cli_links_test.go | 4 ++-- integration-cli/docker_cli_network_unix_test.go | 3 +-- integration-cli/docker_cli_run_test.go | 2 +- integration-cli/requirements_test.go | 4 ---- integration-cli/test_vars_exec_test.go | 8 -------- integration-cli/test_vars_noexec_test.go | 8 -------- 9 files changed, 5 insertions(+), 30 deletions(-) delete mode 100644 integration-cli/test_vars_exec_test.go delete mode 100644 integration-cli/test_vars_noexec_test.go diff --git a/integration-cli/docker_api_exec_test.go b/integration-cli/docker_api_exec_test.go index dcb14af6def4f..78c89f17b14c7 100644 --- a/integration-cli/docker_api_exec_test.go +++ b/integration-cli/docker_api_exec_test.go @@ -1,5 +1,3 @@ -// +build !test_no_exec - package main import ( diff --git a/integration-cli/docker_cli_exec_test.go b/integration-cli/docker_cli_exec_test.go index f6d4e3cf20e00..fcffeefe380e7 100644 --- a/integration-cli/docker_cli_exec_test.go +++ b/integration-cli/docker_cli_exec_test.go @@ -1,5 +1,3 @@ -// +build !test_no_exec - package main import ( diff --git a/integration-cli/docker_cli_exec_unix_test.go b/integration-cli/docker_cli_exec_unix_test.go index c36cf56519293..f2f89f2be090e 100644 --- a/integration-cli/docker_cli_exec_unix_test.go +++ b/integration-cli/docker_cli_exec_unix_test.go @@ -1,4 +1,4 @@ -// +build !windows,!test_no_exec +// +build !windows package main diff --git a/integration-cli/docker_cli_links_test.go b/integration-cli/docker_cli_links_test.go index 9be3ea117a1f3..8966caed1c97a 100644 --- a/integration-cli/docker_cli_links_test.go +++ b/integration-cli/docker_cli_links_test.go @@ -140,7 +140,7 @@ func (s *DockerSuite) TestLinksNotStartedParentNotFail(c *check.C) { func (s *DockerSuite) TestLinksHostsFilesInject(c *check.C) { testRequires(c, DaemonIsLinux) - testRequires(c, testEnv.IsLocalDaemon, ExecSupport) + testRequires(c, testEnv.IsLocalDaemon) out, _ := dockerCmd(c, "run", "-itd", "--name", "one", "busybox", "top") idOne := strings.TrimSpace(out) @@ -158,7 +158,7 @@ func (s *DockerSuite) TestLinksHostsFilesInject(c *check.C) { func (s *DockerSuite) TestLinksUpdateOnRestart(c *check.C) { testRequires(c, DaemonIsLinux) - testRequires(c, testEnv.IsLocalDaemon, ExecSupport) + testRequires(c, testEnv.IsLocalDaemon) dockerCmd(c, "run", "-d", "--name", "one", "busybox", "top") out, _ := dockerCmd(c, "run", "-d", "--name", "two", "--link", "one:onetwo", "--link", "one:one", "busybox", "top") id := strings.TrimSpace(string(out)) diff --git a/integration-cli/docker_cli_network_unix_test.go b/integration-cli/docker_cli_network_unix_test.go index fd0355adb5a57..a071edd3f62e2 100644 --- a/integration-cli/docker_cli_network_unix_test.go +++ b/integration-cli/docker_cli_network_unix_test.go @@ -805,7 +805,6 @@ func (s *DockerNetworkSuite) TestDockerPluginV2NetworkDriver(c *check.C) { } func (s *DockerDaemonSuite) TestDockerNetworkNoDiscoveryDefaultBridgeNetwork(c *check.C) { - testRequires(c, ExecSupport) // On default bridge network built-in service discovery should not happen hostsFile := "/etc/hosts" bridgeName := "external-bridge" @@ -863,7 +862,7 @@ func (s *DockerDaemonSuite) TestDockerNetworkNoDiscoveryDefaultBridgeNetwork(c * } func (s *DockerNetworkSuite) TestDockerNetworkAnonymousEndpoint(c *check.C) { - testRequires(c, ExecSupport, NotArm) + testRequires(c, NotArm) hostsFile := "/etc/hosts" cstmBridgeNw := "custom-bridge-nw" cstmBridgeNw1 := "custom-bridge-nw1" diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index 1a5204ff67603..6bbcb1145cdb2 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -3430,7 +3430,7 @@ func (s *DockerSuite) TestRunLoopbackWhenNetworkDisabled(c *check.C) { func (s *DockerSuite) TestRunModeNetContainerHostname(c *check.C) { // Windows does not support --net=container - testRequires(c, DaemonIsLinux, ExecSupport) + testRequires(c, DaemonIsLinux) dockerCmd(c, "run", "-i", "-d", "--name", "parent", "busybox", "top") out, _ := dockerCmd(c, "exec", "parent", "cat", "/etc/hostname") diff --git a/integration-cli/requirements_test.go b/integration-cli/requirements_test.go index 98220cfdecb1f..fd3f4efaad5d8 100644 --- a/integration-cli/requirements_test.go +++ b/integration-cli/requirements_test.go @@ -80,10 +80,6 @@ func UnixCli() bool { return isUnixCli } -func ExecSupport() bool { - return supportsExec -} - func Network() bool { // Set a timeout on the GET at 15s var timeout = time.Duration(15 * time.Second) diff --git a/integration-cli/test_vars_exec_test.go b/integration-cli/test_vars_exec_test.go deleted file mode 100644 index 7633b346ba9bd..0000000000000 --- a/integration-cli/test_vars_exec_test.go +++ /dev/null @@ -1,8 +0,0 @@ -// +build !test_no_exec - -package main - -const ( - // indicates docker daemon tested supports 'docker exec' - supportsExec = true -) diff --git a/integration-cli/test_vars_noexec_test.go b/integration-cli/test_vars_noexec_test.go deleted file mode 100644 index 08450905247f2..0000000000000 --- a/integration-cli/test_vars_noexec_test.go +++ /dev/null @@ -1,8 +0,0 @@ -// +build test_no_exec - -package main - -const ( - // indicates docker daemon tested supports 'docker exec' - supportsExec = false -) From a63a02fefd32d852b4de100e00a12a3a5803298e Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 8 Jul 2019 18:42:08 +0200 Subject: [PATCH 08/59] integration-cli: remove defaultSleepImage constant Both Linux and Windows now use busybox, so no need to keep a constant for this. Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 27f432ca57fb6d4d0409fc3c5358b74feae228cc) Signed-off-by: Sebastiaan van Stijn --- integration-cli/benchmark_test.go | 2 +- integration-cli/docker_cli_service_scale_test.go | 4 ++-- integration-cli/docker_utils_test.go | 2 +- integration-cli/test_vars_unix_test.go | 4 ---- integration-cli/test_vars_windows_test.go | 4 ---- 5 files changed, 4 insertions(+), 12 deletions(-) diff --git a/integration-cli/benchmark_test.go b/integration-cli/benchmark_test.go index ed51f79ead656..47f164ff38be8 100644 --- a/integration-cli/benchmark_test.go +++ b/integration-cli/benchmark_test.go @@ -28,7 +28,7 @@ func (s *DockerSuite) BenchmarkConcurrentContainerActions(c *check.C) { go func() { defer innerGroup.Done() for i := 0; i < numIterations; i++ { - args := []string{"run", "-d", defaultSleepImage} + args := []string{"run", "-d", "busybox"} args = append(args, sleepCommandForDaemonPlatform()...) out, _, err := dockerCmdWithError(args...) if err != nil { diff --git a/integration-cli/docker_cli_service_scale_test.go b/integration-cli/docker_cli_service_scale_test.go index f02bc738aad93..25a0e145c1823 100644 --- a/integration-cli/docker_cli_service_scale_test.go +++ b/integration-cli/docker_cli_service_scale_test.go @@ -14,11 +14,11 @@ func (s *DockerSwarmSuite) TestServiceScale(c *check.C) { d := s.AddDaemon(c, true, true) service1Name := "TestService1" - service1Args := append([]string{"service", "create", "--detach", "--no-resolve-image", "--name", service1Name, defaultSleepImage}, sleepCommandForDaemonPlatform()...) + service1Args := append([]string{"service", "create", "--detach", "--no-resolve-image", "--name", service1Name, "busybox"}, sleepCommandForDaemonPlatform()...) // global mode service2Name := "TestService2" - service2Args := append([]string{"service", "create", "--detach", "--no-resolve-image", "--name", service2Name, "--mode=global", defaultSleepImage}, sleepCommandForDaemonPlatform()...) + service2Args := append([]string{"service", "create", "--detach", "--no-resolve-image", "--name", service2Name, "--mode=global", "busybox"}, sleepCommandForDaemonPlatform()...) // Create services _, err := d.Cmd(service1Args...) diff --git a/integration-cli/docker_utils_test.go b/integration-cli/docker_utils_test.go index c142564483974..1d84e63e5e383 100644 --- a/integration-cli/docker_utils_test.go +++ b/integration-cli/docker_utils_test.go @@ -347,7 +347,7 @@ func getInspectBody(c *check.C, version, id string) []byte { // Run a long running idle task in a background container using the // system-specific default image and command. func runSleepingContainer(c *check.C, extraArgs ...string) string { - return runSleepingContainerInImage(c, defaultSleepImage, extraArgs...) + return runSleepingContainerInImage(c, "busybox", extraArgs...) } // Run a long running idle task in a background container using the specified diff --git a/integration-cli/test_vars_unix_test.go b/integration-cli/test_vars_unix_test.go index f9ecc01123cd9..1ab8a5ca48700 100644 --- a/integration-cli/test_vars_unix_test.go +++ b/integration-cli/test_vars_unix_test.go @@ -7,8 +7,4 @@ const ( isUnixCli = true expectedFileChmod = "-rw-r--r--" - - // On Unix variants, the busybox image comes with the `top` command which - // runs indefinitely while still being interruptible by a signal. - defaultSleepImage = "busybox" ) diff --git a/integration-cli/test_vars_windows_test.go b/integration-cli/test_vars_windows_test.go index bfc9a5a915c09..f81ac53cc31e5 100644 --- a/integration-cli/test_vars_windows_test.go +++ b/integration-cli/test_vars_windows_test.go @@ -8,8 +8,4 @@ const ( // this is the expected file permission set on windows: gh#11395 expectedFileChmod = "-rwxr-xr-x" - - // On Windows, the busybox image doesn't have the `top` command, so we rely - // on `sleep` with a high duration. - defaultSleepImage = "busybox" ) From e286096089cec30158f991538837e30f6c2daeb9 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 8 Jul 2019 18:58:46 +0200 Subject: [PATCH 09/59] integration-cli: remove unused requirements utils Removes some test functions that were unused: - bridgeNfIP6tables - ambientCapabilities (added to support #26979, which was reverted in #27737) - overlay2Supported Signed-off-by: Sebastiaan van Stijn (cherry picked from commit c887b09abc7d4ae149a9c314f74f9c351ac4cba2) Signed-off-by: Sebastiaan van Stijn --- integration-cli/requirements_unix_test.go | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/integration-cli/requirements_unix_test.go b/integration-cli/requirements_unix_test.go index cea1db1e6d73c..c309824de7523 100644 --- a/integration-cli/requirements_unix_test.go +++ b/integration-cli/requirements_unix_test.go @@ -84,20 +84,11 @@ func bridgeNfIptables() bool { return !SysInfo.BridgeNFCallIPTablesDisabled } -func bridgeNfIP6tables() bool { - return !SysInfo.BridgeNFCallIP6TablesDisabled -} - func unprivilegedUsernsClone() bool { content, err := ioutil.ReadFile("/proc/sys/kernel/unprivileged_userns_clone") return err != nil || !strings.Contains(string(content), "0") } -func ambientCapabilities() bool { - content, err := ioutil.ReadFile("/proc/self/status") - return err != nil || strings.Contains(string(content), "CapAmb:") -} - func overlayFSSupported() bool { cmd := exec.Command(dockerBinary, "run", "--rm", "busybox", "/bin/sh", "-c", "cat /proc/filesystems") out, err := cmd.CombinedOutput() @@ -107,20 +98,6 @@ func overlayFSSupported() bool { return bytes.Contains(out, []byte("overlay\n")) } -func overlay2Supported() bool { - if !overlayFSSupported() { - return false - } - - daemonV, err := kernel.ParseRelease(testEnv.DaemonInfo.KernelVersion) - if err != nil { - return false - } - requiredV := kernel.VersionInfo{Kernel: 4} - return kernel.CompareKernelVersion(*daemonV, requiredV) > -1 - -} - func init() { if testEnv.IsLocalDaemon() { SysInfo = sysinfo.New(true) From 34418110ecc9135ba9dcd50952ee0c3764fc4d83 Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Thu, 11 Jul 2019 16:42:16 -0700 Subject: [PATCH 10/59] Add (hidden) flags to set containerd namespaces This allows our tests, which all share a containerd instance, to be a bit more isolated by setting the containerd namespaces to the generated daemon ID's rather than the default namespaces. This came about because I found in some cases we had test daemons failing to start (really very slow to start) because it was (seemingly) processing events from other tests. Signed-off-by: Brian Goff (cherry picked from commit 24ad2f486d92681080a8e257760b047f8de2c71c) Signed-off-by: Sebastiaan van Stijn --- cmd/dockerd/config.go | 10 +++++++++- daemon/config/config.go | 3 +++ daemon/daemon.go | 8 ++++---- daemon/daemon_unix.go | 3 +++ integration-cli/docker_cli_daemon_test.go | 7 +++---- internal/test/daemon/daemon.go | 8 ++++++++ plugin/executor/containerd/containerd.go | 4 ++-- 7 files changed, 32 insertions(+), 11 deletions(-) diff --git a/cmd/dockerd/config.go b/cmd/dockerd/config.go index b28ac1cdc4ddf..c6c6b8a7a1c73 100644 --- a/cmd/dockerd/config.go +++ b/cmd/dockerd/config.go @@ -3,8 +3,10 @@ package main import ( "runtime" + "github.com/docker/docker/daemon" "github.com/docker/docker/daemon/config" "github.com/docker/docker/opts" + "github.com/docker/docker/plugin/executor/containerd" "github.com/docker/docker/registry" "github.com/spf13/pflag" ) @@ -85,7 +87,13 @@ func installCommonConfigFlags(conf *config.Config, flags *pflag.FlagSet) error { conf.MaxConcurrentDownloads = &maxConcurrentDownloads conf.MaxConcurrentUploads = &maxConcurrentUploads - return nil + + flags.StringVar(&conf.ContainerdNamespace, "containerd-namespace", daemon.ContainersNamespace, "Containerd namespace to use") + if err := flags.MarkHidden("containerd-namespace"); err != nil { + return err + } + flags.StringVar(&conf.ContainerdPluginNamespace, "containerd-plugins-namespace", containerd.PluginNamespace, "Containerd namespace to use for plugins") + return flags.MarkHidden("containerd-plugins-namespace") } func installRegistryServiceFlags(options *registry.ServiceOptions, flags *pflag.FlagSet) { diff --git a/daemon/config/config.go b/daemon/config/config.go index 3b23d7aecb55b..9ccb7b2362476 100644 --- a/daemon/config/config.go +++ b/daemon/config/config.go @@ -235,6 +235,9 @@ type CommonConfig struct { Features map[string]bool `json:"features,omitempty"` Builder BuilderConfig `json:"builder,omitempty"` + + ContainerdNamespace string `json:"containerd-namespace,omitempty"` + ContainerdPluginNamespace string `json:"containerd-plugin-namespace,omitempty"` } // IsValueSet returns true if a configuration value diff --git a/daemon/daemon.go b/daemon/daemon.go index e14aa0aeff7a0..014ec970a98a4 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -875,7 +875,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S grpc.WithDefaultCallOptions(grpc.MaxCallSendMsgSize(defaults.DefaultMaxSendMsgSize)), } if config.ContainerdAddr != "" { - d.containerdCli, err = containerd.New(config.ContainerdAddr, containerd.WithDefaultNamespace(ContainersNamespace), containerd.WithDialOpts(gopts), containerd.WithTimeout(60*time.Second)) + d.containerdCli, err = containerd.New(config.ContainerdAddr, containerd.WithDefaultNamespace(config.ContainerdNamespace), containerd.WithDialOpts(gopts), containerd.WithTimeout(60*time.Second)) if err != nil { return nil, errors.Wrapf(err, "failed to dial %q", config.ContainerdAddr) } @@ -887,13 +887,13 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S // Windows is not currently using containerd, keep the // client as nil if config.ContainerdAddr != "" { - pluginCli, err = containerd.New(config.ContainerdAddr, containerd.WithDefaultNamespace(pluginexec.PluginNamespace), containerd.WithDialOpts(gopts), containerd.WithTimeout(60*time.Second)) + pluginCli, err = containerd.New(config.ContainerdAddr, containerd.WithDefaultNamespace(config.ContainerdPluginNamespace), containerd.WithDialOpts(gopts), containerd.WithTimeout(60*time.Second)) if err != nil { return nil, errors.Wrapf(err, "failed to dial %q", config.ContainerdAddr) } } - return pluginexec.New(ctx, getPluginExecRoot(config.Root), pluginCli, m) + return pluginexec.New(ctx, getPluginExecRoot(config.Root), pluginCli, config.ContainerdPluginNamespace, m) } // Plugin system initialization should happen before restore. Do not change order. @@ -1041,7 +1041,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S go d.execCommandGC() - d.containerd, err = libcontainerd.NewClient(ctx, d.containerdCli, filepath.Join(config.ExecRoot, "containerd"), ContainersNamespace, d) + d.containerd, err = libcontainerd.NewClient(ctx, d.containerdCli, filepath.Join(config.ExecRoot, "containerd"), config.ContainerdNamespace, d) if err != nil { return nil, err } diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go index f3c68a2d2f7bd..066d52328faed 100644 --- a/daemon/daemon_unix.go +++ b/daemon/daemon_unix.go @@ -736,6 +736,9 @@ func (daemon *Daemon) initRuntimes(runtimes map[string]types.Runtime) (err error // verifyDaemonSettings performs validation of daemon config struct func verifyDaemonSettings(conf *config.Config) error { + if conf.ContainerdNamespace == conf.ContainerdPluginNamespace { + return errors.New("containers namespace and plugins namespace cannot be the same") + } // Check for mutually incompatible config options if conf.BridgeConfig.Iface != "" && conf.BridgeConfig.IP != "" { return fmt.Errorf("You specified -b & --bip, mutually exclusive options. Please specify only one") diff --git a/integration-cli/docker_cli_daemon_test.go b/integration-cli/docker_cli_daemon_test.go index 9d84d9c7dd37b..eb9ce34d71cdd 100644 --- a/integration-cli/docker_cli_daemon_test.go +++ b/integration-cli/docker_cli_daemon_test.go @@ -26,7 +26,6 @@ import ( "github.com/cloudflare/cfssl/helpers" "github.com/creack/pty" "github.com/docker/docker/api/types" - moby_daemon "github.com/docker/docker/daemon" "github.com/docker/docker/integration-cli/checker" "github.com/docker/docker/integration-cli/cli" "github.com/docker/docker/integration-cli/cli/build" @@ -1457,7 +1456,7 @@ func (s *DockerDaemonSuite) TestCleanupMountsAfterDaemonAndContainerKill(c *chec // kill the container icmd.RunCommand(ctrBinary, "--address", containerdSocket, - "--namespace", moby_daemon.ContainersNamespace, "tasks", "kill", id).Assert(c, icmd.Success) + "--namespace", d.ContainersNamespace(), "tasks", "kill", id).Assert(c, icmd.Success) // restart daemon. d.Restart(c) @@ -1977,7 +1976,7 @@ func (s *DockerDaemonSuite) TestDaemonRestartWithKilledRunningContainer(t *check // kill the container icmd.RunCommand(ctrBinary, "--address", containerdSocket, - "--namespace", moby_daemon.ContainersNamespace, "tasks", "kill", cid).Assert(t, icmd.Success) + "--namespace", s.d.ContainersNamespace(), "tasks", "kill", cid).Assert(t, icmd.Success) // Give time to containerd to process the command if we don't // the exit event might be received after we do the inspect @@ -2080,7 +2079,7 @@ func (s *DockerDaemonSuite) TestDaemonRestartWithUnpausedRunningContainer(t *che result := icmd.RunCommand( ctrBinary, "--address", containerdSocket, - "--namespace", moby_daemon.ContainersNamespace, + "--namespace", s.d.ContainersNamespace(), "tasks", "resume", cid) result.Assert(t, icmd.Success) diff --git a/internal/test/daemon/daemon.go b/internal/test/daemon/daemon.go index 8e6b33c98f963..4cd5b39606c8e 100644 --- a/internal/test/daemon/daemon.go +++ b/internal/test/daemon/daemon.go @@ -147,6 +147,11 @@ func New(t testingT, ops ...func(*Daemon)) *Daemon { return d } +// ContainersNamespace returns the containerd namespace used for containers. +func (d *Daemon) ContainersNamespace() string { + return d.id +} + // RootDir returns the root directory of the daemon. func (d *Daemon) RootDir() string { return d.Root @@ -231,12 +236,15 @@ func (d *Daemon) StartWithLogFile(out *os.File, providedArgs ...string) error { if err != nil { return errors.Wrapf(err, "[%s] could not find docker binary in $PATH", d.id) } + args := append(d.GlobalFlags, "--containerd", containerdSocket, "--data-root", d.Root, "--exec-root", d.execRoot, "--pidfile", fmt.Sprintf("%s/docker.pid", d.Folder), fmt.Sprintf("--userland-proxy=%t", d.userlandProxy), + "--containerd-namespace", d.id, + "--containerd-plugins-namespace", d.id+"p", ) if d.experimental { args = append(args, "--experimental") diff --git a/plugin/executor/containerd/containerd.go b/plugin/executor/containerd/containerd.go index 23418558d8b03..85a159f1ac20c 100644 --- a/plugin/executor/containerd/containerd.go +++ b/plugin/executor/containerd/containerd.go @@ -26,13 +26,13 @@ type ExitHandler interface { } // New creates a new containerd plugin executor -func New(ctx context.Context, rootDir string, cli *containerd.Client, exitHandler ExitHandler) (*Executor, error) { +func New(ctx context.Context, rootDir string, cli *containerd.Client, ns string, exitHandler ExitHandler) (*Executor, error) { e := &Executor{ rootDir: rootDir, exitHandler: exitHandler, } - client, err := libcontainerd.NewClient(ctx, cli, rootDir, PluginNamespace, e) + client, err := libcontainerd.NewClient(ctx, cli, rootDir, ns, e) if err != nil { return nil, errors.Wrap(err, "error creating containerd exec client") } From ad8327f2cef6413dc38260e8630177c548f417ac Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 12 Jul 2019 12:11:05 +0200 Subject: [PATCH 11/59] integration: fix cleanup of raft data The directory used for storage was either changed or new directories were added. Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 6a64a4deecf5b7519d3748023765f79628059f80) Signed-off-by: Sebastiaan van Stijn --- internal/test/daemon/daemon.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/internal/test/daemon/daemon.go b/internal/test/daemon/daemon.go index 4cd5b39606c8e..31166d5dfd3af 100644 --- a/internal/test/daemon/daemon.go +++ b/internal/test/daemon/daemon.go @@ -708,8 +708,10 @@ func cleanupRaftDir(t testingT, rootPath string) { if ht, ok := t.(test.HelperT); ok { ht.Helper() } - walDir := filepath.Join(rootPath, "swarm/raft/wal") - if err := os.RemoveAll(walDir); err != nil { - t.Logf("error removing %v: %v", walDir, err) + for _, p := range []string{"wal", "wal-v3-encrypted", "snap-v3-encrypted"} { + dir := filepath.Join(rootPath, "swarm/raft", p) + if err := os.RemoveAll(dir); err != nil { + t.Logf("error removing %v: %v", dir, err) + } } } From 05c096a1ac062784b9f23f8aca5cbb3cd50e77d9 Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Fri, 12 Jul 2019 09:51:32 -0700 Subject: [PATCH 12/59] Don't log test initial test daemon ping failures This is just noise due to timing. I picked `> 2` just based on logs from tests I've seen there's always 1 or 2. Signed-off-by: Brian Goff (cherry picked from commit 15675e28f1e3ba25f3abd099c14a7800c8bae2b8) Signed-off-by: Sebastiaan van Stijn --- internal/test/daemon/daemon.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/internal/test/daemon/daemon.go b/internal/test/daemon/daemon.go index 31166d5dfd3af..a77835b19d4fe 100644 --- a/internal/test/daemon/daemon.go +++ b/internal/test/daemon/daemon.go @@ -321,7 +321,7 @@ func (d *Daemon) StartWithLogFile(out *os.File, providedArgs ...string) error { defer cancel() // make sure daemon is ready to receive requests - for { + for i := 0; ; i++ { d.log.Logf("[%s] waiting for daemon to start", d.id) select { @@ -335,9 +335,14 @@ func (d *Daemon) StartWithLogFile(out *os.File, providedArgs ...string) error { resp, err := client.Do(req.WithContext(rctx)) if err != nil { - d.log.Logf("[%s] error pinging daemon on start: %v", d.id, err) - - time.Sleep(500 * time.Millisecond) + if i > 2 { // don't log the first couple, this ends up just being noise + d.log.Logf("[%s] error pinging daemon on start: %v", d.id, err) + } + + select { + case <-ctx.Done(): + case <-time.After(500 * time.Microsecond): + } continue } From eeeb2e941d09863ef3ec419254668e95b532f85c Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Fri, 12 Jul 2019 18:41:08 -0700 Subject: [PATCH 13/59] Fix Microsecond -> Milisecond. A bit too quick on the trigger on some text completion I think... Signed-off-by: Brian Goff (cherry picked from commit 5d818213ff3b9f8cda8e4fb3b071bef8fab782ad) Signed-off-by: Sebastiaan van Stijn --- internal/test/daemon/daemon.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/test/daemon/daemon.go b/internal/test/daemon/daemon.go index a77835b19d4fe..7ad377347989c 100644 --- a/internal/test/daemon/daemon.go +++ b/internal/test/daemon/daemon.go @@ -341,7 +341,7 @@ func (d *Daemon) StartWithLogFile(out *os.File, providedArgs ...string) error { select { case <-ctx.Done(): - case <-time.After(500 * time.Microsecond): + case <-time.After(500 * time.Millisecond): } continue } From bf212c5b331ae50de9af655a7fa6ea294b2bfe76 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Sat, 13 Jul 2019 03:13:37 +0200 Subject: [PATCH 14/59] DockerSwarmSuite lock portIndex to work around race Signed-off-by: Sebastiaan van Stijn (cherry picked from commit c096225e8ee6cb36e363ac38de4e4a566cf09918) Signed-off-by: Sebastiaan van Stijn --- integration-cli/check_test.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/integration-cli/check_test.go b/integration-cli/check_test.go index 2a0b1a25d53bd..38eb63579c27d 100644 --- a/integration-cli/check_test.go +++ b/integration-cli/check_test.go @@ -304,8 +304,8 @@ func init() { type DockerSwarmSuite struct { server *httptest.Server ds *DockerSuite + daemonsLock sync.Mutex // protect access to daemons and portIndex daemons []*daemon.Daemon - daemonsLock sync.Mutex // protect access to daemons portIndex int } @@ -336,8 +336,8 @@ func (s *DockerSwarmSuite) AddDaemon(c *check.C, joinSwarm, manager bool) *daemo d.StartNode(c) } - s.portIndex++ s.daemonsLock.Lock() + s.portIndex++ s.daemons = append(s.daemons, d) s.daemonsLock.Unlock() @@ -354,9 +354,8 @@ func (s *DockerSwarmSuite) TearDownTest(c *check.C) { } } s.daemons = nil - s.daemonsLock.Unlock() - s.portIndex = 0 + s.daemonsLock.Unlock() s.ds.TearDownTest(c) } From 7e7643853750ac74a27b39b39fa4a8448a29a374 Mon Sep 17 00:00:00 2001 From: Deep Debroy Date: Wed, 17 Jul 2019 13:13:50 -0700 Subject: [PATCH 15/59] Be more conservative for Windows in TestFrequency for Splunk Signed-off-by: Deep Debroy (cherry picked from commit a5c420ac54f07dbc84bcdea91b83364a25f1c921) Signed-off-by: Sebastiaan van Stijn --- daemon/logger/splunk/splunk_test.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/daemon/logger/splunk/splunk_test.go b/daemon/logger/splunk/splunk_test.go index 654e96a309648..db1e905a737a2 100644 --- a/daemon/logger/splunk/splunk_test.go +++ b/daemon/logger/splunk/splunk_test.go @@ -925,7 +925,12 @@ func TestFrequency(t *testing.T) { // 1 to verify connection and 10 to verify that we have sent messages with required frequency, // but because frequency is too small (to keep test quick), instead of 11, use 9 if context switches will be slow - if hec.numOfRequests < 9 { + expectedRequests := 9 + if runtime.GOOS == "windows" { + // sometimes in Windows, this test fails with number of requests showing 8. So be more conservative. + expectedRequests = 7 + } + if hec.numOfRequests < expectedRequests { t.Fatalf("Unexpected number of requests %d", hec.numOfRequests) } From 1d795b53d3bc820e73b987e6a7ffdc9bbe801c3c Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 17 Jul 2019 23:40:37 +0200 Subject: [PATCH 16/59] integration: run build session tests on non-experimental The session endpoint is no longer experimental since 01c9e7082eba71cbe60ce2e47acb9aad2c83c7ef, so we don't need to start an experimental daemon. Signed-off-by: Sebastiaan van Stijn (cherry picked from commit becd29c6651dffc253027e15f903ae7e7c918594) Signed-off-by: Sebastiaan van Stijn --- integration/build/build_session_test.go | 15 +++------------ integration/session/session_test.go | 20 +++----------------- 2 files changed, 6 insertions(+), 29 deletions(-) diff --git a/integration/build/build_session_test.go b/integration/build/build_session_test.go index db5124f4c796c..578ea2102c8bc 100644 --- a/integration/build/build_session_test.go +++ b/integration/build/build_session_test.go @@ -9,8 +9,8 @@ import ( "testing" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/versions" dclient "github.com/docker/docker/client" - "github.com/docker/docker/internal/test/daemon" "github.com/docker/docker/internal/test/fakecontext" "github.com/docker/docker/internal/test/request" "github.com/moby/buildkit/session" @@ -23,18 +23,9 @@ import ( func TestBuildWithSession(t *testing.T) { skip.If(t, testEnv.DaemonInfo.OSType == "windows") + skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.39"), "experimental in older versions") - var client dclient.APIClient - if !testEnv.DaemonInfo.ExperimentalBuild { - skip.If(t, testEnv.IsRemoteDaemon, "cannot run daemon when remote daemon") - - d := daemon.New(t, daemon.WithExperimental) - d.StartWithBusybox(t) - defer d.Stop(t) - client = d.NewClientT(t) - } else { - client = testEnv.APIClient() - } + client := testEnv.APIClient() dockerfile := ` FROM busybox diff --git a/integration/session/session_test.go b/integration/session/session_test.go index f5602f944904e..2f8d79c0e784f 100644 --- a/integration/session/session_test.go +++ b/integration/session/session_test.go @@ -4,7 +4,7 @@ import ( "net/http" "testing" - "github.com/docker/docker/internal/test/daemon" + "github.com/docker/docker/api/types/versions" req "github.com/docker/docker/internal/test/request" "gotest.tools/assert" is "gotest.tools/assert/cmp" @@ -13,17 +13,10 @@ import ( func TestSessionCreate(t *testing.T) { skip.If(t, testEnv.OSType == "windows", "FIXME") + skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.39"), "experimental in older versions") defer setupTest(t)() daemonHost := req.DaemonHost() - if !testEnv.DaemonInfo.ExperimentalBuild { - skip.If(t, testEnv.IsRemoteDaemon, "cannot run daemon when remote daemon") - - d := daemon.New(t, daemon.WithExperimental) - d.StartWithBusybox(t) - defer d.Stop(t) - daemonHost = d.Sock() - } res, body, err := req.Post("/session", req.Host(daemonHost), @@ -41,17 +34,10 @@ func TestSessionCreate(t *testing.T) { func TestSessionCreateWithBadUpgrade(t *testing.T) { skip.If(t, testEnv.OSType == "windows", "FIXME") + skip.If(t, versions.LessThan(testEnv.DaemonAPIVersion(), "1.39"), "experimental in older versions") defer setupTest(t)() daemonHost := req.DaemonHost() - if !testEnv.DaemonInfo.ExperimentalBuild { - skip.If(t, testEnv.IsRemoteDaemon, "cannot run daemon when remote daemon") - - d := daemon.New(t, daemon.WithExperimental) - d.StartWithBusybox(t) - defer d.Stop(t) - daemonHost = d.Sock() - } res, body, err := req.Post("/session", req.Host(daemonHost)) assert.NilError(t, err) From 1204f3a77c15427f8e265c0ebb5a8d847243af44 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Wed, 17 Jul 2019 18:27:28 -0700 Subject: [PATCH 17/59] integration-cli: increase healthcheck timeout Signed-off-by: Tonis Tiigi (cherry picked from commit 8c9362857f352548b94bc39c675d558b4da0d3b3) Signed-off-by: Sebastiaan van Stijn --- integration-cli/docker_cli_service_health_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-cli/docker_cli_service_health_test.go b/integration-cli/docker_cli_service_health_test.go index 8f6a69b0bc4ab..d72ad3fcf02a8 100644 --- a/integration-cli/docker_cli_service_health_test.go +++ b/integration-cli/docker_cli_service_health_test.go @@ -28,7 +28,7 @@ func (s *DockerSwarmSuite) TestServiceHealthRun(c *check.C) { result := cli.BuildCmd(c, imageName, cli.Daemon(d), build.WithDockerfile(`FROM busybox RUN touch /status - HEALTHCHECK --interval=1s --timeout=1s --retries=1\ + HEALTHCHECK --interval=1s --timeout=5s --retries=1\ CMD cat /status`), ) result.Assert(c, icmd.Success) From 2ebfdfd66c43a0d7495287b20d9e1189b45759a6 Mon Sep 17 00:00:00 2001 From: Drew Erny Date: Thu, 18 Jul 2019 12:58:21 -0500 Subject: [PATCH 18/59] Retry service updates on out of sequence errors Code retrying service update operations when receiving "update out of sequence" errors was removed because of a misunderstanding, which has made tests flaky. This re-adds the "CmdRetryOutOfSequence" method, and uses it in TestSwarmPublishAdd to avoid flaky behavior. Signed-off-by: Drew Erny (cherry picked from commit 1de914695b7d0c9affc97a6da4198548da2f5f78) Signed-off-by: Sebastiaan van Stijn --- integration-cli/daemon/daemon_swarm.go | 22 ++++++++++++++++++++++ integration-cli/docker_cli_swarm_test.go | 10 +++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/integration-cli/daemon/daemon_swarm.go b/integration-cli/daemon/daemon_swarm.go index 0c2f003bbdc4d..bbb124dd86300 100644 --- a/integration-cli/daemon/daemon_swarm.go +++ b/integration-cli/daemon/daemon_swarm.go @@ -189,3 +189,25 @@ func (d *Daemon) 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 +// up to 10 times, retrying if it encounters an "update out of sequence" error. +func (d *Daemon) CmdRetryOutOfSequence(args ...string) (string, error) { + var ( + output string + err error + ) + + for i := 0; i < 10; i++ { + output, err = d.Cmd(args...) + // error, no error, whatever. if we don't have "update out of + // sequence", we don't retry, we just return. + if !strings.Contains(output, "update out of sequence") { + return output, err + } + } + + // otherwise, once all of our attempts have been exhausted, just return + // whatever the last values were. + return output, err +} diff --git a/integration-cli/docker_cli_swarm_test.go b/integration-cli/docker_cli_swarm_test.go index 64d4fade55a8e..0eca47cd09d39 100644 --- a/integration-cli/docker_cli_swarm_test.go +++ b/integration-cli/docker_cli_swarm_test.go @@ -277,19 +277,23 @@ func (s *DockerSwarmSuite) TestSwarmPublishAdd(c *check.C) { d := s.AddDaemon(c, true, true) name := "top" + // this first command does not have to be retried because service creates + // don't return out of sequence errors. out, err := d.Cmd("service", "create", "--detach", "--no-resolve-image", "--name", name, "--label", "x=y", "busybox", "top") assert.NilError(c, err, out) assert.Assert(c, strings.TrimSpace(out) != "") - out, err = d.Cmd("service", "update", "--detach", "--publish-add", "80:80", name) + out, err = d.CmdRetryOutOfSequence("service", "update", "--detach", "--publish-add", "80:80", name) assert.NilError(c, err, out) - out, err = d.Cmd("service", "update", "--detach", "--publish-add", "80:80", name) + out, err = d.CmdRetryOutOfSequence("service", "update", "--detach", "--publish-add", "80:80", name) assert.NilError(c, err, out) - _, err = d.Cmd("service", "update", "--detach", "--publish-add", "80:80", "--publish-add", "80:20", name) + _, err = d.CmdRetryOutOfSequence("service", "update", "--detach", "--publish-add", "80:80", "--publish-add", "80:20", name) assert.ErrorContains(c, err, "") + // this last command does not have to be retried because service inspect + // does not return out of sequence errors. out, err = d.Cmd("service", "inspect", "--format", "{{ .Spec.EndpointSpec.Ports }}", name) assert.NilError(c, err, out) assert.Equal(c, strings.TrimSpace(out), "[{ tcp 80 80 ingress}]") From a768bf867360da307d0c37d35e6cfceec13dd231 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 19 Jul 2019 10:53:42 +0200 Subject: [PATCH 19/59] integration-cli: remove redundant "testrequires" The `DockerDaemonSuite.SetUpTest` already checks for Linux and a local daemon; ``` func (s *DockerDaemonSuite) SetUpTest(c *check.C) { testRequires(c, DaemonIsLinux, testEnv.IsLocalDaemon) s.d = daemon.New(c, dockerBinary, dockerdBinary, testdaemon.WithEnvironment(testEnv.Execution)) } ``` Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 7f37d99ef50b4046284ecb3c3b290319acf11405) Signed-off-by: Sebastiaan van Stijn --- integration-cli/docker_cli_daemon_plugins_test.go | 6 +++--- integration-cli/docker_cli_daemon_test.go | 2 -- integration-cli/docker_cli_events_unix_test.go | 2 -- integration-cli/docker_cli_exec_test.go | 3 +-- integration-cli/docker_cli_info_test.go | 1 - integration-cli/docker_cli_network_unix_test.go | 1 - integration-cli/docker_cli_proxy_test.go | 1 - integration-cli/docker_cli_run_unix_test.go | 8 ++++---- integration-cli/docker_cli_userns_test.go | 2 +- 9 files changed, 9 insertions(+), 17 deletions(-) diff --git a/integration-cli/docker_cli_daemon_plugins_test.go b/integration-cli/docker_cli_daemon_plugins_test.go index 355313f013101..033db85d70539 100644 --- a/integration-cli/docker_cli_daemon_plugins_test.go +++ b/integration-cli/docker_cli_daemon_plugins_test.go @@ -121,7 +121,7 @@ func (s *DockerDaemonSuite) TestDaemonShutdownLiveRestoreWithPlugins(c *check.C) // TestDaemonShutdownWithPlugins shuts down running plugins. func (s *DockerDaemonSuite) TestDaemonShutdownWithPlugins(c *check.C) { - testRequires(c, IsAmd64, Network, testEnv.IsLocalDaemon) + testRequires(c, IsAmd64, Network) s.d.Start(c) if out, err := s.d.Cmd("plugin", "install", "--grant-all-permissions", pName); err != nil { @@ -159,7 +159,7 @@ func (s *DockerDaemonSuite) TestDaemonShutdownWithPlugins(c *check.C) { // TestDaemonKillWithPlugins leaves plugins running. func (s *DockerDaemonSuite) TestDaemonKillWithPlugins(c *check.C) { - testRequires(c, IsAmd64, Network, testEnv.IsLocalDaemon) + testRequires(c, IsAmd64, Network) s.d.Start(c) if out, err := s.d.Cmd("plugin", "install", "--grant-all-permissions", pName); err != nil { @@ -232,7 +232,7 @@ func (s *DockerDaemonSuite) TestVolumePlugin(c *check.C) { } func (s *DockerDaemonSuite) TestPluginVolumeRemoveOnRestart(c *check.C) { - testRequires(c, DaemonIsLinux, Network, IsAmd64) + testRequires(c, IsAmd64, Network) s.d.Start(c, "--live-restore=true") diff --git a/integration-cli/docker_cli_daemon_test.go b/integration-cli/docker_cli_daemon_test.go index eb9ce34d71cdd..d27e7d7e57fe6 100644 --- a/integration-cli/docker_cli_daemon_test.go +++ b/integration-cli/docker_cli_daemon_test.go @@ -825,7 +825,6 @@ func (s *DockerDaemonSuite) TestDaemonDefaultGatewayIPv4ExplicitOutsideContainer } func (s *DockerDaemonSuite) TestDaemonDefaultNetworkInvalidClusterConfig(c *check.C) { - testRequires(c, DaemonIsLinux, testEnv.IsLocalDaemon) // Start daemon without docker0 bridge defaultNetworkBridge := "docker0" @@ -966,7 +965,6 @@ func (s *DockerDaemonSuite) TestDaemonLinksIpTablesRulesWhenLinkAndUnlink(c *che } func (s *DockerDaemonSuite) TestDaemonUlimitDefaults(c *check.C) { - testRequires(c, DaemonIsLinux) s.d.StartWithBusybox(c, "--default-ulimit", "nofile=42:42", "--default-ulimit", "nproc=1024:1024") diff --git a/integration-cli/docker_cli_events_unix_test.go b/integration-cli/docker_cli_events_unix_test.go index aaa7a91f1ef11..44252c9ac6fa3 100644 --- a/integration-cli/docker_cli_events_unix_test.go +++ b/integration-cli/docker_cli_events_unix_test.go @@ -388,7 +388,6 @@ func (s *DockerSuite) TestEventsFilterNetworkID(c *check.C) { } func (s *DockerDaemonSuite) TestDaemonEvents(c *check.C) { - testRequires(c, testEnv.IsLocalDaemon, DaemonIsLinux) // daemon config file configFilePath := "test.json" @@ -457,7 +456,6 @@ func (s *DockerDaemonSuite) TestDaemonEvents(c *check.C) { } func (s *DockerDaemonSuite) TestDaemonEventsWithFilters(c *check.C) { - testRequires(c, testEnv.IsLocalDaemon, DaemonIsLinux) // daemon config file configFilePath := "test.json" diff --git a/integration-cli/docker_cli_exec_test.go b/integration-cli/docker_cli_exec_test.go index fcffeefe380e7..72fa092824b0e 100644 --- a/integration-cli/docker_cli_exec_test.go +++ b/integration-cli/docker_cli_exec_test.go @@ -79,8 +79,7 @@ func (s *DockerSuite) TestExecAfterContainerRestart(c *check.C) { } func (s *DockerDaemonSuite) TestExecAfterDaemonRestart(c *check.C) { - // TODO Windows CI: Requires a little work to get this ported. - testRequires(c, DaemonIsLinux, testEnv.IsLocalDaemon) + // TODO Windows CI: DockerDaemonSuite doesn't run on Windows, and requires a little work to get this ported. s.d.StartWithBusybox(c) out, err := s.d.Cmd("run", "-d", "--name", "top", "-p", "80", "busybox:latest", "top") diff --git a/integration-cli/docker_cli_info_test.go b/integration-cli/docker_cli_info_test.go index 24d9c61a3c0e0..c569a0d1dfebe 100644 --- a/integration-cli/docker_cli_info_test.go +++ b/integration-cli/docker_cli_info_test.go @@ -211,7 +211,6 @@ func (s *DockerSuite) TestInsecureRegistries(c *check.C) { } func (s *DockerDaemonSuite) TestRegistryMirrors(c *check.C) { - testRequires(c, testEnv.IsLocalDaemon, DaemonIsLinux) registryMirror1 := "https://192.168.1.2" registryMirror2 := "http://registry.mirror.com:5000" diff --git a/integration-cli/docker_cli_network_unix_test.go b/integration-cli/docker_cli_network_unix_test.go index a071edd3f62e2..cbc953e581a8d 100644 --- a/integration-cli/docker_cli_network_unix_test.go +++ b/integration-cli/docker_cli_network_unix_test.go @@ -1664,7 +1664,6 @@ func (s *DockerNetworkSuite) TestDockerNetworkCreateDeleteSpecialCharacters(c *c } func (s *DockerDaemonSuite) TestDaemonRestartRestoreBridgeNetwork(t *check.C) { - testRequires(t, DaemonIsLinux) s.d.StartWithBusybox(t, "--live-restore") defer s.d.Stop(t) oldCon := "old" diff --git a/integration-cli/docker_cli_proxy_test.go b/integration-cli/docker_cli_proxy_test.go index d7bb1c8fbeba5..c444b611b51a8 100644 --- a/integration-cli/docker_cli_proxy_test.go +++ b/integration-cli/docker_cli_proxy_test.go @@ -21,7 +21,6 @@ func (s *DockerSuite) TestCLIProxyDisableProxyUnixSock(c *check.C) { // Can't use localhost here since go has a special case to not use proxy if connecting to localhost // See https://golang.org/pkg/net/http/#ProxyFromEnvironment func (s *DockerDaemonSuite) TestCLIProxyProxyTCPSock(c *check.C) { - testRequires(c, testEnv.IsLocalDaemon) // get the IP to use to connect since we can't use localhost addrs, err := net.InterfaceAddrs() assert.NilError(c, err) diff --git a/integration-cli/docker_cli_run_unix_test.go b/integration-cli/docker_cli_run_unix_test.go index b35d62a2060d5..1675418633de5 100644 --- a/integration-cli/docker_cli_run_unix_test.go +++ b/integration-cli/docker_cli_run_unix_test.go @@ -1442,7 +1442,7 @@ func (s *DockerSuite) TestRunUserDeviceAllowed(c *check.C) { } func (s *DockerDaemonSuite) TestRunSeccompJSONNewFormat(c *check.C) { - testRequires(c, testEnv.IsLocalDaemon, seccompEnabled) + testRequires(c, seccompEnabled) s.d.StartWithBusybox(c) @@ -1467,7 +1467,7 @@ func (s *DockerDaemonSuite) TestRunSeccompJSONNewFormat(c *check.C) { } func (s *DockerDaemonSuite) TestRunSeccompJSONNoNameAndNames(c *check.C) { - testRequires(c, testEnv.IsLocalDaemon, seccompEnabled) + testRequires(c, seccompEnabled) s.d.StartWithBusybox(c) @@ -1493,7 +1493,7 @@ func (s *DockerDaemonSuite) TestRunSeccompJSONNoNameAndNames(c *check.C) { } func (s *DockerDaemonSuite) TestRunSeccompJSONNoArchAndArchMap(c *check.C) { - testRequires(c, testEnv.IsLocalDaemon, seccompEnabled) + testRequires(c, seccompEnabled) s.d.StartWithBusybox(c) @@ -1530,7 +1530,7 @@ func (s *DockerDaemonSuite) TestRunSeccompJSONNoArchAndArchMap(c *check.C) { } func (s *DockerDaemonSuite) TestRunWithDaemonDefaultSeccompProfile(c *check.C) { - testRequires(c, testEnv.IsLocalDaemon, seccompEnabled) + testRequires(c, seccompEnabled) s.d.StartWithBusybox(c) diff --git a/integration-cli/docker_cli_userns_test.go b/integration-cli/docker_cli_userns_test.go index 1cbf367fe4dc7..c423f5cd433d3 100644 --- a/integration-cli/docker_cli_userns_test.go +++ b/integration-cli/docker_cli_userns_test.go @@ -23,7 +23,7 @@ import ( // 1. validate uid/gid maps are set properly // 2. verify that files created are owned by remapped root func (s *DockerDaemonSuite) TestDaemonUserNamespaceRootSetting(c *check.C) { - testRequires(c, DaemonIsLinux, testEnv.IsLocalDaemon, UserNamespaceInKernel) + testRequires(c, UserNamespaceInKernel) s.d.StartWithBusybox(c, "--userns-remap", "default") From 24395d55fc2c0dd31cd4b9010306d5cf7098e407 Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Wed, 24 Jul 2019 13:02:54 -0700 Subject: [PATCH 20/59] Better logging for swarm tests Call helper for starting swarm agents and add some logging with daemon id's when joining the swarm. Signed-off-by: Brian Goff (cherry picked from commit b0fe0dff7a5b7f70e2d08e59f4773c40e48e5c0d) Signed-off-by: Sebastiaan van Stijn --- internal/test/daemon/swarm.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/internal/test/daemon/swarm.go b/internal/test/daemon/swarm.go index b37593a3fb44f..08cb9895f6d8a 100644 --- a/internal/test/daemon/swarm.go +++ b/internal/test/daemon/swarm.go @@ -47,6 +47,9 @@ func (d *Daemon) StartAndSwarmInit(t testingT) { // 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) { + if th, ok := t.(test.HelperT); ok { + th.Helper() + } d.StartNode(t) tokens := leader.JoinTokens(t) @@ -54,6 +57,7 @@ func (d *Daemon) StartAndSwarmJoin(t testingT, leader *Daemon, manager bool) { if manager { token = tokens.Manager } + t.Logf("[%s] joining swarm manager [%s]@%s, swarm listen addr %s", d.id, leader.id, leader.SwarmListenAddr(), d.SwarmListenAddr()) d.SwarmJoin(t, swarm.JoinRequest{ RemoteAddrs: []string{leader.SwarmListenAddr()}, JoinToken: token, @@ -106,7 +110,7 @@ func (d *Daemon) SwarmJoin(t assert.TestingT, req swarm.JoinRequest) { cli := d.NewClientT(t) defer cli.Close() err := cli.SwarmJoin(context.Background(), req) - assert.NilError(t, err, "initializing swarm") + assert.NilError(t, err, "[%s] joining swarm", d.id) d.CachedInfo = d.Info(t) } From 316390891c9802a9040f3cec7fa1efc4a435141e Mon Sep 17 00:00:00 2001 From: Eli Uriegas Date: Wed, 24 Jul 2019 21:02:47 +0000 Subject: [PATCH 21/59] hack: Remove inContainer check, it wasn't useful The inContainer check isn't really useful anymore. Even though it was said that we shouldn't rely on its existence back in 2016, we're now in 2019 and this thing still exists so we should just rely on it now to check whether or not we're in a container. Signed-off-by: Eli Uriegas (cherry picked from commit f5cd8fdd446750a749182f3410adc6f1968053ca) Signed-off-by: Sebastiaan van Stijn --- hack/make.sh | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/hack/make.sh b/hack/make.sh index 29e39122351b0..f019e910f9e90 100755 --- a/hack/make.sh +++ b/hack/make.sh @@ -28,30 +28,6 @@ export SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" export MAKEDIR="$SCRIPTDIR/make" export PKG_CONFIG=${PKG_CONFIG:-pkg-config} -# We're a nice, sexy, little shell script, and people might try to run us; -# but really, they shouldn't. We want to be in a container! -inContainer="AssumeSoInitially" -if [ "$(go env GOHOSTOS)" = 'windows' ]; then - if [ -z "$FROM_DOCKERFILE" ]; then - unset inContainer - fi -else - if [ "$PWD" != "/go/src/$DOCKER_PKG" ]; then - unset inContainer - fi -fi - -if [ -z "$inContainer" ]; then - { - echo "# WARNING! I don't seem to be running in a Docker container." - echo "# The result of this command might be an incorrect build, and will not be" - echo "# officially supported." - echo "#" - echo "# Try this instead: make all" - echo "#" - } >&2 -fi - echo # List of bundles to create when no argument is passed From 1da2e90b5622092177faa2c94b3ebe70aeac3a16 Mon Sep 17 00:00:00 2001 From: SataQiu Date: Tue, 13 Aug 2019 22:46:32 +0800 Subject: [PATCH 22/59] fix some spelling mistakes Signed-off-by: SataQiu (cherry picked from commit f6226a2a56c38b790b59393ff4ce7f88f790c811) Signed-off-by: Sebastiaan van Stijn --- MAINTAINERS | 2 +- api/swagger.yaml | 2 +- integration-cli/docker_cli_restart_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 93013e004d4d8..81494a4d2bac8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -111,7 +111,7 @@ # still stumble into him in our issue tracker, or on IRC. "erikh", - # Evan Hazlett is the creator of of the Shipyard and Interlock open source projects, + # Evan Hazlett is the creator of the Shipyard and Interlock open source projects, # and the author of "Orca", which became the foundation of Docker Universal Control # Plane (UCP). As a maintainer, Evan helped integrating SwarmKit (secrets, tasks) # into the Docker engine. diff --git a/api/swagger.yaml b/api/swagger.yaml index 6e0bc25b52d6a..0e021fed6656a 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -3262,7 +3262,7 @@ definitions:


- - "ingress" makes the target port accessible on on every node, + - "ingress" makes the target port accessible on every node, regardless of whether there is a task for the service running on that node or not. - "host" bypasses the routing mesh and publish the port directly on diff --git a/integration-cli/docker_cli_restart_test.go b/integration-cli/docker_cli_restart_test.go index 566532583cff5..f6c41d5519080 100644 --- a/integration-cli/docker_cli_restart_test.go +++ b/integration-cli/docker_cli_restart_test.go @@ -292,7 +292,7 @@ func (s *DockerSuite) TestRestartContainerwithRestartPolicy(c *check.C) { dockerCmd(c, "start", id1) dockerCmd(c, "start", id2) - // Kill the containers, making sure the are stopped at the end of the test + // Kill the containers, making sure they are stopped at the end of the test dockerCmd(c, "kill", id1) dockerCmd(c, "kill", id2) err = waitInspect(id1, "{{ .State.Restarting }} {{ .State.Running }}", "false false", waitTimeout) From 14d561eb1cdd4d7a0deeabb271406b7ddd9131a3 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Sat, 24 Aug 2019 00:24:03 +0200 Subject: [PATCH 23/59] integration: simplify parallel run destination 'Namespace' parallel runs by bind-mounting a different directory in the container, instead of making the tests running inside the container aware of the namespaced location. This makes it transparent to the tests, and slightly reduces complexity. Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 3262a69be6c582e4543199ddc54ebe2e306e3637) Signed-off-by: Sebastiaan van Stijn --- Jenkinsfile | 4 ++-- Makefile | 1 - hack/make/test-integration | 6 ------ 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 26cc9e352481b..245bb0d97c457 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -257,13 +257,13 @@ pipeline { run_tests() { [ -n "$TESTDEBUG" ] && rm= || rm=--rm; docker run $rm -t --privileged \ - -v "$WORKSPACE/bundles:/go/src/github.com/docker/docker/bundles" \ + -v "$WORKSPACE/bundles/${TEST_INTEGRATION_DEST}:/go/src/github.com/docker/docker/bundles" \ + -v "$WORKSPACE/bundles/dynbinary-daemon:/go/src/github.com/docker/docker/bundles/dynbinary-daemon" \ -v "$WORKSPACE/.git:/go/src/github.com/docker/docker/.git" \ --name "$CONTAINER_NAME" \ -e KEEPBUNDLE=1 \ -e TESTDEBUG \ -e TESTFLAGS \ - -e TEST_INTEGRATION_DEST \ -e TEST_SKIP_INTEGRATION \ -e TEST_SKIP_INTEGRATION_CLI \ -e DOCKER_GITCOMMIT=${GIT_COMMIT} \ diff --git a/Makefile b/Makefile index ed9372a16a9ab..71f12d176e713 100644 --- a/Makefile +++ b/Makefile @@ -53,7 +53,6 @@ DOCKER_ENVS := \ -e DOCKER_TEST_HOST \ -e DOCKER_USERLANDPROXY \ -e DOCKERD_ARGS \ - -e TEST_INTEGRATION_DEST \ -e TEST_INTEGRATION_DIR \ -e TEST_SKIP_INTEGRATION \ -e TEST_SKIP_INTEGRATION_CLI \ diff --git a/hack/make/test-integration b/hack/make/test-integration index 039afc9526f85..5ea41b0a3220a 100755 --- a/hack/make/test-integration +++ b/hack/make/test-integration @@ -1,12 +1,6 @@ #!/usr/bin/env bash set -e -o pipefail -if [ -n "$TEST_INTEGRATION_DEST" ]; then - export DEST="$ABS_DEST/$TEST_INTEGRATION_DEST" - export DOCKER_INTEGRATION_DAEMON_DEST="$DEST" - mkdir -p "$DEST" -fi - source hack/make/.integration-test-helpers if [ ! -z "${TEST_SKIP_INTEGRATION}" ] && [ ! -z "${TEST_SKIP_INTEGRATION_CLI}" ]; then From 517ebe626ce08b0527ff80a86e14e3d8a5fe80f0 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Sun, 11 Aug 2019 20:32:49 +0200 Subject: [PATCH 24/59] integration: use gotestsum to generate junit.xml and go-test-report.json Signed-off-by: Sebastiaan van Stijn (cherry picked from commit f3be6b346f5300150dfa1de927880ea84440bb5b) Signed-off-by: Sebastiaan van Stijn --- Jenkinsfile | 35 ++++++++++++++++++++++++----- hack/make/.integration-test-helpers | 8 ++++++- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 245bb0d97c457..f93ab62d552fd 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -308,6 +308,11 @@ pipeline { exit $c ''' } + post { + always { + junit testResults: 'bundles/**/*-report.xml', allowEmptyResults: true + } + } } } @@ -328,7 +333,7 @@ pipeline { bundleName=amd64 echo "Creating ${bundleName}-bundles.tar.gz" # exclude overlay2 directories - find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*.log' -o -name '*.prof' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz + find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*-report.json' -o -name '*.log' -o -name '*.prof' -o -name '*-report.xml' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz ''' archiveArtifacts artifacts: '*-bundles.tar.gz', allowEmptyArchive: true @@ -405,6 +410,11 @@ pipeline { test-integration ''' } + post { + always { + junit testResults: 'bundles/**/*-report.xml', allowEmptyResults: true + } + } } } @@ -425,7 +435,7 @@ pipeline { bundleName=s390x-integration echo "Creating ${bundleName}-bundles.tar.gz" # exclude overlay2 directories - find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*.log' -o -name '*.prof' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz + find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*-report.json' -o -name '*.log' -o -name '*.prof' -o -name '*-report.xml' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz ''' archiveArtifacts artifacts: '*-bundles.tar.gz', allowEmptyArchive: true @@ -483,6 +493,11 @@ pipeline { test-integration ''' } + post { + always { + junit testResults: 'bundles/**/*-report.xml', allowEmptyResults: true + } + } } } @@ -503,7 +518,7 @@ pipeline { bundleName=s390x-integration-cli echo "Creating ${bundleName}-bundles.tar.gz" # exclude overlay2 directories - find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*.log' -o -name '*.prof' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz + find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*-report.json' -o -name '*.log' -o -name '*.prof' -o -name '*-report.xml' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz ''' archiveArtifacts artifacts: '*-bundles.tar.gz', allowEmptyArchive: true @@ -578,6 +593,11 @@ pipeline { test-integration ''' } + post { + always { + junit testResults: 'bundles/**/*-report.xml', allowEmptyResults: true + } + } } } @@ -598,7 +618,7 @@ pipeline { bundleName=ppc64le-integration echo "Creating ${bundleName}-bundles.tar.gz" # exclude overlay2 directories - find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*.log' -o -name '*.prof' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz + find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*-report.json' -o -name '*.log' -o -name '*.prof' -o -name '*-report.xml' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz ''' archiveArtifacts artifacts: '*-bundles.tar.gz', allowEmptyArchive: true @@ -654,6 +674,11 @@ pipeline { test-integration ''' } + post { + always { + junit testResults: 'bundles/**/*-report.xml', allowEmptyResults: true + } + } } } @@ -676,7 +701,7 @@ pipeline { bundleName=ppc64le-integration-cli echo "Creating ${bundleName}-bundles.tar.gz" # exclude overlay2 directories - find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*.log' -o -name '*.prof' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz + find bundles -path '*/root/*overlay2' -prune -o -type f \\( -name '*-report.json' -o -name '*.log' -o -name '*.prof' -o -name '*-report.xml' \\) -print | xargs tar -czf ${bundleName}-bundles.tar.gz ''' archiveArtifacts artifacts: '*-bundles.tar.gz', allowEmptyArchive: true diff --git a/hack/make/.integration-test-helpers b/hack/make/.integration-test-helpers index f430df9aa1ef7..f1fd2399d6d94 100644 --- a/hack/make/.integration-test-helpers +++ b/hack/make/.integration-test-helpers @@ -73,8 +73,14 @@ run_test_integration_suites() { if ! ( cd "$dir" echo "Running $PWD flags=${flags}" + [ -n "$TESTDEBUG" ] && set -x # shellcheck disable=SC2086 - test_env ./test.main ${flags} + test_env gotestsum \ + --format=standard-verbose \ + --jsonfile="${ABS_DEST}/$(basename "$dir")-go-test-report.json" \ + --junitfile="${ABS_DEST}/$(basename "$dir")-junit-report.xml" \ + --raw-command \ + -- go tool test2json ./test.main ${flags} ); then exit 1; fi done } From 48e8f184953ac211c34b46fc7169d01c79bd8b34 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 23 Aug 2019 14:09:48 +0200 Subject: [PATCH 25/59] integration: test2json: enable timestamps to fix zero-time test durations Without these options set, test2json does not include a `Time` field in the generated JSON; {"Action":"run","Test":"TestCgroupNamespacesBuild"} {"Action":"output","Test":"TestCgroupNamespacesBuild","Output":"=== RUN TestCgroupNamespacesBuild\n"} {"Action":"output","Test":"TestCgroupNamespacesBuild","Output":"--- PASS: TestCgroupNamespacesBuild (1.70s)\n"} ... {"Action":"pass","Test":"TestCgroupNamespacesBuild"} As a result, `gotestsum` was not able to calculate test-duration, and reported `time="0.000000"` for all tests; With this patch applied: {"Time":"2019-08-23T22:42:41.644361357Z","Action":"run","Package":"amd64.integration.build","Test":"TestCgroupNamespacesBuild"} {"Time":"2019-08-23T22:42:41.644367647Z","Action":"output","Package":"amd64.integration.build","Test":"TestCgroupNamespacesBuild","Output":"=== RUN TestCgroupNamespacesBuild\n"} {"Time":"2019-08-23T22:42:44.926933252Z","Action":"output","Package":"amd64.integration.build","Test":"TestCgroupNamespacesBuild","Output":"--- PASS: TestCgroupNamespacesBuild (3.28s)\n"} ... {"Time":"2019-08-23T22:42:44.927003836Z","Action":"pass","Package":"amd64.integration.build","Test":"TestCgroupNamespacesBuild","Elapsed":3.28} Which now correctly reports the test's duration: Signed-off-by: Sebastiaan van Stijn (cherry picked from commit d2e00d62e244b293b5b2459942b3a55447c191f3) Signed-off-by: Sebastiaan van Stijn --- hack/make/.integration-test-helpers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hack/make/.integration-test-helpers b/hack/make/.integration-test-helpers index f1fd2399d6d94..dbece6b40ddcb 100644 --- a/hack/make/.integration-test-helpers +++ b/hack/make/.integration-test-helpers @@ -80,7 +80,7 @@ run_test_integration_suites() { --jsonfile="${ABS_DEST}/$(basename "$dir")-go-test-report.json" \ --junitfile="${ABS_DEST}/$(basename "$dir")-junit-report.xml" \ --raw-command \ - -- go tool test2json ./test.main ${flags} + -- go tool test2json -t ./test.main ${flags} ); then exit 1; fi done } From 5d4f5db76c78942aeccac6ecebab8f6988cbdb6b Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 23 Aug 2019 14:25:57 +0200 Subject: [PATCH 26/59] integration: improve package- and filename for junit.xml Generate more unique names, based on architecture and test-suite name. Clean up the path to this integration test to create a useful package name. "$dir" can be either absolute (/go/src/github.com/docker/docker/integration/foo) or relative (./integration/foo). To account for both, first we strip the absolute path, then any leading periods and slashes. For the package-name, we use periods as separator instead of slashes, to be more in-line with Java package names (which is what junit.xml was originally designed for). Signed-off-by: Sebastiaan van Stijn (cherry picked from commit f007b0150a1559ab3ba34cd81832c7c9b4e8f78f) Signed-off-by: Sebastiaan van Stijn --- hack/make/.integration-test-helpers | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/hack/make/.integration-test-helpers b/hack/make/.integration-test-helpers index dbece6b40ddcb..91179c94a31b2 100644 --- a/hack/make/.integration-test-helpers +++ b/hack/make/.integration-test-helpers @@ -72,15 +72,27 @@ run_test_integration_suites() { for dir in ${integration_api_dirs}; do if ! ( cd "$dir" - echo "Running $PWD flags=${flags}" + # Create a useful package name based on the tests's $dir. We need to take + # into account that "$dir" can be either an absolute (/go/src/github.com/docker/docker/integration/foo) + # or relative (./integration/foo) path. To account for both, first we strip + # the absolute path, then remove any leading periods and slashes. + pkgname="${dir}" + pkgname="${pkgname#*${GOPATH}/src/${DOCKER_PKG}}" + pkgname="${pkgname#*.}" + pkgname="${pkgname#*\/}" + + # Finally, we use periods as separator (instead of slashes) to be more + # in line with Java package names (which is what junit.xml was designed for) + pkgname="$(go env GOARCH).${pkgname//\//.}" + echo "Running $PWD (${pkgname}) flags=${flags}" [ -n "$TESTDEBUG" ] && set -x # shellcheck disable=SC2086 test_env gotestsum \ --format=standard-verbose \ - --jsonfile="${ABS_DEST}/$(basename "$dir")-go-test-report.json" \ - --junitfile="${ABS_DEST}/$(basename "$dir")-junit-report.xml" \ + --jsonfile="${ABS_DEST}/${pkgname//./-}-go-test-report.json" \ + --junitfile="${ABS_DEST}/${pkgname//./-}-junit-report.xml" \ --raw-command \ - -- go tool test2json -t ./test.main ${flags} + -- go tool test2json -p "${pkgname}" -t ./test.main ${flags} ); then exit 1; fi done } From 08573e292009b2659d862a4d2cecee85fc0a59d8 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 23 Aug 2019 21:46:55 +0200 Subject: [PATCH 27/59] Jenkinsfile: add TESTDEBUG Signed-off-by: Sebastiaan van Stijn (cherry picked from commit d723643dc38c18556ec5f7f0e97a8a594df545f7) Signed-off-by: Sebastiaan van Stijn --- Jenkinsfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index f93ab62d552fd..effd37e41c161 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -22,6 +22,7 @@ pipeline { DOCKER_GRAPHDRIVER = 'overlay2' APT_MIRROR = 'cdn-fastly.deb.debian.org' CHECK_CONFIG_COMMIT = '78405559cfe5987174aa2cb6463b9b2c1b917255' + TESTDEBUG = '0' TIMEOUT = '120m' } stages { @@ -402,6 +403,7 @@ pipeline { -e DOCKER_EXPERIMENTAL \ -e DOCKER_GITCOMMIT=${GIT_COMMIT} \ -e DOCKER_GRAPHDRIVER \ + -e TESTDEBUG \ -e TEST_SKIP_INTEGRATION_CLI \ -e TIMEOUT \ docker:${GIT_COMMIT} \ @@ -585,6 +587,7 @@ pipeline { -e DOCKER_EXPERIMENTAL \ -e DOCKER_GITCOMMIT=${GIT_COMMIT} \ -e DOCKER_GRAPHDRIVER \ + -e TESTDEBUG \ -e TEST_SKIP_INTEGRATION_CLI \ -e TIMEOUT \ docker:${GIT_COMMIT} \ From b8b8bcb8bf179fa0d2b43405e17ed6f938acb3b7 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 14 Aug 2019 20:43:52 +0200 Subject: [PATCH 28/59] Dockerfile: update CRIU to v3.12 New features - build CRIU with Android NDK - C/R of - IP RAW sockets - lsm: dump and restore any SELinux process label - support restoring ghost files on readonly mounts Bugfixes - Do not lock network if running in the host network namespace - Fix RPC configuration file handling - util: don't leak file descriptors to third-party tools - small fixes here and there Improvements - travis: switch to the Ubuntu Xenial - travis-ci: Enable ia32 tests - Many improvements and bug fixes in the libcriu - Changes in the API and ABI (SONAME increased from 1 to 2) full diff: https://github.com/checkpoint-restore/criu/compare/v3.11...v3.12 Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 00ad0222cef8024f19394e2e9d5dc0e05f0ec982) Signed-off-by: Sebastiaan van Stijn --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 143dec64073f2..e0b729a22d16c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,7 +36,7 @@ RUN sed -ri "s/(httpredir|deb).debian.org/${APT_MIRROR:-deb.debian.org}/g" /etc/ FROM base AS criu ARG DEBIAN_FRONTEND # Install CRIU for checkpoint/restore support -ENV CRIU_VERSION 3.11 +ENV CRIU_VERSION 3.12 # Install dependency packages specific to criu RUN apt-get update && apt-get install -y --no-install-recommends \ libnet-dev \ From 6d7d877c73737cc202f8bd98d25730180dae1b90 Mon Sep 17 00:00:00 2001 From: Vitaly Ostrosablin Date: Tue, 20 Aug 2019 09:14:42 +0300 Subject: [PATCH 29/59] Fix testcase name TestBuildMulitStageResetScratch testcase was actually meant to be TestBuildMulitStageResetScratch Signed-off-by: Vitaly Ostrosablin (cherry picked from commit c266d8fe563d4b1b65fb14a90da1b72f61b6310c) Signed-off-by: Sebastiaan van Stijn --- integration-cli/docker_cli_build_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go index 0ff2882cff9e2..f77424491b320 100644 --- a/integration-cli/docker_cli_build_test.go +++ b/integration-cli/docker_cli_build_test.go @@ -5952,7 +5952,7 @@ func (s *DockerSuite) TestBuildCopyFromWindowsIsCaseInsensitive(c *check.C) { } // #33176 -func (s *DockerSuite) TestBuildMulitStageResetScratch(c *check.C) { +func (s *DockerSuite) TestBuildMultiStageResetScratch(c *check.C) { testRequires(c, DaemonIsLinux) dockerfile := ` From 79e5950b2f21b5fae8a305039df6e404c3980772 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 27 Aug 2019 14:58:04 +0200 Subject: [PATCH 30/59] pkg/term: refactor TestEscapeProxyRead - use subtests to make it clearer what the individual test-cases are, and to prevent tests from depending on values set by the previous test(s). - remove redundant messages in assert (gotest.tools already prints a useful message if assertions fail). Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 556d26c07d068d92fd896428ab4ac890554239d7) Signed-off-by: Sebastiaan van Stijn --- pkg/term/proxy_test.go | 242 +++++++++++++++++++++++------------------ 1 file changed, 139 insertions(+), 103 deletions(-) diff --git a/pkg/term/proxy_test.go b/pkg/term/proxy_test.go index df588fe15bb00..8f8e4cb6d4442 100644 --- a/pkg/term/proxy_test.go +++ b/pkg/term/proxy_test.go @@ -2,7 +2,6 @@ package term // import "github.com/docker/docker/pkg/term" import ( "bytes" - "fmt" "testing" "gotest.tools/assert" @@ -10,106 +9,143 @@ import ( ) func TestEscapeProxyRead(t *testing.T) { - escapeKeys, _ := ToBytes("") - keys, _ := ToBytes("a") - reader := NewEscapeProxy(bytes.NewReader(keys), escapeKeys) - buf := make([]byte, len(keys)) - 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.DeepEqual(t, keys, buf) - - keys, _ = ToBytes("a,b,c") - reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) - buf = make([]byte, len(keys)) - 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.DeepEqual(t, keys, buf) - - keys, _ = ToBytes("") - reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) - buf = make([]byte, len(keys)) - nr, err = reader.Read(buf) - 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("DEL") - keys, _ = ToBytes("a,b,c,+") - reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) - buf = make([]byte, len(keys)) - 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.DeepEqual(t, keys, buf) - - keys, _ = ToBytes("") - reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) - buf = make([]byte, len(keys)) - nr, err = reader.Read(buf) - 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) - assert.NilError(t, err) - assert.Equal(t, nr, 1, fmt.Sprintf("nr %d should be equal to the number of 1", nr)) - assert.DeepEqual(t, keys, buf) - - escapeKeys, _ = ToBytes("ctrl-c") - keys, _ = ToBytes("ctrl-c") - reader = NewEscapeProxy(bytes.NewReader(keys), escapeKeys) - buf = make([]byte, len(keys)) - nr, err = reader.Read(buf) - assert.Error(t, err, "read escape sequence") - assert.Equal(t, nr, 0, "nr should be equal to 0") - assert.DeepEqual(t, keys, buf) - - 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) - assert.NilError(t, err) - assert.Equal(t, nr, 0, "nr should be equal to 0") - 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.DeepEqual(t, keys[1:], buf) - - 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) - assert.NilError(t, err) - assert.Equal(t, nr, 0, "nr should be equal to 0") - 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.DeepEqual(t, keys, buf) - - 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) - assert.NilError(t, err) - assert.Equal(t, nr, 0, "nr should be equal to 0") - 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.DeepEqual(t, keys, buf) + t.Run("no escape keys, keys a", func(t *testing.T) { + escapeKeys, _ := ToBytes("") + keys, _ := ToBytes("a") + reader := NewEscapeProxy(bytes.NewReader(keys), escapeKeys) + + buf := make([]byte, len(keys)) + nr, err := reader.Read(buf) + assert.NilError(t, err) + assert.Equal(t, nr, len(keys)) + assert.DeepEqual(t, keys, buf) + }) + + t.Run("no escape keys, keys a,b,c", func(t *testing.T) { + escapeKeys, _ := ToBytes("") + keys, _ := ToBytes("a,b,c") + reader := NewEscapeProxy(bytes.NewReader(keys), escapeKeys) + + buf := make([]byte, len(keys)) + nr, err := reader.Read(buf) + assert.NilError(t, err) + assert.Equal(t, nr, len(keys)) + assert.DeepEqual(t, keys, buf) + }) + + t.Run("no escape keys, no keys", func(t *testing.T) { + escapeKeys, _ := ToBytes("") + keys, _ := ToBytes("") + reader := NewEscapeProxy(bytes.NewReader(keys), escapeKeys) + + buf := make([]byte, len(keys)) + nr, err := reader.Read(buf) + assert.Assert(t, is.ErrorContains(err, ""), "Should throw error when no keys are to read") + assert.Equal(t, nr, 0) + assert.Check(t, is.Len(keys, 0)) + assert.Check(t, is.Len(buf, 0)) + }) + + t.Run("DEL escape key, keys a,b,c,+", func(t *testing.T) { + escapeKeys, _ := ToBytes("DEL") + keys, _ := ToBytes("a,b,c,+") + reader := NewEscapeProxy(bytes.NewReader(keys), escapeKeys) + + buf := make([]byte, len(keys)) + nr, err := reader.Read(buf) + assert.NilError(t, err) + assert.Equal(t, nr, len(keys)) + assert.DeepEqual(t, keys, buf) + }) + + t.Run("DEL escape key, no keys", func(t *testing.T) { + escapeKeys, _ := ToBytes("DEL") + keys, _ := ToBytes("") + reader := NewEscapeProxy(bytes.NewReader(keys), escapeKeys) + + buf := make([]byte, len(keys)) + nr, err := reader.Read(buf) + assert.Assert(t, is.ErrorContains(err, ""), "Should throw error when no keys are to read") + assert.Equal(t, nr, 0) + assert.Check(t, is.Len(keys, 0)) + assert.Check(t, is.Len(buf, 0)) + }) + + t.Run("ctrl-x,ctrl-@ escape key, keys DEL", func(t *testing.T) { + escapeKeys, _ := ToBytes("ctrl-x,ctrl-@") + keys, _ := ToBytes("DEL") + reader := NewEscapeProxy(bytes.NewReader(keys), escapeKeys) + + buf := make([]byte, len(keys)) + nr, err := reader.Read(buf) + assert.NilError(t, err) + assert.Equal(t, nr, 1) + assert.DeepEqual(t, keys, buf) + }) + + t.Run("ctrl-c escape key, keys ctrl-c", func(t *testing.T) { + escapeKeys, _ := ToBytes("ctrl-c") + keys, _ := ToBytes("ctrl-c") + reader := NewEscapeProxy(bytes.NewReader(keys), escapeKeys) + + buf := make([]byte, len(keys)) + nr, err := reader.Read(buf) + assert.Error(t, err, "read escape sequence") + assert.Equal(t, nr, 0) + assert.DeepEqual(t, keys, buf) + }) + + t.Run("ctrl-c,ctrl-z escape key, keys ctrl-c,ctrl-z", func(t *testing.T) { + 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) + assert.NilError(t, err) + assert.Equal(t, nr, 0) + assert.DeepEqual(t, keys[0:1], buf) + + nr, err = reader.Read(buf) + assert.Error(t, err, "read escape sequence") + assert.Equal(t, nr, 0) + assert.DeepEqual(t, keys[1:], buf) + }) + + t.Run("ctrl-c,ctrl-z escape key, keys ctrl-c,DEL,+", func(t *testing.T) { + 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) + assert.NilError(t, err) + assert.Equal(t, nr, 0) + 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)) + assert.DeepEqual(t, keys, buf) + }) + + t.Run("ctrl-c,ctrl-z escape key, keys ctrl-c,DEL", func(t *testing.T) { + 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) + assert.NilError(t, err) + assert.Equal(t, nr, 0) + 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)) + assert.DeepEqual(t, keys, buf) + }) + } From 1d91898ca655afa0690f1e136e4c9f22d0532d83 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 27 Aug 2019 18:06:34 +0200 Subject: [PATCH 31/59] integration: windows.ps1: turn defender error into a warning Some integration tests are known to fail if Windows Defender is enabled. On the machines that run our CI, defender is disabled for that reason. Contributors likely will have defender enabled, and because of that are currently not able to run the integration tests. This patch changes the ERROR into a WARNING, so that contributors can still run (a limited set of) the integration tests, but get informed that some may fail. We should make this requirement more specific, and only skip tests that are known to require defender to be disabled, but while that's not yet in place, let's print a warning instead. Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 31885181fcc0ca0cacd6c12f6c64ac553ff2bc2b) Signed-off-by: Sebastiaan van Stijn --- hack/ci/windows.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hack/ci/windows.ps1 b/hack/ci/windows.ps1 index 705a23b1d3e6a..f4d8b7e283bee 100644 --- a/hack/ci/windows.ps1 +++ b/hack/ci/windows.ps1 @@ -266,7 +266,7 @@ Try { } } } Catch {} - if ($defender) { Throw "ERROR: Windows Defender real time protection must be disabled for integration tests" } + if ($defender) { Write-Host -ForegroundColor Magenta "WARN: Windows Defender real time protection is enabled, which may cause some integration tests to fail" } # Make sure SOURCES_DRIVE is set if ($null -eq $env:SOURCES_DRIVE) { Throw "ERROR: Environment variable SOURCES_DRIVE is not set" } From 45f49fe5c36816e12f498526a8b3829bc2b8306d Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 27 Aug 2019 17:26:15 +0200 Subject: [PATCH 32/59] TestDispatch: refactor to use subtests again, and fix linting (structcheck) Instead of using a `initDispatchTestCases()` function, declare the test-table inside `TestDispatch` itself, and run the tests as subtests. ``` [2019-08-27T15:14:51.072Z] builder/dockerfile/evaluator_test.go:18:2: `name` is unused (structcheck) [2019-08-27T15:14:51.072Z] name, expectedError string ``` Signed-off-by: Sebastiaan van Stijn (cherry picked from commit a3f9cb5b635a76484a926289bfa4fc6feee1763a) Signed-off-by: Sebastiaan van Stijn --- builder/dockerfile/evaluator_test.go | 81 +++++++++++++--------------- 1 file changed, 37 insertions(+), 44 deletions(-) diff --git a/builder/dockerfile/evaluator_test.go b/builder/dockerfile/evaluator_test.go index 28607ead0d220..ebd9d8d7f1e1b 100644 --- a/builder/dockerfile/evaluator_test.go +++ b/builder/dockerfile/evaluator_test.go @@ -24,8 +24,11 @@ func init() { reexec.Init() } -func initDispatchTestCases() []dispatchTestCase { - dispatchTestCases := []dispatchTestCase{ +func TestDispatch(t *testing.T) { + if runtime.GOOS != "windows" { + skip.If(t, os.Getuid() != 0, "skipping test that requires root") + } + testCases := []dispatchTestCase{ { name: "ADD multiple files to file", cmd: &instructions.AddCommand{SourcesAndDest: instructions.SourcesAndDest{ @@ -92,56 +95,46 @@ func initDispatchTestCases() []dispatchTestCase { }}, expectedError: "source can't be a URL for COPY", files: nil, - }} - - return dispatchTestCases -} - -func TestDispatch(t *testing.T) { - if runtime.GOOS != "windows" { - skip.If(t, os.Getuid() != 0, "skipping test that requires root") + }, } - testCases := initDispatchTestCases() - for _, testCase := range testCases { - executeTestCase(t, testCase) - } -} + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + contextDir, cleanup := createTestTempDir(t, "", "builder-dockerfile-test") + defer cleanup() -func executeTestCase(t *testing.T, testCase dispatchTestCase) { - contextDir, cleanup := createTestTempDir(t, "", "builder-dockerfile-test") - defer cleanup() + for filename, content := range tc.files { + createTestTempFile(t, contextDir, filename, content, 0777) + } - for filename, content := range testCase.files { - createTestTempFile(t, contextDir, filename, content, 0777) - } + tarStream, err := archive.Tar(contextDir, archive.Uncompressed) - tarStream, err := archive.Tar(contextDir, archive.Uncompressed) + if err != nil { + t.Fatalf("Error when creating tar stream: %s", err) + } - if err != nil { - t.Fatalf("Error when creating tar stream: %s", err) - } - - defer func() { - if err = tarStream.Close(); err != nil { - t.Fatalf("Error when closing tar stream: %s", err) - } - }() + defer func() { + if err = tarStream.Close(); err != nil { + t.Fatalf("Error when closing tar stream: %s", err) + } + }() - context, err := remotecontext.FromArchive(tarStream) + context, err := remotecontext.FromArchive(tarStream) - if err != nil { - t.Fatalf("Error when creating tar context: %s", err) - } + if err != nil { + t.Fatalf("Error when creating tar context: %s", err) + } - defer func() { - if err = context.Close(); err != nil { - t.Fatalf("Error when closing tar context: %s", err) - } - }() + defer func() { + if err = context.Close(); err != nil { + t.Fatalf("Error when closing tar context: %s", err) + } + }() - b := newBuilderWithMockBackend() - sb := newDispatchRequest(b, '`', context, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) - err = dispatch(sb, testCase.cmd) - assert.Check(t, is.ErrorContains(err, testCase.expectedError)) + b := newBuilderWithMockBackend() + sb := newDispatchRequest(b, '`', context, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) + err = dispatch(sb, tc.cmd) + assert.Check(t, is.ErrorContains(err, tc.expectedError)) + }) + } } From e8e2666705f381f4959aa1ea300e4385ab4cf156 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 28 Aug 2019 19:39:50 +0200 Subject: [PATCH 33/59] integration-cli: getContainerCount() fix trimming prefix caught by staticcheck: ``` integration-cli/docker_utils_test.go:66:29: SA1024: cutset contains duplicate characters (staticcheck) ``` Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 02c9b0674fe2cf43def3a1e625cab74a0db8136a) Signed-off-by: Sebastiaan van Stijn --- integration-cli/docker_utils_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-cli/docker_utils_test.go b/integration-cli/docker_utils_test.go index 1d84e63e5e383..a95246f141224 100644 --- a/integration-cli/docker_utils_test.go +++ b/integration-cli/docker_utils_test.go @@ -63,7 +63,7 @@ func getContainerCount(c *check.C) int { for _, line := range lines { if strings.Contains(line, containers) { output := strings.TrimSpace(line) - output = strings.TrimLeft(output, containers) + output = strings.TrimPrefix(output, containers) output = strings.Trim(output, " ") containerCount, err := strconv.Atoi(output) assert.NilError(c, err) From 93b38b80086139517b67c7a762ddafdcb0abbdfb Mon Sep 17 00:00:00 2001 From: Stefan Scherer Date: Fri, 30 Aug 2019 12:44:20 +0200 Subject: [PATCH 34/59] Fix docker inspect for dutimgVersion Signed-off-by: Stefan Scherer (cherry picked from commit 52a53e2587e34d45b1d4a9b7b7d307ad51c5b0b0) Signed-off-by: Sebastiaan van Stijn --- hack/ci/windows.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hack/ci/windows.ps1 b/hack/ci/windows.ps1 index f4d8b7e283bee..28a7f7860e8d2 100644 --- a/hack/ci/windows.ps1 +++ b/hack/ci/windows.ps1 @@ -717,7 +717,7 @@ Try { # Inspect the pulled or loaded image to get the version directly $ErrorActionPreference = "SilentlyContinue" - $dutimgVersion = $(&"$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" inspect $($env:WINDOWS_BASE_IMAGE) --format "{{.OsVersion}}") + $dutimgVersion = $(&"$env:TEMP\binary\docker-$COMMITHASH" "-H=$($DASHH_CUT)" inspect "$($env:WINDOWS_BASE_IMAGE):$env:WINDOWS_BASE_IMAGE_TAG" --format "{{.OsVersion}}") $ErrorActionPreference = "Stop" Write-Host -ForegroundColor Green $("INFO: Version of $($env:WINDOWS_BASE_IMAGE):$env:WINDOWS_BASE_IMAGE_TAG is '"+$dutimgVersion+"'") } From 69da36f39e7123c1331966a74cec43d3817bf448 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Sat, 31 Aug 2019 12:12:25 +0200 Subject: [PATCH 35/59] hack/make/binary-daemon: fix some linting issues - Add quotes to prevent word splitting in `cp` statement (SC2046) - Replace legacy back tics with `$()` - Replace `which` with `command -v` (SC2230) - Fix incorrect (`==`) comparison Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 70d36778252124d7cec0489ed98d1bac475d9727) Signed-off-by: Sebastiaan van Stijn --- hack/make/binary-daemon | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hack/make/binary-daemon b/hack/make/binary-daemon index 003bd4feef589..3b360a9e03df7 100644 --- a/hack/make/binary-daemon +++ b/hack/make/binary-daemon @@ -15,16 +15,16 @@ copy_binaries() { fi echo "Copying nested executables into $dir" for file in containerd containerd-shim ctr runc docker-init docker-proxy rootlesskit rootlesskit-docker-proxy dockerd-rootless.sh; do - cp -f `which "$file"` "$dir/" - if [ "$hash" == "hash" ]; then + cp -f "$(command -v "$file")" "$dir/" + if [ "$hash" = "hash" ]; then hash_files "$dir/$file" fi done # vpnkit is amd64 only - if which "vpnkit.$(uname -m)" 2>&1 >/dev/null; then - cp -f `which "vpnkit.$(uname -m)"` "$dir/vpnkit" - if [ "$hash" == "hash" ]; then + if command -v "vpnkit.$(uname -m)" 2>&1 >/dev/null; then + cp -f "$(command -v "vpnkit.$(uname -m)")" "$dir/vpnkit" + if [ "$hash" = "hash" ]; then hash_files "$dir/vpnkit" fi fi From ae7858ff2c76b4573ea2bd05ce7ec06a053d17b0 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 2 Sep 2019 10:51:18 +0200 Subject: [PATCH 36/59] integration-cli: fix some bashism's in Dockerfiles `TestBuildBuildTimeArgEnv` and `TestBuildBuildTimeArgEmptyValVariants` were using non-standard comparisons. Signed-off-by: Sebastiaan van Stijn (cherry picked from commit dbde4786e48531f095f9c3ecaff0f57b838abefc) Signed-off-by: Sebastiaan van Stijn --- integration-cli/docker_cli_build_test.go | 26 ++++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go index f77424491b320..5f192afa88dbf 100644 --- a/integration-cli/docker_cli_build_test.go +++ b/integration-cli/docker_cli_build_test.go @@ -4535,17 +4535,17 @@ func (s *DockerSuite) TestBuildBuildTimeArgEnv(c *check.C) { ARG FOO6 ARG FO10 RUN env - RUN [ "$FOO1" == "fromcmd" ] - RUN [ "$FOO2" == "" ] - RUN [ "$FOO3" == "fromenv" ] - RUN [ "$FOO4" == "fromfile" ] - RUN [ "$FOO5" == "fromcmd" ] + RUN [ "$FOO1" = "fromcmd" ] + RUN [ "$FOO2" = "" ] + RUN [ "$FOO3" = "fromenv" ] + RUN [ "$FOO4" = "fromfile" ] + RUN [ "$FOO5" = "fromcmd" ] # The following should not exist at all in the env - RUN [ "$(env | grep FOO6)" == "" ] - RUN [ "$(env | grep FOO7)" == "" ] - RUN [ "$(env | grep FOO8)" == "" ] - RUN [ "$(env | grep FOO9)" == "" ] - RUN [ "$FO10" == "" ] + RUN [ "$(env | grep FOO6)" = "" ] + RUN [ "$(env | grep FOO7)" = "" ] + RUN [ "$(env | grep FOO8)" = "" ] + RUN [ "$(env | grep FOO9)" = "" ] + RUN [ "$FO10" = "" ] ` result := buildImage("testbuildtimeargenv", cli.WithFlags( @@ -4615,9 +4615,9 @@ func (s *DockerSuite) TestBuildBuildTimeArgEmptyValVariants(c *check.C) { ARG %s= ARG %s="" ARG %s='' - RUN [ "$%s" == "$%s" ] - RUN [ "$%s" == "$%s" ] - RUN [ "$%s" == "$%s" ]`, envKey, envKey1, envKey2, envKey, envKey1, envKey1, envKey2, envKey, envKey2) + RUN [ "$%s" = "$%s" ] + RUN [ "$%s" = "$%s" ] + RUN [ "$%s" = "$%s" ]`, envKey, envKey1, envKey2, envKey, envKey1, envKey1, envKey2, envKey, envKey2) buildImageSuccessfully(c, imgName, build.WithDockerfile(dockerfile)) } From 24181cd2657ff8fcff60038b0f8897b5caad91d8 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 2 Sep 2019 10:52:39 +0200 Subject: [PATCH 37/59] TestBuildSquashParent: fix non-standard comparisson Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 32f1c651623421ee1ac480b200d34025a74436bb) Signed-off-by: Sebastiaan van Stijn --- integration/build/build_squash_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration/build/build_squash_test.go b/integration/build/build_squash_test.go index 4398ebc7b7712..788589d612cd4 100644 --- a/integration/build/build_squash_test.go +++ b/integration/build/build_squash_test.go @@ -100,7 +100,7 @@ func TestBuildSquashParent(t *testing.T) { ) container.Run(ctx, t, client, container.WithImage(name), - container.WithCmd("/bin/sh", "-c", `[ "$(echo $HELLO)" == "world" ]`), + container.WithCmd("/bin/sh", "-c", `[ "$(echo $HELLO)" = "world" ]`), ) origHistory, err := client.ImageHistory(ctx, origID) From b116452a03dff51f54097c19aa80407f0bcce371 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 2 Sep 2019 15:34:34 +0200 Subject: [PATCH 38/59] docker-py: skip flaky AttachContainerTest::test_attach_no_stream Seen failing a couple of times: ``` [2019-09-02T08:40:15.796Z] =================================== FAILURES =================================== [2019-09-02T08:40:15.796Z] __________________ AttachContainerTest.test_attach_no_stream ___________________ [2019-09-02T08:40:15.796Z] tests/integration/api_container_test.py:1250: in test_attach_no_stream [2019-09-02T08:40:15.796Z] assert output == 'hello\n'.encode(encoding='ascii') [2019-09-02T08:40:15.796Z] E AssertionError: assert b'' == b'hello\n' [2019-09-02T08:40:15.796Z] E Right contains more items, first extra item: 104 [2019-09-02T08:40:15.796Z] E Use -v to get the full diff ``` Signed-off-by: Sebastiaan van Stijn (cherry picked from commit ce77a804b86886489fae47aa15a3ee5a0a8815e0) Signed-off-by: Sebastiaan van Stijn --- hack/make/test-docker-py | 1 + 1 file changed, 1 insertion(+) diff --git a/hack/make/test-docker-py b/hack/make/test-docker-py index 9625f47e619c8..da51928e9d601 100644 --- a/hack/make/test-docker-py +++ b/hack/make/test-docker-py @@ -13,6 +13,7 @@ source hack/make/.integration-test-helpers # TODO remove these skip once we update to a docker-py version that has https://github.com/docker/docker-py/pull/2369, https://github.com/docker/docker-py/pull/2380, https://github.com/docker/docker-py/pull/2382 : "${PY_TEST_OPTIONS:=\ --deselect=tests/integration/api_swarm_test.py::SwarmTest::test_init_swarm_data_path_addr \ +--deselect=tests/integration/api_container_test.py::AttachContainerTest::test_attach_no_stream \ --deselect=tests/integration/api_exec_test.py::ExecTest::test_detach_with_arg \ --deselect=tests/integration/api_exec_test.py::ExecDemuxTest::test_exec_command_tty_stream_no_demux \ --deselect=tests/integration/api_build_test.py::BuildTest::test_build_invalid_platform \ From d58829550ef3bba875724c7639488a8288965d89 Mon Sep 17 00:00:00 2001 From: Jintao Zhang Date: Tue, 3 Sep 2019 07:12:58 +0800 Subject: [PATCH 39/59] TestCase: use `icmd.RunCmd` instead `icmd.StartCmd` Use `cli.Docker` instead `dockerCmdWithResult`. Signed-off-by: Jintao Zhang (cherry picked from commit e6fce00ec83df2f23523b836f647b8f3df97953f) Signed-off-by: Sebastiaan van Stijn --- integration-cli/docker_cli_run_test.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index 6bbcb1145cdb2..46e731a60924b 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/integration-cli/docker_cli_run_test.go @@ -1792,16 +1792,14 @@ func (s *DockerSuite) TestRunExitOnStdinClose(c *check.C) { func (s *DockerSuite) TestRunInteractiveWithRestartPolicy(c *check.C) { name := "test-inter-restart" - result := icmd.StartCmd(icmd.Cmd{ + result := icmd.RunCmd(icmd.Cmd{ Command: []string{dockerBinary, "run", "-i", "--name", name, "--restart=always", "busybox", "sh"}, Stdin: bytes.NewBufferString("exit 11"), }) - assert.NilError(c, result.Error) defer func() { - dockerCmdWithResult("stop", name).Assert(c, icmd.Success) + cli.Docker(cli.Args("stop", name)).Assert(c, icmd.Success) }() - result = icmd.WaitOnCmd(60*time.Second, result) result.Assert(c, icmd.Expected{ExitCode: 11}) } From 4329550a742036bc5a7faa69ac60223976083dc7 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 2 Sep 2019 14:10:11 +0200 Subject: [PATCH 40/59] hack/ci/windows.ps1: explicitly set exit code to result of tests Trying to see if this helps with the cleanup step exiting in CI, but Jenkins continuing to wait for the script to end afterwards. Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 8e8c52c4abe011a4cf3334da0726ef1fc0d17b14) Signed-off-by: Sebastiaan van Stijn --- hack/ci/windows.ps1 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hack/ci/windows.ps1 b/hack/ci/windows.ps1 index 28a7f7860e8d2..faaad162d8485 100644 --- a/hack/ci/windows.ps1 +++ b/hack/ci/windows.ps1 @@ -960,6 +960,9 @@ Catch [Exception] { Throw $_ } Finally { + # Preserve the LastExitCode of the tests + $tmpLastExitCode = $LastExitCode + $ErrorActionPreference="SilentlyContinue" $global:ProgressPreference=$origProgressPreference Write-Host -ForegroundColor Green "INFO: Tidying up at end of run" @@ -993,4 +996,6 @@ Finally { Nuke-Everything $Dur=New-TimeSpan -Start $StartTime -End $(Get-Date) Write-Host -ForegroundColor $FinallyColour "`nINFO: executeCI.ps1 exiting at $(date). Duration $dur`n" + + exit $tmpLastExitCode } From ff26a233144de69353373a7e1dca5ce327ffeb3f Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 6 Sep 2019 23:32:57 +0200 Subject: [PATCH 41/59] hack/ci/windows.ps1 print all environment variables to check how Jenkins runs this script Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 7eb522a2350d759cf6a9aad493ac1b8ffc3d3335) Signed-off-by: Sebastiaan van Stijn --- hack/ci/windows.ps1 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hack/ci/windows.ps1 b/hack/ci/windows.ps1 index faaad162d8485..8dc30e368d378 100644 --- a/hack/ci/windows.ps1 +++ b/hack/ci/windows.ps1 @@ -15,6 +15,11 @@ if ($env:BUILD_TAG -match "-LoW") { $env:LCOW_MODE=1 } if ($env:BUILD_TAG -match "-WoW") { $env:LCOW_MODE="" } +Write-Host -ForegroundColor Red "DEBUG: print all environment variables to check how Jenkins runs this script" +$allArgs = [Environment]::GetCommandLineArgs() +Write-Host -ForegroundColor Red $allArgs +Write-Host -ForegroundColor Red "----------------------------------------------------------------------------" + # ------------------------------------------------------------------------------------------- # When executed, we rely on four variables being set in the environment: # From a365f0745d7eceb43d3f6fe9d10bc9a621bd0ef2 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 3 Sep 2019 15:51:41 +0200 Subject: [PATCH 42/59] Jenkinsfile: create bundles for Windows stages CI already stores the logs of the test daemon, so we might as well store them as artifacts ``` [2019-09-03T12:49:39.835Z] INFO: Tidying up at end of run [2019-09-03T12:49:39.835Z] INFO: Saving daemon under test log (d:\CI-2\CI-3593e7622\dut.out) to C:\windows\TEMP\CIDUT.out [2019-09-03T12:49:39.835Z] INFO: Saving daemon under test log (d:\CI-2\CI-3593e7622\dut.err) to C:\windows\TEMP\CIDUT.err ``` Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 6ee61f54935d77d3d5667b4a3ba8f0be6c3de23d) Signed-off-by: Sebastiaan van Stijn --- Jenkinsfile | 38 ++++++++++++++++++++++++++++++++++++++ hack/ci/windows.ps1 | 4 ++++ 2 files changed, 42 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index effd37e41c161..dfa8f844c5338 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -760,6 +760,25 @@ pipeline { } } } + post { + always { + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE', message: 'Failed to create bundles.tar.gz') { + powershell ''' + $bundleName="windowsRS1-integration" + Write-Host -ForegroundColor Green "Creating ${bundleName}-bundles.zip" + + # archiveArtifacts does not support env-vars to , so save the artifacts in a fixed location + Compress-Archive -Path "${env:TEMP}/CIDUT.out", "${env:TEMP}/CIDUT.err" -CompressionLevel Optimal -DestinationPath "${bundleName}-bundles.zip" + ''' + + archiveArtifacts artifacts: '*-bundles.zip', allowEmptyArchive: true + } + } + cleanup { + sh 'make clean' + deleteDir() + } + } } stage('win-RS5') { when { @@ -800,6 +819,25 @@ pipeline { } } } + post { + always { + catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE', message: 'Failed to create bundles.tar.gz') { + powershell ''' + $bundleName="windowsRS5-integration" + Write-Host -ForegroundColor Green "Creating ${bundleName}-bundles.zip" + + # archiveArtifacts does not support env-vars to , so save the artifacts in a fixed location + Compress-Archive -Path "${env:TEMP}/CIDUT.out", "${env:TEMP}/CIDUT.err" -CompressionLevel Optimal -DestinationPath "${bundleName}-bundles.zip" + ''' + + archiveArtifacts artifacts: '*-bundles.zip', allowEmptyArchive: true + } + } + cleanup { + sh 'make clean' + deleteDir() + } + } } } } diff --git a/hack/ci/windows.ps1 b/hack/ci/windows.ps1 index 8dc30e368d378..4c6368ec425ae 100644 --- a/hack/ci/windows.ps1 +++ b/hack/ci/windows.ps1 @@ -999,6 +999,10 @@ Finally { Set-Location "$env:SOURCES_DRIVE\$env:SOURCES_SUBDIR" -ErrorAction SilentlyContinue Nuke-Everything + + # Restore the TEMP path + if ($null -ne $TEMPORIG) { $env:TEMP="$TEMPORIG" } + $Dur=New-TimeSpan -Start $StartTime -End $(Get-Date) Write-Host -ForegroundColor $FinallyColour "`nINFO: executeCI.ps1 exiting at $(date). Duration $dur`n" From e101935ae801e4d7ffafa17e7a2b4365d3f01177 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Tue, 3 Sep 2019 18:47:24 +0200 Subject: [PATCH 43/59] Jenkinsfile: Windows: enabled debug-mode for daemon under test Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 1fbadd76b7ceab6e5bb683a7471f5cae8e715495) Signed-off-by: Sebastiaan van Stijn --- Jenkinsfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index dfa8f844c5338..64f44f6208177 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -727,6 +727,7 @@ pipeline { } environment { DOCKER_BUILDKIT = '0' + DOCKER_DUT_DEBUG = '1' SKIP_VALIDATION_TESTS = '1' SOURCES_DRIVE = 'd' SOURCES_SUBDIR = 'gopath' @@ -787,6 +788,7 @@ pipeline { } environment { DOCKER_BUILDKIT = '0' + DOCKER_DUT_DEBUG = '1' SKIP_VALIDATION_TESTS = '1' SOURCES_DRIVE = 'd' SOURCES_SUBDIR = 'gopath' From 5d74bd7ef90a1c552b31191390baecc20bc827ea Mon Sep 17 00:00:00 2001 From: Peter Salvatore Date: Tue, 3 Sep 2019 15:26:21 -0400 Subject: [PATCH 44/59] Jenkinsfile hack for auto-cancellation. This change will cause Jenkins to only build the latest HEAD of a PR branch, cancelling any previous builds that may already be in progress. This will decrease feedback time and help mitigate resource contention. Signed-off-by: Peter Salvatore (cherry picked from commit 85bcc524eaa86ea5dde0c7214d15658587863a4c) Signed-off-by: Sebastiaan van Stijn --- Jenkinsfile | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 64f44f6208177..a3325ac77a76a 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -26,12 +26,23 @@ pipeline { TIMEOUT = '120m' } stages { + stage('pr-hack') { + when { changeRequest() } + steps { + script { + echo "Workaround for PR auto-cancel feature. Borrowed from https://issues.jenkins-ci.org/browse/JENKINS-43353" + def buildNumber = env.BUILD_NUMBER as int + if (buildNumber > 1) milestone(buildNumber - 1) + milestone(buildNumber) + } + } + } stage('DCO-check') { when { beforeAgent true expression { !params.skip_dco } } - agent { label 'linux' } + agent { label 'amd64 && ubuntu-1804 && overlay2' } steps { sh ''' docker run --rm \ From a1638563f72977a643cd0324631e00cf0f54a386 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 4 Sep 2019 12:55:47 +0200 Subject: [PATCH 45/59] integration-cli: update TestCreateWithWorkdir for Hyper-V isolation Hyper-V isolated containers do not allow file-operations on a running container. This test currently uses `docker cp` to verify that the WORKDIR was automatically created, which cannot be done while the container is running. ``` FAIL: docker_cli_create_test.go:302: DockerSuite.TestCreateWithWorkdir assertion failed: Command: d:\CI-7\CI-f3768a669\binary\docker.exe cp foo:c:\home\foo\bar c:\tmp ExitCode: 1 Error: exit status 1 Stdout: Stderr: Error response from daemon: filesystem operations against a running Hyper-V container are not supported Failures: ExitCode was 1 expected 0 Expected no error ``` Signed-off-by: Sebastiaan van Stijn (cherry picked from commit ac9ef840ef94ff66266d3d8b9d32caf570d3b93f) Signed-off-by: Sebastiaan van Stijn --- integration-cli/docker_cli_create_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/integration-cli/docker_cli_create_test.go b/integration-cli/docker_cli_create_test.go index 2b1681d32bdf7..cb8171be63863 100644 --- a/integration-cli/docker_cli_create_test.go +++ b/integration-cli/docker_cli_create_test.go @@ -309,7 +309,15 @@ func (s *DockerSuite) TestCreateWithWorkdir(c *check.C) { // Windows does not create the workdir until the container is started if testEnv.OSType == "windows" { dockerCmd(c, "start", name) + if IsolationIsHyperv() { + // Hyper-V isolated containers do not allow file-operations on a + // running container. This test currently uses `docker cp` to verify + // that the WORKDIR was automatically created, which cannot be done + // while the container is running. + dockerCmd(c, "stop", name) + } } + // TODO: rewrite this test to not use `docker cp` for verifying that the WORKDIR was created dockerCmd(c, "cp", fmt.Sprintf("%s:%s", name, dir), prefix+slash+"tmp") } From b9f2e88286ac45b63f5e6b8864ab1f47cc6f618f Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 4 Sep 2019 13:28:16 +0200 Subject: [PATCH 46/59] hack/ci/windows.ps1: add support for DOCKER_STORAGE_OPTS Signed-off-by: Sebastiaan van Stijn (cherry picked from commit b6f596c4112818109441c84d313cf38fa06d6768) Signed-off-by: Sebastiaan van Stijn --- hack/ci/windows.ps1 | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/hack/ci/windows.ps1 b/hack/ci/windows.ps1 index 4c6368ec425ae..150b8c98e7926 100644 --- a/hack/ci/windows.ps1 +++ b/hack/ci/windows.ps1 @@ -55,6 +55,11 @@ Write-Host -ForegroundColor Red "----------------------------------------------- # # DOCKER_DUT_DEBUG if defined starts the daemon under test in debug mode. # +# DOCKER_STORAGE_OPTS comma-separated list of optional storage driver options for the daemon under test +# examples: +# DOCKER_STORAGE_OPTS="size=40G" +# DOCKER_STORAGE_OPTS="lcow.globalmode=false,lcow.kernel=kernel.efi" +# # SKIP_VALIDATION_TESTS if defined skips the validation tests # # SKIP_UNIT_TESTS if defined skips the unit tests @@ -585,6 +590,15 @@ Try { $dutArgs += "--exec-opt isolation=hyperv" } + # Arguments: Allow setting optional storage-driver options + # example usage: DOCKER_STORAGE_OPTS="lcow.globalmode=false,lcow.kernel=kernel.efi" + if (-not ("$env:DOCKER_STORAGE_OPTS" -eq "")) { + Write-Host -ForegroundColor Green "INFO: Running the daemon under test with storage-driver options ${env:DOCKER_STORAGE_OPTS}" + $env:DOCKER_STORAGE_OPTS.Split(",") | ForEach { + $dutArgs += "--storage-opt $_" + } + } + # Start the daemon under test, ensuring everything is redirected to folders under $TEMP. # Important - we launch the -$COMMITHASH version so that we can kill it without # killing the control daemon. From d53f67be35aeed91778846a5bb595a78abab5fbc Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 6 Sep 2019 20:33:12 +0200 Subject: [PATCH 47/59] hack/ci/windows.ps1: stop tailing logs after stopping the daemon There's already a step in "Nuke Everything", but lets' stop it after stopping the daemon as well Signed-off-by: Sebastiaan van Stijn (cherry picked from commit e1636ad5fa1351c3edc20dd9006fb4d6f63c9f69) Signed-off-by: Sebastiaan van Stijn --- hack/ci/windows.ps1 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hack/ci/windows.ps1 b/hack/ci/windows.ps1 index 150b8c98e7926..248d5443bd0e0 100644 --- a/hack/ci/windows.ps1 +++ b/hack/ci/windows.ps1 @@ -627,7 +627,8 @@ Try { # Start tailing the daemon under test if the command is installed if ($null -ne (Get-Command "tail" -ErrorAction SilentlyContinue)) { - $tail = start-process "tail" -ArgumentList "-f $env:TEMP\dut.out" -ErrorAction SilentlyContinue + Write-Host -ForegroundColor green "INFO: Start tailing logs of the daemon under tests" + $tail = Start-Process "tail" -ArgumentList "-f $env:TEMP\dut.out" -PassThru -ErrorAction SilentlyContinue } # Verify we can get the daemon under test to respond @@ -963,6 +964,12 @@ Try { Remove-Item "$env:TEMP\docker.pid" -force -ErrorAction SilentlyContinue } + # Stop the tail process (if started) + if ($null -ne $tail) { + Write-Host -ForegroundColor green "INFO: Stop tailing logs of the daemon under tests" + Stop-Process -InputObject $tail -Force + } + Write-Host -ForegroundColor Green "INFO: executeCI.ps1 Completed successfully at $(Get-Date)." } Catch [Exception] { From 884551acd18ff98a2c1cceff26695b587a74393c Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Sat, 20 Jul 2019 12:46:07 +0200 Subject: [PATCH 48/59] Dockerfile.windows: trim .0 from Go versions This was an oversight when changing the Dockerfile to use a build-arg; the Windows Dockerfile downloads the Go binaries, which never have a trailing `.0`. This patch makes sure that the trailing zero (if any) is removed. Signed-off-by: Sebastiaan van Stijn (cherry picked from commit c5bd6e3dc7680d6c683496f63dafb1f30f87eaa7) Signed-off-by: Sebastiaan van Stijn --- Dockerfile.windows | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.windows b/Dockerfile.windows index f18b5260cc994..613a2513f7c96 100644 --- a/Dockerfile.windows +++ b/Dockerfile.windows @@ -214,7 +214,7 @@ RUN ` Download-File $location C:\gitsetup.zip; ` ` Write-Host INFO: Downloading go...; ` - Download-File $('https://golang.org/dl/go'+$Env:GO_VERSION+'.windows-amd64.zip') C:\go.zip; ` + Download-File $('https://golang.org/dl/go'+$Env:GO_VERSION.TrimEnd('.0')"+'.windows-amd64.zip') C:\go.zip; ` ` Write-Host INFO: Downloading compiler 1 of 3...; ` Download-File https://raw.githubusercontent.com/jhowardmsft/docker-tdmgcc/master/gcc.zip C:\gcc.zip; ` From 6fdd8371100c72df1e4fae89cf19ce052d13b8e2 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 6 Sep 2019 02:57:58 +0200 Subject: [PATCH 49/59] hack/ci/windows.ps1: fix Go version check (due to trailing .0) The Windows Dockerfile downloads the Go binaries, which (unlike the Golang images) do not have a trailing `.0` in their version. Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 61450a651ba8fe4ef3cac284482a9495fc0b761d) Signed-off-by: Sebastiaan van Stijn --- Dockerfile.windows | 3 ++- hack/make.ps1 | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Dockerfile.windows b/Dockerfile.windows index 613a2513f7c96..363c0e1318c73 100644 --- a/Dockerfile.windows +++ b/Dockerfile.windows @@ -214,7 +214,8 @@ RUN ` Download-File $location C:\gitsetup.zip; ` ` Write-Host INFO: Downloading go...; ` - Download-File $('https://golang.org/dl/go'+$Env:GO_VERSION.TrimEnd('.0')"+'.windows-amd64.zip') C:\go.zip; ` + $dlGoVersion=$Env:GO_VERSION -replace '\.0$',''; ` + Download-File "https://golang.org/dl/go${dlGoVersion}.windows-amd64.zip" C:\go.zip; ` ` Write-Host INFO: Downloading compiler 1 of 3...; ` Download-File https://raw.githubusercontent.com/jhowardmsft/docker-tdmgcc/master/gcc.zip C:\gcc.zip; ` diff --git a/hack/make.ps1 b/hack/make.ps1 index 63fdbb32ad0b1..e8ea35d7984b7 100644 --- a/hack/make.ps1 +++ b/hack/make.ps1 @@ -134,7 +134,7 @@ Function Check-InContainer() { # outside of a container where it may be out of date with master. Function Verify-GoVersion() { Try { - $goVersionDockerfile=(Select-String -Path ".\Dockerfile" -Pattern "^ARG[\s]+GO_VERSION=(.*)$").Matches.groups[1].Value.TrimEnd(".0") + $goVersionDockerfile=(Select-String -Path ".\Dockerfile" -Pattern "^ARG[\s]+GO_VERSION=(.*)$").Matches.groups[1].Value -replace '\.0$','' $goVersionInstalled=(go version).ToString().Split(" ")[2].SubString(2) } Catch [Exception] { From 0459d8c7a6d4f1c82c5da2d9ebb4bfa3832c793a Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 9 Sep 2019 17:48:12 +0200 Subject: [PATCH 50/59] integration: TestInspect(): use swarm.RunningTasksCount Instead of using the locally crafted `serviceContainerCount()` utility Signed-off-by: Sebastiaan van Stijn (cherry picked from commit f874f8b6fd10a180cc47d7a9829dff63233ee20c) Signed-off-by: Sebastiaan van Stijn --- integration/service/inspect_test.go | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/integration/service/inspect_test.go b/integration/service/inspect_test.go index c79751f93082f..a4e196e52481d 100644 --- a/integration/service/inspect_test.go +++ b/integration/service/inspect_test.go @@ -7,9 +7,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/container" - "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" "github.com/google/go-cmp/cmp" "gotest.tools/assert" @@ -38,7 +36,7 @@ func TestInspect(t *testing.T) { assert.NilError(t, err) id := resp.ID - poll.WaitOn(t, serviceContainerCount(client, id, instances)) + poll.WaitOn(t, swarm.RunningTasksCount(client, id, instances)) service, _, err := client.ServiceInspectWithRaw(ctx, id, types.ServiceInspectOptions{}) assert.NilError(t, err) @@ -134,21 +132,3 @@ func fullSwarmServiceSpec(name string, replicas uint64) swarmtypes.ServiceSpec { }, } } - -func serviceContainerCount(client client.ServiceAPIClient, id string, count uint64) func(log poll.LogT) poll.Result { - return func(log poll.LogT) poll.Result { - filter := filters.NewArgs() - filter.Add("service", id) - tasks, err := client.TaskList(context.Background(), types.TaskListOptions{ - Filters: filter, - }) - switch { - case err != nil: - return poll.Error(err) - case len(tasks) == int(count): - return poll.Success() - default: - return poll.Continue("task count at %d waiting for %d", len(tasks), count) - } - } -} From eba485a3c6ac41bf844279c13a88844a512de4ac Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Mon, 9 Sep 2019 10:44:11 -0700 Subject: [PATCH 51/59] Fix Service TTY test so signal handlers work Noticed this test container not exiting correctly while debugging another issue. Before this change, signals were being eaten by bash, now they are hanlded by top. This cuts the test time in half since it doesn't have to wait for docker to SIGKILL it. Old: PASS: docker_cli_swarm_test.go:840: DockerSwarmSuite.TestSwarmServiceTTY 18.997s New: PASS: docker_cli_swarm_test.go:840: DockerSwarmSuite.TestSwarmServiceTTY 6.293s Signed-off-by: Brian Goff (cherry picked from commit e6c5563ae9d083cc72fcf84796c542047ac0a299) Signed-off-by: Sebastiaan van Stijn --- integration-cli/docker_cli_swarm_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-cli/docker_cli_swarm_test.go b/integration-cli/docker_cli_swarm_test.go index 0eca47cd09d39..9800b5fbd10d1 100644 --- a/integration-cli/docker_cli_swarm_test.go +++ b/integration-cli/docker_cli_swarm_test.go @@ -842,7 +842,7 @@ func (s *DockerSwarmSuite) TestSwarmServiceTTY(c *check.C) { name := "top" - ttyCheck := "if [ -t 0 ]; then echo TTY > /status && top; else echo none > /status && top; fi" + ttyCheck := "if [ -t 0 ]; then echo TTY > /status; else echo none > /status; fi; exec top" // Without --tty expectedOutput := "none" From 55aadb3a8f5f66b526a67744159c286d4221e88f Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 9 Sep 2019 22:32:10 +0200 Subject: [PATCH 52/59] integration-cli: swarm.RestartNode(); don't load busybox again The daemon was already created and started with the busybox image loaded, so there's no need to load the image again. Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 8fc23588f1aa14054f1134e60dd996220c595363) Signed-off-by: Sebastiaan van Stijn --- internal/test/daemon/swarm.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/test/daemon/swarm.go b/internal/test/daemon/swarm.go index 08cb9895f6d8a..f513981df19e6 100644 --- a/internal/test/daemon/swarm.go +++ b/internal/test/daemon/swarm.go @@ -36,7 +36,7 @@ func (d *Daemon) RestartNode(t testingT) { } // avoid networking conflicts d.Stop(t) - d.StartWithBusybox(t, startArgs...) + d.Start(t, startArgs...) } // StartAndSwarmInit starts the daemon (with busybox) and init the swarm From c2b84fd0e87679e2d541d386ebe3252d733d0dca Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 9 Sep 2019 22:38:44 +0200 Subject: [PATCH 53/59] integration-cli: add daemon.StartNodeWithBusybox function Starting the daemon should not load the busybox image again in most cases, so add a new `StartNodeWithBusybox` function to be clear that this one loads the busybox image, and use `StartNode()` for cases where loading the busybox image is not needed. Signed-off-by: Sebastiaan van Stijn (cherry picked from commit ead3f4e7c8b7add7beb2de44649b38f41947180f) Signed-off-by: Sebastiaan van Stijn --- integration-cli/check_test.go | 2 +- internal/test/daemon/swarm.go | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/integration-cli/check_test.go b/integration-cli/check_test.go index 38eb63579c27d..4fd9a1062d86e 100644 --- a/integration-cli/check_test.go +++ b/integration-cli/check_test.go @@ -333,7 +333,7 @@ func (s *DockerSwarmSuite) AddDaemon(c *check.C, joinSwarm, manager bool) *daemo d.StartAndSwarmInit(c) } } else { - d.StartNode(c) + d.StartNodeWithBusybox(c) } s.daemonsLock.Lock() diff --git a/internal/test/daemon/swarm.go b/internal/test/daemon/swarm.go index f513981df19e6..20300a1f4a5a4 100644 --- a/internal/test/daemon/swarm.go +++ b/internal/test/daemon/swarm.go @@ -20,12 +20,19 @@ var ( startArgs = []string{"--iptables=false", "--swarm-default-advertise-addr=lo"} ) -// StartNode starts daemon to be used as a swarm node +// StartNode (re)starts the daemon func (d *Daemon) StartNode(t testingT) { if ht, ok := t.(test.HelperT); ok { ht.Helper() } - // avoid networking conflicts + d.Start(t, startArgs...) +} + +// StartNodeWithBusybox starts daemon to be used as a swarm node, and loads the busybox image +func (d *Daemon) StartNodeWithBusybox(t testingT) { + if ht, ok := t.(test.HelperT); ok { + ht.Helper() + } d.StartWithBusybox(t, startArgs...) } @@ -41,7 +48,7 @@ func (d *Daemon) RestartNode(t testingT) { // StartAndSwarmInit starts the daemon (with busybox) and init the swarm func (d *Daemon) StartAndSwarmInit(t testingT) { - d.StartNode(t) + d.StartNodeWithBusybox(t) d.SwarmInit(t, swarm.InitRequest{}) } @@ -50,7 +57,7 @@ func (d *Daemon) StartAndSwarmJoin(t testingT, leader *Daemon, manager bool) { if th, ok := t.(test.HelperT); ok { th.Helper() } - d.StartNode(t) + d.StartNodeWithBusybox(t) tokens := leader.JoinTokens(t) token := tokens.Worker From de3a04a65d64c31f275452c604b3a2d02a39c76d Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 9 Sep 2019 23:50:04 +0200 Subject: [PATCH 54/59] Windows: skip flaky TestLogBlocking This test frequently fails on Windows RS1 (mainly), so skipping it for now on Windows; ``` ok github.com/docker/docker/daemon/logger 0.525s coverage: 43.0% of statements time="2019-09-09T20:37:35Z" level=info msg="Trying to get region from EC2 Metadata" time="2019-09-09T20:37:36Z" level=info msg="Log stream already exists" errorCode=ResourceAlreadyExistsException logGroupName= logStreamName= message= origError="" --- FAIL: TestLogBlocking (0.02s) cloudwatchlogs_test.go:313: Expected to be able to read from stream.messages but was unable to time="2019-09-09T20:37:36Z" level=error msg=Error time="2019-09-09T20:37:36Z" level=error msg="Failed to put log events" errorCode=InvalidSequenceTokenException logGroupName=groupName logStreamName=streamName message="use token token" origError="" time="2019-09-09T20:37:36Z" level=error msg="Failed to put log events" errorCode=DataAlreadyAcceptedException logGroupName=groupName logStreamName=streamName message="use token token" origError="" time="2019-09-09T20:37:36Z" level=info msg="Data already accepted, ignoring error" errorCode=DataAlreadyAcceptedException logGroupName=groupName logStreamName=streamName message="use token token" FAIL coverage: 78.2% of statements FAIL github.com/docker/docker/daemon/logger/awslogs 0.630s ``` Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 6c75c862403c98138ab0f7811f6ba9113f9e5d61) Signed-off-by: Sebastiaan van Stijn --- daemon/logger/awslogs/cloudwatchlogs_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/daemon/logger/awslogs/cloudwatchlogs_test.go b/daemon/logger/awslogs/cloudwatchlogs_test.go index 7ed52ee19dca2..d05e9249d839b 100644 --- a/daemon/logger/awslogs/cloudwatchlogs_test.go +++ b/daemon/logger/awslogs/cloudwatchlogs_test.go @@ -24,6 +24,7 @@ import ( "github.com/docker/docker/dockerversion" "gotest.tools/assert" is "gotest.tools/assert/cmp" + "gotest.tools/skip" ) const ( @@ -286,6 +287,7 @@ func TestLogClosed(t *testing.T) { } func TestLogBlocking(t *testing.T) { + skip.If(t, runtime.GOOS == "windows", "FIXME: test is flaky on Windows. See #39857") mockClient := newMockClient() stream := &logStream{ client: mockClient, From 06cca53fa0d6116a34d00a560ef754010a416e32 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 11 Sep 2019 08:51:06 +0200 Subject: [PATCH 55/59] Dockerfile: remove GOMETALINTER_OPTS This `ENV` was added to the Dockerfile in b96093fa56a9c085cb3123010be2430753c40cbc, when the repository used per-architecture Dockerfiles, and some architectures needed a different configuration. Now that we use a multi-arch Dockerfile, and CI uses a Jenkinsfile, we can remove this `ENV` from the Dockerfile, and set it in CI instead if needed. Also updated the wording and fixed linting issues in hack/validate/gometalinter Signed-off-by: Sebastiaan van Stijn (cherry picked from commit a464a3d51f89566b3e480d66903056004576cc85) Signed-off-by: Sebastiaan van Stijn --- Dockerfile | 2 -- hack/validate/gometalinter | 7 ++++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index e0b729a22d16c..edd41b1c86459 100644 --- a/Dockerfile +++ b/Dockerfile @@ -281,8 +281,6 @@ COPY --from=djs55/vpnkit@sha256:e508a17cfacc8fd39261d5b4e397df2b953690da577e2c98 ENV PATH=/usr/local/cli:$PATH ENV DOCKER_BUILDTAGS apparmor seccomp selinux -# Options for hack/validate/gometalinter -ENV GOMETALINTER_OPTS="--deadline=2m" WORKDIR /go/src/github.com/docker/docker VOLUME /var/lib/docker # Wrap all commands in the "docker-in-docker" script to allow nested containers diff --git a/hack/validate/gometalinter b/hack/validate/gometalinter index 0c0ae0d7ee9bc..4300b67a11a63 100755 --- a/hack/validate/gometalinter +++ b/hack/validate/gometalinter @@ -4,10 +4,11 @@ set -e -o pipefail SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" # CI platforms differ, so per-platform GOMETALINTER_OPTS can be set -# from a platform-specific Dockerfile, otherwise let's just set +# in the Jenkinsfile, otherwise let's just set a # (somewhat pessimistic) default of 10 minutes. -: ${GOMETALINTER_OPTS=--deadline=10m} +: "${GOMETALINTER_OPTS=--deadline=10m}" +# shellcheck disable=SC2086 gometalinter \ ${GOMETALINTER_OPTS} \ - --config ${SCRIPTDIR}/gometalinter.json ./... + --config "${SCRIPTDIR}/gometalinter.json" ./... From 35e9ee82a6a62b755941a8236856eec84c8b5ea3 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 11 Sep 2019 20:59:48 +0200 Subject: [PATCH 56/59] integration-cli: Skip TestAPIImagesSaveAndLoad on RS3 and older I've seen this test fail a number of times recently on RS1 Looking at failures, the test is taking a long time ro run (491.77s, which is more than 8 minutes), so perhaps it's just too slow on RS1, which may be because we switch to a different base image, or because we're now running on different machines. Compared to RS5 (still slow, but a lot faster); ``` --- PASS: Test/DockerSuite/TestAPIImagesSaveAndLoad (146.25s) ``` ``` --- FAIL: Test/DockerSuite/TestAPIImagesSaveAndLoad (491.77s) cli.go:45: assertion failed: Command: d:\CI-5\CI-93d2cf881\binary\docker.exe inspect --format {{.Id}} sha256:69e7c1ff23be5648c494294a3808c0ea3f78616fad67bfe3b10d3a7e2be5ff02 ExitCode: 1 Error: exit status 1 Stdout: Stderr: Error: No such object: sha256:69e7c1ff23be5648c494294a3808c0ea3f78616fad67bfe3b10d3a7e2be5ff02 Failures: ExitCode was 1 expected 0 Expected no error ``` Signed-off-by: Sebastiaan van Stijn (cherry picked from commit 5adaf52953476bf0ff612c8d78500e35821035bb) Signed-off-by: Sebastiaan van Stijn --- integration-cli/docker_api_images_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integration-cli/docker_api_images_test.go b/integration-cli/docker_api_images_test.go index 9e4f84a581f1c..a281ce20c783f 100644 --- a/integration-cli/docker_api_images_test.go +++ b/integration-cli/docker_api_images_test.go @@ -62,8 +62,8 @@ func (s *DockerSuite) TestAPIImagesSaveAndLoad(c *check.C) { v, err := kernel.GetKernelVersion() assert.NilError(c, err) build, _ := strconv.Atoi(strings.Split(strings.SplitN(v.String(), " ", 3)[2][1:], ".")[0]) - if build == 16299 { - c.Skip("Temporarily disabled on RS3 builds") + if build <= 16299 { + c.Skip("Temporarily disabled on RS3 and older because they are too slow. See #39909") } } From 168e23a2f542b603b0c21cb8a70f758c0cea074e Mon Sep 17 00:00:00 2001 From: Stefan Scherer Date: Thu, 12 Sep 2019 14:53:33 +0200 Subject: [PATCH 57/59] Zap a fixed folder, add build number to folder inside Signed-off-by: Stefan Scherer (cherry picked from commit 48662075434da5a13b1316df1ac7488a81e4cf0a) Signed-off-by: Sebastiaan van Stijn --- Jenkinsfile | 4 ++-- hack/ci/windows.ps1 | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index a3325ac77a76a..61fc12e5aaa54 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -743,7 +743,7 @@ pipeline { SOURCES_DRIVE = 'd' SOURCES_SUBDIR = 'gopath' TESTRUN_DRIVE = 'd' - TESTRUN_SUBDIR = "CI-$BUILD_NUMBER" + TESTRUN_SUBDIR = "CI" WINDOWS_BASE_IMAGE = 'mcr.microsoft.com/windows/servercore' WINDOWS_BASE_IMAGE_TAG = 'ltsc2016' } @@ -804,7 +804,7 @@ pipeline { SOURCES_DRIVE = 'd' SOURCES_SUBDIR = 'gopath' TESTRUN_DRIVE = 'd' - TESTRUN_SUBDIR = "CI-$BUILD_NUMBER" + TESTRUN_SUBDIR = "CI" WINDOWS_BASE_IMAGE = 'mcr.microsoft.com/windows/servercore' WINDOWS_BASE_IMAGE_TAG = 'ltsc2019' } diff --git a/hack/ci/windows.ps1 b/hack/ci/windows.ps1 index 248d5443bd0e0..19929f326a697 100644 --- a/hack/ci/windows.ps1 +++ b/hack/ci/windows.ps1 @@ -51,6 +51,15 @@ Write-Host -ForegroundColor Red "----------------------------------------------- # TESTRUN_DRIVE\TESTRUN_SUBDIR\CI- or # d:\CI\CI- # +# Optional environment variables help in CI: +# +# BUILD_NUMBER + BRANCH_NAME are optional variables to be added to the directory below TESTRUN_SUBDIR +# to have individual folder per CI build. If some files couldn't be +# cleaned up and we want to re-run the build in CI. +# Hence, the daemon under test is run under +# TESTRUN_DRIVE\TESTRUN_SUBDIR\PR-\ or +# d:\CI\PR-\ +# # In addition, the following variables can control the run configuration: # # DOCKER_DUT_DEBUG if defined starts the daemon under test in debug mode. @@ -428,7 +437,12 @@ Try { # Redirect to a temporary location. $TEMPORIG=$env:TEMP - $env:TEMP="$env:TESTRUN_DRIVE`:\$env:TESTRUN_SUBDIR\CI-$COMMITHASH" + if ($null -eq $env:BUILD_NUMBER) { + $env:TEMP="$env:TESTRUN_DRIVE`:\$env:TESTRUN_SUBDIR\CI-$COMMITHASH" + } else { + # individual temporary location per CI build that better matches the BUILD_URL + $env:TEMP="$env:TESTRUN_DRIVE`:\$env:TESTRUN_SUBDIR\$env:BRANCH_NAME\$env:BUILD_NUMBER" + } $env:LOCALAPPDATA="$env:TEMP\localappdata" $errorActionPreference='Stop' New-Item -ItemType Directory "$env:TEMP" -ErrorAction SilentlyContinue | Out-Null From 183cac25f9804ba2e215ab1518d2ae1275f35dbd Mon Sep 17 00:00:00 2001 From: Samuel Karp Date: Fri, 20 Sep 2019 16:02:22 -0700 Subject: [PATCH 58/59] awslogs: fix flaky TestLogBlocking unit test TestLogBlocking is intended to test that the Log method blocks by default. It does this by mocking out the internals of the awslogs.logStream and replacing one of its internal channels with one that is controlled by the test. The call to Log occurs inside a goroutine. Go may or may not schedule the goroutine immediately and the blocking may or may not be observed outside the goroutine immediately due to decisions made by the Go runtime. This change adds a small timeout for test failure so that the Go runtime has the opportunity to run the goroutine before the test fails. Signed-off-by: Samuel Karp (cherry picked from commit fd94bae0b8acc451a79667dd1cef4c583d532187) Signed-off-by: Sebastiaan van Stijn --- daemon/logger/awslogs/cloudwatchlogs_test.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/daemon/logger/awslogs/cloudwatchlogs_test.go b/daemon/logger/awslogs/cloudwatchlogs_test.go index d05e9249d839b..1a32f881e8432 100644 --- a/daemon/logger/awslogs/cloudwatchlogs_test.go +++ b/daemon/logger/awslogs/cloudwatchlogs_test.go @@ -24,7 +24,6 @@ import ( "github.com/docker/docker/dockerversion" "gotest.tools/assert" is "gotest.tools/assert/cmp" - "gotest.tools/skip" ) const ( @@ -286,8 +285,10 @@ func TestLogClosed(t *testing.T) { } } +// TestLogBlocking tests that the Log method blocks appropriately when +// non-blocking behavior is not enabled. Blocking is achieved through an +// internal channel that must be drained for Log to return. func TestLogBlocking(t *testing.T) { - skip.If(t, runtime.GOOS == "windows", "FIXME: test is flaky on Windows. See #39857") mockClient := newMockClient() stream := &logStream{ client: mockClient, @@ -301,18 +302,20 @@ func TestLogBlocking(t *testing.T) { err := stream.Log(&logger.Message{}) errorCh <- err }() + // block until the goroutine above has started <-started select { case err := <-errorCh: t.Fatal("Expected stream.Log to block: ", err) default: - break } + // assuming it is blocked, we can now try to drain the internal channel and + // unblock it select { - case <-stream.messages: - break - default: + case <-time.After(10 * time.Millisecond): + // if we're unable to drain the channel within 10ms, something seems broken t.Fatal("Expected to be able to read from stream.messages but was unable to") + case <-stream.messages: } select { case err := <-errorCh: From dfadf729d338b171451040fb31fd2b9c16c3ab3d Mon Sep 17 00:00:00 2001 From: Tibor Vass Date: Tue, 24 Sep 2019 23:40:33 +0000 Subject: [PATCH 59/59] Jenkinsfile: move integration step cleanup to amd64 where it was intended to be Signed-off-by: Tibor Vass (cherry picked from commit f3d8b8ae74804ba6a0386186c1c65bd1d556075a) Signed-off-by: Sebastiaan van Stijn --- Jenkinsfile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 61fc12e5aaa54..efc859f3e22d9 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -332,7 +332,8 @@ pipeline { always { sh ''' echo "Ensuring container killed." - docker rm -vf docker-pr$BUILD_NUMBER || true + cids=$(docker ps -aq -f name=docker-pr${BUILD_NUMBER}-*) + [ -n "$cids" ] && docker rm -vf $cids || true ''' sh ''' @@ -701,8 +702,6 @@ pipeline { sh ''' echo "Ensuring container killed." docker rm -vf docker-pr$BUILD_NUMBER || true - cids=$(docker ps -aq -f name=docker-pr${BUILD_NUMBER}-*) - [ -n "$cids" ] && docker rm -vf $cids || true ''' sh '''