Unverified Commit ee5be420 authored by Axel Kohlmeyer's avatar Axel Kohlmeyer
Browse files

avoid having to use external test runner script by parsing environment variables directly

parent 8cec13a0
Loading
Loading
Loading
Loading
+80 −0
Original line number Diff line number Diff line
@@ -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);
}

/* ----------------------------------------------------------------------
   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
------------------------------------------------------------------------- */
+15 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include "lmptype.h"
#include <string>
#include <vector>
#include <cstdio>

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");

    /**
     * \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
     * \param text string that should be checked
+8 −20
Original line number Diff line number Diff line
@@ -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)
foreach(TEST ${MOL_PAIR_TESTS})
  string(REGEX REPLACE "^.*mol-pair-(.*)\.yaml" "MolPairStyle:\\1" TNAME ${TEST})
  add_test(NAME ${TNAME}
    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})
  add_test(NAME ${TNAME} COMMAND pair_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
  set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}")
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})
  add_test(NAME ${TNAME}
    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})
  add_test(NAME ${TNAME} COMMAND pair_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
  set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}")
endforeach()

@@ -58,10 +53,7 @@ endforeach()
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})
  add_test(NAME ${TNAME}
    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})
  add_test(NAME ${TNAME} COMMAND pair_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
  set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}")
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)
foreach(TEST ${BOND_TESTS})
  string(REGEX REPLACE "^.*bond-(.*)\.yaml" "BondStyle:\\1" TNAME ${TEST})
  add_test(NAME ${TNAME}
    COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$<TARGET_FILE:bond_style>
    -DTEST_INPUT=${TEST} -DTEST_NAME=${TNAME} -P ${CMAKE_CURRENT_SOURCE_DIR}/TestRunner.cmake
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
  add_test(NAME ${TNAME} COMMAND bond_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
  set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}")
endforeach()

# 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)
foreach(TEST ${ANGLE_TESTS})
  string(REGEX REPLACE "^.*angle-(.*)\.yaml" "AngleStyle:\\1" TNAME ${TEST})
  add_test(NAME ${TNAME}
    COMMAND ${CMAKE_COMMAND} -DTEST_EXECUTABLE=$<TARGET_FILE:angle_style>
    -DTEST_INPUT=${TEST} -DTEST_NAME=${TNAME} -P ${CMAKE_CURRENT_SOURCE_DIR}/TestRunner.cmake
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
  add_test(NAME ${TNAME} COMMAND angle_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
  set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}")
endforeach()
+0 −8
Original line number Diff line number Diff line
# 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()
+15 −0
Original line number Diff line number Diff line
@@ -17,9 +17,11 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <mpi.h>
#include <vector>

// common read_yaml_file function
bool read_yaml_file(const char *infile, TestConfig &config)
@@ -76,6 +78,19 @@ int main(int argc, char **argv)
        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;
    while (iarg < argc) {

Loading