Allow test sharding for e.g. Bazel test sharding feature
This greatly simplifies running Catch2 tests in single binary in parallel from external test runners. Instead of having to shard the tests by tags/test names, an external test runner can now just ask for test shard 2 (out of X), and execute that in single process, without having to know what tests are actually in the shard. Note that sharding also applies to test listing, and happens after tests were ordered according to the `--order` feature.
This commit is contained in:
1 parent
6456ee8b01
commit
3087e19cc7
21 files changed
+415
-6
No files matched your search
@@ -149,6 +149,15 @@ namespace Catch {
|
||||
return ParserResult::runtimeError( "Unrecognized reporter, '" + reporter + "'. Check available with --list-reporters" );
|
||||
return ParserResult::ok( ParseResultType::Matched );
|
||||
};
|
||||
auto const setShardCount = [&]( std::string const& shardCount ) {
|
||||
auto result = Clara::Detail::convertInto( shardCount, config.shardCount );
|
||||
|
||||
if (config.shardCount == 0) {
|
||||
return ParserResult::runtimeError( "The shard count must be greater than 0" );
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
auto cli
|
||||
= ExeName( config.processName )
|
||||
@@ -240,6 +249,12 @@ namespace Catch {
|
||||
| Opt( config.benchmarkWarmupTime, "benchmarkWarmupTime" )
|
||||
["--benchmark-warmup-time"]
|
||||
( "amount of time in milliseconds spent on warming up each test (default: 100)" )
|
||||
| Opt( setShardCount, "shard count" )
|
||||
["--shard-count"]
|
||||
( "split the tests to execute into this many groups" )
|
||||
| Opt( config.shardIndex, "shard index" )
|
||||
["--shard-index"]
|
||||
( "index of the group of tests to execute (see --shard-count)" )
|
||||
| Arg( config.testsOrTags, "test name|pattern|tags" )
|
||||
( "which test or tests to use" );
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
|
||||
// Copyright Catch2 Authors
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
#ifndef CATCH_SHARDING_HPP_INCLUDED
|
||||
#define CATCH_SHARDING_HPP_INCLUDED
|
||||
|
||||
#include <catch2/catch_session.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
template<typename Container>
|
||||
Container createShard(Container const& container, std::size_t const shardCount, std::size_t const shardIndex) {
|
||||
assert(shardCount > shardIndex);
|
||||
|
||||
if (shardCount == 1) {
|
||||
return container;
|
||||
}
|
||||
|
||||
const std::size_t totalTestCount = container.size();
|
||||
|
||||
const std::size_t shardSize = totalTestCount / shardCount;
|
||||
const std::size_t leftoverTests = totalTestCount % shardCount;
|
||||
|
||||
const std::size_t startIndex = shardIndex * shardSize + (std::min)(shardIndex, leftoverTests);
|
||||
const std::size_t endIndex = (shardIndex + 1) * shardSize + (std::min)(shardIndex + 1, leftoverTests);
|
||||
|
||||
auto startIterator = std::next(container.begin(), startIndex);
|
||||
auto endIterator = std::next(container.begin(), endIndex);
|
||||
|
||||
return Container(startIterator, endIterator);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // CATCH_SHARDING_HPP_INCLUDED
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <catch2/interfaces/catch_interfaces_registry_hub.hpp>
|
||||
#include <catch2/internal/catch_random_number_generator.hpp>
|
||||
#include <catch2/internal/catch_run_context.hpp>
|
||||
#include <catch2/internal/catch_sharding.hpp>
|
||||
#include <catch2/catch_test_case_info.hpp>
|
||||
#include <catch2/catch_test_spec.hpp>
|
||||
#include <catch2/internal/catch_move_and_forward.hpp>
|
||||
@@ -135,7 +136,7 @@ namespace {
|
||||
filtered.push_back(testCase);
|
||||
}
|
||||
}
|
||||
return filtered;
|
||||
return createShard(filtered, config.shardCount(), config.shardIndex());
|
||||
}
|
||||
std::vector<TestCaseHandle> const& getAllTestCasesSorted( IConfig const& config ) {
|
||||
return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
|
||||
|
||||
Reference in new issue
Block a user