mongo-cxx-driver icon indicating copy to clipboard operation
mongo-cxx-driver copied to clipboard

CXX-3094 Upgrade Catch2 from v2 to v3

Open eramongodb opened this issue 6 months ago • 1 comments

Summary

Resolves CXX-3094. Verified by this patch.

Upgrades the Catch2 library used by the test suite from the v2 standalone header to the v3 library obtained via FetchContent.

This bumps the minimum required C++ standard to build tests to C++14 as reflected in the new changelog entry. This does not bump the minimum required C++ standard to build the bsoncxx or mongocxx libraries.

ClangFormat

The ClangFormat config file is updated to separate bsoncxx/mongocxx headers from test and third party headers. Note the order of the Regex entries is significant (first match from top to bottom), hence the regex for config and test headers must (confusingly) come before the regex driver and third party headers even though they are prioritized to come after in formatted source code.

FetchCatch2 Module

This PR adds a new FetchCatch2.cmake module used to obtain the Catch2 library via FetchContent in a manner similar to FetchMongoC.cmake. The only notable difference to FetchMongoC.cmake is that Catch2 cache variables are set via set_property() instead of via set() (normal variable overrides) due to CMP0077, as Catch2's CMake config does not set its CMake policy to 3.13 or newer.

Catch2 v2 -> v3 Migration

Due to the new minimum C++ standard requirement of C++14 or newer by Catch2 v3 (notably the use of extended constexpr functions), tests are no longer built or run on VS 2015 distros, as "extended constexpr" requires VS 2017 and newer. Instead, they now only run the compile_without_tests EVG task on VS 2015 distros to preserve build coverage + uninstall check tasks.

The cxx_std_14 CMake compile feature is used to build bsoncxx and mongocxx tests with C++14 via the (bsoncxx|mongocxx)_test_properties interface library. Note the (bsoncxx|mongocxx)_testing libraries themselves do not require C++14 (nor do the normal static/shared libraries); they are still compiled with C++11 when CMAKE_CXX_STANDARD=11, which matches the standard used for normal library compilation.

[!NOTE] Only the test executables require C++14 or newer. Users whose compilers do not have C++14 support can set ENABLE_TESTS=OFF to avoid the C++14 requirement while still being able to build the bsoncxx/mongocxx libraries.

The <bsoncxx/test/catch.hh> header is still used as the primary method to import Catch2 test macros, thus it is the header by which <catch2/catch_test_macros.hpp> is included by most test files. Several test files needed to be updated to include the now separate Catch2 headers for matcher, generators, and etc. as needed. Otherwise, the migration mostly involved the namespace-scoping of matcher-related entities:

  • Catch::Matches -> Catch::Matchers::Matches
  • Catch::Contains -> Catch::Matchers::ContainsSubstring
  • Catch::MatcherBase -> Catch::Matchers::MatcherBase
  • etc.

The catch/include/helpers.hpp header was moved to mongocxx/test/catch_helpers.hh where it is more appropriate + formatted.

The test.sh script required the addition of the Catch2 binary directory to $PATH find Catch2 DLLs on Windows.

Although improving compilation times isn't the goal of this PR, it is considered a major feature of Catch2 v3 (in large part due to no longer being a header-only library), so here are some crude benchmarks comparing the old vs. new compilation times to build test_bson from scratch (rounded to nearest second):

  • Environment
    • Compiler: Clang 19.0.0
    • Build System: Ninja 1.10.1
    • OS: WSL2 Ubuntu 22.04
    • CPU: Intel i9-10885H @ 2.40GHz (-j 16 for parallel benchmarks)
  • Before
    • Single: 41 secs
    • Parallel: 14 secs
  • After (excluding build of Catch2WithMain)
    • Single: 29 secs (-29%)
    • Parallel: 7 secs (-50%)
  • After (including build of Catch2WithMain)
    • Single: 68 secs (+66%)
    • Parallel: 13 secs (-7%)

Miscellaneous

Drive-by improvements include:

  • Passing SYSTEM to FetchContent_Declare() with CMake 3.25+, which reduces the amount of noisy warnings emitted when compiling imported library sources or when including imported library headers. CMake 3.28 additionally adds support for EXCLUDE_FROM_ALL, but setting the directory property directly seems more convenient for backward compatibility purposes.
  • Removal of the MONGO_CXX_DRIVER_COMPILING preprocessor macro definition which was obsoleted by https://github.com/mongodb/mongo-cxx-driver/pull/1024.
  • Address -Wextra-semi-stmt warnings due to the CHECK_OPTIONAL_ARGUMENT macro.
  • Avoid building tests in uninstall check tasks.
  • Avoid building tests in RPM snapshot builds.

eramongodb avatar Aug 28 '24 19:08 eramongodb