Compare commits

..

170 Commits

Author SHA1 Message Date
9ee9f402cd Merge pull request #75 from andrewhsu/v3
[18.03] bump version to 18.03.1-ce
2018-04-25 21:27:49 -07:00
c32349b9a9 Merge pull request #77 from andrewhsu/c3
[18.03] update changelog for 18.03.1-ce
2018-04-25 21:27:33 -07:00
6d0d01b238 Merge pull request #74 from andrewhsu/c03
[18.03] vndr hcsshim to 79062a5
2018-04-25 17:51:37 -07:00
fda40de70c update changelog for 18.03.1-ce
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
2018-04-26 00:22:09 +00:00
fdb8850492 bump version to 18.03.1-ce
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
2018-04-26 00:15:38 +00:00
56e55727a8 vndr hcsshim to 79062a5
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
2018-04-25 22:09:31 +00:00
fcdc984cfd Merge pull request #517 from jose-bigio/18.03_version_bump
[18.03] version bump to 18.03.1-ce-rc2
2018-04-18 23:23:53 -07:00
8921f8bec1 Merge pull request #518 from jose-bigio/18.03_changelog
[18.03] Update changelog for 18.03.1
2018-04-18 23:23:35 -07:00
6f1fe53965 fixup changelog
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
2018-04-19 06:22:38 +00:00
af03317180 Merge pull request #507 from thaJeztah/18.03-backport-plugin_exec_fixes
[18.03] Make sure plugin container is removed on failure
2018-04-18 21:53:37 -07:00
76cbc5d636 Merge pull request #509 from cpuguy83/18.03_backport_authz_buffer_fix_36595
[18.03] backport authz buffer fix
2018-04-18 20:42:44 -07:00
14b513f77d Merge pull request #520 from thaJeztah/18.03-backport-libcontainerd_client_locking
[18.03] Relax global client lock on containerd restore.
2018-04-18 20:35:00 -07:00
a78f916dfb Add more updates for 18.03.1-ce
Signed-off-by: Eli Uriegas <eli.uriegas@docker.com>
2018-04-19 00:25:35 +00:00
be3f367578 Merge pull request #515 from thaJeztah/18.03-backport-election
[18.03] Increase raft ElectionTick to 10xHeartbeatTick
2018-04-18 17:01:37 -07:00
db5f5c037d Merge pull request #516 from thaJeztah/18.03-backport-booo
[18.03] Don't make container mount unbindable
2018-04-18 17:01:03 -07:00
905f71561a Relax global client lock on containerd restore.
This unblocks the client to take other restore requests and makes sure
that a long/stuck request can't block the client forever.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
(cherry picked from commit 806700e410a1b30aa1033d71d825e57880c75298)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-18 16:49:38 -07:00
60dc869e44 Limit authz response buffer
When the authz response buffer limit is hit, perform a flush.
This prevents excessive buffer sizes, especially on large responses
(e.g. `/containers/<id>/archive` or `/containers/<id>/export`).

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
(cherry picked from commit 74f8e47352e71aad4015d8d9dea8f16e7a055863)
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-18 16:27:50 -07:00
ce2f874741 Make sure plugin container is removed on failure
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
(cherry picked from commit f81172b9031160218e51fb2a7dbeee19962a60a9)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-18 16:24:51 -07:00
e79a05793b Merge pull request #513 from thaJeztah/18.03-backport-test-improvements
[18.03] Updates to integration tests, migrate to "gotestyourself"
2018-04-18 16:19:12 -07:00
4fd6bf8c4a Merge pull request #514 from thaJeztah/18.03-bump-libnetwork
[18.03] Update libnetwork
2018-04-18 15:44:33 -07:00
3d5ce4f418 Merge pull request #477 from thaJeztah/18.03-distribution-cache
[18.03] fix(distribution): digest cache should not be moved if it was an auth error
2018-04-18 15:27:38 -07:00
edee73b51b Merge pull request #511 from thaJeztah/18.03-backport-fix-stack-deploy-after-force
[18.03] Fix stack deploy re-deploying service after --force
2018-04-18 14:48:17 -07:00
02e93e419f Merge pull request #479 from thaJeztah/18.03-err_return
[18.03] Add missing error return for plugin creation.
2018-04-18 14:47:52 -07:00
68acf3c023 Merge pull request #468 from thaJeztah/18.03-do-not-panic
[18.03] ExportContainer: do not panic
2018-04-18 14:47:18 -07:00
b522d934b9 Merge pull request #498 from thaJeztah/18.03-backport-fix-version-output
[18.03] Fix docker version output alignment
2018-04-18 14:46:15 -07:00
029cfa0956 Merge pull request #519 from thaJeztah/18.03-backport-docs-fixes
[18.03] backport docs and completion fixes
2018-04-18 14:45:46 -07:00
da69d9e253 Add bash completion for secret|config create --template-driver
Signed-off-by: Harald Albers <github@albersweb.de>
(cherry picked from commit 43024e2d57)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-18 10:18:01 -07:00
79e8ae0e9d docker load: Typofix in examples
Remove the double "docker docker" from example

