Merge pull request #2679 from akohlmey/more-unittests

Expand unit tests
This commit is contained in:
Axel Kohlmeyer
2021-04-02 17:51:29 -04:00
committed by GitHub
67 changed files with 7451 additions and 2485 deletions

View File

@ -37,6 +37,10 @@ add_executable(test_groups test_groups.cpp)
target_link_libraries(test_groups PRIVATE lammps GTest::GMock GTest::GTest)
add_test(NAME Groups COMMAND test_groups WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
add_executable(test_variables test_variables.cpp)
target_link_libraries(test_variables PRIVATE lammps GTest::GMock GTest::GTest)
add_test(NAME Variables COMMAND test_variables WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
add_executable(test_kim_commands test_kim_commands.cpp)
if(KIM_EXTRA_UNITTESTS)
if(CURL_FOUND)

View File

@ -22,6 +22,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "../testing/core.h"
#include <cstring>
#include <vector>
@ -29,12 +30,6 @@
// whether to print verbose output (i.e. not capturing LAMMPS screen output).
bool verbose = false;
#if defined(OMPI_MAJOR_VERSION)
const bool have_openmpi = true;
#else
const bool have_openmpi = false;
#endif
using LAMMPS_NS::utils::split_words;
namespace LAMMPS_NS {
@ -42,54 +37,22 @@ using ::testing::ExitedWithCode;
using ::testing::MatchesRegex;
using ::testing::StrEq;
#define TEST_FAILURE(errmsg, ...) \
if (Info::has_exceptions()) { \
::testing::internal::CaptureStdout(); \
ASSERT_ANY_THROW({__VA_ARGS__}); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
if (verbose) std::cout << mesg; \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} else { \
if (!have_openmpi) { \
::testing::internal::CaptureStdout(); \
ASSERT_DEATH({__VA_ARGS__}, ""); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
if (verbose) std::cout << mesg; \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} \
}
class GroupTest : public ::testing::Test {
class GroupTest : public LAMMPSTest {
protected:
LAMMPS *lmp;
Group *group;
Domain *domain;
void SetUp() override
{
const char *args[] = {"GroupTest", "-log", "none", "-echo", "screen", "-nocite"};
char **argv = (char **)args;
int argc = sizeof(args) / sizeof(char *);
if (!verbose) ::testing::internal::CaptureStdout();
lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD);
if (!verbose) ::testing::internal::GetCapturedStdout();
group = lmp->group;
testbinary = "GroupTest";
LAMMPSTest::SetUp();
group = lmp->group;
domain = lmp->domain;
}
void TearDown() override
{
if (!verbose) ::testing::internal::CaptureStdout();
delete lmp;
if (!verbose) ::testing::internal::GetCapturedStdout();
std::cout.flush();
}
void command(const std::string &cmd) { lmp->input->one(cmd); }
void atomic_system()
{
if (!verbose) ::testing::internal::CaptureStdout();
BEGIN_HIDE_OUTPUT();
command("units real");
command("lattice sc 1.0 origin 0.125 0.125 0.125");
command("region box block -2 2 -2 2 -2 2");
@ -101,23 +64,25 @@ protected:
command("region top block INF INF -2.0 -1.0 INF INF");
command("set region left type 2");
command("set region right type 3");
if (!verbose) ::testing::internal::GetCapturedStdout();
END_HIDE_OUTPUT();
}
void molecular_system()
{
if (!verbose) ::testing::internal::CaptureStdout();
BEGIN_HIDE_OUTPUT();
command("fix props all property/atom mol rmass q");
if (!verbose) ::testing::internal::GetCapturedStdout();
END_HIDE_OUTPUT();
atomic_system();
if (!verbose) ::testing::internal::CaptureStdout();
BEGIN_HIDE_OUTPUT();
command("variable molid atom floor(id/4)+1");
command("variable charge atom 2.0*sin(PI/32*id)");
command("set atom * mol v_molid");
command("set atom * charge v_charge");
command("set type 1 mass 0.5");
command("set type 2*4 mass 2.0");
if (!verbose) ::testing::internal::GetCapturedStdout();
END_HIDE_OUTPUT();
}
};
@ -131,7 +96,7 @@ TEST_F(GroupTest, EmptyDelete)
{
atomic_system();
if (!verbose) ::testing::internal::CaptureStdout();
BEGIN_HIDE_OUTPUT();
command("group new1 empty");
command("group new2 empty");
command("group new2 empty");
@ -143,16 +108,16 @@ TEST_F(GroupTest, EmptyDelete)
command("compute 1 new3 ke");
command("dump 1 new4 atom 50 dump.melt");
command("atom_modify first new5");
if (!verbose) ::testing::internal::GetCapturedStdout();
END_HIDE_OUTPUT();
ASSERT_EQ(group->ngroup, 7);
TEST_FAILURE(".*ERROR: Illegal group command.*", command("group new3 xxx"););
TEST_FAILURE(".*ERROR: Illegal group command.*", command("group new3 empty xxx"););
TEST_FAILURE(".*ERROR: Group command requires atom attribute molecule.*",
command("group new2 include molecule"););
if (!verbose) ::testing::internal::CaptureStdout();
BEGIN_HIDE_OUTPUT();
group->assign("new1 delete");
if (!verbose) ::testing::internal::GetCapturedStdout();
END_HIDE_OUTPUT();
ASSERT_EQ(group->ngroup, 6);
TEST_FAILURE(".*ERROR: Illegal group command.*", command("group new2 delete xxx"););
@ -172,13 +137,13 @@ TEST_F(GroupTest, RegionClear)
{
atomic_system();
if (!verbose) ::testing::internal::CaptureStdout();
BEGIN_HIDE_OUTPUT();
command("group one region left");
command("group two region right");
command("group three empty");
command("group four region left");
command("group four region right");
if (!verbose) ::testing::internal::GetCapturedStdout();
END_HIDE_OUTPUT();
ASSERT_EQ(group->count(group->find("one")), 16);
ASSERT_EQ(group->count(group->find("two")), 16);
ASSERT_EQ(group->count(group->find("three")), 0);
@ -189,20 +154,20 @@ TEST_F(GroupTest, RegionClear)
TEST_FAILURE(".*ERROR: Illegal group command.*", command("group three region left xxx"););
TEST_FAILURE(".*ERROR: Group region ID does not exist.*", command("group four region dummy"););
if (!verbose) ::testing::internal::CaptureStdout();
BEGIN_HIDE_OUTPUT();
command("group one clear");
command("group two clear");
command("group three clear");
command("group four clear");
if (!verbose) ::testing::internal::GetCapturedStdout();
END_HIDE_OUTPUT();
ASSERT_EQ(group->count(group->find("one")), 0);
ASSERT_EQ(group->count(group->find("two")), 0);
ASSERT_EQ(group->count(group->find("three")), 0);
ASSERT_EQ(group->count(group->find("four")), 0);
if (!verbose) ::testing::internal::CaptureStdout();
BEGIN_HIDE_OUTPUT();
command("delete_atoms region box");
if (!verbose) ::testing::internal::GetCapturedStdout();
END_HIDE_OUTPUT();
ASSERT_EQ(group->count(group->find("all")), 0);
}
@ -214,7 +179,7 @@ TEST_F(GroupTest, SelectRestart)
for (int i = 0; i < lmp->atom->natoms; ++i)
flags[i] = i & 1;
if (!verbose) ::testing::internal::CaptureStdout();
BEGIN_HIDE_OUTPUT();
command("group one region left");
command("group two region right");
group->create("half", flags);
@ -224,7 +189,7 @@ TEST_F(GroupTest, SelectRestart)
command("group five subtract all half four");
command("group top region top");
command("group six intersect half top");
if (!verbose) ::testing::internal::GetCapturedStdout();
END_HIDE_OUTPUT();
ASSERT_EQ(group->count(group->find("one")), 16);
ASSERT_EQ(group->count(group->find("two")), 16);
ASSERT_EQ(group->count(group->find("three")), 0);
@ -235,12 +200,12 @@ TEST_F(GroupTest, SelectRestart)
ASSERT_EQ(group->count(group->find("half"), domain->find_region("top")), 8);
ASSERT_DOUBLE_EQ(group->mass(group->find("half"), domain->find_region("top")), 8.0);
if (!verbose) ::testing::internal::CaptureStdout();
BEGIN_HIDE_OUTPUT();
command("write_restart group.restart");
command("clear");
command("read_restart group.restart");
unlink("group.restart");
if (!verbose) ::testing::internal::GetCapturedStdout();
END_HIDE_OUTPUT();
group = lmp->group;
ASSERT_EQ(group->count(group->find("one")), 16);
ASSERT_EQ(group->count(group->find("two")), 16);
@ -250,11 +215,11 @@ TEST_F(GroupTest, SelectRestart)
ASSERT_EQ(group->count(group->find("five")), 16);
ASSERT_DOUBLE_EQ(group->mass(group->find("six")), 8.0);
if (!verbose) ::testing::internal::CaptureStdout();
BEGIN_HIDE_OUTPUT();
command("group four clear");
command("group five clear");
command("group six clear");
if (!verbose) ::testing::internal::GetCapturedStdout();
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Group ID does not exist.*", command("group four union one two xxx"););
TEST_FAILURE(".*ERROR: Group ID does not exist.*",
@ -267,14 +232,14 @@ TEST_F(GroupTest, Molecular)
{
molecular_system();
if (!verbose) ::testing::internal::CaptureStdout();
BEGIN_HIDE_OUTPUT();
command("group one region left");
command("group two region right");
command("group half id 1:1000:2");
command("group top region top");
command("group three intersect half top");
command("group three include molecule");
if (!verbose) ::testing::internal::GetCapturedStdout();
END_HIDE_OUTPUT();
ASSERT_EQ(group->count(group->find("one")), 16);
ASSERT_EQ(group->count(group->find("two")), 16);
ASSERT_EQ(group->count(group->find("three")), 15);
@ -290,36 +255,36 @@ TEST_F(GroupTest, Dynamic)
{
atomic_system();
if (!verbose) ::testing::internal::CaptureStdout();
BEGIN_HIDE_OUTPUT();
command("variable step atom id<=step");
command("group half id 1:1000:2");
command("group grow dynamic half var step every 1");
if (!verbose) ::testing::internal::GetCapturedStdout();
END_HIDE_OUTPUT();
ASSERT_EQ(group->count(group->find("grow")), 0);
if (!verbose) ::testing::internal::CaptureStdout();
BEGIN_HIDE_OUTPUT();
command("run 10 post no");
if (!verbose) ::testing::internal::GetCapturedStdout();
END_HIDE_OUTPUT();
ASSERT_EQ(group->count(group->find("grow")), 5);
if (!verbose) ::testing::internal::CaptureStdout();
BEGIN_HIDE_OUTPUT();
command("group grow dynamic half var step every 1");
command("run 10 post no");
if (!verbose) ::testing::internal::GetCapturedStdout();
END_HIDE_OUTPUT();
ASSERT_EQ(group->count(group->find("grow")), 10);
if (!verbose) ::testing::internal::CaptureStdout();
BEGIN_HIDE_OUTPUT();
command("group grow static");
command("run 10 post no");
command("group part variable step");
if (!verbose) ::testing::internal::GetCapturedStdout();
END_HIDE_OUTPUT();
ASSERT_EQ(group->count(group->find("grow")), 10);
ASSERT_EQ(group->count(group->find("part")), 30);
if (!verbose) ::testing::internal::CaptureStdout();
BEGIN_HIDE_OUTPUT();
command("group grow dynamic half var step every 1");
command("run 10 post no");
if (!verbose) ::testing::internal::GetCapturedStdout();
END_HIDE_OUTPUT();
ASSERT_EQ(group->count(group->find("grow")), 20);
TEST_FAILURE(".*ERROR: Cannot subtract groups using a dynamic group.*",
command("group chunk subtract half grow"););
@ -328,10 +293,10 @@ TEST_F(GroupTest, Dynamic)
TEST_FAILURE(".*ERROR: Cannot intersect groups using a dynamic group.*",
command("group chunk intersect half grow"););
if (!verbose) ::testing::internal::CaptureStdout();
BEGIN_HIDE_OUTPUT();
command("group grow delete");
command("variable ramp equal step");
if (!verbose) ::testing::internal::GetCapturedStdout();
END_HIDE_OUTPUT();
ASSERT_EQ(group->ngroup, 4);
TEST_FAILURE(".*ERROR: Group dynamic cannot reference itself.*",
@ -351,7 +316,7 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv);
if (have_openmpi && !LAMMPS_NS::Info::has_exceptions())
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. "
"Death tests will be skipped\n";

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,7 @@
#include "utils.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "../testing/core.h"
#include <cstdio>
#include <cstring>
@ -32,12 +33,6 @@
// whether to print verbose output (i.e. not capturing LAMMPS screen output).
bool verbose = false;
#if defined(OMPI_MAJOR_VERSION)
const bool have_openmpi = true;
#else
const bool have_openmpi = false;
#endif
using LAMMPS_NS::utils::split_words;
namespace LAMMPS_NS {
@ -45,49 +40,22 @@ using ::testing::ExitedWithCode;
using ::testing::MatchesRegex;
using ::testing::StrEq;
#define TEST_FAILURE(errmsg, ...) \
if (Info::has_exceptions()) { \
::testing::internal::CaptureStdout(); \
ASSERT_ANY_THROW({__VA_ARGS__}); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} else { \
if (!have_openmpi) { \
::testing::internal::CaptureStdout(); \
ASSERT_DEATH({__VA_ARGS__}, ""); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} \
}
class LatticeRegionTest : public ::testing::Test {
class LatticeRegionTest : public LAMMPSTest {
protected:
LAMMPS *lmp;
void SetUp() override
{
const char *args[] = {"LatticeRegionTest", "-log", "none", "-echo", "screen", "-nocite"};
char **argv = (char **)args;
int argc = sizeof(args) / sizeof(char *);
if (!verbose) ::testing::internal::CaptureStdout();
lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD);
lmp->input->one("units metal");
if (!verbose) ::testing::internal::GetCapturedStdout();
}
void TearDown() override
{
if (!verbose) ::testing::internal::CaptureStdout();
delete lmp;
if (!verbose) ::testing::internal::GetCapturedStdout();
testbinary = "LatticeRegionTest";
LAMMPSTest::SetUp();
command("units metal");
}
};
TEST_F(LatticeRegionTest, lattice_none)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice none 2.0");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice none 2.0");
END_HIDE_OUTPUT();
auto lattice = lmp->domain->lattice;
ASSERT_EQ(lattice->style, Lattice::NONE);
ASSERT_EQ(lattice->xlattice, 2.0);
@ -96,15 +64,15 @@ TEST_F(LatticeRegionTest, lattice_none)
ASSERT_EQ(lattice->nbasis, 0);
ASSERT_EQ(lattice->basis, nullptr);
TEST_FAILURE(".*ERROR: Illegal lattice command.*", lmp->input->one("lattice"););
TEST_FAILURE(".*ERROR: Illegal lattice command.*", lmp->input->one("lattice xxx"););
TEST_FAILURE(".*ERROR: Illegal lattice command.*", lmp->input->one("lattice none 1.0 origin"););
TEST_FAILURE(".*ERROR: Expected floating point.*", lmp->input->one("lattice none xxx"););
TEST_FAILURE(".*ERROR: Illegal lattice command.*", command("lattice"););
TEST_FAILURE(".*ERROR: Illegal lattice command.*", command("lattice xxx"););
TEST_FAILURE(".*ERROR: Illegal lattice command.*", command("lattice none 1.0 origin"););
TEST_FAILURE(".*ERROR: Expected floating point.*", command("lattice none xxx"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("units lj");
lmp->input->one("lattice none 1.0");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("units lj");
command("lattice none 1.0");
END_HIDE_OUTPUT();
lattice = lmp->domain->lattice;
ASSERT_EQ(lattice->xlattice, 1.0);
ASSERT_EQ(lattice->ylattice, 1.0);
@ -113,10 +81,9 @@ TEST_F(LatticeRegionTest, lattice_none)
TEST_F(LatticeRegionTest, lattice_sc)
{
::testing::internal::CaptureStdout();
lmp->input->one("lattice sc 1.0 spacing 1.5 2.0 3.0");
auto output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
BEGIN_CAPTURE_OUTPUT();
command("lattice sc 1.0 spacing 1.5 2.0 3.0");
auto output = END_CAPTURE_OUTPUT();
ASSERT_THAT(output, MatchesRegex(".*Lattice spacing in x,y,z = 1.50* 2.0* 3.0*.*"));
auto lattice = lmp->domain->lattice;
@ -124,10 +91,9 @@ TEST_F(LatticeRegionTest, lattice_sc)
ASSERT_EQ(lattice->ylattice, 2.0);
ASSERT_EQ(lattice->zlattice, 3.0);
::testing::internal::CaptureStdout();
lmp->input->one("lattice sc 2.0");
output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
BEGIN_CAPTURE_OUTPUT();
command("lattice sc 2.0");
output = END_CAPTURE_OUTPUT();
ASSERT_THAT(output, MatchesRegex(".*Lattice spacing in x,y,z = 2.0* 2.0* 2.0*.*"));
lattice = lmp->domain->lattice;
@ -151,43 +117,42 @@ TEST_F(LatticeRegionTest, lattice_sc)
ASSERT_EQ(lattice->basis[0][2], 0.0);
TEST_FAILURE(".*ERROR: Illegal lattice command.*",
lmp->input->one("lattice sc 1.0 origin 1.0 1.0 1.0"););
command("lattice sc 1.0 origin 1.0 1.0 1.0"););
TEST_FAILURE(".*ERROR: Illegal lattice command.*", command("lattice sc 1.0 origin 1.0"););
TEST_FAILURE(".*ERROR: Illegal lattice command.*",
lmp->input->one("lattice sc 1.0 origin 1.0"););
TEST_FAILURE(".*ERROR: Illegal lattice command.*",
lmp->input->one("lattice sc 1.0 origin 0.0 0.0 0.0 xxx"););
command("lattice sc 1.0 origin 0.0 0.0 0.0 xxx"););
TEST_FAILURE(".*ERROR: Expected floating point.*",
lmp->input->one("lattice sc 1.0 origin xxx 1.0 1.0"););
command("lattice sc 1.0 origin xxx 1.0 1.0"););
TEST_FAILURE(".*ERROR: Lattice orient vectors are not orthogonal.*",
lmp->input->one("lattice sc 1.0 orient x 2 2 0"););
command("lattice sc 1.0 orient x 2 2 0"););
TEST_FAILURE(".*ERROR: Lattice orient vectors are not right-handed.*",
lmp->input->one("lattice sc 1.0 orient y 0 -1 0"););
command("lattice sc 1.0 orient y 0 -1 0"););
TEST_FAILURE(".*ERROR: Lattice spacings are invalid.*",
lmp->input->one("lattice sc 1.0 spacing 0.0 1.0 1.0"););
command("lattice sc 1.0 spacing 0.0 1.0 1.0"););
TEST_FAILURE(".*ERROR: Lattice spacings are invalid.*",
lmp->input->one("lattice sc 1.0 spacing 1.0 -0.1 1.0"););
command("lattice sc 1.0 spacing 1.0 -0.1 1.0"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("units lj");
lmp->input->one("lattice sc 2.0");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("units lj");
command("lattice sc 2.0");
END_HIDE_OUTPUT();
lattice = lmp->domain->lattice;
ASSERT_DOUBLE_EQ(lattice->xlattice, pow(0.5, 1.0 / 3.0));
ASSERT_DOUBLE_EQ(lattice->ylattice, pow(0.5, 1.0 / 3.0));
ASSERT_DOUBLE_EQ(lattice->zlattice, pow(0.5, 1.0 / 3.0));
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 2");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("dimension 2");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
lmp->input->one("lattice sc 1.0"););
command("lattice sc 1.0"););
}
TEST_F(LatticeRegionTest, lattice_bcc)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice bcc 4.2 orient x 1 1 0 orient y -1 1 0");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice bcc 4.2 orient x 1 1 0 orient y -1 1 0");
END_HIDE_OUTPUT();
auto lattice = lmp->domain->lattice;
ASSERT_EQ(lattice->style, Lattice::BCC);
ASSERT_DOUBLE_EQ(lattice->xlattice, sqrt(2.0) * 4.2);
@ -201,18 +166,18 @@ TEST_F(LatticeRegionTest, lattice_bcc)
ASSERT_EQ(lattice->basis[1][1], 0.5);
ASSERT_EQ(lattice->basis[1][2], 0.5);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 2");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("dimension 2");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
lmp->input->one("lattice bcc 1.0"););
command("lattice bcc 1.0"););
}
TEST_F(LatticeRegionTest, lattice_fcc)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice fcc 3.5 origin 0.5 0.5 0.5");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice fcc 3.5 origin 0.5 0.5 0.5");
END_HIDE_OUTPUT();
auto lattice = lmp->domain->lattice;
ASSERT_EQ(lattice->style, Lattice::FCC);
ASSERT_DOUBLE_EQ(lattice->xlattice, 3.5);
@ -233,24 +198,23 @@ TEST_F(LatticeRegionTest, lattice_fcc)
ASSERT_EQ(lattice->basis[3][2], 0.5);
TEST_FAILURE(".*ERROR: Invalid option in lattice command for non-custom style.*",
lmp->input->one("lattice fcc 1.0 basis 0.0 0.0 0.0"););
command("lattice fcc 1.0 basis 0.0 0.0 0.0"););
TEST_FAILURE(".*ERROR: Invalid option in lattice command for non-custom style.*",
lmp->input->one("lattice fcc 1.0 a1 0.0 1.0 0.0"););
TEST_FAILURE(".*ERROR: Illegal lattice command.*",
lmp->input->one("lattice fcc 1.0 orient w 1 0 0"););
command("lattice fcc 1.0 a1 0.0 1.0 0.0"););
TEST_FAILURE(".*ERROR: Illegal lattice command.*", command("lattice fcc 1.0 orient w 1 0 0"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 2");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("dimension 2");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
lmp->input->one("lattice fcc 1.0"););
command("lattice fcc 1.0"););
}
TEST_F(LatticeRegionTest, lattice_hcp)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice hcp 3.0 orient z 0 0 1");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice hcp 3.0 orient z 0 0 1");
END_HIDE_OUTPUT();
auto lattice = lmp->domain->lattice;
ASSERT_EQ(lattice->style, Lattice::HCP);
ASSERT_DOUBLE_EQ(lattice->xlattice, 3.0);
@ -280,21 +244,21 @@ TEST_F(LatticeRegionTest, lattice_hcp)
ASSERT_DOUBLE_EQ(lattice->a3[2], sqrt(8.0 / 3.0));
TEST_FAILURE(".*ERROR: Invalid option in lattice command for non-custom style.*",
lmp->input->one("lattice hcp 1.0 a2 0.0 1.0 0.0"););
command("lattice hcp 1.0 a2 0.0 1.0 0.0"););
TEST_FAILURE(".*ERROR: Invalid option in lattice command for non-custom style.*",
lmp->input->one("lattice hcp 1.0 a3 0.0 1.0 0.0"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 2");
if (!verbose) ::testing::internal::GetCapturedStdout();
command("lattice hcp 1.0 a3 0.0 1.0 0.0"););
BEGIN_HIDE_OUTPUT();
command("dimension 2");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
lmp->input->one("lattice hcp 1.0"););
command("lattice hcp 1.0"););
}
TEST_F(LatticeRegionTest, lattice_diamond)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice diamond 4.1 orient x 1 1 2 orient y -1 1 0 orient z -1 -1 1");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice diamond 4.1 orient x 1 1 2 orient y -1 1 0 orient z -1 -1 1");
END_HIDE_OUTPUT();
auto lattice = lmp->domain->lattice;
ASSERT_EQ(lattice->style, Lattice::DIAMOND);
ASSERT_DOUBLE_EQ(lattice->xlattice, 6.6952719636073539);
@ -335,19 +299,19 @@ TEST_F(LatticeRegionTest, lattice_diamond)
ASSERT_EQ(lattice->a3[1], 0.0);
ASSERT_EQ(lattice->a3[2], 1.0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 2");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("dimension 2");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
lmp->input->one("lattice diamond 1.0"););
command("lattice diamond 1.0"););
}
TEST_F(LatticeRegionTest, lattice_sq)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 2");
lmp->input->one("lattice sq 3.0");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("dimension 2");
command("lattice sq 3.0");
END_HIDE_OUTPUT();
auto lattice = lmp->domain->lattice;
ASSERT_EQ(lattice->style, Lattice::SQ);
ASSERT_DOUBLE_EQ(lattice->xlattice, 3.0);
@ -358,23 +322,22 @@ TEST_F(LatticeRegionTest, lattice_sq)
ASSERT_EQ(lattice->basis[0][1], 0.0);
ASSERT_EQ(lattice->basis[0][2], 0.0);
TEST_FAILURE(
".*ERROR: Lattice settings are not compatible with 2d simulation.*",
lmp->input->one("lattice sq 1.0 orient x 1 1 2 orient y -1 1 0 orient z -1 -1 1"););
TEST_FAILURE(".*ERROR: Lattice settings are not compatible with 2d simulation.*",
command("lattice sq 1.0 orient x 1 1 2 orient y -1 1 0 orient z -1 -1 1"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 3");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("dimension 3");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
lmp->input->one("lattice sq 1.0"););
command("lattice sq 1.0"););
}
TEST_F(LatticeRegionTest, lattice_sq2)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 2");
lmp->input->one("lattice sq2 2.0");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("dimension 2");
command("lattice sq2 2.0");
END_HIDE_OUTPUT();
auto lattice = lmp->domain->lattice;
ASSERT_EQ(lattice->style, Lattice::SQ2);
ASSERT_DOUBLE_EQ(lattice->xlattice, 2.0);
@ -388,19 +351,19 @@ TEST_F(LatticeRegionTest, lattice_sq2)
ASSERT_EQ(lattice->basis[1][1], 0.5);
ASSERT_EQ(lattice->basis[1][2], 0.0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 3");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("dimension 3");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
lmp->input->one("lattice sq2 1.0"););
command("lattice sq2 1.0"););
}
TEST_F(LatticeRegionTest, lattice_hex)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 2");
lmp->input->one("lattice hex 2.0");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("dimension 2");
command("lattice hex 2.0");
END_HIDE_OUTPUT();
auto lattice = lmp->domain->lattice;
ASSERT_EQ(lattice->style, Lattice::HEX);
ASSERT_DOUBLE_EQ(lattice->xlattice, 2.0);
@ -423,34 +386,34 @@ TEST_F(LatticeRegionTest, lattice_hex)
ASSERT_EQ(lattice->a3[1], 0.0);
ASSERT_EQ(lattice->a3[2], 1.0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 3");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("dimension 3");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
lmp->input->one("lattice hex 1.0"););
command("lattice hex 1.0"););
}
TEST_F(LatticeRegionTest, lattice_custom)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("variable a equal 4.34");
lmp->input->one("variable b equal $a*sqrt(3.0)");
lmp->input->one("variable c equal $a*sqrt(8.0/3.0)");
lmp->input->one("variable t equal 1.0/3.0");
lmp->input->one("variable f equal 5.0/6.0");
lmp->input->one("lattice custom 1.0 "
"a1 $a 0.0 0.0 "
"a2 0.0 $b 0.0 "
"a3 0.0 0.0 $c "
"basis 0.0 0.0 0.0 "
"basis 0.5 0.5 0.0 "
"basis $t 0.0 0.5 "
"basis $f 0.5 0.5 "
"basis 0.0 0.0 0.625 "
"basis 0.5 0.5 0.625 "
"basis $t 0.0 0.125 "
"basis $f 0.5 0.125 ");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("variable a equal 4.34");
command("variable b equal $a*sqrt(3.0)");
command("variable c equal $a*sqrt(8.0/3.0)");
command("variable t equal 1.0/3.0");
command("variable f equal 5.0/6.0");
command("lattice custom 1.0 "
"a1 $a 0.0 0.0 "
"a2 0.0 $b 0.0 "
"a3 0.0 0.0 $c "
"basis 0.0 0.0 0.0 "
"basis 0.5 0.5 0.0 "
"basis $t 0.0 0.5 "
"basis $f 0.5 0.5 "
"basis 0.0 0.0 0.625 "
"basis 0.5 0.5 0.625 "
"basis $t 0.0 0.125 "
"basis $f 0.5 0.125 ");
END_HIDE_OUTPUT();
auto lattice = lmp->domain->lattice;
ASSERT_EQ(lattice->style, Lattice::CUSTOM);
ASSERT_DOUBLE_EQ(lattice->xlattice, 4.34);
@ -492,48 +455,48 @@ TEST_F(LatticeRegionTest, lattice_custom)
ASSERT_DOUBLE_EQ(lattice->a3[2], 4.34 * sqrt(8.0 / 3.0));
TEST_FAILURE(".*ERROR: Illegal lattice command.*",
lmp->input->one("lattice custom 1.0 basis -0.1 0 0"););
command("lattice custom 1.0 basis -0.1 0 0"););
TEST_FAILURE(".*ERROR: Illegal lattice command.*",
lmp->input->one("lattice custom 1.0 basis 0.0 1.0 0"););
command("lattice custom 1.0 basis 0.0 1.0 0"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 2");
if (!verbose) ::testing::internal::GetCapturedStdout();
TEST_FAILURE(".*ERROR: No basis atoms in lattice.*", lmp->input->one("lattice custom 1.0"););
BEGIN_HIDE_OUTPUT();
command("dimension 2");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: No basis atoms in lattice.*", command("lattice custom 1.0"););
TEST_FAILURE(".*ERROR: Lattice settings are not compatible with 2d simulation.*",
lmp->input->one("lattice custom 1.0 origin 0.5 0.5 0.5 basis 0.0 0.0 0.0"););
command("lattice custom 1.0 origin 0.5 0.5 0.5 basis 0.0 0.0 0.0"););
TEST_FAILURE(".*ERROR: Lattice settings are not compatible with 2d simulation.*",
lmp->input->one("lattice custom 1.0 a1 1.0 1.0 1.0 basis 0.0 0.0 0.0"););
command("lattice custom 1.0 a1 1.0 1.0 1.0 basis 0.0 0.0 0.0"););
TEST_FAILURE(".*ERROR: Lattice settings are not compatible with 2d simulation.*",
lmp->input->one("lattice custom 1.0 a2 1.0 1.0 1.0 basis 0.0 0.0 0.0"););
command("lattice custom 1.0 a2 1.0 1.0 1.0 basis 0.0 0.0 0.0"););
TEST_FAILURE(".*ERROR: Lattice settings are not compatible with 2d simulation.*",
lmp->input->one("lattice custom 1.0 a3 1.0 1.0 1.0 basis 0.0 0.0 0.0"););
command("lattice custom 1.0 a3 1.0 1.0 1.0 basis 0.0 0.0 0.0"););
}
TEST_F(LatticeRegionTest, region_fail)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice none 2.0");
lmp->input->one("region box block 0 1 0 1 0 1");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice none 2.0");
command("region box block 0 1 0 1 0 1");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Create_atoms command before simulation box is defined.*",
lmp->input->one("create_atoms 1 box"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("create_box 1 box");
if (!verbose) ::testing::internal::GetCapturedStdout();
command("create_atoms 1 box"););
BEGIN_HIDE_OUTPUT();
command("create_box 1 box");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Cannot create atoms with undefined lattice.*",
lmp->input->one("create_atoms 1 box"););
command("create_atoms 1 box"););
}
TEST_F(LatticeRegionTest, region_block_lattice)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice sc 1.5");
lmp->input->one("region box block 0 2 0 2 0 2 units lattice");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 box");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice sc 1.5");
command("region box block 0 2 0 2 0 2 units lattice");
command("create_box 1 box");
command("create_atoms 1 box");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->domain->triclinic, 0);
auto x = lmp->atom->x;
@ -554,12 +517,12 @@ TEST_F(LatticeRegionTest, region_block_lattice)
TEST_F(LatticeRegionTest, region_block_box)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice sc 1.5 origin 0.75 0.75 0.75");
lmp->input->one("region box block 0 2 0 2 0 2 units box");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 box");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice sc 1.5 origin 0.75 0.75 0.75");
command("region box block 0 2 0 2 0 2 units box");
command("create_box 1 box");
command("create_atoms 1 box");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->domain->triclinic, 0);
auto x = lmp->atom->x;
@ -571,93 +534,93 @@ TEST_F(LatticeRegionTest, region_block_box)
TEST_F(LatticeRegionTest, region_cone)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice fcc 2.5 origin 0.5 0.5 0.5");
lmp->input->one("region box cone x 1.0 1.0 0.5 2.1 0.0 2.0");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 region box");
lmp->input->one("write_dump all atom init.lammpstrj");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice fcc 2.5 origin 0.5 0.5 0.5");
command("region box cone x 1.0 1.0 0.5 2.1 0.0 2.0");
command("create_box 1 box");
command("create_atoms 1 region box");
command("write_dump all atom init.lammpstrj");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->domain->triclinic, 0);
ASSERT_EQ(lmp->atom->natoms, 42);
}
TEST_F(LatticeRegionTest, region_cylinder)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice fcc 2.5 origin 0.5 0.5 0.5");
lmp->input->one("region box cylinder z 1.0 1.0 2.1 0.0 2.0 ");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 region box");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice fcc 2.5 origin 0.5 0.5 0.5");
command("region box cylinder z 1.0 1.0 2.1 0.0 2.0 ");
command("create_box 1 box");
command("create_atoms 1 region box");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->domain->triclinic, 0);
ASSERT_EQ(lmp->atom->natoms, 114);
}
TEST_F(LatticeRegionTest, region_prism)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice bcc 2.5 origin 0.75 0.75 0.75");
lmp->input->one("region box prism 0 2 0 2 0 2 0.5 0.0 0.0");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 box");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice bcc 2.5 origin 0.75 0.75 0.75");
command("region box prism 0 2 0 2 0 2 0.5 0.0 0.0");
command("create_box 1 box");
command("create_atoms 1 box");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->domain->triclinic, 1);
ASSERT_EQ(lmp->atom->natoms, 16);
}
TEST_F(LatticeRegionTest, region_sphere)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice fcc 2.5 origin 0.5 0.5 0.5");
lmp->input->one("region box sphere 1.0 1.0 1.0 1.1");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 region box");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice fcc 2.5 origin 0.5 0.5 0.5");
command("region box sphere 1.0 1.0 1.0 1.1");
command("create_box 1 box");
command("create_atoms 1 region box");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->domain->triclinic, 0);
ASSERT_EQ(lmp->atom->natoms, 14);
}
TEST_F(LatticeRegionTest, region_union)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice fcc 2.5 origin 0.5 0.5 0.5");
lmp->input->one("region part1 sphere 2.0 1.0 1.0 1.1");
lmp->input->one("region part2 block 0.0 2.0 0.0 2.0 0.0 2.0");
lmp->input->one("region box union 2 part1 part2");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 region box");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice fcc 2.5 origin 0.5 0.5 0.5");
command("region part1 sphere 2.0 1.0 1.0 1.1");
command("region part2 block 0.0 2.0 0.0 2.0 0.0 2.0");
command("region box union 2 part1 part2");
command("create_box 1 box");
command("create_atoms 1 region box");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->domain->triclinic, 0);
ASSERT_EQ(lmp->atom->natoms, 67);
}
TEST_F(LatticeRegionTest, region_intersect)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice fcc 2.5 origin 0.5 0.5 0.5");
lmp->input->one("region part1 sphere 2.0 1.0 1.0 1.8");
lmp->input->one("region part2 block 0.0 2.0 0.0 2.0 0.0 2.0");
lmp->input->one("region box intersect 2 part1 part2");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 region box");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice fcc 2.5 origin 0.5 0.5 0.5");
command("region part1 sphere 2.0 1.0 1.0 1.8");
command("region part2 block 0.0 2.0 0.0 2.0 0.0 2.0");
command("region box intersect 2 part1 part2");
command("create_box 1 box");
command("create_atoms 1 region box");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->domain->triclinic, 0);
ASSERT_EQ(lmp->atom->natoms, 21);
}
TEST_F(LatticeRegionTest, region_plane)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice fcc 2.5 origin 0.5 0.5 0.5");
lmp->input->one("region box block 0.0 2.0 0.0 2.0 0.0 2.0");
lmp->input->one("region part1 plane 0.5 1.0 0.0 0.75 0.0 0.0");
lmp->input->one("region part2 plane 1.5 1.0 0.0 0.75 0.0 0.0 side out");
lmp->input->one("region atoms intersect 2 part1 part2");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 region atoms");
lmp->input->one("write_dump all atom init.lammpstrj");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice fcc 2.5 origin 0.5 0.5 0.5");
command("region box block 0.0 2.0 0.0 2.0 0.0 2.0");
command("region part1 plane 0.5 1.0 0.0 0.75 0.0 0.0");
command("region part2 plane 1.5 1.0 0.0 0.75 0.0 0.0 side out");
command("region atoms intersect 2 part1 part2");
command("create_box 1 box");
command("create_atoms 1 region atoms");
command("write_dump all atom init.lammpstrj");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->domain->triclinic, 0);
ASSERT_EQ(lmp->atom->natoms, 16);
}
@ -669,7 +632,7 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv);
if (have_openmpi && !LAMMPS_NS::Info::has_exceptions())
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. "
"Death tests will be skipped\n";

