Skip to content

ci: run tests in parallel (part 1)#2857

Merged
polarathene merged 5 commits intomasterfrom
tests/parallelize
Dec 3, 2022
Merged

ci: run tests in parallel (part 1)#2857
polarathene merged 5 commits intomasterfrom
tests/parallelize

Conversation

@georglauterbach
Copy link
Copy Markdown
Member

@georglauterbach georglauterbach commented Oct 23, 2022

Description

See notable changes below. Commit messages should help too.

Thanks to @polarathene for helping me with the history. I tried to apply the same pattern with the new commits.


Notable Changes

  • tests can now be arbitrarily grouped into subdirectories
  • some tests (test files to be more precise) are now run in parallel
  • CI will now spawn 4 jobs to run the whole test suite in parallel

Type of change

  • Improvement (non-breaking change that does improve existing functionality)

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation (README.md or the documentation under docs/)
  • If necessary I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@georglauterbach georglauterbach added area/ci kind/improvement Improve an existing feature, configuration file or the documentation labels Oct 23, 2022
@georglauterbach georglauterbach added this to the v11.3.0 milestone Oct 23, 2022
@georglauterbach georglauterbach self-assigned this Oct 23, 2022
@georglauterbach

This comment was marked as outdated.

@polarathene

This comment was marked as resolved.

@georglauterbach

This comment was marked as resolved.

@georglauterbach georglauterbach changed the title ci: run tests in parallel (part 1) [re-revision of #2850 which is a revision of #2822 itself] ci: run tests in parallel (part 1) [history to be revised] Oct 25, 2022
@georglauterbach georglauterbach marked this pull request as draft October 25, 2022 09:21
@georglauterbach

This comment was marked as resolved.

@polarathene
Copy link
Copy Markdown
Member

I've dropped the commit cited below for the following reasons:

  • The linked PR comment concern was about running generate-accounts multiple times. This doesn't change that, the matrix feature will run all steps on separate CI instances, thus will happen regardless and is necessary.
  • CI: true I assume from your commit message you maybe were wanting pretty output instead? Github has limited support here, it's able to support colour, but not other features/syntax used to manipulate terminal output AFAIK. I had looked into this back in August, and raised an issue at bats-core which explains that --pretty will not work.

If I'm mistaken and you intended something else, make this change in a separate PR as it's unrelated to this one 👍


Dropped commit

Commit message (original commit title differed):

tests(CI): Drop `CI: true` + separate step for `generate-accounts`
===
See https://github.com/docker-mailserver/docker-mailserver/pull/2822#discussion_r996283731

I also removed `CI: true` because I think GH Runners can now properly handle colored TTY output.

Commit Diff:

+      - name: 'Prepare tests'
+        run: make generate-accounts
+
      - name: 'Run tests'
-        run: make generate-accounts tests/${{ matrix.part }}
-        env:
-          CI: true
+        run: make tests/${{ matrix.part }}

@polarathene

This comment was marked as resolved.

@polarathene
Copy link
Copy Markdown
Member

polarathene commented Oct 28, 2022

Commit history has been revised, here's a breakdown:

  1. 3fc8945 - Move all existing tests into their serial / parallel subdirectories.
  2. 638eedb - @georglauterbach modified some tests here, presumably as an example of changes / improvements for a future PR to make to all other tests as a convention. I have written a more detailed commit message highlighting the changes covered in the diffs, noting the common change across files and some file specific ones that stood out.
  3. 01a498d - Has a bit more going on. I'm not quite following the comment explanation for using explicit / hard-coded container names instead of the ENV var that had been working, apparently that breaks with the parallel feature? (couldn't we just assign different var names though?)
  4. 7b00907 - Adds what looks like a reference / example (template.bats) to copy / paste for new tests, or for updating existing tests with to support parallel testing? The additional serial test I haven't looked over yet, and doesn't seem relevant to this PR, but a separate test in itself that could have been added via it's own PR?
  5. 369e4b4 - Besides the file renames, the bulk of files changed is just the top line to use an absolute path via REPOSITORY_ROOT (defined in the Makefile), this allows for the nested test folders to properly load test helpers.
  6. 5789915 - Finally, all changes to Makefile and the CI testing workflow is bundled into this commit. The commit message is revised based on the content of multiple original commit messages for these file changes from @georglauterbach .

