Skip to content

Commit b46bf4f

Browse files
committed
Merge branch 'functional_tests_use_gtest' of github.com:Algebraic-Programming/LPF into zero_engine
2 parents f9d91d6 + 5642874 commit b46bf4f

27 files changed

+285
-194
lines changed

CMakeLists.txt

Lines changed: 78 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,6 @@ set( INSTALL_HEADERS "${prefix}/include" CACHE PATH
105105
"Installation path for header files" )
106106
message( STATUS "Installation directory prefix is ${prefix}")
107107

108-
# C++ standard
109-
set(CMAKE_CXX_STANDARD 17)
110-
set(CMAKE_CXX_STANDARD_REQUIRED YES)
111-
112108
# Dependencies
113109
set(ENGINES)
114110
find_library( LIB_POSIX_THREADS
@@ -165,9 +161,6 @@ if ( MPI_FOUND )
165161
if ( NOT MPI_IS_THREAD_COMPAT OR NOT MPI_IS_NOT_OPENMPI1 )
166162
message( WARNING "MPI implementation does not tolerate any threading. Hybrid implementation will not be built")
167163
endif()
168-
if ( NOT MPI_OPEN_PORT )
169-
message( WARNING "MPI implementation does not support dynamically connecting separate MPI processes. Hence, lpf_mpi_initialize_over_tcp will always fail.")
170-
endif()
171164
if ( NOT MPI_IBARRIER )
172165
message( WARNING "MPI implementation does not have MPI_Ibarrier, which is required to use the dense all-to-all algorithm on large (> 2 GB) meta-data exchanges")
173166
endif()
@@ -181,17 +174,16 @@ if ( LIB_MATH AND LIB_DL AND MPI_FOUND )
181174
list(APPEND ENGINES "mpirma")
182175
endif()
183176

184-
if (LIB_IBVERBS)
177+
if (ENABLE_IBVERBS)
185178
list(APPEND ENGINES "ibverbs")
186-
list(APPEND ENGINES "zero")
187179
endif()
188180

189181
endif()
190182

191183
#enable the hybrid engine
192184
if ( LIB_POSIX_THREADS AND LIB_MATH AND LIB_DL AND MPI_FOUND
193185
AND MPI_IS_THREAD_COMPAT AND MPI_IS_NOT_OPENMPI1
194-
AND LIB_IBVERBS )
186+
AND ENABLE_IBVERBS )
195187
list(APPEND ENGINES "hybrid")
196188
set(HYBRID_ENGINE_ENABLED on)
197189
endif()
@@ -239,6 +231,19 @@ add_definitions(-DBSPLIB_DLL=1)
239231
option(LPF_ENABLE_TESTS
240232
"Enable unit and API tests. This uses Google Testing and Mocking Framework"
241233
OFF)
234+
option(GTEST_AGREE_TO_LICENSE
235+
"Does the user agree to the GoogleTest license"
236+
OFF)
237+
238+
# C++ standard -- Google tests require newer C++ standard than C++11
239+
if (LPF_ENABLE_TESTS)
240+
set(CMAKE_CXX_STANDARD 17)
241+
set(CMAKE_CXX_STANDARD_REQUIRED YES)
242+
else()
243+
set(CMAKE_CXX_STANDARD 11)
244+
set(CMAKE_CXX_STANDARD_REQUIRED YES)
245+
endif()
246+
242247

243248
# Handling of compiler flags
244249
function(target_add_compilation_flags target visibility)
@@ -336,9 +341,13 @@ endfunction()
336341
if (LPF_ENABLE_TESTS)
337342
message(STATUS "Unit and API tests will be built. This requires CMake version 3.29 or higher, since we use recent features of the GoogleTest package in CMake.")
338343