Signed-off-by: Henry Ne <henrynmail-github@yahoo.de>
(cherry picked from commit 79c489d812)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-18 10:17:55 -07:00
39f7e7efd0 build.md: Document --build-arg without value
This use case is currently _working correctly_, which is nice, but there is no documentation to be found about it. This PR fixes that.

Signed-off-by: Per Lundberg <perlun@gmail.com>
(cherry picked from commit 82c23208ee)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-18 10:17:50 -07:00
766c24e554 Update examples to reflect docker-runc's runtime root for plugins.
Signed-off-by: Anusha Ragunathan <anusha.ragunathan@docker.com>
(cherry picked from commit 5fd9eab3d0)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-18 10:17:44 -07:00
4e72a2fd51 Fix --format example for docker history
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 2f7bf40e73)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-18 10:17:39 -07:00
24306165c5 Use printf, not echo when creating secrets
Update the docs so that users don't use `echo` when creating
secrets from STDIN. `echo` adds a trailing new line, so users
will probably be confused when their passwords don't work.

Signed-off-by: Joao Fernandes <joao.fernandes@docker.com>
(cherry picked from commit 5238f3e93e)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-18 10:17:33 -07:00
27540de1ad Update build.md
Explicitly stated that you must add --build-arg for each build argument.
Added multiple arguments to example of `--build-arg` usage.
Fix for https://github.com/docker/docker.github.io/issues/6248

Signed-off-by: Preston Cowley <cowlinator@gmail.com>
(cherry picked from commit ad44e2d45e)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-18 10:17:26 -07:00
1df656a2f0 Clarify behaviour of restart policy in run ref doc
This clarifies that the behaviour of `unless-stopped` will restart the container on daemon start.  This was implied before, but now the restart-on-daemon-start behaviour is mentioned directly.

Signed-off-by: David Beitey <david@davidjb.com>
(cherry picked from commit 8ca237054f)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-18 10:17:18 -07:00
bb68afd0fc Docs touch-ups for "autoremove" and broken anchor
`--rm` moved to the daemon, so is now also supported
when combined with `-d`.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit e9ce688d6e)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-18 10:17:11 -07:00
35fc88bcd9 Update changelog for 18.03.1
Signed-off-by: jose-bigio <jose.bigio@docker.com>
2018-04-18 09:51:43 -07:00
b45862f481 Version bum to 18.03.1-ce-rc2
Signed-off-by: jose-bigio <jose.bigio@docker.com>
2018-04-18 09:17:16 -07:00
72f31848f8 Don't make container mount unbindable
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
(cherry picked from commit 4c000662feb3c8e3d63cbcb044a47f627cd9bb45)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 23:55:02 -07:00
0e66a94980 Increase raft ElectionTick to 10xHeartbeatTick
Signed-off-by: Anshul Pundir <anshul.pundir@docker.com>
(cherry picked from commit 6abee2008b314a65553202b15d9a333d171e3433)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 23:43:11 -07:00
85143bcb4d Bump libnetwork commit
Full diff
5c1218c956...c15b372ef2

Fixes a panic on concurrent read/write to a map.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
(cherry picked from commit 248aed5766ba330ab8cb2b10b03b6ce57dc64283)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 19:24:33 -07:00
a4b56ba187 update libnetwork to improve scalabiltiy of bridge network isolation rules
* libnetwork#2121: Retry other external DNS servers on ServFail
* libnetwork#2125: Fix README flag and expose orphan network peers
* libnetwork#2126: Adding goreport card
* libnetwork#2130: Modify awk to use cut in check_ip_overlap
* libnetwork#2117: [Carry 1534] Improve scalabiltiy of bridge network isolation rules

