Skip to content

ci(integration-cli): split test suites in a matrix#43682

Merged
thaJeztah merged 5 commits intomoby:masterfrom
crazy-max:split-test-suites
Jun 22, 2022
Merged

ci(integration-cli): split test suites in a matrix#43682
thaJeztah merged 5 commits intomoby:masterfrom
crazy-max:split-test-suites

Conversation

@crazy-max
Copy link
Member

@crazy-max crazy-max commented Jun 2, 2022

Split DockerSuite for integration-cli tests so we can create a matrix to reduce build time in our pipeline (windows atm). We could also use tags for this purpose. Let me know what sounds better to you. Keeping the working tree like this for visibility but will squash commits if it sgty.

Here is the overall build time for each of them after splitting (still windows):

- DockerApiSuite: ~12m06s
- DockerBenchmarkSuite: ~11s
- DockerCliAttachSuite: ~16s
- DockerCliBuildSuite: ~16m33s
- DockerCliCommitSuite: ~33s
- DockerCliCpSuite: ~54s
- DockerCliCreateSuite: ~45s
- DockerCliEventSuite: ~1m31s
- DockerCliExecSuite: ~26s
- DockerCliHealthSuite: ~8s
- DockerCliHistorySuite: ~32s
- DockerCliImagesSuite: ~27s
- DockerCliImportSuite: ~8s
- DockerCliInfoSuite: ~8s
- DockerCliInspectSuite: ~52s
- DockerCliLinksSuite: ~9s
- DockerCliLoginSuite: ~8s
- DockerCliLogsSuite: ~48s
- DockerCliNetmodeSuite: ~8s
- DockerCliNetworkSuite: ~8s
- DockerCliPluginLogDriverSuite: ~8s
- DockerCliPluginsSuite: ~10s
- DockerCliPortSuite: ~11s
- DockerCliProxySuite: ~8s
- DockerCliPruneSuite: ~9s
- DockerCliPsSuite: ~1m19s
- DockerCliPullSuite: ~9s
- DockerCliPushSuite: ~13s
- DockerCliRestartSuite: ~58s
- DockerCliRmiSuite: ~1m52s
- DockerCliRunSuite: ~4m07s
- DockerCliSaveLoadSuite: ~8s
- DockerCliSearchSuite: ~11s
- DockerCliSniSuite: ~10s
- DockerCliStartSuite: ~26s
- DockerCliStatsSuite: ~7s
- DockerCliTopSuite: ~16s
- DockerCliUpdateSuite: ~11s
- DockerNetworkSuite|DockerHubPullSuite|DockerRegistrySuite|DockerSchema1RegistrySuite|DockerRegistryAuthTokenSuite|DockerRegistryAuthHtpasswdSuite: ~11s
- DockerSwarmSuite: ~8s
- DockerDaemonSuite: ~8s
- DockerExternalVolumeSuite: ~7s

Before ~1h20m

After ~42m

image

@crazy-max
Copy link
Member Author

@thaJeztah Not linked to these changes but looks like we have an issue with criu repo: https://ci-next.docker.com/public/blue/organizations/jenkins/moby/detail/PR-43682/1/pipeline#step-163-log-428

[2022-06-02T17:20:49.208Z] #51 ERROR: executor failed running [/bin/sh -c echo 'deb https://download.opensuse.org/repositories/devel:/tools:/criu/Debian_11/ /' > /etc/apt/sources.list.d/criu.list         && apt-get update         && apt-get install -y --no-install-recommends criu         && install -D /usr/sbin/criu /build/criu]: exit code: 100

@thaJeztah
Copy link
Member

Hmm that repo has had issues a couple of times; maybe it's temporary, or they're fixing it?

@crazy-max crazy-max force-pushed the split-test-suites branch from e2bca75 to 931f7fa Compare June 2, 2022 17:55
@crazy-max
Copy link
Member Author

crazy-max commented Jun 2, 2022

Forced push and looks worse now 😅:

[2022-06-02T17:57:17.080Z] #51 19.97 E: Failed to fetch https://mirrorcache-us.opensuse.org/repositories/devel:/tools:/criu/Debian_11/amd64/criu_3.17-1_amd64.deb  Could not connect to mirrorcache-us.opensuse.org:443 (91.193.113.65). - connect (111: Connection refused) Could not connect to mirrorcache-us.opensuse.org:443 (2a07:de40:401::65). - connect (101: Network is unreachable)

