Compare trajectories to reference data
[alexxy/gromacs.git] / src / testutils / refdata.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
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.
9  *
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.
14  *
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.
19  *
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.
24  *
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.
32  *
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.
35  */
36 /*! \libinternal \file
37  * \brief
38  * Functionality for writing tests that can produce their own reference data.
39  *
40  * See \ref page_refdata for more details.
41  *
42  * \author Teemu Murtola <teemu.murtola@gmail.com>
43  * \inlibraryapi
44  * \ingroup module_testutils
45  */
46 #ifndef GMX_TESTUTILS_REFDATA_H
47 #define GMX_TESTUTILS_REFDATA_H
48
49 #include <iterator>
50 #include <memory>
51 #include <string>
52
53 #include "gromacs/utility/basedefinitions.h"
54 #include "gromacs/utility/classhelpers.h"
55
56 namespace gmx
57 {
58
59 class IOptionsContainer;
60 class KeyValueTreeObject;
61 class KeyValueTreeValue;
62 class Any;
63
64 template<typename ValueType>
65 class BasicVector;
66
67 namespace test
68 {
69
70 class FloatingPointTolerance;
71
72 /*! \libinternal \brief
73  * Mode of operation for reference data handling.
74  *
75  * There should be no need to use this type outside the test utility module.
76  *
77  * \ingroup module_testutils
78  */
79 enum class ReferenceDataMode : int
80 {
81     /*! \brief
82      * Compare to existing reference data.
83      *
84      * If reference data does not exist, or if the test results differ from
85      * those in the reference data, the test fails.
86      */
87     Compare,
88     /*! \brief
89      * Create missing reference data.
90      *
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.
94      */
95     CreateMissing,
96     /*! \brief
97      * Update reference data that does not pass comparison.
98      *
99      * Tests utilizing reference data should always pass in this mode unless
100      * there is an I/O error.
101      */
102     UpdateChanged,
103     /*! \brief
104      * Update reference data, overwriting old data.
105      *
106      * Tests utilizing reference data should always pass in this mode unless
107      * there is an I/O error.
108      */
109     UpdateAll,
110     //! Marks the end of the enum
111     Count
112 };
113
114 /*! \libinternal \brief
115  * Initializes reference data handling.
116  *
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.
120  *
121  * This function is automatically called by initTestUtils().
122  *
123  * \ingroup module_testutils
124  */
125 void initReferenceData(IOptionsContainer* options);
126
127 class TestReferenceChecker;
128
129 namespace internal
130 {
131 class TestReferenceDataImpl;
132 }
133
134 /*! \libinternal \brief
135  * Handles creation of and comparison to test reference data.
136  *
137  * See \ref page_refdata for an overview of the functionality.
138  *
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.
153  *
154  * Simple example (using Google Test):
155  * \code
156    int functionToTest(int param);
157
158    namespace gmx
159    {
160    namespace test
161    {
162    TEST(MyTest, SimpleTest)
163    {
164        TestReferenceData data;
165
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");
175    }
176    } // namespace test
177    } // namespace gmx
178  * \endcode
179  *
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).
183  *
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).
187  *
188  * \inlibraryapi
189  * \ingroup module_testutils
190  */
191 class TestReferenceData
192 {
193 public:
194     /*! \brief
195      * Initializes the reference data in the global mode.
196      */
197     TestReferenceData();
198     /*! \brief
199      * Initializes the reference data in a specific mode.
200      *
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.
207      */
208     explicit TestReferenceData(ReferenceDataMode mode);
209     /*! \brief
210      * Frees reference data structures.
211      *
212      * The reference data is written out if necessary automatically when
213      * the test finishes.
214      */
215     ~TestReferenceData();
216
217     /*! \brief
218      * Returns a root-level checker object for comparisons.
219      *
220      * Each call returns an independent instance.
221      */
222     TestReferenceChecker rootChecker();
223
224 private:
225     std::shared_ptr<internal::TestReferenceDataImpl> impl_;
226
227     GMX_DISALLOW_COPY_AND_ASSIGN(TestReferenceData);
228 };
229
230 /*! \libinternal \brief
231  * Handles comparison to test reference data.
232  *
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
242  * can be nested.
243  *
244  * For usage example, see TestReferenceData.
245  *
246  * Copies of this class behave have independent internal state.
247  *
248  * \inlibraryapi
249  * \ingroup module_testutils
250  */
251 class TestReferenceChecker
252 {
253 public:
254     /*! \brief
255      * Creates a checker that cannot be used for checking.
256      *
257      * Attempting to call the check methods generates an assert.
258      * It is possible to check whether the checker is initialized by
259      * calling isValid().
260      * This constructor exists to allow declaring checker variables that
261      * will receive their value later without resorting to dynamic
262      * allocation.
263      */
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();
270
271     //! Prevents implicit copying during assignment.
272     TestReferenceChecker& operator=(const TestReferenceChecker&) = delete;
273     //! Assigns a test reference checker.
274     TestReferenceChecker& operator=(TestReferenceChecker&& other) noexcept;
275
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(); }
280
281     /*! \brief
282      * Sets the tolerance for floating-point comparisons.
283      *
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.
288      *
289      * Does not throw.
290      */
291     void setDefaultTolerance(const FloatingPointTolerance& tolerance);
292
293     /*! \brief
294      * Checks that all reference values have been compared against.
295      *
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.
299      *
300      * If not called explicitly, the same check will be done for all
301      * reference data values when the test ends.
302      *
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.
306      */
307     void checkUnusedEntries();
308
309     /*! \brief Disables checking for unused entries
310      *
311      * \see checkUnusedEntries()
312      */
313     void disableUnusedEntriesCheck();
314
315     /*! \brief
316      * Checks whether a data item is present.
317      *
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.
321      *
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.
325      *
326      * If reference data is being written, the check always succeeds and the
327      * return value is \p bPresent.
328      *
329      * The main use of this method is to assign meaning for missing
330      * reference data.  Example use:
331      * \code
332        if (checker.checkPresent(bHaveVelocities, "Velocities"))
333        {
334            // <check the velocities>
335        }
336      * \endcode
337      */
338     bool checkPresent(bool bPresent, const char* id);
339
340     /*! \brief
341      * Initializes comparison of a group of related data items.
342      *
343      * \param[in] type Informational type for the compound.
344      * \param[in] id   Unique identifier for the compound among its
345      *                 siblings.
346      * \returns   Checker to use for comparison within the compound.
347      *
348      * All checks performed with the returned checker only
349      * need to have unique ids within the compound, not globally.
350      *
351      * Compound structures can be nested.
352      */
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);
356
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);
363     /*! \brief
364      * Check a multi-line string value.
365      *
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.
370      */
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);
412
413     /*! \name Methods to read values from reference data
414      *
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
417      * the correct type.
418      *
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.
422      * \{
423      */
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);
438     //! \}
439
440     /*! \name Overloaded versions of simple checker methods
441      *
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.
447      * \{
448      */
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)
479     {
480         checkKeyValueTreeValue(value, id);
481     }
482     /*!\}*/
483
484     /*! \brief
485      * Generic method to check a sequence of simple values.
486      *
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
493      *                   siblings.
494      */
495     template<class Iterator>
496     void checkSequence(Iterator begin, Iterator end, const char* id)
497     {
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)
501         {
502             compound.checkValue(*i, nullptr);
503         }
504     }
505     /*! \brief
506      * Generic method to check a sequence of custom values.
507      *
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
515      *                   siblings.
516      * \param[in] checkItem  Functor to check an individual item.
517      *
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.
523      *
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)
531     {
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)
535         {
536             checkItem(&compound, *i);
537         }
538     }
539     /*! \brief
540      * Check an array of values.
541      *
542      * \tparam T  Type of values to check. Should be one of those accepted
543      *      by checkValue(), or implicitly convertible to one.
544      *
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
548      *                   siblings.
549      *
550      * This is a convenience method that delegates all work to
551      * checkSequence().
552      */
553     template<typename T>
554     void checkSequenceArray(size_t length, const T* values, const char* id)
555     {
556         checkSequence(values, values + length, id);
557     }
558     /*! \brief
559      * Convenience method for checking that a sequence is empty.
560      *
561      * \param[in] id     Unique identifier for the sequence among its
562      *                   siblings.
563      *
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.
569      */
570     void checkEmptySequence(const char* id);
571     /*! \brief
572      * Initializes a compound for a sequence of items.
573      *
574      * \param[in] id     Unique identifier for the sequence among its
575      *                   siblings.
576      * \param[in] length Number of items that will be in the sequence.
577      * \returns   Checker to use for comparison within the sequence.
578      *
579      * This method can be used to check custom sequences where
580      * checkSequence() is not appropriate.
581      */
582     TestReferenceChecker checkSequenceCompound(const char* id, size_t length);
583
584 private:
585     class Impl;
586
587     /*! \brief
588      * Constructs a checker with a specific internal state.
589      *
590      * Is private to only allow users of this class to create instances
591      * using TestReferenceData::rootChecker() or checkCompound()
592      * (or by copying).
593      */
594     explicit TestReferenceChecker(Impl* impl);
595
596     PrivateImplPointer<Impl> impl_;
597
598     /*! \brief
599      * Needed to expose the constructor only to TestReferenceData.
600      */
601     friend class TestReferenceData;
602 };
603
604 } // namespace test
605 } // namespace gmx
606
607 #endif