Moved generic simulationdatabase code to testutils.
[gromacs.git] / src / testutils / refdata.h
blobc1040949d737bc54c3b04bcad96b24f78b19fe5e
1 /*
2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2011,2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
35 /*! \libinternal \file
36 * \brief
37 * Functionality for writing tests that can produce their own reference data.
39 * See \ref page_refdata for more details.
41 * \author Teemu Murtola <teemu.murtola@gmail.com>
42 * \inlibraryapi
43 * \ingroup module_testutils
45 #ifndef GMX_TESTUTILS_REFDATA_H
46 #define GMX_TESTUTILS_REFDATA_H
48 #include <iterator>
49 #include <memory>
50 #include <string>
52 #include "gromacs/utility/basedefinitions.h"
53 #include "gromacs/utility/classhelpers.h"
55 namespace gmx
58 class IOptionsContainer;
59 class KeyValueTreeObject;
60 class KeyValueTreeValue;
61 class Variant;
63 namespace test
66 class FloatingPointTolerance;
68 /*! \libinternal \brief
69 * Mode of operation for reference data handling.
71 * There should be no need to use this type outside the test utility module.
73 * \ingroup module_testutils
75 enum ReferenceDataMode
77 /*! \brief
78 * Compare to existing reference data.
80 * If reference data does not exist, or if the test results differ from
81 * those in the reference data, the test fails.
83 erefdataCompare,
84 /*! \brief
85 * Create missing reference data.
87 * If reference data does not exist for a test, that test behaves as if
88 * ::erefdataUpdateAll had been specified. Tests for which reference data
89 * exists, behave like with ::erefdataCompare.
91 erefdataCreateMissing,
92 /*! \brief
93 * Update reference data that does not pass comparison.
95 * Tests utilizing reference data should always pass in this mode unless
96 * there is an I/O error.
98 erefdataUpdateChanged,
99 /*! \brief
100 * Update reference data, overwriting old data.
102 * Tests utilizing reference data should always pass in this mode unless
103 * there is an I/O error.
105 erefdataUpdateAll
108 /*! \libinternal \brief
109 * Initializes reference data handling.
111 * Adds command-line options to \p options to set the reference data mode.
112 * By default, ::erefdataCompare is used, but ``--ref-data create`` or
113 * ``--ref-data update`` can be used to change it.
115 * This function is automatically called by initTestUtils().
117 * \ingroup module_testutils
119 void initReferenceData(IOptionsContainer *options);
121 class TestReferenceChecker;
123 namespace internal
125 class TestReferenceDataImpl;
128 /*! \libinternal \brief
129 * Handles creation of and comparison to test reference data.
131 * See \ref page_refdata for an overview of the functionality.
133 * This class provides functionality to use the same code to generate reference
134 * data and then on later runs compare the results of the code against that
135 * reference. The mode in which the class operates (writing reference data or
136 * comparing against existing data) is set using a command-line option that
137 * is automatically managed when using the testutils module to implement tests.
138 * Tests only need to create an instance of TestReferenceData, obtain a
139 * TestReferenceChecker using the rootChecker() method and use the various
140 * check*() methods in TestReferenceChecker to indicate values to check. If
141 * the test is running in reference data creation mode, it will produce an XML
142 * file with the values recorder. In comparison mode, it will read that same
143 * XML file and produce a Google Test non-fatal assertion for every discrepancy
144 * it detects with the reference data (including missing reference data file or
145 * individual item). Exceptions derived from TestException are thrown for I/O
146 * errors and syntax errors in the reference data.
148 * Simple example (using Google Test):
149 * \code
150 int functionToTest(int param);
152 TEST(MyTest, SimpleTest)
154 gmx::test::TestReferenceData data;
156 gmx::test::TestReferenceChecker checker(data.rootChecker());
157 checker.checkInteger(functionToTest(3), "ValueWith3");
158 checker.checkInteger(functionToTest(5), "ValueWith5");
159 gmx::test::TestReferenceChecker compound(
160 checker.checkCompound("CustomCompound", "Item"));
161 compound.checkInteger(function2ToTest(3), "ValueWith3");
162 compound.checkInteger(function2ToTest(5), "ValueWith5");
163 checker.checkInteger(functionToTest(4), "ValueWith4");
165 * \endcode
167 * If rootChecker() is never called, no comparison is done (i.e., missing
168 * reference data file is not reported as an error, nor is empty reference data
169 * file created in write mode).
171 * For floating-point comparisons, the reference data should be generated in
172 * double precision (currently, no warning is provided even if this is not the
173 * case, but the double precision tests will then very likely fail).
175 * \inlibraryapi
176 * \ingroup module_testutils
178 class TestReferenceData
180 public:
181 /*! \brief
182 * Initializes the reference data in the global mode.
184 TestReferenceData();
185 /*! \brief
186 * Initializes the reference data in a specific mode.
188 * This function is only useful for self-testing the reference data
189 * framework. As such, it also puts the framework in a state where it
190 * logs additional internal information for failures to help diagnosing
191 * problems in the framework, and stores the reference data in a
192 * temporary directory instead of the source tree.
193 * The default constructor should be used in tests utilizing this class.
195 explicit TestReferenceData(ReferenceDataMode mode);
196 /*! \brief
197 * Frees reference data structures.
199 * The reference data is written out if necessary automatically when
200 * the test finishes.
202 ~TestReferenceData();
204 /*! \brief
205 * Returns a root-level checker object for comparisons.
207 * Each call returns an independent instance.
209 TestReferenceChecker rootChecker();
211 private:
212 std::shared_ptr<internal::TestReferenceDataImpl> impl_;
214 GMX_DISALLOW_COPY_AND_ASSIGN(TestReferenceData);
217 /*! \libinternal \brief
218 * Handles comparison to test reference data.
220 * Every check*() method takes an id string as the last parameter. This id is
221 * used to uniquely identify the value in the reference data, and it makes the
222 * output XML more human-friendly and more robust to errors. The id can be
223 * NULL; in this case, multiple elements with no id are created, and they will
224 * be matched in the same order as in which they are created. The
225 * checkCompound() method can be used to create a set of reference values
226 * grouped together. In this case, all check*() calls using the returned child
227 * TestReferenceChecker object will create the reference data within this
228 * group, and the ids only need to be unique within the compound. Compounds
229 * can be nested.
231 * For usage example, see TestReferenceData.
233 * Copies of this class behave have independent internal state.
235 * \inlibraryapi
236 * \ingroup module_testutils
238 class TestReferenceChecker
240 public:
241 /*! \brief
242 * Creates a checker that cannot be used for checking.
244 * Attempting to call the check methods generates an assert.
245 * It is possible to check whether the checker is initialized by
246 * calling isValid().
247 * This constructor exists to allow declaring checker variables that
248 * will receive their value later without resorting to dynamic
249 * allocation.
251 TestReferenceChecker();
252 //! Creates a deep copy of the other checker.
253 explicit TestReferenceChecker(const TestReferenceChecker &other);
254 //! Moves the checker.
255 TestReferenceChecker(TestReferenceChecker &&other) noexcept;
256 ~TestReferenceChecker();
258 //! Prevents implicit copying during assignment.
259 TestReferenceChecker &operator=(const TestReferenceChecker &) = delete;
260 //! Assigns a test reference checker.
261 TestReferenceChecker &operator=(TestReferenceChecker &&other) noexcept;
263 //! Returns whether the checker is initialized.
264 bool isValid() const;
265 //! Allows testing whether the checker is initialized directly with if.
266 explicit operator bool() const { return isValid(); }
268 /*! \brief
269 * Sets the tolerance for floating-point comparisons.
271 * All following floating-point comparisons using this checker will use
272 * the new tolerance. Child checkers created with checkCompound()
273 * will inherit the tolerance from their parent checker at the time
274 * checkCompound() is called.
276 * Does not throw.
278 void setDefaultTolerance(const FloatingPointTolerance &tolerance);
280 /*! \brief
281 * Checks that all reference values have been compared against.
283 * All values under the compound represented by this checker are
284 * checked, and a non-fatal Google Test assertion is produced if some
285 * values have not been used.
287 * If not called explicitly, the same check will be done for all
288 * reference data values when the test ends.
290 * This method also marks the values used, so that subsequent checks
291 * (including the check at the end of the test) will not produce
292 * another assertion about the same values.
294 void checkUnusedEntries();
296 /*! \brief
297 * Checks whether a data item is present.
299 * \param[in] bPresent Whether to check for presence or absence.
300 * \param[in] id Unique identifier of the item to check.
301 * \returns true if bPresent was true and the data item was found.
303 * If \p bPresent is true, checks that a data item with \p id is
304 * present, otherwise checks that the data item is absent.
305 * If the check fails, a non-fatal Google Test assertion is generated.
307 * If reference data is being written, the check always succeeds and the
308 * return value is \p bPresent.
310 * The main use of this method is to assign meaning for missing
311 * reference data. Example use:
312 * \code
313 if (checker.checkPresent(bHaveVelocities, "Velocities"))
315 // <check the velocities>
317 * \endcode
319 bool checkPresent(bool bPresent, const char *id);
321 /*! \brief
322 * Initializes comparison of a group of related data items.
324 * \param[in] type Informational type for the compound.
325 * \param[in] id Unique identifier for the compound among its
326 * siblings.
327 * \returns Checker to use for comparison within the compound.
329 * All checks performed with the returned checker only
330 * need to have unique ids within the compound, not globally.
332 * Compound structures can be nested.
334 TestReferenceChecker checkCompound(const char *type, const char *id);
335 //! \copydoc checkCompound(const char *, const char *)
336 TestReferenceChecker checkCompound(const char *type, const std::string &id);
338 //! Check a single boolean value.
339 void checkBoolean(bool value, const char *id);
340 //! Check a single string value.
341 void checkString(const char *value, const char *id);
342 //! Check a single string value.
343 void checkString(const std::string &value, const char *id);
344 /*! \brief
345 * Check a multi-line string value.
347 * This method works as checkString(), but should be used for long
348 * strings that may contain, e.g., newlines. Typically used to check
349 * formatted output, and attempts to make the output XML such that it
350 * is easier to edit by hand to set the desired output formatting.
352 void checkTextBlock(const std::string &value, const char *id);
353 //! Check a single unsigned char value.
354 void checkUChar(unsigned char value, const char *id);
355 //! Check a single integer value.
356 void checkInteger(int value, const char *id);
357 //! Check a single int64 value.
358 void checkInt64(int64_t value, const char *id);
359 //! Check a single uint64 value.
360 void checkUInt64(uint64_t value, const char *id);
361 //! Check a single single-precision floating point value.
362 void checkFloat(float value, const char *id);
363 //! Check a single double-precision floating point value.
364 void checkDouble(double value, const char *id);
365 //! Check a single floating point value.
366 void checkReal(float value, const char *id);
367 //! Check a single floating point value.
368 void checkReal(double value, const char *id);
369 //! Check a vector of three integer values.
370 void checkVector(const int value[3], const char *id);
371 //! Check a vector of three single-precision floating point values.
372 void checkVector(const float value[3], const char *id);
373 //! Check a vector of three double-precision floating point values.
374 void checkVector(const double value[3], const char *id);
375 //! Check a single floating-point value from a string.
376 void checkRealFromString(const std::string &value, const char *id);
377 //! Checks a variant value that contains a supported simple type.
378 void checkVariant(const Variant &value, const char *id);
379 //! Checks a key-value tree rooted at a object.
380 void checkKeyValueTreeObject(const KeyValueTreeObject &tree, const char *id);
381 //! Checks a generic key-value tree value.
382 void checkKeyValueTreeValue(const KeyValueTreeValue &value, const char *id);
384 /*! \name Methods to read values from reference data
386 * These methods assume that a value with the given `id` has already
387 * been created in the test with `check*()` methods, and that it has
388 * the correct type.
390 * Currently, these methods do not work correctly if the reference data
391 * file does not exist, so a test using them may fail with exceptions
392 * before the reference data has been generated.
393 * \{
395 //! Reads an unsigned char value.
396 unsigned char readUChar(const char *id);
397 //! Reads an integer value.
398 int readInteger(const char *id);
399 //! Reads a 64-bit integer value.
400 int64_t readInt64(const char *id);
401 //! Reads a float value.
402 float readFloat(const char *id);
403 //! Reads a double value.
404 double readDouble(const char *id);
405 //! Reads a string value.
406 std::string readString(const char *id);
407 //! \}
409 /*! \name Overloaded versions of simple checker methods
411 * These methods provide overloads under a single name for all the
412 * methods checkBoolean(), checkString(), checkReal() and checkVector().
413 * They are provided mainly to allow template implementations (such as
414 * checkSequence()). Typically callers should use the individually
415 * named versions for greater clarity.
416 * \{
418 //! Check a single boolean value.
419 void checkValue(bool value, const char *id)
421 checkBoolean(value, id);
423 //! Check a single string value.
424 void checkValue(const char *value, const char *id)
426 checkString(value, id);
428 //! Check a single string value.
429 void checkValue(const std::string &value, const char *id)
431 checkString(value, id);
433 //! Check a single integer value.
434 void checkValue(int value, const char *id)
436 checkInteger(value, id);
438 //! Check a single integer value.
439 void checkValue(int64_t value, const char *id)
441 checkInt64(value, id);
443 //! Check a single integer value.
444 void checkValue(uint64_t value, const char *id)
446 checkUInt64(value, id);
448 //! Check a single single-precision floating point value.
449 void checkValue(float value, const char *id)
451 checkFloat(value, id);
453 //! Check a single double-precision floating point value.
454 void checkValue(double value, const char *id)
456 checkDouble(value, id);
458 //! Check a vector of three integer values.
459 void checkValue(const int value[3], const char *id)
461 checkVector(value, id);
463 //! Check a vector of three single-precision floating point values.
464 void checkValue(const float value[3], const char *id)
466 checkVector(value, id);
468 //! Check a vector of three double-precision floating point values.
469 void checkValue(const double value[3], const char *id)
471 checkVector(value, id);
473 //! Check a generic key-value tree value.
474 void checkValue(const KeyValueTreeValue &value, const char *id)
476 checkKeyValueTreeValue(value, id);
478 /*!\}*/
480 /*! \brief
481 * Generic method to check a sequence of simple values.
483 * \tparam Iterator Input iterator that allows multiple (two) passes.
484 * Value type must be one of those accepted by checkValue(), or
485 * implicitly convertible to one.
486 * \param[in] begin Iterator to the start of the range to check.
487 * \param[in] end Iterator to the end of the range to check.
488 * \param[in] id Unique identifier for the sequence among its
489 * siblings.
491 template <class Iterator>
492 void checkSequence(Iterator begin, Iterator end, const char *id)
494 typename std::iterator_traits<Iterator>::difference_type length
495 = std::distance(begin, end);
496 TestReferenceChecker compound(checkSequenceCompound(id, length));
497 for (Iterator i = begin; i != end; ++i)
499 compound.checkValue(*i, nullptr);
502 /*! \brief
503 * Generic method to check a sequence of custom values.
505 * \tparam Iterator Input iterator that allows multiple (two) passes.
506 * \tparam ItemChecker Functor to check an individual value. Signature
507 * void(TestReferenceChecker *, const T &), where T is the value
508 * type of \p Iterator.
509 * \param[in] begin Iterator to the start of the range to check.
510 * \param[in] end Iterator to the end of the range to check.
511 * \param[in] id Unique identifier for the sequence among its
512 * siblings.
513 * \param[in] checkItem Functor to check an individual item.
515 * This method creates a compound checker \c compound within which all
516 * values of the sequence are checked. Calls \c checkItem(&compound, *i)
517 * with that compound for each iterator \c i in the range [begin, end).
518 * \p checkItem should use the various check methods in the passed
519 * checker to check each value.
521 * This method can be used to check a sequence made of compound types.
522 * Typically \p checkItem will create a compound within the passed
523 * checker to check different aspects of the value that was passed
524 * to it. Either NULL or a unique identifier string must be used for
525 * the id value of that compound. */
526 template <class Iterator, class ItemChecker>
527 void checkSequence(Iterator begin, Iterator end, const char *id,
528 ItemChecker checkItem)
530 typename std::iterator_traits<Iterator>::difference_type length
531 = std::distance(begin, end);
532 TestReferenceChecker compound(checkSequenceCompound(id, length));
533 for (Iterator i = begin; i != end; ++i)
535 checkItem(&compound, *i);
538 /*! \brief
539 * Check an array of values.
541 * \tparam T Type of values to check. Should be one of those accepted
542 * by checkValue(), or implicitly convertible to one.
544 * \param[in] length Number of values to check.
545 * \param[in] values Pointer to the first value to check.
546 * \param[in] id Unique identifier for the sequence among its
547 * siblings.
549 * This is a convenience method that delegates all work to
550 * checkSequence().
552 template <typename T>
553 void checkSequenceArray(size_t length, const T *values, const char *id)
555 checkSequence(values, values + length, id);
557 /*! \brief
558 * Convenience method for checking that a sequence is empty.
560 * \param[in] id Unique identifier for the sequence among its
561 * siblings.
563 * This method provides a convenient solution for a case where there is
564 * implicitly a sequence to be checked, but there is no pointer
565 * available to the values since the sequence is empty.
566 * Since this method does not require the type of the values, it can be
567 * used in such cases easily.
569 void checkEmptySequence(const char *id);
570 /*! \brief
571 * Initializes a compound for a sequence of items.
573 * \param[in] id Unique identifier for the sequence among its
574 * siblings.
575 * \param[in] length Number of items that will be in the sequence.
576 * \returns Checker to use for comparison within the sequence.
578 * This method can be used to check custom sequences where
579 * checkSequence() is not appropriate.
581 TestReferenceChecker checkSequenceCompound(const char *id, size_t length);
583 private:
584 class Impl;
586 /*! \brief
587 * Constructs a checker with a specific internal state.
589 * Is private to only allow users of this class to create instances
590 * using TestReferenceData::rootChecker() or checkCompound()
591 * (or by copying).
593 explicit TestReferenceChecker(Impl *impl);
595 PrivateImplPointer<Impl> impl_;
597 /*! \brief
598 * Needed to expose the constructor only to TestReferenceData.
600 friend class TestReferenceData;
603 } // namespace test
604 } // namespace gmx
606 #endif