Skip to content

Test & Fix build with rm/force-rm matrix#35139

Merged
vdemeester merged 1 commit intomoby:masterfrom
simonferquel:fix-remaining-containers-on-fail
Oct 13, 2017
Merged

Test & Fix build with rm/force-rm matrix#35139
vdemeester merged 1 commit intomoby:masterfrom
simonferquel:fix-remaining-containers-on-fail

Conversation

@simonferquel
Copy link
Contributor

fix #35116

- What I did

Added test cases for build related to rm/force-rm flags, and fixed a few related issues

- How I did it

Added a test with a case matrix in integration/build reproducing potential issues and fixed them in build code base

- How to verify it

run the tests :)

Note:
docker build rm and force-rm flags might be better documented:
It is unclear that on build failures, rm still remove successfull individual intermediate containers (only the failing one is kept).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe reuse the context for all the calls ? 🤔

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but I'd like @tonistiigi to have a look as well 👍

@simonferquel simonferquel force-pushed the fix-remaining-containers-on-fail branch 2 times, most recently from dc4cffc to 9361b6c Compare October 9, 2017 16:02
Copy link
Member

@tonistiigi tonistiigi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andrewhsu We should take this for next v17.10 RC. lmk if you need cherry-pick prs.

cc @dnephin to check the test

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is another ForceRemove defer inside the dispatch function

defer d.builder.containerManager.RemoveAll(d.builder.Stdout)
that overrides this condition. I think we should keep always removing after each dispatch to be consistent with old versions and better protect against crashes. This is how it works atm as well but this code/comment indicates the opposite.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch @tonistiigi. I'll put remove handling in the global dispatch function.

@simonferquel
Copy link
Contributor Author

@tonistiigi I centralized intermediate container removal logic in a single defer block in the dispatch() function with proper comments.
I think it makes it easier to understand the effect of rm/force-rm flags.
I'll make a PR in CLI that tries to make the -rm flag documentation more precise.

@simonferquel simonferquel force-pushed the fix-remaining-containers-on-fail branch from 87680a5 to f420a43 Compare October 10, 2017 09:50
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps making these two separate conditions (small bit of duplication, but may be better to understand without having to add comments to explain)

if d.builder.options.ForceRemove {
	d.builder.containerManager.RemoveAll(d.builder.Stdout)
	return
}
if d.builder.options.Remove && err == nil {
	d.builder.containerManager.RemoveAll(d.builder.Stdout)
	return
}

One thing I was wondering; it --rm=false, should --force-remove still remove containers? Can you check on an older version?

If that's the case, then it should likely look like:

if !d.builder.options.Remove {
	return
}
if err == nil || d.builder.options.ForceRemove {
	d.builder.containerManager.RemoveAll(d.builder.Stdout)
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thaJeztah on options deserialization, there is a reconcilation that forces rm to true if force-rm is true:

	if httputils.BoolValue(r, "forcerm") && versions.GreaterThanOrEqualTo(version, "1.12") {
		options.Remove = true
	} else if r.FormValue("rm") == "" && versions.GreaterThanOrEqualTo(version, "1.12") {
		options.Remove = true
	} else {
		options.Remove = httputils.BoolValue(r, "rm")
	}

@simonferquel
Copy link
Contributor Author

@thaJeztah condition expression split :)

Copy link
Member

@dnephin dnephin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, fix looks good, left some suggestions for the tests

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use https://golang.org/pkg/testing/#T.Run so that all test cases run even if one of the require fail.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe TestBuildWithRemoveAndForceRemove or something like that? Intermediate containers seem like more of the test result than the test condition. And this tests both failures and non-failures, so failures doesn't seem relevant to the name.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you use t.Run() you can use this extra string as the test name so that any assert/require failure has this extra information associated with it, instead of just the last assert.Equal()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will make it impossible to run the test in parallel with any other test that creates containers.

Instead of counting the total number of containers I think it would be possible to parse the build output and grab the container ids. Then attempt to list or inspect the containers with those ids to see if they exist.

@tonistiigi
Copy link
Member

LGTM

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one nit in the code; also can you check if some of the commits should be squashed?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you remove the blank lines between the github.com... dependencies, and make sure they're sorted correctly?

import (
	"archive/tar"
	"bytes"
	"context"
	"encoding/json"
	"io"
	"strings"
	"testing"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/api/types/filters"
	"github.com/docker/docker/integration/util/request"
	"github.com/docker/docker/pkg/jsonmessage"
	"github.com/stretchr/testify/require"
)

Copy link
Member

@vdemeester vdemeester left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🐸

Copy link
Member

@dnephin dnephin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor nits on the test

LGTM

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These names could be a lot more descriptive. The dashes can also be spaces, testing.Run() will take care of adding the dashes.

  • "successful build with no removal"
  • "successful build with remove"
  • "successful build with remove and force remove"
  • "failed build with no removal"
    ...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this cleanup will be missed if require.NoError(t, err) fails the test, could be deferred.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parsing of ids from the response would be great in a separate function to keep the test more readable.

Signed-off-by: Simon Ferquel <simon.ferquel@docker.com>
@simonferquel simonferquel force-pushed the fix-remaining-containers-on-fail branch from 4473173 to 172e73a Compare October 12, 2017 08:22
@simonferquel
Copy link
Contributor Author

@dnephin, @thaJeztah, latest nits are fixed, everything squashed and rebased

Copy link
Member

@dnephin dnephin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@dnephin
Copy link
Member

dnephin commented Oct 12, 2017

powerpc failures mostly look like flakes, but the busybox missing flag is weird. I'll try restarting it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[17.10-rc1] Build containers not being removed after failing build

6 participants