Full changes: 2bf63300c5...5c1218c956

Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
(cherry picked from commit b159da19734269c4a162763ebfa28dff07b703f3)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 19:24:27 -07:00
5a884e1a0d Remove (now) extra call to sb.DisableService()
This call was added as part of commit a042e5a20 and at the time was
useful.  sandbox.DisableService() basically calls
endpoint.deleteServiceInfoFromCluster() for every endpoint in the
sandbox.  However, with the libnetwork change, endpoint.sbLeave()
invokes endpoint.deleteServiceInfoFromCluster(). The releaseNetwork()
call invokes sandbox.Delete() immediately after
sandbox.DisableService().  The sandbox.Delete() in turn ultimately
invokes endpoint.sbLeave() for every endpoint in the sandbox which thus
removes the endpoint's load balancing entry via
endpoint.deleteServiceInfoFromCluster().  So the call to
sandbox.DisableService() is now redundant.

It is noteworthy that, while redundant, the presence of the call would
not cause errors.  It would just be sub-optimal.  The DisableService()
call would cause libnetwork to down-weight the load balancing entries
while the call to sandbox.Delete() would cause it to remove the entries
immediately afterwards.  Aside from the wasted computation, the extra
call would also propagate an extra state change in the networkDB gossip
messages.  So, overall, it is much better to just avoid the extra
overhead.

Signed-off-by: Chris Telfer <ctelfer@docker.com>
(cherry picked from commit c27417aa7de46daa415600b39fc8a9c411c8c493)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 19:24:20 -07:00
0fae0d5a40 Import libnetwork fix for rolling updates
This patch allows endpoints to complete servicing connections while
being removed from a service.  The fix is entirely within libnetwork
and requires no changes to the moby codebase proper.  It operates
by initially down-weighting a container endpoint in the load balancer
to 0 while keeping the endpoint present in the load balancer.  This
allows traffic to continue to flow to the endpoint while preventing new
connections from going to the endpoint.  This allows the container
to complete requests during the "stop_grace_period" and then exit when
finished without interruption of service.

This change requires propagating the status of disabled service
endpoints via the networkDB.  Accordingly, the patch includes both code
to generate and handle service update messages.  It also augments the
service structure with a ServiceDisabled boolean to convey whether an
endpoint should ultimately be removed or just disabled.  This,
naturally, required a rebuild of the protocol buffer code.

The protocol buffer encoding is designed to support additions of fields
to messages in a backwards-compatible manner.  Protocol buffer
unmarshalling code automatically skips past any fields that it isn't
aware of.  As a result, an older moby daemon without this fix can
receive and will process correctly networkDB messages from newer moby
daemons with this patch.

As it turns out, the additional field is simply a bool that is otherwise
irrelevent on networkDB create and delete events.  So its absence in
older moby daemon processing has no impact.  However, the fix leverages
the "update" networkDB message which was previously unused in
libnetwork.  Although older libnetwork implementations parse the message
cleanly, they will see the message as unexpected and as such issue a log
at error level indicating the receipt of such.

Other than this there should be no other negative impact for use of this
patch in mixed environments. (Although older mobys won't be able to
gracefully downgrade connections on their nodes of course.)

Signed-off-by: Chris Telfer <ctelfer@docker.com>
(cherry picked from commit 50dbdeff9fd186bb0e9926996436e1f56529a831)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 19:24:13 -07:00
608b278d01 Fix a misused network object name
A minor nit. `test01` never been created and used in
`TestDockerNetworkInspectCustomSpecified()` function, so correct it.

Signed-off-by: Dennis Chen <dennis.chen@arm.com>
(cherry picked from commit f041953d04bffa2be05466173f02dd016c68286d)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 19:11:29 -07:00
faccf7d3a7 remove the retries for service update
Signed-off-by: Anda Xu <anda.xu@docker.com>
(cherry picked from commit 7380935331f0c35315003578258f6c1f47c1a586)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 19:08:23 -07:00
04b5ed6c10 Migrate image tag tests from integration-cli to api tests
This fix migrates image tag tests from integration-cli to api tests.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
(cherry picked from commit 9bcb960508a6066811cffcca1e35ca44d7f1cf94)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 19:06:13 -07:00
7974841233 Move fakecontext, fakegit and fakestorage to internal/test
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 062564084a22f71cf5807ae5dfad7d29afb12e04)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 18:42:10 -07:00
f70c483990 Some enhancement in integration tests
This fix converts some `client.ContainerCreate` to `container.Create`,
and removes some unneeded `name` fields when test containers are created.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
(cherry picked from commit ab9bb47b05b1dde445a5e4ba78ae97303208dc8b)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 18:34:06 -07:00
49acaa1f03 Small daemon refactoring and add swarm init/join helpers
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 239a8a518904dfb51fe62087d8702519c20ce808)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 18:33:54 -07:00
09fa7b76b7 Migrate test-integration-cli experimental build tests to integration
All `docker build` tests that require an `ExperimentalDaemon` are
migrated to `integration/build` package and start an experimental
daemon to test on it.

