Unit tests and some off-by-one errors

This commit is contained in:
Karl Hammond
2022-10-28 19:09:31 -05:00
parent 7a10cf2b53
commit 55dafc110d
3 changed files with 305 additions and 19 deletions

View File

@ -2134,7 +2134,7 @@ CONTAINS
buf_size = LEN(buffer, KIND=c_int) + 1_c_int buf_size = LEN(buffer, KIND=c_int) + 1_c_int
Ccategory = f2c_string(category) Ccategory = f2c_string(category)
Cptr = C_LOC(Cbuffer) Cptr = C_LOC(Cbuffer)
success = lammps_style_name(self%handle, Ccategory, idx, Cptr, buf_size) success = lammps_style_name(self%handle, Ccategory, idx - 1, Cptr, buf_size)
IF (success == 1_c_int) THEN IF (success == 1_c_int) THEN
buffer = array2string(Cbuffer) buffer = array2string(Cbuffer)
ELSE ELSE
@ -2185,7 +2185,7 @@ CONTAINS
Ccategory = f2c_string(category) Ccategory = f2c_string(category)
buf_size = LEN(buffer, KIND=c_int) buf_size = LEN(buffer, KIND=c_int)
Cptr = C_LOC(Cbuffer(1)) Cptr = C_LOC(Cbuffer(1))
success = lammps_id_name(self%handle, Ccategory, idx, Cptr, buf_size) success = lammps_id_name(self%handle, Ccategory, idx - 1, Cptr, buf_size)
IF (success /= 0) THEN IF (success /= 0) THEN
buffer = array2string(Cbuffer) buffer = array2string(Cbuffer)
ELSE ELSE
@ -2206,7 +2206,7 @@ CONTAINS
buf_size = MIN(LEN(stylebuf, KIND=c_int), LEN(namebuf, KIND=c_int)) buf_size = MIN(LEN(stylebuf, KIND=c_int), LEN(namebuf, KIND=c_int))
Cstylebuf = lammps_malloc(INT(buf_size, KIND=c_size_t)) Cstylebuf = lammps_malloc(INT(buf_size, KIND=c_size_t))
Cnamebuf = lammps_malloc(INT(buf_size, KIND=c_size_t)) Cnamebuf = lammps_malloc(INT(buf_size, KIND=c_size_t))
success = lammps_plugin_name(idx, Cstylebuf, Cnamebuf, buf_size) success = lammps_plugin_name(idx - 1, Cstylebuf, Cnamebuf, buf_size)
IF (success /= 0_c_int) THEN IF (success /= 0_c_int) THEN
stylebuf = c2f_string(Cstylebuf) stylebuf = c2f_string(Cstylebuf)
namebuf = c2f_string(Cnamebuf) namebuf = c2f_string(Cnamebuf)

View File