344+
if (NOT GTEST_AGREE_TO_LICENSE)
345+
message(FATAL_ERROR "The user needs to agree with the GoogleTest license to use tests (option GTEST_AGREE_TO_LICENSE=TRUE)")
346+
endif()
339347
# Enable testing in CMake
340348
enable_testing()
341349
find_package(GTest)
350+
include(GoogleTest)
342351
if(NOT GTest_FOUND) # if not found, download it and pull it in
343352
include(FetchContent)
344353
FetchContent_Declare(
@@ -357,104 +366,73 @@ if (LPF_ENABLE_TESTS)
357366
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/junit)
358367
set(test_output "${CMAKE_BINARY_DIR}/junit")
359368

360-
# Have a macro to add a unit test
361-
function(add_gtest testName engines debug testSource)
362-
include(GoogleTest)
363-
add_executable(${testName} ${testSource})
364-
if (debug)
365-
target_include_directories( ${testName} BEFORE PRIVATE ${CMAKE_SOURCE_DIR}/include/debug )
366-
target_link_libraries(${testName} lpf_debug lpf_hl_debug GTest::gtest GTest::gtest_main)
367-
else(debug)
368-
target_link_libraries(${testName} GTest::gtest GTest::gtest_main)
369-
endif(debug)
370-
target_link_exe_with_core(${testName} ${engines})
371-
foreach(LPF_IMPL_ID ${engines})
372-
target_compile_definitions(${testName} PUBLIC LPF_CORE_IMPL_ID=${LPF_IMPL_ID})
373-
endforeach(LPF_IMPL_ID)
374-
gtest_add_tests(TARGET ${testName}
375-
EXTRA_ARGS --gtest_output=xml:${test_output}/${testName}
376-
TEST_LIST seqTests
377-
)
378-
endfunction(add_gtest)
379-
380-
381-
382369
set(MY_TEST_LAUNCHER ${CMAKE_BINARY_DIR}/test_launcher.py)
383-
configure_file( ${CMAKE_SOURCE_DIR}/test_launcher.py ${MY_TEST_LAUNCHER} @ONLY )
370+
configure_file( ${CMAKE_SOURCE_DIR}/test_launcher.py ${MY_TEST_LAUNCHER} @ONLY FILE_PERMISSIONS WORLD_EXECUTE OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ)
384371
if( NOT Python3_FOUND )
385-
find_package( Python3 )
372+
find_package( Python3 REQUIRED)
386373
endif()
387-
# Proposed optimisation by Albert
388-
#execute_process( COMMAND ${Python3_EXECUTABLE} -OO -m py_compile ${MY_TEST_LAUNCHER}
389-
# OUTPUT_QUIET ERROR_QUIET RESULT_VARIABLE python_opt
390-
#)
391-
#if ( NOT python_opt EQUAL "0" )
392-
# message( FATAL_ERROR "cannot compile test runner" )
393-
#else()
394-
# message( "compilation of test runner successful" )
395-
#endif()
396-
397-
set(MY_DT_LAUNCHER ${Python3_EXECUTABLE} ${MY_TEST_LAUNCHER})
398-
# Have a macro to add a unit test that should run with MPI
399-
if (MPI_FOUND)
400-
401-
function(add_gtest_mpi testName ENGINE debug deathTest testSource )
402-
if ("{$ENGINE}" STREQUAL "")
403-
message(FATAL_ERROR "engine cannot be empty, ever!")
404-
endif()
405-
include(GoogleTest)
406-
add_executable(${testName} ${testSource} ${ARGN})
407-
target_compile_definitions(${testName} PUBLIC LPF_CORE_IMPL_ID=${ENGINE})
408-
target_compile_definitions(${testName} PUBLIC LPF_CORE_MPI_USES_${ENGINE})
409-
if (debug)
410-
target_include_directories( ${testName} BEFORE PRIVATE ${CMAKE_SOURCE_DIR}/include/debug )
411-
target_link_libraries(${testName} lpf_debug lpf_hl_debug GTest::gtest GTest::gtest_main)
412-
else(debug)
413-
target_link_libraries(${testName} GTest::gtest GTest::gtest_main)
414-
endif(debug)
415-
416-
417-
execute_process(COMMAND bash -c "grep -m 1 \"Exit code\" ${testSource} | awk 'NF>1{print $NF}' | tr -d '[:cntrl:]'" OUTPUT_VARIABLE retCode)
418-
execute_process(COMMAND bash -c "grep -m 1 \" P >=\" ${testSource} | awk 'NF>1{print $NF}' | tr -d '[:cntrl:]'" OUTPUT_VARIABLE minProcs)
419-
execute_process(COMMAND bash -c "grep -m 1 \" P <=\" ${testSource} | awk 'NF>1{print $NF}' | tr -d '[:cntrl:]'" OUTPUT_VARIABLE maxProcs)
420-
execute_process(COMMAND bash -c "grep -m 1 \"\\-probe\" ${testSource} | awk 'NF>1{print $NF}' | tr -d '[:cntrl:]'" OUTPUT_VARIABLE lpfProbeSecs)
421-
422-
target_link_exe_with_core(${testName} ${ENGINE})
423-
424-
425-
gtest_add_tests(TARGET ${testName}
426-
TEST_PREFIX ${ENGINE}_
427-
EXTRA_ARGS --gtest_output=xml:${test_output}/${ENGINE}_${testName}
428-
)
429-
430-
431-
if ("${minProcs}" STREQUAL "")
432-
set(minProcs "1")
433-
endif()
434-
if ("${maxProcs}" STREQUAL "")
435-
set(maxProcs "5")
436-
endif()
437-
if ("${lpfProbeSecs}" STREQUAL "")
438-
set(lpfProbeSecs "0.0")
439-
endif()
440-
if ("${retCode}" STREQUAL "")
441-
set(retCode "0")
442-
endif()
443-
444-
set_property(TARGET ${testName} PROPERTY TEST_LAUNCHER ${MY_DT_LAUNCHER};-e;${ENGINE};-L;${CMAKE_BINARY_DIR}/lpfrun_build;-p;${minProcs};-P;${maxProcs};-t;${lpfProbeSecs};-R;${retCode})
445-
446-
endfunction(add_gtest_mpi)
447-
endif(MPI_FOUND)
374+
375+
# Macro for adding a new GoogleTest test
376+
function(add_gtest testName ENGINE debug testSource )
377+
if ("{$ENGINE}" STREQUAL "")
378+
message(FATAL_ERROR "engine cannot be empty, ever!")
379+
endif()
380+
add_executable(${testName} ${testSource} ${ARGN})
381+
target_compile_definitions(${testName} PUBLIC LPF_CORE_IMPL_ID=${ENGINE})
382+
target_compile_definitions(${testName} PUBLIC LPF_CORE_MPI_USES_${ENGINE})
383+
if (debug)
384+
target_include_directories( ${testName} BEFORE PRIVATE ${CMAKE_SOURCE_DIR}/include/debug )
385+
target_link_libraries(${testName} lpf_debug lpf_hl_debug GTest::gtest GTest::gtest_main)
386+
else(debug)
387+
target_link_libraries(${testName} GTest::gtest GTest::gtest_main)
388+
endif(debug)
389+
390+
391+
# Extract test-specific information from comments of tests
392+
file(READ ${testSource} fileContents)
393+
string(REGEX MATCH "Exit code: ([0-9]+)" _ ${fileContents})
394+
set(retCode ${CMAKE_MATCH_1})
395+
string(REGEX MATCH "pre P >= ([0-9]+)" _ ${fileContents})
396+
set(minProcs ${CMAKE_MATCH_1})
397+
string(REGEX MATCH "pre P <= ([0-9]+)" _ ${fileContents})
398+
set(maxProcs ${CMAKE_MATCH_1})
399+
string(REGEX MATCH "-probe ([0-9]+.[0-9]+)" _ ${fileContents})
400+
set(lpfProbeSecs ${CMAKE_MATCH_1})
401+
402+
target_link_exe_with_core(${testName} ${ENGINE})
403+
404+
405+
if ("${minProcs}" STREQUAL "")
406+
set(minProcs "1")
407+
endif()
408+
if ("${maxProcs}" STREQUAL "")
409+
set(maxProcs "5")
410+
endif()
411+
if ("${lpfProbeSecs}" STREQUAL "")
412+
set(lpfProbeSecs "0.0")
413+
endif()
414+
if ("${retCode}" STREQUAL "")
415+
set(retCode "0")
416+
endif()
417+
418+
# Most recent approach to Gtests, recommended!
419+
set_property(TARGET ${testName} PROPERTY TEST_LAUNCHER ${MY_TEST_LAUNCHER};-e;${ENGINE};-L;${CMAKE_BINARY_DIR}/lpfrun_build;-p;${minProcs};-P;${maxProcs};-t;${lpfProbeSecs};-R;${retCode})
420+
gtest_discover_tests(${testName}
421+
TEST_PREFIX ${ENGINE}_
422+
EXTRA_ARGS --gtest_output=xml:${test_output}/${ENGINE}_${testName}
423+
DISCOVERY_MODE POST_BUILD
424+
DISCOVERY_TIMEOUT 15
425+
)
426+
427+
428+
endfunction(add_gtest)
448429