Notes

  • I have made a slight error it seems. serial/no_container.bats was renamed to serial/setup.sh.bats thus there is an actual diff between the two to review, it is not a new test file.
  • The github review view is not too helpful with some files. This is due to the diff being a merge commit one, that is unable to recognize some files that were renamed and received changes from @georglauterbach are the same file... So you'll want to refer to the actual commit to review the diff there (the commit message should summarize the diff fairly well).

@polarathene polarathene marked this pull request as ready for review October 28, 2022 23:36
Copy link
Copy Markdown
Member

@polarathene polarathene left a comment

Choose a reason for hiding this comment

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

I've now reviewed almost everything (I still need to go over setup.sh.bats (previously no_containers.bats).

Majority of feedback is questions for clarification on changes, or additions and possible improvements. No change requests atm 👍

Comment thread Makefile
Comment thread Makefile
Comment thread Makefile Outdated
Comment thread Makefile
Comment thread test/tests/parallel/set1/default_relay_host.bats Outdated
Comment thread test/tests/parallel/set2/test_helper.bats Outdated
Comment thread test/tests/parallel/set2/test_helper.bats Outdated
Comment thread test/tests/parallel/set2/test_helper.bats Outdated
Comment thread test/tests/serial/setup.sh.bats Outdated
Comment thread test/tests/parallel/set3/helper-functions.bats Outdated
@georglauterbach
Copy link
Copy Markdown
Member Author

Will answer the rest of the question later - not enough time at the moment :)

@georglauterbach georglauterbach changed the title ci: run tests in parallel (part 1) [history to be revised] ci: run tests in parallel (part 1) Nov 1, 2022
@georglauterbach

This comment was marked as outdated.

@georglauterbach

This comment was marked as outdated.

@georglauterbach
Copy link
Copy Markdown
Member Author

So I revised the commit history and did some things in a slightly different way. Had to force-push the branch - hope you don't mind.

Comment thread test/helper/common.bash
georglauterbach added a commit that referenced this pull request Nov 3, 2022
Comment thread Makefile
Comment on lines +43 to +49
tests: ALWAYS_RUN
@ $(MAKE) generate-accounts tests/serial
@ $(MAKE) generate-accounts tests/parallel/set1
@ $(MAKE) generate-accounts tests/parallel/set2
@ $(MAKE) generate-accounts tests/parallel/set3
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I switched to this syntax as I encountered issues before when generate-accounts was not run before certain parallel tests were run because of prior modifications. Just FYI.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

BTW, do I miss something, where is the ALWAYS_RUN target? I only see references to it.

Copy link
Copy Markdown
Member Author

@georglauterbach georglauterbach Nov 4, 2022

Choose a reason for hiding this comment

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

At the top of the file; it is not defined as a target like ALWAYS_RUN:, but just as .PHONY: ALWAYS_RUN :) This suffices to tell make to always run the target.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

tests: ALWAYS_RUN
	@ $(MAKE) generate-accounts tests/serial
	@ $(MAKE) generate-accounts tests/parallel/set1
	@ $(MAKE) generate-accounts tests/parallel/set2
	@ $(MAKE) generate-accounts tests/parallel/set3

Can you clarify why we have generate-accounts repeated here? Is this some syntax to express a dependency, or does it run make generate-accounts 4 times?

Copy link
Copy Markdown
Member

@polarathene polarathene left a comment

Choose a reason for hiding this comment

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

Finally got around to tackling the review 😅

I am expecting I won't have much time for feedback next weekend, thanks for the patience 🙏 I know this PR has a slow feedback cycle from me, but I really appreciate the time and effort you've put into tackling this 💪


So far it's looking good 👍

Just making notes about some changes I noticed, few minor change suggestions, and some questions about new stuff you've done.

I reviewed iterating through the commit history, the commit messages you added were appreciated :)

Comment thread test/helper/setup.bash Outdated
Comment thread test/helper/common.bash Outdated
Comment thread test/helper/setup.bash
Comment thread test/helper/setup.bash
Comment thread test/helper/setup.bash
Comment thread test/tests/parallel/set2/template.bats Outdated
Comment thread test/tests/parallel/set2/template.bats Outdated
Comment thread test/tests/parallel/set3/dovecot_inet_protocol.bats Outdated
Comment thread test/tests/parallel/set3/dovecot_inet_protocol.bats Outdated
Comment thread test/helper/setup.bash
@georglauterbach
Copy link
Copy Markdown
Member Author

In commit 22d358f you reverted some changes you introduced.

The commit message explains why, but I am curious about some of the reverted content. Noting here in case you'd like to add via a follow-up PR at some point:

The file in question probably needs a dedicated follow-up PR indeed. I completely reverted the changes because I was not sure on how much of an impact my initial changes were and why some of the changes lead to test failures. In short: The questions you stated should indeed be picked up later; I cannot give you a comprehensive answer as I currently lack the answers and a proper explanation myself.

@georglauterbach
Copy link
Copy Markdown
Member Author

@polarathene for some reason I cannot directly answer #2857 (comment), so here it is:

generate-accounts is run 4 times, because I observed some test files alter the accounts files which leads to other tests failing for no apparent reason. There is some sort of dependency here on the order test files that are run. This is not optimal, but currently solved by running the generate-accounts target before every new test set invocation.

@polarathene
Copy link
Copy Markdown
Member

In short: The questions you stated should indeed be picked up later; I cannot give you a comprehensive answer as I currently lack the answers and a proper explanation myself.

No worries, that can be looked into after this is merged then 👍

polarathene
polarathene previously approved these changes Nov 13, 2022
Copy link
Copy Markdown
Member

@polarathene polarathene left a comment

Choose a reason for hiding this comment

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

LGTM, might be nice to add some contextual maintenance comments, but otherwise I'm happy with current progress and we can revise the commit history once another approval comes in.

Comment thread test/helper/setup.bash
@georglauterbach
Copy link
Copy Markdown
Member Author

@casperklein @polarathene I pushed the commits addressing the latest PR feedback. Hope all as well now - happy final reviewing :D

Copy link
Copy Markdown
Member

@polarathene polarathene left a comment

Choose a reason for hiding this comment

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

Awesome work thanks! 🥳

casperklein
casperklein previously approved these changes Nov 14, 2022
Copy link
Copy Markdown
Member

@polarathene polarathene left a comment

Choose a reason for hiding this comment

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

I'll handle the interactive rebase before we merge this when I have some time spare 👍

@polarathene
Copy link
Copy Markdown
Member

polarathene commented Nov 26, 2022

Apologies for the delay, finally got around to tackling this! 😀

  • Refactored commit history from 24 commits down to 5.
  • Commit messages rewritten accordingly.
  • There is no difference in output to review.

Upon approval, merge via merge commit or rebase, not squash.


Commit messages:

tests(chore): Rename test files to serial and parallel types

  • test_helper.bats needs more work than this PR provides to be compatible with parallel tests, so must remain as a serial test for now.
  • spam_bounced.bats had failures as a serial test, but works well converted to a parallel test in a future commit.

tests(CI): Adjust Makefile & GHA workflow to support new test layout

These updates support running tests that have been relocated into serial and parallel/set* directories.

  • make tests now calls the two make targets beneath it. The only difference is that serial continues the "1 test at a time" approach used prior to this PR, while the parallel target increases the --jobs arg to run multiple tests concurrently (configured by PARALLEL_JOBS).
  • The test/% target leverages Bash syntax magic to ease running single tests without providing the exact path.
  • This syntax also supports providing multiple test names (eg: make test/clamav,template) to run.
  • ** (globstar) allows for future improvements that can group multiple test files into sub-directories by their scope (eg: anti-spam, ssl, etc).

chore: Add shopt -s globstar to other targets
I realized that other targets should have this as well in case it is not set.
It is better to be more explicit here than to have weird errors due to ** not expanding properly.


fix(Makefile): Add back .PHONY targets

I encountered make telling me the target was already up-to-date, which of course is nonsense.
I therefore added back the .PHONY targets to ensure tests are always run.


docs: Added instructions for running a single test
See https://github.com/docker-mailserver/docker-mailserver/pull/2857/files#r1008582760

tests(chore): Use REPOSITORY_ROOT export var from Makefile

Allows for using load with an absolute path instead of a relative one, which makes it possible to group tests into different directories.

Parallel tests differ slightly, loading the newer helper/common.bash and helper/setup.bash files instead of the older test_helper/common.bash which serial tests continue to use.

tests(refactor): common.bash helper split into two files

The current test/test_helper/common.bash was getting large. Setup logic has been extracted out into a new file.

common.bash resides in a directory named test_helper/, the test_ prefix is redundant.

