Skip to content

feat: add optional asynchronous/parallel support#312

Draft
Daan Timmer (daantimmer) wants to merge 2 commits intomainfrom
feature/add-optional-parallel/async-support
Draft

feat: add optional asynchronous/parallel support#312
Daan Timmer (daantimmer) wants to merge 2 commits intomainfrom
feature/add-optional-parallel/async-support

Conversation

@daantimmer
Copy link
Collaborator

No description provided.

Copilot AI review requested due to automatic review settings March 18, 2026 09:32
@daantimmer Daan Timmer (daantimmer) changed the title feat: add parallel support feat: add optional asynchronous/parallel support Mar 18, 2026
@daantimmer Daan Timmer (daantimmer) marked this pull request as draft March 18, 2026 09:32
@github-actions
Copy link

github-actions bot commented Mar 18, 2026

⚠️MegaLinter analysis: Success with warnings

Descriptor Linter Files Fixed Errors Warnings Elapsed time
✅ ACTION actionlint 6 0 0 0.02s
✅ CPP clang-format 231 0 0 0 1.81s
✅ DOCKERFILE hadolint 1 0 0 0.03s
✅ JSON jsonlint 8 0 0 0.38s
✅ JSON prettier 8 6 0 0 0.65s
⚠️ MARKDOWN markdownlint 6 3 16 0 1.19s
✅ MARKDOWN markdown-table-formatter 6 3 0 0 0.33s
✅ REPOSITORY git_diff yes no no 0.03s
✅ REPOSITORY grype yes no no 33.12s
✅ REPOSITORY ls-lint yes no no 0.1s
✅ REPOSITORY secretlint yes no no 4.17s
✅ REPOSITORY syft yes no no 1.25s
✅ REPOSITORY trivy yes no no 10.04s
✅ REPOSITORY trivy-sbom yes no no 0.26s
✅ REPOSITORY trufflehog yes no no 4.37s
⚠️ SPELL lychee 85 1 0 5.22s
✅ YAML prettier 10 0 0 0 0.82s
✅ YAML v8r 10 0 0 7.41s
✅ YAML yamllint 10 0 0 0.65s

Detailed Issues

⚠️ SPELL / lychee - 1 error
[404] https://github.com/yourname/amp-cucumber-cpp-runner.git | Network error: Not Found
📝 Summary
---------------------
🔍 Total..........158
✅ Successful.....157
⏳ Timeouts.........0
🔀 Redirected.......0
👻 Excluded.........0
❓ Unknown..........0
🚫 Errors...........1

Errors in CONTRIBUTING.md
[404] https://github.com/yourname/amp-cucumber-cpp-runner.git | Network error: Not Found
⚠️ MARKDOWN / markdownlint - 16 errors
CHANGELOG.md:30 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Features"]
CHANGELOG.md:37 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Chores"]
CHANGELOG.md:45 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "⚠ BREAKING CHANGES"]
CHANGELOG.md:49 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Features"]
CHANGELOG.md:58 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Features"]
CHANGELOG.md:64 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Chores"]
CHANGELOG.md:72 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "⚠ BREAKING CHANGES"]
CHANGELOG.md:76 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Features"]
CHANGELOG.md:81 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Bug Fixes"]
CHANGELOG.md:90 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Features"]
CHANGELOG.md:101 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Chores"]
CHANGELOG.md:109 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "⚠ BREAKING CHANGES"]
CHANGELOG.md:113 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Features"]
CHANGELOG.md:138 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Bug Fixes"]
CHANGELOG.md:145 error MD024/no-duplicate-heading Multiple headings with the same content [Context: "Chores"]
README.md:114 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]

See detailed reports in MegaLinter artifacts

Your project could benefit from a custom flavor, which would allow you to run only the linters you need, and thus improve runtime performances. (Skip this info by defining FLAVOR_SUGGESTIONS: false)

  • Documentation: Custom Flavors
  • Command: npx mega-linter-runner@9.4.0 --custom-flavor-setup --custom-flavor-linters ACTION_ACTIONLINT,CPP_CLANG_FORMAT,DOCKERFILE_HADOLINT,JSON_JSONLINT,JSON_PRETTIER,MARKDOWN_MARKDOWNLINT,MARKDOWN_MARKDOWN_TABLE_FORMATTER,REPOSITORY_GIT_DIFF,REPOSITORY_GRYPE,REPOSITORY_LS_LINT,REPOSITORY_SECRETLINT,REPOSITORY_SYFT,REPOSITORY_TRIVY,REPOSITORY_TRIVY_SBOM,REPOSITORY_TRUFFLEHOG,SPELL_LYCHEE,YAML_PRETTIER,YAML_YAMLLINT,YAML_V8R