449430
else(LPF_ENABLE_TESTS)
450431
message(STATUS "Unit and API tests will *not* be built")
451-
function(add_gtest testName)
432+
function(add_gtest testName ENGINE debug testSource )
452433
# Do nothing because tests are disabled
453434
endfunction(add_gtest)
454435

455-
function(add_gtest_mpi testName ENGINE debug deathTest testSource )
456-
# DO nothing because tests are disabled
457-
endfunction(add_gtest_mpi)
458436
endif(LPF_ENABLE_TESTS)
459437

460438
include_directories(include)
@@ -531,5 +509,5 @@ install(DIRECTORY "include/bsp" DESTINATION ${INSTALL_HEADERS})
531509
install(DIRECTORY "include/debug" DESTINATION ${INSTALL_HEADERS}/lpf )
532510

533511
# Post install actions
534-
#add_subdirectory(post-install)
512+
add_subdirectory(post-install)
535513

README

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ Prerequisites
2828
Mandatory
2929
- GNU/Linux,
3030
- GNU C compiler,
31-
- GNU C++ compiler (C++03/TR1 or C++11),
31+
- GNU C++ compiler (C++11 compatible; however, C++17 compatible with tests enabled)
3232
- GNU Make,
33-
- CMake 3.1 or better.
33+
- CMake 3.29.0 or better.
3434