The end goal being to remove the `experimental` builds.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 183076e89df64928bd2e94ad0da9725b482367cd)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 18:33:46 -07:00
b11c120bdf Clean some integration-cli/fixtures package/files
- Move go package used by both `integration-cli` and `integration` to
  `internal/test/fixtures`.
- Remove fixtures that are not used anymore (moved to `docker/cli` a
  while ago) : deploy, notary, secrets.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 5f56503f583f21d655394f755f71849381bd58c7)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 18:29:31 -07:00
f160c829fb Move and refactor integration-cli/registry to internal/test
- Move the code from `integration-cli` to `internal/test`.
- Use `testingT` and `assert` when creating the registry.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 66de2e6e3b6d927a3396743cd7c363aa9f7b776e)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 18:29:23 -07:00
fa03812525 Move ipvlan and macvlan tests on their own folder…
… making each folder/suites quicker to run

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit a3323d2e4349b7e8d449c6e571ca3d4aa3e53d63)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 18:24:06 -07:00
997850a2f2 Refactor macvlan tests a bit
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 0ab6116ce868a0fc671a49a89696e3a1ce35e26d)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 18:23:56 -07:00
cb93f50ae0 Migrate test-integration-cli experimental ipvlan test to integration
All `Ipvlan` related test on `DockerSuite` and `DockerNetworkSuite`
are migrated to `ipvlan_test.go`.

The end goal being to remove the `experimental` builds.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 24f934751120ea420b7ba4d2e314df805f3eff06)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 18:23:46 -07:00
174c840b96 Make internal/test/daemon.Daemon swarm aware
This remove the daemon.Swarm construction by make the new test Daemon
struct aware of swarm.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 83d18cf4e3e84055f7034816eed2a10c04e777ca)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 18:23:34 -07:00
e0b31bfb7b Using the default PollSettings function
Using the default PollSettings functions to adjust the timeout
value instead of changing the value each time when needed.

Signed-off-by: Dennis Chen <dennis.chen@arm.com>
(cherry picked from commit b8912feeffcdfd489c9fc1212277840adac2719c)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 18:23:21 -07:00
176c10200c Add default pollSettings adjustment routines
Add the default function per resource to override the `pollSettings`
which will be re-used where it's needed.

Signed-off-by: Dennis Chen <dennis.chen@arm.com>
(cherry picked from commit ee6959addc5664a5c55765f2c721f84414ea4779)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 18:23:13 -07:00
16e1ab0f89 Fix for Flaky test TestServiceWithPredefinedNetwork
TestServiceWithPredefinedNetwork test case was failing
	at times. To fix the issue, added new API to check
	for services after we clean up all services. Tested
	multiple times and this sould fix flaky issue.

Signed-off-by: selansen <elango.siva@docker.com>
(cherry picked from commit dabffd806c98ab13dbc25e57bee21c5291b9a50c)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 18:23:01 -07:00
1776b7beed Move integration-cli daemon package to internal/test…
… and do not use the `docker` cli in it. One of the reason of this
move is to not make `integration` package using legacy
`integration-cli` package.

Next move will be to support swarm within this package *and* provide
some helper function using the api (compared to the one using cli in
`integration-cli/daemon` package).

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit f0d277fe84a72b29c0d2d541c20d5a9c4d7e4884)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 18:14:34 -07:00
362aa8f58a Migrate test-integration-cli experimental macvlan test to integration
All `Macvlan` related test on `DockerSuite` and `DockerNetworkSuite`
are migrated to `macvlan_test.go`.

Also, as `macvlan` seems to be out of experimental, this removes
the *skip* when the run is not experimental (and doesn't start a
daemon with experimental either).

The end goal being to remove the `experimental` builds.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit ef5bc603266b9fa5df525319d67329ebc14a8ee7)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 18:14:14 -07:00
2c0117e268 Network testing with busybox:glibc
Using the `busybox:glibc` instead of `busybox:latest` to the
network related test cases (`ping` issue).

