Skip to content

Unit tests for cli/command/image package#32248

Merged
vdemeester merged 1 commit intomoby:masterfrom
icapurro:cli-image-tests
Apr 24, 2017
Merged

Unit tests for cli/command/image package#32248
vdemeester merged 1 commit intomoby:masterfrom
icapurro:cli-image-tests

Conversation

@icapurro
Copy link
Contributor

@icapurro icapurro commented Mar 31, 2017

This PR adds unit tests for the cli/command/image package. Part of the work on #31217

Signed-off-by: Ignacio Capurro [email protected]

- What I did
Added unit tests for the following commands in package cli/command/image

  • history.go (100%)
  • inspect.go (100%)
  • load.go(100%)
  • pull.go (96.9%)
  • remove.go (100%)
  • tag.go (100%)
  • import.go (100%)
  • list.go (100%)
  • prune.go (100%)
  • push.go (95.2%)
  • save.go (100%)

To accomplish the 100% package coverage the following two commands need to be tested:

  • build.go (issue link goes here)
  • tag.go (issue link goes here)

I will the issues to work on them since this PR was getting really big and those two commands in particular will need some code refactor to accomplish a good coverage.

- How I did it
I followed @vdemeester previous test structure in other cli commands. Used gold files, builders created under cli/internal/test/builders and added new interfaces for some structs to be stubbed.

- How to verify it
Run the unit tests or check the Jenkins build.

Before this PR

ok  	github.com/docker/docker/cli/command/image	0.086s	coverage: 0.0% of statements

After this PR

ok  	github.com/docker/docker/cli/command/image	0.346s	coverage: 45.4% of statements

- Description for the changelog

Added unit test coverage to some cli image commands.

Copy link
Member

Choose a reason for hiding this comment

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

Should contain NewTag instead of Leave (same for below 😝)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks! You can figure out from where I'm copying the test structure now 😄

@vdemeester vdemeester mentioned this pull request Mar 31, 2017
19 tasks
@vdemeester vdemeester requested review from dnephin and vdemeester April 1, 2017 18:42
@GordonTheTurtle GordonTheTurtle added the dco/no Automatically set by a bot when one of the commits lacks proper signature label Apr 1, 2017
@GordonTheTurtle GordonTheTurtle removed the dco/no Automatically set by a bot when one of the commits lacks proper signature label Apr 1, 2017
@icapurro icapurro changed the title [wip] Tests for cli/command/image package Tests for cli/command/image package Apr 3, 2017
@icapurro icapurro changed the title Tests for cli/command/image package Unit tests for cli/command/image package Apr 3, 2017
@vdemeester vdemeester added the status/failing-ci Indicates that the PR in its current state fails the test suite label Apr 3, 2017
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.

Big PR ! Nice, thanks for putting this work @icapurro. Few comments from me though 😉,

The less production code is changed when writing tests (afterwards), the better.

We shouldn't modify OutStream or InStream for writing tests (and this cli/command/stream.go, etc.. shouldn't be changed — FakeClican). Why not do a refactoring after if we feel like it, but it shouldn't change a think for the tests — if it does, we coupled our test heavily on the implementation.

On the same note, cli/compose/schema/bindata.go has no reason to change in this PR, don't know why it did, but this change shouldn't be there.

Copy link
Member

Choose a reason for hiding this comment

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

I'm pretty sure this is not required and complexify the code 😓

Copy link
Member

Choose a reason for hiding this comment

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

Same here, the only change I would see here is the addition of CredentialsStore on the Cli interface.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did this because I need to stub the method IsTerminal(), and I don't see any other way to do it if the Cli interface only accepts the specific OutStream struct. Do you see any other alternative?

Copy link
Member

Choose a reason for hiding this comment

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

I think you can avoid this change by adding this to cli/command/in_test.go

func NewStubInStream(isTerminal bool) *InStream {
    return &InStream{
        isTerminal: isTerminal,
        in: ioutil.NopCloser(strings.NewReader("")),
    }
}

and using that stream in the FakeCli.

You can probably leave the existing NewFakeCli() as is, and add a new NewFakeCliWithStreams() that takes all the streams, not just stdout.

Copy link
Contributor Author

@icapurro icapurro Apr 4, 2017

Choose a reason for hiding this comment

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

@dnephin I did what you propose, but I can't find a way to import a function from a *_test file in package cli/command into another *_test file in package cli/command/image. From what I've been reading it seems not possible, but maybe I'm missing something.

A solution could be to define that function in cli/command/in.go but we will end up with a function intended 100% for testing included in the production binary. 😿

Copy link
Member

Choose a reason for hiding this comment

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

Ah, you're right. I guess I was mistaken.

A function like this (with a better name) might still be ok in in.go, another option would be to create a setter for isTerminal.

Copy link
Member

Choose a reason for hiding this comment

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