MegaLinter is graciously provided by OX Security
Show us your support by starring ⭐ the repository

Choose a reason for hiding this comment

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

[MegaLinter] reported by reviewdog 🐶

"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${command:cmake.launchTargetPath}",
"args": [
"--format",
"pretty",
// "summary",
"--parallel",
"2",
"--fail-fast",
"--retry",
"1",
"--tags",
"${input:tag}",
"--",
"${input:features}"
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [
{
"name": "ASAN_OPTIONS",
"value": "detect_leaks=0"
}
],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
},

Choose a reason for hiding this comment

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

[MegaLinter] reported by reviewdog 🐶

"version": 6,
"cmakeMinimumRequired": {
"major": 3,
"minor": 24,
"patch": 0
},
"configurePresets": [
{
"name": "defaults",
"hidden": true,
"binaryDir": "${sourceDir}/.build/${presetName}",
"installDir": "${sourceDir}/.install/${presetName}",
"cacheVariables": {
"CMAKE_EXPORT_COMPILE_COMMANDS": "On",
"CMAKE_CONFIGURATION_TYPES": "Debug;RelWithDebInfo;Release",
"CMAKE_C_COMPILER_LAUNCHER": "ccache",
"CMAKE_CXX_COMPILER_LAUNCHER": "ccache"
}
},
{
"name": "Coverage",
"inherits": "defaults",
"generator": "Ninja",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CCR_ENABLE_COVERAGE": "On"
}
},
{
"name": "Host",
"inherits": "defaults",
"generator": "Ninja Multi-Config"
},
{
"name": "Host-Parallel",
"inherits": "Host",
"generator": "Ninja Multi-Config",
"cacheVariables": {
"CCR_ENABLE_PARALLEL_SUPPORT": "On"
}
},
{
"name": "host-single-Debug",
"displayName": "Configuration for Host Tooling and Tests, Single Config Generator, Debug",
"inherits": "defaults",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "host-single-time-profile",
"displayName": "Configuration time profiling",
"inherits": "defaults",
"cacheVariables": {
"CMAKE_C_COMPILER": "clang",
"CMAKE_CXX_COMPILER": "clang++",
"CMAKE_BUILD_TYPE": "Debug",
"CCR_ENABLE_TIME_PROFILE": "On"
}
},
{
"name": "Host-Iwyu",
"inherits": "defaults",
"cacheVariables": {
"CMAKE_CXX_INCLUDE_WHAT_YOU_USE": "include-what-you-use;-Wno-unknown-warning-option;-Xiwyu;--no_comments;-Xiwyu;--cxx17ns;-Xiwyu;--no_fwd_decls"
},
"generator": "Ninja Multi-Config"
},
{
"name": "Windows",
"inherits": "defaults",
"toolchainFile": "${sourceDir}/cmake/toolchain-clang-x86_64-pc-windows-msvc.cmake",
"environment": {
"CCACHE_DEPEND": "true",
"CCACHE_COMPILERTYPE": "clang-cl"
},
"generator": "Ninja Multi-Config"
},
{
"name": "Windows-Parallel",
"inherits": "Windows",
"cacheVariables": {
"CCR_ENABLE_PARALLEL_SUPPORT": "On"
}
}
],
"buildPresets": [
{
"name": "Coverage",
"configurePreset": "Coverage"
},
{
"name": "Host-Release",
"configuration": "Release",
"configurePreset": "Host"
},
{
"name": "Host-Debug",
"configuration": "Debug",
"configurePreset": "Host",
"jobs": 4
},
{
"name": "Host-Iwyu-Debug",
"configuration": "Debug",
"configurePreset": "Host-Iwyu"
},
{
"name": "host-single-Debug",
"configuration": "Debug",
"configurePreset": "host-single-Debug"
},
{
"name": "host-single-time-profile",
"configuration": "Debug",
"configurePreset": "host-single-time-profile"
},
{
"name": "Windows-Release",
"configuration": "Release",
"configurePreset": "Windows"
},
{
"name": "Windows-RelWithDebInfo",
"configuration": "RelWithDebInfo",
"configurePreset": "Windows"
},
{
"name": "Windows-Debug",
"configuration": "Debug",
"configurePreset": "Windows"
}
],
"testPresets": [
{
"name": "defaults",
"hidden": true,
"output": {
"outputOnFailure": true
},
"execution": {
"noTestsAction": "error",
"stopOnFailure": true
}
},
{
"name": "Coverage",
"configurePreset": "Coverage",
"configuration": "Debug",
"inherits": "defaults"
},
{
"name": "Host-Debug",
"configurePreset": "Host",
"configuration": "Debug",
"inherits": "defaults"
},
{
"name": "Host-Release",
"configurePreset": "Host",
"configuration": "Release",
"inherits": "defaults"
},
{
"name": "host-single-Debug",
"configurePreset": "host-single-Debug",
"configuration": "Debug",
"inherits": "defaults"
}
]

