Repository: ceph/ceph
Pull request #63529: make adding Catch2 tests straightforward
Author: login: chardan
Labels: name: rgw
name: tests
name: build/ops
Created: 2025-05-27T17:56:30Z | Merged: 2025-05-30T15:48:48Z

Makes it less tedious to add a new Catch2 test with CMake by adding functions that handle some
of the bookkeeping tedium.

Adding a new test should be easy and let programmers get to writing tests, not fiddling with the
build system; before this PR, adding a new Catch2 test was a bit of a pain and required more focus
on CMake and the build system than one might hope for-- discouraging the addition of new tests and
making for sad programmers. 

But, the sadness is no more! This PR adds a cmake module function that may in turn 
be wrapped to give you a joyful test-adding experience:

touch rgw_hex.cc foo_test.cc

...and then in CMakelists.txt:

add_catch2_test_rgw(rgw_hex)
add_catch2_test_rgw(foo_test NO_CATCH2_MAIN)

Signed-off-by: Jesse Williamson <jfw@ibm.com>

## Contribution Guidelines
- To sign and title your commits, please refer to [Submitting Patches to Ceph](https://github.com/ceph/ceph/blob/main/SubmittingPatches.rst).

- If you are submitting a fix for a stable branch (e.g. "quincy"), please refer to [Submitting Patches to Ceph - Backports](https://github.com/ceph/ceph/blob/master/SubmittingPatches-backports.rst) for the proper workflow.

- When filling out the below checklist, you may click boxes directly in the GitHub web UI.  When entering or editing the entire PR message in the GitHub web UI editor, you may also select a checklist item by adding an `x` between the brackets: `[x]`.  Spaces and capitalization matter when checking off items this way.

## Checklist
- Tracker (select at least one)
  - [ ] References tracker ticket
  - [ ] Very recent bug; references commit where it was introduced
  - [ ] New feature (ticket optional)
  - [ ] Doc update (no ticket needed)
  - [x] Code cleanup (no ticket needed)
- Component impact
  - [ ] Affects [Dashboard](https://tracker.ceph.com/projects/dashboard/issues/new), opened tracker ticket
  - [ ] Affects [Orchestrator](https://tracker.ceph.com/projects/orchestrator/issues/new), opened tracker ticket
  - [x] No impact that needs to be tracked
- Documentation (select at least one)
  - [ ] Updates relevant documentation
  - [x] No doc update is appropriate
- Tests (select at least one)
  - [ ] Includes [unit test(s)](https://docs.ceph.com/en/latest/dev/developer_guide/tests-unit-tests/)
  - [ ] Includes [integration test(s)](https://docs.ceph.com/en/latest/dev/developer_guide/testing_integration_tests/)
  - [ ] Includes bug reproducer
  - [x] No tests

<details>
<summary>Show available Jenkins commands</summary>

- `jenkins test classic perf` [Jenkins Job](https://jenkins.ceph.com/view/all/job/ceph-perf-classic/) | [Jenkins Job Definition](https://github.com/ceph/ceph-build/blob/main/ceph-perf-pull-requests/config/definitions/ceph-perf-pull-requests.yml)
- `jenkins test crimson perf` [Jenkins Job](https://jenkins.ceph.com/view/all/job/ceph-perf-crimson/) | [Jenkins Job Definition](https://github.com/ceph/ceph-build/blob/main/ceph-perf-pull-requests/config/definitions/ceph-perf-pull-requests.yml)
- `jenkins test signed` [Jenkins Job](https://jenkins.ceph.com/job/ceph-pr-commits/) | [Jenkins Job Definition](https://github.com/ceph/ceph-build/blob/main/ceph-pr-commits/config/definitions/ceph-pr-commits.yml)
- `jenkins test make check` [Jenkins Job](https://jenkins.ceph.com/job/ceph-pull-requests/) | [Jenkins Job Definition](https://github.com/ceph/ceph-build/blob/main/ceph-pull-requests/config/definitions/ceph-pull-requests.yml)
- `jenkins test make check arm64` [Jenkins Job](https://jenkins.ceph.com/job/ceph-pull-requests-arm64/) | [Jenkins Job Definition](https://github.com/ceph/ceph-build/blob/main/ceph-pull-requests-arm64/config/definitions/ceph-pull-requests-arm64.yml)
- `jenkins test submodules` [Jenkins Job](https://jenkins.ceph.com/view/all/job/ceph-pr-submodules/) | [Jenkins Job Definition](https://github.com/ceph/ceph-build/blob/main/ceph-pr-submodules/config/definitions/ceph-pr-commits.yml)
- `jenkins test dashboard` [Jenkins Job](https://jenkins.ceph.com/view/all/job/ceph-dashboard-pull-requests/) | [Jenkins Job Definition](https://github.com/ceph/ceph-build/blob/main/ceph-dashboard-pull-requests/config/definitions/ceph-dashboard-pull-requests.yml)
- `jenkins test dashboard cephadm` [Jenkins Job](https://jenkins.ceph.com/view/all/job/ceph-dashboard-cephadm-e2e/) | [Jenkins Job Definition](https://github.com/ceph/ceph-build/blob/main/ceph-dashboard-cephadm-e2e/config/definitions/ceph-dashboard-cephadm-e2e.yml)
- `jenkins test api` [Jenkins Job](https://jenkins.ceph.com/view/all/job/ceph-api/) | [Jenkins Job Definition](https://github.com/ceph/ceph-build/blob/main/ceph-pr-api/config/definitions/ceph-pr-api.yml)
- `jenkins test docs` [ReadTheDocs](https://readthedocs.org/projects/ceph/) | [Github Workflow Definition](https://github.com/ceph/ceph/blob/main/.readthedocs.yml)
- `jenkins test ceph-volume all` [Jenkins Jobs](https://jenkins.ceph.com/view/ceph-volume%20PR/) | [Jenkins Jobs Definition](https://github.com/ceph/ceph-build/blob/main/ceph-volume-cephadm-prs/config/definitions/ceph-volume-pr.yml)
- `jenkins test windows` [Jenkins Job](https://jenkins.ceph.com/job/ceph-windows-pull-requests/) | [Jenkins Job Definition](https://github.com/ceph/ceph-build/blob/main/ceph-windows-pull-requests/config/definitions/ceph-windows-pull-requests.yml)
- `jenkins test rook e2e` [Jenkins Job](https://jenkins.ceph.com/view/all/job/ceph-orchestrator-rook-e2e/) | [Jenkins Job Definition](https://github.com/ceph/ceph-build/blob/main/ceph-rook-e2e/config/definitions/ceph-orchestrator-rook-e2e.yml)
</details>



Diff:
diff --git a/cmake/modules/AddCephTest.cmake b/cmake/modules/AddCephTest.cmake
index ab4dc63ca32a2..67e60504d6dd8 100644
--- a/cmake/modules/AddCephTest.cmake
+++ b/cmake/modules/AddCephTest.cmake
@@ -136,3 +136,51 @@ function(add_tox_test name)
     PYTHONPATH=${CMAKE_SOURCE_DIR}/src/pybind)
   list(APPEND tox_test run-tox-${name})
 endfunction()
+
+# Helper for adding new tests built with Catch2:
+function(add_catch2_test test_name)
+if(NOT WITH_CATCH2)
+  return()
+endif()
+
+set(options NO_CATCH2_MAIN)
+set(oneValueArgs)
+set(multiValueArgs EXTRA_LIBS EXTRA_INCS)
+
+cmake_parse_arguments(PARSE_ARGV 0 catch2_opt
+  "${options}" "${oneValueArgs}" "${multiValueArgs}")
+
+ add_executable(unittest_${test_name}
+ test_${test_name}.cc)
+
+SET(tl_libs
+  librados
+  ceph-common
+  ${EXTRALIBS})
+
+SET(tl_incs
+  SYSTEM PRIVATE ${CMAKE_SOURCE_DIR})
+
+if(DEFINED catch2_opt_EXTRA_LIBS)
+  LIST(APPEND tl_libs ${catch2_opt_EXTRA_LIBS})
+endif()
+
+if(DEFINED catch2_opt_EXTRA_INCS)
+  LIST(APPEND tl_incs ${catch2_opt_EXTRA_INCS})
+endif()
+
+if(${catch2_opt_NO_CATCH2_MAIN})
+  LIST(APPEND tl_libs Catch2)
+else()
+  LIST(APPEND tl_libs Catch2WithMain)
+endif()
+
+target_link_libraries(unittest_${test_name} 
+  ${tl_libs})
+
+target_include_directories(unittest_${test_name}
+  ${tl_incs})
+
+add_ceph_unittest(unittest_${test_name})
+
+endfunction()
diff --git a/src/test/rgw/CMakeLists.txt b/src/test/rgw/CMakeLists.txt
index 5605031731406..a8e5896316a6a 100644
--- a/src/test/rgw/CMakeLists.txt
+++ b/src/test/rgw/CMakeLists.txt
@@ -388,21 +388,19 @@ target_link_libraries(ceph_test_datalog
   ${rgw_libs})
 install(TARGETS ceph_test_datalog DESTINATION ${CMAKE_INSTALL_BINDIR})
 
-if(WITH_CATCH2)
- add_executable(unittest_rgw_hex
-  test_rgw_hex.cc)
+#
+# Helper for adding RGW tests built with Catch2:
+# Note: to define a test that does not use Catch2::main(), use:
+#   add_catch2_test_rgw(my_test_name NO_CATCH2_MAIN)
+# ...your test should be in a file called "test_<my_test_name>.cc (ex. "test_foo.cc")
+# and the output will be called "unittest_my_test_name".
+#
+function(add_catch2_test_rgw test_name)
+add_catch2_test(${test_name}
+ ${ARGV1}
+ EXTRA_LIBS rgw_common ${rgw_libs}
+ EXTRA_INCS "SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/src/rgw")
+endfunction()
+
+add_catch2_test_rgw(rgw_hex)
 
- target_include_directories(unittest_rgw_hex
-  SYSTEM PRIVATE "${CMAKE_SOURCE_DIR}/src/rgw")
-
- target_link_libraries(unittest_rgw_hex 
-  rgw_common
-  librados
-  ceph-common
-  ${rgw_libs}
-  ${EXTRALIBS}
-  Catch2WithMain)
-
- add_ceph_unittest(unittest_rgw_hex)
-
-endif(WITH_CATCH2)


Reviews:
user: login: chardan
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-28T20:16:41Z
user: login: chardan
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-29T03:19:02Z
user: login: adamemerson
body: Looks good to me! And very useful. Push to Shaman just to make sure it builds on everything, please.
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-29T19:02:40Z

Review comments:
diff_hunk: @@ -388,21 +388,19 @@ target_link_libraries(ceph_test_datalog
   ${rgw_libs})
 install(TARGETS ceph_test_datalog DESTINATION ${CMAKE_INSTALL_BINDIR})
 
-if(WITH_CATCH2)
- add_executable(unittest_rgw_hex
-  test_rgw_hex.cc)
+#
+# Helper for adding RGW tests built with Catch2:
+# Note: to define a test that does not use Catch2::main(), use:
+#   add_catch2_test_rgw(my_test_name NO_CATCH2_MAIN)
+# ...your test should be in a file called my_test_name.cc and the output will be
path: src/test/rgw/CMakeLists.txt
user: login: chardan
body: It should actually be "test_<my-test-name>.cc" (ex. "test_foo.cc"). Will fix comment.
created_at: 2025-05-28T20:16:41Z
author_association: CONTRIBUTOR
diff_hunk: @@ -136,3 +136,52 @@ function(add_tox_test name)
     PYTHONPATH=${CMAKE_SOURCE_DIR}/src/pybind)
   list(APPEND tox_test run-tox-${name})
 endfunction()
+
+# Helper for adding new tests built with Catch2:
+function(add_catch2_test test_name)
+
+set(options NO_CATCH2_MAIN)
+set(oneValueArgs)
+set(multiValueArgs EXTRA_LIBS EXTRA_INCS)
+
+cmake_parse_arguments(PARSE_ARGV 0 catch2_opt
+  "${options}" "${oneValueArgs}" "${multiValueArgs}")
+
+if(NOT WITH_CATCH2)
path: cmake/modules/AddCephTest.cmake
user: login: chardan
body: I could move this to the top.
created_at: 2025-05-29T03:19:02Z
author_association: CONTRIBUTOR

PR comments:
user: login: chardan
created_at: 2025-05-28T04:39:36Z
body: jenkins test make check
author_association: CONTRIBUTOR
user: login: chardan
created_at: 2025-05-28T07:17:28Z
body: jenkins test api
author_association: CONTRIBUTOR
user: login: chardan
created_at: 2025-05-28T14:26:11Z
body: jenkins test make check arm64
author_association: CONTRIBUTOR
user: login: chardan
created_at: 2025-05-28T16:13:02Z
body: jenkins test make check arm64
author_association: CONTRIBUTOR
user: login: chardan
created_at: 2025-05-29T16:47:55Z
body: jenkins test windows
author_association: CONTRIBUTOR
user: login: adamemerson
created_at: 2025-05-29T19:02:51Z
body: jenkins test windows
author_association: CONTRIBUTOR
user: login: chardan
created_at: 2025-05-29T21:07:36Z
body: Shaman-says:
https://shaman.ceph.com/builds/ceph/build-cmake-improve-catch2-support/9bdc4e1a02839384928c23d48d45d39b57f1c272/
author_association: CONTRIBUTOR