3535
Optional MPI engine requires
3636
- MPI-3, such as 'MPICH', 'OpenMPI', or 'MVAPICH'.

bootstrap.sh

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ installdir="$builddir"
8787
config=Release
8888
doc=OFF
8989
functests=OFF
90+
googletest_license_agreement=FALSE
9091
perftests=OFF
9192
reconfig=no
9293
CMAKE_EXE=cmake
@@ -125,6 +126,43 @@ do
125126

126127
--functests)
127128
functests=ON
129+
cat <<EOF
130+
131+
==============================================================================
132+
*** Use of third party software: Google Testing Framework ***
133+
------------------------------------------------------------------------------
134+
The functional test suite requires Google Testing Framework which comes with
135+
its own license. The license can be viewed via
136+
https://github.com/google/googletest/blob/v1.15.x/LICENSE
137+
Do you agree with the license [yes/no] ?
138+
EOF
139+
read answer
140+
if [ x$answer != xyes ]; then
141+
cat <<EOF
142+
------------------------------------------------------------------------------
143+
The answer was is '$answer'. For agreement, please type 'yes'.
144+
145+
Agreement with Google Testing Framework license is necessary for the
146+
functioning of the test suite. Please do not use the --functests parameter.
147+
==============================================================================
148+
EOF
149+
exit 1
150+
else
151+
cat <<EOF
152+
------------------------------------------------------------------------------
153+
User agrees with Google Testing Framework license. It will be downloaded during
154+
the build.
155+
==============================================================================
156+
EOF
157+
googletest_license_agreement=TRUE
158+
fi
159+
160+
shift
161+
;;
162+
163+
--functests=i-agree-with-googletest-license)
164+
functests=ON
165+
googletest_license_agreement=TRUE
128166
shift
129167
;;
130168

