Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/catch2/catch_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ namespace Catch {
double Config::minDuration() const { return m_data.minDuration; }
TestRunOrder Config::runOrder() const { return m_data.runOrder; }
uint32_t Config::rngSeed() const { return m_data.rngSeed; }
bool Config::rngSeedWasFixed() const { return m_data.rngSeedWasFixed; }
unsigned int Config::shardCount() const { return m_data.shardCount; }
unsigned int Config::shardIndex() const { return m_data.shardIndex; }
ColourMode Config::defaultColourMode() const { return m_data.defaultColourMode; }
Expand Down Expand Up @@ -271,6 +272,7 @@ namespace Catch {
<< bazelRandomSeed << "') as proper seed.\n";
} else {
m_data.rngSeed = *parsedSeed;
m_data.rngSeedWasFixed = true;
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/catch2/catch_config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ namespace Catch {

int abortAfter = -1;
uint32_t rngSeed = generateRandomSeed(GenerateFrom::Default);
bool rngSeedWasFixed = false;

unsigned int shardCount = 1;
unsigned int shardIndex = 0;
Expand Down Expand Up @@ -133,6 +134,7 @@ namespace Catch {
double minDuration() const override;
TestRunOrder runOrder() const override;
uint32_t rngSeed() const override;
bool rngSeedWasFixed() const;
unsigned int shardCount() const override;
unsigned int shardIndex() const override;
ColourMode defaultColourMode() const override;
Expand Down
13 changes: 13 additions & 0 deletions src/catch2/catch_session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,19 @@ namespace Catch {
CATCH_TRY {
config(); // Force config to be constructed

if ( m_config->shardCount() > 1 &&
m_config->runOrder() == TestRunOrder::Randomized &&
!m_config->rngSeedWasFixed() ) {
Catch::cerr()
<< "Warning: using sharding (--shard-count) with random "
"order (--order rand, the default) and without a fixed "
"numeric --rng-seed does not guarantee disjoint coverage "
"between shard invocations. Pass the same numeric "
"--rng-seed to every shard, or use --order decl or "
"--order lex instead.\n"
<< std::flush;
}

// We need to retrieve potential Bazel config with the full Config
// constructor, so we have to create the guard file after it is created.
setUpGuardFile( m_config->getExitGuardFilePath() );
Expand Down
3 changes: 3 additions & 0 deletions src/catch2/internal/catch_commandline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,11 @@ namespace Catch {
auto const setRngSeed = [&]( std::string const& seed ) {
if( seed == "time" ) {
config.rngSeed = generateRandomSeed(GenerateFrom::Time);
config.rngSeedWasFixed = false;
return ParserResult::ok(ParseResultType::Matched);
} else if (seed == "random-device") {
config.rngSeed = generateRandomSeed(GenerateFrom::RandomDevice);
config.rngSeedWasFixed = false;
return ParserResult::ok(ParseResultType::Matched);
}

Expand All @@ -88,6 +90,7 @@ namespace Catch {
return ParserResult::runtimeError( "Could not parse '" + seed + "' as seed" );
}
config.rngSeed = *parsedSeed;
config.rngSeedWasFixed = true;
return ParserResult::ok( ParseResultType::Matched );
};
auto const setDefaultColourMode = [&]( std::string const& colourMode ) {
Expand Down
32 changes: 32 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -712,5 +712,37 @@ set_tests_properties("Bazel::RngSeedEnvVar::MalformedValueIsIgnored"
PASS_REGULAR_EXPRESSION "Randomness seeded to: 17171717"
)

set(CATCH_SHARDING_WARNING_REGEX "Warning: using sharding .* with random order")

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Went with this to give us more flexibility while still getting the gist of the message


add_test(NAME "Sharding::WarnsWithoutFixedSeed"
COMMAND
$<TARGET_FILE:SelfTest> --shard-index 0 --shard-count 2 --list-tests
)
Comment thread
mattyrazz7 marked this conversation as resolved.
set_tests_properties("Sharding::WarnsWithoutFixedSeed"
PROPERTIES
PASS_REGULAR_EXPRESSION "${CATCH_SHARDING_WARNING_REGEX}"
)

add_test(NAME "Sharding::NoWarningOnRandomOrderWithFixedSeed"
COMMAND
$<TARGET_FILE:SelfTest> --shard-index 0 --shard-count 2 --rng-seed 12345 --list-tests
)
set_tests_properties("Sharding::NoWarningOnRandomOrderWithFixedSeed"
PROPERTIES
FAIL_REGULAR_EXPRESSION "${CATCH_SHARDING_WARNING_REGEX}"
)

foreach(shardOrder decl lex)
string(CAPITALIZE ${shardOrder} shardOrderName)
add_test(NAME "Sharding::NoWarningOn${shardOrderName}OrderWithoutFixedSeed"
COMMAND
$<TARGET_FILE:SelfTest> --shard-index 0 --shard-count 2 --order ${shardOrder} --list-tests
)
set_tests_properties("Sharding::NoWarningOn${shardOrderName}OrderWithoutFixedSeed"
PROPERTIES
FAIL_REGULAR_EXPRESSION "${CATCH_SHARDING_WARNING_REGEX}"
)
endforeach()

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Used a loop to test both lex and decl, but let me know if you want me to do it another way


list(APPEND CATCH_TEST_TARGETS SelfTest)
set(CATCH_TEST_TARGETS ${CATCH_TEST_TARGETS} PARENT_SCOPE)
12 changes: 12 additions & 0 deletions tests/SelfTest/IntrospectiveTests/CmdLine.tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -475,12 +475,24 @@ TEST_CASE( "Parse rng seed in different formats", "[approvals][cli][rng-seed]" )

REQUIRE( result );
REQUIRE( config.rngSeed == seed_value );
REQUIRE( config.rngSeedWasFixed );
}
SECTION( "time seed is not considered fixed" ) {
auto result = cli.parse( { "tests", "--rng-seed", "time" } );
REQUIRE( result );
REQUIRE_FALSE( config.rngSeedWasFixed );
}
SECTION( "random-device seed is not considered fixed" ) {
auto result = cli.parse( { "tests", "--rng-seed", "random-device" } );
REQUIRE( result );
REQUIRE_FALSE( config.rngSeedWasFixed );
}
SECTION( "Error cases" ) {
auto seed_string =
GENERATE( "0xSEED", "999999999999", "08888", "BEEF", "123 456" );
CAPTURE( seed_string );
REQUIRE_FALSE( cli.parse( { "tests", "--rng-seed", seed_string } ) );
REQUIRE_FALSE( config.rngSeedWasFixed );
}
}

Expand Down