ctest and MPI parallel googletests

The Goal

My goal is to create tests with googleTest that make use of MPI, add them via gtest_discover_tests(), and execute them via ctest.

I have seen posts where people use add_test to add the MPI executer manually to their tests (e.g. here) but gtest_discover_tests() (which is way handier) seems to not expose such an option. There exists the CROSSCOMPILING_EMULATOR property which can apparently be abused for this but this seems hacky (see here).

Minimal Example:

CMakeLists.txt:

cmake_minimum_required(VERSION 3.23)
project(TheProject)
set(CMAKE_CXX_STANDARD 17)
# get dependencies
include(FetchContent)
FetchContent_Declare(
        googletest
        URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip
)
FetchContent_MakeAvailable(googletest)
find_package(MPI REQUIRED)
# define a exe
add_executable(TheExe main.cpp theTest.cpp)
target_link_libraries(TheExe PUBLIC gtest MPI::MPI_CXX)
# set up tests
enable_testing()
include(GoogleTest)
set_property(TARGET TheExe PROPERTY CROSSCOMPILING_EMULATOR '${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 3')
gtest_discover_tests(TheExe)

theTest.cpp: (some dummy tests)

#include <gtest/gtest.h>
#include <mpi.h>
TEST(HelloTest, TestA) {
  int rank;
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  std::cout << rank << std::endl;
  EXPECT_LT(rank, 1337);
}
TEST(HelloTest, TestB) {
  MPI_Barrier(MPI_COMM_WORLD);  // sync all ranks
  EXPECT_EQ(42, 7*6);
}

main.cpp

#include <gtest/gtest.h>
#include <mpi.h>

int main(int argc, char **argv) {
  testing::InitGoogleTest(&argc, argv);
  MPI_Init(&argc, &argv);
  auto result = RUN_ALL_TESTS();
  MPI_Finalize();
  return result;
}

Build via CMake and then execute with ctest. This appears to give the desired behavior, alas very verbose because we get the output of all ranks. There is also no way to make use of MPIEXEC_POSTFLAGS. However, at least for me, both of these points are secondary.

The Question

Is this is recommended / proper /best way to achieve the goal stated in the beginning??

I suspect this is something that gtest_discover_tests() just doesn’t support right now.

Cc: @Matthew_Woehlke

What Ben said. Wrapping tests with another executable (which IIUC is what needs to happen here) is a fairly exotic use case, outside, perhaps, of emulators for cross-compiles (i.e. why CROSSCOMPILING_EMULATOR exists).

Contributions welcomed? :slightly_smiling_face:

@Matthew_Woehlke while I agree that this wrapping seems weird, I would argue that MPI is hardly an exotic tool. That’s why I was wondering whether I’m just looking at this from the wrong angle and whether all of this should be done totally differently?

MPI support could probably be added, but it’d need someone to do so.

1 Like