Signed-off-by: Dennis Chen <dennis.chen@arm.com>
(cherry picked from commit 0d31dee5ec724731607e277a415b1ca4ecb7b2c4)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 18:14:03 -07:00
a29f2e130f Add busybox:latest into the frozen images
Adding `busybox:latest` and `busybox:glibc` as the frozen images

Signed-off-by: Dennis Chen <dennis.chen@arm.com>
(cherry picked from commit 3ae45c5f173d88ba621116f9e1b5611fe687e050)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 18:13:56 -07:00
34e1feb36b Skip some tests in certain condition to run with e2e image
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit e55d6fc8573580f6eea009cd7f1034aa912128ef)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 17:59:41 -07:00
23752adb2d use unique names for resources used by integration tests container/inspect_test, container/ps_test, container/stop_test
Signed-off-by: Arash Deshmeh <adeshmeh@ca.ibm.com>
(cherry picked from commit 78e4be91332e2237c0fa14eb3ba0fb5b915c3256)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 17:46:26 -07:00
69f0e0e720 integration/*: make e2e run without failure
… mainly by skipping if daemon is remote.

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 6016e79d2552b21643f4bfd093ce76d8ef956d79)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 17:39:11 -07:00
33df5137f7 Update e2e script
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 4bb0f24716f45ac520e73a52d7d7ca2752cabd31)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 17:39:01 -07:00
612f972789 integration/TestContainerShmNoLeak: use --iptables=false
As mentioned in commit 9e31938, test cases that use t.Parallel()
and start a docker daemon might step on each other toes as they
try to configure iptables during startup, resulting in flaky tests.

To avoid this, --iptables=false should be used while starting daemon.

Fixes: eaa5192856c1 ("Make container resource mounts unbindable")
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit c125e10a0486623ba3badebf974ea6e582373151)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 17:29:43 -07:00
f03b3e54d7 Update testing doc
Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit 58de6277821698a2f97d1a0c83664ab34ff2e8d8)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 17:29:34 -07:00
dc814f391e Cleanup pkg/jsonmessage progress tests
Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit 7d8815ea705e85a73248b5d9e468f9dc65277bb8)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 17:29:28 -07:00
cb1f6242ed Post migration assertion fixes
Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit c9e52bd0da0461e605a3678b85702f83081504a7)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 17:29:22 -07:00
03ad49ebec Automated migration using
gty-migrate-from-testify --ignore-build-tags

Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit 6be0f709830113966f295401327b027ec2f0bbca)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 17:28:49 -07:00
2ad8904abb Update vendor
Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit 073963e3b770efbdf8bd4b4f92d46b2c62eaf434)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 17:27:37 -07:00
a415a11279 Cleanup some assertions
Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit ef01dea8935932486f03a37069720987e805dce6)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 17:27:29 -07:00
c4adb3c164 Add missing error return for plugin creation.
Signed-off-by: Anusha Ragunathan <anusha.ragunathan@docker.com>
(cherry picked from commit 89a882e2f1706e567a8514209701892b40da7a62)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 16:15:07 -07:00
3ca5c31d84 fix(distribution): digest cache should not be moved if it was an auth
error

local digest cache will be removed when error occured on push image
but it should not be removed if it is an auth error while on auth was
provided

https://github.com/moby/moby/issues/36309
Signed-off-by: 慕陶 <jihui.xjh@alibaba-inc.com>
(cherry picked from commit 8b387b165ab2eaab3f9fdac25caa186d05d236a0)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 16:11:13 -07:00
a978050d4f Windows: Fix Hyper-V containers regression from 36586
Signed-off-by: John Howard <jhoward@microsoft.com>
(cherry picked from commit 0f5fe3f9cf17457761dab28473ece5a7c94f4a0c)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 15:12:38 -07:00
3c896e300b integration/TestExportContainerAfterDaemonRestart: add
This test case checks that a container created before start
of the currently running dockerd can be exported (as reported
in #36561). To satisfy this condition, either a pre-existing
container is required, or a daemon restart after container
creation.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 6e7141c7a2c0de6fa3d6c9dcc56978a81f9d835e)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 15:12:26 -07:00
46ad9721ef container.BaseFS: check for nil before deref
Commit 7a7357dae1bccc ("LCOW: Implemented support for docker cp + build")
changed `container.BaseFS` from being a string (that could be empty but
can't lead to nil pointer dereference) to containerfs.ContainerFS,
which could be be `nil` and so nil dereference is at least theoretically
possible, which leads to panic (i.e. engine crashes).

Such a panic can be avoided by carefully analysing the source code in all
the places that dereference a variable, to make the variable can't be nil.
Practically, this analisys are impossible as code is constantly
evolving.

Still, we need to avoid panics and crashes. A good way to do so is to
explicitly check that a variable is non-nil, returning an error
otherwise. Even in case such a check looks absolutely redundant,
further changes to the code might make it useful, and having an
extra check is not a big price to pay to avoid a panic.

This commit adds such checks for all the places where it is not obvious
that container.BaseFS is not nil (which in this case means we do not
call daemon.Mount() a few lines earlier).

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit d6ea46cedaca0098c15843c5254a337d087f5cd6)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 15:09:12 -07:00
c9c8799088 daemon.ContainerExport(): do not panic
In case ContainerExport() is called for an unmounted container, it leads
to a daemon panic as container.BaseFS, which is dereferenced here, is
nil.

To fix, do not rely on container.BaseFS; use the one returned from
rwlayer.Mount().

Fixes: 7a7357dae1bccc ("LCOW: Implemented support for docker cp + build")
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit 81f6307eda44ab3a91de6e29304810a976161d74)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-17 15:09:01 -07:00
ec3221ac7d Merge pull request #512 from thaJeztah/18.03-backport-tests
[18.03] backport updates to tests, and fix empty LogPath with non-blocking logging mode
2018-04-17 14:56:29 -07:00
d602967356 Merge pull request #495 from thaJeztah/18.03-backport-972-fix-merge-network
[18.03] backport Fix error with merge composefile with networks…
2018-04-16 19:04:36 -07:00
aded7a8259 Fix stack deploy re-deploying service after --force
When updating a service with the `--force` option, the `ForceUpdate`
property of the taskspec is incremented.

Stack deploy did not take this into account, and reset this
field to its default value (0), causing the service to be
re-deployed.

This patch copies the existing value before updating the service.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 76439457d2)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 15:42:45 -07:00
a3540962fd Add some tests to the volume store
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
(cherry picked from commit 834d0e262ac248191c09bcdb2b86ee92edb6aaf0)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:44:33 -07:00
c25858e94c TestLinksEtcHostsContentMatch: use container.Exec()
I am not quite sure why but this test is sometimes failing like this:

> 15:21:41 --- FAIL: TestLinksEtcHostsContentMatch (0.53s)
> 15:21:41 	assertions.go:226:
>
> 	Error Trace:	links_linux_test.go:46
> 15:21:41
> 	Error:      	Not equal:
> 15:21:41
> 	            	expected: "127.0.0.1\tlocalhost\n::1\tlocalhost
> ip6-localhost
> ip6-loopback\nfe00::0\tip6-localnet\nff00::0\tip6-mcastprefix\nff02::1\tip6-allnodes\nff02::2\tip6-allrouters\n172.17.0.2\tf53feb6df161\n"
> 15:21:41
> 	            	received: ""

To eliminate some possible failures (like ignoring stderr from `cat` or
its exit code), let's use container.Exec() to read a file from a container.

Fixes: e6bd20edcbf ("Migrate some integration-cli test to api tests")
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit ad2f88d8ccbd9dd0a8d9c4f96ece3956f60489df)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:44:17 -07:00
ae56939688 Remove unnecessary diff tests
Signed-off-by: Daniel Nephin <dnephin@docker.com>
(cherry picked from commit 038f3add5191240058c7a4154556553c5493ea44)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:44:09 -07:00
df6211ff9e Remove duplicate TestServiceUpdatePort
The TestAPIServiceUpdatePort test performs exactly
the same steps.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 36e1646e4f010ea033643c6df3d9c3dccc166ed2)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:22:15 -07:00
e945f93024 Adds a unit test for plugin request timeout
Signed-off-by: Brian Goff <cpuguy83@gmail.com>
(cherry picked from commit 7ca971fb495e4de4aa4455964625974464d86920)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:22:10 -07:00
04ebff9f98 Address expected vs actual in integration tests
This fix addresses `expected` vs `actual` in integration tests
so that they match `assert.Equal(t, expected, actual)`

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
(cherry picked from commit 8a854e933b3dbb26cfce28b920cff61909412c6f)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:22:04 -07:00
b3929fad23 Remove unnecessary container.WithName in kill test
This fix removes several unnecessary `container.WithName`
usage in docker kill integration test.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
(cherry picked from commit 1778719d6ac166250acfaebe5dd99b5e9d151c3e)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:21:58 -07:00
6fbd783f33 Migrate docker rm tests to api tests
This fix migrates docker rm test in integration-cli
to api tests.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
(cherry picked from commit ed58ba99fb28ceac56063b7f003f38b597ddef80)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:21:53 -07:00
618f290b37 Improvement in integration tests
This fix adds several improvement:
1. No need for explicit ContainerRemove as it has been handled in setupTest()
2. Added `container.WithImage` helper function and used it in commit tests.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
(cherry picked from commit 6ab465804b0b8cec6c5ac278a21151d49e34885d)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:21:48 -07:00
1f529b2bd2 Fixes some integration/container test to run on remote daemon
```
docker build -f Dockerfile.e2e -t moby-e2e .
docker run -v /var/run/docker.sock:/var/run/docker.sock \
           -e TEST_INTEGRATION_DIR=/tests/integration/container \
           -e DOCKER_API_VERSION=1.36 moby-e2e
```

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 18dd1d9aba3c79d355abaa7f498b88ad816f7d04)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:21:42 -07:00
e695ffea63 Migrate export tests to api tests
This fix migrates export tests in integration-cli to api tests.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
(cherry picked from commit 4e702cf70d50ee5b0737270f27d9973fd3084c66)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:21:36 -07:00
d4444e3446 Fix "expected" and "actual" being reversed
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit a2517cbf62d75c48861337182aa841c5089f8ac4)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:21:29 -07:00
53a10ae2bc Enhancement of replacing ContainerCreate with helper funcs in tests
This fix is a minor enhancement to replace several ContainerCreate with
helper funcs of `container.Create` in tests.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
(cherry picked from commit 6ad4720c78d6ac61a60a3e7ed1d0c0119c5d103e)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:21:20 -07:00
0fd259afcb Remove docker_cli_secret_inspect_test.go
as the test (TestSecretInspectMultiple) seems to have been covered pretty well in cli:
https://github.com/docker/cli/blob/master/cli/command/secret/inspect_test.go

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
(cherry picked from commit 3d38adb20c619b87edab72e51ff0fd1cf6e08691)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:21:12 -07:00
8b54bcc057 Migrate events tests to api tests
This fix migrates events tests in integration-cli to api tests.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
(cherry picked from commit 3a749157d2c2b320fea49f7aa4d4eb634f52662f)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:21:06 -07:00
e4022bf934 Migrate config inspect test to api test
This fix migrates config inspect test in integration-cli
to api test.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
(cherry picked from commit 4b99d782079dc390c2d8fb78f6973bbeee7d8a47)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:21:00 -07:00
bae8ccdbd7 Clean-up after container unit test
Remove temp directories and close file loggers in container unit tests.

Signed-off-by: mnussbaum <michael.nussbaum@getbraintree.com>
(cherry picked from commit 07d5446fe27cb92d881df48be6e8a6510d9608b0)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:20:53 -07:00
b2ff741b5f Fix empty LogPath with non-blocking logging mode
This fixes an issue where the container LogPath was empty when the
non-blocking logging mode was enabled. This change sets the LogPath on
the container as soon as the path is generated, instead of setting the
LogPath on a logger struct and then attempting to pull it off that
logger at a later point. That attempt to pull the LogPath off the logger
was error prone since it assumed that the logger would only ever be a
single type.

Prior to this change docker inspect returned an empty string for
LogPath. This caused issues with tools that rely on docker inspect
output to discover container logs, e.g. Kubernetes.

This commit also removes some LogPath methods that are now unnecessary
and are never invoked.

Signed-off-by: junzhe and mnussbaum <code@getbraintree.com>
(cherry picked from commit 20ca612a59c45c0bd58c71c199a7ebd2a6bf1a9e)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:20:43 -07:00
89f42b5a6e Migrate some config secret tests to api test
This fix migrates some secret create tests to api tests,
and remove redundant TestConfigCreate.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
(cherry picked from commit 99e28188507bbcb925b0c09df6b53cdd882d24c5)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:20:28 -07:00
811b93ac9b Move containerIsStopped/containerIsInState to integration/internal/container
This fix moves helper functions containerIsStopped and
containerIsInState to integration/internal/container,
so that they could be used outside of integration/container.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
(cherry picked from commit eda311c18f388ed4541dc44dcfba08cd4347a685)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:20:21 -07:00
fd75fd2b45 Clean the teardown process of network test
We need to clean the resources created in some test cases, else
in some cases we'll get below error for other tests:

> FAIL: docker_experimental_network_test.go:37: DockerNetworkSuite.TestDockerNetworkMacvlanPersistance
>  docker_experimental_network_test.go:44:
> ...
> Command:  ip link add dm-dummy0 type dummy
> ExitCode: 2
> Error:    exit status 2
> Stdout:
> Stderr:   RTNETLINK answers: File exists
> ...

Logically, each test case should be independent, the failure of previous
test case should not have side-effect for the test cases followed.

Signed-off-by: Dennis Chen <dennis.chen@arm.com>
(cherry picked from commit 57d85e7e54f7d074af8c496cba43ee18d3815207)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:20:14 -07:00
7aa342f808 Update docker-py
This fix update docker-py so that containers from the tests run
could be cleaned up during teardown:
```diff
-ENV DOCKER_PY_COMMIT 5e28dcaace5f7b70cbe44c313b7a3b288fa38916
+ENV DOCKER_PY_COMMIT 8b246db271a85d6541dc458838627e89c683e42f
```

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
(cherry picked from commit 66935a0f64f0a72162fb3919c759f4f500b6c372)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:20:07 -07:00
15237fd242 Migrate several docker rm tests to api tests
This fix migrates several docker rm tests to api tests

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
(cherry picked from commit 6bd4f4801b244555213f0040b9885033e99d4ae8)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:20:00 -07:00
1331808a09 Migrate volumes tests in integration-cli to api tests
This fix migrates volumes tests in integration-cli to api tests
in integration/

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
(cherry picked from commit d896f87c0595134fa2f0787dad30b237815f233f)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-16 14:19:52 -07:00
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
a0c8cc80ab Fix docker version output alignment
Use tabwriter to print the version output

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 48eb7a082d)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-11 19:13:58 -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
d6931c2d12 Fix error with merge composefile with networks…
… and other cases too. Updating mergo fixes the bugs (but introduced a
slight behaviour change that had to be fixed too)

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 0122730faf)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-11 14:41:04 -07:00
92f0dce1d1 Fix docker stack deploy reference flag
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
(cherry picked from commit 2ee9635b1e)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2018-04-11 14:40:52 -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
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
775 changed files with 19752 additions and 19427 deletions

View File

@ -2,6 +2,42 @@
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.1-ce (2018-04-26)
### Client
- Fix error with merge compose file with networks [docker/cli#983](https://github.com/docker/cli/pull/983)
* Fix docker stack deploy re-deploying services after the service was updated with `--force` [docker/cli#963](https://github.com/docker/cli/pull/963)
* Fix docker version output alignment [docker/cli#965](https://github.com/docker/cli/pull/965)
### 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)
* Don't make container mount unbindable [moby/moby#36768](https://github.com/moby/moby/pull/36768)
- Fix Daemon panics on container export after a daemon restart [moby/moby/36586](https://github.com/moby/moby/pull/36586)
- Fix digest cache being removed on autherrors [moby/moby#36509](https://github.com/moby/moby/pull/36509)
- Make sure plugin container is removed on failure [moby/moby#36715](https://github.com/moby/moby/pull/36715)
- Copy: avoid using all system memory with authz plugins [moby/moby#36595](https://github.com/moby/moby/pull/36595)
- Relax some libcontainerd client locking [moby/moby#36848](https://github.com/moby/moby/pull/36848)
### Swarm Mode
* Increase raft Election tick to 10 times Heartbeat tick [moby/moby#36672](https://github.com/moby/moby/pull/36672)
### Networking
* Gracefully remove LB endpoints from services [docker/libnetwork#2112](https://github.com/docker/libnetwork/pull/2112)
* Retry other external DNS servers on ServFail [docker/libnetwork#2121](https://github.com/docker/libnetwork/pull/2121)
* Improve scalabiltiy of bridge network isolation rules [docker/libnetwork#2117](https://github.com/docker/libnetwork/pull/2117)
* Allow for larger preset property values, do not override [docker/libnetwork#2124](https://github.com/docker/libnetwork/pull/2124)
* Prevent panics on concurrent reads/writes when calling `changeNodeState` [docker/libnetwork#2136](https://github.com/docker/libnetwork/pull/2136)
## 18.03.0-ce (2018-03-21)
### Builder
@ -73,7 +109,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
18.03.1-ce

View File

@ -1 +1 @@
18.03.0-ce
18.03.1-ce

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