Compare commits

..

64 Commits

Author SHA1 Message Date
dc75023a9a Merge pull request #503 from jose-bigio/18.03_version_bump
[18.03] version bump to 18.03.1-ce-rc1
2018-04-11 23:24:42 -07:00
9fb2695fa5 Merge pull request #505 from jose-bigio/18.03_changelog
[18.03] changelog
2018-04-11 23:24:25 -07:00
473116d3a2 Changelog for 18.03.1
Signed-off-by: jose-bigio <jose.bigio@docker.com>
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
2018-04-12 05:33:22 +00:00
f10cbe710b Merge pull request #506 from thaJeztah/18.03-backport-defensive-attachment-processing
[18.03] daemon/cluster: handle partial attachment entries during configure
2018-04-11 21:34:44 -07:00
aff214cf5c Merge pull request #497 from thaJeztah/18.03-backport-fix-manifest-docs-typo
[18.03] [docs] Fix typo in manifest command docs: updated `MANFEST` to `MANIFEST`
2018-04-11 21:32:33 -07:00
4cff440f16 Merge pull request #499 from thaJeztah/18.03-backport-bump-golang-1.9.5
[18.03] bump golang to 1.9.5
2018-04-11 21:28:45 -07:00
5770d86dae Merge pull request #458 from thaJeztah/18.03-backport-resilient-cpu-sampling
[18.03] daemon/stats: more resilient cpu sampling
2018-04-11 21:20:16 -07:00
e921cf31fc Merge pull request #487 from thaJeztah/18.03-backport-update-containerd-1.0.3
[18.03] containerd: update to 1.0.3 release
2018-04-11 19:17:35 -07:00
7ee3cf582d Merge pull request #470 from thaJeztah/18.03-fix-exec-apparmor
[18.03] Fix AppArmor not being applied to Exec processes
2018-04-11 17:48:49 -07:00
8e67119f1f Merge pull request #476 from thaJeztah/18.03-systemd-memlimit
[18.03] Test for systemd cgroupdriver memory setting
2018-04-11 17:47:37 -07:00
59875dbe8e Merge pull request #478 from corbin-coleman/update-changelog
[18.03] Remove update runc line
2018-04-11 17:41:57 -07:00
0190af907b Merge pull request #490 from cpuguy83/18.03_backport_36711
[18.03] Don't sort plugin mounts slice
2018-04-11 17:32:14 -07:00
711807560d Merge pull request #508 from thaJeztah/18.03-backport-LayerLeak
[18.03] Fix Windows layer leak when write fails
2018-04-11 17:31:41 -07:00
1556d2d2f9 Merge pull request #504 from thaJeztah/18.03-backport-content-trust-tests
[18.03] backport content trust tests, windows, test-refactoring
2018-04-11 14:06:59 -07:00
d8b4bd5c6f Fix Windows layer leak when write fails
Signed-off-by: Darren Stahl <darst@microsoft.com>
(cherry picked from commit 1f28844d7869609f371ab2a7881e4488a79a7e27)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-11 11:54:18 -07:00
603c7932bb daemon/cluster: handle partial attachment entries during configure
We have seen a panic when re-joining a node to a swarm cluster. The
cause of the issue is unknown, so we just need to add a test for nil
objects and log when we get the condition. Hopefully this can prevent
the crash and we can recover the config at a later time.

Signed-off-by: Stephen J Day <stephen.day@docker.com>
(cherry picked from commit 454128c6e82cded211c1412e3eb350b1f7533ee2)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-11 11:46:06 -07:00
7bfd67bece Fix imports in CLI compose test
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-11 11:39:36 -07:00
010ba8f1dd Fix test for trust inspect --pretty
This fix was part of 8c3d0b93d6,
but was reverted due to the order in which other changes were
backported.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 17:28:16 -07:00
7dd4bb6171 18.03.1-ce-rc1 version bump
Signed-off-by: jose-bigio <jose.bigio@docker.com>
2018-04-10 15:52:21 -07:00
566c20094c Remove filewatcher
Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit c0588a9c8f)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 15:21:13 -07:00
bc28daf367 Add more content trust tests
Importing from moby's DockerTrustSuite tests.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 8b00c5cfd8)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 15:20:40 -07:00
a20423b7f7 Add a build unit test for symlinked context
Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit 00b803b2d8)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 15:20:29 -07:00
8723ba6cc0 Remove unused powershell function
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 10baa756b2)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 15:19:06 -07:00
c270672ced Fixes some unit tests to be able to run them on windows
Some of them are skipped for now (because the feature is not supported
or needs more work), some of them are fixed.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 0cf2e6353a)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 15:18:59 -07:00
0d45d8f964 Add appveyor setup to build and unit test
Adds a `make.ps1` powershell script to make it easy to compile and test.

```
.\scripts\make.ps1 -Binary
INFO: make.ps1 starting at 03/01/2018 14:37:28
INFO: Building...

 ________   ____  __.
 \_____  \ |    |/ _|
 /   |   \|      <
 /    |    \    |  \
 \_______  /____|__ \
         \/        \/

INFO: make.ps1 ended at 03/01/2018 14:37:30

.\scripts\make.ps1 -TestUnit
```

The next step is to run e2e tests on windows too.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit facb22573d)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 15:18:52 -07:00
311944ec04 Small content trust enhancement
- `replaceDockerfileForContentTrust` is only used when content trust is
  enabled, so remove the boolean.
- rename `isContentTrustEnabled` to `contentTrustEnabled`

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 63ebcae382)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 15:14:17 -07:00
ad89cb6a38 Only read trust setting from options
Rename IsTrusted to ContentTrustEnabled

Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit feae0e9756)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 15:12:02 -07:00
aba0bb77e1 Refactor content_trust cli/flags handling
Remove the global variable used. Allows easier unit testing.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 6e21829af4)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 15:07:03 -07:00
a20c69243b Cleanup config load error handling
Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit 789acb526c)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 15:01:36 -07:00
bcb040440f Don't set a default filename for ConfigFile
With a default filename tests will leave a file in the working directory
that is never cleaned up.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit 7c8b5708eb)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 15:01:20 -07:00
2cc21bf56f Use new APIClient interface
Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit cff874122c)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 14:55:17 -07:00
a218857a9a Convert assert.Check(t, is.Error()) to assert.Error
git grep -l -P '^\s+assert\.Check\(t, is\.Error\(' | \
    xargs perl -pi -e 's/^(\s+assert\.)Check\(t, is\.Error\((.*)\)$/\1Error(t, \2/'

Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit e15b208e96)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 14:48:48 -07:00
a723f7351d manual clean of asserts
Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit f21276575f)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 14:48:41 -07:00
df9ed934e3 Convert assert.Check with
git grep -l -P '^\s+assert\.Check\(t, ' | \
    xargs perl -pi -e 's/^(\s+assert)\.Check(\(t, (?!is).*(\.Execute\(|\.Set\(|\.Write\(|\.Close\(|\.Untar\(|\.WriteFile\(|Validate\().*\)$)/\1.NilError\2/'

Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit 078cbc9c4b)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 14:48:34 -07:00
f7124ab5e4 Convert to assert.NilError
Using:

  git grep -l '^\s\+assert\.Check(t, err)$' | \
    xargs sed -i -e 's/^\(\s\+assert\)\.Check(t, err)$/\1.NilError(t, err)/'

Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit baf65a5502)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 14:48:09 -07:00
9550f71467 dont prompt for github creds in unit test
Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit 0f11a310fd)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 14:45:49 -07:00
1f1816b098 Remove testutil
Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit 681c921528)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 14:40:48 -07:00
7c2863a6e0 Post migration fixes
Fix tests that failed when using cmp.Compare()
internal/test/testutil/assert
InDelta
Fix DeepEqual with kube metav1.Time
Convert some ErrorContains to assert

Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit 5155cda716)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 14:33:18 -07:00
fb9700fdbd Automated migration
Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit 39c2ca57c1)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 14:29:47 -07:00
70083e56be Replace testify vendor with updated gotestyourself
Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit 5ef8835f23)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 13:54:23 -07:00
659ea5343c Update some assertions.
and fix some tests

Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit 93615dd967)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 13:54:15 -07:00
49dc9b064e Update gotestyourself dependency
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 98ba439f67)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 12:12:52 -07:00
9f1c3a6814 Migrate DockerTrustSuite to docker/cli e2e tests
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 5433ceb12ead305d8c85e8e27c4b4d842ef88ae0)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 11:59:36 -07:00
83bc7fbbe0 Revert "update integration-cli tests for stderr output"
This reverts commit d5f8753b88.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 11:51:53 -07:00
fbe9d5d378 Revert "Blacklist tests, will be rewritten later on"
This reverts commit a720337d2e.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-10 11:51:37 -07:00
c925888822 Bump Golang to 1.9.5
go1.9.5 (released 2018/03/28) includes fixes to the compiler, go command, and
net/http/pprof package. See the Go 1.9.5 milestone on the issue tracker for details:

https://github.com/golang/go/issues?q=milestone%3AGo1.9.5

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit c62336593118020462d65d4e9784143e07de2da7)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-09 17:04:22 -07:00
2032af137d Add Ubuntu 18.04 arm64 builds
Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
(cherry picked from commit aac8310bbee3c7480487a624756d25d22d53c7dd)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-09 17:04:13 -07:00
7b5c3637ab Add packaging code for Fedora 28
Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
(cherry picked from commit 00148a3c994c753a3e171b1aa2b422342e00fd16)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-09 17:04:06 -07:00
abd6f38345 Add building code for Ubuntu Bionic (18.04) LTS
Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
(cherry picked from commit 460f0b5becbbc5ec2bd341df409af8f06c0a70f7)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-09 17:03:59 -07:00
212445876d Bump other Dockerfiles to Go 1.9.5
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-09 16:57:14 -07:00
9134da61fe Update Golang to 1.9.5
go1.9.5 (released 2018/03/28) includes fixes to the compiler, go
command, and net/http/pprof package. See the Go 1.9.5 milestone on
the issue tracker for details:

https://github.com/golang/go/issues?q=milestone%3AGo1.9.5

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 0b6f8a7eff325a683b10d64db363da2145aa1c36)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-09 16:42:42 -07:00
45c8a7d911 Bump Golang to 1.9.5
go1.9.5 (released 2018/03/28) includes fixes to the compiler, go command, and
net/http/pprof package. See the Go 1.9.5 milestone on the issue tracker for details:

https://github.com/golang/go/issues?q=milestone%3AGo1.9.5

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit d3b8ceb52c)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-09 16:35:48 -07:00
64fe575962 [docs] Fix typo in manifest command docs: updated MANFEST to MANIFEST.
Signed-off-by: Bogdan Anton <contact@bogdananton.ro>
(cherry picked from commit 9fa6bd4174)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-09 13:31:04 -07:00
4b4614c8b7 Don't sort plugin mounts slice
This was added as part of a53930a04fa81b082aa78e66b342ff19cc63cc5f with
the intent to sort the mounts in the plugin config, but this was sorting
*all* the mounts from the default OCI spec which is problematic.

In reality we don't need to sort this because we are only adding a
self-binded mount to flag it as rshared.

We may want to look at sorting the plugin mounts before they are added
to the OCI spec in the future, but for now I think the existing behavior
is fine since the plugin author has control of the order (except for the
propagated mount).

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
(cherry picked from commit ec90839ca302ca53a7d55e4c7f79e7b4779f5e15)
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
2018-04-04 08:25:55 -04:00
0eadfaeecd containerd: update to 1.0.3 release
Signed-off-by: Stephen J Day <stephen.day@docker.com>
(cherry picked from commit 554d657c1f7a0f4dce51f0d26407fb05a0580fa1)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-03 13:36:06 -07:00
7364fc672e Remove update runc line
Removes a line talking about updating runc to a specific commit.
Runc was updated twice during separate rcs and this line might cause confusion for users in regards to what version of runc to expect in 18.03.

Signed-off-by: corbin-coleman <corbin.coleman@docker.com>
2018-03-23 14:46:04 -07:00
c05a7395f2 Test for systemd cgroupdriver memory setting
This is a test case for issue https://github.com/moby/moby/issues/35123,
making sure we can set container's memory limit when using
`native.cgroupdriver=systemd`.

[v2: skip if no systemd present]
[v3: add --iptables=false to avoid flaky tests with t.Parallel()]
[v4: rebase after PR#36507 merge]

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 4ca5c5361059e29ed31074ca5b96f8b2030b5f99)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-03-22 13:46:19 +01:00
0520e24302 Merge pull request #473 from seemethere/vbump
[18.03] bump version to 18.03.0-ce
2018-03-21 15:59:46 -07:00
f178926203 Merge pull request #474 from seemethere/bump_change
[18.03] Bump date for 18.03.0-ce GA
2018-03-21 15:59:23 -07:00
e4b87d5a7d Bump date for 18.03.0-ce GA
Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
2018-03-21 18:00:38 +00:00
95930e8794 bump version to 18.03.0-ce
Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
2018-03-21 17:59:46 +00:00
d8bfd4004a Fix AppArmor not being applied to Exec processes
Exec processes do not automatically inherit AppArmor
profiles from the container.

This patch sets the AppArmor profile for the exec
process.