@crazy-max crazy-max force-pushed the split-test-suites branch 3 times, most recently from b9a74e8 to 0e1f09c Compare June 2, 2022 20:47
@tianon
Copy link
Member

tianon commented Jun 3, 2022

Very interesting! I like the idea, but I'm concerned about how repetitive it is (both in the code and in the configuration) -- for example, maintaining that long list of tiny functions and/or the list of all their names in the YAML seems really error prone. 😬

@crazy-max crazy-max force-pushed the split-test-suites branch from 0e1f09c to 15c8cf9 Compare June 3, 2022 07:52
@crazy-max
Copy link
Member Author

Very interesting! I like the idea, but I'm concerned about how repetitive it is (both in the code and in the configuration) -- for example, maintaining that long list of tiny functions and/or the list of all their names in the YAML seems really error prone. 😬

Yes I'm also worried about missing some tests in the future using this pattern. I will check if go tooling allows to have some stats with available tests and suites in a pkg and split them accordingly in the matrix workflow like this.

@crazy-max crazy-max force-pushed the split-test-suites branch from 15c8cf9 to c123a46 Compare June 3, 2022 10:24
@crazy-max
Copy link
Member Author

@thaJeztah Looks like we are not able to update or add new tests in integration-cli: https://ci-next.docker.com/public/blue/organizations/jenkins/moby/detail/PR-43682/7/pipeline#step-256-log-7 😅

