Evolution of testing @moby

Let’s discuss the evolution of testing in the Moby Project – mainly integration-cli tests and their future.

  • Most of our integration tests (in integration-cli package) are using the docker cli to execute — now that this CLI has be exctracted elsewhere we should not depend on it anymore.
  • Some tests in this packages are more than just integration tests and could be seen as more end-to-end test of docker. These should move to our e2e repository and/or have a set of end-to-end tests for moby in the future.
  • All the tests are in the same package, in huge files and quick a few of them are a little bit to noisy.

Here is a proposal (that I’ll try to keep up-to-date) of what should happen and in what order — based on our daily in the community slack.

  1. Freeze integration-cli package — i.e. not adding anymore tests in there that are using the docker cli. Also add a check to validate that (i.e. if there is any addition in integration-cli, the build fail).
  2. Create an integration package for moby api integration tests
  3. Move docker_api_*_test.go suites there :angel: in small packages — i.e. integration/image/build for build-related tests, integration/container/run for container run related tests, integration/distribution for push/pull related tests, etc…
  4. List tests that in integration-cli that should move away, either in a end-to-end repository, as api tests or as unit tests.
  5. For api tests we should use the client package (it’s unit tested so risks of weirdiness should be limited)

There is more open-question too :

  • Should we freeze the integration-cli or should we extract them in a repo ? Either way, we need a CI job that execute those on moby/moby for an indeterminate time.
  • Should we use client (docker go sdk) for the API tests or http.Client/integration-cli/request package ? It’s probably a mix of those too but better discussing it.
  • Which testing framework to use for those integration tests ? integration-cli uses go-check, should we do the same for integration api tests or should we go back to testing with testify for example ?

If you think there is more point to discuss on that topics, feel free to talk about it, I’ll update that according to the discussions :angel:

1 Like

I’m in favor of using http.Client, the docker SDK should have its own testing in its own repo.

Should we freeze the integration-cli or should we extract them in a repo ? Either way, *we need a CI job that execute those on moby/moby for an indeterminate time.

I think we want to “freeze” them in the short term, they are most of our test coverage right now.

Even when docker/e2e repo exists, I assume based on the name, that it will test the docker product, not the moby project, so we would end up with a cyclic dependency between them. Over time components that are removed from moby/moby will have their own tests suites and we should be able to remove some tests.

I see some potential problems/complications with freezing integration-cli

  • We will need to make exceptions for fixing test flakes
  • We will want to remove tests occasionally, which will probably involved some + lines in the diff, even if it’s only removing a test (because of shared code, and table tests)
  • Some tests make poor assumptions and could need to be changed because of a backend/api change. Do we require contributors to rewrite the test as an API test at that time?

Which testing framework to use for those integration tests ? integration-cli uses go-check, should we do the same for integration api tests or should we go back to testing with testify for example ?

I’m partial to testify. What does go-check provide?

client/ is not actually an SDK, it’s just a client library. Regardless of the API implementation (http+json REST, gRPC, etc) there is always some client library there. I think the question is more about do we test using the client library or with an HTTP client.

I think the trade off is that the client library is more convenient, but you risk missing flaws in the API because they get hidden by the client library.

If you test with http.Client any API flaws should be more obvious, but you end up duplicating part of what’s in the client library.

Can we get a middle ground where we just have a few helper (i.e. for avoid repeating error checking, and things like encoding/decoding data) instead of a full-fledged client package?

There’s really not much in the client/ package that we would omit. 90% of it is just translating arguments into an HTTP request, and an HTTP response into a struct.

Indeed.

I should have done so before, but the client/ covers a lot less than what I thought. We’d have to check that all parameters can effectively be set via the methods exposed by the client though, since an intermediary type is sometimes used, I assume there may be some gap.

TL;DR: client/ will work for me in the end.

Discussion in the standup; looks like we agree on using client/ for the tests. We will have to update the CONTRIBUTING.md and/or other documents to provide examples on how to write these tests