This tests, when failing, only produced a non-informative "exit status 1",
which limits investigating why it failed.
This patch:
- Rewrites the parallel pushes to use an error-group, and asserts each
push to get the failure output of the command.
- Simplifies the Dockerfile that's used for building the test-image,
removing steps that were not needed for the test.
- Adds a cleanup step to make sure the images are deleted after the
test, or if the test fails (although the test-suite should already
handle this).
Before this, a failure looked like:
make BIND_DIR=. TEST_FILTER='TestConcurrentPush' test-integration-cli
=== FAIL: arm64.integration-cli TestDockerRegistrySuite/TestConcurrentPush (5.49s)
docker_cli_push_test.go:159: assertion failed: error is not nil: exit status 1: concurrent push failed with error: exit status 1
check_test.go:476: [dfa779e71fdf8] daemon is not started
--- FAIL: TestDockerRegistrySuite/TestConcurrentPush (5.49s)
With this patch applied:
make BIND_DIR=. TEST_FILTER='TestConcurrentPush' test-integration-cli
=== FAIL: arm64.integration-cli TestDockerRegistrySuite/TestConcurrentPush (2.47s)
docker_cli_push_test.go:156: assertion failed:
Command: /usr/local/cli-integration/docker push 127.0.0.1:5000/dockercli/busybox:push2nosuch
ExitCode: 1
Error: exit status 1
Stdout: The push refers to repository 127.0.0.1:5000/dockercli/busybox
Stderr: tag does not exist: 127.0.0.1:5000/dockercli/busybox:push2nosuch
Failures:
ExitCode was 1 expected 0
Expected no error
docker_cli_push_test.go:160: assertion failed: error is not nil: exit status 1
check_test.go:476: [db77ef03a8fd8] daemon is not started
--- FAIL: TestDockerRegistrySuite/TestConcurrentPush (2.47s)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
| ... | ... |
@@ -15,6 +15,7 @@ import ( |
| 15 | 15 |
"github.com/moby/moby/api/types/versions" |
| 16 | 16 |
"github.com/moby/moby/v2/integration-cli/cli" |
| 17 | 17 |
"github.com/moby/moby/v2/integration-cli/cli/build" |
| 18 |
+ "golang.org/x/sync/errgroup" |
|
| 18 | 19 |
"gotest.tools/v3/assert" |
| 19 | 20 |
is "gotest.tools/v3/assert/cmp" |
| 20 | 21 |
"gotest.tools/v3/icmd" |
| ... | ... |
@@ -134,41 +135,38 @@ func (s *DockerRegistrySuite) TestConcurrentPush(c *testing.T) {
|
| 134 | 134 |
var repos []string |
| 135 | 135 |
for _, tag := range []string{"push1", "push2", "push3"} {
|
| 136 | 136 |
repo := fmt.Sprintf("%v:%v", imgRepo, tag)
|
| 137 |
- buildImageSuccessfully(c, repo, build.WithDockerfile(fmt.Sprintf(` |
|
| 138 |
- FROM busybox |
|
| 139 |
- ENTRYPOINT ["/bin/echo"] |
|
| 140 |
- ENV FOO foo |
|
| 141 |
- ENV BAR bar |
|
| 142 |
- CMD echo %s |
|
| 143 |
-`, repo))) |
|
| 137 |
+ buildImageSuccessfully(c, repo, build.WithDockerfile(fmt.Sprintf("FROM busybox\nCMD echo hello from %s\n", repo)))
|
|
| 144 | 138 |
repos = append(repos, repo) |
| 145 | 139 |
} |
| 146 | 140 |
|
| 147 |
- // Push tags, in parallel |
|
| 148 |
- results := make(chan error, len(repos)) |
|
| 141 |
+ cleanup := func() {
|
|
| 142 |
+ args := append([]string{"rmi", "--force"}, repos...)
|
|
| 143 |
+ cli.DockerCmd(c, args...) |
|
| 144 |
+ } |
|
| 145 |
+ defer cleanup() |
|
| 149 | 146 |
|
| 147 |
+ // Push tags, in parallel |
|
| 148 |
+ var eg errgroup.Group |
|
| 150 | 149 |
for _, repo := range repos {
|
| 151 |
- go func(repo string) {
|
|
| 150 |
+ eg.Go(func() error {
|
|
| 152 | 151 |
result := icmd.RunCommand(dockerBinary, "push", repo) |
| 153 |
- results <- result.Error |
|
| 154 |
- }(repo) |
|
| 155 |
- } |
|
| 156 |
- |
|
| 157 |
- for range repos {
|
|
| 158 |
- err := <-results |
|
| 159 |
- assert.NilError(c, err, "concurrent push failed with error: %v", err) |
|
| 152 |
+ // check the result, but don't fail immediately (result.Assert) |
|
| 153 |
+ // to prevent the errgroup from not completing. |
|
| 154 |
+ assert.Check(c, result.Equal(icmd.Success)) |
|
| 155 |
+ return result.Error |
|
| 156 |
+ }) |
|
| 160 | 157 |
} |
| 158 |
+ assert.NilError(c, eg.Wait()) |
|
| 161 | 159 |
|
| 162 | 160 |
// Clear local images store. |
| 163 |
- args := append([]string{"rmi"}, repos...)
|
|
| 164 |
- cli.DockerCmd(c, args...) |
|
| 161 |
+ cleanup() |
|
| 165 | 162 |
|
| 166 | 163 |
// Re-pull and run individual tags, to make sure pushes succeeded |
| 167 | 164 |
for _, repo := range repos {
|
| 168 | 165 |
cli.DockerCmd(c, "pull", repo) |
| 169 | 166 |
cli.DockerCmd(c, "inspect", repo) |
| 170 | 167 |
out := cli.DockerCmd(c, "run", "--rm", repo).Combined() |
| 171 |
- assert.Equal(c, strings.TrimSpace(out), "/bin/sh -c echo "+repo) |
|
| 168 |
+ assert.Equal(c, strings.TrimSpace(out), "hello from "+repo) |
|
| 172 | 169 |
} |
| 173 | 170 |
} |
| 174 | 171 |
|