View File

@ -21,6 +21,7 @@
#include "utils.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "../testing/core.h"
#include <cstdio>
#include <mpi.h>
@ -28,12 +29,6 @@
// whether to print verbose output (i.e. not capturing LAMMPS screen output).
bool verbose = false;
#if defined(OMPI_MAJOR_VERSION)
const bool have_openmpi = true;
#else
const bool have_openmpi = false;
#endif
using LAMMPS_NS::utils::split_words;
namespace LAMMPS_NS {
@ -41,49 +36,22 @@ using ::testing::MatchesRegex;
#define GETIDX(i) lmp->atom->map(i)
#define TEST_FAILURE(errmsg, ...) \
if (Info::has_exceptions()) { \
::testing::internal::CaptureStdout(); \
ASSERT_ANY_THROW({__VA_ARGS__}); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} else { \
if (!have_openmpi) { \
::testing::internal::CaptureStdout(); \
ASSERT_DEATH({__VA_ARGS__}, ""); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} \
}
#define STRINGIFY(val) XSTR(val)
#define XSTR(val) #val
class ResetIDsTest : public ::testing::Test {
class ResetIDsTest : public LAMMPSTest {
protected:
LAMMPS *lmp;
void SetUp() override
{
const char *args[] = {"ResetIDsTest", "-log", "none", "-nocite", "-echo", "screen"};
char **argv = (char **)args;
int argc = sizeof(args) / sizeof(char *);
if (!verbose) ::testing::internal::CaptureStdout();
lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD);
Info *info = new Info(lmp);
testbinary = "ResetIDsTest";
LAMMPSTest::SetUp();
if (info->has_style("atom", "full")) {
lmp->input->one("variable input_dir index " STRINGIFY(TEST_INPUT_FOLDER));
lmp->input->one("include ${input_dir}/in.fourmol");
BEGIN_HIDE_OUTPUT();
command("variable input_dir index " STRINGIFY(TEST_INPUT_FOLDER));
command("include ${input_dir}/in.fourmol");
END_HIDE_OUTPUT();
}
delete info;
if (!verbose) ::testing::internal::GetCapturedStdout();
}
void TearDown() override
{
if (!verbose) ::testing::internal::CaptureStdout();
delete lmp;
if (!verbose) ::testing::internal::GetCapturedStdout();
}
};
@ -124,9 +92,9 @@ TEST_F(ResetIDsTest, MolIDAll)
// the original data file has two different molecule IDs
// for two residues of the same molecule/fragment.
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("reset_mol_ids all");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("reset_mol_ids all");
END_HIDE_OUTPUT();
ASSERT_EQ(molid[GETIDX(1)], 1);
ASSERT_EQ(molid[GETIDX(2)], 1);
@ -166,12 +134,12 @@ TEST_F(ResetIDsTest, DeletePlusAtomID)
auto molid = lmp->atom->molecule;
// delete two water molecules
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("group allwater molecule 3:6");
lmp->input->one("group twowater molecule 4:6:2");
lmp->input->one("delete_atoms group twowater compress no bond yes");
lmp->input->one("reset_mol_ids all");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("group allwater molecule 3:6");
command("group twowater molecule 4:6:2");
command("delete_atoms group twowater compress no bond yes");
command("reset_mol_ids all");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->atom->natoms, 23);
ASSERT_EQ(lmp->atom->map_tag_max, 26);
@ -228,9 +196,9 @@ TEST_F(ResetIDsTest, DeletePlusAtomID)
ASSERT_GE(GETIDX(25), 0);
ASSERT_GE(GETIDX(26), 0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("reset_atom_ids");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("reset_atom_ids");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->atom->map_tag_max, 23);
for (int i = 1; i <= 23; ++i)
@ -244,11 +212,11 @@ TEST_F(ResetIDsTest, PartialOffset)
auto molid = lmp->atom->molecule;
// delete two water molecules
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("group allwater molecule 3:6");
lmp->input->one("group nowater subtract all allwater");
lmp->input->one("reset_mol_ids allwater offset 4");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("group allwater molecule 3:6");
command("group nowater subtract all allwater");
command("reset_mol_ids allwater offset 4");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->atom->natoms, 29);
ASSERT_EQ(lmp->atom->map_tag_max, 29);
@ -282,9 +250,9 @@ TEST_F(ResetIDsTest, PartialOffset)
ASSERT_EQ(molid[GETIDX(28)], 8);
ASSERT_EQ(molid[GETIDX(29)], 8);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("reset_mol_ids nowater offset 0");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("reset_mol_ids nowater offset 0");
END_HIDE_OUTPUT();
ASSERT_EQ(molid[GETIDX(1)], 1);
ASSERT_EQ(molid[GETIDX(2)], 1);
@ -324,13 +292,13 @@ TEST_F(ResetIDsTest, DeleteAdd)
auto molid = lmp->atom->molecule;
// delete two water molecules
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("group allwater molecule 3:6");
lmp->input->one("group twowater molecule 4:6:2");
lmp->input->one("group nowater subtract all allwater");
lmp->input->one("delete_atoms group twowater compress no bond yes mol yes");
lmp->input->one("reset_mol_ids allwater");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("group allwater molecule 3:6");
command("group twowater molecule 4:6:2");
command("group nowater subtract all allwater");
command("delete_atoms group twowater compress no bond yes mol yes");
command("reset_mol_ids allwater");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->atom->natoms, 23);
ASSERT_EQ(lmp->atom->map_tag_max, 26);
@ -387,17 +355,17 @@ TEST_F(ResetIDsTest, DeleteAdd)
ASSERT_GE(GETIDX(25), 0);
ASSERT_GE(GETIDX(26), 0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("reset_atom_ids sort yes");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("reset_atom_ids sort yes");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->atom->map_tag_max, 23);
for (int i = 1; i <= 23; ++i)
ASSERT_GE(GETIDX(i), 0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("reset_mol_ids nowater offset 1");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("reset_mol_ids nowater offset 1");
END_HIDE_OUTPUT();
ASSERT_EQ(molid[GETIDX(1)], 2);
ASSERT_EQ(molid[GETIDX(2)], 2);
@ -423,13 +391,13 @@ TEST_F(ResetIDsTest, DeleteAdd)
ASSERT_EQ(molid[GETIDX(22)], 4);
ASSERT_EQ(molid[GETIDX(23)], 4);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("create_atoms 1 single 0.0 0.0 0.0");
lmp->input->one("create_atoms 2 single 1.0 0.0 0.0");
lmp->input->one("create_atoms 3 single 2.0 0.0 0.0");
lmp->input->one("create_atoms 4 single 3.0 0.0 0.0");
lmp->input->one("reset_mol_ids all single yes");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("create_atoms 1 single 0.0 0.0 0.0");
command("create_atoms 2 single 1.0 0.0 0.0");
command("create_atoms 3 single 2.0 0.0 0.0");
command("create_atoms 4 single 3.0 0.0 0.0");
command("reset_mol_ids all single yes");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->atom->natoms, 27);
ASSERT_EQ(lmp->atom->map_tag_max, 27);
@ -441,9 +409,9 @@ TEST_F(ResetIDsTest, DeleteAdd)
ASSERT_EQ(molid[GETIDX(26)], 6);
ASSERT_EQ(molid[GETIDX(27)], 7);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("reset_mol_ids all single no");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("reset_mol_ids all single no");
END_HIDE_OUTPUT();
ASSERT_EQ(molid[GETIDX(21)], 3);
ASSERT_EQ(molid[GETIDX(22)], 3);
@ -453,9 +421,9 @@ TEST_F(ResetIDsTest, DeleteAdd)
ASSERT_EQ(molid[GETIDX(26)], 0);
ASSERT_EQ(molid[GETIDX(27)], 0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("reset_mol_ids all compress no single yes");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("reset_mol_ids all compress no single yes");
END_HIDE_OUTPUT();
ASSERT_EQ(molid[GETIDX(21)], 21);
ASSERT_EQ(molid[GETIDX(22)], 21);
@ -471,21 +439,21 @@ TEST_F(ResetIDsTest, TopologyData)
if (lmp->atom->natoms == 0) GTEST_SKIP();
// delete two water molecules
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("group allwater molecule 3:6");
lmp->input->one("group twowater molecule 4:6:2");
lmp->input->one("group nowater subtract all allwater");
lmp->input->one("delete_atoms group twowater compress no bond yes mol yes");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("group allwater molecule 3:6");
command("group twowater molecule 4:6:2");
command("group nowater subtract all allwater");
command("delete_atoms group twowater compress no bond yes mol yes");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->atom->natoms, 23);
ASSERT_EQ(lmp->atom->map_tag_max, 26);
auto num_bond = lmp->atom->num_bond;
auto num_angle = lmp->atom->num_angle;
auto bond_atom = lmp->atom->bond_atom;
auto angle_atom1 = lmp->atom->angle_atom1;
auto angle_atom2 = lmp->atom->angle_atom2;
auto angle_atom3 = lmp->atom->angle_atom3;
auto num_bond = lmp->atom->num_bond;
auto num_angle = lmp->atom->num_angle;
auto bond_atom = lmp->atom->bond_atom;
auto angle_atom1 = lmp->atom->angle_atom1;
auto angle_atom2 = lmp->atom->angle_atom2;
auto angle_atom3 = lmp->atom->angle_atom3;
ASSERT_EQ(num_bond[GETIDX(1)], 2);
ASSERT_EQ(bond_atom[GETIDX(1)][0], 2);
ASSERT_EQ(bond_atom[GETIDX(1)][1], 3);
@ -560,16 +528,16 @@ TEST_F(ResetIDsTest, TopologyData)
ASSERT_EQ(angle_atom2[GETIDX(24)][0], 24);
ASSERT_EQ(angle_atom3[GETIDX(24)][0], 26);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("reset_atom_ids sort yes");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("reset_atom_ids sort yes");
END_HIDE_OUTPUT();
num_bond = lmp->atom->num_bond;
num_angle = lmp->atom->num_angle;
bond_atom = lmp->atom->bond_atom;
angle_atom1 = lmp->atom->angle_atom1;
angle_atom2 = lmp->atom->angle_atom2;
angle_atom3 = lmp->atom->angle_atom3;
num_bond = lmp->atom->num_bond;
num_angle = lmp->atom->num_angle;
bond_atom = lmp->atom->bond_atom;
angle_atom1 = lmp->atom->angle_atom1;
angle_atom2 = lmp->atom->angle_atom2;
angle_atom3 = lmp->atom->angle_atom3;
ASSERT_EQ(num_bond[GETIDX(1)], 2);
ASSERT_EQ(bond_atom[GETIDX(1)][0], 3);
ASSERT_EQ(bond_atom[GETIDX(1)][1], 2);
@ -658,61 +626,60 @@ TEST_F(ResetIDsTest, DeathTests)
{
if (lmp->atom->natoms == 0) GTEST_SKIP();
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*", lmp->input->one("reset_mol_ids"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*", command("reset_mol_ids"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*",
lmp->input->one("reset_mol_ids all offset 1 1"););
command("reset_mol_ids all offset 1 1"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*",
lmp->input->one("reset_mol_ids all offset -2"););
command("reset_mol_ids all offset -2"););
TEST_FAILURE(".*ERROR on proc 0: Expected integer.*", command("reset_mol_ids all offset xxx"););
TEST_FAILURE(".*ERROR on proc 0: Expected integer.*",
lmp->input->one("reset_mol_ids all offset xxx"););
TEST_FAILURE(".*ERROR on proc 0: Expected integer.*",
lmp->input->one("reset_mol_ids all compress yes single no offset xxx"););
command("reset_mol_ids all compress yes single no offset xxx"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*", command("reset_mol_ids all offset"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*",
lmp->input->one("reset_mol_ids all offset"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*",
lmp->input->one("reset_mol_ids all compress"););
command("reset_mol_ids all compress"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*",
lmp->input->one("reset_mol_ids all compress xxx"););
command("reset_mol_ids all compress xxx"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*", command("reset_mol_ids all single"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*",
lmp->input->one("reset_mol_ids all single"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*",
lmp->input->one("reset_mol_ids all single xxx"););
command("reset_mol_ids all single xxx"););
}
TEST(ResetMolIds, CMDFail)
{
LAMMPS *lmp;
const char *args[] = {"ResetIDsTest", "-log", "none", "-nocite", "-echo", "screen"};
char **argv = (char **)args;
int argc = sizeof(args) / sizeof(char *);
if (!verbose) ::testing::internal::CaptureStdout();
lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD);
if (!verbose) ::testing::internal::GetCapturedStdout();
TEST_FAILURE(".*ERROR: Reset_mol_ids command before simulation box is.*",
lmp->input->one("reset_mol_ids all"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("atom_modify id no");
lmp->input->one("region box block 0 1 0 1 0 1");
lmp->input->one("create_box 1 box");
if (!verbose) ::testing::internal::GetCapturedStdout();
TEST_FAILURE(".*ERROR: Cannot use reset_mol_ids unless.*",
lmp->input->one("reset_mol_ids all"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
lmp->input->one("region box block 0 1 0 1 0 1");
lmp->input->one("create_box 1 box");
if (!verbose) ::testing::internal::GetCapturedStdout();
TEST_FAILURE(".*ERROR: Can only use reset_mol_ids.*", lmp->input->one("reset_mol_ids all"););
if (!verbose) ::testing::internal::CaptureStdout();
delete lmp;
if (!verbose) ::testing::internal::GetCapturedStdout();
class ResetMolIDsTest : public LAMMPSTest {
protected:
void SetUp() override
{
testbinary = "ResetIDsTest";
LAMMPSTest::SetUp();
}
};
TEST_F(ResetMolIDsTest, FailBeforeBox)
{
TEST_FAILURE(".*ERROR: Reset_mol_ids command before simulation box is.*",
command("reset_mol_ids all"););
}
TEST_F(ResetMolIDsTest, FailMissingId)
{
BEGIN_HIDE_OUTPUT();
command("atom_modify id no");
command("region box block 0 1 0 1 0 1");
command("create_box 1 box");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Cannot use reset_mol_ids unless.*", command("reset_mol_ids all"););
}
TEST_F(ResetMolIDsTest, FailOnlyMolecular)
{
BEGIN_HIDE_OUTPUT();
command("clear");
command("region box block 0 1 0 1 0 1");
command("create_box 1 box");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Can only use reset_mol_ids.*", command("reset_mol_ids all"););
}
} // namespace LAMMPS_NS
int main(int argc, char **argv)
@ -720,7 +687,7 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv);
if (have_openmpi && !LAMMPS_NS::Info::has_exceptions())
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. "
"Death tests will be skipped\n";

View File

@ -24,6 +24,7 @@
#include "fmt/format.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "../testing/core.h"
#include <cstdio>
#include <cstring>
@ -34,11 +35,6 @@
// whether to print verbose output (i.e. not capturing LAMMPS screen output).
bool verbose = false;
#if defined(OMPI_MAJOR_VERSION)
const bool have_openmpi = true;
#else
const bool have_openmpi = false;
#endif
using LAMMPS_NS::utils::split_words;
@ -47,46 +43,12 @@ using ::testing::ExitedWithCode;
using ::testing::MatchesRegex;
using ::testing::StrEq;
#define TEST_FAILURE(errmsg, ...) \
if (Info::has_exceptions()) { \
::testing::internal::CaptureStdout(); \
ASSERT_ANY_THROW({__VA_ARGS__}); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} else { \
if (!have_openmpi) { \
::testing::internal::CaptureStdout(); \
ASSERT_DEATH({__VA_ARGS__}, ""); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} \
}
class SimpleCommandsTest : public ::testing::Test {
protected:
LAMMPS *lmp;
void SetUp() override
{
const char *args[] = {"SimpleCommandsTest", "-log", "none", "-echo", "screen", "-nocite"};
char **argv = (char **)args;
int argc = sizeof(args) / sizeof(char *);
if (!verbose) ::testing::internal::CaptureStdout();
lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD);
if (!verbose) ::testing::internal::GetCapturedStdout();
}
void TearDown() override
{
if (!verbose) ::testing::internal::CaptureStdout();
delete lmp;
if (!verbose) ::testing::internal::GetCapturedStdout();
}
class SimpleCommandsTest : public LAMMPSTest {
};
TEST_F(SimpleCommandsTest, UnknownCommand)
{
TEST_FAILURE(".*ERROR: Unknown command.*", lmp->input->one("XXX one two"););
TEST_FAILURE(".*ERROR: Unknown command.*", command("XXX one two"););
}
TEST_F(SimpleCommandsTest, Echo)
@ -94,47 +56,47 @@ TEST_F(SimpleCommandsTest, Echo)
ASSERT_EQ(lmp->input->echo_screen, 1);
ASSERT_EQ(lmp->input->echo_log, 0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("echo none");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("echo none");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->input->echo_screen, 0);
ASSERT_EQ(lmp->input->echo_log, 0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("echo both");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("echo both");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->input->echo_screen, 1);
ASSERT_EQ(lmp->input->echo_log, 1);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("echo screen");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("echo screen");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->input->echo_screen, 1);
ASSERT_EQ(lmp->input->echo_log, 0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("echo log");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("echo log");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->input->echo_screen, 0);
ASSERT_EQ(lmp->input->echo_log, 1);
TEST_FAILURE(".*ERROR: Illegal echo command.*", lmp->input->one("echo"););
TEST_FAILURE(".*ERROR: Illegal echo command.*", lmp->input->one("echo xxx"););
TEST_FAILURE(".*ERROR: Illegal echo command.*", command("echo"););
TEST_FAILURE(".*ERROR: Illegal echo command.*", command("echo xxx"););
}
TEST_F(SimpleCommandsTest, Log)
{
ASSERT_EQ(lmp->logfile, nullptr);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("log simple_command_test.log");
lmp->input->one("print 'test1'");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("log simple_command_test.log");
command("print 'test1'");
END_HIDE_OUTPUT();
ASSERT_NE(lmp->logfile, nullptr);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("log none");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("log none");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->logfile, nullptr);
std::string text;
@ -144,14 +106,14 @@ TEST_F(SimpleCommandsTest, Log)
in.close();
ASSERT_THAT(text, StrEq("test1"));
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("log simple_command_test.log append");
lmp->input->one("print 'test2'");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("log simple_command_test.log append");
command("print 'test2'");
END_HIDE_OUTPUT();
ASSERT_NE(lmp->logfile, nullptr);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("log none");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("log none");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->logfile, nullptr);
in.open("simple_command_test.log");
@ -162,7 +124,7 @@ TEST_F(SimpleCommandsTest, Log)
in.close();
remove("simple_command_test.log");
TEST_FAILURE(".*ERROR: Illegal log command.*", lmp->input->one("log"););
TEST_FAILURE(".*ERROR: Illegal log command.*", command("log"););
}
TEST_F(SimpleCommandsTest, Newton)
@ -170,82 +132,79 @@ TEST_F(SimpleCommandsTest, Newton)
// default setting is "on" for both
ASSERT_EQ(lmp->force->newton_pair, 1);
ASSERT_EQ(lmp->force->newton_bond, 1);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("newton off");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("newton off");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->force->newton_pair, 0);
ASSERT_EQ(lmp->force->newton_bond, 0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("newton on off");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("newton on off");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->force->newton_pair, 1);
ASSERT_EQ(lmp->force->newton_bond, 0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("newton off on");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("newton off on");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->force->newton_pair, 0);
ASSERT_EQ(lmp->force->newton_bond, 1);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("newton on");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("newton on");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->force->newton_pair, 1);
ASSERT_EQ(lmp->force->newton_bond, 1);
}
TEST_F(SimpleCommandsTest, Partition)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("echo none");
if (!verbose) ::testing::internal::GetCapturedStdout();
TEST_FAILURE(".*ERROR: Illegal partition command .*",
lmp->input->one("partition xxx 1 echo none"););
BEGIN_HIDE_OUTPUT();
command("echo none");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Illegal partition command .*", command("partition xxx 1 echo none"););
TEST_FAILURE(".*ERROR: Numeric index 2 is out of bounds.*",
lmp->input->one("partition yes 2 echo none"););
command("partition yes 2 echo none"););
::testing::internal::CaptureStdout();
lmp->input->one("partition yes 1 print 'test'");
auto text = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << text;
BEGIN_CAPTURE_OUTPUT();
command("partition yes 1 print 'test'");
auto text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, StrEq("test\n"));
::testing::internal::CaptureStdout();
lmp->input->one("partition no 1 print 'test'");
text = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << text;
BEGIN_CAPTURE_OUTPUT();
command("partition no 1 print 'test'");
text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, StrEq(""));
}
TEST_F(SimpleCommandsTest, Quit)
{
::testing::internal::CaptureStdout();
lmp->input->one("echo none");
::testing::internal::GetCapturedStdout();
TEST_FAILURE(".*ERROR: Expected integer .*", lmp->input->one("quit xxx"););
BEGIN_HIDE_OUTPUT();
command("echo none");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Expected integer .*", command("quit xxx"););
// the following tests must be skipped with OpenMPI due to using threads
if (have_openmpi) GTEST_SKIP();
ASSERT_EXIT(lmp->input->one("quit"), ExitedWithCode(0), "");
ASSERT_EXIT(lmp->input->one("quit 9"), ExitedWithCode(9), "");
if (Info::get_mpi_vendor() == "Open MPI") GTEST_SKIP();
ASSERT_EXIT(command("quit"), ExitedWithCode(0), "");
ASSERT_EXIT(command("quit 9"), ExitedWithCode(9), "");
}
TEST_F(SimpleCommandsTest, ResetTimestep)
{
ASSERT_EQ(lmp->update->ntimestep, 0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("reset_timestep 10");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("reset_timestep 10");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->update->ntimestep, 10);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("reset_timestep 0");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("reset_timestep 0");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->update->ntimestep, 0);
TEST_FAILURE(".*ERROR: Timestep must be >= 0.*", lmp->input->one("reset_timestep -10"););
TEST_FAILURE(".*ERROR: Illegal reset_timestep .*", lmp->input->one("reset_timestep"););
TEST_FAILURE(".*ERROR: Illegal reset_timestep .*", lmp->input->one("reset_timestep 10 10"););
TEST_FAILURE(".*ERROR: Expected integer .*", lmp->input->one("reset_timestep xxx"););
TEST_FAILURE(".*ERROR: Timestep must be >= 0.*", command("reset_timestep -10"););
TEST_FAILURE(".*ERROR: Illegal reset_timestep .*", command("reset_timestep"););
TEST_FAILURE(".*ERROR: Illegal reset_timestep .*", command("reset_timestep 10 10"););
TEST_FAILURE(".*ERROR: Expected integer .*", command("reset_timestep xxx"););
}
TEST_F(SimpleCommandsTest, Suffix)
@ -254,93 +213,92 @@ TEST_F(SimpleCommandsTest, Suffix)
ASSERT_EQ(lmp->suffix, nullptr);
ASSERT_EQ(lmp->suffix2, nullptr);
TEST_FAILURE(".*ERROR: May only enable suffixes after defining one.*",
lmp->input->one("suffix on"););
TEST_FAILURE(".*ERROR: May only enable suffixes after defining one.*", command("suffix on"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("suffix one");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("suffix one");
END_HIDE_OUTPUT();
ASSERT_THAT(lmp->suffix, StrEq("one"));
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("suffix hybrid two three");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("suffix hybrid two three");
END_HIDE_OUTPUT();
ASSERT_THAT(lmp->suffix, StrEq("two"));
ASSERT_THAT(lmp->suffix2, StrEq("three"));
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("suffix four");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("suffix four");
END_HIDE_OUTPUT();
ASSERT_THAT(lmp->suffix, StrEq("four"));
ASSERT_EQ(lmp->suffix2, nullptr);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("suffix off");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("suffix off");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->suffix_enable, 0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("suffix on");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("suffix on");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->suffix_enable, 1);
TEST_FAILURE(".*ERROR: Illegal suffix command.*", lmp->input->one("suffix"););
TEST_FAILURE(".*ERROR: Illegal suffix command.*", lmp->input->one("suffix hybrid"););
TEST_FAILURE(".*ERROR: Illegal suffix command.*", lmp->input->one("suffix hybrid one"););
TEST_FAILURE(".*ERROR: Illegal suffix command.*", command("suffix"););
TEST_FAILURE(".*ERROR: Illegal suffix command.*", command("suffix hybrid"););
TEST_FAILURE(".*ERROR: Illegal suffix command.*", command("suffix hybrid one"););
}
TEST_F(SimpleCommandsTest, Thermo)
{
ASSERT_EQ(lmp->output->thermo_every, 0);
ASSERT_EQ(lmp->output->var_thermo, nullptr);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("thermo 2");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("thermo 2");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->output->thermo_every, 2);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("variable step equal logfreq(10,3,10)");
lmp->input->one("thermo v_step");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("variable step equal logfreq(10,3,10)");
command("thermo v_step");
END_HIDE_OUTPUT();
ASSERT_THAT(lmp->output->var_thermo, StrEq("step"));
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("thermo 10");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("thermo 10");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->output->thermo_every, 10);
ASSERT_EQ(lmp->output->var_thermo, nullptr);
TEST_FAILURE(".*ERROR: Illegal thermo command.*", lmp->input->one("thermo"););
TEST_FAILURE(".*ERROR: Illegal thermo command.*", lmp->input->one("thermo -1"););
TEST_FAILURE(".*ERROR: Expected integer.*", lmp->input->one("thermo xxx"););
TEST_FAILURE(".*ERROR: Illegal thermo command.*", command("thermo"););
TEST_FAILURE(".*ERROR: Illegal thermo command.*", command("thermo -1"););
TEST_FAILURE(".*ERROR: Expected integer.*", command("thermo xxx"););
}
TEST_F(SimpleCommandsTest, TimeStep)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("timestep 1");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("timestep 1");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->update->dt, 1.0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("timestep 0.1");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("timestep 0.1");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->update->dt, 0.1);
// zero timestep is legal and works (atoms don't move)
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("timestep 0.0");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("timestep 0.0");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->update->dt, 0.0);
// negative timestep also creates a viable MD.
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("timestep -0.1");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("timestep -0.1");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->update->dt, -0.1);
TEST_FAILURE(".*ERROR: Illegal timestep command.*", lmp->input->one("timestep"););
TEST_FAILURE(".*ERROR: Expected floating point.*", lmp->input->one("timestep xxx"););
TEST_FAILURE(".*ERROR: Illegal timestep command.*", command("timestep"););
TEST_FAILURE(".*ERROR: Expected floating point.*", command("timestep xxx"););
}
TEST_F(SimpleCommandsTest, Units)
@ -352,19 +310,19 @@ TEST_F(SimpleCommandsTest, Units)
ASSERT_THAT(lmp->update->unit_style, StrEq("lj"));
for (std::size_t i = 0; i < num; ++i) {
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one(fmt::format("units {}", names[i]));
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command(fmt::format("units {}", names[i]));
END_HIDE_OUTPUT();
ASSERT_THAT(lmp->update->unit_style, StrEq(names[i]));
ASSERT_EQ(lmp->update->dt, dt[i]);
}
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("clear");
END_HIDE_OUTPUT();
ASSERT_THAT(lmp->update->unit_style, StrEq("lj"));
TEST_FAILURE(".*ERROR: Illegal units command.*", lmp->input->one("units unknown"););
TEST_FAILURE(".*ERROR: Illegal units command.*", command("units unknown"););
}
#if defined(LMP_PLUGIN)
@ -442,18 +400,18 @@ TEST_F(SimpleCommandsTest, Plugin)
TEST_F(SimpleCommandsTest, Shell)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("shell putenv TEST_VARIABLE=simpletest");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("shell putenv TEST_VARIABLE=simpletest");
END_HIDE_OUTPUT();
char *test_var = getenv("TEST_VARIABLE");
ASSERT_NE(test_var, nullptr);
ASSERT_THAT(test_var, StrEq("simpletest"));
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("shell putenv TEST_VARIABLE=simpletest");
lmp->input->one("shell putenv TEST_VARIABLE2=simpletest2 OTHER_VARIABLE=2");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("shell putenv TEST_VARIABLE=simpletest");
command("shell putenv TEST_VARIABLE2=simpletest2 OTHER_VARIABLE=2");
END_HIDE_OUTPUT();
char *test_var2 = getenv("TEST_VARIABLE2");
char *other_var = getenv("OTHER_VARIABLE");
@ -471,32 +429,30 @@ TEST_F(SimpleCommandsTest, CiteMe)
lmp->citeme = new LAMMPS_NS::CiteMe(lmp, CiteMe::TERSE, CiteMe::TERSE, nullptr);
::testing::internal::CaptureStdout();
BEGIN_CAPTURE_OUTPUT();
lmp->citeme->add("test citation one:\n 1\n");
lmp->citeme->add("test citation two:\n 2\n");
lmp->citeme->add("test citation one:\n 1\n");
lmp->citeme->flush();
std::string text = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << text;
std::string text = END_CAPTURE_OUTPUT();
// find the two unique citations, but not the third
ASSERT_THAT(text, MatchesRegex(".*one.*two.*"));
ASSERT_THAT(text, Not(MatchesRegex(".*one.*two.*one.*")));
::testing::internal::CaptureStdout();
BEGIN_CAPTURE_OUTPUT();
lmp->citeme->add("test citation one:\n 0\n");
lmp->citeme->add("test citation two:\n 2\n");
lmp->citeme->add("test citation three:\n 3\n");
lmp->citeme->flush();
text = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << text;
text = END_CAPTURE_OUTPUT();
// find the forth (only differs in long citation) and sixth added citation
ASSERT_THAT(text, MatchesRegex(".*one.*three.*"));
ASSERT_THAT(text, Not(MatchesRegex(".*two.*")));
::testing::internal::CaptureStdout();
BEGIN_CAPTURE_OUTPUT();
lmp->citeme->add("test citation one:\n 1\n");
lmp->citeme->add("test citation two:\n 2\n");
lmp->citeme->add("test citation one:\n 0\n");
@ -504,8 +460,7 @@ TEST_F(SimpleCommandsTest, CiteMe)
lmp->citeme->add("test citation three:\n 3\n");
lmp->citeme->flush();
text = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << text;
text = END_CAPTURE_OUTPUT();
// no new citation. no CITE-CITE-CITE- lines
ASSERT_THAT(text, Not(MatchesRegex(".*CITE-CITE-CITE-CITE.*")));
@ -517,7 +472,7 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv);
if (have_openmpi && !LAMMPS_NS::Info::has_exceptions())
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. "
"Death tests will be skipped\n";

