Conversation
| } else { | ||
| exception.expect(NotFoundException.class); | ||
| } | ||
| }*/ |
There was a problem hiding this comment.
you will have different errors for different api versions, i spent a lot of time in this place
There was a problem hiding this comment.
Yes true, but it seems that only swarm behaves differently here compared to docker. The main error here was that awaitCompletion and not awaitSuccess was called.
The error handling for the pull command was only in awaitSuccess. I have moved that to awaitCompletion since you will expect correct error handling there.
15dfe16 to
a028b16
Compare
|
Hm..., I really don't like it that all test cases leave there containers and resources there. |
Codecov Report
@@ Coverage Diff @@
## master #938 +/- ##
==========================================
+ Coverage 61.29% 61.58% +0.29%
==========================================
Files 411 411
Lines 8134 8172 +38
Branches 526 530 +4
==========================================
+ Hits 4986 5033 +47
+ Misses 2846 2838 -8
+ Partials 302 301 -1
Continue to review full report at Codecov.
|
# Conflicts: # src/main/java/com/github/dockerjava/api/model/PullResponseItem.java # src/main/java/com/github/dockerjava/core/command/PullImageResultCallback.java
.travis/travis-before-install.sh
Outdated
| "--name=swarm_join" \ | ||
| "swarm:${SWARM_VERSION}" \ | ||
| join --advertise="${HOST_IP}:${HOST_PORT}" --delay="0s" --heartbeat "5s" "nodes://${HOST_IP}:${HOST_PORT}" | ||
| # join engine to swarm, is not required if fixed ip addresses are used |
There was a problem hiding this comment.
because then you will have huge default delays
| LOG.info("Committing container: {}", container.toString()); | ||
| String imageId = dockerRule.getClient().commitCmd(container.getId()).exec(); | ||
|
|
||
| //swarm needs some time to refelct new images |
| String imageId = dockerRule.getClient().commitCmd(container.getId()).exec(); | ||
|
|
||
| //swarm needs some time to refelct new images | ||
| wait(5000); |
There was a problem hiding this comment.
use awaitility with query to what needed?
There was a problem hiding this comment.
What do you exactly mean?
There was a problem hiding this comment.
I mean that awaitility with client query for some good to go criteria is right way. https://github.com/awaitility/awaitility
|
|
||
| @Test | ||
| public void createContainerWithPortBindings() throws DockerException { | ||
| int baseport = dockerRule.getKind().equals("jersey")? 11000: 12000; |
There was a problem hiding this comment.
getKind() is string value, test itself is parametrized with enum, so you can do it easy with getFactoryType() == JERSEY
|
|
||
| // we have to block until image is pushed | ||
| dockerRule.getClient().pushImageCmd(username + "/busybox").exec(new PushImageResultCallback()).awaitSuccess(); | ||
| dockerRule.getClient().pushImageCmd(username + "/busybox").exec(new PushImageResultCallback()).awaitCompletion(); |
There was a problem hiding this comment.
it may complete with not pushed r tests needs awaitSuccess() everywhere as clear success of operation.
There was a problem hiding this comment.
I think that it is not a good choice to have an awaitComplete and an awaitSuccess. Since awaitComplete does not validate all error cases on pull and push
There was a problem hiding this comment.
Then it will hide bugs in .awaitSuccess logic. In any case success should be success for test even the next code do single checks of success criteria.
| dockerRule.getClient().pushImageCmd(username + "/xxx") | ||
| .exec(new PushImageResultCallback()) | ||
| .awaitCompletion(20, TimeUnit.SECONDS); // exclude infinite await sleep | ||
| .awaitCompletion(); // exclude infinite await sleep |
There was a problem hiding this comment.
- comment is wrong
- without timeout test may stuck forever, test needs some timeout.
| exception.expect(DockerClientException.class); | ||
| } else { | ||
| //swarms throws a different error here | ||
| if (TestUtils.isSwarm(dockerRule.getClient())) { |
There was a problem hiding this comment.
it not related to swarm. Run locally 2 DINDs with different version and run test against - you will see different behaviour
There was a problem hiding this comment.
The Problem was that sometimes awaitSuccess and sometimes awaitComplete was used. And they behaves inconsistent while handling the error.
Therefore i propose that awaitComplete does the correct error handling and we deprecate awaitSuccess.
There was a problem hiding this comment.
i not sure at all why we parse messages because http response code should indicate success or failure... But it could be changed in future, now i want end swarm & tests scope of changes and make major release.
There was a problem hiding this comment.
Not really since docker send always an success status code and will later then indicate the error status in the body. That is not so unknown pattern for long running asynchronous operations, since a http request will otherwise be timeout by clients or intermediate proxies.
|
Yeah all seems to be green |
| dockerRule.getClient().startContainerCmd(container.getId()).exec(); | ||
|
|
||
| Integer status = dockerRule.getClient().waitContainerCmd(container.getId()) | ||
| .exec(new WaitContainerResultCallback()).awaitStatusCode(); |
There was a problem hiding this comment.
on one line client.command()
on other lines fluent calls .exec()
.await()
That's for eyes redability
|
|
||
| //swarm needs some time to refelct new images | ||
| synchronized (this) { | ||
| wait(5000); |
There was a problem hiding this comment.
what is the criteria that it swarm is ready?
There was a problem hiding this comment.
I don't know but we use the same trick in our production swarm cluster. I guess that swarm manager keeps an image cache in memory or something like that.
And this cache is lazy reinitialized after a new image is in place.
| .exec(new PushImageResultCallback()) | ||
| .awaitCompletion(30, TimeUnit.SECONDS); | ||
|
|
||
| Assert.fail("An exception is expected."); |
There was a problem hiding this comment.
Assert.fail() is not junit Expected Rule style
There was a problem hiding this comment.
Yes sure is there a different easy way to define two different expectations?
There was a problem hiding this comment.
fast lookup shows that ExpectedException.expect(Class) uses org.hamcrest.CoreMatchers#instanceOf and there is org.junit.rules.ExpectedException#expect(org.hamcrest.Matcher<?>)
so i guess you can construct org.hamcrest.CoreMatchers#anyOf(java.lang.Iterable<org.hamcrest.Matcher<? super T>>) + instanceOf()
But again, you are changing the existing behaviour of the test. Test was about success + different api versions, so you shouldn't combine and hide this errors.
This tests not only about green status, they like documentation examples. Usually when i have questions i go to tests and this conditionals will show what may be wrong.
There was a problem hiding this comment.
That will make only sense for me if I can always expect the same exception for the same error. But that is not the case. If I upgrade my docker version, for example, I will get no a different Exception. Thats not a really cool behavior. And since docker behaves like that, it should be more straightforward to throw an exception that I can always handle. For instance a common DockerException base class for all Exception which the docker client will throw.
| .awaitCompletion(30, TimeUnit.SECONDS); | ||
|
|
||
| fail("An exception is expected."); | ||
| } catch (NotFoundException | DockerClientException e) { |
There was a problem hiding this comment.
that seems a wrong junit exception usage. test shouldn't suppress exceptions, it need only configure exception (that is Rule).
There was a problem hiding this comment.
There was a problem hiding this comment.
But thats an or exception condition
maybe we let DockerClientException extend DockerException?
There was a problem hiding this comment.
no idea, how it influence on this test case? Different docker versions return different error codes so client returns different exceptions. That's why Exception Rule was conditionally configured before call that should throw error.
There was a problem hiding this comment.
It will change that each method will at least throw a DockerException. So you can always expect a DockerException regardless which docker version you exactly use.
Currently you must expect a DockerException or a DockerClientException.
| exception.expect(DockerClientException.class); | ||
| } | ||
| //different docker version throws different errors here | ||
| exception.expect(anyOf(instanceOf(NotFoundException.class), instanceOf(DockerClientException.class))); |
There was a problem hiding this comment.
Please restore original logic, original code tests for expected exceptions, not or.
There was a problem hiding this comment.
There was a bug, in the error handling logic it will always throw an error now. But in my tests docker behaves different also on same versions by just switching to swarm. And again I do not like that, that you must handle different exception types depending on the used docker/swarm version.
If we at least let DockerClientException extend DockerException we can say it will always throw an DockerException independent of the used docker / swarm version.
There was a problem hiding this comment.
library is transparent to docker api/daemon bugs. We don't do magic, NotFoundException is handled in different way by library users because it means that image not found and user may be wanting to switch to other image, all other errors - 500, 501 etc are not recoverable for application usage. And if swarm and docker behaves differently then it should be library user problem. In fact i don't see a problem, in library you can catch it with oneEx | secondEx and tests catches exactly like it is.
There was a problem hiding this comment.
The case why I do not like this behavior is, that the docker daemon indicates an error asynchronously and we make a docker client exception out of it.
My expectation was that the DockerClientException is only thrown if a client-side error occurred, not a remote one.
| .exec(new PushImageResultCallback()) | ||
| .awaitCompletion(20, TimeUnit.SECONDS); // exclude infinite await sleep | ||
|
|
||
| .awaitCompletion(30, TimeUnit.SECONDS); |
| //swarm will attach additional labels here | ||
| assertThat(responseLabels.size(), greaterThanOrEqualTo(2)); | ||
| assertThat(responseLabels.get("label1"), equalTo("abc")); | ||
| assertThat(responseLabels.get("label2"), equalTo("123")); |
There was a problem hiding this comment.
It works before because, on some docker versions, the labels were copied to the containerConfig. That was the reason why this test fails on some test configurations. We can only expect the labels on the config object since the container was not started with any labels.
|
Thanks! |
Try to fix some outstanding test failures
This change is