[2022-06-03T10:34:23.854Z] The following new tests were added to integration-cli:
[2022-06-03T10:34:23.854Z] 
[2022-06-03T10:34:23.854Z] +func (s *DockerApiSuite) TestGetContainersAttachWebsocket(c *testing.T) {
[2022-06-03T10:34:23.854Z] +func (s *DockerApiSuite) TestPostContainersAttachContainerNotFound(c *testing.T) {
[2022-06-03T10:34:23.854Z] +func (s *DockerApiSuite) TestGetContainersWsAttachContainerNotFound(c *testing.T) {
[2022-06-03T10:34:23.854Z] +func (s *DockerApiSuite) TestPostContainersAttach(c *testing.T) {

@crazy-max crazy-max force-pushed the split-test-suites branch 4 times, most recently from c434e01 to 27a8762 Compare June 4, 2022 13:57
@crazy-max
Copy link
Member Author

crazy-max commented Jun 4, 2022

To dynamically generate and distribute tests in a matrix I checked go test -list but unfortunately it doesn't list test suites.

I have created a small library called gotestlist to list tests in the given Go packages. Here is what it looks like if I run gotestlist in integration-cli:

$ go install github.com/crazy-max/gotestlist/cmd/gotestlist@latest
$ cd integration-cli/
$ gotestlist -d 4 ./... | jq
[
  "DockerAPISuite|DockerBenchmarkSuite|DockerCliAttachSuite",
  "DockerCliBuildSuite|DockerCliCommitSuite|DockerCliCpSuite|DockerCliCreateSuite|DockerCliEventSuite",
  "DockerCliExecSuite|DockerCliHealthSuite|DockerCliHistorySuite|DockerCliImagesSuite|DockerCliImportSuite|DockerCliInfoSuite|DockerCliInspectSuite|DockerCliLinksSuite|DockerCliLoginSuite|DockerCliLogsSuite|DockerCliNetmodeSuite|DockerCliNetworkSuite|DockerCliPluginLogDriverSuite|DockerCliPluginsSuite|DockerCliPortSuite|DockerCliProxySuite|DockerCliPruneSuite|DockerCliPsSuite|DockerCliPullSuite|DockerCliPushSuite|DockerCliRestartSuite|DockerCliRmiSuite",
  "DockerCliRunSuite|DockerCliSaveLoadSuite|DockerCliSearchSuite|DockerCliSniSuite|DockerCliStartSuite|DockerCliStatsSuite|DockerCliTopSuite|DockerCliUpdateSuite|DockerCliVolumeSuite|DockerDaemonSuite|DockerExternalVolumeSuite|DockerHubPullSuite|DockerNetworkSuite|DockerPluginSuite|DockerRegistryAuthHtpasswdSuite|DockerRegistryAuthTokenSuite|DockerRegistrySuite|DockerSchema1RegistrySuite|DockerSwarmSuite"
]

-d flag dynamically distributes the tests based on the given matrix size (here 4) and number of tests. This JSON output can then be used as matrix input in our workflow. This way no tests are missing.

I don't calculate cyclomatic complexities of tests functions in gotestlist to add some "weight" and distribute a bit better but I think it's ok in the meantime.

@crazy-max crazy-max force-pushed the split-test-suites branch 4 times, most recently from 3f40d08 to 07bce15 Compare June 6, 2022 14:48
@crazy-max
Copy link
Member Author

crazy-max commented Jun 6, 2022

@corhere @neersighted @thaJeztah As discussed on Slack, I looked at how we could aggregate data from JSON reports of Go tests. Last commit adds a step for unit and integration tests that will render the output as markdown and create a GitHub summary in our workflow:

image

There are also some useful stats about slow tests:

image

Summary also includes failed tests with logs:

image

@crazy-max crazy-max marked this pull request as ready for review June 6, 2022 15:11
@crazy-max crazy-max requested a review from tianon as a code owner June 6, 2022 15:11
@neersighted
Copy link
Member

@corhere @neersighted @thaJeztah As discussed on Slack, I looked at how we could aggregate data from JSON reports of Go tests. Last commit adds a step for unit and integration tests that will render the output as markdown and create a GitHub summary in our workflow:
...

Nice! Looks like teststat was a solid find -- everything here looks good to me as long as there's no interest in templating/generating the workflows to avoid duplication.

@tianon
Copy link
Member

tianon commented Jun 6, 2022

Nice, gotestlist is really clever -- I'm assuming the lists have such dramatically different numbers of suites due to the number of tests in each suite, right? (Just to make sure I'm understanding the implementation correctly 😅)

@crazy-max crazy-max force-pushed the split-test-suites branch 2 times, most recently from f72ad34 to 06e949a Compare June 7, 2022 07:51
@crazy-max
Copy link
Member Author

Nice, gotestlist is really clever -- I'm assuming the lists have such dramatically different numbers of suites due to the number of tests in each suite, right? (Just to make sure I'm understanding the implementation correctly 😅)

Yes exactly, here are the current stats for tests in integration-cli:

{
  "DockerAPISuite": 151,
  "DockerBenchmarkSuite": 2,
  "DockerCliAttachSuite": 7,
  "DockerCliBuildSuite": 249,
  "DockerCliCommitSuite": 9,
  "DockerCliCpSuite": 43,
  "DockerCliCreateSuite": 20,
  "DockerCliEventSuite": 43,
  "DockerCliExecSuite": 27,
  "DockerCliHealthSuite": 2,
  "DockerCliHistorySuite": 6,
  "DockerCliImagesSuite": 17,
  "DockerCliImportSuite": 7,
  "DockerCliInfoSuite": 5,
  "DockerCliInspectSuite": 29,
  "DockerCliLinksSuite": 14,
  "DockerCliLoginSuite": 1,
  "DockerCliLogsSuite": 15,
  "DockerCliNetmodeSuite": 6,
  "DockerCliNetworkSuite": 14,
  "DockerCliPluginLogDriverSuite": 2,
  "DockerCliPluginsSuite": 6,
  "DockerCliPortSuite": 5,
  "DockerCliProxySuite": 1,
  "DockerCliPruneSuite": 4,
  "DockerCliPsSuite": 18,
  "DockerCliPullSuite": 2,
  "DockerCliPushSuite": 2,
  "DockerCliRestartSuite": 13,
  "DockerCliRmiSuite": 15,
  "DockerCliRunSuite": 298,
  "DockerCliSaveLoadSuite": 16,
  "DockerCliSearchSuite": 5,
  "DockerCliSniSuite": 1,
  "DockerCliStartSuite": 9,
  "DockerCliStatsSuite": 6,
  "DockerCliTopSuite": 4,
  "DockerCliUpdateSuite": 13,
  "DockerCliVolumeSuite": 24,
  "DockerDaemonSuite": 123,
  "DockerExternalVolumeSuite": 18,
  "DockerHubPullSuite": 6,
  "DockerNetworkSuite": 48,
  "DockerPluginSuite": 11,
  "DockerRegistryAuthHtpasswdSuite": 8,
  "DockerRegistryAuthTokenSuite": 5,
  "DockerRegistrySuite": 38,
  "DockerSchema1RegistrySuite": 11,
  "DockerSwarmSuite": 121
}

With gotestlist -d 4 each matrix entry has a max allocation of 388 tests so will be distribute accordingly like this:

[
  "DockerAPISuite|DockerBenchmarkSuite|DockerCliAttachSuite",
  "DockerCliBuildSuite|DockerCliCommitSuite|DockerCliCpSuite|DockerCliCreateSuite|DockerCliEventSuite",
  "DockerCliExecSuite|DockerCliHealthSuite|DockerCliHistorySuite|DockerCliImagesSuite|DockerCliImportSuite|DockerCliInfoSuite|DockerCliInspectSuite|DockerCliLinksSuite|DockerCliLoginSuite|DockerCliLogsSuite|DockerCliNetmodeSuite|DockerCliNetworkSuite|DockerCliPluginLogDriverSuite|DockerCliPluginsSuite|DockerCliPortSuite|DockerCliProxySuite|DockerCliPruneSuite|DockerCliPsSuite|DockerCliPullSuite|DockerCliPushSuite|DockerCliRestartSuite|DockerCliRmiSuite",
  "DockerCliRunSuite|DockerCliSaveLoadSuite|DockerCliSearchSuite|DockerCliSniSuite|DockerCliStartSuite|DockerCliStatsSuite|DockerCliTopSuite|DockerCliUpdateSuite|DockerCliVolumeSuite|DockerDaemonSuite|DockerExternalVolumeSuite|DockerHubPullSuite|DockerNetworkSuite|DockerPluginSuite|DockerRegistryAuthHtpasswdSuite|DockerRegistryAuthTokenSuite|DockerRegistrySuite|DockerSchema1RegistrySuite|DockerSwarmSuite"
]

@crazy-max crazy-max requested a review from tianon June 7, 2022 07:59
@crazy-max crazy-max force-pushed the split-test-suites branch 3 times, most recently from 2ea1f8e to ac55feb Compare June 7, 2022 12:57
Copy link
Member

@tianon tianon left a comment

Choose a reason for hiding this comment

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

Nice! I'm still a little worried about all those duplicated tiny "test suite" function entrypoints, but at least we now don't also have the hand-maintained lists in the YAML too 👍

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

this looks really nice! I left comments about the capitalisation not being "correct" CamelCase; I realise that'd be a lot of work to change though 🙈

Happy to spend some time to make those changes though.

We should also have a look at (finally) renaming all the c *testing.T to t *testing.T, but that's gonna be more fun to do (there's some tests that will have a conflicting variable, so may not be a straight "rename").

@crazy-max crazy-max force-pushed the split-test-suites branch 2 times, most recently from a2aef49 to ac12c09 Compare June 16, 2022 21:42
@crazy-max crazy-max force-pushed the split-test-suites branch from ac12c09 to 15716fc Compare June 17, 2022 08:59
@crazy-max
Copy link
Member Author

We should also have a look at (finally) renaming all the c *testing.T to t *testing.T, but that's gonna be more fun to do (there's some tests that will have a conflicting variable, so may not be a straight "rename").

Yes let's do that in a follow-up

@crazy-max crazy-max requested a review from thaJeztah June 22, 2022 09:22
Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

}

func TestDockerAPISuite(t *testing.T) {
ensureTestEnvSetup(t)
Copy link
Member

Choose a reason for hiding this comment

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

Not a blocker; mostly wondering if this should be part of / handled by suite.Run()

@thaJeztah
Copy link
Member

I'm bringing this one in; there was some discussion on Slack about the large number of jobs (as there's a job limit in GitHub actions); we'll likely run into that limit if we're gonna add Linux as well, but I think this gives the foundation to be flexible, and we can re-slice-and-dice once we run into those limits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants