Skip to content

Generate certificates in unit-test fixtures to fix parallel test execution#10767

Merged
julianbrost merged 5 commits intomasterfrom
certificate_fixture_two_electric_boogaloo
Apr 7, 2026
Merged

Generate certificates in unit-test fixtures to fix parallel test execution#10767
julianbrost merged 5 commits intomasterfrom
certificate_fixture_two_electric_boogaloo

Conversation

@jschmidt-icinga
Copy link
Copy Markdown
Contributor

@jschmidt-icinga jschmidt-icinga commented Mar 24, 2026

Description

Currently in master, parallel test execution is broken, because the tests that need TLS certificates overwrite each other's certificate files in the middle of tests. This PR fixes parallel test execution by generating CTest fixture units to set up each certificate once for all tests that require it and using CTest's dependency resolution to run those units before the actual tests.

Implementation

A new unit-test decorator RequiresCertificate is added that can be constructed with a list of certificates that this test requires and a prefix domain the test belongs to. Tests from different prefix domains are not run in parallel with each other and a cleanup will be performed in between the groups.

On instantiation, this decorator will add CTest fixtures for the setup and cleanup of the CA and required certificates (if no other test has added them yet). CTest fixtures are themselves test-units that are put into a dependency relationship with their associated test-cases by CTest and it is ensured that the setup routine runs before all tests that require the fixture and the cleanup routine runs after these tests. The fixtures are shared by all tests that require the same certificates with the same prefix.

The old prepare_directory_* and cleanup_certs tests that made up the ssl_certs fixture were removed in favor of these new fixtures. And the CertificateFixture Boost.Test fixture (which gets run once per test) no longer does any setup and cleanup on its own. All it does now is copy the certificates from the persistent directory to the local test directory, which has been prefixed with a UUID to make it unique between tests.

Rationale

The generation of the fixture units is fairly complex for currently not a lot of (current) usage, but it is a general proper solution, unlike the increasingly ugly workarounds that the lazy generation of certificates and manually added ssl_certs_* fixtures that do much other than enforce ordering between the tests. Recently I attempted to fix another problem this caused in #10749, which added more workarounds, but I should have gone with this solution instead.

Parallel execution of tests is the default on for example the build scripts of Gentoo and maybe other distros and our CI could also benefit from it. See below for a comparison of serialized vs parallel test execution. Just requiring downstream to turn off parallel testing because our tests break with it would also not be a good look so this fixes it to run as much in parallel as possible.

Before

$ ctest --parallel --output-on-failure
<various errors>
$ ctest --output-on-failure
[...]
Total Test time (real) =  12.80 sec

After

$ ctest --parallel --output-on-failure
[...]
Total Test time (real) =   3.53 sec

Other Changes

Since I was editing those lines anyway I also added the network label to the http unit-tests which fixes #10722.

@cla-bot cla-bot bot added the cla/signed label Mar 24, 2026
@jschmidt-icinga jschmidt-icinga force-pushed the certificate_fixture_two_electric_boogaloo branch 7 times, most recently from 16d03ed to ad696eb Compare March 25, 2026 13:20
@jschmidt-icinga jschmidt-icinga marked this pull request as ready for review March 25, 2026 14:35
@jschmidt-icinga jschmidt-icinga force-pushed the certificate_fixture_two_electric_boogaloo branch from ad696eb to 1e86025 Compare March 26, 2026 08:25
@jschmidt-icinga jschmidt-icinga added this to the 2.16.0 milestone Mar 30, 2026
Copy link
Copy Markdown
Member

@yhabteab yhabteab left a comment

Choose a reason for hiding this comment

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

Too much low-level boost test framework stuff, but seems to just work fine. I've left just some nitpicking comments, but overall I don't see any major issues. However, why aren't the GHA tests running in parallel now? Instead of postponing that change into the future, I think we should just do it now, as it could help us catch some issues not triggered on my/your local machine.

@jschmidt-icinga
Copy link
Copy Markdown
Contributor Author

However, why aren't the GHA tests running in parallel now? Instead of postponing that change into the future, I think we should just do it now, as it could help us catch some issues not triggered on my/your local machine.

Agreed. I'll add a commit to change the GHAs and ContainerImage to use the parallel tests.

@jschmidt-icinga jschmidt-icinga force-pushed the certificate_fixture_two_electric_boogaloo branch from 1e86025 to 529d42e Compare March 30, 2026 11:46
@jschmidt-icinga
Copy link
Copy Markdown
Contributor Author

jschmidt-icinga commented Mar 30, 2026

  • Fixed the formatting mistakes and requested minor changes.
  • Now uses ctest --parallel --output-on-failure on Linux and Windows GHAs and on the ContainerImage build. Let's see if it works properly on all targets.

Too much low-level boost test framework stuff

I agree, but it's supported low-level functionality that hasn't changed in ages, so the added maintenance burden should be minimal. And registering test-cases programmatically is something every modern C++ unit-test framework has, so migrating to a different one (like doctest or catch2 for example) should be as easy as switching out the function calls to register the new test cases. Many even have an identical syntax to add decorators.

@jschmidt-icinga jschmidt-icinga force-pushed the certificate_fixture_two_electric_boogaloo branch from 529d42e to a8a32d5 Compare March 30, 2026 11:57
@jschmidt-icinga jschmidt-icinga force-pushed the certificate_fixture_two_electric_boogaloo branch 7 times, most recently from c5633ba to 383dc5f Compare March 31, 2026 14:28
Mostly unrelated change to add the network label to test suites
already touched by other changes in this PR. The label is already
used for the perfdata writer tests to make it easy to exclude tests
that need a network connection when building and testing in a sandbox.
This is necessary for parallel test execution so that tests don't overwrite
or delete (destructor of the fixture) data in these directories.

This is implemented by generating a unique name for each test with
`Utility::NewUniqueId()`.
@jschmidt-icinga jschmidt-icinga force-pushed the certificate_fixture_two_electric_boogaloo branch 4 times, most recently from 01d5a2b to 1e4f1ec Compare April 1, 2026 10:38
@yhabteab yhabteab mentioned this pull request Apr 1, 2026
8 tasks
@jschmidt-icinga jschmidt-icinga force-pushed the certificate_fixture_two_electric_boogaloo branch 6 times, most recently from e66682f to a05e2a3 Compare April 2, 2026 13:41
@jschmidt-icinga
Copy link
Copy Markdown
Contributor Author

I've given up on enabling and fixing the parallel builds for the Container Image for now and will do that in a separate PR so we can review and possibly merge this in the meantime.

@yhabteab
Copy link
Copy Markdown
Member

yhabteab commented Apr 2, 2026

Shouldn't this PR also fix #10722?

@julianbrost julianbrost merged commit a810d64 into master Apr 7, 2026
28 checks passed
@julianbrost julianbrost deleted the certificate_fixture_two_electric_boogaloo branch April 7, 2026 07:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HTTP server tests broken on master in network sandbox

3 participants