2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2011-2018, The GROMACS development team.
5 * Copyright (c) 2019,2020, by the GROMACS development team, led by
6 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
7 * and including many others, as listed in the AUTHORS file in the
8 * top-level source directory and at http://www.gromacs.org.
10 * GROMACS is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public License
12 * as published by the Free Software Foundation; either version 2.1
13 * of the License, or (at your option) any later version.
15 * GROMACS is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with GROMACS; if not, see
22 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
23 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 * If you want to redistribute modifications to GROMACS, please
26 * consider that scientific software is very special. Version
27 * control is crucial - bugs must be traceable. We will be happy to
28 * consider code for inclusion in the official distribution, but
29 * derived work must not be called official GROMACS. Details are found
30 * in the README & COPYING files - if they are missing, get the
31 * official version at http://www.gromacs.org.
33 * To help us fund GROMACS development, we humbly ask that you cite
34 * the research papers on the package. Check out http://www.gromacs.org.
36 /*! \libinternal \file
38 * Functionality for writing tests that can produce their own reference data.
40 * See \ref page_refdata for more details.
42 * \author Teemu Murtola <teemu.murtola@gmail.com>
44 * \ingroup module_testutils
46 #ifndef GMX_TESTUTILS_REFDATA_H
47 #define GMX_TESTUTILS_REFDATA_H
53 #include "gromacs/utility/basedefinitions.h"
54 #include "gromacs/utility/classhelpers.h"
59 class IOptionsContainer;
60 class KeyValueTreeObject;
61 class KeyValueTreeValue;
64 template<typename ValueType>
70 class FloatingPointTolerance;
72 /*! \libinternal \brief
73 * Mode of operation for reference data handling.
75 * There should be no need to use this type outside the test utility module.
77 * \ingroup module_testutils
79 enum class ReferenceDataMode : int
82 * Compare to existing reference data.
84 * If reference data does not exist, or if the test results differ from
85 * those in the reference data, the test fails.
89 * Create missing reference data.
91 * If reference data does not exist for a test, that test behaves as if
92 * ReferenceDataMode::UpdateAll had been specified. Tests for which reference data
93 * exists, behave like with ReferenceDataMode::Compare.
97 * Update reference data that does not pass comparison.
99 * Tests utilizing reference data should always pass in this mode unless
100 * there is an I/O error.
104 * Update reference data, overwriting old data.
106 * Tests utilizing reference data should always pass in this mode unless
107 * there is an I/O error.
110 //! Marks the end of the enum
114 /*! \libinternal \brief
115 * Initializes reference data handling.
117 * Adds command-line options to \p options to set the reference data mode.
118 * By default, ReferenceDataMode::Compare is used, but ``--ref-data create`` or
119 * ``--ref-data update`` can be used to change it.
121 * This function is automatically called by initTestUtils().
123 * \ingroup module_testutils
125 void initReferenceData(IOptionsContainer* options);
127 class TestReferenceChecker;
131 class TestReferenceDataImpl;
134 /*! \libinternal \brief
135 * Handles creation of and comparison to test reference data.
137 * See \ref page_refdata for an overview of the functionality.
139 * This class provides functionality to use the same code to generate reference
140 * data and then on later runs compare the results of the code against that
141 * reference. The mode in which the class operates (writing reference data or
142 * comparing against existing data) is set using a command-line option that
143 * is automatically managed when using the testutils module to implement tests.
144 * Tests only need to create an instance of TestReferenceData, obtain a
145 * TestReferenceChecker using the rootChecker() method and use the various
146 * check*() methods in TestReferenceChecker to indicate values to check. If
147 * the test is running in reference data creation mode, it will produce an XML
148 * file with the values recorder. In comparison mode, it will read that same
149 * XML file and produce a Google Test non-fatal assertion for every discrepancy
150 * it detects with the reference data (including missing reference data file or
151 * individual item). Exceptions derived from TestException are thrown for I/O
152 * errors and syntax errors in the reference data.
154 * Simple example (using Google Test):
156 int functionToTest(int param);
162 TEST(MyTest, SimpleTest)
164 TestReferenceData data;
166 TestReferenceChecker checker(data.rootChecker());
167 checker.checkInteger(functionToTest(3), "ValueWith3");
168 checker.checkInteger(functionToTest(5), "ValueWith5");
169 TestReferenceChecker compound(
170 checker.checkCompound("CustomCompound", "Item"));
171 compound.checkInteger(function2ToTest(3), "ValueWith3");
172 compound.checkInteger(function2ToTest(5), "ValueWith5");
173 checker.checkInteger(functionToTest(4), "ValueWith4");
174 checker.checkVector(functionProducingRVec(), "Describe The RVec");
180 * If rootChecker() is never called, no comparison is done (i.e., missing
181 * reference data file is not reported as an error, nor is empty reference data
182 * file created in write mode).
184 * For floating-point comparisons, the reference data should be generated in
185 * double precision (currently, no warning is provided even if this is not the
186 * case, but the double precision tests will then very likely fail).
189 * \ingroup module_testutils
191 class TestReferenceData
195 * Initializes the reference data in the global mode.
199 * Initializes the reference data in a specific mode.
201 * This function is only useful for self-testing the reference data
202 * framework. As such, it also puts the framework in a state where it
203 * logs additional internal information for failures to help diagnosing
204 * problems in the framework, and stores the reference data in a
205 * temporary directory instead of the source tree.
206 * The default constructor should be used in tests utilizing this class.
208 explicit TestReferenceData(ReferenceDataMode mode);
210 * Frees reference data structures.
212 * The reference data is written out if necessary automatically when
215 ~TestReferenceData();
218 * Returns a root-level checker object for comparisons.
220 * Each call returns an independent instance.
222 TestReferenceChecker rootChecker();
225 std::shared_ptr<internal::TestReferenceDataImpl> impl_;
227 GMX_DISALLOW_COPY_AND_ASSIGN(TestReferenceData);
230 /*! \libinternal \brief
231 * Handles comparison to test reference data.
233 * Every check*() method takes an id string as the last parameter. This id is
234 * used to uniquely identify the value in the reference data, and it makes the
235 * output XML more human-friendly and more robust to errors. The id can be
236 * NULL; in this case, multiple elements with no id are created, and they will
237 * be matched in the same order as in which they are created. The
238 * checkCompound() method can be used to create a set of reference values
239 * grouped together. In this case, all check*() calls using the returned child
240 * TestReferenceChecker object will create the reference data within this
241 * group, and the ids only need to be unique within the compound. Compounds
244 * For usage example, see TestReferenceData.
246 * Copies of this class behave have independent internal state.
249 * \ingroup module_testutils
251 class TestReferenceChecker
255 * Creates a checker that cannot be used for checking.
257 * Attempting to call the check methods generates an assert.
258 * It is possible to check whether the checker is initialized by
260 * This constructor exists to allow declaring checker variables that
261 * will receive their value later without resorting to dynamic
264 TestReferenceChecker();
265 //! Creates a deep copy of the other checker.
266 explicit TestReferenceChecker(const TestReferenceChecker& other);
267 //! Moves the checker.
268 TestReferenceChecker(TestReferenceChecker&& other) noexcept;
269 ~TestReferenceChecker();
271 //! Prevents implicit copying during assignment.
272 TestReferenceChecker& operator=(const TestReferenceChecker&) = delete;
273 //! Assigns a test reference checker.
274 TestReferenceChecker& operator=(TestReferenceChecker&& other) noexcept;
276 //! Returns whether the checker is initialized.
277 bool isValid() const;
278 //! Allows testing whether the checker is initialized directly with if.
279 explicit operator bool() const { return isValid(); }
282 * Sets the tolerance for floating-point comparisons.
284 * All following floating-point comparisons using this checker will use
285 * the new tolerance. Child checkers created with checkCompound()
286 * will inherit the tolerance from their parent checker at the time
287 * checkCompound() is called.
291 void setDefaultTolerance(const FloatingPointTolerance& tolerance);
294 * Checks that all reference values have been compared against.
296 * All values under the compound represented by this checker are
297 * checked, and a non-fatal Google Test assertion is produced if some
298 * values have not been used.
300 * If not called explicitly, the same check will be done for all
301 * reference data values when the test ends.
303 * This method also marks the values used, so that subsequent checks
304 * (including the check at the end of the test) will not produce
305 * another assertion about the same values.
307 void checkUnusedEntries();
309 /*! \brief Disables checking for unused entries
311 * \see checkUnusedEntries()
313 void disableUnusedEntriesCheck();
316 * Checks whether a data item is present.
318 * \param[in] bPresent Whether to check for presence or absence.
319 * \param[in] id Unique identifier of the item to check.
320 * \returns true if bPresent was true and the data item was found.
322 * If \p bPresent is true, checks that a data item with \p id is
323 * present, otherwise checks that the data item is absent.
324 * If the check fails, a non-fatal Google Test assertion is generated.
326 * If reference data is being written, the check always succeeds and the
327 * return value is \p bPresent.
329 * The main use of this method is to assign meaning for missing
330 * reference data. Example use:
332 if (checker.checkPresent(bHaveVelocities, "Velocities"))
334 // <check the velocities>
338 bool checkPresent(bool bPresent, const char* id);
341 * Initializes comparison of a group of related data items.
343 * \param[in] type Informational type for the compound.
344 * \param[in] id Unique identifier for the compound among its
346 * \returns Checker to use for comparison within the compound.
348 * All checks performed with the returned checker only
349 * need to have unique ids within the compound, not globally.
351 * Compound structures can be nested.
353 TestReferenceChecker checkCompound(const char* type, const char* id);
354 //! \copydoc checkCompound(const char *, const char *)
355 TestReferenceChecker checkCompound(const char* type, const std::string& id);
357 //! Check a single boolean value.
358 void checkBoolean(bool value, const char* id);
359 //! Check a single string value.
360 void checkString(const char* value, const char* id);
361 //! Check a single string value.
362 void checkString(const std::string& value, const char* id);
364 * Check a multi-line string value.
366 * This method works as checkString(), but should be used for long
367 * strings that may contain, e.g., newlines. Typically used to check
368 * formatted output, and attempts to make the output XML such that it
369 * is easier to edit by hand to set the desired output formatting.
371 void checkTextBlock(const std::string& value, const char* id);
372 //! Check a single unsigned char value.
373 void checkUChar(unsigned char value, const char* id);
374 //! Check a single integer value.
375 void checkInteger(int value, const char* id);
376 //! Check a single int32 value.
377 void checkInt32(int32_t value, const char* id);
378 //! Check a single uint32 value.
379 void checkUInt32(uint32_t value, const char* id);
380 //! Check a single int64 value.
381 void checkInt64(int64_t value, const char* id);
382 //! Check a single uint64 value.
383 void checkUInt64(uint64_t value, const char* id);
384 //! Check a single single-precision floating point value.
385 void checkFloat(float value, const char* id);
386 //! Check a single double-precision floating point value.
387 void checkDouble(double value, const char* id);
388 //! Check a single floating point value.
389 void checkReal(float value, const char* id);
390 //! Check a single floating point value.
391 void checkReal(double value, const char* id);
392 //! Check a vector of three integer values.
393 void checkVector(const int value[3], const char* id);
394 //! Check a vector of three single-precision floating point values.
395 void checkVector(const float value[3], const char* id);
396 //! Check a vector of three double-precision floating point values.
397 void checkVector(const double value[3], const char* id);
398 //! Check a BasicVector of ints, ie. IVec
399 void checkVector(const BasicVector<int>& value, const char* id);
400 //! Check a BasicVector of floats, ie. RVec
401 void checkVector(const BasicVector<float>& value, const char* id);
402 //! Check a BasicVector of doubles, ie. DVec
403 void checkVector(const BasicVector<double>& value, const char* id);
404 //! Check a single floating-point value from a string.
405 void checkRealFromString(const std::string& value, const char* id);
406 //! Checks a any value that contains a supported simple type.
407 void checkAny(const Any& value, const char* id);
408 //! Checks a key-value tree rooted at a object.
409 void checkKeyValueTreeObject(const KeyValueTreeObject& tree, const char* id);
410 //! Checks a generic key-value tree value.
411 void checkKeyValueTreeValue(const KeyValueTreeValue& value, const char* id);
413 /*! \name Methods to read values from reference data
415 * These methods assume that a value with the given `id` has already
416 * been created in the test with `check*()` methods, and that it has
419 * Currently, these methods do not work correctly if the reference data
420 * file does not exist, so a test using them may fail with exceptions
421 * before the reference data has been generated.
424 //! Reads an unsigned char value.
425 unsigned char readUChar(const char* id);
426 //! Reads an integer value.
427 int readInteger(const char* id);
428 //! Reads a 32-bit integer value.
429 int32_t readInt32(const char* id);
430 //! Reads a 64-bit integer value.
431 int64_t readInt64(const char* id);
432 //! Reads a float value.
433 float readFloat(const char* id);
434 //! Reads a double value.
435 double readDouble(const char* id);
436 //! Reads a string value.
437 std::string readString(const char* id);
440 /*! \name Overloaded versions of simple checker methods
442 * These methods provide overloads under a single name for all the
443 * methods checkBoolean(), checkString(), checkReal() and checkVector().
444 * They are provided mainly to allow template implementations (such as
445 * checkSequence()). Typically callers should use the individually
446 * named versions for greater clarity.
449 //! Check a single boolean value.
450 void checkValue(bool value, const char* id) { checkBoolean(value, id); }
451 //! Check a single string value.
452 void checkValue(const char* value, const char* id) { checkString(value, id); }
453 //! Check a single string value.
454 void checkValue(const std::string& value, const char* id) { checkString(value, id); }
455 //! Check a single signed integer value
456 void checkValue(int value, const char* id) { checkInteger(value, id); }
457 //! Check a single signed integer value of width 64 bits.
458 void checkValue(int64_t value, const char* id) { checkInt64(value, id); }
459 //! Check a single unsigned integer value of width 64 bits.
460 void checkValue(uint64_t value, const char* id) { checkUInt64(value, id); }
461 //! Check a single single-precision floating point value.
462 void checkValue(float value, const char* id) { checkFloat(value, id); }
463 //! Check a single double-precision floating point value.
464 void checkValue(double value, const char* id) { checkDouble(value, id); }
465 //! Check a vector of three integer values.
466 void checkValue(const int value[3], const char* id) { checkVector(value, id); }
467 //! Check a vector of three single-precision floating point values.
468 void checkValue(const float value[3], const char* id) { checkVector(value, id); }
469 //! Check a vector of three double-precision floating point values.
470 void checkValue(const double value[3], const char* id) { checkVector(value, id); }
471 //! Check a BasicVector of integer values, ie. IVec.
472 void checkValue(const BasicVector<int>& value, const char* id) { checkVector(value, id); }
473 //! Check a BasicVector of float values, ie. RVec.
474 void checkValue(const BasicVector<float>& value, const char* id) { checkVector(value, id); }
475 //! Check a BasicVector of double values, ie. DVec.
476 void checkValue(const BasicVector<double>& value, const char* id) { checkVector(value, id); }
477 //! Check a generic key-value tree value.
478 void checkValue(const KeyValueTreeValue& value, const char* id)
480 checkKeyValueTreeValue(value, id);
485 * Generic method to check a sequence of simple values.
487 * \tparam Iterator Input iterator that allows multiple (two) passes.
488 * Value type must be one of those accepted by checkValue(), or
489 * implicitly convertible to one.
490 * \param[in] begin Iterator to the start of the range to check.
491 * \param[in] end Iterator to the end of the range to check.
492 * \param[in] id Unique identifier for the sequence among its
495 template<class Iterator>
496 void checkSequence(Iterator begin, Iterator end, const char* id)
498 typename std::iterator_traits<Iterator>::difference_type length = std::distance(begin, end);
499 TestReferenceChecker compound(checkSequenceCompound(id, length));
500 for (Iterator i = begin; i != end; ++i)
502 compound.checkValue(*i, nullptr);
506 * Generic method to check a sequence of custom values.
508 * \tparam Iterator Input iterator that allows multiple (two) passes.
509 * \tparam ItemChecker Functor to check an individual value. Signature
510 * void(TestReferenceChecker *, const T &), where T is the value
511 * type of \p Iterator.
512 * \param[in] begin Iterator to the start of the range to check.
513 * \param[in] end Iterator to the end of the range to check.
514 * \param[in] id Unique identifier for the sequence among its
516 * \param[in] checkItem Functor to check an individual item.
518 * This method creates a compound checker \c compound within which all
519 * values of the sequence are checked. Calls \c checkItem(&compound, *i)
520 * with that compound for each iterator \c i in the range [begin, end).
521 * \p checkItem should use the various check methods in the passed
522 * checker to check each value.
524 * This method can be used to check a sequence made of compound types.
525 * Typically \p checkItem will create a compound within the passed
526 * checker to check different aspects of the value that was passed
527 * to it. Either NULL or a unique identifier string must be used for
528 * the id value of that compound. */
529 template<class Iterator, class ItemChecker>
530 void checkSequence(Iterator begin, Iterator end, const char* id, ItemChecker checkItem)
532 typename std::iterator_traits<Iterator>::difference_type length = std::distance(begin, end);
533 TestReferenceChecker compound(checkSequenceCompound(id, length));
534 for (Iterator i = begin; i != end; ++i)
536 checkItem(&compound, *i);
540 * Check an array of values.
542 * \tparam T Type of values to check. Should be one of those accepted
543 * by checkValue(), or implicitly convertible to one.
545 * \param[in] length Number of values to check.
546 * \param[in] values Pointer to the first value to check.
547 * \param[in] id Unique identifier for the sequence among its
550 * This is a convenience method that delegates all work to
554 void checkSequenceArray(size_t length, const T* values, const char* id)
556 checkSequence(values, values + length, id);
559 * Convenience method for checking that a sequence is empty.
561 * \param[in] id Unique identifier for the sequence among its
564 * This method provides a convenient solution for a case where there is
565 * implicitly a sequence to be checked, but there is no pointer
566 * available to the values since the sequence is empty.
567 * Since this method does not require the type of the values, it can be
568 * used in such cases easily.
570 void checkEmptySequence(const char* id);
572 * Initializes a compound for a sequence of items.
574 * \param[in] id Unique identifier for the sequence among its
576 * \param[in] length Number of items that will be in the sequence.
577 * \returns Checker to use for comparison within the sequence.
579 * This method can be used to check custom sequences where
580 * checkSequence() is not appropriate.
582 TestReferenceChecker checkSequenceCompound(const char* id, size_t length);
588 * Constructs a checker with a specific internal state.
590 * Is private to only allow users of this class to create instances
591 * using TestReferenceData::rootChecker() or checkCompound()
594 explicit TestReferenceChecker(Impl* impl);
596 PrivateImplPointer<Impl> impl_;
599 * Needed to expose the constructor only to TestReferenceData.
601 friend class TestReferenceData;