1 /* ----------------------------------------------------------------------
2 LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
3 https://www.lammps.org/, Sandia National Laboratories
4 Steve Plimpton, sjplimp@sandia.gov
5
6 Copyright (2003) Sandia Corporation. Under the terms of Contract
7 DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
8 certain rights in this software. This software is distributed under
9 the GNU General Public License.
10
11 See the README file in the top-level LAMMPS directory.
12 ------------------------------------------------------------------------- */
13
14 #include "lammps.h"
15
16 #include "atom.h"
17 #include "domain.h"
18 #include "group.h"
19 #include "info.h"
20 #include "input.h"
21 #include "math_const.h"
22 #include "region.h"
23 #include "variable.h"
24
25 #include "../testing/core.h"
26 #include "gmock/gmock.h"
27 #include "gtest/gtest.h"
28
29 #include <cstring>
30 #include <vector>
31
32 // whether to print verbose output (i.e. not capturing LAMMPS screen output).
33 bool verbose = false;
34
35 using LAMMPS_NS::MathConst::MY_PI;
36 using LAMMPS_NS::utils::split_words;
37
38 namespace LAMMPS_NS {
39 using ::testing::ExitedWithCode;
40 using ::testing::MatchesRegex;
41 using ::testing::StrEq;
42
43 class VariableTest : public LAMMPSTest {
44 protected:
45 Group *group;
46 Domain *domain;
47 Variable *variable;
48
SetUp()49 void SetUp() override
50 {
51 testbinary = "VariableTest";
52 args = {"-log", "none", "-echo", "screen", "-nocite", "-v", "num", "1"};
53 LAMMPSTest::SetUp();
54 group = lmp->group;
55 domain = lmp->domain;
56 variable = lmp->input->variable;
57 }
58
TearDown()59 void TearDown() override
60 {
61 LAMMPSTest::TearDown();
62 unlink("test_variable.file");
63 unlink("test_variable.atomfile");
64 }
65
atomic_system()66 void atomic_system()
67 {
68 BEGIN_HIDE_OUTPUT();
69 command("units real");
70 command("lattice sc 1.0 origin 0.125 0.125 0.125");
71 command("region box block -2 2 -2 2 -2 2");
72 command("create_box 8 box");
73 command("create_atoms 1 box");
74 command("mass * 1.0");
75 command("region left block -2.0 -1.0 INF INF INF INF");
76 command("region right block 0.5 2.0 INF INF INF INF");
77 command("region top block INF INF -2.0 -1.0 INF INF");
78 command("set region left type 2");
79 command("set region right type 3");
80 END_HIDE_OUTPUT();
81 }
82
molecular_system()83 void molecular_system()
84 {
85 BEGIN_HIDE_OUTPUT();
86 command("fix props all property/atom mol rmass q");
87 END_HIDE_OUTPUT();
88 atomic_system();
89 BEGIN_HIDE_OUTPUT();
90 command("variable molid atom floor(id/4)+1");
91 command("variable charge atom 2.0*sin(PI/32*id)");
92 command("set atom * mol v_molid");
93 command("set atom * charge v_charge");
94 command("set type 1 mass 0.5");
95 command("set type 2*4 mass 2.0");
96 END_HIDE_OUTPUT();
97 }
98
file_vars()99 void file_vars()
100 {
101 FILE *fp = fopen("test_variable.file", "w");
102 fputs("# test file for file style variable\n\n\none\n two \n\n"
103 "three # with comment\nfour ! with non-comment\n"
104 "# comments only\n five\n#END\n",
105 fp);
106 fclose(fp);
107
108 fp = fopen("test_variable.atomfile", "w");
109 fputs("# test file for atomfile style variable\n\n"
110 "4 # four lines\n4 0.5 #with comment\n"
111 "2 -0.5 \n3 1.5\n1 -1.5\n\n"
112 "2\n10 1.0 # test\n13 1.0\n\n######\n"
113 "4\n1 4.0 # test\n2 3.0\n3 2.0\n4 1.0\n#END\n",
114 fp);
115 fclose(fp);
116 }
117 };
118
TEST_F(VariableTest,CreateDelete)119 TEST_F(VariableTest, CreateDelete)
120 {
121 file_vars();
122 ASSERT_EQ(variable->nvar, 1);
123 BEGIN_HIDE_OUTPUT();
124 command("shell putenv TEST_VARIABLE=simpletest2");
125 command("shell putenv TEST_VARIABLE2=simpletest OTHER_VARIABLE=2");
126 command("variable one index 1 2 3 4");
127 command("variable two equal 1");
128 command("variable two equal 2");
129 command("variable three string four");
130 command("variable three string three");
131 command("variable four1 loop 4");
132 command("variable four2 loop 2 4");
133 command("variable five1 loop 100 pad");
134 command("variable five2 loop 10 200 pad");
135 command("variable six world one");
136 command("variable seven format two \"%5.2f\"");
137 command("variable eight getenv TEST_VARIABLE2");
138 command("variable eight getenv XXX");
139 command("variable nine file test_variable.file");
140 command("variable ten internal 1.0");
141 command("variable ten internal 10.0");
142 command("variable ten1 universe 1 2 3 4");
143 command("variable ten2 uloop 4");
144 command("variable ten3 uloop 4 pad");
145 command("variable dummy index 0");
146 command("variable file equal is_file(MYFILE)");
147 END_HIDE_OUTPUT();
148 ASSERT_EQ(variable->nvar, 18);
149 BEGIN_HIDE_OUTPUT();
150 command("variable dummy delete");
151 END_HIDE_OUTPUT();
152 ASSERT_EQ(variable->nvar, 17);
153 ASSERT_THAT(variable->retrieve("three"), StrEq("three"));
154 variable->set_string("three", "four");
155 ASSERT_THAT(variable->retrieve("three"), StrEq("four"));
156 ASSERT_THAT(variable->retrieve("four2"), StrEq("2"));
157 ASSERT_THAT(variable->retrieve("five1"), StrEq("001"));
158 ASSERT_THAT(variable->retrieve("seven"), StrEq(" 2.00"));
159 ASSERT_THAT(variable->retrieve("ten"), StrEq("1"));
160 ASSERT_THAT(variable->retrieve("eight"), StrEq(""));
161 variable->internal_set(variable->find("ten"), 2.5);
162 ASSERT_THAT(variable->retrieve("ten"), StrEq("2.5"));
163 ASSERT_THAT(variable->retrieve("file"), StrEq("0"));
164 FILE *fp = fopen("MYFILE", "w");
165 fputs(" ", fp);
166 fclose(fp);
167 ASSERT_THAT(variable->retrieve("file"), StrEq("1"));
168 unlink("MYFILE");
169 ASSERT_THAT(variable->retrieve("file"), StrEq("0"));
170
171 BEGIN_HIDE_OUTPUT();
172 command("variable seven delete");
173 command("variable seven getenv TEST_VARIABLE");
174 command("variable eight getenv OTHER_VARIABLE");
175 END_HIDE_OUTPUT();
176 ASSERT_THAT(variable->retrieve("seven"), StrEq("simpletest2"));
177 ASSERT_THAT(variable->retrieve("eight"), StrEq("2"));
178
179 ASSERT_EQ(variable->equalstyle(variable->find("one")), 0);
180 ASSERT_EQ(variable->equalstyle(variable->find("two")), 1);
181 ASSERT_EQ(variable->equalstyle(variable->find("ten")), 1);
182
183 ASSERT_EQ(variable->internalstyle(variable->find("two")), 0);
184 ASSERT_EQ(variable->internalstyle(variable->find("ten")), 1);
185
186 TEST_FAILURE(".*ERROR: Illegal variable command.*", command("variable"););
187 TEST_FAILURE(".*ERROR: Illegal variable command.*", command("variable dummy index"););
188 TEST_FAILURE(".*ERROR: Illegal variable command.*", command("variable dummy delete xxx"););
189 TEST_FAILURE(".*ERROR: Illegal variable command.*", command("variable dummy loop -1"););
190 TEST_FAILURE(".*ERROR: Illegal variable command.*", command("variable dummy loop 10 1"););
191 TEST_FAILURE(".*ERROR: Illegal variable command.*", command("variable dummy xxxx"););
192 TEST_FAILURE(".*ERROR: Cannot redefine variable as a different style.*",
193 command("variable two string xxx"););
194 TEST_FAILURE(".*ERROR: Cannot redefine variable as a different style.*",
195 command("variable two getenv xxx"););
196 TEST_FAILURE(".*ERROR: Cannot redefine variable as a different style.*",
197 command("variable one equal 2"););
198 TEST_FAILURE(".*ERROR: Cannot redefine variable as a different style.*",
199 command("variable one internal 2"););
200 TEST_FAILURE(".*ERROR: Cannot use atomfile-style variable unless an atom map exists.*",
201 command("variable eleven atomfile test_variable.atomfile"););
202 TEST_FAILURE(".*ERROR on proc 0: Cannot open file variable file test_variable.xxx.*",
203 command("variable nine1 file test_variable.xxx"););
204 TEST_FAILURE(".*ERROR: World variable count doesn't match # of partitions.*",
205 command("variable ten10 world xxx xxx"););
206 TEST_FAILURE(".*ERROR: All universe/uloop variables must have same # of values.*",
207 command("variable ten4 uloop 2"););
208 TEST_FAILURE(".*ERROR: Incorrect conversion in format string.*",
209 command("variable ten11 format two \"%08f\""););
210 TEST_FAILURE(".*ERROR: Variable name 'ten@12' must have only alphanumeric characters or.*",
211 command("variable ten@12 index one two three"););
212 TEST_FAILURE(".*ERROR: Variable evaluation before simulation box is defined.*",
213 variable->compute_equal("c_thermo_press"););
214 TEST_FAILURE(".*ERROR: Invalid variable reference v_unknown in variable formula.*",
215 variable->compute_equal("v_unknown"););
216 }
217
TEST_F(VariableTest,AtomicSystem)218 TEST_F(VariableTest, AtomicSystem)
219 {
220 HIDE_OUTPUT([&] {
221 command("atom_modify map array");
222 });
223 atomic_system();
224 file_vars();
225
226 BEGIN_HIDE_OUTPUT();
227 command("variable one index 1 2 3 4");
228 command("variable id atom type");
229 command("variable id atom id");
230 command("variable ten atomfile test_variable.atomfile");
231
232 command("compute press all pressure NULL pair");
233 command("compute rg all gyration");
234 command("compute vacf all vacf");
235 command("fix press all ave/time 1 1 1 c_press mode vector");
236 command("fix rg all ave/time 1 1 1 c_rg mode vector");
237 command("fix vacf all ave/time 1 1 1 c_vacf mode vector");
238
239 command("variable press vector f_press");
240 command("variable rg vector f_rg");
241 command("variable vacf vector f_vacf");
242 command("variable press vector f_press+0.0");
243 command("variable self vector v_self+f_press");
244 command("variable circle vector f_press+v_circle");
245 command("variable sum vector v_press+v_rg");
246 command("variable sum2 vector v_vacf+v_rg");
247 command("variable pmax equal max(v_press)");
248 command("variable psum equal sum(v_press)");
249 command("variable rgmax equal max(v_rg)");
250 command("variable rgsum equal sum(v_rg)");
251 command("variable loop equal v_loop+1");
252 command("run 0 post no");
253 END_HIDE_OUTPUT();
254
255 ASSERT_EQ(variable->atomstyle(variable->find("one")), 0);
256 ASSERT_EQ(variable->atomstyle(variable->find("id")), 1);
257 ASSERT_EQ(variable->atomstyle(variable->find("ten")), 1);
258
259 ASSERT_EQ(variable->vectorstyle(variable->find("one")), 0);
260 ASSERT_EQ(variable->vectorstyle(variable->find("press")), 1);
261
262 ASSERT_DOUBLE_EQ(variable->compute_equal("v_pmax"), 0.0);
263 ASSERT_DOUBLE_EQ(variable->compute_equal("v_psum"), 0.0);
264 ASSERT_DOUBLE_EQ(variable->compute_equal("v_rgmax"), 1.25);
265 ASSERT_DOUBLE_EQ(variable->compute_equal("v_rgsum"), 3.75);
266 ASSERT_DOUBLE_EQ(variable->compute_equal("v_sum[1]"), 1.25);
267
268 TEST_FAILURE(".*ERROR: Cannot redefine variable as a different style.*",
269 command("variable one atom x"););
270 TEST_FAILURE(".*ERROR: Cannot redefine variable as a different style.*",
271 command("variable one vector f_press"););
272 TEST_FAILURE(".*ERROR on proc 0: Cannot open file variable file test_variable.xxx.*",
273 command("variable ten1 atomfile test_variable.xxx"););
274 TEST_FAILURE(".*ERROR: Variable loop: has a circular dependency.*",
275 variable->compute_equal("v_loop"););
276 TEST_FAILURE(".*Variable self: Vector-style variable in equal-style variable formula.*",
277 variable->compute_equal("v_self"););
278 TEST_FAILURE(".*ERROR: Variable sum2: Inconsistent lengths in vector-style variable.*",
279 variable->compute_equal("max(v_sum2)"););
280 }
281
TEST_F(VariableTest,Expressions)282 TEST_F(VariableTest, Expressions)
283 {
284 atomic_system();
285 BEGIN_HIDE_OUTPUT();
286 command("variable one index 1");
287 command("variable two equal 2");
288 command("variable three equal v_one+v_two");
289 command("variable four equal PI");
290 command("variable five equal version");
291 command("variable six equal XXX");
292 command("variable seven equal -v_one");
293 command("variable eight equal v_three-0.5");
294 command("variable nine equal v_two*(v_one+v_three)");
295 command("variable ten equal (1.0/v_two)^2");
296 command("variable eleven equal v_three%2");
297 command("variable twelve equal 1==2");
298 command("variable ten3 equal 1!=v_two");
299 command("variable ten4 equal 1<2");
300 command("variable ten5 equal 2>1");
301 command("variable ten6 equal (1<=v_one)&&(v_ten>=0.2)");
302 command("variable ten7 equal !(1<v_two)");
303 command("variable ten8 equal 1|^0");
304 command("variable ten9 equal v_one-v_ten9");
305 command("variable ten10 internal 100.0");
306 command("variable ten11 equal (1!=1)+(2<1)+(2<=1)+(1>2)+(1>=2)+(1&&0)+(0||0)+(1|^1)+10^0");
307 command("variable ten12 equal yes+no+on+off+true+false");
308 command("variable err1 equal v_one/v_ten7");
309 command("variable err2 equal v_one%v_ten7");
310 command("variable err3 equal v_ten7^-v_one");
311 variable->set("dummy index 1 2");
312 END_HIDE_OUTPUT();
313
314 int ivar = variable->find("one");
315 ASSERT_FALSE(variable->equalstyle(ivar));
316 ivar = variable->find("two");
317 ASSERT_TRUE(variable->equalstyle(ivar));
318 ASSERT_DOUBLE_EQ(variable->compute_equal(ivar), 2.0);
319 ASSERT_DOUBLE_EQ(variable->compute_equal("v_three"), 3.0);
320 ASSERT_FLOAT_EQ(variable->compute_equal("v_four"), MY_PI);
321 ASSERT_GE(variable->compute_equal("v_five"), 20210310);
322 ASSERT_DOUBLE_EQ(variable->compute_equal("v_seven"), -1);
323 ASSERT_DOUBLE_EQ(variable->compute_equal("v_eight"), 2.5);
324 ASSERT_DOUBLE_EQ(variable->compute_equal("v_nine"), 8);
325 ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten"), 0.25);
326 ASSERT_DOUBLE_EQ(variable->compute_equal("v_eleven"), 1);
327 ASSERT_DOUBLE_EQ(variable->compute_equal("v_twelve"), 0);
328 ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten3"), 1);
329 ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten4"), 1);
330 ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten5"), 1);
331 ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten6"), 1);
332 ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten7"), 0);
333 ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten8"), 1);
334 ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten10"), 100);
335 ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten11"), 1);
336 ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten12"), 3);
337
338 TEST_FAILURE(".*ERROR: Variable six: Invalid thermo keyword 'XXX' in variable formula.*",
339 command("print \"${six}\""););
340 TEST_FAILURE(".*ERROR: Variable ten9: has a circular dependency.*",
341 command("print \"${ten9}\""););
342 TEST_FAILURE(".*ERROR on proc 0: Variable err1: Divide by 0 in variable formula.*",
343 command("print \"${err1}\""););
344 TEST_FAILURE(".*ERROR on proc 0: Variable err2: Modulo 0 in variable formula.*",
345 command("print \"${err2}\""););
346 TEST_FAILURE(".*ERROR on proc 0: Variable err3: Invalid power expression in variable formula.*",
347 command("print \"${err3}\""););
348 }
349
TEST_F(VariableTest,Functions)350 TEST_F(VariableTest, Functions)
351 {
352 atomic_system();
353 file_vars();
354
355 BEGIN_HIDE_OUTPUT();
356 command("variable seed index 643532");
357 command("variable one index 1");
358 command("variable two equal random(1,2,v_seed)");
359 command("variable three equal atan2(v_one,1)");
360 command("variable four equal atan2()");
361 command("variable five equal sqrt(v_one+v_one)");
362 command("variable six equal exp(ln(0.1))");
363 command("variable seven equal abs(log(1.0/100.0))");
364 command("variable eight equal 0.5*PI");
365 command("variable nine equal round(sin(v_eight)+cos(v_eight))");
366 command("variable ten equal floor(1.85)+ceil(1.85)");
367 command("variable ten1 equal tan(v_eight/2.0)");
368 command("variable ten2 equal asin(-1.0)+acos(0.0)");
369 command("variable ten3 equal floor(100*random(0.2,0.8,v_seed)+1)");
370 END_HIDE_OUTPUT();
371
372 ASSERT_GT(variable->compute_equal(variable->find("two")), 0.99);
373 ASSERT_LT(variable->compute_equal(variable->find("two")), 2.01);
374 ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("three")), 0.25 * MY_PI);
375 ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("five")), sqrt(2.0));
376 ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("six")), 0.1);
377 ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("seven")), 2);
378 ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("nine")), 1);
379 ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("ten")), 3);
380 ASSERT_FLOAT_EQ(variable->compute_equal(variable->find("ten1")), 1);
381 ASSERT_GT(variable->compute_equal(variable->find("ten3")), 19);
382 ASSERT_LT(variable->compute_equal(variable->find("ten3")), 81);
383
384 TEST_FAILURE(".*ERROR: Variable four: Invalid syntax in variable formula.*",
385 command("print \"${four}\""););
386 }
387
TEST_F(VariableTest,IfCommand)388 TEST_F(VariableTest, IfCommand)
389 {
390 BEGIN_HIDE_OUTPUT();
391 command("variable one index 1");
392 END_HIDE_OUTPUT();
393
394 BEGIN_CAPTURE_OUTPUT();
395 command("if 1>0 then 'print \"bingo!\"'");
396 auto text = END_CAPTURE_OUTPUT();
397 ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
398
399 BEGIN_CAPTURE_OUTPUT();
400 command("if 1>2 then 'print \"bingo!\"' else 'print \"nope?\"'");
401 text = END_CAPTURE_OUTPUT();
402 ASSERT_THAT(text, MatchesRegex(".*nope\?.*"));
403
404 BEGIN_CAPTURE_OUTPUT();
405 command("if (1<=0) then 'print \"bingo!\"' else 'print \"nope?\"'");
406 text = END_CAPTURE_OUTPUT();
407 ASSERT_THAT(text, MatchesRegex(".*nope\?.*"));
408
409 BEGIN_CAPTURE_OUTPUT();
410 command("if (-1.0e-1<0.0E+0)|^(1<0) then 'print \"bingo!\"'");
411 text = END_CAPTURE_OUTPUT();
412 ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
413
414 BEGIN_CAPTURE_OUTPUT();
415 command("if (${one}==1.0)&&(2>=1) then 'print \"bingo!\"'");
416 text = END_CAPTURE_OUTPUT();
417 ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
418
419 BEGIN_CAPTURE_OUTPUT();
420 command("if !((${one}!=1.0)||(2|^1)) then 'print \"missed\"' else 'print \"bingo!\"'");
421 text = END_CAPTURE_OUTPUT();
422 ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
423
424 BEGIN_CAPTURE_OUTPUT();
425 command("if (1>=2)&&(0&&1) then 'print \"missed\"' else 'print \"bingo!\"'");
426 text = END_CAPTURE_OUTPUT();
427 ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
428
429 BEGIN_CAPTURE_OUTPUT();
430 command("if !1 then 'print \"missed\"' else 'print \"bingo!\"'");
431 text = END_CAPTURE_OUTPUT();
432 ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
433
434 BEGIN_CAPTURE_OUTPUT();
435 command("if !(a==b) then 'print \"bingo!\"'");
436 text = END_CAPTURE_OUTPUT();
437 ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
438
439 BEGIN_CAPTURE_OUTPUT();
440 command("if x==x|^1==0 then 'print \"bingo!\"'");
441 text = END_CAPTURE_OUTPUT();
442 ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
443
444 BEGIN_CAPTURE_OUTPUT();
445 command("if x!=x|^a!=b then 'print \"bingo!\"'");
446 text = END_CAPTURE_OUTPUT();
447
448 ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
449
450 TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
451 command("if () then 'print \"bingo!\"'"););
452 TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
453 command("if \"1 1\" then 'print \"bingo!\"'"););
454 TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
455 command("if 1a then 'print \"bingo!\"'"););
456 TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
457 command("if 1=<2 then 'print \"bingo!\"'"););
458 TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
459 command("if 1!=a then 'print \"bingo!\"'"););
460 TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
461 command("if 1&<2 then 'print \"bingo!\"'"););
462 TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
463 command("if 1|<2 then 'print \"bingo!\"'"););
464 TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
465 command("if (1)( then 'print \"bingo!\"'"););
466 TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
467 command("if (1)1 then 'print \"bingo!\"'"););
468 TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
469 command("if (v_one==1.0)&&(2>=1) then 'print \"bingo!\"'"););
470 }
471
TEST_F(VariableTest,NextCommand)472 TEST_F(VariableTest, NextCommand)
473 {
474 file_vars();
475
476 BEGIN_HIDE_OUTPUT();
477 command("variable one index 1 2");
478 command("variable two equal 2");
479 command("variable three file test_variable.file");
480 command("variable four loop 2 4");
481 command("variable five index 1 2");
482 END_HIDE_OUTPUT();
483 ASSERT_DOUBLE_EQ(variable->compute_equal("v_one"), 1);
484 ASSERT_THAT(variable->retrieve("three"), StrEq("one"));
485 BEGIN_HIDE_OUTPUT();
486 command("next one");
487 command("next three");
488 END_HIDE_OUTPUT();
489 ASSERT_DOUBLE_EQ(variable->compute_equal("v_one"), 2);
490 ASSERT_THAT(variable->retrieve("three"), StrEq("two"));
491 ASSERT_GE(variable->find("one"), 0);
492 BEGIN_HIDE_OUTPUT();
493 command("next one");
494 command("next three");
495 END_HIDE_OUTPUT();
496 // index style variable is deleted if no more next element
497 ASSERT_EQ(variable->find("one"), -1);
498 ASSERT_GE(variable->find("three"), 0);
499 BEGIN_HIDE_OUTPUT();
500 command("next three");
501 command("next three");
502 command("next three");
503 END_HIDE_OUTPUT();
504 // file style variable is deleted if no more next element
505 ASSERT_EQ(variable->find("three"), -1);
506
507 TEST_FAILURE(".*ERROR: Illegal next command.*", command("next"););
508 TEST_FAILURE(".*ERROR: Invalid variable 'xxx' in next command.*", command("next xxx"););
509 TEST_FAILURE(".*ERROR: Invalid variable style with next command.*", command("next two"););
510 TEST_FAILURE(".*ERROR: All variables in next command must have same style.*",
511 command("next five four"););
512 }
513 } // namespace LAMMPS_NS
514
main(int argc,char ** argv)515 int main(int argc, char **argv)
516 {
517 MPI_Init(&argc, &argv);
518 ::testing::InitGoogleMock(&argc, argv);
519
520 if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
521 std::cout << "Warning: using OpenMPI without exceptions. "
522 "Death tests will be skipped\n";
523
524 // handle arguments passed via environment variable
525 if (const char *var = getenv("TEST_ARGS")) {
526 std::vector<std::string> env = split_words(var);
527 for (auto arg : env) {
528 if (arg == "-v") {
529 verbose = true;
530 }
531 }
532 }
533
534 if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true;
535
536 int rv = RUN_ALL_TESTS();
537 MPI_Finalize();
538 return rv;
539 }
540