diff --git a/src/catch2/catch_config.cpp b/src/catch2/catch_config.cpp index ac8eb7226f..52f4c8fd03 100644 --- a/src/catch2/catch_config.cpp +++ b/src/catch2/catch_config.cpp @@ -15,7 +15,7 @@ #include namespace { - bool enableBazelEnvSupport() { + static bool enableBazelEnvSupport() { #if defined(CATCH_CONFIG_BAZEL_SUPPORT) return true; #elif defined(CATCH_PLATFORM_WINDOWS_UWP) @@ -62,17 +62,6 @@ namespace Catch { elem = trim(elem); } - - TestSpecParser parser(ITagAliasRegistry::get()); - if (!m_data.testsOrTags.empty()) { - m_hasTestFilters = true; - for (auto const& testOrTags : m_data.testsOrTags) { - parser.parse(testOrTags); - } - } - m_testSpec = parser.testSpec(); - - // Insert the default reporter if user hasn't asked for a specfic one if ( m_data.reporterSpecifications.empty() ) { m_data.reporterSpecifications.push_back( { @@ -85,29 +74,21 @@ namespace Catch { } ); } -#if !defined(CATCH_PLATFORM_WINDOWS_UWP) - if(enableBazelEnvSupport()){ - // Register a JUnit reporter for Bazel. Bazel sets an environment - // variable with the path to XML output. If this file is written to - // during test, Bazel will not generate a default XML output. - // This allows the XML output file to contain higher level of detail - // than what is possible otherwise. -# if defined( _MSC_VER ) - // On Windows getenv throws a warning as there is no input validation, - // since the key is hardcoded, this should not be an issue. -# pragma warning( push ) -# pragma warning( disable : 4996 ) -# endif - const auto bazelOutputFilePtr = std::getenv( "XML_OUTPUT_FILE" ); -# if defined( _MSC_VER ) -# pragma warning( pop ) -# endif - if ( bazelOutputFilePtr != nullptr ) { - m_data.reporterSpecifications.push_back( - { "junit", std::string( bazelOutputFilePtr ), {}, {} } ); + if ( enableBazelEnvSupport() ) { + readBazelEnvVars(); + } + + // Bazel support can modify the test specs, so parsing has to happen + // after reading Bazel env vars. + TestSpecParser parser( ITagAliasRegistry::get() ); + if ( !m_data.testsOrTags.empty() ) { + m_hasTestFilters = true; + for ( auto const& testOrTags : m_data.testsOrTags ) { + parser.parse( testOrTags ); } - } -#endif + } + m_testSpec = parser.testSpec(); + // We now fixup the reporter specs to handle default output spec, // default colour spec, etc @@ -187,4 +168,40 @@ namespace Catch { unsigned int Config::benchmarkResamples() const { return m_data.benchmarkResamples; } std::chrono::milliseconds Config::benchmarkWarmupTime() const { return std::chrono::milliseconds(m_data.benchmarkWarmupTime); } + void Config::readBazelEnvVars() { +#if defined( CATCH_PLATFORM_WINDOWS_UWP ) +// We cannot read environment variables on UWP platforms +#else + +# if defined( _MSC_VER ) +# pragma warning( push ) +# pragma warning( disable : 4996 ) // use getenv_s instead of getenv +# endif + + // Register a JUnit reporter for Bazel. Bazel sets an environment + // variable with the path to XML output. If this file is written to + // during test, Bazel will not generate a default XML output. + // This allows the XML output file to contain higher level of detail + // than what is possible otherwise. + const auto bazelOutputFile = std::getenv( "XML_OUTPUT_FILE" ); + if ( bazelOutputFile ) { + m_data.reporterSpecifications.push_back( + { "junit", std::string( bazelOutputFile ), {}, {} } ); + } + + const auto bazelTestSpec = std::getenv( "TESTBRIDGE_TEST_ONLY" ); + if ( bazelTestSpec ) { + // Presumably the test spec from environment should overwrite + // the one we got from CLI (if we got any) + m_data.testsOrTags.clear(); + m_data.testsOrTags.push_back( bazelTestSpec ); + } + +# if defined( _MSC_VER ) +# pragma warning( pop ) +# endif + +#endif + } + } // end namespace Catch diff --git a/src/catch2/catch_config.hpp b/src/catch2/catch_config.hpp index 10df4d64ad..1959d08ed0 100644 --- a/src/catch2/catch_config.hpp +++ b/src/catch2/catch_config.hpp @@ -140,6 +140,9 @@ namespace Catch { std::chrono::milliseconds benchmarkWarmupTime() const override; private: + // Reads Bazel env vars and applies them to the config + void readBazelEnvVars(); + ConfigData m_data; std::vector m_processedReporterSpecs; TestSpec m_testSpec; diff --git a/tests/ExtraTests/CMakeLists.txt b/tests/ExtraTests/CMakeLists.txt index 0943a9c370..780f2559e2 100644 --- a/tests/ExtraTests/CMakeLists.txt +++ b/tests/ExtraTests/CMakeLists.txt @@ -150,6 +150,17 @@ set_tests_properties(NO_CATCH_CONFIG_BAZEL_REPORTER-1 ENVIRONMENT "BAZEL_TEST=1" ) +add_test(NAME BazelEnv::TESTBRIDGE_TEST_ONLY + COMMAND + $ +) +set_tests_properties(BazelEnv::TESTBRIDGE_TEST_ONLY + PROPERTIES + ENVIRONMENT "BAZEL_TEST=1;TESTBRIDGE_TEST_ONLY=Passing test case" + PASS_REGULAR_EXPRESSION "All tests passed \\(1 assertion in 1 test case\\)" +) + + # The default handler on Windows leads to the just-in-time debugger firing, # which makes this test unsuitable for CI and headless runs, as it opens # up an interactive dialog.