diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt index addc8bc244..26db526b60 100644 --- a/unittest/CMakeLists.txt +++ b/unittest/CMakeLists.txt @@ -10,6 +10,22 @@ set_tests_properties(RunLammps PROPERTIES ENVIRONMENT "TSAN_OPTIONS=ignore_noninstrumented_modules=1" PASS_REGULAR_EXPRESSION "^LAMMPS \\([0-9]+ [A-Za-z]+ 2[0-9][0-9][0-9]\\)") +# check if the compiled executable will print the help message +add_test(NAME HelpMessage + COMMAND $ -h + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) +set_tests_properties(HelpMessage PROPERTIES + ENVIRONMENT "TSAN_OPTIONS=ignore_noninstrumented_modules=1;PAGER=head" + PASS_REGULAR_EXPRESSION ".*Large-scale Atomic/Molecular Massively Parallel Simulator -.*Usage example:.*") + +# check if the compiled executable will error out on an invalid command line flag +add_test(NAME InvalidFlag + COMMAND $ -xxx + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) +set_tests_properties(InvalidFlag PROPERTIES + ENVIRONMENT "TSAN_OPTIONS=ignore_noninstrumented_modules=1" + PASS_REGULAR_EXPRESSION "ERROR: Invalid command-line argument.*") + if(BUILD_MPI) function(add_mpi_test) set(MPI_TEST_NUM_PROCS 1) diff --git a/unittest/cplusplus/CMakeLists.txt b/unittest/cplusplus/CMakeLists.txt index 90ef9a0282..aef69f3722 100644 --- a/unittest/cplusplus/CMakeLists.txt +++ b/unittest/cplusplus/CMakeLists.txt @@ -2,6 +2,7 @@ add_executable(test_lammps_class test_lammps_class.cpp) target_link_libraries(test_lammps_class PRIVATE lammps GTest::GMockMain GTest::GTest GTest::GMock) add_test(LammpsClass test_lammps_class) +set_tests_properties(LammpsClass PROPERTIES ENVIRONMENT "OMP_NUM_THREADS=1") add_executable(test_input_class test_input_class.cpp) target_link_libraries(test_input_class PRIVATE lammps GTest::GTest GTest::GTestMain) diff --git a/unittest/cplusplus/test_lammps_class.cpp b/unittest/cplusplus/test_lammps_class.cpp index c20cdf336a..6a0e6719cc 100644 --- a/unittest/cplusplus/test_lammps_class.cpp +++ b/unittest/cplusplus/test_lammps_class.cpp @@ -1,13 +1,17 @@ // unit tests for the LAMMPS base class +#include "comm.h" +#include "info.h" #include "lammps.h" -#include // for stdin, stdout +#include // for stdin, stdout +#include // for setenv #include #include #include "gmock/gmock.h" #include "gtest/gtest.h" +using ::testing::MatchesRegex; using ::testing::StartsWith; namespace LAMMPS_NS { @@ -95,6 +99,7 @@ TEST_F(LAMMPS_plain, InitMembers) EXPECT_STREQ(LAMMPS::git_branch, "(unknown)"); EXPECT_STREQ(LAMMPS::git_descriptor, "(unknown)"); } + EXPECT_EQ(lmp->comm->nthreads, 1); } TEST_F(LAMMPS_plain, TestStyles) @@ -229,6 +234,7 @@ TEST_F(LAMMPS_omp, InitMembers) EXPECT_STREQ(LAMMPS::git_branch, "(unknown)"); EXPECT_STREQ(LAMMPS::git_descriptor, "(unknown)"); } + EXPECT_EQ(lmp->comm->nthreads, 2); } // test fixture for Kokkos tests @@ -318,10 +324,49 @@ TEST_F(LAMMPS_kokkos, InitMembers) } } -// check help message printing -TEST(LAMMPS_help, HelpMessage) +// check if Comm::nthreads is initialized to either 1 or 2 (from the previous tests) +TEST(LAMMPS_init, OpenMP) { - const char *args[] = {"LAMMPS_test", "-h"}; + if (!LAMMPS::is_installed_pkg("USER-OMP")) GTEST_SKIP(); + + FILE *fp = fopen("in.lammps_empty", "w"); + fputs("\n", fp); + fclose(fp); + + const char *args[] = {"LAMMPS_init", "-in", "in.lammps_empty", "-log", "none", "-nocite"}; + char **argv = (char **)args; + int argc = sizeof(args) / sizeof(char *); + + ::testing::internal::CaptureStdout(); + LAMMPS *lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD); + std::string output = ::testing::internal::GetCapturedStdout(); + EXPECT_THAT(output, MatchesRegex(".*using 2 OpenMP thread.*per MPI task.*")); + + if (LAMMPS_NS::Info::has_accelerator_feature("USER-OMP", "api", "openmp")) + EXPECT_EQ(lmp->comm->nthreads, 2); + else + EXPECT_EQ(lmp->comm->nthreads, 1); + ::testing::internal::CaptureStdout(); + delete lmp; + ::testing::internal::GetCapturedStdout(); + + remove("in.lammps_empty"); +} + +// check no OMP_NUM_THREADS warning message printing. this must be the +// last OpenMP related test as threads will be locked to 1 from here on. + +TEST(LAMMPS_init, NoOpenMP) +{ + if (!LAMMPS_NS::Info::has_accelerator_feature("USER-OMP", "api", "openmp")) + GTEST_SKIP() << "No threading enabled"; + + FILE *fp = fopen("in.lammps_class_noomp", "w"); + fputs("\n", fp); + fclose(fp); + unsetenv("OMP_NUM_THREADS"); + + const char *args[] = {"LAMMPS_init", "-in", "in.lammps_class_noomp", "-log", "none", "-nocite"}; char **argv = (char **)args; int argc = sizeof(args) / sizeof(char *); @@ -329,7 +374,11 @@ TEST(LAMMPS_help, HelpMessage) LAMMPS *lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD); std::string output = ::testing::internal::GetCapturedStdout(); EXPECT_THAT(output, - StartsWith("\nLarge-scale Atomic/Molecular Massively Parallel Simulator -")); + MatchesRegex(".*OMP_NUM_THREADS environment is not set.*Defaulting to 1 thread.*")); + EXPECT_EQ(lmp->comm->nthreads, 1); + ::testing::internal::CaptureStdout(); delete lmp; + ::testing::internal::GetCapturedStdout(); } + } // namespace LAMMPS_NS