Add generateRandomSeed utility to generate randomness seed

This commit is contained in:
Martin Hořeňovský 2021-10-08 20:02:24 +02:00
parent fce42b62ad
commit 200a487cf2
No known key found for this signature in database
GPG Key ID: DE48307B8B0D381A
14 changed files with 184 additions and 8 deletions

View File

@ -106,6 +106,7 @@ set(INTERNAL_HEADERS
${SOURCES_DIR}/internal/catch_polyfills.hpp ${SOURCES_DIR}/internal/catch_polyfills.hpp
${SOURCES_DIR}/internal/catch_preprocessor.hpp ${SOURCES_DIR}/internal/catch_preprocessor.hpp
${SOURCES_DIR}/internal/catch_random_number_generator.hpp ${SOURCES_DIR}/internal/catch_random_number_generator.hpp
${SOURCES_DIR}/internal/catch_random_seed_generation.hpp
${SOURCES_DIR}/catch_reporter_registrars.hpp ${SOURCES_DIR}/catch_reporter_registrars.hpp
${SOURCES_DIR}/internal/catch_reporter_registry.hpp ${SOURCES_DIR}/internal/catch_reporter_registry.hpp
${SOURCES_DIR}/internal/catch_result_type.hpp ${SOURCES_DIR}/internal/catch_result_type.hpp
@ -175,6 +176,7 @@ set(IMPL_SOURCES
${SOURCES_DIR}/catch_registry_hub.cpp ${SOURCES_DIR}/catch_registry_hub.cpp
${SOURCES_DIR}/internal/catch_combined_tu.cpp ${SOURCES_DIR}/internal/catch_combined_tu.cpp
${SOURCES_DIR}/internal/catch_random_number_generator.cpp ${SOURCES_DIR}/internal/catch_random_number_generator.cpp
${SOURCES_DIR}/internal/catch_random_seed_generation.cpp
${SOURCES_DIR}/internal/catch_reporter_registry.cpp ${SOURCES_DIR}/internal/catch_reporter_registry.cpp
${SOURCES_DIR}/internal/catch_result_type.cpp ${SOURCES_DIR}/internal/catch_result_type.cpp
${SOURCES_DIR}/internal/catch_run_context.cpp ${SOURCES_DIR}/internal/catch_run_context.cpp

View File

@ -80,6 +80,7 @@
#include <catch2/internal/catch_polyfills.hpp> #include <catch2/internal/catch_polyfills.hpp>
#include <catch2/internal/catch_preprocessor.hpp> #include <catch2/internal/catch_preprocessor.hpp>
#include <catch2/internal/catch_random_number_generator.hpp> #include <catch2/internal/catch_random_number_generator.hpp>
#include <catch2/internal/catch_random_seed_generation.hpp>
#include <catch2/internal/catch_reporter_registry.hpp> #include <catch2/internal/catch_reporter_registry.hpp>
#include <catch2/internal/catch_result_type.hpp> #include <catch2/internal/catch_result_type.hpp>
#include <catch2/internal/catch_run_context.hpp> #include <catch2/internal/catch_run_context.hpp>

View File

@ -0,0 +1,34 @@
// 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
#include <catch2/internal/catch_random_seed_generation.hpp>
#include <catch2/internal/catch_enforce.hpp>
#include <ctime>
#include <random>
namespace Catch {
std::uint32_t generateRandomSeed( GenerateFrom from ) {
switch ( from ) {
case GenerateFrom::Time:
return static_cast<std::uint32_t>( std::time( nullptr ) );
case GenerateFrom::Default:
case GenerateFrom::RandomDevice:
// In theory, a platform could have random_device that returns just
// 16 bits. That is still some randomness, so we don't care too much
return static_cast<std::uint32_t>( std::random_device{}() );
default:
CATCH_ERROR("Unknown generation method");
}
}
} // end namespace Catch

View File

@ -0,0 +1,26 @@
// 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_RANDOM_SEED_GENERATION_HPP_INCLUDED
#define CATCH_RANDOM_SEED_GENERATION_HPP_INCLUDED
#include <cstdint>
namespace Catch {
enum class GenerateFrom {
Time,
RandomDevice,
//! Currently equivalent to RandomDevice, but can change at any point
Default
};
std::uint32_t generateRandomSeed(GenerateFrom from);
} // end namespace Catch
#endif // CATCH_RANDOM_SEED_GENERATION_HPP_INCLUDED

View File

@ -183,6 +183,8 @@ Nor would this
:test-result: PASS Product with differing arities - std::tuple<int, double, float> :test-result: PASS Product with differing arities - std::tuple<int, double, float>
:test-result: PASS Product with differing arities - std::tuple<int, double> :test-result: PASS Product with differing arities - std::tuple<int, double>
:test-result: PASS Product with differing arities - std::tuple<int> :test-result: PASS Product with differing arities - std::tuple<int>
:test-result: PASS Random seed generation accepts known methods
:test-result: PASS Random seed generation reports unknown methods
:test-result: PASS Range type with sentinel :test-result: PASS Range type with sentinel
:test-result: FAIL Reconstruction should be based on stringification: #914 :test-result: FAIL Reconstruction should be based on stringification: #914
:test-result: FAIL Regex string matcher :test-result: FAIL Regex string matcher

View File

@ -1272,6 +1272,10 @@ CmdLine.tests.cpp:<line number>: passed: config.benchmarkWarmupTime == 10 for: 1
Misc.tests.cpp:<line number>: passed: std::tuple_size<TestType>::value >= 1 for: 3 >= 1 Misc.tests.cpp:<line number>: passed: std::tuple_size<TestType>::value >= 1 for: 3 >= 1
Misc.tests.cpp:<line number>: passed: std::tuple_size<TestType>::value >= 1 for: 2 >= 1 Misc.tests.cpp:<line number>: passed: std::tuple_size<TestType>::value >= 1 for: 2 >= 1
Misc.tests.cpp:<line number>: passed: std::tuple_size<TestType>::value >= 1 for: 1 >= 1 Misc.tests.cpp:<line number>: passed: std::tuple_size<TestType>::value >= 1 for: 1 >= 1
RandomNumberGeneration.tests.cpp:<line number>: passed: Catch::generateRandomSeed(method)
RandomNumberGeneration.tests.cpp:<line number>: passed: Catch::generateRandomSeed(method)
RandomNumberGeneration.tests.cpp:<line number>: passed: Catch::generateRandomSeed(method)
RandomNumberGeneration.tests.cpp:<line number>: passed: Catch::generateRandomSeed(static_cast<Catch::GenerateFrom>(77))
ToString.tests.cpp:<line number>: passed: Catch::Detail::stringify(UsesSentinel{}) == "{ }" for: "{ }" == "{ }" ToString.tests.cpp:<line number>: passed: Catch::Detail::stringify(UsesSentinel{}) == "{ }" for: "{ }" == "{ }"
Decomposition.tests.cpp:<line number>: failed: truthy(false) for: Hey, its truthy! Decomposition.tests.cpp:<line number>: failed: truthy(false) for: Hey, its truthy!
Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Matches( "this STRING contains 'abc' as a substring" ) for: "this string contains 'abc' as a substring" matches "this STRING contains 'abc' as a substring" case sensitively Matchers.tests.cpp:<line number>: failed: testStringForMatching(), Matches( "this STRING contains 'abc' as a substring" ) for: "this string contains 'abc' as a substring" matches "this STRING contains 'abc' as a substring" case sensitively

View File

@ -1386,6 +1386,6 @@ due to unexpected exception with message:
Why would you throw a std::string? Why would you throw a std::string?
=============================================================================== ===============================================================================
test cases: 369 | 293 passed | 70 failed | 6 failed as expected test cases: 371 | 295 passed | 70 failed | 6 failed as expected
assertions: 2106 | 1954 passed | 129 failed | 23 failed as expected assertions: 2110 | 1958 passed | 129 failed | 23 failed as expected

View File

@ -9383,6 +9383,42 @@ Misc.tests.cpp:<line number>: PASSED:
with expansion: with expansion:
1 >= 1 1 >= 1
-------------------------------------------------------------------------------
Random seed generation accepts known methods
-------------------------------------------------------------------------------
RandomNumberGeneration.tests.cpp:<line number>
...............................................................................
RandomNumberGeneration.tests.cpp:<line number>: PASSED:
REQUIRE_NOTHROW( Catch::generateRandomSeed(method) )
-------------------------------------------------------------------------------
Random seed generation accepts known methods
-------------------------------------------------------------------------------
RandomNumberGeneration.tests.cpp:<line number>
...............................................................................
RandomNumberGeneration.tests.cpp:<line number>: PASSED:
REQUIRE_NOTHROW( Catch::generateRandomSeed(method) )
-------------------------------------------------------------------------------
Random seed generation accepts known methods
-------------------------------------------------------------------------------
RandomNumberGeneration.tests.cpp:<line number>
...............................................................................
RandomNumberGeneration.tests.cpp:<line number>: PASSED:
REQUIRE_NOTHROW( Catch::generateRandomSeed(method) )
-------------------------------------------------------------------------------
Random seed generation reports unknown methods
-------------------------------------------------------------------------------
RandomNumberGeneration.tests.cpp:<line number>
...............................................................................
RandomNumberGeneration.tests.cpp:<line number>: PASSED:
REQUIRE_THROWS( Catch::generateRandomSeed(static_cast<Catch::GenerateFrom>(77)) )
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Range type with sentinel Range type with sentinel
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@ -16954,6 +16990,6 @@ Misc.tests.cpp:<line number>
Misc.tests.cpp:<line number>: PASSED: Misc.tests.cpp:<line number>: PASSED:
=============================================================================== ===============================================================================
test cases: 369 | 277 passed | 86 failed | 6 failed as expected test cases: 371 | 279 passed | 86 failed | 6 failed as expected
assertions: 2123 | 1954 passed | 146 failed | 23 failed as expected assertions: 2127 | 1958 passed | 146 failed | 23 failed as expected

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<testsuitesloose text artifact <testsuitesloose text artifact
> >
<testsuite name="<exe-name>" errors="17" failures="129" tests="2123" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}"> <testsuite name="<exe-name>" errors="17" failures="129" tests="2127" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
<properties> <properties>
<property name="filters" value="~[!nonportable]~[!benchmark]~[approvals] *"/> <property name="filters" value="~[!nonportable]~[!benchmark]~[approvals] *"/>
<property name="random-seed" value="1"/> <property name="random-seed" value="1"/>
@ -1066,6 +1066,8 @@ Message.tests.cpp:<line number>
<testcase classname="<exe-name>.global" name="Product with differing arities - std::tuple&lt;int, double, float>" time="{duration}" status="run"/> <testcase classname="<exe-name>.global" name="Product with differing arities - std::tuple&lt;int, double, float>" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Product with differing arities - std::tuple&lt;int, double>" time="{duration}" status="run"/> <testcase classname="<exe-name>.global" name="Product with differing arities - std::tuple&lt;int, double>" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Product with differing arities - std::tuple&lt;int>" time="{duration}" status="run"/> <testcase classname="<exe-name>.global" name="Product with differing arities - std::tuple&lt;int>" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Random seed generation accepts known methods" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Random seed generation reports unknown methods" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Range type with sentinel" time="{duration}" status="run"/> <testcase classname="<exe-name>.global" name="Range type with sentinel" time="{duration}" status="run"/>
<testcase classname="<exe-name>.global" name="Reconstruction should be based on stringification: #914" time="{duration}" status="run"> <testcase classname="<exe-name>.global" name="Reconstruction should be based on stringification: #914" time="{duration}" status="run">
<failure message="truthy(false)" type="CHECK"> <failure message="truthy(false)" type="CHECK">

View File

@ -152,6 +152,8 @@
<testCase name="Comparison ops" duration="{duration}"/> <testCase name="Comparison ops" duration="{duration}"/>
<testCase name="Our PCG implementation provides expected results for known seeds/Default seeded" duration="{duration}"/> <testCase name="Our PCG implementation provides expected results for known seeds/Default seeded" duration="{duration}"/>
<testCase name="Our PCG implementation provides expected results for known seeds/Specific seed" duration="{duration}"/> <testCase name="Our PCG implementation provides expected results for known seeds/Specific seed" duration="{duration}"/>
<testCase name="Random seed generation accepts known methods" duration="{duration}"/>
<testCase name="Random seed generation reports unknown methods" duration="{duration}"/>
</file> </file>
<file path="tests/<exe-name>/IntrospectiveTests/Reporters.tests.cpp"> <file path="tests/<exe-name>/IntrospectiveTests/Reporters.tests.cpp">
<testCase name="Reporter's write listings to provided stream" duration="{duration}"/> <testCase name="Reporter's write listings to provided stream" duration="{duration}"/>

View File

@ -2466,6 +2466,14 @@ ok {test-number} - std::tuple_size<TestType>::value >= 1 for: 3 >= 1
ok {test-number} - std::tuple_size<TestType>::value >= 1 for: 2 >= 1 ok {test-number} - std::tuple_size<TestType>::value >= 1 for: 2 >= 1
# Product with differing arities - std::tuple<int> # Product with differing arities - std::tuple<int>
ok {test-number} - std::tuple_size<TestType>::value >= 1 for: 1 >= 1 ok {test-number} - std::tuple_size<TestType>::value >= 1 for: 1 >= 1
# Random seed generation accepts known methods
ok {test-number} - Catch::generateRandomSeed(method)
# Random seed generation accepts known methods
ok {test-number} - Catch::generateRandomSeed(method)
# Random seed generation accepts known methods
ok {test-number} - Catch::generateRandomSeed(method)
# Random seed generation reports unknown methods
ok {test-number} - Catch::generateRandomSeed(static_cast<Catch::GenerateFrom>(77))
# Range type with sentinel # Range type with sentinel
ok {test-number} - Catch::Detail::stringify(UsesSentinel{}) == "{ }" for: "{ }" == "{ }" ok {test-number} - Catch::Detail::stringify(UsesSentinel{}) == "{ }" for: "{ }" == "{ }"
# Reconstruction should be based on stringification: #914 # Reconstruction should be based on stringification: #914
@ -4248,5 +4256,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0
ok {test-number} - ok {test-number} -
# xmlentitycheck # xmlentitycheck
ok {test-number} - ok {test-number} -
1..2123 1..2127

View File

@ -467,6 +467,10 @@ Message.tests.cpp:<line number>|nexplicit failure with message:|n "Message from
##teamcity[testFinished name='Product with differing arities - std::tuple<int, double>' duration="{duration}"] ##teamcity[testFinished name='Product with differing arities - std::tuple<int, double>' duration="{duration}"]
##teamcity[testStarted name='Product with differing arities - std::tuple<int>'] ##teamcity[testStarted name='Product with differing arities - std::tuple<int>']
##teamcity[testFinished name='Product with differing arities - std::tuple<int>' duration="{duration}"] ##teamcity[testFinished name='Product with differing arities - std::tuple<int>' duration="{duration}"]
##teamcity[testStarted name='Random seed generation accepts known methods']
##teamcity[testFinished name='Random seed generation accepts known methods' duration="{duration}"]
##teamcity[testStarted name='Random seed generation reports unknown methods']
##teamcity[testFinished name='Random seed generation reports unknown methods' duration="{duration}"]
##teamcity[testStarted name='Range type with sentinel'] ##teamcity[testStarted name='Range type with sentinel']
##teamcity[testFinished name='Range type with sentinel' duration="{duration}"] ##teamcity[testFinished name='Range type with sentinel' duration="{duration}"]
##teamcity[testStarted name='Reconstruction should be based on stringification: #914'] ##teamcity[testStarted name='Reconstruction should be based on stringification: #914']

View File

@ -11468,6 +11468,44 @@ Nor would this
</Expression> </Expression>
<OverallResult success="true"/> <OverallResult success="true"/>
</TestCase> </TestCase>
<TestCase name="Random seed generation accepts known methods" tags="[rng][seed]" filename="tests/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
<Expression success="true" type="REQUIRE_NOTHROW" filename="tests/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
<Original>
Catch::generateRandomSeed(method)
</Original>
<Expanded>
Catch::generateRandomSeed(method)
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE_NOTHROW" filename="tests/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
<Original>
Catch::generateRandomSeed(method)
</Original>
<Expanded>
Catch::generateRandomSeed(method)
</Expanded>
</Expression>
<Expression success="true" type="REQUIRE_NOTHROW" filename="tests/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
<Original>
Catch::generateRandomSeed(method)
</Original>
<Expanded>
Catch::generateRandomSeed(method)
</Expanded>
</Expression>
<OverallResult success="true"/>
</TestCase>
<TestCase name="Random seed generation reports unknown methods" tags="[rng][seed]" filename="tests/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
<Expression success="true" type="REQUIRE_THROWS" filename="tests/<exe-name>/IntrospectiveTests/RandomNumberGeneration.tests.cpp" >
<Original>
Catch::generateRandomSeed(static_cast&lt;Catch::GenerateFrom>(77))
</Original>
<Expanded>
Catch::generateRandomSeed(static_cast&lt;Catch::GenerateFrom>(77))
</Expanded>
</Expression>
<OverallResult success="true"/>
</TestCase>
<TestCase name="Range type with sentinel" filename="tests/<exe-name>/IntrospectiveTests/ToString.tests.cpp" > <TestCase name="Range type with sentinel" filename="tests/<exe-name>/IntrospectiveTests/ToString.tests.cpp" >
<Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/ToString.tests.cpp" > <Expression success="true" type="CHECK" filename="tests/<exe-name>/IntrospectiveTests/ToString.tests.cpp" >
<Original> <Original>
@ -19953,6 +19991,6 @@ loose text artifact
</Section> </Section>
<OverallResult success="true"/> <OverallResult success="true"/>
</TestCase> </TestCase>
<OverallResults successes="1954" failures="146" expectedFailures="23"/> <OverallResults successes="1958" failures="146" expectedFailures="23"/>
<OverallResultsCases successes="277" failures="86" expectedFailures="6"/> <OverallResultsCases successes="279" failures="86" expectedFailures="6"/>
</Catch2TestRun> </Catch2TestRun>

View File

@ -5,6 +5,8 @@
#include <catch2/catch_test_macros.hpp> #include <catch2/catch_test_macros.hpp>
#include <catch2/internal/catch_random_number_generator.hpp> #include <catch2/internal/catch_random_number_generator.hpp>
#include <catch2/internal/catch_random_seed_generation.hpp>
#include <catch2/generators/catch_generators.hpp>
TEST_CASE("Our PCG implementation provides expected results for known seeds", "[rng]") { TEST_CASE("Our PCG implementation provides expected results for known seeds", "[rng]") {
Catch::SimplePcg32 rng; Catch::SimplePcg32 rng;
@ -40,3 +42,18 @@ TEST_CASE("Comparison ops", "[rng]") {
REQUIRE_FALSE(SimplePcg32{ 1 } == SimplePcg32{ 2 }); REQUIRE_FALSE(SimplePcg32{ 1 } == SimplePcg32{ 2 });
REQUIRE_FALSE(SimplePcg32{ 1 } != SimplePcg32{ 1 }); REQUIRE_FALSE(SimplePcg32{ 1 } != SimplePcg32{ 1 });
} }
TEST_CASE("Random seed generation reports unknown methods", "[rng][seed]") {
REQUIRE_THROWS(Catch::generateRandomSeed(static_cast<Catch::GenerateFrom>(77)));
}
TEST_CASE("Random seed generation accepts known methods", "[rng][seed]") {
using Catch::GenerateFrom;
const auto method = GENERATE(
GenerateFrom::Time,
GenerateFrom::RandomDevice,
GenerateFrom::Default
);
REQUIRE_NOTHROW(Catch::generateRandomSeed(method));
}