Could go in the same package tree as the builders, i.e. cli/internal/test (to make sure it can't be imported outside of cli package 👼 )

Copy link
Member

Choose a reason for hiding this comment

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

Hum I used the struct here client.Client, not sure if it does a different though 😛

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It shouldn't, I'll change it.

Copy link
Member

Choose a reason for hiding this comment

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

I don't think we need golden usage here, a assert.Error(t, cmd.Execute(), tc.expectedError) (with the corresponding expectedError field in the anonymous struct) feels simpler.

It would be more consistent with other cli tests too.

Copy link
Member

Choose a reason for hiding this comment

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

assert.Error does a "contains", so we only need to verify that it contains "requires exactly 1 argument(s)" or …

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I just feel that I need to generalise this as much as possible. But I didn't know assert.Error does a contains , I'll change it.

Copy link
Member

Choose a reason for hiding this comment

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

I tend to prefer if tc.outputRegex == "", because it's more readable for a human (and tests are meant to be read by humans). It's a nit though 👼

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, let me follow the same style then.

Copy link
Member

Choose a reason for hiding this comment

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

And here

Copy link
Member

Choose a reason for hiding this comment

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

And here.

Copy link
Member

Choose a reason for hiding this comment

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

If we don't introduce OutputStreamer (and I really think we shouldn't), this is not required.

Copy link
Member

Choose a reason for hiding this comment

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

Same as for OutStreamer, I think we shouldn't have to do that.

Copy link
Member

Choose a reason for hiding this comment

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

Neither that one.

@vdemeester
Copy link
Member

Ah, and there is a build error on gofmt.

09:39:31 These files are not properly gofmt'd:
09:39:31  - cli/command/image/client_test.go
09:39:31  - cli/command/image/history_test.go
09:39:31  - cli/command/image/import_test.go
09:39:31  - cli/command/image/inspect_test.go
09:39:31  - cli/command/image/list_test.go
09:39:31  - cli/command/image/load_test.go
09:39:31 
09:39:31 Please reformat the above files using "gofmt -s -w" and commit the result.

@icapurro
Copy link
Contributor Author

icapurro commented Apr 3, 2017

@vdemeester Thanks for the thorough review! I applied most of your comments but I still have question on the following:

  • The OutputStreamer interface. I need a way to stub the IsTerminal method from cli.Out()
  • A nicer approach to count method invocations in cli/command/image/inspect_test.go

@icapurro
Copy link
Contributor Author

icapurro commented Apr 4, 2017

@dnephin I went in the direction of creating a setter SetIsTerminal(tty bool) in the CommonStream struct that is applied to both InStream and OutStream.

FYI: CommonStream was created in this PR to remove the duplicated code from InStream and OutStream.

@vdemeester vdemeester self-assigned this Apr 4, 2017
@GordonTheTurtle GordonTheTurtle added the dco/no Automatically set by a bot when one of the commits lacks proper signature label Apr 5, 2017
@GordonTheTurtle GordonTheTurtle removed the dco/no Automatically set by a bot when one of the commits lacks proper signature label Apr 5, 2017
@dnephin dnephin added rebuild/z and removed status/failing-ci Indicates that the PR in its current state fails the test suite labels Apr 5, 2017
@icapurro
Copy link
Contributor Author

@dnephin @vdemeester love the moby project initiative, but I think the repo rename broke the PR update... I made the changes in my branch but they are not appearing here. Should I create a new PR?

@dnephin
Copy link
Member

dnephin commented Apr 18, 2017

I think it's broken for all PRs. We're looking into it. Don't open a new PR just yet.

@GordonTheTurtle GordonTheTurtle added the dco/no Automatically set by a bot when one of the commits lacks proper signature label Apr 20, 2017
@GordonTheTurtle GordonTheTurtle removed the dco/no Automatically set by a bot when one of the commits lacks proper signature label Apr 21, 2017
@icapurro icapurro force-pushed the cli-image-tests branch 3 times, most recently from 461c5ea to c3ae796 Compare April 22, 2017 00:19
@icapurro
Copy link
Contributor Author

@dnephin can we re run experimental and windowsRS1 please? thanks!

@icapurro
Copy link
Contributor Author

Should be done

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

@vdemeester vdemeester merged commit 663f0ba into moby:master Apr 24, 2017
@lowenna
Copy link
Member

lowenna commented Apr 24, 2017

😢 This has broken docker run -it on Windows....

@vdemeester
Copy link
Member

@jhowardmsft arg, really ? I'll have to try it out and see how to fix it then 😓

@aaronlehmann
Copy link

Sorry I didn't have a chance to review the final version.

With testify, the expected value comes before the actual value. So:

assert.Equal(t, ref, "image:local")

should be:

assert.Equal(t, "image:local", ref)

... and so on.

There are also some opportunities to use testify helpers like assert.Len and assert.True.

I can make these changes if that's helpful.

@aaronlehmann
Copy link

Opened #32829

Comment on lines +87 to +89
imageSaveFunc: func(images []string) (io.ReadCloser, error) {
return ioutil.NopCloser(strings.NewReader("")), nil
},
Copy link
Member

Choose a reason for hiding this comment

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

Heh; 7 Years later, and I stumble on this line to discover that tc.imageSaveFunc was not wired up here, so this test didn't actually run the tests 😂

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.

7 participants