Before this change:

    apparmor_parser -q -r <<EOF
    #include <tunables/global>
    profile deny-write flags=(attach_disconnected) {
      #include <abstractions/base>
      file,
      network,
      deny /tmp/** w,
      capability,
    }
    EOF

    docker run -dit --security-opt "apparmor=deny-write" --name aa busybox

    docker exec aa sh -c 'mkdir /tmp/test'
    (no error)

With this change applied:

    docker exec aa sh -c 'mkdir /tmp/test'
    mkdir: can't create directory '/tmp/test': Permission denied

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 8f3308ae10ec9ad0dd4edfb46fde53a0e1e19b34)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-03-20 10:13:17 +01:00
912261ed44 Fix stats collector spinning CPU if no stats are collected
Commit fd0e24b7189374e0fe7c55b6d26ee916d3ee1655 changed
the stats collection loop to use a `sleep()` instead
of `time.Tick()` in the for-loop.

This change caused a regression in situations where
no stats are being collected, or an error is hit
in the loop (in which case the loop would `continue`,
and the `sleep()` is not hit).

This patch puts the sleep at the start of the loop
to guarantee it's always hit.

This will delay the sampling, which is similar to the
behavior before fd0e24b7189374e0fe7c55b6d26ee916d3ee1655.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 481b8e54b45955e40075f49a9af321afce439320)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-03-19 10:25:58 +01:00
fd1a7dfd47 daemon/stats: more resilient cpu sampling
To avoid noise in sampling CPU usage metrics, we now sample the system
usage closer to the actual response from the underlying runtime. Because
the response from the runtime may be delayed, this makes the sampling
more resilient in loaded conditions. In addition to this, we also
replace the tick with a sleep to avoid situations where ticks can backup
under loaded conditions.

The trade off here is slightly more load reading the system CPU usage
for each container. There may be an optimization required for large
amounts of containers but the cost is on the order of 15 ms per 1000
containers. If this becomes a problem, we can time slot the sampling,
but the complexity may not be worth it unless we can test further.

Unfortunately, there aren't really any good tests for this condition.
Triggering this behavior is highly system dependent. As a matter of
course, we should qualify the fix with the users that are affected.

Signed-off-by: Stephen J Day <stephen.day@docker.com>
(cherry picked from commit fd0e24b7189374e0fe7c55b6d26ee916d3ee1655)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-03-10 00:21:52 +01:00
400 changed files with 9204 additions and 7149 deletions

View File

@ -2,7 +2,19 @@
For more information on the list of deprecated flags and APIs please have a look at
https://docs.docker.com/engine/deprecated/ where you can find the target removal dates
## 18.03.0-ce (2018-03-DD)
## 18.03.1-ce (2018-04-DD)
### Runtime
- Fix AppArmor profiles not being applied to `docker exec` processes [moby/moby#36466](https://github.com/moby/moby/pull/36466)
- Don't sort plugin mount slice [moby/moby#36711](https://github.com/moby/moby/pull/36711)
- Daemon/cluster: handle partial attachment entries during configure [moby/moby#36769](https://github.com/moby/moby/pull/36769)
* Bump Golang to 1.9.5 [moby/moby#36779](https://github.com/moby/moby/pull/36779) [docker/cli#986](https://github.com/docker/cli/pull/986)
- Daemon/stats: more resilient cpu sampling [moby/moby#36519](https://github.com/moby/moby/pull/36519)
* Containerd: update to 1.0.3 release [moby/moby#36749](https://github.com/moby/moby/pull/36749)
- Fix Windows layer leak when write fails [moby/moby#36728](https://github.com/moby/moby/pull/36728)
## 18.03.0-ce (2018-03-21)
### Builder
@ -73,7 +85,6 @@ https://docs.docker.com/engine/deprecated/ where you can find the target removal
* Bump containerd to 1.0.2 (cfd04396dc68220d1cecbe686a6cc3aa5ce3667c) [moby/moby#36308](https://github.com/moby/moby/pull/36308)
* Bump Golang to 1.9.4 [moby/moby#36243](https://github.com/moby/moby/pull/36243)
* Ensure daemon root is unmounted on shutdown [moby/moby#36107](https://github.com/moby/moby/pull/36107)
* Update runc to 6c55f98695e902427906eed2c799e566e3d3dfb5 [moby/moby#36222](https://github.com/moby/moby/pull/36222)
- Fix container cleanup on daemon restart [moby/moby#36249](https://github.com/moby/moby/pull/36249)
* Support SCTP port mapping (bump up API to v1.37) [moby/moby#33922](https://github.com/moby/moby/pull/33922)
* Support SCTP port mapping [docker/cli#278](https://github.com/docker/cli/pull/278)

View File

@ -1 +1 @@
18.03.0-ce-rc4
18.03.1-ce-rc1

View File

@ -1 +1 @@
18.03.0-ce-rc4
18.03.1-ce-rc1

View File

@ -0,0 +1,23 @@
version: "{build}"
clone_folder: c:\gopath\src\github.com\docker\cli
environment:
GOPATH: c:\gopath
GOVERSION: 1.10
DEPVERSION: v0.4.1
install:
- rmdir c:\go /s /q
- appveyor DownloadFile https://storage.googleapis.com/golang/go%GOVERSION%.windows-amd64.msi
- msiexec /i go%GOVERSION%.windows-amd64.msi /q
- go version
- go env
deploy: false
build_script:
- ps: .\scripts\make.ps1 -Binary
test_script:
- ps: .\scripts\make.ps1 -TestUnit

View File

@ -5,7 +5,8 @@ import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func TestLoadFileV01Success(t *testing.T) {
@ -25,9 +26,9 @@ func TestLoadFileV01Success(t *testing.T) {
}`)
bundle, err := LoadFile(reader)
assert.NoError(t, err)
assert.Equal(t, "0.1", bundle.Version)
assert.Len(t, bundle.Services, 2)
assert.NilError(t, err)
assert.Check(t, is.Equal("0.1", bundle.Version))
assert.Check(t, is.Len(bundle.Services, 2))
}
func TestLoadFileSyntaxError(t *testing.T) {
@ -37,7 +38,7 @@ func TestLoadFileSyntaxError(t *testing.T) {
}`)
_, err := LoadFile(reader)
assert.EqualError(t, err, "JSON syntax error at byte 37: invalid character 'u' looking for beginning of value")
assert.Error(t, err, "JSON syntax error at byte 37: invalid character 'u' looking for beginning of value")
}
func TestLoadFileTypeError(t *testing.T) {
@ -52,7 +53,7 @@ func TestLoadFileTypeError(t *testing.T) {
}`)
_, err := LoadFile(reader)
assert.EqualError(t, err, "Unexpected type at byte 94. Expected []string but received string.")
assert.Error(t, err, "Unexpected type at byte 94. Expected []string but received string.")
}
func TestPrint(t *testing.T) {
@ -66,12 +67,12 @@ func TestPrint(t *testing.T) {
},
},
}
assert.NoError(t, Print(&buffer, bundle))
assert.Check(t, Print(&buffer, bundle))
output := buffer.String()
assert.Contains(t, output, "\"Image\": \"image\"")
assert.Contains(t, output,
assert.Check(t, is.Contains(output, "\"Image\": \"image\""))
assert.Check(t, is.Contains(output,
`"Command": [
"echo",
"something"
]`)
]`))
}

View File

@ -6,10 +6,10 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
)
func TestCheckpointCreateErrors(t *testing.T) {
@ -42,7 +42,7 @@ func TestCheckpointCreateErrors(t *testing.T) {
cmd := newCreateCommand(cli)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -63,10 +63,10 @@ func TestCheckpointCreateWithOptions(t *testing.T) {
cmd.SetArgs([]string{"container-foo", checkpoint})
cmd.Flags().Set("leave-running", "true")
cmd.Flags().Set("checkpoint-dir", "/dir/foo")
assert.NoError(t, cmd.Execute())
assert.Equal(t, "container-foo", containerID)
assert.Equal(t, checkpoint, checkpointID)
assert.Equal(t, "/dir/foo", checkpointDir)
assert.Equal(t, false, exit)
assert.Equal(t, checkpoint, strings.TrimSpace(cli.OutBuffer().String()))
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal("container-foo", containerID))
assert.Check(t, is.Equal(checkpoint, checkpointID))
assert.Check(t, is.Equal("/dir/foo", checkpointDir))
assert.Check(t, is.Equal(false, exit))
assert.Check(t, is.Equal(checkpoint, strings.TrimSpace(cli.OutBuffer().String())))
}

View File

@ -5,11 +5,11 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
)
func TestCheckpointListErrors(t *testing.T) {
@ -42,7 +42,7 @@ func TestCheckpointListErrors(t *testing.T) {
cmd := newListCommand(cli)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -60,8 +60,8 @@ func TestCheckpointListWithOptions(t *testing.T) {
cmd := newListCommand(cli)
cmd.SetArgs([]string{"container-foo"})
cmd.Flags().Set("checkpoint-dir", "/dir/foo")
assert.NoError(t, cmd.Execute())
assert.Equal(t, "container-foo", containerID)
assert.Equal(t, "/dir/foo", checkpointDir)
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal("container-foo", containerID))
assert.Check(t, is.Equal("/dir/foo", checkpointDir))
golden.Assert(t, cli.OutBuffer().String(), "checkpoint-list-with-options.golden")
}

View File

@ -5,10 +5,10 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
)
func TestCheckpointRemoveErrors(t *testing.T) {
@ -41,7 +41,7 @@ func TestCheckpointRemoveErrors(t *testing.T) {
cmd := newRemoveCommand(cli)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -58,8 +58,8 @@ func TestCheckpointRemoveWithOptions(t *testing.T) {
cmd := newRemoveCommand(cli)
cmd.SetArgs([]string{"container-foo", "checkpoint-bar"})
cmd.Flags().Set("checkpoint-dir", "/dir/foo")
assert.NoError(t, cmd.Execute())
assert.Equal(t, "container-foo", containerID)
assert.Equal(t, "checkpoint-bar", checkpointID)
assert.Equal(t, "/dir/foo", checkpointDir)
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal("container-foo", containerID))
assert.Check(t, is.Equal("checkpoint-bar", checkpointID))
assert.Check(t, is.Equal("/dir/foo", checkpointDir))
}

View File

@ -22,7 +22,6 @@ import (
"github.com/docker/docker/api/types"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/client"
"github.com/docker/go-connections/sockets"
"github.com/docker/go-connections/tlsconfig"
"github.com/pkg/errors"
"github.com/spf13/cobra"
@ -53,18 +52,20 @@ type Cli interface {
DefaultVersion() string
ManifestStore() manifeststore.Store
RegistryClient(bool) registryclient.RegistryClient
ContentTrustEnabled() bool
}
// DockerCli is an instance the docker command line client.
// Instances of the client can be returned from NewDockerCli.
type DockerCli struct {
configFile *configfile.ConfigFile
in *InStream
out *OutStream
err io.Writer
client client.APIClient
serverInfo ServerInfo
clientInfo ClientInfo
configFile *configfile.ConfigFile
in *InStream
out *OutStream
err io.Writer
client client.APIClient
serverInfo ServerInfo
clientInfo ClientInfo
contentTrust bool
}
// DefaultVersion returns api.defaultVersion or DOCKER_API_VERSION if specified.
@ -122,6 +123,12 @@ func (cli *DockerCli) ClientInfo() ClientInfo {
return cli.clientInfo
}
// ContentTrustEnabled returns whether content trust has been enabled by an
// environment variable.
func (cli *DockerCli) ContentTrustEnabled() bool {
return cli.contentTrust
}
// ManifestStore returns a store for local manifests
func (cli *DockerCli) ManifestStore() manifeststore.Store {
// TODO: support override default location from config file
@ -238,8 +245,8 @@ func (c ClientInfo) HasKubernetes() bool {
}
// NewDockerCli returns a DockerCli instance with IO output and error streams set by in, out and err.
func NewDockerCli(in io.ReadCloser, out, err io.Writer) *DockerCli {
return &DockerCli{in: NewInStream(in), out: NewOutStream(out), err: err}
func NewDockerCli(in io.ReadCloser, out, err io.Writer, isTrusted bool) *DockerCli {
return &DockerCli{in: NewInStream(in), out: NewOutStream(out), err: err, contentTrust: isTrusted}
}
// NewAPIClientFromFlags creates a new APIClient from command line flags
@ -260,12 +267,12 @@ func NewAPIClientFromFlags(opts *cliflags.CommonOptions, configFile *configfile.
verStr = tmpStr
}
httpClient, err := newHTTPClient(host, opts.TLSOptions)
if err != nil {
return &client.Client{}, err
}
return client.NewClient(host, verStr, httpClient, customHeaders)
return client.NewClientWithOpts(
withHTTPClient(opts.TLSOptions),
client.WithHTTPHeaders(customHeaders),
client.WithVersion(verStr),
client.WithHost(host),
)
}
func getServerHost(hosts []string, tlsOptions *tlsconfig.Options) (string, error) {
@ -282,35 +289,32 @@ func getServerHost(hosts []string, tlsOptions *tlsconfig.Options) (string, error
return dopts.ParseHost(tlsOptions != nil, host)
}
func newHTTPClient(host string, tlsOptions *tlsconfig.Options) (*http.Client, error) {
if tlsOptions == nil {
// let the api client configure the default transport.
return nil, nil
}
opts := *tlsOptions
opts.ExclusiveRootPools = true
config, err := tlsconfig.Client(opts)
if err != nil {
return nil, err
}
tr := &http.Transport{
TLSClientConfig: config,
DialContext: (&net.Dialer{
KeepAlive: 30 * time.Second,
Timeout: 30 * time.Second,
}).DialContext,
}
hostURL, err := client.ParseHostURL(host)
if err != nil {
return nil, err
}
func withHTTPClient(tlsOpts *tlsconfig.Options) func(*client.Client) error {
return func(c *client.Client) error {
if tlsOpts == nil {
// Use the default HTTPClient
return nil
}
sockets.ConfigureTransport(tr, hostURL.Scheme, hostURL.Host)
opts := *tlsOpts
opts.ExclusiveRootPools = true
tlsConfig, err := tlsconfig.Client(opts)
if err != nil {
return err
}
return &http.Client{
Transport: tr,
CheckRedirect: client.CheckRedirect,
}, nil
httpClient := &http.Client{
Transport: &http.Transport{
TLSClientConfig: tlsConfig,
DialContext: (&net.Dialer{
KeepAlive: 30 * time.Second,
Timeout: 30 * time.Second,
}).DialContext,
},
CheckRedirect: client.CheckRedirect,
}
return client.WithHTTPClient(httpClient)(c)
}
}
// UserAgent returns the user agent string used for making API requests

View File

@ -3,24 +3,27 @@ package command
import (
"crypto/x509"
"os"
"runtime"
"testing"
cliconfig "github.com/docker/cli/cli/config"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/cli/flags"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/fs"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/net/context"
)
func TestNewAPIClientFromFlags(t *testing.T) {
host := "unix://path"
if runtime.GOOS == "windows" {
host = "npipe://./"
}
opts := &flags.CommonOptions{Hosts: []string{host}}
configFile := &configfile.ConfigFile{
HTTPHeaders: map[string]string{
@ -28,15 +31,15 @@ func TestNewAPIClientFromFlags(t *testing.T) {
},
}
apiclient, err := NewAPIClientFromFlags(opts, configFile)
require.NoError(t, err)
assert.Equal(t, host, apiclient.DaemonHost())
assert.NilError(t, err)
assert.Check(t, is.Equal(host, apiclient.DaemonHost()))
expectedHeaders := map[string]string{
"My-Header": "Custom-Value",
"User-Agent": UserAgent(),
}
assert.Equal(t, expectedHeaders, apiclient.(*client.Client).CustomHTTPHeaders())
assert.Equal(t, api.DefaultVersion, apiclient.ClientVersion())
assert.Check(t, is.DeepEqual(expectedHeaders, apiclient.(*client.Client).CustomHTTPHeaders()))
assert.Check(t, is.Equal(api.DefaultVersion, apiclient.ClientVersion()))
}
func TestNewAPIClientFromFlagsWithAPIVersionFromEnv(t *testing.T) {
@ -46,20 +49,20 @@ func TestNewAPIClientFromFlagsWithAPIVersionFromEnv(t *testing.T) {
opts := &flags.CommonOptions{}
configFile := &configfile.ConfigFile{}
apiclient, err := NewAPIClientFromFlags(opts, configFile)
require.NoError(t, err)
assert.Equal(t, customVersion, apiclient.ClientVersion())
assert.NilError(t, err)
assert.Check(t, is.Equal(customVersion, apiclient.ClientVersion()))
}
// TODO: use gotestyourself/env.Patch
func patchEnvVariable(t *testing.T, key, value string) func() {
oldValue, ok := os.LookupEnv(key)
require.NoError(t, os.Setenv(key, value))
assert.NilError(t, os.Setenv(key, value))
return func() {
if !ok {
require.NoError(t, os.Unsetenv(key))
assert.NilError(t, os.Unsetenv(key))
return
}
require.NoError(t, os.Setenv(key, oldValue))
assert.NilError(t, os.Setenv(key, oldValue))
}
}
@ -125,8 +128,8 @@ func TestInitializeFromClient(t *testing.T) {
cli := &DockerCli{client: apiclient}
cli.initializeFromClient()
assert.Equal(t, testcase.expectedServer, cli.serverInfo)
assert.Equal(t, testcase.negotiated, apiclient.negotiated)
assert.Check(t, is.DeepEqual(testcase.expectedServer, cli.serverInfo))
assert.Check(t, is.Equal(testcase.negotiated, apiclient.negotiated))
})
}
}
@ -164,8 +167,8 @@ func TestExperimentalCLI(t *testing.T) {
cli := &DockerCli{client: apiclient, err: os.Stderr}
cliconfig.SetDir(dir.Path())
err := cli.Initialize(flags.NewClientOptions())
assert.NoError(t, err)
assert.Equal(t, testcase.expectedExperimentalCLI, cli.ClientInfo().HasExperimental)
assert.NilError(t, err)
assert.Check(t, is.Equal(testcase.expectedExperimentalCLI, cli.ClientInfo().HasExperimental))
})
}
}
@ -267,9 +270,9 @@ func TestOrchestratorSwitch(t *testing.T) {
options.Common.Orchestrator = testcase.flagOrchestrator
}
err := cli.Initialize(options)
assert.NoError(t, err)
assert.Equal(t, testcase.expectedKubernetes, cli.ClientInfo().HasKubernetes())
assert.Equal(t, testcase.expectedOrchestrator, string(cli.ClientInfo().Orchestrator))
assert.NilError(t, err)
assert.Check(t, is.Equal(testcase.expectedKubernetes, cli.ClientInfo().HasKubernetes()))
assert.Check(t, is.Equal(testcase.expectedOrchestrator, string(cli.ClientInfo().Orchestrator)))
})
}
}
@ -331,11 +334,11 @@ func TestGetClientWithPassword(t *testing.T) {
_, err := getClientWithPassword(passRetriever, newClient)
if testcase.expectedErr != "" {
testutil.ErrorContains(t, err, testcase.expectedErr)
assert.ErrorContains(t, err, testcase.expectedErr)
return
}
assert.NoError(t, err)
assert.NilError(t, err)
})
}
}

View File

@ -8,12 +8,12 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
)
const configDataFile = "config-create-with-name.golden"
@ -47,7 +47,7 @@ func TestConfigCreateErrors(t *testing.T) {
)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -70,9 +70,9 @@ func TestConfigCreateWithName(t *testing.T) {
cmd := newConfigCreateCommand(cli)
cmd.SetArgs([]string{name, filepath.Join("testdata", configDataFile)})
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, string(actual), configDataFile)
assert.Equal(t, "ID-"+name, strings.TrimSpace(cli.OutBuffer().String()))
assert.Check(t, is.Equal("ID-"+name, strings.TrimSpace(cli.OutBuffer().String())))
}
func TestConfigCreateWithLabels(t *testing.T) {
@ -83,7 +83,7 @@ func TestConfigCreateWithLabels(t *testing.T) {
name := "foo"
data, err := ioutil.ReadFile(filepath.Join("testdata", configDataFile))
assert.NoError(t, err)
assert.NilError(t, err)
expected := swarm.ConfigSpec{
Annotations: swarm.Annotations{
@ -109,8 +109,8 @@ func TestConfigCreateWithLabels(t *testing.T) {
cmd.SetArgs([]string{name, filepath.Join("testdata", configDataFile)})
cmd.Flags().Set("label", "lbl1=Label-foo")
cmd.Flags().Set("label", "lbl2=Label-bar")
assert.NoError(t, cmd.Execute())
assert.Equal(t, "ID-"+name, strings.TrimSpace(cli.OutBuffer().String()))
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal("ID-"+name, strings.TrimSpace(cli.OutBuffer().String())))
}
func TestConfigCreateWithTemplatingDriver(t *testing.T) {
@ -138,6 +138,6 @@ func TestConfigCreateWithTemplatingDriver(t *testing.T) {
cmd := newConfigCreateCommand(cli)
cmd.SetArgs([]string{name, filepath.Join("testdata", configDataFile)})
cmd.Flags().Set("template-driver", expectedDriver.Name)
assert.NoError(t, cmd.Execute())
assert.Equal(t, "ID-"+name, strings.TrimSpace(cli.OutBuffer().String()))
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal("ID-"+name, strings.TrimSpace(cli.OutBuffer().String())))
}

View File

@ -11,9 +11,8 @@ import (
"github.com/pkg/errors"
// Import builders to get the builder function as package function
. "github.com/docker/cli/internal/test/builders"
"github.com/docker/cli/internal/test/testutil"
"github.com/gotestyourself/gotestyourself/assert"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/stretchr/testify/assert"
)
func TestConfigInspectErrors(t *testing.T) {
@ -62,7 +61,7 @@ func TestConfigInspectErrors(t *testing.T) {
cmd.Flags().Set(key, value)
}
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -96,7 +95,7 @@ func TestConfigInspectWithoutFormat(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{configInspectFunc: tc.configInspectFunc})
cmd := newConfigInspectCommand(cli)
cmd.SetArgs(tc.args)
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("config-inspect-without-format.%s.golden", tc.name))
}
}
@ -133,7 +132,7 @@ func TestConfigInspectWithFormat(t *testing.T) {
cmd := newConfigInspectCommand(cli)
cmd.SetArgs(tc.args)
cmd.Flags().Set("format", tc.format)
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("config-inspect-with-format.%s.golden", tc.name))
}
}
@ -167,7 +166,7 @@ func TestConfigInspectPretty(t *testing.T) {
cmd.SetArgs([]string{"configID"})
cmd.Flags().Set("pretty", "true")
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("config-inspect-pretty.%s.golden", tc.name))
}
}

View File

@ -12,9 +12,9 @@ import (
"github.com/pkg/errors"
// Import builders to get the builder function as package function
. "github.com/docker/cli/internal/test/builders"
"github.com/docker/cli/internal/test/testutil"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/stretchr/testify/assert"
)
func TestConfigListErrors(t *testing.T) {
@ -42,7 +42,7 @@ func TestConfigListErrors(t *testing.T) {
)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -72,7 +72,7 @@ func TestConfigList(t *testing.T) {
},
})
cmd := newConfigListCommand(cli)
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "config-list-sort.golden")
}
@ -89,7 +89,7 @@ func TestConfigListWithQuietOption(t *testing.T) {
})
cmd := newConfigListCommand(cli)
cmd.Flags().Set("quiet", "true")
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "config-list-with-quiet-option.golden")
}
@ -108,7 +108,7 @@ func TestConfigListWithConfigFormat(t *testing.T) {
ConfigFormat: "{{ .Name }} {{ .Labels }}",
})
cmd := newConfigListCommand(cli)
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "config-list-with-config-format.golden")
}
@ -125,15 +125,15 @@ func TestConfigListWithFormat(t *testing.T) {
})
cmd := newConfigListCommand(cli)
cmd.Flags().Set("format", "{{ .Name }} {{ .Labels }}")
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "config-list-with-format.golden")
}
func TestConfigListWithFilter(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
configListFunc: func(options types.ConfigListOptions) ([]swarm.Config, error) {
assert.Equal(t, "foo", options.Filters.Get("name")[0])
assert.Equal(t, "lbl1=Label-bar", options.Filters.Get("label")[0])
assert.Check(t, is.Equal("foo", options.Filters.Get("name")[0]))
assert.Check(t, is.Equal("lbl1=Label-bar", options.Filters.Get("label")[0]))
return []swarm.Config{
*Config(ConfigID("ID-foo"),
ConfigName("foo"),
@ -153,6 +153,6 @@ func TestConfigListWithFilter(t *testing.T) {
cmd := newConfigListCommand(cli)
cmd.Flags().Set("filter", "name=foo")
cmd.Flags().Set("filter", "label=lbl1=Label-bar")
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "config-list-with-filter.golden")
}

View File

@ -6,9 +6,9 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
)
func TestConfigRemoveErrors(t *testing.T) {
@ -37,7 +37,7 @@ func TestConfigRemoveErrors(t *testing.T) {
)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -52,9 +52,9 @@ func TestConfigRemoveWithName(t *testing.T) {
})
cmd := newConfigRemoveCommand(cli)
cmd.SetArgs(names)
assert.NoError(t, cmd.Execute())
assert.Equal(t, names, strings.Split(strings.TrimSpace(cli.OutBuffer().String()), "\n"))
assert.Equal(t, names, removedConfigs)
assert.NilError(t, cmd.Execute())
assert.Check(t, is.DeepEqual(names, strings.Split(strings.TrimSpace(cli.OutBuffer().String()), "\n")))
assert.Check(t, is.DeepEqual(names, removedConfigs))
}
func TestConfigRemoveContinueAfterError(t *testing.T) {
@ -74,6 +74,6 @@ func TestConfigRemoveContinueAfterError(t *testing.T) {
cmd := newConfigRemoveCommand(cli)
cmd.SetArgs(names)
cmd.SetOutput(ioutil.Discard)
assert.EqualError(t, cmd.Execute(), "error removing config: foo")
assert.Equal(t, names, removedConfigs)
assert.Error(t, cmd.Execute(), "error removing config: foo")
assert.Check(t, is.DeepEqual(names, removedConfigs))
}

View File

@ -7,11 +7,10 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/gotestyourself/gotestyourself/assert"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
)
func TestNewAttachCommandErrors(t *testing.T) {
@ -74,7 +73,7 @@ func TestNewAttachCommandErrors(t *testing.T) {
cmd := NewAttachCommand(test.NewFakeCli(&fakeClient{inspectFunc: tc.containerInspectFunc}))
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -101,9 +100,7 @@ func TestGetExitStatus(t *testing.T) {
},
{
result: &container.ContainerWaitOKBody{
Error: &container.ContainerWaitOKBodyError{
expectedErr.Error(),
},
Error: &container.ContainerWaitOKBodyError{expectedErr.Error()},
},
expectedError: expectedErr,
},
@ -123,6 +120,10 @@ func TestGetExitStatus(t *testing.T) {
resultC <- *testcase.result
}
err := getExitStatus(errC, resultC)
assert.Equal(t, testcase.expectedError, err)
if testcase.expectedError == nil {
assert.NilError(t, err)
} else {
assert.Error(t, err, testcase.expectedError.Error())
}
}
}

View File

@ -9,13 +9,12 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/archive"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/fs"
"github.com/gotestyourself/gotestyourself/skip"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestRunCopyWithInvalidArguments(t *testing.T) {
@ -44,7 +43,7 @@ func TestRunCopyWithInvalidArguments(t *testing.T) {
for _, testcase := range testcases {
t.Run(testcase.doc, func(t *testing.T) {
err := runCopy(test.NewFakeCli(nil), testcase.options)
assert.EqualError(t, err, testcase.expectedErr)
assert.Error(t, err, testcase.expectedErr)
})
}
}
@ -54,16 +53,16 @@ func TestRunCopyFromContainerToStdout(t *testing.T) {
fakeClient := &fakeClient{
containerCopyFromFunc: func(container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) {
assert.Equal(t, "container", container)
assert.Check(t, is.Equal("container", container))
return ioutil.NopCloser(strings.NewReader(tarContent)), types.ContainerPathStat{}, nil
},
}
options := copyOptions{source: "container:/path", destination: "-"}
cli := test.NewFakeCli(fakeClient)
err := runCopy(cli, options)
require.NoError(t, err)
assert.Equal(t, tarContent, cli.OutBuffer().String())
assert.Equal(t, "", cli.ErrBuffer().String())
assert.NilError(t, err)
assert.Check(t, is.Equal(tarContent, cli.OutBuffer().String()))
assert.Check(t, is.Equal("", cli.ErrBuffer().String()))
}
func TestRunCopyFromContainerToFilesystem(t *testing.T) {
@ -73,7 +72,7 @@ func TestRunCopyFromContainerToFilesystem(t *testing.T) {
fakeClient := &fakeClient{
containerCopyFromFunc: func(container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) {
assert.Equal(t, "container", container)
assert.Check(t, is.Equal("container", container))
readCloser, err := archive.TarWithOptions(destDir.Path(), &archive.TarOptions{})
return readCloser, types.ContainerPathStat{}, err
},
@ -81,13 +80,13 @@ func TestRunCopyFromContainerToFilesystem(t *testing.T) {
options := copyOptions{source: "container:/path", destination: destDir.Path()}
cli := test.NewFakeCli(fakeClient)
err := runCopy(cli, options)
require.NoError(t, err)
assert.Equal(t, "", cli.OutBuffer().String())
assert.Equal(t, "", cli.ErrBuffer().String())
assert.NilError(t, err)
assert.Check(t, is.Equal("", cli.OutBuffer().String()))
assert.Check(t, is.Equal("", cli.ErrBuffer().String()))
content, err := ioutil.ReadFile(destDir.Join("file1"))
require.NoError(t, err)
assert.Equal(t, "content\n", string(content))
assert.NilError(t, err)
assert.Check(t, is.Equal("content\n", string(content)))
}
func TestRunCopyFromContainerToFilesystemMissingDestinationDirectory(t *testing.T) {
@ -97,7 +96,7 @@ func TestRunCopyFromContainerToFilesystemMissingDestinationDirectory(t *testing.
fakeClient := &fakeClient{
containerCopyFromFunc: func(container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) {
assert.Equal(t, "container", container)
assert.Check(t, is.Equal("container", container))
readCloser, err := archive.TarWithOptions(destDir.Path(), &archive.TarOptions{})
return readCloser, types.ContainerPathStat{}, err
},
@ -109,7 +108,7 @@ func TestRunCopyFromContainerToFilesystemMissingDestinationDirectory(t *testing.
}
cli := test.NewFakeCli(fakeClient)
err := runCopy(cli, options)
testutil.ErrorContains(t, err, destDir.Join("missing"))
assert.ErrorContains(t, err, destDir.Join("missing"))
}
func TestRunCopyToContainerFromFileWithTrailingSlash(t *testing.T) {
@ -122,7 +121,12 @@ func TestRunCopyToContainerFromFileWithTrailingSlash(t *testing.T) {
}
cli := test.NewFakeCli(&fakeClient{})
err := runCopy(cli, options)
testutil.ErrorContains(t, err, "not a directory")
expectedError := "not a directory"
if runtime.GOOS == "windows" {
expectedError = "The filename, directory name, or volume label syntax is incorrect"
}
assert.ErrorContains(t, err, expectedError)
}
func TestRunCopyToContainerSourceDoesNotExist(t *testing.T) {
@ -136,7 +140,7 @@ func TestRunCopyToContainerSourceDoesNotExist(t *testing.T) {
if runtime.GOOS == "windows" {
expected = "cannot find the file specified"
}
testutil.ErrorContains(t, err, expected)
assert.ErrorContains(t, err, expected)
}
func TestSplitCpArg(t *testing.T) {
@ -181,8 +185,8 @@ func TestSplitCpArg(t *testing.T) {
skip.IfCondition(t, testcase.os != "" && testcase.os != runtime.GOOS)
container, path := splitCpArg(testcase.path)
assert.Equal(t, testcase.expectedContainer, container)
assert.Equal(t, testcase.expectedPath, path)
assert.Check(t, is.Equal(testcase.expectedContainer, container))
assert.Check(t, is.Equal(testcase.expectedPath, path))
})
}
}

View File

@ -21,8 +21,9 @@ import (
)
type createOptions struct {
name string
platform string
name string
platform string
untrusted bool
}
// NewCreateCommand creates a new cobra.Command for `docker create`
@ -53,7 +54,7 @@ func NewCreateCommand(dockerCli command.Cli) *cobra.Command {
flags.Bool("help", false, "Print usage")
command.AddPlatformFlag(flags, &opts.platform)
command.AddTrustVerificationFlags(flags)
command.AddTrustVerificationFlags(flags, &opts.untrusted, dockerCli.ContentTrustEnabled())
copts = addFlags(flags)
return cmd
}
@ -64,7 +65,7 @@ func runCreate(dockerCli command.Cli, flags *pflag.FlagSet, opts *createOptions,
reportError(dockerCli.Err(), "create", err.Error(), true)
return cli.StatusError{StatusCode: 125}
}
response, err := createContainer(context.Background(), dockerCli, containerConfig, opts.name, opts.platform)
response, err := createContainer(context.Background(), dockerCli, containerConfig, opts)
if err != nil {
return err
}
@ -158,7 +159,7 @@ func newCIDFile(path string) (*cidFile, error) {
return &cidFile{path: path, file: f}, nil
}
func createContainer(ctx context.Context, dockerCli command.Cli, containerConfig *containerConfig, name string, platform string) (*container.ContainerCreateCreatedBody, error) {
func createContainer(ctx context.Context, dockerCli command.Cli, containerConfig *containerConfig, opts *createOptions) (*container.ContainerCreateCreatedBody, error) {
config := containerConfig.Config
hostConfig := containerConfig.HostConfig
networkingConfig := containerConfig.NetworkingConfig
@ -182,7 +183,7 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerConfig
if named, ok := ref.(reference.Named); ok {
namedRef = reference.TagNameOnly(named)
if taggedRef, ok := namedRef.(reference.NamedTagged); ok && command.IsTrusted() {
if taggedRef, ok := namedRef.(reference.NamedTagged); ok && !opts.untrusted {
var err error
trustedRef, err = image.TrustedReference(ctx, dockerCli, taggedRef, nil)
if err != nil {
@ -193,7 +194,7 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerConfig
}
//create the container
response, err := dockerCli.Client().ContainerCreate(ctx, config, hostConfig, networkingConfig, name)
response, err := dockerCli.Client().ContainerCreate(ctx, config, hostConfig, networkingConfig, opts.name)
//if image not found try to pull it
if err != nil {
@ -201,7 +202,7 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerConfig
fmt.Fprintf(stderr, "Unable to find image '%s' locally\n", reference.FamiliarString(namedRef))
// we don't want to write to stdout anything apart from container.ID
if err := pullImage(ctx, dockerCli, config.Image, platform, stderr); err != nil {
if err := pullImage(ctx, dockerCli, config.Image, opts.platform, stderr); err != nil {
return nil, err
}
if taggedRef, ok := namedRef.(reference.NamedTagged); ok && trustedRef != nil {
@ -211,7 +212,7 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerConfig
}
// Retry
var retryErr error
response, retryErr = dockerCli.Client().ContainerCreate(ctx, config, hostConfig, networkingConfig, name)
response, retryErr = dockerCli.Client().ContainerCreate(ctx, config, hostConfig, networkingConfig, opts.name)
if retryErr != nil {
return nil, retryErr
}

View File

@ -2,6 +2,7 @@ package container
import (
"context"
"fmt"
"io"
"io/ioutil"
"os"
@ -10,23 +11,24 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/cli/internal/test/notary"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/google/go-cmp/cmp"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/fs"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestCIDFileNoOPWithNoFilename(t *testing.T) {
file, err := newCIDFile("")
require.NoError(t, err)
assert.Equal(t, &cidFile{}, file)
assert.NilError(t, err)
assert.DeepEqual(t, &cidFile{}, file, cmp.AllowUnexported(cidFile{}))
assert.NoError(t, file.Write("id"))
assert.NoError(t, file.Close())
assert.NilError(t, file.Write("id"))
assert.NilError(t, file.Close())
}
func TestNewCIDFileWhenFileAlreadyExists(t *testing.T) {
@ -34,7 +36,7 @@ func TestNewCIDFileWhenFileAlreadyExists(t *testing.T) {
defer tempfile.Remove()
_, err := newCIDFile(tempfile.Path())
testutil.ErrorContains(t, err, "Container ID file found")
assert.ErrorContains(t, err, "Container ID file found")
}
func TestCIDFileCloseWithNoWrite(t *testing.T) {
@ -43,12 +45,12 @@ func TestCIDFileCloseWithNoWrite(t *testing.T) {
path := tempdir.Join("cidfile")
file, err := newCIDFile(path)
require.NoError(t, err)
assert.Equal(t, file.path, path)
assert.NilError(t, err)
assert.Check(t, is.Equal(file.path, path))
assert.NoError(t, file.Close())
assert.NilError(t, file.Close())
_, err = os.Stat(path)
assert.True(t, os.IsNotExist(err))
assert.Check(t, os.IsNotExist(err))
}
func TestCIDFileCloseWithWrite(t *testing.T) {
@ -57,18 +59,18 @@ func TestCIDFileCloseWithWrite(t *testing.T) {
path := tempdir.Join("cidfile")
file, err := newCIDFile(path)
require.NoError(t, err)
assert.NilError(t, err)
content := "id"
assert.NoError(t, file.Write(content))
assert.NilError(t, file.Write(content))
actual, err := ioutil.ReadFile(path)
require.NoError(t, err)
assert.Equal(t, content, string(actual))
assert.NilError(t, err)
assert.Check(t, is.Equal(content, string(actual)))
assert.NoError(t, file.Close())
assert.NilError(t, file.Close())
_, err = os.Stat(path)
require.NoError(t, err)
assert.NilError(t, err)
}
func TestCreateContainerPullsImageIfMissing(t *testing.T) {
@ -107,12 +109,61 @@ func TestCreateContainerPullsImageIfMissing(t *testing.T) {
},
HostConfig: &container.HostConfig{},
}
body, err := createContainer(context.Background(), cli, config, "name", runtime.GOOS)
require.NoError(t, err)
body, err := createContainer(context.Background(), cli, config, &createOptions{
name: "name",
platform: runtime.GOOS,
untrusted: true,
})
assert.NilError(t, err)
expected := container.ContainerCreateCreatedBody{ID: containerID}
assert.Equal(t, expected, *body)
assert.Check(t, is.DeepEqual(expected, *body))
stderr := cli.ErrBuffer().String()
assert.Contains(t, stderr, "Unable to find image 'does-not-exist-locally:latest' locally")
assert.Check(t, is.Contains(stderr, "Unable to find image 'does-not-exist-locally:latest' locally"))
}
func TestNewCreateCommandWithContentTrustErrors(t *testing.T) {
testCases := []struct {
name string
args []string
expectedError string
notaryFunc test.NotaryClientFuncType
}{
{
name: "offline-notary-server",
notaryFunc: notary.GetOfflineNotaryRepository,
expectedError: "client is offline",
args: []string{"image:tag"},
},
{
name: "uninitialized-notary-server",
notaryFunc: notary.GetUninitializedNotaryRepository,
expectedError: "remote trust data does not exist",
args: []string{"image:tag"},
},
{
name: "empty-notary-server",
notaryFunc: notary.GetEmptyTargetsNotaryRepository,
expectedError: "No valid trust data for tag",
args: []string{"image:tag"},
},
}
for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{
createContainerFunc: func(config *container.Config,
hostConfig *container.HostConfig,
networkingConfig *network.NetworkingConfig,
containerName string,
) (container.ContainerCreateCreatedBody, error) {
return container.ContainerCreateCreatedBody{}, fmt.Errorf("shouldn't try to pull image")
},
}, test.EnableContentTrust)
cli.SetNotaryClient(tc.notaryFunc)
cmd := NewCreateCommand(cli)
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
err := cmd.Execute()
assert.ErrorContains(t, err, tc.expectedError)
}
}
type fakeNotFound struct{}

View File

@ -7,11 +7,11 @@ import (
"github.com/docker/cli/cli"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/cli/opts"
"github.com/docker/docker/api/types"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"golang.org/x/net/context"
)
@ -106,7 +106,7 @@ func TestParseExec(t *testing.T) {
for _, testcase := range testcases {
execConfig := parseExec(testcase.options, &testcase.configFile)
assert.Equal(t, testcase.expected, *execConfig)
assert.Check(t, is.DeepEqual(testcase.expected, *execConfig))
}
}
@ -150,14 +150,14 @@ func TestRunExec(t *testing.T) {
err := runExec(cli, testcase.options)
if testcase.expectedError != "" {
testutil.ErrorContains(t, err, testcase.expectedError)
assert.ErrorContains(t, err, testcase.expectedError)
} else {
if !assert.NoError(t, err) {
if !assert.Check(t, err) {
return
}
}
assert.Equal(t, testcase.expectedOut, cli.OutBuffer().String())
assert.Equal(t, testcase.expectedErr, cli.ErrBuffer().String())
assert.Check(t, is.Equal(testcase.expectedOut, cli.OutBuffer().String()))
assert.Check(t, is.Equal(testcase.expectedErr, cli.ErrBuffer().String()))
})
}
}
@ -192,12 +192,12 @@ func TestGetExecExitStatus(t *testing.T) {
for _, testcase := range testcases {
client := &fakeClient{
execInspectFunc: func(id string) (types.ContainerExecInspect, error) {
assert.Equal(t, execID, id)
assert.Check(t, is.Equal(execID, id))
return types.ContainerExecInspect{ExitCode: testcase.exitCode}, testcase.inspectError
},
}
err := getExecExitStatus(context.Background(), client, execID)
assert.Equal(t, testcase.expectedError, err)
assert.Check(t, is.Equal(testcase.expectedError, err))
}
}
@ -222,6 +222,6 @@ func TestNewExecCommandErrors(t *testing.T) {
cmd := NewExecCommand(cli)
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}

View File

@ -7,11 +7,10 @@ import (
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/stretchr/testify/assert"
// Import builders to get the builder function as package function
. "github.com/docker/cli/internal/test/builders"
"github.com/gotestyourself/gotestyourself/assert"
"github.com/gotestyourself/gotestyourself/golden"
)
@ -52,7 +51,7 @@ func TestContainerListErrors(t *testing.T) {
cmd.Flags().Set(key, value)
}
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -69,7 +68,7 @@ func TestContainerListWithoutFormat(t *testing.T) {
},
})
cmd := newListCommand(cli)
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "container-list-without-format.golden")
}
@ -84,7 +83,7 @@ func TestContainerListNoTrunc(t *testing.T) {
})
cmd := newListCommand(cli)
cmd.Flags().Set("no-trunc", "true")
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "container-list-without-format-no-trunc.golden")
}
@ -100,7 +99,7 @@ func TestContainerListNamesMultipleTime(t *testing.T) {
})
cmd := newListCommand(cli)
cmd.Flags().Set("format", "{{.Names}} {{.Names}}")
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "container-list-format-name-name.golden")
}
@ -116,20 +115,20 @@ func TestContainerListFormatTemplateWithArg(t *testing.T) {
})
cmd := newListCommand(cli)
cmd.Flags().Set("format", `{{.Names}} {{.Label "some.label"}}`)
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "container-list-format-with-arg.golden")
}
func TestContainerListFormatSizeSetsOption(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
containerListFunc: func(options types.ContainerListOptions) ([]types.Container, error) {
assert.True(t, options.Size)
assert.Check(t, options.Size)
return []types.Container{}, nil
},
})
cmd := newListCommand(cli)
cmd.Flags().Set("format", `{{.Size}}`)
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
}
func TestContainerListWithConfigFormat(t *testing.T) {
@ -145,7 +144,7 @@ func TestContainerListWithConfigFormat(t *testing.T) {
PsFormat: "{{ .Names }} {{ .Image }} {{ .Labels }}",
})
cmd := newListCommand(cli)
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "container-list-with-config-format.golden")
}
@ -160,6 +159,6 @@ func TestContainerListWithFormat(t *testing.T) {
})
cmd := newListCommand(cli)
cmd.Flags().Set("format", "{{ .Names }} {{ .Image }} {{ .Labels }}")
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "container-list-with-format.golden")
}

View File

@ -7,10 +7,10 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
var logFn = func(expectedOut string) func(string, types.ContainerLogsOptions) (io.ReadCloser, error) {
@ -49,14 +49,14 @@ func TestRunLogs(t *testing.T) {
err := runLogs(cli, testcase.options)
if testcase.expectedError != "" {
testutil.ErrorContains(t, err, testcase.expectedError)
assert.ErrorContains(t, err, testcase.expectedError)
} else {
if !assert.NoError(t, err) {
if !assert.Check(t, err) {
return
}
}
assert.Equal(t, testcase.expectedOut, cli.OutBuffer().String())
assert.Equal(t, testcase.expectedErr, cli.ErrBuffer().String())
assert.Check(t, is.Equal(testcase.expectedOut, cli.OutBuffer().String()))
assert.Check(t, is.Equal(testcase.expectedErr, cli.ErrBuffer().String()))
})
}
}

View File

@ -9,14 +9,13 @@ import (
"testing"
"time"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types/container"
networktypes "github.com/docker/docker/api/types/network"
"github.com/docker/go-connections/nat"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/pkg/errors"
"github.com/spf13/pflag"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestValidateAttach(t *testing.T) {
@ -67,12 +66,12 @@ func setupRunFlags() (*pflag.FlagSet, *containerOptions) {
func parseMustError(t *testing.T, args string) {
_, _, _, err := parseRun(strings.Split(args+" ubuntu bash", " "))
assert.Error(t, err, args)
assert.ErrorContains(t, err, "", args)
}
func mustParse(t *testing.T, args string) (*container.Config, *container.HostConfig) {
config, hostConfig, _, err := parseRun(append(strings.Split(args, " "), "ubuntu", "bash"))
assert.NoError(t, err)
assert.NilError(t, err)
return config, hostConfig
}
@ -236,23 +235,23 @@ func TestRunFlagsParseWithMemory(t *testing.T) {
flags, _ := setupRunFlags()
args := []string{"--memory=invalid", "img", "cmd"}
err := flags.Parse(args)
testutil.ErrorContains(t, err, `invalid argument "invalid" for "-m, --memory" flag`)
assert.ErrorContains(t, err, `invalid argument "invalid" for "-m, --memory" flag`)
_, hostconfig := mustParse(t, "--memory=1G")
assert.Equal(t, int64(1073741824), hostconfig.Memory)
assert.Check(t, is.Equal(int64(1073741824), hostconfig.Memory))
}
func TestParseWithMemorySwap(t *testing.T) {
flags, _ := setupRunFlags()
args := []string{"--memory-swap=invalid", "img", "cmd"}
err := flags.Parse(args)
testutil.ErrorContains(t, err, `invalid argument "invalid" for "--memory-swap" flag`)
assert.ErrorContains(t, err, `invalid argument "invalid" for "--memory-swap" flag`)
_, hostconfig := mustParse(t, "--memory-swap=1G")
assert.Equal(t, int64(1073741824), hostconfig.MemorySwap)
assert.Check(t, is.Equal(int64(1073741824), hostconfig.MemorySwap))
_, hostconfig = mustParse(t, "--memory-swap=-1")
assert.Equal(t, int64(-1), hostconfig.MemorySwap)
assert.Check(t, is.Equal(int64(-1), hostconfig.MemorySwap))
}
func TestParseHostname(t *testing.T) {
@ -373,24 +372,24 @@ func TestParseModes(t *testing.T) {
// pid ko
flags, copts := setupRunFlags()
args := []string{"--pid=container:", "img", "cmd"}
require.NoError(t, flags.Parse(args))
assert.NilError(t, flags.Parse(args))
_, err := parse(flags, copts)
testutil.ErrorContains(t, err, "--pid: invalid PID mode")
assert.ErrorContains(t, err, "--pid: invalid PID mode")
// pid ok
_, hostconfig, _, err := parseRun([]string{"--pid=host", "img", "cmd"})
require.NoError(t, err)
assert.NilError(t, err)
if !hostconfig.PidMode.Valid() {
t.Fatalf("Expected a valid PidMode, got %v", hostconfig.PidMode)
}
// uts ko
_, _, _, err = parseRun([]string{"--uts=container:", "img", "cmd"})
testutil.ErrorContains(t, err, "--uts: invalid UTS mode")
assert.ErrorContains(t, err, "--uts: invalid UTS mode")
// uts ok
_, hostconfig, _, err = parseRun([]string{"--uts=host", "img", "cmd"})
require.NoError(t, err)
assert.NilError(t, err)
if !hostconfig.UTSMode.Valid() {
t.Fatalf("Expected a valid UTSMode, got %v", hostconfig.UTSMode)
}
@ -402,11 +401,11 @@ func TestRunFlagsParseShmSize(t *testing.T) {
args := []string{"--shm-size=a128m", "img", "cmd"}
expectedErr := `invalid argument "a128m" for "--shm-size" flag: invalid size: 'a128m'`
err := flags.Parse(args)
testutil.ErrorContains(t, err, expectedErr)
assert.ErrorContains(t, err, expectedErr)
// shm-size ok
_, hostconfig, _, err := parseRun([]string{"--shm-size=128m", "img", "cmd"})
require.NoError(t, err)
assert.NilError(t, err)
if hostconfig.ShmSize != 134217728 {
t.Fatalf("Expected a valid ShmSize, got %d", hostconfig.ShmSize)
}

View File

@ -4,13 +4,14 @@ import (
"testing"
"github.com/docker/cli/opts"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func TestBuildContainerListOptions(t *testing.T) {
filters := opts.NewFilterOpt()
assert.NoError(t, filters.Set("foo=bar"))
assert.NoError(t, filters.Set("baz=foo"))
assert.NilError(t, filters.Set("foo=bar"))
assert.NilError(t, filters.Set("baz=foo"))
contexts := []struct {
psOpts *psOptions
@ -101,12 +102,12 @@ func TestBuildContainerListOptions(t *testing.T) {
for _, c := range contexts {
options, err := buildContainerListOptions(c.psOpts)
assert.NoError(t, err)
assert.NilError(t, err)
assert.Equal(t, c.expectedAll, options.All)
assert.Equal(t, c.expectedSize, options.Size)
assert.Equal(t, c.expectedLimit, options.Limit)
assert.Equal(t, len(c.expectedFilters), options.Filters.Len())
assert.Check(t, is.Equal(c.expectedAll, options.All))
assert.Check(t, is.Equal(c.expectedSize, options.Size))
assert.Check(t, is.Equal(c.expectedLimit, options.Limit))
assert.Check(t, is.Equal(len(c.expectedFilters), options.Filters.Len()))
for k, v := range c.expectedFilters {
f := options.Filters

View File

@ -25,11 +25,10 @@ import (
)
type runOptions struct {
createOptions
detach bool
sigProxy bool
name string
detachKeys string
platform string
}
// NewRunCommand create a new `docker run` command
@ -64,7 +63,7 @@ func NewRunCommand(dockerCli command.Cli) *cobra.Command {
flags.Bool("help", false, "Print usage")
command.AddPlatformFlag(flags, &opts.platform)
command.AddTrustVerificationFlags(flags)
command.AddTrustVerificationFlags(flags, &opts.untrusted, dockerCli.ContentTrustEnabled())
copts = addFlags(flags)
return cmd
}
@ -162,7 +161,7 @@ func runContainer(dockerCli command.Cli, opts *runOptions, copts *containerOptio
ctx, cancelFun := context.WithCancel(context.Background())
createResponse, err := createContainer(ctx, dockerCli, containerConfig, opts.name, opts.platform)
createResponse, err := createContainer(ctx, dockerCli, containerConfig, &opts.createOptions)
if err != nil {
reportError(stderr, cmdPath, err.Error(), true)
return runStartContainerErr(err)

View File

@ -1,12 +1,15 @@
package container
import (
"fmt"
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/notary"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func TestRunLabel(t *testing.T) {
@ -21,5 +24,50 @@ func TestRunLabel(t *testing.T) {
cmd := NewRunCommand(cli)
cmd.Flags().Set("detach", "true")
cmd.SetArgs([]string{"--label", "foo", "busybox"})
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
}
func TestRunCommandWithContentTrustErrors(t *testing.T) {
testCases := []struct {
name string
args []string
expectedError string
notaryFunc test.NotaryClientFuncType
}{
{
name: "offline-notary-server",
notaryFunc: notary.GetOfflineNotaryRepository,
expectedError: "client is offline",
args: []string{"image:tag"},
},
{
name: "uninitialized-notary-server",
notaryFunc: notary.GetUninitializedNotaryRepository,
expectedError: "remote trust data does not exist",
args: []string{"image:tag"},
},
{
name: "empty-notary-server",
notaryFunc: notary.GetEmptyTargetsNotaryRepository,
expectedError: "No valid trust data for tag",
args: []string{"image:tag"},
},
}
for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{
createContainerFunc: func(config *container.Config,
hostConfig *container.HostConfig,
networkingConfig *network.NetworkingConfig,
containerName string,
) (container.ContainerCreateCreatedBody, error) {
return container.ContainerCreateCreatedBody{}, fmt.Errorf("shouldn't try to pull image")
},
}, test.EnableContentTrust)
cli.SetNotaryClient(tc.notaryFunc)
cmd := NewRunCommand(cli)
cmd.SetArgs(tc.args)
err := cmd.Execute()
assert.Assert(t, err != nil)
assert.Assert(t, is.Contains(cli.ErrBuffer().String(), tc.expectedError))
}
}

View File

@ -1,10 +1,11 @@
package container
import (
"fmt"
"testing"
"github.com/docker/docker/api/types"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
)
func TestCalculateMemUsageUnixNoCache(t *testing.T) {
@ -15,7 +16,7 @@ func TestCalculateMemUsageUnixNoCache(t *testing.T) {
result := calculateMemUsageUnixNoCache(stats)
// Then
assert.InDelta(t, 100.0, result, 1e-6)
assert.Assert(t, inDelta(100.0, result, 1e-6))
}
func TestCalculateMemPercentUnixNoCache(t *testing.T) {
@ -27,10 +28,20 @@ func TestCalculateMemPercentUnixNoCache(t *testing.T) {
// When and Then
t.Run("Limit is set", func(t *testing.T) {
result := calculateMemPercentUnixNoCache(someLimit, used)
assert.InDelta(t, 70.0, result, 1e-6)
assert.Assert(t, inDelta(70.0, result, 1e-6))
})
t.Run("No limit, no cgroup data", func(t *testing.T) {
result := calculateMemPercentUnixNoCache(noLimit, used)
assert.InDelta(t, 0.0, result, 1e-6)
assert.Assert(t, inDelta(0.0, result, 1e-6))
})
}
func inDelta(x, y, delta float64) func() (bool, string) {
return func() (bool, string) {
diff := x - y
if diff < -delta || diff > delta {
return false, fmt.Sprintf("%f != %f within %f", x, y, delta)
}
return true, ""
}
}

View File

@ -7,8 +7,9 @@ import (
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api"
"github.com/docker/docker/api/types/container"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"golang.org/x/net/context"
)
@ -64,6 +65,6 @@ func TestWaitExitOrRemoved(t *testing.T) {
for _, testcase := range testcases {
statusC := waitExitOrRemoved(context.Background(), client, testcase.cid, true)
exitCode := <-statusC
assert.Equal(t, testcase.exitCode, exitCode)
assert.Check(t, is.Equal(testcase.exitCode, exitCode))
}
}

View File

@ -5,7 +5,7 @@ import (
"testing"
"github.com/docker/docker/api/types"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
)
func TestCheckpointContextFormatWrite(t *testing.T) {
@ -46,10 +46,7 @@ checkpoint-3:
out := bytes.NewBufferString("")
testcase.context.Output = out
err := CheckpointWrite(testcase.context, checkpoints)
if err != nil {
assert.Error(t, err, testcase.expected)
} else {
assert.Equal(t, out.String(), testcase.expected)
}
assert.NilError(t, err)
assert.Equal(t, out.String(), testcase.expected)
}
}

View File

@ -6,7 +6,8 @@ import (
"time"
"github.com/docker/docker/api/types/swarm"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func TestConfigContextFormatWrite(t *testing.T) {
@ -55,9 +56,9 @@ id_rsa
out := bytes.NewBufferString("")
testcase.context.Output = out
if err := ConfigWrite(testcase.context, configs); err != nil {
assert.Error(t, err, testcase.expected)
assert.ErrorContains(t, err, testcase.expected)
} else {
assert.Equal(t, out.String(), testcase.expected)
assert.Check(t, is.Equal(out.String(), testcase.expected))
}
}
}

View File

@ -10,9 +10,9 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/stringid"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestContainerPsContext(t *testing.T) {
@ -244,9 +244,9 @@ size: 0B
testcase.context.Output = out
err := ContainerWrite(testcase.context, containers)
if err != nil {
assert.EqualError(t, err, testcase.expected)
assert.Error(t, err, testcase.expected)
} else {
assert.Equal(t, testcase.expected, out.String())
assert.Check(t, is.Equal(testcase.expected, out.String()))
}
}
}
@ -305,7 +305,7 @@ func TestContainerContextWriteWithNoContainers(t *testing.T) {
for _, context := range contexts {
ContainerWrite(context.context, containers)
assert.Equal(t, context.expected, out.String())
assert.Check(t, is.Equal(context.expected, out.String()))
// Clean buffer
out.Reset()
}
@ -359,8 +359,8 @@ func TestContainerContextWriteJSON(t *testing.T) {
msg := fmt.Sprintf("Output: line %d: %s", i, line)
var m map[string]interface{}
err := json.Unmarshal([]byte(line), &m)
require.NoError(t, err, msg)
assert.Equal(t, expectedJSONs[i], m, msg)
assert.NilError(t, err, msg)
assert.Check(t, is.DeepEqual(expectedJSONs[i], m), msg)
}
}
@ -378,8 +378,8 @@ func TestContainerContextWriteJSONField(t *testing.T) {
msg := fmt.Sprintf("Output: line %d: %s", i, line)
var s string
err := json.Unmarshal([]byte(line), &s)
require.NoError(t, err, msg)
assert.Equal(t, containers[i].ID, s, msg)
assert.NilError(t, err, msg)
assert.Check(t, is.Equal(containers[i].ID, s), msg)
}
}
@ -653,6 +653,6 @@ func TestDisplayablePorts(t *testing.T) {
for _, port := range cases {
actual := DisplayablePorts(port.ports)
assert.Equal(t, port.expected, actual)
assert.Check(t, is.Equal(port.expected, actual))
}
}

View File

@ -4,7 +4,8 @@ import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func compareMultipleValues(t *testing.T, value, expected string) {
@ -23,5 +24,5 @@ func compareMultipleValues(t *testing.T, value, expected string) {
keyval := strings.Split(expected, "=")
expMap[keyval[0]] = keyval[1]
}
assert.Equal(t, expMap, entriesMap)
assert.Check(t, is.DeepEqual(expMap, entriesMap))
}

View File

@ -6,7 +6,8 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/pkg/archive"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func TestDiffContextFormatWrite(t *testing.T) {
@ -51,9 +52,9 @@ D: /usr/app/old_app.js
testcase.context.Output = out
err := DiffWrite(testcase.context, diffs)
if err != nil {
assert.EqualError(t, err, testcase.expected)
assert.Error(t, err, testcase.expected)
} else {
assert.Equal(t, testcase.expected, out.String())
assert.Check(t, is.Equal(testcase.expected, out.String()))
}
}
}

View File

@ -4,8 +4,9 @@ import (
"bytes"
"testing"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/stretchr/testify/assert"
)
func TestDiskUsageContextFormatWrite(t *testing.T) {
@ -101,9 +102,9 @@ Build Cache 0B
out := bytes.NewBufferString("")
testcase.context.Output = out
if err := testcase.context.Write(); err != nil {
assert.Equal(t, testcase.expected, err.Error())
assert.Check(t, is.Equal(testcase.expected, err.Error()))
} else {
assert.Equal(t, testcase.expected, out.String())
assert.Check(t, is.Equal(testcase.expected, out.String()))
}
}
}

View File

@ -3,7 +3,8 @@ package formatter
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func TestEllipsis(t *testing.T) {
@ -25,6 +26,6 @@ func TestEllipsis(t *testing.T) {
}
for _, testcase := range testcases {
assert.Equal(t, testcase.expected, Ellipsis(testcase.source, testcase.width))
assert.Check(t, is.Equal(testcase.expected, Ellipsis(testcase.source, testcase.width)))
}
}

View File

@ -1,16 +1,16 @@
package formatter
import (
"bytes"
"strconv"
"strings"
"testing"
"time"
"bytes"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/pkg/stringid"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
type historyCase struct {
@ -50,6 +50,7 @@ func TestHistoryContext_ID(t *testing.T) {
}
func TestHistoryContext_CreatedSince(t *testing.T) {
dateStr := "2009-11-10T23:00:00Z"
var ctx historyContext
cases := []historyCase{
{
@ -64,7 +65,7 @@ func TestHistoryContext_CreatedSince(t *testing.T) {
h: image.HistoryResponseItem{Created: time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC).Unix()},
trunc: false,
human: false,
}, "2009-11-10T23:00:00Z", ctx.CreatedSince,
}, dateStr, ctx.CreatedSince,
},
}
@ -218,7 +219,7 @@ imageID4 24 hours ago /bin/bash grep
for _, context := range contexts {
HistoryWrite(context.context, true, histories)
assert.Equal(t, context.expected, out.String())
assert.Check(t, is.Equal(context.expected, out.String()))
// Clean buffer
out.Reset()
}

View File

@ -9,7 +9,8 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/stringid"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func TestImageContext(t *testing.T) {
@ -83,7 +84,7 @@ func TestImageContext(t *testing.T) {
if strings.Contains(v, ",") {
compareMultipleValues(t, v, c.expValue)
} else {
assert.Equal(t, c.expValue, v)
assert.Check(t, is.Equal(c.expValue, v))
}
}
}
@ -293,9 +294,9 @@ image_id: imageID3
testcase.context.Output = out
err := ImageWrite(testcase.context, images)
if err != nil {
assert.EqualError(t, err, testcase.expected)
assert.Error(t, err, testcase.expected)
} else {
assert.Equal(t, testcase.expected, out.String())
assert.Check(t, is.Equal(testcase.expected, out.String()))
}
}
}
@ -348,7 +349,7 @@ func TestImageContextWriteWithNoImage(t *testing.T) {
for _, context := range contexts {
ImageWrite(context.context, images)
assert.Equal(t, context.expected, out.String())
assert.Check(t, is.Equal(context.expected, out.String()))
// Clean buffer
out.Reset()
}

View File

@ -10,8 +10,8 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/stringid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func TestNetworkContext(t *testing.T) {
@ -162,9 +162,9 @@ foobar_bar 2017-01-01 00:00:00 +0000 UTC
testcase.context.Output = out
err := NetworkWrite(testcase.context, networks)
if err != nil {
assert.EqualError(t, err, testcase.expected)
assert.Error(t, err, testcase.expected)
} else {
assert.Equal(t, testcase.expected, out.String())
assert.Check(t, is.Equal(testcase.expected, out.String()))
}
}
}
@ -188,8 +188,8 @@ func TestNetworkContextWriteJSON(t *testing.T) {
msg := fmt.Sprintf("Output: line %d: %s", i, line)
var m map[string]interface{}
err := json.Unmarshal([]byte(line), &m)
require.NoError(t, err, msg)
assert.Equal(t, expectedJSONs[i], m, msg)
assert.NilError(t, err, msg)
assert.Check(t, is.DeepEqual(expectedJSONs[i], m), msg)
}
}
@ -207,7 +207,7 @@ func TestNetworkContextWriteJSONField(t *testing.T) {
msg := fmt.Sprintf("Output: line %d: %s", i, line)
var s string
err := json.Unmarshal([]byte(line), &s)
require.NoError(t, err, msg)
assert.Equal(t, networks[i].ID, s, msg)
assert.NilError(t, err, msg)
assert.Check(t, is.Equal(networks[i].ID, s), msg)
}
}

View File

@ -10,8 +10,8 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/pkg/stringid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func TestNodeContext(t *testing.T) {
@ -203,9 +203,9 @@ foobar_boo Unknown
testcase.context.Output = out
err := NodeWrite(testcase.context, nodes, types.Info{Swarm: swarm.Info{Cluster: &testcase.clusterInfo}})
if err != nil {
assert.EqualError(t, err, testcase.expected)
assert.Error(t, err, testcase.expected)
} else {
assert.Equal(t, testcase.expected, out.String())
assert.Check(t, is.Equal(testcase.expected, out.String()))
}
}
}
@ -255,8 +255,8 @@ func TestNodeContextWriteJSON(t *testing.T) {
msg := fmt.Sprintf("Output: line %d: %s", i, line)
var m map[string]interface{}
err := json.Unmarshal([]byte(line), &m)
require.NoError(t, err, msg)
assert.Equal(t, testcase.expected[i], m, msg)
assert.NilError(t, err, msg)
assert.Check(t, is.DeepEqual(testcase.expected[i], m), msg)
}
}
}
@ -275,8 +275,8 @@ func TestNodeContextWriteJSONField(t *testing.T) {
msg := fmt.Sprintf("Output: line %d: %s", i, line)
var s string
err := json.Unmarshal([]byte(line), &s)
require.NoError(t, err, msg)
assert.Equal(t, nodes[i].ID, s, msg)
assert.NilError(t, err, msg)
assert.Check(t, is.Equal(nodes[i].ID, s), msg)
}
}
@ -344,5 +344,5 @@ data
Issuer Subject: c3ViamVjdA==
Issuer Public Key: cHViS2V5
`
assert.Equal(t, expected, out.String())
assert.Check(t, is.Equal(expected, out.String()))
}

View File

@ -8,7 +8,8 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/stringid"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func TestPluginContext(t *testing.T) {
@ -131,9 +132,9 @@ foobar_bar
testcase.context.Output = out
err := PluginWrite(testcase.context, plugins)
if err != nil {
assert.EqualError(t, err, testcase.expected)
assert.Error(t, err, testcase.expected)
} else {
assert.Equal(t, testcase.expected, out.String())
assert.Check(t, is.Equal(testcase.expected, out.String()))
}
}
}
@ -158,7 +159,7 @@ func TestPluginContextWriteJSON(t *testing.T) {
if err := json.Unmarshal([]byte(line), &m); err != nil {
t.Fatal(err)
}
assert.Equal(t, expectedJSONs[i], m)
assert.Check(t, is.DeepEqual(expectedJSONs[i], m))
}
}
@ -177,6 +178,6 @@ func TestPluginContextWriteJSONField(t *testing.T) {
if err := json.Unmarshal([]byte(line), &s); err != nil {
t.Fatal(err)
}
assert.Equal(t, plugins[i].ID, s)
assert.Check(t, is.Equal(plugins[i].ID, s))
}
}

View File

@ -7,8 +7,9 @@ import (
"testing"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/stretchr/testify/assert"
)
func TestSearchContext(t *testing.T) {
@ -154,9 +155,9 @@ result2 5
testcase.context.Output = out
err := SearchWrite(testcase.context, results, false, 0)
if err != nil {
assert.Error(t, err, testcase.expected)
assert.Check(t, is.ErrorContains(err, testcase.expected))
} else {
assert.Equal(t, out.String(), testcase.expected)
assert.Check(t, is.Equal(out.String(), testcase.expected))
}
}
}
@ -191,9 +192,9 @@ result2
testcase.context.Output = out
err := SearchWrite(testcase.context, results, true, 0)
if err != nil {
assert.Error(t, err, testcase.expected)
assert.Check(t, is.ErrorContains(err, testcase.expected))
} else {
assert.Equal(t, out.String(), testcase.expected)
assert.Check(t, is.Equal(out.String(), testcase.expected))
}
}
}
@ -226,9 +227,9 @@ result1
testcase.context.Output = out
err := SearchWrite(testcase.context, results, false, 6)
if err != nil {
assert.Error(t, err, testcase.expected)
assert.Check(t, is.ErrorContains(err, testcase.expected))
} else {
assert.Equal(t, out.String(), testcase.expected)
assert.Check(t, is.Equal(out.String(), testcase.expected))
}
}
}
@ -254,7 +255,7 @@ func TestSearchContextWriteJSON(t *testing.T) {
if err := json.Unmarshal([]byte(line), &m); err != nil {
t.Fatal(err)
}
assert.Equal(t, m, expectedJSONs[i])
assert.Check(t, is.DeepEqual(m, expectedJSONs[i]))
}
}
@ -274,6 +275,6 @@ func TestSearchContextWriteJSONField(t *testing.T) {
if err := json.Unmarshal([]byte(line), &s); err != nil {
t.Fatal(err)
}
assert.Equal(t, s, results[i].Name)
assert.Check(t, is.Equal(s, results[i].Name))
}
}

View File

@ -6,7 +6,8 @@ import (
"time"
"github.com/docker/docker/api/types/swarm"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func TestSecretContextFormatWrite(t *testing.T) {
@ -55,9 +56,9 @@ id_rsa
out := bytes.NewBufferString("")
testcase.context.Output = out
if err := SecretWrite(testcase.context, secrets); err != nil {
assert.EqualError(t, err, testcase.expected)
assert.Error(t, err, testcase.expected)
} else {
assert.Equal(t, testcase.expected, out.String())
assert.Check(t, is.Equal(testcase.expected, out.String()))
}
}
}

View File

@ -8,9 +8,9 @@ import (
"testing"
"github.com/docker/docker/api/types/swarm"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestServiceContextWrite(t *testing.T) {
@ -126,9 +126,9 @@ bar
testcase.context.Output = out
err := ServiceListWrite(testcase.context, services, info)
if err != nil {
assert.EqualError(t, err, testcase.expected)
assert.Error(t, err, testcase.expected)
} else {
assert.Equal(t, testcase.expected, out.String())
assert.Check(t, is.Equal(testcase.expected, out.String()))
}
}
}
@ -192,8 +192,8 @@ func TestServiceContextWriteJSON(t *testing.T) {
msg := fmt.Sprintf("Output: line %d: %s", i, line)
var m map[string]interface{}
err := json.Unmarshal([]byte(line), &m)
require.NoError(t, err, msg)
assert.Equal(t, expectedJSONs[i], m, msg)
assert.NilError(t, err, msg)
assert.Check(t, is.DeepEqual(expectedJSONs[i], m), msg)
}
}
func TestServiceContextWriteJSONField(t *testing.T) {
@ -220,8 +220,8 @@ func TestServiceContextWriteJSONField(t *testing.T) {
msg := fmt.Sprintf("Output: line %d: %s", i, line)
var s string
err := json.Unmarshal([]byte(line), &s)
require.NoError(t, err, msg)
assert.Equal(t, services[i].Spec.Name, s, msg)
assert.NilError(t, err, msg)
assert.Check(t, is.Equal(services[i].Spec.Name, s), msg)
}
}
@ -355,5 +355,5 @@ func TestServiceContext_Ports(t *testing.T) {
},
}
assert.Equal(t, "*:97-98->97-98/sctp, *:60-61->60-61/tcp, *:62->61/tcp, *:80-81->80/tcp, *:90-95->90-95/tcp, *:90-96->90-96/udp", c.Ports())
assert.Check(t, is.Equal("*:97-98->97-98/sctp, *:60-61->60-61/tcp, *:62->61/tcp, *:80-81->80/tcp, *:90-95->90-95/tcp, *:90-96->90-96/udp", c.Ports()))
}

View File

@ -4,7 +4,8 @@ import (
"bytes"
"testing"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func TestStackContextWrite(t *testing.T) {
@ -56,9 +57,9 @@ bar
testcase.context.Output = out
err := StackWrite(testcase.context, stacks)
if err != nil {
assert.Error(t, err, testcase.expected)
assert.Check(t, is.ErrorContains(err, testcase.expected))
} else {
assert.Equal(t, out.String(), testcase.expected)
assert.Check(t, is.Equal(out.String(), testcase.expected))
}
}
}

View File

@ -5,7 +5,8 @@ import (
"testing"
"github.com/docker/docker/pkg/stringid"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func TestContainerStatsContext(t *testing.T) {
@ -116,9 +117,9 @@ container2 --
te.context.Output = &out
err := ContainerStatsWrite(te.context, stats, "linux", false)
if err != nil {
assert.EqualError(t, err, te.expected)
assert.Error(t, err, te.expected)
} else {
assert.Equal(t, te.expected, out.String())
assert.Check(t, is.Equal(te.expected, out.String()))
}
}
}
@ -182,9 +183,9 @@ container2 -- --
te.context.Output = &out
err := ContainerStatsWrite(te.context, stats, "windows", false)
if err != nil {
assert.EqualError(t, err, te.expected)
assert.Error(t, err, te.expected)
} else {
assert.Equal(t, te.expected, out.String())
assert.Check(t, is.Equal(te.expected, out.String()))
}
}
}
@ -221,7 +222,7 @@ func TestContainerStatsContextWriteWithNoStats(t *testing.T) {
for _, context := range contexts {
ContainerStatsWrite(context.context, []StatsEntry{}, "linux", false)
assert.Equal(t, context.expected, out.String())
assert.Check(t, is.Equal(context.expected, out.String()))
// Clean buffer
out.Reset()
}
@ -259,7 +260,7 @@ func TestContainerStatsContextWriteWithNoStatsWindows(t *testing.T) {
for _, context := range contexts {
ContainerStatsWrite(context.context, []StatsEntry{}, "windows", false)
assert.Equal(t, context.expected, out.String())
assert.Check(t, is.Equal(context.expected, out.String()))
// Clean buffer
out.Reset()
}
@ -293,7 +294,7 @@ func TestContainerStatsContextWriteTrunc(t *testing.T) {
for _, context := range contexts {
ContainerStatsWrite(context.context, []StatsEntry{{ID: "b95a83497c9161c9b444e3d70e1a9dfba0c1840d41720e146a95a08ebf938afc"}}, "linux", context.trunc)
assert.Equal(t, context.expected, out.String())
assert.Check(t, is.Equal(context.expected, out.String()))
// Clean buffer
out.Reset()
}

View File

@ -7,8 +7,9 @@ import (
"testing"
"github.com/docker/docker/api/types/swarm"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/stretchr/testify/assert"
)
func TestTaskContextWrite(t *testing.T) {
@ -74,9 +75,9 @@ foobar_bar foo2
testcase.context.Output = out
err := TaskWrite(testcase.context, tasks, names, nodes)
if err != nil {
assert.EqualError(t, err, testcase.expected)
assert.Error(t, err, testcase.expected)
} else {
assert.Equal(t, testcase.expected, out.String())
assert.Check(t, is.Equal(testcase.expected, out.String()))
}
}
}
@ -100,6 +101,6 @@ func TestTaskContextWriteJSONField(t *testing.T) {
if err := json.Unmarshal([]byte(line), &s); err != nil {
t.Fatal(err)
}
assert.Equal(t, tasks[i].ID, s)
assert.Check(t, is.Equal(tasks[i].ID, s))
}
}

View File

@ -5,7 +5,8 @@ import (
"testing"
"github.com/docker/docker/pkg/stringid"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func TestTrustTag(t *testing.T) {
@ -126,9 +127,9 @@ tag3 bbbbbbbb
testcase.context.Output = out
err := TrustTagWrite(testcase.context, signedTags)
if err != nil {
assert.EqualError(t, err, testcase.expected)
assert.Error(t, err, testcase.expected)
} else {
assert.Equal(t, testcase.expected, out.String())
assert.Check(t, is.Equal(testcase.expected, out.String()))
}
}
}
@ -152,8 +153,8 @@ func TestTrustTagContextEmptyWrite(t *testing.T) {
out := bytes.NewBufferString("")
emptyCase.context.Output = out
err := TrustTagWrite(emptyCase.context, emptySignedTags)
assert.NoError(t, err)
assert.Equal(t, emptyCase.expected, out.String())
assert.NilError(t, err)
assert.Check(t, is.Equal(emptyCase.expected, out.String()))
}
func TestSignerInfoContextEmptyWrite(t *testing.T) {
@ -171,8 +172,8 @@ func TestSignerInfoContextEmptyWrite(t *testing.T) {
out := bytes.NewBufferString("")
emptyCase.context.Output = out
err := SignerInfoWrite(emptyCase.context, emptySignerInfo)
assert.NoError(t, err)
assert.Equal(t, emptyCase.expected, out.String())
assert.NilError(t, err)
assert.Check(t, is.Equal(emptyCase.expected, out.String()))
}
func TestSignerInfoContextWrite(t *testing.T) {
@ -230,9 +231,9 @@ eve foobarbazquxquux, key31, key32
testcase.context.Output = out
err := SignerInfoWrite(testcase.context, signerInfo)
if err != nil {
assert.EqualError(t, err, testcase.expected)
assert.Error(t, err, testcase.expected)
} else {
assert.Equal(t, testcase.expected, out.String())
assert.Check(t, is.Equal(testcase.expected, out.String()))
}
}
}

View File

@ -9,8 +9,8 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/stringid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func TestVolumeContext(t *testing.T) {
@ -133,9 +133,9 @@ foobar_bar
testcase.context.Output = out
err := VolumeWrite(testcase.context, volumes)
if err != nil {
assert.EqualError(t, err, testcase.expected)
assert.Error(t, err, testcase.expected)
} else {
assert.Equal(t, testcase.expected, out.String())
assert.Check(t, is.Equal(testcase.expected, out.String()))
}
}
}
@ -158,8 +158,8 @@ func TestVolumeContextWriteJSON(t *testing.T) {
msg := fmt.Sprintf("Output: line %d: %s", i, line)
var m map[string]interface{}
err := json.Unmarshal([]byte(line), &m)
require.NoError(t, err, msg)
assert.Equal(t, expectedJSONs[i], m, msg)
assert.NilError(t, err, msg)
assert.Check(t, is.DeepEqual(expectedJSONs[i], m), msg)
}
}
@ -177,7 +177,7 @@ func TestVolumeContextWriteJSONField(t *testing.T) {
msg := fmt.Sprintf("Output: line %d: %s", i, line)
var s string
err := json.Unmarshal([]byte(line), &s)
require.NoError(t, err, msg)
assert.Equal(t, volumes[i].Name, s, msg)
assert.NilError(t, err, msg)
assert.Check(t, is.Equal(volumes[i].Name, s), msg)
}
}

View File

@ -4,10 +4,11 @@ import (
"testing"
"github.com/docker/docker/api/types/swarm"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
// Import builders to get the builder function as package function
. "github.com/docker/cli/internal/test/builders"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"golang.org/x/net/context"
)
@ -21,7 +22,7 @@ func TestResolveError(t *testing.T) {
idResolver := New(cli, false)
_, err := idResolver.Resolve(context.Background(), struct{}{}, "nodeID")
assert.EqualError(t, err, "unsupported type")
assert.Error(t, err, "unsupported type")
}
func TestResolveWithNoResolveOption(t *testing.T) {
@ -40,9 +41,9 @@ func TestResolveWithNoResolveOption(t *testing.T) {
idResolver := New(cli, true)
id, err := idResolver.Resolve(context.Background(), swarm.Node{}, "nodeID")
assert.NoError(t, err)
assert.Equal(t, "nodeID", id)
assert.False(t, resolved)
assert.NilError(t, err)
assert.Check(t, is.Equal("nodeID", id))
assert.Check(t, !resolved)
}
func TestResolveWithCache(t *testing.T) {
@ -59,11 +60,11 @@ func TestResolveWithCache(t *testing.T) {
ctx := context.Background()
for i := 0; i < 2; i++ {
id, err := idResolver.Resolve(ctx, swarm.Node{}, "nodeID")
assert.NoError(t, err)
assert.Equal(t, "node-foo", id)
assert.NilError(t, err)
assert.Check(t, is.Equal("node-foo", id))
}
assert.Equal(t, 1, inspectCounter)
assert.Check(t, is.Equal(1, inspectCounter))
}
func TestResolveNode(t *testing.T) {
@ -103,8 +104,8 @@ func TestResolveNode(t *testing.T) {
idResolver := New(cli, false)
id, err := idResolver.Resolve(ctx, swarm.Node{}, tc.nodeID)
assert.NoError(t, err)
assert.Equal(t, tc.expectedID, id)
assert.NilError(t, err)
assert.Check(t, is.Equal(tc.expectedID, id))
}
}
@ -138,7 +139,7 @@ func TestResolveService(t *testing.T) {
idResolver := New(cli, false)
id, err := idResolver.Resolve(ctx, swarm.Service{}, tc.serviceID)
assert.NoError(t, err)
assert.Equal(t, tc.expectedID, id)
assert.NilError(t, err)
assert.Check(t, is.Equal(tc.expectedID, id))
}
}

View File

@ -67,6 +67,7 @@ type buildOptions struct {
imageIDFile string
stream bool
platform string
untrusted bool
}
// dockerfileFromStdin returns true when the user specified that the Dockerfile
@ -137,7 +138,7 @@ func NewBuildCommand(dockerCli command.Cli) *cobra.Command {
flags.StringVar(&options.target, "target", "", "Set the target build stage to build.")
flags.StringVar(&options.imageIDFile, "iidfile", "", "Write the image ID to the file")
command.AddTrustVerificationFlags(flags)
command.AddTrustVerificationFlags(flags, &options.untrusted, dockerCli.ContentTrustEnabled())
command.AddPlatformFlag(flags, &options.platform)
flags.BoolVar(&options.squash, "squash", false, "Squash newly built layers into a single new layer")
@ -285,7 +286,7 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
defer cancel()
var resolvedTags []*resolvedTag
if command.IsTrusted() {
if !options.untrusted {
translator := func(ctx context.Context, ref reference.NamedTagged) (reference.Canonical, error) {
return TrustedReference(ctx, dockerCli, ref, nil)
}
@ -293,10 +294,10 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
if buildCtx != nil {
// Wrap the tar archive to replace the Dockerfile entry with the rewritten
// Dockerfile which uses trusted pulls.
buildCtx = replaceDockerfileTarWrapper(ctx, buildCtx, relDockerfile, translator, &resolvedTags)
buildCtx = replaceDockerfileForContentTrust(ctx, buildCtx, relDockerfile, translator, &resolvedTags)
} else if dockerfileCtx != nil {
// if there was not archive context still do the possible replacements in Dockerfile
newDockerfile, _, err := rewriteDockerfileFrom(ctx, dockerfileCtx, translator)
newDockerfile, _, err := rewriteDockerfileFromForContentTrust(ctx, dockerfileCtx, translator)
if err != nil {
return err
}
@ -460,7 +461,7 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
return err
}
}
if command.IsTrusted() {
if !options.untrusted {
// Since the build was successful, now we must tag any of the resolved
// images from the above Dockerfile rewrite.
for _, resolved := range resolvedTags {
@ -499,11 +500,12 @@ type resolvedTag struct {
tagRef reference.NamedTagged
}
// rewriteDockerfileFrom rewrites the given Dockerfile by resolving images in
// rewriteDockerfileFromForContentTrust rewrites the given Dockerfile by resolving images in
// "FROM <image>" instructions to a digest reference. `translator` is a
// function that takes a repository name and tag reference and returns a
// trusted digest reference.
func rewriteDockerfileFrom(ctx context.Context, dockerfile io.Reader, translator translatorFunc) (newDockerfile []byte, resolvedTags []*resolvedTag, err error) {
// This should be called *only* when content trust is enabled
func rewriteDockerfileFromForContentTrust(ctx context.Context, dockerfile io.Reader, translator translatorFunc) (newDockerfile []byte, resolvedTags []*resolvedTag, err error) {
scanner := bufio.NewScanner(dockerfile)
buf := bytes.NewBuffer(nil)
@ -520,7 +522,7 @@ func rewriteDockerfileFrom(ctx context.Context, dockerfile io.Reader, translator
return nil, nil, err
}
ref = reference.TagNameOnly(ref)
if ref, ok := ref.(reference.NamedTagged); ok && command.IsTrusted() {
if ref, ok := ref.(reference.NamedTagged); ok {
trustedRef, err := translator(ctx, ref)
if err != nil {
return nil, nil, err
@ -543,11 +545,10 @@ func rewriteDockerfileFrom(ctx context.Context, dockerfile io.Reader, translator
return buf.Bytes(), resolvedTags, scanner.Err()
}
// replaceDockerfileTarWrapper wraps the given input tar archive stream and
// replaces the entry with the given Dockerfile name with the contents of the
// new Dockerfile. Returns a new tar archive stream with the replaced
// Dockerfile.
func replaceDockerfileTarWrapper(ctx context.Context, inputTarStream io.ReadCloser, dockerfileName string, translator translatorFunc, resolvedTags *[]*resolvedTag) io.ReadCloser {
// replaceDockerfileForContentTrust wraps the given input tar archive stream and
// uses the translator to replace the Dockerfile which uses a trusted reference.
// Returns a new tar archive stream with the replaced Dockerfile.
func replaceDockerfileForContentTrust(ctx context.Context, inputTarStream io.ReadCloser, dockerfileName string, translator translatorFunc, resolvedTags *[]*resolvedTag) io.ReadCloser {
pipeReader, pipeWriter := io.Pipe()
go func() {
tarReader := tar.NewReader(inputTarStream)
@ -574,7 +575,7 @@ func replaceDockerfileTarWrapper(ctx context.Context, inputTarStream io.ReadClos
// generated from a directory on the local filesystem, the
// Dockerfile will only appear once in the archive.
var newDockerfile []byte
newDockerfile, *resolvedTags, err = rewriteDockerfileFrom(ctx, content, translator)
newDockerfile, *resolvedTags, err = rewriteDockerfileFromForContentTrust(ctx, content, translator)
if err != nil {
pipeWriter.CloseWithError(err)
return

View File

@ -11,10 +11,9 @@ import (
"strings"
"testing"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/pkg/archive"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
const dockerfileContents = "FROM busybox"
@ -38,7 +37,7 @@ func testValidateContextDirectory(t *testing.T, prepare func(t *testing.T) (stri
defer cleanup()
err := ValidateContextDirectory(contextDir, excludes)
require.NoError(t, err)
assert.NilError(t, err)
}
func TestGetContextFromLocalDirNoDockerfile(t *testing.T) {
@ -46,7 +45,7 @@ func TestGetContextFromLocalDirNoDockerfile(t *testing.T) {
defer cleanup()
_, _, err := GetContextFromLocalDir(contextDir, "")
testutil.ErrorContains(t, err, "Dockerfile")
assert.ErrorContains(t, err, "Dockerfile")
}
func TestGetContextFromLocalDirNotExistingDir(t *testing.T) {
@ -56,7 +55,7 @@ func TestGetContextFromLocalDirNotExistingDir(t *testing.T) {
fakePath := filepath.Join(contextDir, "fake")
_, _, err := GetContextFromLocalDir(fakePath, "")
testutil.ErrorContains(t, err, "fake")
assert.ErrorContains(t, err, "fake")
}
func TestGetContextFromLocalDirNotExistingDockerfile(t *testing.T) {
@ -66,7 +65,7 @@ func TestGetContextFromLocalDirNotExistingDockerfile(t *testing.T) {
fakePath := filepath.Join(contextDir, "fake")
_, _, err := GetContextFromLocalDir(contextDir, fakePath)
testutil.ErrorContains(t, err, "fake")
assert.ErrorContains(t, err, "fake")
}
func TestGetContextFromLocalDirWithNoDirectory(t *testing.T) {
@ -79,10 +78,10 @@ func TestGetContextFromLocalDirWithNoDirectory(t *testing.T) {
defer chdirCleanup()
absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, "")
require.NoError(t, err)
assert.NilError(t, err)
assert.Equal(t, contextDir, absContextDir)
assert.Equal(t, DefaultDockerfileName, relDockerfile)
assert.Check(t, is.Equal(contextDir, absContextDir))
assert.Check(t, is.Equal(DefaultDockerfileName, relDockerfile))
}
func TestGetContextFromLocalDirWithDockerfile(t *testing.T) {
@ -92,10 +91,10 @@ func TestGetContextFromLocalDirWithDockerfile(t *testing.T) {
createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777)
absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, "")
require.NoError(t, err)
assert.NilError(t, err)
assert.Equal(t, contextDir, absContextDir)
assert.Equal(t, DefaultDockerfileName, relDockerfile)
assert.Check(t, is.Equal(contextDir, absContextDir))
assert.Check(t, is.Equal(DefaultDockerfileName, relDockerfile))
}
func TestGetContextFromLocalDirLocalFile(t *testing.T) {
@ -130,10 +129,10 @@ func TestGetContextFromLocalDirWithCustomDockerfile(t *testing.T) {
createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777)
absContextDir, relDockerfile, err := GetContextFromLocalDir(contextDir, DefaultDockerfileName)
require.NoError(t, err)
assert.NilError(t, err)
assert.Equal(t, contextDir, absContextDir)
assert.Equal(t, DefaultDockerfileName, relDockerfile)
assert.Check(t, is.Equal(contextDir, absContextDir))
assert.Check(t, is.Equal(DefaultDockerfileName, relDockerfile))
}
func TestGetContextFromReaderString(t *testing.T) {
@ -161,7 +160,7 @@ func TestGetContextFromReaderString(t *testing.T) {
t.Fatalf("Tar stream too long: %s", err)
}
require.NoError(t, tarArchive.Close())
assert.NilError(t, tarArchive.Close())
if dockerfileContents != contents {
t.Fatalf("Uncompressed tar archive does not equal: %s, got: %s", dockerfileContents, contents)
@ -179,15 +178,15 @@ func TestGetContextFromReaderTar(t *testing.T) {
createTestTempFile(t, contextDir, DefaultDockerfileName, dockerfileContents, 0777)
tarStream, err := archive.Tar(contextDir, archive.Uncompressed)
require.NoError(t, err)
assert.NilError(t, err)
tarArchive, relDockerfile, err := GetContextFromReader(tarStream, DefaultDockerfileName)
require.NoError(t, err)
assert.NilError(t, err)
tarReader := tar.NewReader(tarArchive)
header, err := tarReader.Next()
require.NoError(t, err)
assert.NilError(t, err)
if header.Name != DefaultDockerfileName {
t.Fatalf("Dockerfile name should be: %s, got: %s", DefaultDockerfileName, header.Name)
@ -203,7 +202,7 @@ func TestGetContextFromReaderTar(t *testing.T) {
t.Fatalf("Tar stream too long: %s", err)
}
require.NoError(t, tarArchive.Close())
assert.NilError(t, tarArchive.Close())
if dockerfileContents != contents {
t.Fatalf("Uncompressed tar archive does not equal: %s, got: %s", dockerfileContents, contents)
@ -243,8 +242,8 @@ func TestValidateContextDirectoryWithOneFileExcludes(t *testing.T) {
// When an error occurs, it terminates the test.
func createTestTempDir(t *testing.T, dir, prefix string) (string, func()) {
path, err := ioutil.TempDir(dir, prefix)
require.NoError(t, err)
return path, func() { require.NoError(t, os.RemoveAll(path)) }
assert.NilError(t, err)
return path, func() { assert.NilError(t, os.RemoveAll(path)) }
}
// createTestTempFile creates a temporary file within dir with specific contents and permissions.
@ -252,7 +251,7 @@ func createTestTempDir(t *testing.T, dir, prefix string) (string, func()) {
func createTestTempFile(t *testing.T, dir, filename, contents string, perm os.FileMode) string {
filePath := filepath.Join(dir, filename)
err := ioutil.WriteFile(filePath, []byte(contents), perm)
require.NoError(t, err)
assert.NilError(t, err)
return filePath
}
@ -262,9 +261,9 @@ func createTestTempFile(t *testing.T, dir, filename, contents string, perm os.Fi
// When an error occurs, it terminates the test.
func chdir(t *testing.T, dir string) func() {
workingDirectory, err := os.Getwd()
require.NoError(t, err)
require.NoError(t, os.Chdir(dir))
return func() { require.NoError(t, os.Chdir(workingDirectory)) }
assert.NilError(t, err)
assert.NilError(t, os.Chdir(dir))
return func() { assert.NilError(t, os.Chdir(workingDirectory)) }
}
func TestIsArchive(t *testing.T) {
@ -295,6 +294,6 @@ func TestIsArchive(t *testing.T) {
},
}
for _, testcase := range testcases {
assert.Equal(t, testcase.expected, IsArchive(testcase.header), testcase.doc)
assert.Check(t, is.Equal(testcase.expected, IsArchive(testcase.header)), testcase.doc)
}
}

View File

@ -0,0 +1,55 @@
//+build linux
package image
import (
"bytes"
"io"
"io/ioutil"
"syscall"
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/archive"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/fs"
"golang.org/x/net/context"
)
func TestRunBuildResetsUidAndGidInContext(t *testing.T) {
dest := fs.NewDir(t, "test-build-context-dest")
defer dest.Remove()
fakeImageBuild := func(_ context.Context, context io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) {
assert.NilError(t, archive.Untar(context, dest.Path(), nil))
body := new(bytes.Buffer)
return types.ImageBuildResponse{Body: ioutil.NopCloser(body)}, nil
}
cli := test.NewFakeCli(&fakeClient{imageBuildFunc: fakeImageBuild})
dir := fs.NewDir(t, "test-build-context",
fs.WithFile("foo", "some content", fs.AsUser(65534, 65534)),
fs.WithFile("Dockerfile", `
FROM alpine:3.6
COPY foo bar /
`),
)
defer dir.Remove()
options := newBuildOptions()
options.context = dir.Path()
options.untrusted = true
err := runBuild(cli, options)
assert.NilError(t, err)
files, err := ioutil.ReadDir(dest.Path())
assert.NilError(t, err)
for _, fileInfo := range files {
assert.Check(t, is.Equal(uint32(0), fileInfo.Sys().(*syscall.Stat_t).Uid))
assert.Check(t, is.Equal(uint32(0), fileInfo.Sys().(*syscall.Stat_t).Gid))
}
}

View File

@ -1,65 +1,28 @@
package image
import (
"archive/tar"
"bytes"
"io"
"io/ioutil"
"os"
"path/filepath"
"runtime"
"sort"
"syscall"
"testing"
"github.com/docker/cli/cli/command"
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/archive"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/fs"
"github.com/gotestyourself/gotestyourself/skip"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/net/context"
)
func TestRunBuildResetsUidAndGidInContext(t *testing.T) {
skip.IfCondition(t, runtime.GOOS == "windows", "uid and gid not relevant on windows")
dest := fs.NewDir(t, "test-build-context-dest")
defer dest.Remove()
fakeImageBuild := func(_ context.Context, context io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) {
assert.NoError(t, archive.Untar(context, dest.Path(), nil))
body := new(bytes.Buffer)
return types.ImageBuildResponse{Body: ioutil.NopCloser(body)}, nil
}
cli := test.NewFakeCli(&fakeClient{imageBuildFunc: fakeImageBuild})
dir := fs.NewDir(t, "test-build-context",
fs.WithFile("foo", "some content", fs.AsUser(65534, 65534)),
fs.WithFile("Dockerfile", `
FROM alpine:3.6
COPY foo bar /
`),
)
defer dir.Remove()
options := newBuildOptions()
options.context = dir.Path()
err := runBuild(cli, options)
require.NoError(t, err)
files, err := ioutil.ReadDir(dest.Path())
require.NoError(t, err)
for _, fileInfo := range files {
assert.Equal(t, uint32(0), fileInfo.Sys().(*syscall.Stat_t).Uid)
assert.Equal(t, uint32(0), fileInfo.Sys().(*syscall.Stat_t).Gid)
}
}
func TestRunBuildDockerfileFromStdinWithCompress(t *testing.T) {
dest, err := ioutil.TempDir("", "test-build-compress-dest")
require.NoError(t, err)
assert.NilError(t, err)
defer os.RemoveAll(dest)
var dockerfileName string
@ -67,11 +30,11 @@ func TestRunBuildDockerfileFromStdinWithCompress(t *testing.T) {
buffer := new(bytes.Buffer)
tee := io.TeeReader(context, buffer)
assert.NoError(t, archive.Untar(tee, dest, nil))
assert.NilError(t, archive.Untar(tee, dest, nil))
dockerfileName = options.Dockerfile
header := buffer.Bytes()[:10]
assert.Equal(t, archive.Gzip, archive.DetectCompression(header))
assert.Check(t, is.Equal(archive.Gzip, archive.DetectCompression(header)))
body := new(bytes.Buffer)
return types.ImageBuildResponse{Body: ioutil.NopCloser(body)}, nil
@ -85,7 +48,7 @@ func TestRunBuildDockerfileFromStdinWithCompress(t *testing.T) {
cli.SetIn(command.NewInStream(ioutil.NopCloser(dockerfile)))
dir, err := ioutil.TempDir("", "test-build-compress")
require.NoError(t, err)
assert.NilError(t, err)
defer os.RemoveAll(dir)
ioutil.WriteFile(filepath.Join(dir, "foo"), []byte("some content"), 0644)
@ -94,18 +57,19 @@ func TestRunBuildDockerfileFromStdinWithCompress(t *testing.T) {
options.compress = true
options.dockerfileName = "-"
options.context = dir
options.untrusted = true
err = runBuild(cli, options)
require.NoError(t, err)
assert.NilError(t, err)
files, err := ioutil.ReadDir(dest)
require.NoError(t, err)
assert.NilError(t, err)
actual := []string{}
for _, fileInfo := range files {
actual = append(actual, fileInfo.Name())
}
sort.Strings(actual)
assert.Equal(t, []string{dockerfileName, ".dockerignore", "foo"}, actual)
assert.Check(t, is.DeepEqual([]string{dockerfileName, ".dockerignore", "foo"}, actual))
}
func TestRunBuildDockerfileOutsideContext(t *testing.T) {
@ -124,7 +88,7 @@ COPY data /data
defer df.Remove()
dest, err := ioutil.TempDir("", t.Name())
require.NoError(t, err)
assert.NilError(t, err)
defer os.RemoveAll(dest)
var dockerfileName string
@ -132,7 +96,7 @@ COPY data /data
buffer := new(bytes.Buffer)
tee := io.TeeReader(context, buffer)
assert.NoError(t, archive.Untar(tee, dest, nil))
assert.NilError(t, archive.Untar(tee, dest, nil))
dockerfileName = options.Dockerfile
body := new(bytes.Buffer)
@ -144,30 +108,34 @@ COPY data /data
options := newBuildOptions()
options.context = dir.Path()
options.dockerfileName = df.Path()
options.untrusted = true
err = runBuild(cli, options)
require.NoError(t, err)
assert.NilError(t, err)
files, err := ioutil.ReadDir(dest)
require.NoError(t, err)
assert.NilError(t, err)
var actual []string
for _, fileInfo := range files {
actual = append(actual, fileInfo.Name())
}
sort.Strings(actual)
assert.Equal(t, []string{dockerfileName, ".dockerignore", "data"}, actual)
assert.Check(t, is.DeepEqual([]string{dockerfileName, ".dockerignore", "data"}, actual))
}
// TestRunBuildFromLocalGitHubDirNonExistingRepo tests that build contexts
// starting with `github.com/` are special-cased, and the build command attempts
// to clone the remote repo.
// TODO: test "context selection" logic directly when runBuild is refactored
// to support testing (ex: docker/cli#294)
func TestRunBuildFromGitHubSpecialCase(t *testing.T) {
cmd := NewBuildCommand(test.NewFakeCli(nil))
cmd.SetArgs([]string{"github.com/docker/no-such-repository"})
// Clone a small repo that exists so git doesn't prompt for credentials
cmd.SetArgs([]string{"github.com/docker/for-win"})
cmd.SetOutput(ioutil.Discard)
err := cmd.Execute()
assert.Error(t, err)
assert.Contains(t, err.Error(), "unable to prepare context: unable to 'git clone'")
assert.ErrorContains(t, err, "unable to prepare context")
assert.ErrorContains(t, err, "docker-build-git")
}
// TestRunBuildFromLocalGitHubDirNonExistingRepo tests that a local directory
@ -175,19 +143,57 @@ func TestRunBuildFromGitHubSpecialCase(t *testing.T) {
// case.
func TestRunBuildFromLocalGitHubDir(t *testing.T) {
tmpDir, err := ioutil.TempDir("", "docker-build-from-local-dir-")
require.NoError(t, err)
assert.NilError(t, err)
defer os.RemoveAll(tmpDir)
buildDir := filepath.Join(tmpDir, "github.com", "docker", "no-such-repository")
err = os.MkdirAll(buildDir, 0777)
require.NoError(t, err)
assert.NilError(t, err)
err = ioutil.WriteFile(filepath.Join(buildDir, "Dockerfile"), []byte("FROM busybox\n"), 0644)
require.NoError(t, err)
assert.NilError(t, err)
client := test.NewFakeCli(&fakeClient{})
cmd := NewBuildCommand(client)
cmd.SetArgs([]string{buildDir})
cmd.SetOutput(ioutil.Discard)
err = cmd.Execute()
require.NoError(t, err)
assert.NilError(t, err)
}
func TestRunBuildWithSymlinkedContext(t *testing.T) {
dockerfile := `
FROM alpine:3.6
RUN echo hello world
`
tmpDir := fs.NewDir(t, t.Name(),
fs.WithDir("context",
fs.WithFile("Dockerfile", dockerfile)),
fs.WithSymlink("context-link", "context"))
defer tmpDir.Remove()
files := []string{}
fakeImageBuild := func(_ context.Context, context io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) {
tarReader := tar.NewReader(context)
for {
hdr, err := tarReader.Next()
switch err {
case io.EOF:
body := new(bytes.Buffer)
return types.ImageBuildResponse{Body: ioutil.NopCloser(body)}, nil
case nil:
files = append(files, hdr.Name)
default:
return types.ImageBuildResponse{}, err
}
}
}
cli := test.NewFakeCli(&fakeClient{imageBuildFunc: fakeImageBuild})
options := newBuildOptions()
options.context = tmpDir.Join("context-link")
options.untrusted = true
assert.NilError(t, runBuild(cli, options))
assert.DeepEqual(t, files, []string{"Dockerfile"})
}

View File

@ -7,11 +7,10 @@ import (
"time"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types/image"
"github.com/gotestyourself/gotestyourself/assert"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
)
func TestNewHistoryCommandErrors(t *testing.T) {
@ -39,7 +38,7 @@ func TestNewHistoryCommandErrors(t *testing.T) {
cmd := NewHistoryCommand(test.NewFakeCli(&fakeClient{imageHistoryFunc: tc.imageHistoryFunc}))
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -47,7 +46,6 @@ func TestNewHistoryCommandSuccess(t *testing.T) {
testCases := []struct {
name string
args []string
outputRegex string
imageHistoryFunc func(img string) ([]image.HistoryResponseItem, error)
}{
{
@ -64,16 +62,17 @@ func TestNewHistoryCommandSuccess(t *testing.T) {
name: "quiet",
args: []string{"--quiet", "image:tag"},
},
// TODO: This test is failing since the output does not contain an RFC3339 date
//{
// name: "non-human",
// args: []string{"--human=false", "image:tag"},
// outputRegex: "\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}", // RFC3339 date format match
//},
{
name: "non-human-header",
args: []string{"--human=false", "image:tag"},
outputRegex: "CREATED\\sAT",
name: "non-human",
args: []string{"--human=false", "image:tag"},
imageHistoryFunc: func(img string) ([]image.HistoryResponseItem, error) {
return []image.HistoryResponseItem{{
ID: "abcdef",
Created: time.Date(2017, 1, 1, 12, 0, 3, 0, time.UTC).Unix(),
CreatedBy: "rose",
Comment: "new history item!",
}}, nil
},
},
{
name: "quiet-no-trunc",
@ -92,12 +91,8 @@ func TestNewHistoryCommandSuccess(t *testing.T) {
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
err := cmd.Execute()
assert.NoError(t, err)
assert.NilError(t, err)
actual := cli.OutBuffer().String()
if tc.outputRegex == "" {
golden.Assert(t, actual, fmt.Sprintf("history-command-success.%s.golden", tc.name))
} else {
assert.Regexp(t, tc.outputRegex, actual)
}
golden.Assert(t, actual, fmt.Sprintf("history-command-success.%s.golden", tc.name))
}
}

View File

@ -7,10 +7,10 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
)
func TestNewImportCommandErrors(t *testing.T) {
@ -38,7 +38,7 @@ func TestNewImportCommandErrors(t *testing.T) {
cmd := NewImportCommand(test.NewFakeCli(&fakeClient{imageImportFunc: tc.imageImportFunc}))
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -46,7 +46,7 @@ func TestNewImportCommandInvalidFile(t *testing.T) {
cmd := NewImportCommand(test.NewFakeCli(&fakeClient{}))
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs([]string{"testdata/import-command-success.unexistent-file"})
testutil.ErrorContains(t, cmd.Execute(), "testdata/import-command-success.unexistent-file")
assert.ErrorContains(t, cmd.Execute(), "testdata/import-command-success.unexistent-file")
}
func TestNewImportCommandSuccess(t *testing.T) {
@ -67,7 +67,7 @@ func TestNewImportCommandSuccess(t *testing.T) {
name: "double",
args: []string{"-", "image:local"},
imageImportFunc: func(source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error) {
assert.Equal(t, "image:local", ref)
assert.Check(t, is.Equal("image:local", ref))
return ioutil.NopCloser(strings.NewReader("")), nil
},
},
@ -75,7 +75,7 @@ func TestNewImportCommandSuccess(t *testing.T) {
name: "message",
args: []string{"--message", "test message", "-"},
imageImportFunc: func(source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error) {
assert.Equal(t, "test message", options.Message)
assert.Check(t, is.Equal("test message", options.Message))
return ioutil.NopCloser(strings.NewReader("")), nil
},
},
@ -83,7 +83,7 @@ func TestNewImportCommandSuccess(t *testing.T) {
name: "change",
args: []string{"--change", "ENV DEBUG true", "-"},
imageImportFunc: func(source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error) {
assert.Equal(t, "ENV DEBUG true", options.Changes[0])
assert.Check(t, is.Equal("ENV DEBUG true", options.Changes[0]))
return ioutil.NopCloser(strings.NewReader("")), nil
},
},
@ -92,6 +92,6 @@ func TestNewImportCommandSuccess(t *testing.T) {
cmd := NewImportCommand(test.NewFakeCli(&fakeClient{imageImportFunc: tc.imageImportFunc}))
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
}
}

View File

@ -6,10 +6,10 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/stretchr/testify/assert"
)
func TestNewInspectCommandErrors(t *testing.T) {
@ -28,7 +28,7 @@ func TestNewInspectCommandErrors(t *testing.T) {
cmd := newInspectCommand(test.NewFakeCli(&fakeClient{}))
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -46,7 +46,7 @@ func TestNewInspectCommandSuccess(t *testing.T) {
imageCount: 1,
imageInspectFunc: func(image string) (types.ImageInspect, []byte, error) {
imageInspectInvocationCount++
assert.Equal(t, "image", image)
assert.Check(t, is.Equal("image", image))
return types.ImageInspect{}, nil, nil
},
},
@ -66,9 +66,9 @@ func TestNewInspectCommandSuccess(t *testing.T) {
imageInspectFunc: func(image string) (types.ImageInspect, []byte, error) {
imageInspectInvocationCount++
if imageInspectInvocationCount == 1 {
assert.Equal(t, "image1", image)
assert.Check(t, is.Equal("image1", image))
} else {
assert.Equal(t, "image2", image)
assert.Check(t, is.Equal("image2", image))
}
return types.ImageInspect{}, nil, nil
},
@ -81,8 +81,8 @@ func TestNewInspectCommandSuccess(t *testing.T) {
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
err := cmd.Execute()
assert.NoError(t, err)
assert.NilError(t, err)
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("inspect-command-success.%s.golden", tc.name))
assert.Equal(t, imageInspectInvocationCount, tc.imageCount)
assert.Check(t, is.Equal(imageInspectInvocationCount, tc.imageCount))
}
}

View File

@ -7,11 +7,11 @@ import (
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
)
func TestNewImagesCommandErrors(t *testing.T) {
@ -38,7 +38,7 @@ func TestNewImagesCommandErrors(t *testing.T) {
cmd := NewImagesCommand(test.NewFakeCli(&fakeClient{imageListFunc: tc.imageListFunc}))
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -65,7 +65,7 @@ func TestNewImagesCommandSuccess(t *testing.T) {
name: "match-name",
args: []string{"image"},
imageListFunc: func(options types.ImageListOptions) ([]types.ImageSummary, error) {
assert.Equal(t, "image", options.Filters.Get("reference")[0])
assert.Check(t, is.Equal("image", options.Filters.Get("reference")[0]))
return []types.ImageSummary{{}}, nil
},
},
@ -73,7 +73,7 @@ func TestNewImagesCommandSuccess(t *testing.T) {
name: "filters",
args: []string{"--filter", "name=value"},
imageListFunc: func(options types.ImageListOptions) ([]types.ImageSummary, error) {
assert.Equal(t, "value", options.Filters.Get("name")[0])
assert.Check(t, is.Equal("value", options.Filters.Get("name")[0]))
return []types.ImageSummary{{}}, nil
},
},
@ -85,14 +85,14 @@ func TestNewImagesCommandSuccess(t *testing.T) {
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
err := cmd.Execute()
assert.NoError(t, err)
assert.NilError(t, err)
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("list-command-success.%s.golden", tc.name))
}
}
func TestNewListCommandAlias(t *testing.T) {
cmd := newListCommand(test.NewFakeCli(&fakeClient{}))
assert.True(t, cmd.HasAlias("images"))
assert.True(t, cmd.HasAlias("list"))
assert.False(t, cmd.HasAlias("other"))
assert.Check(t, cmd.HasAlias("images"))
assert.Check(t, cmd.HasAlias("list"))
assert.Check(t, !cmd.HasAlias("other"))
}

View File

@ -8,11 +8,10 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/gotestyourself/gotestyourself/assert"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
)
func TestNewLoadCommandErrors(t *testing.T) {
@ -47,7 +46,7 @@ func TestNewLoadCommandErrors(t *testing.T) {
cmd := NewLoadCommand(cli)
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -57,7 +56,7 @@ func TestNewLoadCommandInvalidInput(t *testing.T) {
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs([]string{"--input", "*"})
err := cmd.Execute()
testutil.ErrorContains(t, err, expectedError)
assert.ErrorContains(t, err, expectedError)
}
func TestNewLoadCommandSuccess(t *testing.T) {
@ -96,7 +95,7 @@ func TestNewLoadCommandSuccess(t *testing.T) {
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
err := cmd.Execute()
assert.NoError(t, err)
assert.NilError(t, err)
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("load-command-success.%s.golden", tc.name))
}
}

View File

@ -6,12 +6,12 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
)
func TestNewPruneCommandErrors(t *testing.T) {
@ -41,7 +41,7 @@ func TestNewPruneCommandErrors(t *testing.T) {
}))
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -55,7 +55,7 @@ func TestNewPruneCommandSuccess(t *testing.T) {
name: "all",
args: []string{"--all"},
imagesPruneFunc: func(pruneFilter filters.Args) (types.ImagesPruneReport, error) {
assert.Equal(t, "false", pruneFilter.Get("dangling")[0])
assert.Check(t, is.Equal("false", pruneFilter.Get("dangling")[0]))
return types.ImagesPruneReport{}, nil
},
},
@ -63,7 +63,7 @@ func TestNewPruneCommandSuccess(t *testing.T) {
name: "force-deleted",
args: []string{"--force"},
imagesPruneFunc: func(pruneFilter filters.Args) (types.ImagesPruneReport, error) {
assert.Equal(t, "true", pruneFilter.Get("dangling")[0])
assert.Check(t, is.Equal("true", pruneFilter.Get("dangling")[0]))
return types.ImagesPruneReport{
ImagesDeleted: []types.ImageDeleteResponseItem{{Deleted: "image1"}},
SpaceReclaimed: 1,
@ -74,7 +74,7 @@ func TestNewPruneCommandSuccess(t *testing.T) {
name: "force-untagged",
args: []string{"--force"},
imagesPruneFunc: func(pruneFilter filters.Args) (types.ImagesPruneReport, error) {
assert.Equal(t, "true", pruneFilter.Get("dangling")[0])
assert.Check(t, is.Equal("true", pruneFilter.Get("dangling")[0]))
return types.ImagesPruneReport{
ImagesDeleted: []types.ImageDeleteResponseItem{{Untagged: "image1"}},
SpaceReclaimed: 2,
@ -88,7 +88,7 @@ func TestNewPruneCommandSuccess(t *testing.T) {
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
err := cmd.Execute()
assert.NoError(t, err)
assert.NilError(t, err)
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("prune-command-success.%s.golden", tc.name))
}
}

View File

@ -14,9 +14,10 @@ import (
)
type pullOptions struct {
remote string
all bool
platform string
remote string
all bool
platform string
untrusted bool
}
// NewPullCommand creates a new `docker pull` command
@ -38,7 +39,7 @@ func NewPullCommand(dockerCli command.Cli) *cobra.Command {
flags.BoolVarP(&opts.all, "all-tags", "a", false, "Download all tagged images in the repository")
command.AddPlatformFlag(flags, &opts.platform)
command.AddTrustVerificationFlags(flags)
command.AddTrustVerificationFlags(flags, &opts.untrusted, dockerCli.ContentTrustEnabled())
return cmd
}
@ -58,14 +59,14 @@ func runPull(cli command.Cli, opts pullOptions) error {
}
ctx := context.Background()
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, AuthResolver(cli), distributionRef.String())
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, nil, AuthResolver(cli), distributionRef.String())
if err != nil {
return err
}
// Check if reference has a digest
_, isCanonical := distributionRef.(reference.Canonical)
if command.IsTrusted() && !isCanonical {
if !opts.untrusted && !isCanonical {
err = trustedPull(ctx, cli, imgRefAndAuth, opts.platform)
} else {
err = imagePullPrivileged(ctx, cli, imgRefAndAuth, opts.all, opts.platform)

View File

@ -8,10 +8,11 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/cli/internal/test/notary"
"github.com/docker/docker/api/types"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/stretchr/testify/assert"
)
func TestNewPullCommandErrors(t *testing.T) {
@ -41,7 +42,7 @@ func TestNewPullCommandErrors(t *testing.T) {
cmd := NewPullCommand(cli)
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -65,7 +66,7 @@ func TestNewPullCommandSuccess(t *testing.T) {
for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{
imagePullFunc: func(ref string, options types.ImagePullOptions) (io.ReadCloser, error) {
assert.Equal(t, tc.expectedTag, ref, tc.name)
assert.Check(t, is.Equal(tc.expectedTag, ref), tc.name)
return ioutil.NopCloser(strings.NewReader("")), nil
},
})
@ -73,7 +74,48 @@ func TestNewPullCommandSuccess(t *testing.T) {
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
err := cmd.Execute()
assert.NoError(t, err)
assert.NilError(t, err)
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("pull-command-success.%s.golden", tc.name))
}
}
func TestNewPullCommandWithContentTrustErrors(t *testing.T) {
testCases := []struct {
name string
args []string
expectedError string
notaryFunc test.NotaryClientFuncType
}{
{
name: "offline-notary-server",
notaryFunc: notary.GetOfflineNotaryRepository,
expectedError: "client is offline",
args: []string{"image:tag"},
},
{
name: "uninitialized-notary-server",
notaryFunc: notary.GetUninitializedNotaryRepository,
expectedError: "remote trust data does not exist",
args: []string{"image:tag"},
},
{
name: "empty-notary-server",
notaryFunc: notary.GetEmptyTargetsNotaryRepository,
expectedError: "No valid trust data for tag",
args: []string{"image:tag"},
},
}
for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{
imagePullFunc: func(ref string, options types.ImagePullOptions) (io.ReadCloser, error) {
return ioutil.NopCloser(strings.NewReader("")), fmt.Errorf("shouldn't try to pull image")
},
}, test.EnableContentTrust)
cli.SetNotaryClient(tc.notaryFunc)
cmd := NewPullCommand(cli)
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
err := cmd.Execute()
assert.ErrorContains(t, err, tc.expectedError)
}
}

View File

@ -11,26 +11,34 @@ import (
"github.com/spf13/cobra"
)
type pushOptions struct {
remote string
untrusted bool
}
// NewPushCommand creates a new `docker push` command
func NewPushCommand(dockerCli command.Cli) *cobra.Command {
var opts pushOptions
cmd := &cobra.Command{
Use: "push [OPTIONS] NAME[:TAG]",
Short: "Push an image or a repository to a registry",
Args: cli.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return runPush(dockerCli, args[0])
opts.remote = args[0]
return runPush(dockerCli, opts)
},
}
flags := cmd.Flags()
command.AddTrustSigningFlags(flags)
command.AddTrustSigningFlags(flags, &opts.untrusted, dockerCli.ContentTrustEnabled())
return cmd
}
func runPush(dockerCli command.Cli, remote string) error {
ref, err := reference.ParseNormalizedNamed(remote)
func runPush(dockerCli command.Cli, opts pushOptions) error {
ref, err := reference.ParseNormalizedNamed(opts.remote)
if err != nil {
return err
}
@ -47,7 +55,7 @@ func runPush(dockerCli command.Cli, remote string) error {
authConfig := command.ResolveAuthConfig(ctx, dockerCli, repoInfo.Index)
requestPrivilege := command.RegistryAuthenticationPrivilegedFunc(dockerCli, repoInfo.Index, "push")
if command.IsTrusted() {
if !opts.untrusted {
return TrustedPush(ctx, dockerCli, repoInfo, ref, authConfig, requestPrivilege)
}

View File

@ -7,10 +7,9 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/gotestyourself/gotestyourself/assert"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
)
func TestNewPushCommandErrors(t *testing.T) {
@ -38,18 +37,13 @@ func TestNewPushCommandErrors(t *testing.T) {
return ioutil.NopCloser(strings.NewReader("")), errors.Errorf("Failed to push")
},
},
{
name: "trust-error",
args: []string{"--disable-content-trust=false", "image:repo"},
expectedError: "you are not authorized to perform this operation: server returned 401.",
},
}
for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{imagePushFunc: tc.imagePushFunc})
cmd := NewPushCommand(cli)
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -72,6 +66,6 @@ func TestNewPushCommandSuccess(t *testing.T) {
cmd := NewPushCommand(cli)
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
}
}

View File

@ -6,11 +6,11 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
)
type notFound struct {
@ -27,9 +27,9 @@ func (n notFound) NotFound() bool {
func TestNewRemoveCommandAlias(t *testing.T) {
cmd := newRemoveCommand(test.NewFakeCli(&fakeClient{}))
assert.True(t, cmd.HasAlias("rmi"))
assert.True(t, cmd.HasAlias("remove"))
assert.False(t, cmd.HasAlias("other"))
assert.Check(t, cmd.HasAlias("rmi"))
assert.Check(t, cmd.HasAlias("remove"))
assert.Check(t, !cmd.HasAlias("other"))
}
func TestNewRemoveCommandErrors(t *testing.T) {
@ -48,7 +48,7 @@ func TestNewRemoveCommandErrors(t *testing.T) {
args: []string{"-f", "image1"},
expectedError: "error removing image",
imageRemoveFunc: func(image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error) {
assert.Equal(t, "image1", image)
assert.Check(t, is.Equal("image1", image))
return []types.ImageDeleteResponseItem{}, errors.Errorf("error removing image")
},
},
@ -57,8 +57,8 @@ func TestNewRemoveCommandErrors(t *testing.T) {
args: []string{"arg1"},
expectedError: "error removing image",
imageRemoveFunc: func(image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error) {
assert.False(t, options.Force)
assert.True(t, options.PruneChildren)
assert.Check(t, !options.Force)
assert.Check(t, options.PruneChildren)
return []types.ImageDeleteResponseItem{}, errors.Errorf("error removing image")
},
},
@ -70,7 +70,7 @@ func TestNewRemoveCommandErrors(t *testing.T) {
}))
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
})
}
}
@ -86,7 +86,7 @@ func TestNewRemoveCommandSuccess(t *testing.T) {
name: "Image Deleted",
args: []string{"image1"},
imageRemoveFunc: func(image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error) {
assert.Equal(t, "image1", image)
assert.Check(t, is.Equal("image1", image))
return []types.ImageDeleteResponseItem{{Deleted: image}}, nil
},
},
@ -94,8 +94,8 @@ func TestNewRemoveCommandSuccess(t *testing.T) {
name: "Image not found with force option",
args: []string{"-f", "image1"},
imageRemoveFunc: func(image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error) {
assert.Equal(t, "image1", image)
assert.Equal(t, true, options.Force)
assert.Check(t, is.Equal("image1", image))
assert.Check(t, is.Equal(true, options.Force))
return []types.ImageDeleteResponseItem{}, notFound{"image1"}
},
expectedStderr: "Error: No such image: image1\n",
@ -105,7 +105,7 @@ func TestNewRemoveCommandSuccess(t *testing.T) {
name: "Image Untagged",
args: []string{"image1"},
imageRemoveFunc: func(image string, options types.ImageRemoveOptions) ([]types.ImageDeleteResponseItem, error) {
assert.Equal(t, "image1", image)
assert.Check(t, is.Equal("image1", image))
return []types.ImageDeleteResponseItem{{Untagged: image}}, nil
},
},
@ -126,8 +126,8 @@ func TestNewRemoveCommandSuccess(t *testing.T) {
cmd := NewRemoveCommand(cli)
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
assert.NoError(t, cmd.Execute())
assert.Equal(t, tc.expectedStderr, cli.ErrBuffer().String())
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal(tc.expectedStderr, cli.ErrBuffer().String()))
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("remove-command-success.%s.golden", tc.name))
})
}

View File

@ -8,10 +8,9 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestNewSaveCommandErrors(t *testing.T) {
@ -54,7 +53,7 @@ func TestNewSaveCommandErrors(t *testing.T) {
cmd := NewSaveCommand(cli)
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -69,8 +68,8 @@ func TestNewSaveCommandSuccess(t *testing.T) {
args: []string{"-o", "save_tmp_file", "arg1"},
isTerminal: true,
imageSaveFunc: func(images []string) (io.ReadCloser, error) {
require.Len(t, images, 1)
assert.Equal(t, "arg1", images[0])
assert.Assert(t, is.Len(images, 1))
assert.Check(t, is.Equal("arg1", images[0]))
return ioutil.NopCloser(strings.NewReader("")), nil
},
deferredFunc: func() {
@ -81,9 +80,9 @@ func TestNewSaveCommandSuccess(t *testing.T) {
args: []string{"arg1", "arg2"},
isTerminal: false,
imageSaveFunc: func(images []string) (io.ReadCloser, error) {
require.Len(t, images, 2)
assert.Equal(t, "arg1", images[0])
assert.Equal(t, "arg2", images[1])
assert.Assert(t, is.Len(images, 2))
assert.Check(t, is.Equal("arg1", images[0]))
assert.Check(t, is.Equal("arg2", images[1]))
return ioutil.NopCloser(strings.NewReader("")), nil
},
},
@ -96,7 +95,7 @@ func TestNewSaveCommandSuccess(t *testing.T) {
}))
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(tc.args)
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
if tc.deferredFunc != nil {
tc.deferredFunc()
}

View File

@ -5,8 +5,8 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func TestCliNewTagCommandErrors(t *testing.T) {
@ -20,7 +20,7 @@ func TestCliNewTagCommandErrors(t *testing.T) {
cmd := NewTagCommand(test.NewFakeCli(&fakeClient{}))
cmd.SetArgs(args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), expectedError)
assert.ErrorContains(t, cmd.Execute(), expectedError)
}
}
@ -28,14 +28,14 @@ func TestCliNewTagCommand(t *testing.T) {
cmd := NewTagCommand(
test.NewFakeCli(&fakeClient{
imageTagFunc: func(image string, ref string) error {
assert.Equal(t, "image1", image)
assert.Equal(t, "image2", ref)
assert.Check(t, is.Equal("image1", image))
assert.Check(t, is.Equal("image2", ref))
return nil
},
}))
cmd.SetArgs([]string{"image1", "image2"})
cmd.SetOutput(ioutil.Discard)
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
value, _ := cmd.Flags().GetBool("interspersed")
assert.False(t, value)
assert.Check(t, !value)
}

View File

@ -0,0 +1,2 @@
IMAGE CREATED AT CREATED BY SIZE COMMENT
abcdef 2017-01-01T12:00:03Z rose 0 new history item!

View File

@ -198,7 +198,7 @@ func trustedPull(ctx context.Context, cli command.Cli, imgRefAndAuth trust.Image
if err != nil {
return err
}
updatedImgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, AuthResolver(cli), trustedRef.String())
updatedImgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, nil, AuthResolver(cli), trustedRef.String())
if err != nil {
return err
}
@ -293,35 +293,24 @@ func imagePullPrivileged(ctx context.Context, cli command.Cli, imgRefAndAuth tru
// TrustedReference returns the canonical trusted reference for an image reference
func TrustedReference(ctx context.Context, cli command.Cli, ref reference.NamedTagged, rs registry.Service) (reference.Canonical, error) {
var (
repoInfo *registry.RepositoryInfo
err error
)
if rs != nil {
repoInfo, err = rs.ResolveRepository(ref)
} else {
repoInfo, err = registry.ParseRepositoryInfo(ref)
}
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, rs, AuthResolver(cli), ref.String())
if err != nil {
return nil, err
}
// Resolve the Auth config relevant for this server
authConfig := command.ResolveAuthConfig(ctx, cli, repoInfo.Index)
notaryRepo, err := trust.GetNotaryRepository(cli.In(), cli.Out(), command.UserAgent(), repoInfo, &authConfig, "pull")
notaryRepo, err := cli.NotaryClient(imgRefAndAuth, []string{"pull"})
if err != nil {
return nil, errors.Wrap(err, "error establishing connection to trust repository")
}
t, err := notaryRepo.GetTargetByName(ref.Tag(), trust.ReleasesRole, data.CanonicalTargetsRole)
if err != nil {
return nil, trust.NotaryError(repoInfo.Name.Name(), err)
return nil, trust.NotaryError(imgRefAndAuth.RepoInfo().Name.Name(), err)
}
// Only list tags in the top level targets role or the releases delegation role - ignore
// all other delegation roles
if t.Role != trust.ReleasesRole && t.Role != data.CanonicalTargetsRole {
return nil, trust.NotaryError(repoInfo.Name.Name(), client.ErrNoSuchTarget(ref.Tag()))
return nil, trust.NotaryError(imgRefAndAuth.RepoInfo().Name.Name(), client.ErrNoSuchTarget(ref.Tag()))
}
r, err := convertTarget(t.Target)
if err != nil {

View File

@ -8,8 +8,7 @@ import (
"github.com/docker/cli/cli/trust"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/docker/docker/registry"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/gotestyourself/gotestyourself/assert"
"github.com/theupdateframework/notary/client"
"github.com/theupdateframework/notary/passphrase"
"github.com/theupdateframework/notary/trustpinning"
@ -64,12 +63,12 @@ func TestNonOfficialTrustServer(t *testing.T) {
func TestAddTargetToAllSignableRolesError(t *testing.T) {
tmpDir, err := ioutil.TempDir("", "notary-test-")
assert.NoError(t, err)
assert.NilError(t, err)
defer os.RemoveAll(tmpDir)
notaryRepo, err := client.NewFileCachedRepository(tmpDir, "gun", "https://localhost", nil, passphrase.ConstantRetriever("password"), trustpinning.TrustPinConfig{})
require.NoError(t, err)
assert.NilError(t, err)
target := client.Target{}
err = AddTargetToAllSignableRoles(notaryRepo, &target)
assert.EqualError(t, err, "client is offline")
assert.Error(t, err, "client is offline")
}

View File

@ -6,8 +6,8 @@ import (
"testing"
"github.com/docker/cli/templates"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
type testElement struct {
@ -243,17 +243,17 @@ func TestTemplateInspectorRawFallbackNumber(t *testing.T) {
}
b := new(bytes.Buffer)
tmpl, err := templates.Parse("{{.Size}} {{.Id}}")
require.NoError(t, err)
assert.NilError(t, err)
i := NewTemplateInspector(b, tmpl)
for _, tc := range testcases {
err = i.Inspect(typedElem, tc.raw)
require.NoError(t, err)
assert.NilError(t, err)
err = i.Flush()
require.NoError(t, err)
assert.NilError(t, err)
assert.Equal(t, tc.exp, b.String())
assert.Check(t, is.Equal(tc.exp, b.String()))
b.Reset()
}
}

View File

@ -5,10 +5,9 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestManifestAnnotateError(t *testing.T) {
@ -35,7 +34,7 @@ func TestManifestAnnotateError(t *testing.T) {
cmd := newAnnotateCommand(cli)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -48,13 +47,13 @@ func TestManifestAnnotate(t *testing.T) {
namedRef := ref(t, "alpine:3.0")
imageManifest := fullImageManifest(t, namedRef)
err := store.Save(ref(t, "list:v1"), namedRef, imageManifest)
require.NoError(t, err)
assert.NilError(t, err)
cmd := newAnnotateCommand(cli)
cmd.SetArgs([]string{"example.com/list:v1", "example.com/fake:0.0"})
cmd.SetOutput(ioutil.Discard)
expectedError := "manifest for image example.com/fake:0.0 does not exist"
testutil.ErrorContains(t, cmd.Execute(), expectedError)
assert.ErrorContains(t, cmd.Execute(), expectedError)
cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"})
cmd.Flags().Set("os", "freebsd")
@ -62,17 +61,17 @@ func TestManifestAnnotate(t *testing.T) {
cmd.Flags().Set("os-features", "feature1")
cmd.Flags().Set("variant", "v7")
expectedError = "manifest entry for image has unsupported os/arch combination"
testutil.ErrorContains(t, cmd.Execute(), expectedError)
assert.ErrorContains(t, cmd.Execute(), expectedError)
cmd.Flags().Set("arch", "arm")
require.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
cmd = newInspectCommand(cli)
err = cmd.Flags().Set("verbose", "true")
require.NoError(t, err)
assert.NilError(t, err)
cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"})
require.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
actual := cli.OutBuffer()
expected := golden.Get(t, "inspect-annotate.golden")
assert.Equal(t, string(expected), actual.String())
assert.Check(t, is.Equal(string(expected), actual.String()))
}

View File

@ -21,7 +21,7 @@ func newCreateListCommand(dockerCli command.Cli) *cobra.Command {
opts := createOpts{}
cmd := &cobra.Command{
Use: "create MANFEST_LIST MANIFEST [MANIFEST...]",
Use: "create MANIFEST_LIST MANIFEST [MANIFEST...]",
Short: "Create a local manifest list for annotating and pushing to a registry",
Args: cli.RequiresMinArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {

View File

@ -6,12 +6,11 @@ import (
manifesttypes "github.com/docker/cli/cli/manifest/types"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/distribution/reference"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/net/context"
)
@ -35,7 +34,7 @@ func TestManifestCreateErrors(t *testing.T) {
cmd := newCreateListCommand(cli)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -50,28 +49,28 @@ func TestManifestCreateAmend(t *testing.T) {
namedRef := ref(t, "alpine:3.0")
imageManifest := fullImageManifest(t, namedRef)
err := store.Save(ref(t, "list:v1"), namedRef, imageManifest)
require.NoError(t, err)
assert.NilError(t, err)
namedRef = ref(t, "alpine:3.1")
imageManifest = fullImageManifest(t, namedRef)
err = store.Save(ref(t, "list:v1"), namedRef, imageManifest)
require.NoError(t, err)
assert.NilError(t, err)
cmd := newCreateListCommand(cli)
cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.1"})
cmd.Flags().Set("amend", "true")
cmd.SetOutput(ioutil.Discard)
err = cmd.Execute()
require.NoError(t, err)
assert.NilError(t, err)
// make a new cli to clear the buffers
cli = test.NewFakeCli(nil)
cli.SetManifestStore(store)
inspectCmd := newInspectCommand(cli)
inspectCmd.SetArgs([]string{"example.com/list:v1"})
require.NoError(t, inspectCmd.Execute())
assert.NilError(t, inspectCmd.Execute())
actual := cli.OutBuffer()
expected := golden.Get(t, "inspect-manifest-list.golden")
assert.Equal(t, string(expected), actual.String())
assert.Check(t, is.Equal(string(expected), actual.String()))
}
// attempt to overwrite a saved manifest and get refused
@ -84,13 +83,13 @@ func TestManifestCreateRefuseAmend(t *testing.T) {
namedRef := ref(t, "alpine:3.0")
imageManifest := fullImageManifest(t, namedRef)
err := store.Save(ref(t, "list:v1"), namedRef, imageManifest)
require.NoError(t, err)
assert.NilError(t, err)
cmd := newCreateListCommand(cli)
cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"})
cmd.SetOutput(ioutil.Discard)
err = cmd.Execute()
assert.EqualError(t, err, "refusing to amend an existing manifest list with no --amend flag")
assert.Error(t, err, "refusing to amend an existing manifest list with no --amend flag")
}
// attempt to make a manifest list without valid images
@ -113,5 +112,5 @@ func TestManifestCreateNoManifest(t *testing.T) {
cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"})
cmd.SetOutput(ioutil.Discard)
err := cmd.Execute()
assert.EqualError(t, err, "No such image: example.com/alpine:3.0")
assert.Error(t, err, "No such image: example.com/alpine:3.0")
}

View File

@ -12,24 +12,24 @@ import (
"github.com/docker/distribution"
"github.com/docker/distribution/manifest/schema2"
"github.com/docker/distribution/reference"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/opencontainers/go-digest"
digest "github.com/opencontainers/go-digest"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/net/context"
)
func newTempManifestStore(t *testing.T) (store.Store, func()) {
tmpdir, err := ioutil.TempDir("", "test-manifest-storage")
require.NoError(t, err)
assert.NilError(t, err)
return store.NewStore(tmpdir), func() { os.RemoveAll(tmpdir) }
}
func ref(t *testing.T, name string) reference.Named {
named, err := reference.ParseNamed("example.com/" + name)
require.NoError(t, err)
assert.NilError(t, err)
return named
}
@ -49,7 +49,7 @@ func fullImageManifest(t *testing.T, ref reference.Named) types.ImageManifest {
},
},
})
require.NoError(t, err)
assert.NilError(t, err)
// TODO: include image data for verbose inspect
return types.NewImageManifest(ref, digest.Digest("sha256:7328f6f8b41890597575cbaadc884e7386ae0acc53b747401ebce5cf0d62abcd"), types.Image{OS: "linux", Architecture: "amd64"}, man)
}
@ -65,7 +65,7 @@ func TestInspectCommandLocalManifestNotFound(t *testing.T) {
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"})
err := cmd.Execute()
assert.EqualError(t, err, "No such manifest: example.com/alpine:3.0")
assert.Error(t, err, "No such manifest: example.com/alpine:3.0")
}
func TestInspectCommandNotFound(t *testing.T) {
@ -87,7 +87,7 @@ func TestInspectCommandNotFound(t *testing.T) {
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs([]string{"example.com/alpine:3.0"})
err := cmd.Execute()
assert.EqualError(t, err, "No such manifest: example.com/alpine:3.0")
assert.Error(t, err, "No such manifest: example.com/alpine:3.0")
}
func TestInspectCommandLocalManifest(t *testing.T) {
@ -99,14 +99,14 @@ func TestInspectCommandLocalManifest(t *testing.T) {
namedRef := ref(t, "alpine:3.0")
imageManifest := fullImageManifest(t, namedRef)
err := store.Save(ref(t, "list:v1"), namedRef, imageManifest)
require.NoError(t, err)
assert.NilError(t, err)
cmd := newInspectCommand(cli)
cmd.SetArgs([]string{"example.com/list:v1", "example.com/alpine:3.0"})
require.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
actual := cli.OutBuffer()
expected := golden.Get(t, "inspect-manifest.golden")
assert.Equal(t, string(expected), actual.String())
assert.Check(t, is.Equal(string(expected), actual.String()))
}
func TestInspectcommandRemoteManifest(t *testing.T) {
@ -124,8 +124,8 @@ func TestInspectcommandRemoteManifest(t *testing.T) {
cmd := newInspectCommand(cli)
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs([]string{"example.com/alpine:3.0"})
require.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
actual := cli.OutBuffer()
expected := golden.Get(t, "inspect-manifest.golden")
assert.Equal(t, string(expected), actual.String())
assert.Check(t, is.Equal(string(expected), actual.String()))
}

View File

@ -6,15 +6,14 @@ import (
manifesttypes "github.com/docker/cli/cli/manifest/types"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/distribution/reference"
"github.com/gotestyourself/gotestyourself/assert"
"github.com/pkg/errors"
"github.com/stretchr/testify/require"
"golang.org/x/net/context"
)
func newFakeRegistryClient(t *testing.T) *fakeRegistryClient {
require.NoError(t, nil)
assert.NilError(t, nil)
return &fakeRegistryClient{
getManifestFunc: func(_ context.Context, _ reference.Named) (manifesttypes.ImageManifest, error) {
@ -46,7 +45,7 @@ func TestManifestPushErrors(t *testing.T) {
cmd := newPushListCommand(cli)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -64,10 +63,10 @@ func TestManifestPush(t *testing.T) {
namedRef := ref(t, "alpine:3.0")
imageManifest := fullImageManifest(t, namedRef)
err := store.Save(ref(t, "list:v1"), namedRef, imageManifest)
require.NoError(t, err)
assert.NilError(t, err)
cmd := newPushListCommand(cli)
cmd.SetArgs([]string{"example.com/list:v1"})
err = cmd.Execute()
require.NoError(t, err)
assert.NilError(t, err)
}

View File

@ -5,10 +5,10 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types/network"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"golang.org/x/net/context"
)
@ -38,7 +38,7 @@ func TestNetworkConnectErrors(t *testing.T) {
)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -54,7 +54,7 @@ func TestNetworkConnectWithFlags(t *testing.T) {
}
cli := test.NewFakeCli(&fakeClient{
networkConnectFunc: func(ctx context.Context, networkID, container string, config *network.EndpointSettings) error {
assert.Equal(t, expectedOpts, config.IPAMConfig, "not expected driver error")
assert.Check(t, is.DeepEqual(expectedOpts, config.IPAMConfig), "not expected driver error")
return nil
},
})
@ -66,5 +66,5 @@ func TestNetworkConnectWithFlags(t *testing.T) {
cmd.Flags().Set("ip-range", "192.168.4.0/24")
cmd.Flags().Set("gateway", "192.168.4.1/24")
cmd.Flags().Set("subnet", "192.168.4.0/24")
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
}

View File

@ -6,12 +6,11 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/network"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/net/context"
)
@ -136,10 +135,10 @@ func TestNetworkCreateErrors(t *testing.T) {
)
cmd.SetArgs(tc.args)
for key, value := range tc.flags {
require.NoError(t, cmd.Flags().Set(key, value))
assert.NilError(t, cmd.Flags().Set(key, value))
}
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -155,8 +154,8 @@ func TestNetworkCreateWithFlags(t *testing.T) {
}
cli := test.NewFakeCli(&fakeClient{
networkCreateFunc: func(ctx context.Context, name string, createBody types.NetworkCreate) (types.NetworkCreateResponse, error) {
assert.Equal(t, expectedDriver, createBody.Driver, "not expected driver error")
assert.Equal(t, expectedOpts, createBody.IPAM.Config, "not expected driver error")
assert.Check(t, is.Equal(expectedDriver, createBody.Driver), "not expected driver error")
assert.Check(t, is.DeepEqual(expectedOpts, createBody.IPAM.Config), "not expected driver error")
return types.NetworkCreateResponse{
ID: name,
}, nil
@ -170,6 +169,6 @@ func TestNetworkCreateWithFlags(t *testing.T) {
cmd.Flags().Set("ip-range", "192.168.4.0/24")
cmd.Flags().Set("gateway", "192.168.4.1/24")
cmd.Flags().Set("subnet", "192.168.4.0/24")
assert.NoError(t, cmd.Execute())
assert.Equal(t, "banana", strings.TrimSpace(cli.OutBuffer().String()))
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal("banana", strings.TrimSpace(cli.OutBuffer().String())))
}

View File

@ -5,7 +5,7 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/gotestyourself/gotestyourself/assert"
"github.com/pkg/errors"
"golang.org/x/net/context"
)
@ -36,6 +36,6 @@ func TestNetworkDisconnectErrors(t *testing.T) {
)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}

View File

@ -1,20 +1,19 @@
package network
import (
"testing"
"io/ioutil"
"strings"
"testing"
"github.com/docker/cli/internal/test"
. "github.com/docker/cli/internal/test/builders"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/google/go-cmp/cmp"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"golang.org/x/net/context"
)
@ -38,23 +37,18 @@ func TestNetworkListErrors(t *testing.T) {
}),
)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
func TestNetworkListWithFlags(t *testing.T) {
filterArgs := filters.NewArgs()
filterArgs.Add("image.name", "ubuntu")
expectedOpts := types.NetworkListOptions{
Filters: filterArgs,
Filters: filters.NewArgs(filters.Arg("image.name", "ubuntu")),
}
cli := test.NewFakeCli(&fakeClient{
networkListFunc: func(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) {
assert.Equal(t, expectedOpts, options, "not expected options error")
assert.Check(t, is.DeepEqual(expectedOpts, options, cmp.AllowUnexported(filters.Args{})))
return []types.NetworkResource{*NetworkResource(NetworkResourceID("123454321"),
NetworkResourceName("network_1"),
NetworkResourceDriver("09.7.01"),
@ -64,6 +58,6 @@ func TestNetworkListWithFlags(t *testing.T) {
cmd := newListCommand(cli)
cmd.Flags().Set("filter", "image.name=ubuntu")
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, strings.TrimSpace(cli.OutBuffer().String()), "network-list.golden")
}

View File

@ -6,11 +6,10 @@ import (
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/swarm"
"github.com/gotestyourself/gotestyourself/assert"
"github.com/pkg/errors"
// Import builders to get the builder function as package function
. "github.com/docker/cli/internal/test/builders"
"github.com/docker/cli/internal/test/testutil"
"github.com/stretchr/testify/assert"
)
func TestNodeDemoteErrors(t *testing.T) {
@ -46,7 +45,7 @@ func TestNodeDemoteErrors(t *testing.T) {
}))
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -64,7 +63,7 @@ func TestNodeDemoteNoChange(t *testing.T) {
},
}))
cmd.SetArgs([]string{"nodeID"})
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
}
func TestNodeDemoteMultipleNode(t *testing.T) {
@ -81,5 +80,5 @@ func TestNodeDemoteMultipleNode(t *testing.T) {
},
}))
cmd.SetArgs([]string{"nodeID1", "nodeID2"})
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
}

View File

@ -11,9 +11,8 @@ import (
"github.com/pkg/errors"
// Import builders to get the builder function as package function
. "github.com/docker/cli/internal/test/builders"
"github.com/docker/cli/internal/test/testutil"
"github.com/gotestyourself/gotestyourself/assert"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/stretchr/testify/assert"
)
func TestNodeInspectErrors(t *testing.T) {
@ -76,7 +75,7 @@ func TestNodeInspectErrors(t *testing.T) {
cmd.Flags().Set(key, value)
}
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -113,7 +112,7 @@ func TestNodeInspectPretty(t *testing.T) {
cmd := newInspectCommand(cli)
cmd.SetArgs([]string{"nodeID"})
cmd.Flags().Set("pretty", "true")
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("node-inspect-pretty.%s.golden", tc.name))
}
}

View File

@ -8,11 +8,12 @@ import (
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/pkg/errors"
// Import builders to get the builder function as package function
. "github.com/docker/cli/internal/test/builders"
"github.com/stretchr/testify/assert"
)
func TestNodeListErrorOnAPIFailure(t *testing.T) {
@ -48,7 +49,7 @@ func TestNodeListErrorOnAPIFailure(t *testing.T) {
})
cmd := newListCommand(cli)
cmd.SetOutput(ioutil.Discard)
assert.EqualError(t, cmd.Execute(), tc.expectedError)
assert.Error(t, cmd.Execute(), tc.expectedError)
}
}
@ -71,7 +72,7 @@ func TestNodeList(t *testing.T) {
})
cmd := newListCommand(cli)
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "node-list-sort.golden")
}
@ -85,8 +86,8 @@ func TestNodeListQuietShouldOnlyPrintIDs(t *testing.T) {
})
cmd := newListCommand(cli)
cmd.Flags().Set("quiet", "true")
assert.NoError(t, cmd.Execute())
assert.Equal(t, cli.OutBuffer().String(), "nodeID1\n")
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal(cli.OutBuffer().String(), "nodeID1\n"))
}
func TestNodeListDefaultFormatFromConfig(t *testing.T) {
@ -110,7 +111,7 @@ func TestNodeListDefaultFormatFromConfig(t *testing.T) {
NodesFormat: "{{.ID}}: {{.Hostname}} {{.Status}}/{{.ManagerStatus}}",
})
cmd := newListCommand(cli)
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "node-list-format-from-config.golden")
}
@ -135,6 +136,6 @@ func TestNodeListFormat(t *testing.T) {
})
cmd := newListCommand(cli)
cmd.Flags().Set("format", "{{.Hostname}}: {{.ManagerStatus}}")
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "node-list-format-flag.golden")
}

View File

@ -6,11 +6,10 @@ import (
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/swarm"
"github.com/gotestyourself/gotestyourself/assert"
"github.com/pkg/errors"
// Import builders to get the builder function as package function
. "github.com/docker/cli/internal/test/builders"
"github.com/docker/cli/internal/test/testutil"
"github.com/stretchr/testify/assert"
)
func TestNodePromoteErrors(t *testing.T) {
@ -46,7 +45,7 @@ func TestNodePromoteErrors(t *testing.T) {
}))
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -64,7 +63,7 @@ func TestNodePromoteNoChange(t *testing.T) {
},
}))
cmd.SetArgs([]string{"nodeID"})
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
}
func TestNodePromoteMultipleNode(t *testing.T) {
@ -81,5 +80,5 @@ func TestNodePromoteMultipleNode(t *testing.T) {
},
}))
cmd.SetArgs([]string{"nodeID1", "nodeID2"})
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
}

View File

@ -12,8 +12,8 @@ import (
"github.com/pkg/errors"
// Import builders to get the builder function as package function
. "github.com/docker/cli/internal/test/builders"
"github.com/gotestyourself/gotestyourself/assert"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/stretchr/testify/assert"
)
func TestNodePsErrors(t *testing.T) {
@ -60,7 +60,7 @@ func TestNodePsErrors(t *testing.T) {
cmd.Flags().Set(key, value)
}
cmd.SetOutput(ioutil.Discard)
assert.EqualError(t, cmd.Execute(), tc.expectedError)
assert.Error(t, cmd.Execute(), tc.expectedError)
}
}
@ -122,7 +122,7 @@ func TestNodePs(t *testing.T) {
for key, value := range tc.flags {
cmd.Flags().Set(key, value)
}
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("node-ps.%s.golden", tc.name))
}
}

View File

@ -5,9 +5,8 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/gotestyourself/gotestyourself/assert"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
)
func TestNodeRemoveErrors(t *testing.T) {
@ -34,12 +33,12 @@ func TestNodeRemoveErrors(t *testing.T) {
}))
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
func TestNodeRemoveMultiple(t *testing.T) {
cmd := newRemoveCommand(test.NewFakeCli(&fakeClient{}))
cmd.SetArgs([]string{"nodeID1", "nodeID2"})
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
}

View File

@ -6,11 +6,10 @@ import (
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types/swarm"
"github.com/gotestyourself/gotestyourself/assert"
"github.com/pkg/errors"
// Import builders to get the builder function as package function
. "github.com/docker/cli/internal/test/builders"
"github.com/docker/cli/internal/test/testutil"
"github.com/stretchr/testify/assert"
)
func TestNodeUpdateErrors(t *testing.T) {
@ -66,7 +65,7 @@ func TestNodeUpdateErrors(t *testing.T) {
cmd.Flags().Set(key, value)
}
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -165,6 +164,6 @@ func TestNodeUpdate(t *testing.T) {
for key, value := range tc.flags {
cmd.Flags().Set(key, value)
}
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
}
}

View File

@ -4,17 +4,21 @@ import (
"fmt"
"io"
"io/ioutil"
"runtime"
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/fs"
"github.com/stretchr/testify/assert"
)
func TestCreateErrors(t *testing.T) {
noSuchFile := "no such file or directory"
if runtime.GOOS == "windows" {
noSuchFile = "The system cannot find the file specified."
}
testCases := []struct {
args []string
expectedError string
@ -29,7 +33,7 @@ func TestCreateErrors(t *testing.T) {
},
{
args: []string{"plugin-foo", "nonexistent_context_dir"},
expectedError: "no such file or directory",
expectedError: noSuchFile,
},
}
@ -38,7 +42,7 @@ func TestCreateErrors(t *testing.T) {
cmd := newCreateCommand(cli)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -50,7 +54,7 @@ func TestCreateErrorOnFileAsContextDir(t *testing.T) {
cmd := newCreateCommand(cli)
cmd.SetArgs([]string{"plugin-foo", tmpFile.Path()})
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), "context must be a directory")
assert.ErrorContains(t, cmd.Execute(), "context must be a directory")
}
func TestCreateErrorOnContextDirWithoutConfig(t *testing.T) {
@ -61,7 +65,12 @@ func TestCreateErrorOnContextDirWithoutConfig(t *testing.T) {
cmd := newCreateCommand(cli)
cmd.SetArgs([]string{"plugin-foo", tmpDir.Path()})
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), "config.json: no such file or directory")
expectedErr := "config.json: no such file or directory"
if runtime.GOOS == "windows" {
expectedErr = "config.json: The system cannot find the file specified."
}
assert.ErrorContains(t, cmd.Execute(), expectedErr)
}
func TestCreateErrorOnInvalidConfig(t *testing.T) {
@ -74,7 +83,7 @@ func TestCreateErrorOnInvalidConfig(t *testing.T) {
cmd := newCreateCommand(cli)
cmd.SetArgs([]string{"plugin-foo", tmpDir.Path()})
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), "invalid")
assert.ErrorContains(t, cmd.Execute(), "invalid")
}
func TestCreateErrorFromDaemon(t *testing.T) {
@ -92,7 +101,7 @@ func TestCreateErrorFromDaemon(t *testing.T) {
cmd := newCreateCommand(cli)
cmd.SetArgs([]string{"plugin-foo", tmpDir.Path()})
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), "Error creating plugin")
assert.ErrorContains(t, cmd.Execute(), "Error creating plugin")
}
func TestCreatePlugin(t *testing.T) {
@ -109,6 +118,6 @@ func TestCreatePlugin(t *testing.T) {
cmd := newCreateCommand(cli)
cmd.SetArgs([]string{"plugin-foo", tmpDir.Path()})
assert.NoError(t, cmd.Execute())
assert.Equal(t, "plugin-foo\n", cli.OutBuffer().String())
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal("plugin-foo\n", cli.OutBuffer().String()))
}

View File

@ -6,9 +6,9 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func TestPluginDisableErrors(t *testing.T) {
@ -41,7 +41,7 @@ func TestPluginDisableErrors(t *testing.T) {
}))
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -53,6 +53,6 @@ func TestPluginDisable(t *testing.T) {
})
cmd := newDisableCommand(cli)
cmd.SetArgs([]string{"plugin-foo"})
assert.NoError(t, cmd.Execute())
assert.Equal(t, "plugin-foo\n", cli.OutBuffer().String())
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal("plugin-foo\n", cli.OutBuffer().String()))
}

View File

@ -6,9 +6,9 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func TestPluginEnableErrors(t *testing.T) {
@ -52,7 +52,7 @@ func TestPluginEnableErrors(t *testing.T) {
cmd.Flags().Set(key, value)
}
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -65,6 +65,6 @@ func TestPluginEnable(t *testing.T) {
cmd := newEnableCommand(cli)
cmd.SetArgs([]string{"plugin-foo"})
assert.NoError(t, cmd.Execute())
assert.Equal(t, "plugin-foo\n", cli.OutBuffer().String())
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal("plugin-foo\n", cli.OutBuffer().String()))
}

View File

@ -24,11 +24,12 @@ type pluginOptions struct {
disable bool
args []string
skipRemoteCheck bool
untrusted bool
}
func loadPullFlags(opts *pluginOptions, flags *pflag.FlagSet) {
func loadPullFlags(dockerCli command.Cli, opts *pluginOptions, flags *pflag.FlagSet) {
flags.BoolVar(&opts.grantPerms, "grant-all-permissions", false, "Grant all permissions necessary to run the plugin")
command.AddTrustVerificationFlags(flags)
command.AddTrustVerificationFlags(flags, &opts.untrusted, dockerCli.ContentTrustEnabled())
}
func newInstallCommand(dockerCli command.Cli) *cobra.Command {
@ -47,7 +48,7 @@ func newInstallCommand(dockerCli command.Cli) *cobra.Command {
}
flags := cmd.Flags()
loadPullFlags(&options, flags)
loadPullFlags(dockerCli, &options, flags)
flags.BoolVar(&options.disable, "disable", false, "Do not enable the plugin on install")
flags.StringVar(&options.localName, "alias", "", "Local name for plugin")
return cmd
@ -90,7 +91,7 @@ func buildPullConfig(ctx context.Context, dockerCli command.Cli, opts pluginOpti
remote := ref.String()
_, isCanonical := ref.(reference.Canonical)
if command.IsTrusted() && !isCanonical {
if !opts.untrusted && !isCanonical {
ref = reference.TagNameOnly(ref)
nt, ok := ref.(reference.NamedTagged)
if !ok {

View File

@ -13,30 +13,37 @@ import (
"github.com/spf13/cobra"
)
type pushOptions struct {
name string
untrusted bool
}
func newPushCommand(dockerCli command.Cli) *cobra.Command {
var opts pushOptions
cmd := &cobra.Command{
Use: "push [OPTIONS] PLUGIN[:TAG]",
Short: "Push a plugin to a registry",
Args: cli.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
return runPush(dockerCli, args[0])
opts.name = args[0]
return runPush(dockerCli, opts)
},
}
flags := cmd.Flags()
command.AddTrustSigningFlags(flags)
command.AddTrustSigningFlags(flags, &opts.untrusted, dockerCli.ContentTrustEnabled())
return cmd
}
func runPush(dockerCli command.Cli, name string) error {
named, err := reference.ParseNormalizedNamed(name)
func runPush(dockerCli command.Cli, opts pushOptions) error {
named, err := reference.ParseNormalizedNamed(opts.name)
if err != nil {
return err
}
if _, ok := named.(reference.Canonical); ok {
return errors.Errorf("invalid name: %s", name)
return errors.Errorf("invalid name: %s", opts.name)
}
named = reference.TagNameOnly(named)
@ -60,7 +67,7 @@ func runPush(dockerCli command.Cli, name string) error {
}
defer responseBody.Close()
if command.IsTrusted() {
if !opts.untrusted {
repoInfo.Class = "plugin"
return image.PushTrustedReference(dockerCli, repoInfo, named, authConfig, responseBody)
}

View File

@ -6,9 +6,9 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func TestRemoveErrors(t *testing.T) {
@ -38,7 +38,7 @@ func TestRemoveErrors(t *testing.T) {
cmd := newRemoveCommand(cli)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -50,8 +50,8 @@ func TestRemove(t *testing.T) {
})
cmd := newRemoveCommand(cli)
cmd.SetArgs([]string{"plugin-foo"})
assert.NoError(t, cmd.Execute())
assert.Equal(t, "plugin-foo\n", cli.OutBuffer().String())
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal("plugin-foo\n", cli.OutBuffer().String()))
}
func TestRemoveWithForceOption(t *testing.T) {
@ -65,7 +65,7 @@ func TestRemoveWithForceOption(t *testing.T) {
cmd := newRemoveCommand(cli)
cmd.SetArgs([]string{"plugin-foo"})
cmd.Flags().Set("force", "true")
assert.NoError(t, cmd.Execute())
assert.True(t, force)
assert.Equal(t, "plugin-foo\n", cli.OutBuffer().String())
assert.NilError(t, cmd.Execute())
assert.Check(t, force)
assert.Check(t, is.Equal("plugin-foo\n", cli.OutBuffer().String()))
}

View File

@ -30,7 +30,7 @@ func newUpgradeCommand(dockerCli command.Cli) *cobra.Command {
}
flags := cmd.Flags()
loadPullFlags(&options, flags)
loadPullFlags(dockerCli, &options, flags)
flags.BoolVar(&options.skipRemoteCheck, "skip-remote-check", false, "Do not check if specified remote plugin matches existing plugin image")
return cmd
}

View File

@ -3,8 +3,9 @@ package command_test
import (
"testing"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"golang.org/x/net/context"
// Prevents a circular import with "github.com/docker/cli/internal/test"
@ -64,12 +65,12 @@ func TestElectAuthServer(t *testing.T) {
for _, tc := range testCases {
cli := test.NewFakeCli(&fakeClient{infoFunc: tc.infoFunc})
server := ElectAuthServer(context.Background(), cli)
assert.Equal(t, tc.expectedAuthServer, server)
assert.Check(t, is.Equal(tc.expectedAuthServer, server))
actual := cli.ErrBuffer().String()
if tc.expectedWarning == "" {
assert.Empty(t, actual)
assert.Check(t, is.Len(actual, 0))
} else {
assert.Contains(t, actual, tc.expectedWarning)
assert.Check(t, is.Contains(actual, tc.expectedWarning))
}
}
}

View File

@ -8,11 +8,11 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
)
const secretDataFile = "secret-create-with-name.golden"
@ -45,14 +45,14 @@ func TestSecretCreateErrors(t *testing.T) {
)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
func TestSecretCreateWithName(t *testing.T) {
name := "foo"
data, err := ioutil.ReadFile(filepath.Join("testdata", secretDataFile))
assert.NoError(t, err)
assert.NilError(t, err)
expected := swarm.SecretSpec{
Annotations: swarm.Annotations{
@ -75,8 +75,8 @@ func TestSecretCreateWithName(t *testing.T) {
cmd := newSecretCreateCommand(cli)
cmd.SetArgs([]string{name, filepath.Join("testdata", secretDataFile)})
assert.NoError(t, cmd.Execute())
assert.Equal(t, "ID-"+name, strings.TrimSpace(cli.OutBuffer().String()))
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal("ID-"+name, strings.TrimSpace(cli.OutBuffer().String())))
}
func TestSecretCreateWithDriver(t *testing.T) {
@ -104,8 +104,8 @@ func TestSecretCreateWithDriver(t *testing.T) {
cmd := newSecretCreateCommand(cli)
cmd.SetArgs([]string{name})
cmd.Flags().Set("driver", expectedDriver.Name)
assert.NoError(t, cmd.Execute())
assert.Equal(t, "ID-"+name, strings.TrimSpace(cli.OutBuffer().String()))
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal("ID-"+name, strings.TrimSpace(cli.OutBuffer().String())))
}
func TestSecretCreateWithTemplatingDriver(t *testing.T) {
@ -133,8 +133,8 @@ func TestSecretCreateWithTemplatingDriver(t *testing.T) {
cmd := newSecretCreateCommand(cli)
cmd.SetArgs([]string{name})
cmd.Flags().Set("template-driver", expectedDriver.Name)
assert.NoError(t, cmd.Execute())
assert.Equal(t, "ID-"+name, strings.TrimSpace(cli.OutBuffer().String()))
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal("ID-"+name, strings.TrimSpace(cli.OutBuffer().String())))
}
func TestSecretCreateWithLabels(t *testing.T) {
@ -164,6 +164,6 @@ func TestSecretCreateWithLabels(t *testing.T) {
cmd.SetArgs([]string{name, filepath.Join("testdata", secretDataFile)})
cmd.Flags().Set("label", "lbl1=Label-foo")
cmd.Flags().Set("label", "lbl2=Label-bar")
assert.NoError(t, cmd.Execute())
assert.Equal(t, "ID-"+name, strings.TrimSpace(cli.OutBuffer().String()))
assert.NilError(t, cmd.Execute())
assert.Check(t, is.Equal("ID-"+name, strings.TrimSpace(cli.OutBuffer().String())))
}

View File

@ -11,9 +11,8 @@ import (
"github.com/pkg/errors"
// Import builders to get the builder function as package function
. "github.com/docker/cli/internal/test/builders"
"github.com/docker/cli/internal/test/testutil"
"github.com/gotestyourself/gotestyourself/assert"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/stretchr/testify/assert"
)
func TestSecretInspectErrors(t *testing.T) {
@ -62,7 +61,7 @@ func TestSecretInspectErrors(t *testing.T) {
cmd.Flags().Set(key, value)
}
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -98,7 +97,7 @@ func TestSecretInspectWithoutFormat(t *testing.T) {
})
cmd := newSecretInspectCommand(cli)
cmd.SetArgs(tc.args)
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("secret-inspect-without-format.%s.golden", tc.name))
}
}
@ -135,7 +134,7 @@ func TestSecretInspectWithFormat(t *testing.T) {
cmd := newSecretInspectCommand(cli)
cmd.SetArgs(tc.args)
cmd.Flags().Set("format", tc.format)
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("secret-inspect-with-format.%s.golden", tc.name))
}
}
@ -168,7 +167,7 @@ func TestSecretInspectPretty(t *testing.T) {
cmd := newSecretInspectCommand(cli)
cmd.SetArgs([]string{"secretID"})
cmd.Flags().Set("pretty", "true")
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), fmt.Sprintf("secret-inspect-pretty.%s.golden", tc.name))
}
}

View File

@ -12,9 +12,9 @@ import (
"github.com/pkg/errors"
// Import builders to get the builder function as package function
. "github.com/docker/cli/internal/test/builders"
"github.com/docker/cli/internal/test/testutil"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/stretchr/testify/assert"
)
func TestSecretListErrors(t *testing.T) {
@ -42,7 +42,7 @@ func TestSecretListErrors(t *testing.T) {
)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -74,7 +74,7 @@ func TestSecretList(t *testing.T) {
},
})
cmd := newSecretListCommand(cli)
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "secret-list-sort.golden")
}
@ -91,7 +91,7 @@ func TestSecretListWithQuietOption(t *testing.T) {
})
cmd := newSecretListCommand(cli)
cmd.Flags().Set("quiet", "true")
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "secret-list-with-quiet-option.golden")
}
@ -110,7 +110,7 @@ func TestSecretListWithConfigFormat(t *testing.T) {
SecretFormat: "{{ .Name }} {{ .Labels }}",
})
cmd := newSecretListCommand(cli)
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "secret-list-with-config-format.golden")
}
@ -127,15 +127,15 @@ func TestSecretListWithFormat(t *testing.T) {
})
cmd := newSecretListCommand(cli)
cmd.Flags().Set("format", "{{ .Name }} {{ .Labels }}")
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "secret-list-with-format.golden")
}
func TestSecretListWithFilter(t *testing.T) {
cli := test.NewFakeCli(&fakeClient{
secretListFunc: func(options types.SecretListOptions) ([]swarm.Secret, error) {
assert.Equal(t, "foo", options.Filters.Get("name")[0], "foo")
assert.Equal(t, "lbl1=Label-bar", options.Filters.Get("label")[0])
assert.Check(t, is.Equal("foo", options.Filters.Get("name")[0]), "foo")
assert.Check(t, is.Equal("lbl1=Label-bar", options.Filters.Get("label")[0]))
return []swarm.Secret{
*Secret(SecretID("ID-foo"),
SecretName("foo"),
@ -155,6 +155,6 @@ func TestSecretListWithFilter(t *testing.T) {
cmd := newSecretListCommand(cli)
cmd.Flags().Set("filter", "name=foo")
cmd.Flags().Set("filter", "label=lbl1=Label-bar")
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "secret-list-with-filter.golden")
}

View File

@ -6,9 +6,9 @@ import (
"testing"
"github.com/docker/cli/internal/test"
"github.com/docker/cli/internal/test/testutil"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
)
func TestSecretRemoveErrors(t *testing.T) {
@ -37,7 +37,7 @@ func TestSecretRemoveErrors(t *testing.T) {
)
cmd.SetArgs(tc.args)
cmd.SetOutput(ioutil.Discard)
testutil.ErrorContains(t, cmd.Execute(), tc.expectedError)
assert.ErrorContains(t, cmd.Execute(), tc.expectedError)
}
}
@ -52,9 +52,9 @@ func TestSecretRemoveWithName(t *testing.T) {
})
cmd := newSecretRemoveCommand(cli)
cmd.SetArgs(names)
assert.NoError(t, cmd.Execute())
assert.Equal(t, names, strings.Split(strings.TrimSpace(cli.OutBuffer().String()), "\n"))
assert.Equal(t, names, removedSecrets)
assert.NilError(t, cmd.Execute())
assert.Check(t, is.DeepEqual(names, strings.Split(strings.TrimSpace(cli.OutBuffer().String()), "\n")))
assert.Check(t, is.DeepEqual(names, removedSecrets))
}
func TestSecretRemoveContinueAfterError(t *testing.T) {
@ -74,6 +74,6 @@ func TestSecretRemoveContinueAfterError(t *testing.T) {
cmd := newSecretRemoveCommand(cli)
cmd.SetOutput(ioutil.Discard)
cmd.SetArgs(names)
assert.EqualError(t, cmd.Execute(), "error removing secret: foo")
assert.Equal(t, names, removedSecrets)
assert.Error(t, cmd.Execute(), "error removing secret: foo")
assert.Check(t, is.DeepEqual(names, removedSecrets))
}

View File

@ -3,7 +3,8 @@ package service
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func TestValidateSingleGenericResource(t *testing.T) {
@ -12,11 +13,11 @@ func TestValidateSingleGenericResource(t *testing.T) {
for _, v := range incorrect {
_, err := ValidateSingleGenericResource(v)
assert.Error(t, err)
assert.Check(t, is.ErrorContains(err, ""))
}
for _, v := range correct {
_, err := ValidateSingleGenericResource(v)
assert.NoError(t, err)
assert.NilError(t, err)
}
}

View File

@ -10,7 +10,8 @@ import (
"github.com/docker/cli/cli/command/formatter"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"github.com/stretchr/testify/assert"
"github.com/gotestyourself/gotestyourself/assert"
is "github.com/gotestyourself/gotestyourself/assert/cmp"
)
func formatServiceInspect(t *testing.T, format formatter.Format, now time.Time) string {
@ -130,5 +131,5 @@ func TestJSONFormatWithNoUpdateConfig(t *testing.T) {
if err := json.Unmarshal([]byte(s2), &m2); err != nil {
t.Fatal(err)
}
assert.Equal(t, m1, m2)
assert.Check(t, is.DeepEqual(m1, m2))
}

View File

@ -6,8 +6,8 @@ import (
"github.com/docker/cli/internal/test"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/swarm"
"github.com/gotestyourself/gotestyourself/assert"
"github.com/gotestyourself/gotestyourself/golden"
"github.com/stretchr/testify/assert"
"golang.org/x/net/context"
)
@ -23,6 +23,6 @@ func TestServiceListOrder(t *testing.T) {
})
cmd := newListCommand(cli)
cmd.Flags().Set("format", "{{.Name}}")
assert.NoError(t, cmd.Execute())
assert.NilError(t, cmd.Execute())
golden.Assert(t, cli.OutBuffer().String(), "service-list-sort.golden")
}

Some files were not shown because too many files have changed in this diff Show More