@ -308,3 +308,166 @@ FUNCTION f_lammps_style_count(ptr) BIND(C)
END DO END DO
f_lammps_style_count = lmp%style_count(category) f_lammps_style_count = lmp%style_count(category)
END FUNCTION f_lammps_style_count END FUNCTION f_lammps_style_count
FUNCTION f_lammps_style_name(category_ptr, idx) BIND(C)
USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_ptr, c_int, c_char, c_size_t, &
C_F_POINTER
USE LIBLAMMPS
USE keepstuff, ONLY : lmp, c_strlen, f2c_string
IMPLICIT NONE
TYPE(c_ptr), INTENT(IN), VALUE :: category_ptr
INTEGER(c_int), INTENT(IN), VALUE :: idx
TYPE(c_ptr) :: f_lammps_style_name
CHARACTER(LEN=1, KIND=c_char), DIMENSION(:), POINTER :: C_category
INTEGER(c_size_t) :: length, i
CHARACTER(LEN=:), ALLOCATABLE :: category
CHARACTER(LEN=100) :: buffer
length = c_strlen(category_ptr)
CALL C_F_POINTER(category_ptr, C_category, [length])
ALLOCATE(CHARACTER(LEN=length) :: category)
DO i = 1, length
category(i:i) = C_category(i)
END DO
CALL lmp%style_name(category, idx, buffer)
f_lammps_style_name = f2c_string(buffer)
END FUNCTION f_lammps_style_name
SUBROUTINE f_setup_has_id() BIND(C)
USE keepstuff, ONLY : lmp
IMPLICIT NONE
CHARACTER(LEN=100), DIMENSION(*), PARAMETER :: setup_commands = &
[CHARACTER(LEN=100) :: 'units lj', &
'region simbox block 0 2 0 3 0 4 units box', &
'create_box 1 simbox', &
'create_atoms 1 single 0.01 0.01 0.01 units box', &
'create_atoms 1 single 1.0 1.0 1.0 units box', &
'pair_style lj/cut 2.5', &
'pair_coeff * * 1.0 1.0', &
'mass * 1.0', &
'compute COM all com', &
'dump 1 all atom 1000 dump.tmp', &
'fix 1 all nve', &
'group one id 1', &
'variable pi equal acos(-1)', &
!'molecule A file1 file2', &
'run 0' &
]
CALL lmp%commands_list(setup_commands)
END SUBROUTINE
FUNCTION f_lammps_has_id(Ccategory, Cname) BIND(C)
USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_ptr, c_int, c_size_t, c_char, &
C_F_POINTER
USE keepstuff, ONLY : lmp, c_strlen
IMPLICIT NONE
TYPE(c_ptr), VALUE :: Ccategory, Cname
INTEGER(c_int) :: f_lammps_has_id
INTEGER(c_size_t) :: len_cat, len_name, i
CHARACTER(LEN=:), ALLOCATABLE :: category, name
CHARACTER(LEN=1, KIND=c_char), DIMENSION(:), POINTER :: Fcategory, Fname
LOGICAL :: has_id
len_cat = c_strlen(Ccategory)
len_name = c_strlen(Cname)
CALL C_F_POINTER(Ccategory, Fcategory, [len_cat])
CALL C_F_POINTER(Cname, Fname, [len_name])
ALLOCATE(CHARACTER(LEN=len_cat) :: category)
ALLOCATE(CHARACTER(LEN=len_name) :: name)
DO i = 1, len_cat
category(i:i) = Fcategory(i)
END DO
DO i = 1, len_name
name(i:i) = Fname(i)
END DO
has_id = lmp%has_id(category, name)
IF (has_id) THEN
f_lammps_has_id = 1_c_int
ELSE
f_lammps_has_id = 0_c_int
END IF
END FUNCTION f_lammps_has_id
FUNCTION f_lammps_id_count(Ccategory) BIND(C)
USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_ptr, c_int, c_size_t, c_char, &
C_F_POINTER
USE keepstuff, ONLY : lmp, c_strlen
IMPLICIT NONE
TYPE(c_ptr), VALUE :: Ccategory
INTEGER(c_int) :: f_lammps_id_count
INTEGER(c_size_t) :: len_cat, i
CHARACTER(LEN=:), ALLOCATABLE :: category
CHARACTER(LEN=1, KIND=c_char), DIMENSION(:), POINTER :: Fcategory
len_cat = c_strlen(Ccategory)
CALL C_F_POINTER(Ccategory, Fcategory, [len_cat])
ALLOCATE(CHARACTER(LEN=len_cat) :: category)
DO i = 1, len_cat
category(i:i) = Fcategory(i)
END DO
f_lammps_id_count = lmp%id_count(category)
END FUNCTION f_lammps_id_count
FUNCTION f_lammps_id_name(Ccategory, idx) BIND(C)
USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_ptr, c_int, c_size_t, c_char, &
C_F_POINTER
USE keepstuff, ONLY : lmp, c_strlen, f2c_string
IMPLICIT NONE
TYPE(c_ptr), VALUE :: Ccategory
INTEGER(c_int), VALUE :: idx
TYPE(c_ptr) :: f_lammps_id_name
INTEGER(c_size_t) :: len_cat, i
CHARACTER(LEN=:), ALLOCATABLE :: category
CHARACTER(LEN=1, KIND=c_char), DIMENSION(:), POINTER :: Fcategory
CHARACTER(LEN=100) :: buffer
len_cat = c_strlen(Ccategory)
CALL C_F_POINTER(Ccategory, Fcategory, [len_cat])
ALLOCATE(CHARACTER(LEN=len_cat) :: category)
DO i = 1, len_cat
category(i:i) = Fcategory(i)
END DO
CALL lmp%id_name(category, idx, buffer)
f_lammps_id_name = f2c_string(buffer)
END FUNCTION f_lammps_id_name
FUNCTION f_lammps_plugin_count() BIND(C)
USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_int
USE keepstuff, ONLY : lmp
INTEGER(c_int) :: f_lammps_plugin_count
f_lammps_plugin_count = lmp%plugin_count();
END FUNCTION f_lammps_plugin_count
FUNCTION f_lammps_plugin_name(idx, Cstyle, Cname) BIND(C)
USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_ptr, c_int, c_size_t, c_char, &
C_F_POINTER
USE keepstuff, ONLY : lmp, c_strlen, f2c_string
IMPLICIT NONE
INTEGER(c_int), INTENT(IN), VALUE :: idx
TYPE(c_ptr), INTENT(IN), VALUE :: Cstyle, Cname
CHARACTER(LEN=1, KIND=c_char), DIMENSION(:), POINTER :: Fstyle, Fname
INTEGER(c_int) :: f_lammps_plugin_name
CHARACTER(LEN=100) :: style, name
INTEGER(c_size_t) :: len_style, len_name, i
LOGICAL :: all_are_identical
CALL lmp%plugin_name(idx, style, name)
len_style = c_strlen(Cstyle)
len_name = c_strlen(Cname)
CALL C_F_POINTER(Cstyle, Fstyle, [len_style])
CALL C_F_POINTER(Cname, Fname, [len_name])
all_are_identical = .TRUE.
DO i = 1, len_style
all_are_identical = all_are_identical .AND. (style(i:i) == Fstyle(i))
END DO
DO i = 1, len_name
all_are_identical = all_are_identical .AND. (name(i:i) == Fname(i))
END DO
IF (all_are_identical) THEN
f_lammps_plugin_name = 1_c_int
ELSE
f_lammps_plugin_name = 0_c_int
END IF
END FUNCTION f_lammps_plugin_name

