avoid having to use external test runner script by parsing environment variables directly
This commit is contained in:
@ -430,6 +430,86 @@ size_t utils::trim_and_count_words(const std::string & text, const std::string &
|
|||||||
return utils::count_words(utils::trim_comment(text), separators);
|
return utils::count_words(utils::trim_comment(text), separators);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
Convert string into words on whitespace while handling single and
|
||||||
|
double quotes.
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
std::vector<std::string> utils::split_words(const std::string &text)
|
||||||
|
{
|
||||||
|
std::vector<std::string> list;
|
||||||
|
const char *buf = text.c_str();
|
||||||
|
std::size_t beg = 0;
|
||||||
|
std::size_t len = 0;
|
||||||
|
char c = *buf;
|
||||||
|
|
||||||
|
while (c) {
|
||||||
|
// leading whitespace
|
||||||
|
if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\f') {
|
||||||
|
c = *++buf;
|
||||||
|
++beg;
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
len = 0;
|
||||||
|
|
||||||
|
// handle escaped/quoted text.
|
||||||
|
quoted:
|
||||||
|
|
||||||
|
// handle single quote
|
||||||
|
if (c == '\'') {
|
||||||
|
c = *++buf;
|
||||||
|
++len;
|
||||||
|
while (((c != '\'') && (c != '\0'))
|
||||||
|
|| ((c == '\\') && (buf[1] == '\''))) {
|
||||||
|
if ((c == '\\') && (buf[1] == '\'')) {
|
||||||
|
++buf;
|
||||||
|
++len;
|
||||||
|
}
|
||||||
|
c = *++buf;
|
||||||
|
++len;
|
||||||
|
}
|
||||||
|
c = *++buf;
|
||||||
|
++len;
|
||||||
|
|
||||||
|
// handle double quote
|
||||||
|
} else if (c == '"') {
|
||||||
|
c = *++buf;
|
||||||
|
++len;
|
||||||
|
while (((c != '"') && (c != '\0'))
|
||||||
|
|| ((c == '\\') && (buf[1] == '"'))) {
|
||||||
|
if ((c == '\\') && (buf[1] == '"')) {
|
||||||
|
++buf;
|
||||||
|
++len;
|
||||||
|
}
|
||||||
|
c = *++buf;
|
||||||
|
++len;
|
||||||
|
}
|
||||||
|
c = *++buf;
|
||||||
|
++len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unquoted
|
||||||
|
while (1) {
|
||||||
|
if ((c == '\'') || (c == '"')) goto quoted;
|
||||||
|
// skip escaped quote
|
||||||
|
if ((c == '\\') && ((buf[1] == '\'') || (buf[1] == '"'))) {
|
||||||
|
++buf;
|
||||||
|
++len;
|
||||||
|
c = *++buf;
|
||||||
|
++len;
|
||||||
|
}
|
||||||
|
if ((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n')
|
||||||
|
|| (c == '\f') || (c == '\0')) {
|
||||||
|
list.push_back(text.substr(beg,len));
|
||||||
|
beg += len;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
c = *++buf;
|
||||||
|
++len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
Return whether string is a valid integer number
|
Return whether string is a valid integer number
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|||||||
15
src/utils.h
15
src/utils.h
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "lmptype.h"
|
#include "lmptype.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
namespace LAMMPS_NS {
|
namespace LAMMPS_NS {
|
||||||
@ -181,6 +182,20 @@ namespace LAMMPS_NS {
|
|||||||
*/
|
*/
|
||||||
size_t trim_and_count_words(const std::string & text, const std::string & separators = " \t\r\n\f");
|
size_t trim_and_count_words(const std::string & text, const std::string & separators = " \t\r\n\f");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Take text and split into non-whitespace words.
|
||||||
|
*
|
||||||
|
* This can handle single and double quotes, escaped quotes,
|
||||||
|
* and escaped codes within quotes, but due to using an STL
|
||||||
|
* container and STL strings is rather slow because of making
|
||||||
|
* copies. Designed for parsing command lines and similar text
|
||||||
|
* and not for time critical processing. Use a tokenizer for that.
|
||||||
|
*
|
||||||
|
* \param text string that should be split
|
||||||
|
* \return STL vector with the words
|
||||||
|
*/
|
||||||
|
std::vector<std::string> split_words(const std::string &text);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Check if string can be converted to valid integer
|
* \brief Check if string can be converted to valid integer
|
||||||
* \param text string that should be checked
|
* \param text string that should be checked
|
||||||
|
|||||||
@ -37,20 +37,15 @@ target_link_libraries(pair_style PRIVATE lammps style_tests)
|
|||||||
file(GLOB MOL_PAIR_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/mol-pair-*.yaml)
|
file(GLOB MOL_PAIR_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/mol-pair-*.yaml)
|
||||||
foreach(TEST ${MOL_PAIR_TESTS})
|
foreach(TEST ${MOL_PAIR_TESTS})
|
||||||
string(REGEX REPLACE "^.*mol-pair-(.*)\.yaml" "MolPairStyle:\\1" TNAME ${TEST})
|
string(REGEX REPLACE "^.*mol-pair-(.*)\.yaml" "MolPairStyle:\\1" TNAME ${TEST})
|
||||||
add_test(NAME ${TNAME}
|
add_test(NAME ${TNAME} COMMAND pair_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$<TARGET_FILE:pair_style>
|
set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}")
|
||||||
-DTEST_INPUT=${TEST} -DTEST_NAME=${TNAME} -P ${CMAKE_CURRENT_SOURCE_DIR}/TestRunner.cmake
|
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
# tests for metal-like atomic systems and related pair styles
|
# tests for metal-like atomic systems and related pair styles
|
||||||
file(GLOB ATOMIC_PAIR_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/atomic-pair-*.yaml)
|
file(GLOB ATOMIC_PAIR_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/atomic-pair-*.yaml)
|
||||||
foreach(TEST ${ATOMIC_PAIR_TESTS})
|
foreach(TEST ${ATOMIC_PAIR_TESTS})
|
||||||
string(REGEX REPLACE "^.*atomic-pair-(.*)\.yaml" "AtomicPairStyle:\\1" TNAME ${TEST})
|
string(REGEX REPLACE "^.*atomic-pair-(.*)\.yaml" "AtomicPairStyle:\\1" TNAME ${TEST})
|
||||||
add_test(NAME ${TNAME}
|
add_test(NAME ${TNAME} COMMAND pair_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$<TARGET_FILE:pair_style>
|
|
||||||
-DTEST_INPUT=${TEST} -DTEST_NAME=${TNAME} -P ${CMAKE_CURRENT_SOURCE_DIR}/TestRunner.cmake
|
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}")
|
set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}")
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
@ -58,10 +53,7 @@ endforeach()
|
|||||||
file(GLOB MANYBODY_PAIR_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/manybody-pair-*.yaml)
|
file(GLOB MANYBODY_PAIR_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/manybody-pair-*.yaml)
|
||||||
foreach(TEST ${MANYBODY_PAIR_TESTS})
|
foreach(TEST ${MANYBODY_PAIR_TESTS})
|
||||||
string(REGEX REPLACE "^.*manybody-pair-(.*)\.yaml" "ManybodyPairStyle:\\1" TNAME ${TEST})
|
string(REGEX REPLACE "^.*manybody-pair-(.*)\.yaml" "ManybodyPairStyle:\\1" TNAME ${TEST})
|
||||||
add_test(NAME ${TNAME}
|
add_test(NAME ${TNAME} COMMAND pair_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$<TARGET_FILE:pair_style>
|
|
||||||
-DTEST_INPUT=${TEST} -DTEST_NAME=${TNAME} -P ${CMAKE_CURRENT_SOURCE_DIR}/TestRunner.cmake
|
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}")
|
set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}")
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
@ -72,10 +64,8 @@ target_link_libraries(bond_style PRIVATE lammps style_tests)
|
|||||||
file(GLOB BOND_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/bond-*.yaml)
|
file(GLOB BOND_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/bond-*.yaml)
|
||||||
foreach(TEST ${BOND_TESTS})
|
foreach(TEST ${BOND_TESTS})
|
||||||
string(REGEX REPLACE "^.*bond-(.*)\.yaml" "BondStyle:\\1" TNAME ${TEST})
|
string(REGEX REPLACE "^.*bond-(.*)\.yaml" "BondStyle:\\1" TNAME ${TEST})
|
||||||
add_test(NAME ${TNAME}
|
add_test(NAME ${TNAME} COMMAND bond_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$<TARGET_FILE:bond_style>
|
set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}")
|
||||||
-DTEST_INPUT=${TEST} -DTEST_NAME=${TNAME} -P ${CMAKE_CURRENT_SOURCE_DIR}/TestRunner.cmake
|
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
# angle style tester
|
# angle style tester
|
||||||
@ -85,8 +75,6 @@ target_link_libraries(angle_style PRIVATE lammps style_tests)
|
|||||||
file(GLOB ANGLE_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/angle-*.yaml)
|
file(GLOB ANGLE_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/angle-*.yaml)
|
||||||
foreach(TEST ${ANGLE_TESTS})
|
foreach(TEST ${ANGLE_TESTS})
|
||||||
string(REGEX REPLACE "^.*angle-(.*)\.yaml" "AngleStyle:\\1" TNAME ${TEST})
|
string(REGEX REPLACE "^.*angle-(.*)\.yaml" "AngleStyle:\\1" TNAME ${TEST})
|
||||||
add_test(NAME ${TNAME}
|
add_test(NAME ${TNAME} COMMAND angle_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$<TARGET_FILE:angle_style>
|
set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}")
|
||||||
-DTEST_INPUT=${TEST} -DTEST_NAME=${TNAME} -P ${CMAKE_CURRENT_SOURCE_DIR}/TestRunner.cmake
|
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
# workaround to allow passing extra arguments to test runs
|
|
||||||
# through ctest via a TEST_ARGS environment variable
|
|
||||||
# This can be used to, e.g. reset reference data for individual
|
|
||||||
# tests from the build folder with "env TEST_ARGS=-u ctest -R sometest"
|
|
||||||
execute_process(COMMAND ${TEST_EXECUTABLE} ${TEST_INPUT} $ENV{TEST_ARGS} RESULT_VARIABLE rv)
|
|
||||||
if(NOT "${rv}" STREQUAL "0")
|
|
||||||
message(FATAL_ERROR "Test ${TEST_NAME} failed with status ${rv}")
|
|
||||||
endif()
|
|
||||||
@ -17,9 +17,11 @@
|
|||||||
#include "gmock/gmock.h"
|
#include "gmock/gmock.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <mpi.h>
|
#include <mpi.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
// common read_yaml_file function
|
// common read_yaml_file function
|
||||||
bool read_yaml_file(const char *infile, TestConfig &config)
|
bool read_yaml_file(const char *infile, TestConfig &config)
|
||||||
@ -76,6 +78,19 @@ int main(int argc, char **argv)
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handle arguments passed via environment variable
|
||||||
|
std::vector<std::string> env = utils::split_words(getenv("TEST_ARGS"));
|
||||||
|
for (auto arg : env) {
|
||||||
|
if (arg == "-u") {
|
||||||
|
generate_yaml_file(argv[1], test_config);
|
||||||
|
return 0;
|
||||||
|
} else if (arg == "-s") {
|
||||||
|
print_stats = true;
|
||||||
|
} else if (arg == "-v") {
|
||||||
|
verbose = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int iarg = 2;
|
int iarg = 2;
|
||||||
while (iarg < argc) {
|
while (iarg < argc) {
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
using namespace LAMMPS_NS;
|
using namespace LAMMPS_NS;
|
||||||
using ::testing::Eq;
|
using ::testing::Eq;
|
||||||
@ -48,6 +49,24 @@ TEST(Utils, count_words_with_extra_spaces)
|
|||||||
ASSERT_EQ(utils::count_words(" some text # comment "), 4);
|
ASSERT_EQ(utils::count_words(" some text # comment "), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Utils, split_words_simple)
|
||||||
|
{
|
||||||
|
std::vector<std::string> list = utils::split_words("one two three");
|
||||||
|
ASSERT_EQ(list.size(), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Utils, split_words_quoted)
|
||||||
|
{
|
||||||
|
std::vector<std::string> list = utils::split_words("one 'two' \"three\"");
|
||||||
|
ASSERT_EQ(list.size(), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Utils, split_words_escaped)
|
||||||
|
{
|
||||||
|
std::vector<std::string> list = utils::split_words("1\\' '\"two\"' 3\\\"");
|
||||||
|
ASSERT_EQ(list.size(), 3);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(Utils, valid_integer1)
|
TEST(Utils, valid_integer1)
|
||||||
{
|
{
|
||||||
ASSERT_TRUE(utils::is_integer("10"));
|
ASSERT_TRUE(utils::is_integer("10"));
|
||||||
|
|||||||
Reference in New Issue
Block a user