find_package(YAML) if(NOT YAML_FOUND) set(YAML_URL "https://pyyaml.org/download/libyaml/yaml-0.2.5.tar.gz" CACHE STRING "URL for libyaml tarball") set(YAML_MD5 "bb15429d8fb787e7d3f1c83ae129a999" CACHE STRING "MD5 checksum of libyaml tarball") mark_as_advanced(YAML_URL) mark_as_advanced(YAML_MD5) # download and build a local copy of libyaml include(ExternalCMakeProject) ExternalCMakeProject(libyaml ${YAML_URL} ${YAML_MD5} yaml . CMakeLists.libyaml) add_library(Yaml::Yaml ALIAS yaml) endif() function(extract_tags out yaml_file) file(STRINGS ${yaml_file} TAGS_LINE REGEX "^tags:") string(REPLACE "tags:" "" TAGS_LINE "${TAGS_LINE}") string(REGEX MATCHALL "[^, \t\r\n]+" TAGS "${TAGS_LINE}") set(${out} "${TAGS}" PARENT_SCOPE) endfunction() if(CMAKE_VERSION VERSION_LESS 3.12) # adjust so we find Python 3 versions before Python 2 on old systems with old CMake set(Python_ADDITIONAL_VERSIONS 3.8 3.7 3.6 3.5) find_package(PythonInterp) # Deprecated since version 3.12 if(PYTHONINTERP_FOUND) set(Python_EXECUTABLE ${PYTHON_EXECUTABLE}) endif() else() find_package(Python COMPONENTS Interpreter) endif() if(Python_EXECUTABLE) add_custom_target(check-tests ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/check_tests.py -s ${LAMMPS_SOURCE_DIR} -t ${CMAKE_CURRENT_SOURCE_DIR}/tests COMMENT "Check completeness of force style tests") endif() set(TEST_INPUT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR}/tests) add_library(style_tests STATIC yaml_writer.cpp error_stats.cpp test_config_reader.cpp test_main.cpp) if(YAML_FOUND) target_compile_definitions(style_tests PRIVATE TEST_INPUT_FOLDER=${TEST_INPUT_FOLDER}) else() # we always use static linkage with local compiled libyaml target_compile_definitions(style_tests PRIVATE TEST_INPUT_FOLDER=${TEST_INPUT_FOLDER} YAML_DECLARE_STATIC) endif() target_include_directories(style_tests PRIVATE ${LAMMPS_SOURCE_DIR}) target_link_libraries(style_tests PUBLIC gmock Yaml::Yaml lammps) # propagate sanitizer options to test tools if(ENABLE_SANITIZER AND (NOT (ENABLE_SANITIZER STREQUAL "none"))) if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.13) target_compile_options(style_tests PUBLIC -fsanitize=${ENABLE_SANITIZER}) target_link_options(style_tests PUBLIC -fsanitize=${ENABLE_SANITIZER}) endif() endif() # unit test for error stats class add_executable(test_error_stats test_error_stats.cpp) target_include_directories(test_error_stats PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${LAMMPS_SOURCE_DIR}) target_link_libraries(test_error_stats PRIVATE gtest_main) add_test(NAME ErrorStats COMMAND test_error_stats) # pair style tester add_executable(test_pair_style test_pair_style.cpp) target_link_libraries(test_pair_style PRIVATE lammps style_tests) if(FFT_SINGLE) target_compile_definitions(test_pair_style PRIVATE -DFFT_SINGLE) endif() # prepare environment for testers if(WIN32) set(FORCE_TEST_ENVIRONMENT PYTHONPATH=${TEST_INPUT_FOLDER}) else() set(FORCE_TEST_ENVIRONMENT PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}) endif() list(APPEND FORCE_TEST_ENVIRONMENT "PYTHONUNBUFFERED=1") list(APPEND FORCE_TEST_ENVIRONMENT "OMP_PROC_BIND=false") list(APPEND FORCE_TEST_ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}") get_property(BUILD_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) if(BUILD_IS_MULTI_CONFIG) set(LAMMPS_LIB_PATH ${CMAKE_BINARY_DIR}/$) else() set(LAMMPS_LIB_PATH ${CMAKE_BINARY_DIR}) endif() if(APPLE) list(APPEND FORCE_TEST_ENVIRONMENT "DYLD_LIBRARY_PATH=${LAMMPS_LIB_PATH}:$ENV{DYLD_LIBRARY_PATH}") elseif(WIN32) list(APPEND FORCE_TEST_ENVIRONMENT "LAMMPSDLLPATH=${LAMMPS_LIB_PATH}") else() list(APPEND FORCE_TEST_ENVIRONMENT "LD_LIBRARY_PATH=${LAMMPS_LIB_PATH}:$ENV{LD_LIBRARY_PATH}") endif() # tests for molecular systems and related pair styles file(GLOB MOL_PAIR_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/mol-pair-*.yaml) # cannot test MSM with single precision data if(FFT_SINGLE) list(FILTER MOL_PAIR_TESTS EXCLUDE REGEX "msm") endif() foreach(TEST ${MOL_PAIR_TESTS}) string(REGEX REPLACE "^.*mol-pair-(.*)\.yaml" "MolPairStyle:\\1" TNAME ${TEST}) extract_tags(TEST_TAGS ${TEST}) list(FIND TEST_TAGS "no${CMAKE_SYSTEM_NAME}" _SKIPME) if(_SKIPME GREATER_EQUAL 0) continue() endif() add_test(NAME ${TNAME} COMMAND test_pair_style ${TEST}) set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "${FORCE_TEST_ENVIRONMENT}") set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}") endforeach() # tests for metal-like atomic systems and related pair styles file(GLOB ATOMIC_PAIR_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/atomic-pair-*.yaml) foreach(TEST ${ATOMIC_PAIR_TESTS}) string(REGEX REPLACE "^.*atomic-pair-(.*)\.yaml" "AtomicPairStyle:\\1" TNAME ${TEST}) extract_tags(TEST_TAGS ${TEST}) list(FIND TEST_TAGS "no${CMAKE_SYSTEM_NAME}" _SKIPME) if(_SKIPME GREATER_EQUAL 0) continue() endif() add_test(NAME ${TNAME} COMMAND test_pair_style ${TEST}) set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "${FORCE_TEST_ENVIRONMENT}") set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}") endforeach() # tests for Si-like manybody systems and related pair styles file(GLOB MANYBODY_PAIR_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/manybody-pair-*.yaml) foreach(TEST ${MANYBODY_PAIR_TESTS}) string(REGEX REPLACE "^.*manybody-pair-(.*)\.yaml" "ManybodyPairStyle:\\1" TNAME ${TEST}) extract_tags(TEST_TAGS ${TEST}) list(FIND TEST_TAGS "no${CMAKE_SYSTEM_NAME}" _SKIPME) if(_SKIPME GREATER_EQUAL 0) continue() endif() add_test(NAME ${TNAME} COMMAND test_pair_style ${TEST}) set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "${FORCE_TEST_ENVIRONMENT}") set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}") endforeach() # bond style tester add_executable(test_bond_style test_bond_style.cpp) target_link_libraries(test_bond_style PRIVATE lammps style_tests) file(GLOB BOND_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/bond-*.yaml) foreach(TEST ${BOND_TESTS}) string(REGEX REPLACE "^.*bond-(.*)\.yaml" "BondStyle:\\1" TNAME ${TEST}) extract_tags(TEST_TAGS ${TEST}) list(FIND TEST_TAGS "no${CMAKE_SYSTEM_NAME}" _SKIPME) if(_SKIPME GREATER_EQUAL 0) continue() endif() add_test(NAME ${TNAME} COMMAND test_bond_style ${TEST}) set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "${FORCE_TEST_ENVIRONMENT}") set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}") endforeach() # angle style tester add_executable(test_angle_style test_angle_style.cpp) target_link_libraries(test_angle_style PRIVATE lammps style_tests) file(GLOB ANGLE_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/angle-*.yaml) foreach(TEST ${ANGLE_TESTS}) string(REGEX REPLACE "^.*angle-(.*)\.yaml" "AngleStyle:\\1" TNAME ${TEST}) extract_tags(TEST_TAGS ${TEST}) list(FIND TEST_TAGS "no${CMAKE_SYSTEM_NAME}" _SKIPME) if(_SKIPME GREATER_EQUAL 0) continue() endif() add_test(NAME ${TNAME} COMMAND test_angle_style ${TEST}) set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "${FORCE_TEST_ENVIRONMENT}") set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}") endforeach() # kspace style tester, currently uses the pair style tool file(GLOB KSPACE_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/kspace-*.yaml) # cannot test MSM with single precision data if(FFT_SINGLE) list(FILTER KSPACE_TESTS EXCLUDE REGEX "msm") endif() foreach(TEST ${KSPACE_TESTS}) string(REGEX REPLACE "^.*kspace-(.*)\.yaml" "KSpaceStyle:\\1" TNAME ${TEST}) extract_tags(TEST_TAGS ${TEST}) list(FIND TEST_TAGS "no${CMAKE_SYSTEM_NAME}" _SKIPME) if(_SKIPME GREATER_EQUAL 0) continue() endif() add_test(NAME ${TNAME} COMMAND test_pair_style ${TEST}) set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "${FORCE_TEST_ENVIRONMENT}") set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}") endforeach() # tester for timestepping fixes add_executable(test_fix_timestep test_fix_timestep.cpp) if(NOT BUILD_SHARED_LIBS) target_compile_definitions(test_fix_timestep PRIVATE USING_STATIC_LIBS=1) endif() target_link_libraries(test_fix_timestep PRIVATE lammps style_tests) # tests for timestep related fixes (time integration, thermostat, force manipulation, constraints/restraints) file(GLOB FIX_TIMESTEP_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/fix-timestep-*.yaml) foreach(TEST ${FIX_TIMESTEP_TESTS}) string(REGEX REPLACE "^.*fix-timestep-(.*)\.yaml" "FixTimestep:\\1" TNAME ${TEST}) extract_tags(TEST_TAGS ${TEST}) list(FIND TEST_TAGS "no${CMAKE_SYSTEM_NAME}" _SKIPME) if(_SKIPME GREATER_EQUAL 0) continue() endif() add_test(NAME ${TNAME} COMMAND test_fix_timestep ${TEST}) if(WIN32) set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}\\\;${LAMMPS_PYTHON_DIR}") else() set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:${LAMMPS_PYTHON_DIR}:$ENV{PYTHONPATH}") endif() set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}") endforeach() # dihedral style tester add_executable(test_dihedral_style test_dihedral_style.cpp) target_link_libraries(test_dihedral_style PRIVATE lammps style_tests) file(GLOB DIHEDRAL_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/dihedral-*.yaml) foreach(TEST ${DIHEDRAL_TESTS}) string(REGEX REPLACE "^.*dihedral-(.*)\.yaml" "DihedralStyle:\\1" TNAME ${TEST}) extract_tags(TEST_TAGS ${TEST}) list(FIND TEST_TAGS "no${CMAKE_SYSTEM_NAME}" _SKIPME) if(_SKIPME GREATER_EQUAL 0) continue() endif() add_test(NAME ${TNAME} COMMAND test_dihedral_style ${TEST}) set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}") set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}") endforeach() # improper style tester add_executable(test_improper_style test_improper_style.cpp) target_link_libraries(test_improper_style PRIVATE lammps style_tests) file(GLOB IMPROPER_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/improper-*.yaml) foreach(TEST ${IMPROPER_TESTS}) string(REGEX REPLACE "^.*improper-(.*)\.yaml" "ImproperStyle:\\1" TNAME ${TEST}) extract_tags(TEST_TAGS ${TEST}) list(FIND TEST_TAGS "no${CMAKE_SYSTEM_NAME}" _SKIPME) if(_SKIPME GREATER_EQUAL 0) continue() endif() add_test(NAME ${TNAME} COMMAND test_improper_style ${TEST}) set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}") set_tests_properties(${TNAME} PROPERTIES LABELS "${TEST_TAGS}") endforeach()