@github-actions
Copy link

github-actions bot commented Mar 18, 2026

Test Results

30 tests  +3   30 ✅ +3   29s ⏱️ -1s
 1 suites ±0    0 💤 ±0 
 1 files   ±0    0 ❌ ±0 

Results for commit 5952264. ± Comparison against base commit 379a56b.

♻️ This comment has been updated with latest results.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds optional parallel scenario execution to the cucumber-cpp runner (guarded behind CCR_ENABLE_PARALLEL_SUPPORT / ENABLE_PARALLEL_SUPPORT) by introducing a libcoro-backed runtime adapter, along with supporting refactors to broadcasting and runtime wiring.

Changes:

  • Add optional libcoro dependency plumbing and CMake presets for enabling parallel support.
  • Refactor util::Broadcaster into an interface + BroadcasterImpl implementation to support parallelized event emission.
  • Introduce ParallelRuntimeAdapter selected via new --parallel runtime option (when compiled with parallel support).

Reviewed changes

Copilot reviewed 27 out of 27 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
external/jbaldwin/libcoro/CMakeLists.txt FetchContent integration for libcoro and warning suppression configuration.
external/jbaldwin/CMakeLists.txt Adds jbaldwin subtree (libcoro) to the build.
external/CMakeLists.txt Conditionally includes jbaldwin deps when CCR_ENABLE_PARALLEL_SUPPORT is on.
cucumber_cpp/library/util/Broadcaster.hpp Converts broadcaster into an abstract interface; adds BroadcasterImpl.
cucumber_cpp/library/util/Broadcaster.cpp Moves implementations onto BroadcasterImpl; minor const-correctness tweak.
cucumber_cpp/library/support/Types.hpp Adds parallel option to runtime config; tweaks enum underlying type.
cucumber_cpp/library/runtime/Worker.hpp Exposes hook/suite helpers needed by adapters; adds [[nodiscard]].
cucumber_cpp/library/runtime/Worker.cpp Removes suite-level runner; small logic simplification and envelope construction tweaks.
cucumber_cpp/library/runtime/SerialRuntimeAdapter.hpp Adds RunTestSuite(...) helper and includes for moved logic.
cucumber_cpp/library/runtime/SerialRuntimeAdapter.cpp Hosts suite-level execution logic previously in Worker.
cucumber_cpp/library/runtime/ParallelRuntimeAdapter.hpp New parallel runtime adapter interface (libcoro-based).
cucumber_cpp/library/runtime/ParallelRuntimeAdapter.cpp New parallel execution implementation with thread pool + queued broadcasting.
cucumber_cpp/library/runtime/MakeRuntime.hpp Removes exported MakeAdapter declaration (now internal).
cucumber_cpp/library/runtime/MakeRuntime.cpp Selects serial vs parallel adapter based on options.parallel + build flag.
cucumber_cpp/library/runtime/CMakeLists.txt Conditionally builds/links parallel adapter + libcoro; defines ENABLE_PARALLEL_SUPPORT.
cucumber_cpp/library/query/Query.hpp Switches Query to inherit BroadcasterImpl (since Broadcaster is now abstract).
cucumber_cpp/library/formatter/helper/Theme.cpp Removes unused optional helper.
cucumber_cpp/library/formatter/UsageFormatter.cpp Avoids structured binding copies in loop.
cucumber_cpp/library/formatter/SummaryFormatter.cpp Avoids structured binding copies; removes unused locals.
cucumber_cpp/library/engine/test/TestStep.cpp Updates test fixture broadcaster type to BroadcasterImpl.
cucumber_cpp/library/Application.hpp Adds parallel CLI option storage; updates broadcaster type + integer widths.
cucumber_cpp/library/Application.cpp Registers --parallel when compiled with parallel support; plumbs into RunOptions.
compatibility/BaseCompatibility.cpp Updates broadcaster type to BroadcasterImpl.
CMakePresets.json Adds Host/Windows presets enabling parallel support.
CMakeLists.txt Introduces CCR_ENABLE_PARALLEL_SUPPORT option; finds libcoro when enabled; standard settings moved earlier.
.vscode/launch.json Updates debug args to include parallel run flags.
.clang-tidy Disables coroutine reference-parameter guideline warning.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +43 to +55
coro::task<void> RunTestCase(std::unique_ptr<coro::thread_pool>& tp, coro::latch& tasksLatch, runtime::Worker& worker, const cucumber::messages::gherkin_document& gherkinDocument, const assemble::AssembledTestCase& assembledTestCase, Context& testSuiteContext, bool& failing)
{
co_await tp->schedule();

try
{
failing |= !worker.RunTestCase(gherkinDocument, assembledTestCase, testSuiteContext, failing);
}
catch (...)
{
failing = true;
}

Comment on lines +150 to +159
coro::latch taskLatch{ 10 * std::ranges::distance(assembledTestSuites | std::views::transform([](const auto& suite)
{
return suite.testCases;
}) |
std::views::join) };

for (const auto& assembledTestSuite : assembledTestSuites)
for (const auto& assembledTestCase : assembledTestSuite.testCases)
for (auto i{ 0 }; i < 10; ++i)
tasks.emplace_back(RunTestCase(threadPool, taskLatch, parallelWorker, assembledTestSuite.gherkinDocument, assembledTestCase, programContext, failing));
Comment on lines +150 to +160
coro::latch taskLatch{ 10 * std::ranges::distance(assembledTestSuites | std::views::transform([](const auto& suite)
{
return suite.testCases;
}) |
std::views::join) };

for (const auto& assembledTestSuite : assembledTestSuites)
for (const auto& assembledTestCase : assembledTestSuite.testCases)
for (auto i{ 0 }; i < 10; ++i)
tasks.emplace_back(RunTestCase(threadPool, taskLatch, parallelWorker, assembledTestSuite.gherkinDocument, assembledTestCase, programContext, failing));

Comment on lines +150 to +155
coro::latch taskLatch{ 10 * std::ranges::distance(assembledTestSuites | std::views::transform([](const auto& suite)
{
return suite.testCases;
}) |
std::views::join) };

Comment on lines +1 to +16
add_compile_options(-Wno-missing-field-initializers)

FetchContent_Declare(
libcoro
GIT_REPOSITORY https://github.com/jbaldwin/libcoro.git
GIT_TAG 0161911f260a7507ac1dd4aa26da2e2c092fb550 # v0.16.0
SYSTEM
)

set(LIBCORO_FEATURE_TLS OFF CACHE STRING "")
set(LIBCORO_BUILD_TESTS OFF CACHE STRING "")
set(LIBCORO_BUILD_EXAMPLES OFF CACHE STRING "")

FetchContent_MakeAvailable(libcoro)

target_compile_options(libcoro INTERFACE $<$<COMPILE_LANGUAGE:CXX>:-Wno-extra>)
@@ -0,0 +1,170 @@
#include "cucumber_cpp/library/runtime/ParallelRuntimeAdapter.hpp"
#include ".build/Host-Iwyu/_deps/libfmt-src/include/fmt/format.h"
@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
44.4% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

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.

2 participants