As an interim solution this provides a new approach for the updated tests, while the "old" tests can use the "old" common.bash. Eventually all tests should migrate to the new approach in helper/ instead of the older test_helper/.

The new helper files are located under test/helper/ (which drops the test_ prefix). The new and updated helpers apply the new naming convention for ENV variables (such as CONTAINER_NAME or IMAGE_NAME).


Some refactoring occurred, including new methods like _run_in_container() and _default_teardown().


I encountered a situation before in which the updated tests would fail because there were collisions of ENV names in the tests (for example with CONTAINER_NAME).

tests(refactor): Conversion to parallel tests and use revised helpers

  • Introduced CONTAINER_NAME and TEST_NAME_PREFIX as new vars for better managing test consistency (DRY).
  • CONTAINER_NAME replaces any repeated container name with the variable. The value will differ slightly as the prior prefix (mail_) has been changed to dms-test-.
  • TEST_NAME_PREFIX provides a prefix value for each @test description string.

chore: Add a reference template for tests

georglauterbach and others added 5 commits November 26, 2022 14:52
- `test_helper.bats` needs more work than this PR provides to be compatible with parallel tests, so must remain as a serial test for now.
- `spam_bounced.bats` had failures as a serial test, but works well converted to a parallel test in a future commit.
These updates support running tests that have been relocated into `serial` and `parallel/set*` directories.

- `make tests` now calls the two make targets beneath it. The only difference is that `serial` continues the "1 test at a time" approach used prior to this PR, while the `parallel` target increases the `--jobs` arg to run multiple tests concurrently (_configured by `PARALLEL_JOBS`_).
- The `test/%` target leverages Bash syntax magic to ease running single tests without providing the exact path.
- This syntax also supports providing multiple test names (eg: `make test/clamav,template`) to run.
- `**` (globstar) allows for future improvements that can group multiple test files into sub-directories by their scope (eg: anti-spam, ssl, etc).

---

chore: Add `shopt -s globstar` to other targets
I realized that other targets should have this as well in case it is not set.
It is better to be more explicit here than to have weird errors due to `**` not expanding properly.

---

fix(Makefile):  Add back `.PHONY` targets

I encountered `make` telling me the target was already up-to-date, which of course is nonsense.
I therefore added back the `.PHONY` targets to ensure tests are always run. 

---

docs: Added instructions for running  a single test
See https://github.com/docker-mailserver/docker-mailserver/pull/2857/files#r1008582760
Allows for using `load` with an absolute path instead of a relative one, which makes it possible to group tests into different directories.

Parallel tests differ slightly, loading the newer `helper/common.bash` and `helper/setup.bash` files instead of the older `test_helper/common.bash` which serial tests continue to use.
The current `test/test_helper/common.bash` was getting large. Setup logic has been extracted out into a new file.

`common.bash` resides in a directory  named `test_helper/`, the `test_` prefix is redundant. 

As an interim solution this provides a new approach for the updated tests, while the "old" tests can use the "old" `common.bash`. Eventually all tests should migrate to the new approach in `helper/` instead of the older `test_helper/`.

The new helper files are located under `test/helper/` (_which drops the `test_` prefix_). The new and updated helpers apply the new naming convention for ENV variables (_such as `CONTAINER_NAME` or `IMAGE_NAME`_).

---

Some refactoring occurred, including new methods like `_run_in_container()` and `_default_teardown()`.

---

I encountered a situation before in which the updated tests would fail because there were collisions of ENV names in the tests (_for example with `CONTAINER_NAME`_).
- Introduced `CONTAINER_NAME` and `TEST_NAME_PREFIX` as new vars for better managing test consistency (DRY).
- `CONTAINER_NAME` replaces any repeated container name with the variable. The value will differ slightly as the prior prefix (`mail_`) has been changed to `dms-test-`.
- `TEST_NAME_PREFIX` provides a prefix value for each `@test` description string.

---

chore: Add a reference template for tests
@github-actions
Copy link
Copy Markdown
Contributor

Documentation preview for this PR is ready! 🎉

Built with commit: 75ee0c1

Copy link
Copy Markdown
Member

@polarathene polarathene left a comment

Choose a reason for hiding this comment

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

🥳

@georglauterbach
Copy link
Copy Markdown
Member Author

ping @casperklein - when you provide approval for this PR (nothing has changed except commit count and descriptions), I think we can start releasing 11.3.

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

Labels

area/ci kind/improvement Improve an existing feature, configuration file or the documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants