Skip to content

Commit 0aeb818

Browse files
mattyrazz7horenmar
authored andcommitted
Emit warning when using --shard-count (> 1) with --order rand
1 parent 97ec4e8 commit 0aeb818

6 files changed

Lines changed: 71 additions & 1 deletion

File tree

src/catch2/catch_config.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ namespace Catch {
209209
double Config::minDuration() const { return m_data.minDuration; }
210210
TestRunOrder Config::runOrder() const { return m_data.runOrder; }
211211
uint32_t Config::rngSeed() const { return m_data.rngSeed; }
212+
bool Config::rngSeedWasFixed() const { return m_data.rngSeedWasFixed; }
212213
unsigned int Config::shardCount() const { return m_data.shardCount; }
213214
unsigned int Config::shardIndex() const { return m_data.shardIndex; }
214215
ColourMode Config::defaultColourMode() const { return m_data.defaultColourMode; }
@@ -273,6 +274,7 @@ namespace Catch {
273274
<< bazelRandomSeed << "') as proper seed.\n";
274275
} else {
275276
m_data.rngSeed = *parsedSeed;
277+
m_data.rngSeedWasFixed = true;
276278
}
277279
}
278280
}

src/catch2/catch_config.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ namespace Catch {
6363

6464
int abortAfter = -1;
6565
uint32_t rngSeed = generateRandomSeed(GenerateFrom::Default);
66+
bool rngSeedWasFixed = false;
6667

6768
unsigned int shardCount = 1;
6869
unsigned int shardIndex = 0;
@@ -134,6 +135,7 @@ namespace Catch {
134135
double minDuration() const override;
135136
TestRunOrder runOrder() const override;
136137
uint32_t rngSeed() const override;
138+
bool rngSeedWasFixed() const;
137139
unsigned int shardCount() const override;
138140
unsigned int shardIndex() const override;
139141
ColourMode defaultColourMode() const override;

src/catch2/catch_session.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,19 @@ namespace Catch {
348348
CATCH_TRY {
349349
config(); // Force config to be constructed
350350

351+
if ( m_config->shardCount() > 1 &&
352+
m_config->runOrder() == TestRunOrder::Randomized &&
353+
!m_config->rngSeedWasFixed() ) {
354+
Catch::cerr()
355+
<< "Warning: using sharding (--shard-count) with random "
356+
"order (--order rand, the default) and without a fixed "
357+
"numeric --rng-seed does not guarantee disjoint coverage "
358+
"between shard invocations. Pass the same numeric "
359+
"--rng-seed to every shard, or use --order decl or "
360+
"--order lex instead.\n"
361+
<< std::flush;
362+
}
363+
351364
// We need to retrieve potential Bazel config with the full Config
352365
// constructor, so we have to create the guard file after it is created.
353366
setUpGuardFile( m_config->getExitGuardFilePath() );

src/catch2/internal/catch_commandline.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,11 @@ namespace Catch {
7575
auto const setRngSeed = [&]( std::string const& seed ) {
7676
if( seed == "time" ) {
7777
config.rngSeed = generateRandomSeed(GenerateFrom::Time);
78+
config.rngSeedWasFixed = false;
7879
return ParserResult::ok(ParseResultType::Matched);
7980
} else if (seed == "random-device") {
8081
config.rngSeed = generateRandomSeed(GenerateFrom::RandomDevice);
82+
config.rngSeedWasFixed = false;
8183
return ParserResult::ok(ParseResultType::Matched);
8284
}
8385

@@ -88,6 +90,7 @@ namespace Catch {
8890
return ParserResult::runtimeError( "Could not parse '" + seed + "' as seed" );
8991
}
9092
config.rngSeed = *parsedSeed;
93+
config.rngSeedWasFixed = true;
9194
return ParserResult::ok( ParseResultType::Matched );
9295
};
9396
auto const setDefaultColourMode = [&]( std::string const& colourMode ) {

tests/ExtraTests/CMakeLists.txt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,37 @@ set_tests_properties(TestSharding::OverlyLargeShardIndex
2121
PASS_REGULAR_EXPRESSION "The shard count \\(5\\) must be greater than the shard index \\(5\\)"
2222
)
2323

24+
set(CATCH_SHARDING_WARNING_REGEX "Warning: using sharding .* with random order")
25+
26+
add_test(
27+
NAME TestSharding::WarningOnRandomOrderWithoutFixedSeed
28+
COMMAND $<TARGET_FILE:SelfTest> --shard-index 0 --shard-count 2 --list-tests
29+
)
30+
set_tests_properties(TestSharding::WarningOnRandomOrderWithoutFixedSeed
31+
PROPERTIES
32+
PASS_REGULAR_EXPRESSION "${CATCH_SHARDING_WARNING_REGEX}"
33+
)
34+
35+
add_test(
36+
NAME TestSharding::NoWarningOnRandomOrderWithFixedSeed
37+
COMMAND $<TARGET_FILE:SelfTest> --shard-index 0 --shard-count 2 --rng-seed 12345 --list-tests
38+
)
39+
set_tests_properties(TestSharding::NoWarningOnRandomOrderWithFixedSeed
40+
PROPERTIES
41+
FAIL_REGULAR_EXPRESSION "${CATCH_SHARDING_WARNING_REGEX}"
42+
)
43+
44+
foreach(shardOrder decl lex)
45+
add_test(
46+
NAME TestSharding::NoWarningOn${shardOrder}OrderWithoutFixedSeed
47+
COMMAND $<TARGET_FILE:SelfTest> --shard-index 0 --shard-count 2 --order ${shardOrder} --list-tests
48+
)
49+
set_tests_properties(TestSharding::NoWarningOn${shardOrder}OrderWithoutFixedSeed
50+
PROPERTIES
51+
FAIL_REGULAR_EXPRESSION "${CATCH_SHARDING_WARNING_REGEX}"
52+
)
53+
endforeach()
54+
2455
# The MinDuration reporting tests do not need separate compilation, but
2556
# they have non-trivial execution time, so they are categorized as
2657
# extra tests, so that they are run less.

tests/SelfTest/IntrospectiveTests/CmdLine.tests.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,15 +473,34 @@ TEST_CASE( "Parse rng seed in different formats", "[approvals][cli][rng-seed]" )
473473
CAPTURE( seed_string );
474474

475475
auto result = cli.parse( { "tests", "--rng-seed", seed_string } );
476+
REQUIRE( result );
476477

478+
Catch::Config cfg{config};
479+
REQUIRE( cfg.rngSeed() == seed_value );
480+
REQUIRE( cfg.rngSeedWasFixed() );
481+
}
482+
SECTION( "time seed is not considered fixed" ) {
483+
auto result = cli.parse( { "tests", "--rng-seed", "time" } );
477484
REQUIRE( result );
478-
REQUIRE( config.rngSeed == seed_value );
485+
486+
Catch::Config cfg{config};
487+
REQUIRE_FALSE( cfg.rngSeedWasFixed() );
488+
}
489+
SECTION( "random-device seed is not considered fixed" ) {
490+
auto result = cli.parse( { "tests", "--rng-seed", "random-device" } );
491+
REQUIRE( result );
492+
493+
Catch::Config cfg{config};
494+
REQUIRE_FALSE( cfg.rngSeedWasFixed() );
479495
}
480496
SECTION( "Error cases" ) {
481497
auto seed_string =
482498
GENERATE( "0xSEED", "999999999999", "08888", "BEEF", "123 456" );
483499
CAPTURE( seed_string );
484500
REQUIRE_FALSE( cli.parse( { "tests", "--rng-seed", seed_string } ) );
501+
502+
Catch::Config cfg{config};
503+
REQUIRE_FALSE( cfg.rngSeedWasFixed() );
485504
}
486505
}
487506

0 commit comments

Comments
 (0)