@@ -243,7 +281,8 @@ ${CMAKE_EXE} -Wno-dev \
243281
-DCMAKE_BUILD_TYPE=$config \
244282
-DLPFLIB_MAKE_DOC=$doc \
245283
-DLPFLIB_MAKE_TEST_DOC=$doc \
246-
-DLPF_ENABLE_TESTS=$functests \
284+
-DLPF_ENABLE_TESTS=$functests \
285+
-DGTEST_AGREE_TO_LICENSE=$googletest_license_agreement \
247286
-DLPFLIB_PERFTESTS=$perftests \
248287
-DLPFLIB_CONFIG_NAME=${config_name:-${config}}\
249288
-DLPF_HWLOC="${hwloc}" \

cmake/ibverbs_init.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include "infiniband/verbs.h"
2+
#include <stdlib.h>
3+
4+
int main(int argc, char** argv)
5+
{
6+
7+
int numDevices = -1;
8+
struct ibv_device * * const try_get_device_list = ibv_get_device_list( &numDevices );
9+
10+
if (!try_get_device_list) {
11+
abort();
12+
}
13+
14+
if (numDevices < 1) {
15+
abort();
16+
}
17+
18+
return 0;
19+
}

cmake/is_openmpi.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include "mpi.h"
2+
#include <stdio.h>
3+
4+
#ifdef OMPI_MAJOR_VERSION
5+
6+
int main() {
7+
printf("The OMPI_MAJOR_VERSION is %d\n", OMPI_MAJOR_VERSION);
8+
return 0;
9+
}
10+
#else
11+
#error This is not Open MPI
12+
#endif

cmake/mpi.cmake

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,14 @@ if (MPI_FOUND)
7878
-DINCLUDE_DIRECTORIES:STRING=${MPI_C_INCLUDE_PATH}
7979
)
8080

81+
try_compile( IS_OPENMPI "${CMAKE_BINARY_DIR}"
82+
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/is_openmpi.c"
83+
LINK_LIBRARIES ${MPI_C_LIBRARIES}
84+
CMAKE_FLAGS
85+
-DCMAKE_C_FLAGS:STRING=${MPI_C_COMPILE_FLAGS}
86+
-DCMAKE_EXE_LINKER_FLAGS:STRING=${MPI_C_LINK_FLAGS}
87+
-DINCLUDE_DIRECTORIES:STRING=${MPI_C_INCLUDE_PATH}
88+
)
8189

8290
try_run( MPI_IS_THREAD_COMPAT_RC MPI_IS_THREAD_COMPAT_COMPILES
8391
${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/mpi_is_thread_compat.c
@@ -153,4 +161,17 @@ if (MPI_FOUND)
153161

154162
endif()
155163

164+
if (LIB_IBVERBS)
165+
try_run( IBVERBS_INIT_RUNS IBVERBS_INIT_COMPILES
166+
${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ibverbs_init.c
167+
LINK_LIBRARIES ${LIB_IBVERBS}
168+
ARGS ${MPIRUN}
169+
)
170+
endif()
171+
172+
set(ENABLE_IBVERBS FALSE)
173+
if (LIB_IBVERBS AND NOT IBVERBS_INIT_RUNS STREQUAL "FAILED_TO_RUN")
174+
set(ENABLE_IBVERBS TRUE)
175+
endif()
176+
156177

0 commit comments

Comments
 (0)