View File

@ -4,6 +4,10 @@
#include "library.h" #include "library.h"
#include "info.h" #include "info.h"
#ifdef LMP_PLUGIN
#include "plugin.h"
#endif
#include <string> #include <string>
#include "gmock/gmock.h" #include "gmock/gmock.h"
@ -29,7 +33,13 @@ int f_lammps_has_gpu();
char* f_lammps_get_gpu_info(size_t); char* f_lammps_get_gpu_info(size_t);
int f_lammps_has_style(const char*, const char*); int f_lammps_has_style(const char*, const char*);
int f_lammps_style_count(const char*); int f_lammps_style_count(const char*);
int f_lammps_style_name(); char* f_lammps_style_name(const char*, int);
void f_setup_has_id();
int f_lammps_has_id(const char*, const char*);
int f_lammps_id_count(const char*);
char* f_lammps_id_name(const char*, int);
int f_lammps_plugin_count();
int f_lammps_plugin_name();
} }
namespace LAMMPS_NS { namespace LAMMPS_NS {
@ -38,6 +48,9 @@ using ::testing::ContainsRegex;
class LAMMPS_configuration : public ::testing::Test { class LAMMPS_configuration : public ::testing::Test {
protected: protected:
LAMMPS *lmp; LAMMPS *lmp;
std::vector <std::string> style_category = {"atom","integrate","minimize",
"pair","bond","angle","dihedral","improper","kspace","fix","compute",
"region","dump","command"};
void SetUp() override void SetUp() override
{ {
@ -145,7 +158,6 @@ TEST_F(LAMMPS_configuration, package_name)
i++; i++;
} }
}; };
TEST_F(LAMMPS_configuration, installed_packages) TEST_F(LAMMPS_configuration, installed_packages)
{ {
const char *package_name; const char *package_name;
@ -220,17 +232,15 @@ TEST_F(LAMMPS_configuration, get_gpu_info)
TEST_F(LAMMPS_configuration, has_style) TEST_F(LAMMPS_configuration, has_style)
{ {
std::vector<std::string> category = {"atom","integrate","minimize","pair",
"bond","angle","dihedral","improper","kspace","fix","compute","region",
"dump","command"};
Info info(lmp); Info info(lmp);
for (int c = 0; c < category.size(); c++) for (int c = 0; c < style_category.size(); c++)
{ {
std::vector<std::string> name = info.get_available_styles(category[c]); std::vector<std::string> name =
info.get_available_styles(style_category[c]);
for (int s = 0; s < name.size(); s++) for (int s = 0; s < name.size(); s++)
{ {
EXPECT_EQ(f_lammps_has_style(category[c].c_str(), EXPECT_EQ(f_lammps_has_style(style_category[c].c_str(),
name[s].c_str()), info.has_style(category[c], name[s])); name[s].c_str()), info.has_style(style_category[c], name[s]));
} }
} }
EXPECT_EQ(f_lammps_has_style("atom","none"), 0); EXPECT_EQ(f_lammps_has_style("atom","none"), 0);
@ -239,14 +249,127 @@ TEST_F(LAMMPS_configuration, has_style)
TEST_F(LAMMPS_configuration, style_count) TEST_F(LAMMPS_configuration, style_count)
{ {
Info info(lmp); Info info(lmp);
std::vector<std::string> category = {"atom","integrate","minimize","pair", for (int i = 0; i < style_category.size(); i++)
"bond","angle","dihedral","improper","kspace","fix","compute","region", EXPECT_EQ(f_lammps_style_count(style_category[i].c_str()),
"dump","command"}; info.get_available_styles(style_category[i].c_str()).size());
for (int i = 0; i < category.size(); i++) };
TEST_F(LAMMPS_configuration, style_name)
{ {
EXPECT_EQ(f_lammps_style_count(category[i].c_str()), char *buffer;
info.get_available_styles(category[i].c_str()).size()); Info info(lmp);
for (int c = 0; c < style_category.size(); c++) {
int nnames = f_lammps_style_count(style_category[c].c_str());
auto styles = info.get_available_styles(style_category[c]);
for (int i = 0; i < nnames; i++) {
buffer = f_lammps_style_name(style_category[c].c_str(), i + 1);
EXPECT_STREQ(buffer, styles[i].c_str());
std::free(buffer);
} }
}
};
TEST_F(LAMMPS_configuration, has_id)
{
f_setup_has_id();
EXPECT_EQ(f_lammps_has_id("compute","com"), 0);
EXPECT_EQ(f_lammps_has_id("compute","COM"), 1);
EXPECT_EQ(f_lammps_has_id("dump","atom"), 0);
EXPECT_EQ(f_lammps_has_id("dump","1"), 1);
EXPECT_EQ(f_lammps_has_id("fix","nve"), 0);
EXPECT_EQ(f_lammps_has_id("fix","1"), 1);
EXPECT_EQ(f_lammps_has_id("group","one"), 1);
EXPECT_EQ(f_lammps_has_id("group","all"), 1);
// Skip this one (we're testing thoroughly enough; molecules require files)
//EXPECT_EQ(f_lammps_has_id("molecule")
EXPECT_EQ(f_lammps_has_id("region","simbox"), 1);
EXPECT_EQ(f_lammps_has_id("region","box"), 0);
EXPECT_EQ(f_lammps_has_id("variable","pi"), 1);
EXPECT_EQ(f_lammps_has_id("variable","PI"), 0);
};
TEST_F(LAMMPS_configuration, id_count)
{
f_setup_has_id();
// computes: thermo_temp, thermo_press, thermo_pe, COM
EXPECT_EQ(f_lammps_id_count("compute"), 4);
EXPECT_EQ(f_lammps_id_count("dump"), 1); // only the one we defined
EXPECT_EQ(f_lammps_id_count("fix"), 1); // only the one we defined
EXPECT_EQ(f_lammps_id_count("group"), 2); // "one" and "all"
EXPECT_EQ(f_lammps_id_count("molecule"), 0);
EXPECT_EQ(f_lammps_id_count("region"), 1); // onle the one we created
EXPECT_EQ(f_lammps_id_count("variable"), 3); // "zpos", "x", and "pi"
};
TEST_F(LAMMPS_configuration, id_name)
{
f_setup_has_id();
char *name;
int nnames = f_lammps_id_count("compute");
EXPECT_EQ(nnames, 4);
name = f_lammps_id_name("compute",1);
EXPECT_STREQ(name, "thermo_temp");
std::free(name);
name = f_lammps_id_name("compute",2);
EXPECT_STREQ(name, "thermo_press");
std::free(name);
name = f_lammps_id_name("compute",3);
EXPECT_STREQ(name, "thermo_pe");
std::free(name);
name = f_lammps_id_name("compute",4);
EXPECT_STREQ(name, "COM");
std::free(name);
name = f_lammps_id_name("dump",1);
EXPECT_STREQ(name, "1");
std::free(name);
name = f_lammps_id_name("fix",1);
EXPECT_STREQ(name, "1");
std::free(name);
name = f_lammps_id_name("group",1);
EXPECT_STREQ(name, "all");
std::free(name);
name = f_lammps_id_name("group",2);
EXPECT_STREQ(name, "one");
std::free(name);
name = f_lammps_id_name("region",1);
EXPECT_STREQ(name, "simbox");
std::free(name);
name = f_lammps_id_name("variable",1);
EXPECT_STREQ(name, "zpos");
std::free(name);
name = f_lammps_id_name("variable",2);
EXPECT_STREQ(name, "x");
std::free(name);
name = f_lammps_id_name("variable",3);
EXPECT_STREQ(name, "pi");
std::free(name);
};
TEST_F(LAMMPS_configuration, plugins)
{
#ifndef LMP_PLUGIN
GTEST_SKIP();
#else
int nplugins = f_lammps_plugin_count();
for (int n = 0; n < nplugins; n++) {
lammpsplugin_t *plugin = plugin_get_info(n);
EXPECT_EQ(f_lammps_plugin_name(n+1, plugin->style, plugin->name), 1);
}
#endif
}; };
} // namespace LAMMPS_NS } // namespace LAMMPS_NS