View File

@ -0,0 +1,528 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://lammps.sandia.gov/, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "lammps.h"
#include "atom.h"
#include "domain.h"
#include "group.h"
#include "info.h"
#include "input.h"
#include "math_const.h"
#include "region.h"
#include "variable.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "../testing/core.h"
#include <cstring>
#include <vector>
// whether to print verbose output (i.e. not capturing LAMMPS screen output).
bool verbose = false;
using LAMMPS_NS::MathConst::MY_PI;
using LAMMPS_NS::utils::split_words;
namespace LAMMPS_NS {
using ::testing::ExitedWithCode;
using ::testing::MatchesRegex;
using ::testing::StrEq;
class VariableTest : public LAMMPSTest {
protected:
Group *group;
Domain *domain;
Variable *variable;
void SetUp() override
{
testbinary = "VariableTest";
args = {"-log", "none", "-echo", "screen", "-nocite", "-v", "num", "1"};
LAMMPSTest::SetUp();
group = lmp->group;
domain = lmp->domain;
variable = lmp->input->variable;
}
void TearDown() override
{
LAMMPSTest::TearDown();
unlink("test_variable.file");
unlink("test_variable.atomfile");
}
void atomic_system()
{
BEGIN_HIDE_OUTPUT();
command("units real");
command("lattice sc 1.0 origin 0.125 0.125 0.125");
command("region box block -2 2 -2 2 -2 2");
command("create_box 8 box");
command("create_atoms 1 box");
command("mass * 1.0");
command("region left block -2.0 -1.0 INF INF INF INF");
command("region right block 0.5 2.0 INF INF INF INF");
command("region top block INF INF -2.0 -1.0 INF INF");
command("set region left type 2");
command("set region right type 3");
END_HIDE_OUTPUT();
}
void molecular_system()
{
BEGIN_HIDE_OUTPUT();
command("fix props all property/atom mol rmass q");
END_HIDE_OUTPUT();
atomic_system();
BEGIN_HIDE_OUTPUT();
command("variable molid atom floor(id/4)+1");
command("variable charge atom 2.0*sin(PI/32*id)");
command("set atom * mol v_molid");
command("set atom * charge v_charge");
command("set type 1 mass 0.5");
command("set type 2*4 mass 2.0");
END_HIDE_OUTPUT();
}
void file_vars()
{
FILE *fp = fopen("test_variable.file", "w");
fputs("# test file for file style variable\n\n\none\n two \n\n"
"three # with comment\nfour ! with non-comment\n"
"# comments only\n five\n#END\n",
fp);
fclose(fp);
fp = fopen("test_variable.atomfile", "w");
fputs("# test file for atomfile style variable\n\n"
"4 # four lines\n4 0.5 #with comment\n"
"2 -0.5 \n3 1.5\n1 -1.5\n\n"
"2\n10 1.0 # test\n13 1.0\n\n######\n"
"4\n1 4.0 # test\n2 3.0\n3 2.0\n4 1.0\n#END\n",
fp);
fclose(fp);
}
};
TEST_F(VariableTest, CreateDelete)
{
file_vars();
ASSERT_EQ(variable->nvar, 1);
BEGIN_HIDE_OUTPUT();
command("variable one index 1 2 3 4");
command("variable two equal 1");
command("variable two equal 2");
command("variable three string four");
command("variable three string three");
command("variable four1 loop 4");
command("variable four2 loop 2 4");
command("variable five1 loop 100 pad");
command("variable five2 loop 10 200 pad");
command("variable six world one");
command("variable seven format two \"%5.2f\"");
command("variable eight getenv PWD");
command("variable eight getenv XXXXX");
command("variable nine file test_variable.file");
command("variable ten internal 1.0");
command("variable ten internal 10.0");
command("variable ten1 universe 1 2 3 4");
command("variable ten2 uloop 4");
command("variable ten3 uloop 4 pad");
command("variable dummy index 0");
command("variable file equal is_file(MYFILE)");
END_HIDE_OUTPUT();
ASSERT_EQ(variable->nvar, 18);
BEGIN_HIDE_OUTPUT();
command("variable dummy delete");
END_HIDE_OUTPUT();
ASSERT_EQ(variable->nvar, 17);
ASSERT_THAT(variable->retrieve("three"), StrEq("three"));
variable->set_string("three", "four");
ASSERT_THAT(variable->retrieve("three"), StrEq("four"));
ASSERT_THAT(variable->retrieve("four2"), StrEq("2"));
ASSERT_THAT(variable->retrieve("five1"), StrEq("001"));
ASSERT_THAT(variable->retrieve("seven"), StrEq(" 2.00"));
ASSERT_THAT(variable->retrieve("ten"), StrEq("1"));
ASSERT_THAT(variable->retrieve("eight"), StrEq(""));
variable->internal_set(variable->find("ten"), 2.5);
ASSERT_THAT(variable->retrieve("ten"), StrEq("2.5"));
ASSERT_THAT(variable->retrieve("file"), StrEq("0"));
FILE *fp = fopen("MYFILE","w");
fputs(" ",fp);
fclose(fp);
ASSERT_THAT(variable->retrieve("file"), StrEq("1"));
unlink("MYFILE");
ASSERT_THAT(variable->retrieve("file"), StrEq("0"));
ASSERT_EQ(variable->equalstyle(variable->find("one")), 0);
ASSERT_EQ(variable->equalstyle(variable->find("two")), 1);
ASSERT_EQ(variable->equalstyle(variable->find("ten")), 1);
ASSERT_EQ(variable->internalstyle(variable->find("two")), 0);
ASSERT_EQ(variable->internalstyle(variable->find("ten")), 1);
TEST_FAILURE(".*ERROR: Illegal variable command.*", command("variable"););
TEST_FAILURE(".*ERROR: Illegal variable command.*", command("variable dummy index"););
TEST_FAILURE(".*ERROR: Illegal variable command.*", command("variable dummy delete xxx"););
TEST_FAILURE(".*ERROR: Illegal variable command.*", command("variable dummy loop -1"););
TEST_FAILURE(".*ERROR: Illegal variable command.*", command("variable dummy loop 10 1"););
TEST_FAILURE(".*ERROR: Illegal variable command.*", command("variable dummy xxxx"););
TEST_FAILURE(".*ERROR: Cannot redefine variable as a different style.*",
command("variable two string xxx"););
TEST_FAILURE(".*ERROR: Cannot redefine variable as a different style.*",
command("variable two getenv xxx"););
TEST_FAILURE(".*ERROR: Cannot redefine variable as a different style.*",
command("variable one equal 2"););
TEST_FAILURE(".*ERROR: Cannot redefine variable as a different style.*",
command("variable one internal 2"););
TEST_FAILURE(".*ERROR: Cannot use atomfile-style variable unless an atom map exists.*",
command("variable eleven atomfile test_variable.atomfile"););
TEST_FAILURE(".*ERROR on proc 0: Cannot open file variable file test_variable.xxx.*",
command("variable nine1 file test_variable.xxx"););
TEST_FAILURE(".*ERROR: World variable count doesn't match # of partitions.*",
command("variable ten10 world xxx xxx"););
TEST_FAILURE(".*ERROR: All universe/uloop variables must have same # of values.*",
command("variable ten4 uloop 2"););
TEST_FAILURE(".*ERROR: Incorrect conversion in format string.*",
command("variable ten11 format two \"%08f\""););
TEST_FAILURE(".*ERROR: Variable name 'ten@12' must have only alphanumeric characters or.*",
command("variable ten@12 index one two three"););
TEST_FAILURE(".*ERROR: Variable evaluation before simulation box is defined.*",
variable->compute_equal("c_thermo_press"););
TEST_FAILURE(".*ERROR: Invalid variable reference v_unknown in variable formula.*",
variable->compute_equal("v_unknown"););
}
TEST_F(VariableTest, AtomicSystem)
{
HIDE_OUTPUT([&] { command("atom_modify map array"); });
atomic_system();
file_vars();
BEGIN_HIDE_OUTPUT();
command("variable one index 1 2 3 4");
command("variable id atom type");
command("variable id atom id");
command("variable ten atomfile test_variable.atomfile");
command("compute press all pressure NULL pair");
command("compute rg all gyration");
command("compute vacf all vacf");
command("fix press all ave/time 1 1 1 c_press mode vector");
command("fix rg all ave/time 1 1 1 c_rg mode vector");
command("fix vacf all ave/time 1 1 1 c_vacf mode vector");
command("variable press vector f_press");
command("variable rg vector f_rg");
command("variable vacf vector f_vacf");
command("variable press vector f_press+0.0");
command("variable self vector v_self+f_press");
command("variable circle vector f_press+v_circle");
command("variable sum vector v_press+v_rg");
command("variable sum2 vector v_vacf+v_rg");
command("variable pmax equal max(v_press)");
command("variable psum equal sum(v_press)");
command("variable rgmax equal max(v_rg)");
command("variable rgsum equal sum(v_rg)");
command("variable loop equal v_loop+1");
command("run 0 post no");
END_HIDE_OUTPUT();
ASSERT_EQ(variable->atomstyle(variable->find("one")), 0);
ASSERT_EQ(variable->atomstyle(variable->find("id")), 1);
ASSERT_EQ(variable->atomstyle(variable->find("ten")), 1);
ASSERT_EQ(variable->vectorstyle(variable->find("one")), 0);
ASSERT_EQ(variable->vectorstyle(variable->find("press")), 1);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_pmax"), 0.0);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_psum"), 0.0);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_rgmax"), 1.25);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_rgsum"), 3.75);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_sum[1]"), 1.25);
TEST_FAILURE(".*ERROR: Cannot redefine variable as a different style.*",
command("variable one atom x"););
TEST_FAILURE(".*ERROR: Cannot redefine variable as a different style.*",
command("variable one vector f_press"););
TEST_FAILURE(".*ERROR on proc 0: Cannot open file variable file test_variable.xxx.*",
command("variable ten1 atomfile test_variable.xxx"););
TEST_FAILURE(".*ERROR: Variable loop: has a circular dependency.*",
variable->compute_equal("v_loop"););
TEST_FAILURE(".*Variable self: Vector-style variable in equal-style variable formula.*",
variable->compute_equal("v_self"););
TEST_FAILURE(".*ERROR: Variable sum2: Inconsistent lengths in vector-style variable.*",
variable->compute_equal("max(v_sum2)"););
}
TEST_F(VariableTest, Expressions)
{
atomic_system();
BEGIN_HIDE_OUTPUT();
command("variable one index 1");
command("variable two equal 2");
command("variable three equal v_one+v_two");
command("variable four equal PI");
command("variable five equal version");
command("variable six equal XXX");
command("variable seven equal -v_one");
command("variable eight equal v_three-0.5");
command("variable nine equal v_two*(v_one+v_three)");
command("variable ten equal (1.0/v_two)^2");
command("variable eleven equal v_three%2");
command("variable twelve equal 1==2");
command("variable ten3 equal 1!=v_two");
command("variable ten4 equal 1<2");
command("variable ten5 equal 2>1");
command("variable ten6 equal (1<=v_one)&&(v_ten>=0.2)");
command("variable ten7 equal !(1<v_two)");
command("variable ten8 equal 1|^0");
command("variable ten9 equal v_one-v_ten9");
command("variable ten10 internal 100.0");
command("variable ten11 equal (1!=1)+(2<1)+(2<=1)+(1>2)+(1>=2)+(1&&0)+(0||0)+(1|^1)+10^0");
command("variable ten12 equal yes+no+on+off+true+false");
command("variable err1 equal v_one/v_ten7");
command("variable err2 equal v_one%v_ten7");
command("variable err3 equal v_ten7^-v_one");
variable->set("dummy index 1 2");
END_HIDE_OUTPUT();
int ivar = variable->find("one");
ASSERT_FALSE(variable->equalstyle(ivar));
ivar = variable->find("two");
ASSERT_TRUE(variable->equalstyle(ivar));
ASSERT_DOUBLE_EQ(variable->compute_equal(ivar), 2.0);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_three"), 3.0);
ASSERT_FLOAT_EQ(variable->compute_equal("v_four"), MY_PI);
ASSERT_GE(variable->compute_equal("v_five"), 20210310);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_seven"), -1);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_eight"), 2.5);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_nine"), 8);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten"), 0.25);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_eleven"), 1);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_twelve"), 0);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten3"), 1);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten4"), 1);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten5"), 1);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten6"), 1);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten7"), 0);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten8"), 1);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten10"), 100);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten11"), 1);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten12"), 3);
TEST_FAILURE(".*ERROR: Variable six: Invalid thermo keyword 'XXX' in variable formula.*",
command("print \"${six}\""););
TEST_FAILURE(".*ERROR: Variable ten9: has a circular dependency.*",
command("print \"${ten9}\""););
TEST_FAILURE(".*ERROR on proc 0: Variable err1: Divide by 0 in variable formula.*",
command("print \"${err1}\""););
TEST_FAILURE(".*ERROR on proc 0: Variable err2: Modulo 0 in variable formula.*",
command("print \"${err2}\""););
TEST_FAILURE(".*ERROR on proc 0: Variable err3: Invalid power expression in variable formula.*",
command("print \"${err3}\""););
}
TEST_F(VariableTest, Functions)
{
atomic_system();
file_vars();
BEGIN_HIDE_OUTPUT();
command("variable seed index 643532");
command("variable one index 1");
command("variable two equal random(1,2,v_seed)");
command("variable three equal atan2(v_one,1)");
command("variable four equal atan2()");
command("variable five equal sqrt(v_one+v_one)");
command("variable six equal exp(ln(0.1))");
command("variable seven equal abs(log(1.0/100.0))");
command("variable eight equal 0.5*PI");
command("variable nine equal round(sin(v_eight)+cos(v_eight))");
command("variable ten equal floor(1.85)+ceil(1.85)");
command("variable ten1 equal tan(v_eight/2.0)");
command("variable ten2 equal asin(-1.0)+acos(0.0)");
command("variable ten3 equal floor(100*random(0.2,0.8,v_seed)+1)");
END_HIDE_OUTPUT();
ASSERT_GT(variable->compute_equal(variable->find("two")), 0.99);
ASSERT_LT(variable->compute_equal(variable->find("two")), 2.01);
ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("three")), 0.25 * MY_PI);
ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("five")), sqrt(2.0));
ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("six")), 0.1);
ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("seven")), 2);
ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("nine")), 1);
ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("ten")), 3);
ASSERT_FLOAT_EQ(variable->compute_equal(variable->find("ten1")), 1);
ASSERT_GT(variable->compute_equal(variable->find("ten3")), 19);
ASSERT_LT(variable->compute_equal(variable->find("ten3")), 81);
TEST_FAILURE(".*ERROR: Variable four: Invalid syntax in variable formula.*",
command("print \"${four}\""););
}
TEST_F(VariableTest, IfCommand)
{
BEGIN_HIDE_OUTPUT();
command("variable one index 1");
END_HIDE_OUTPUT();
BEGIN_CAPTURE_OUTPUT();
command("if 1>0 then 'print \"bingo!\"'");
auto text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
BEGIN_CAPTURE_OUTPUT();
command("if 1>2 then 'print \"bingo!\"' else 'print \"nope?\"'");
text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, MatchesRegex(".*nope\?.*"));
BEGIN_CAPTURE_OUTPUT();
command("if (1<=0) then 'print \"bingo!\"' else 'print \"nope?\"'");
text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, MatchesRegex(".*nope\?.*"));
BEGIN_CAPTURE_OUTPUT();
command("if (-1.0e-1<0.0E+0)|^(1<0) then 'print \"bingo!\"'");
text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
BEGIN_CAPTURE_OUTPUT();
command("if (${one}==1.0)&&(2>=1) then 'print \"bingo!\"'");
text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
BEGIN_CAPTURE_OUTPUT();
command("if !((${one}!=1.0)||(2|^1)) then 'print \"missed\"' else 'print \"bingo!\"'");
text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
BEGIN_CAPTURE_OUTPUT();
command("if (1>=2)&&(0&&1) then 'print \"missed\"' else 'print \"bingo!\"'");
text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
BEGIN_CAPTURE_OUTPUT();
command("if !1 then 'print \"missed\"' else 'print \"bingo!\"'");
text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
BEGIN_CAPTURE_OUTPUT();
command("if !(a==b) then 'print \"bingo!\"'");
text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
BEGIN_CAPTURE_OUTPUT();
command("if x==x|^1==0 then 'print \"bingo!\"'");
text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
BEGIN_CAPTURE_OUTPUT();
command("if x!=x|^a!=b then 'print \"bingo!\"'");
text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
command("if () then 'print \"bingo!\"'"););
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
command("if \"1 1\" then 'print \"bingo!\"'"););
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
command("if 1a then 'print \"bingo!\"'"););
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
command("if 1=<2 then 'print \"bingo!\"'"););
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
command("if 1!=a then 'print \"bingo!\"'"););
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
command("if 1&<2 then 'print \"bingo!\"'"););
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
command("if 1|<2 then 'print \"bingo!\"'"););
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
command("if (1)( then 'print \"bingo!\"'"););
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
command("if (1)1 then 'print \"bingo!\"'"););
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
command("if (v_one==1.0)&&(2>=1) then 'print \"bingo!\"'"););
}
TEST_F(VariableTest, NextCommand)
{
file_vars();
BEGIN_HIDE_OUTPUT();
command("variable one index 1 2");
command("variable two equal 2");
command("variable three file test_variable.file");
command("variable four loop 2 4");
command("variable five index 1 2");
END_HIDE_OUTPUT();
ASSERT_DOUBLE_EQ(variable->compute_equal("v_one"), 1);
ASSERT_THAT(variable->retrieve("three"), StrEq("one"));
BEGIN_HIDE_OUTPUT();
command("next one");
command("next three");
END_HIDE_OUTPUT();
ASSERT_DOUBLE_EQ(variable->compute_equal("v_one"), 2);
ASSERT_THAT(variable->retrieve("three"), StrEq("two"));
ASSERT_GE(variable->find("one"), 0);
BEGIN_HIDE_OUTPUT();
command("next one");
command("next three");
END_HIDE_OUTPUT();
// index style variable is deleted if no more next element
ASSERT_EQ(variable->find("one"), -1);
ASSERT_GE(variable->find("three"), 0);
BEGIN_HIDE_OUTPUT();
command("next three");
command("next three");
command("next three");
END_HIDE_OUTPUT();
// file style variable is deleted if no more next element
ASSERT_EQ(variable->find("three"), -1);
TEST_FAILURE(".*ERROR: Illegal next command.*", command("next"););
TEST_FAILURE(".*ERROR: Invalid variable 'xxx' in next command.*", command("next xxx"););
TEST_FAILURE(".*ERROR: Invalid variable style with next command.*", command("next two"););
TEST_FAILURE(".*ERROR: All variables in next command must have same style.*",
command("next five four"););
}
} // namespace LAMMPS_NS
int main(int argc, char **argv)
{
MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv);
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. "
"Death tests will be skipped\n";
// handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = split_words(var);
for (auto arg : env) {
if (arg == "-v") {
verbose = true;
}
}
}
if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true;
int rv = RUN_ALL_TESTS();
MPI_Finalize();
return rv;
}