Add support for serializing 32-bit integers
[alexxy/gromacs.git] / src / testutils / refdata.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2011,2012,2013,2014,2015,2016,2017,2018,2019, 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.
8  *
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.
13  *
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.
18  *
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.
23  *
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.
31  *
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.
34  */
35 /*! \libinternal \file
36  * \brief
37  * Functionality for writing tests that can produce their own reference data.
38  *
39  * See \ref page_refdata for more details.
40  *
41  * \author Teemu Murtola <teemu.murtola@gmail.com>
42  * \inlibraryapi
43  * \ingroup module_testutils
44  */
45 #ifndef GMX_TESTUTILS_REFDATA_H
46 #define GMX_TESTUTILS_REFDATA_H
47
48 #include <iterator>
49 #include <memory>
50 #include <string>
51
52 #include "gromacs/utility/basedefinitions.h"
53 #include "gromacs/utility/classhelpers.h"
54
55 namespace gmx
56 {
57
58 class IOptionsContainer;
59 class KeyValueTreeObject;
60 class KeyValueTreeValue;
61 class Any;
62
63 namespace test
64 {
65
66 class FloatingPointTolerance;
67
68 /*! \libinternal \brief
69  * Mode of operation for reference data handling.
70  *
71  * There should be no need to use this type outside the test utility module.
72  *
73  * \ingroup module_testutils
74  */
75 enum ReferenceDataMode
76 {
77     /*! \brief
78      * Compare to existing reference data.
79      *
80      * If reference data does not exist, or if the test results differ from
81      * those in the reference data, the test fails.
82      */
83     erefdataCompare,
84     /*! \brief
85      * Create missing reference data.
86      *
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.
90      */
91     erefdataCreateMissing,
92     /*! \brief
93      * Update reference data that does not pass comparison.
94      *
95      * Tests utilizing reference data should always pass in this mode unless
96      * there is an I/O error.
97      */
98     erefdataUpdateChanged,
99     /*! \brief
100      * Update reference data, overwriting old data.
101      *
102      * Tests utilizing reference data should always pass in this mode unless
103      * there is an I/O error.
104      */
105     erefdataUpdateAll
106 };
107
108 /*! \libinternal \brief
109  * Initializes reference data handling.
110  *
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.
114  *
115  * This function is automatically called by initTestUtils().
116  *
117  * \ingroup module_testutils
118  */
119 void initReferenceData(IOptionsContainer *options);
120
121 class TestReferenceChecker;
122
123 namespace internal
124 {
125 class TestReferenceDataImpl;
126 }
127
128 /*! \libinternal \brief
129  * Handles creation of and comparison to test reference data.
130  *
131  * See \ref page_refdata for an overview of the functionality.
132  *
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.
147  *
148  * Simple example (using Google Test):
149  * \code
150    int functionToTest(int param);
151
152    TEST(MyTest, SimpleTest)
153    {
154        gmx::test::TestReferenceData data;
155
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");
164    }
165  * \endcode
166  *
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).
170  *
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).
174  *
175  * \inlibraryapi
176  * \ingroup module_testutils
177  */
178 class TestReferenceData
179 {
180     public:
181         /*! \brief
182          * Initializes the reference data in the global mode.
183          */
184         TestReferenceData();
185         /*! \brief
186          * Initializes the reference data in a specific mode.
187          *
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.
194          */
195         explicit TestReferenceData(ReferenceDataMode mode);
196         /*! \brief
197          * Frees reference data structures.
198          *
199          * The reference data is written out if necessary automatically when
200          * the test finishes.
201          */
202         ~TestReferenceData();
203
204         /*! \brief
205          * Returns a root-level checker object for comparisons.
206          *
207          * Each call returns an independent instance.
208          */
209         TestReferenceChecker rootChecker();
210
211     private:
212         std::shared_ptr<internal::TestReferenceDataImpl> impl_;
213
214         GMX_DISALLOW_COPY_AND_ASSIGN(TestReferenceData);
215 };
216
217 /*! \libinternal \brief
218  * Handles comparison to test reference data.
219  *
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.
230  *
231  * For usage example, see TestReferenceData.
232  *
233  * Copies of this class behave have independent internal state.
234  *
235  * \inlibraryapi
236  * \ingroup module_testutils
237  */
238 class TestReferenceChecker
239 {
240     public:
241         /*! \brief
242          * Creates a checker that cannot be used for checking.
243          *
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.
250          */
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();
257
258         //! Prevents implicit copying during assignment.
259         TestReferenceChecker &operator=(const TestReferenceChecker &) = delete;
260         //! Assigns a test reference checker.
261         TestReferenceChecker &operator=(TestReferenceChecker &&other) noexcept;
262
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(); }
267
268         /*! \brief
269          * Sets the tolerance for floating-point comparisons.
270          *
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.
275          *
276          * Does not throw.
277          */
278         void setDefaultTolerance(const FloatingPointTolerance &tolerance);
279
280         /*! \brief
281          * Checks that all reference values have been compared against.
282          *
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.
286          *
287          * If not called explicitly, the same check will be done for all
288          * reference data values when the test ends.
289          *
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.
293          */
294         void checkUnusedEntries();
295
296         /*! \brief
297          * Checks whether a data item is present.
298          *
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.
302          *
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.
306          *
307          * If reference data is being written, the check always succeeds and the
308          * return value is \p bPresent.
309          *
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"))
314            {
315                // <check the velocities>
316            }
317          * \endcode
318          */
319         bool checkPresent(bool bPresent, const char *id);
320
321         /*! \brief
322          * Initializes comparison of a group of related data items.
323          *
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.
328          *
329          * All checks performed with the returned checker only
330          * need to have unique ids within the compound, not globally.
331          *
332          * Compound structures can be nested.
333          */
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);
337
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.
346          *
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.
351          */
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 int32 value.
358         void checkInt32(int32_t value, const char *id);
359         //! Check a single uint32 value.
360         void checkUInt32(uint32_t value, const char *id);
361         //! Check a single int64 value.
362         void checkInt64(int64_t value, const char *id);
363         //! Check a single uint64 value.
364         void checkUInt64(uint64_t value, const char *id);
365         //! Check a single single-precision floating point value.
366         void checkFloat(float value, const char *id);
367         //! Check a single double-precision floating point value.
368         void checkDouble(double value, const char *id);
369         //! Check a single floating point value.
370         void checkReal(float value, const char *id);
371         //! Check a single floating point value.
372         void checkReal(double value, const char *id);
373         //! Check a vector of three integer values.
374         void checkVector(const int value[3], const char *id);
375         //! Check a vector of three single-precision floating point values.
376         void checkVector(const float value[3], const char *id);
377         //! Check a vector of three double-precision floating point values.
378         void checkVector(const double value[3], const char *id);
379         //! Check a single floating-point value from a string.
380         void checkRealFromString(const std::string &value, const char *id);
381         //! Checks a any value that contains a supported simple type.
382         void checkAny(const Any &value, const char *id);
383         //! Checks a key-value tree rooted at a object.
384         void checkKeyValueTreeObject(const KeyValueTreeObject &tree, const char *id);
385         //! Checks a generic key-value tree value.
386         void checkKeyValueTreeValue(const KeyValueTreeValue &value, const char *id);
387
388         /*! \name Methods to read values from reference data
389          *
390          * These methods assume that a value with the given `id` has already
391          * been created in the test with `check*()` methods, and that it has
392          * the correct type.
393          *
394          * Currently, these methods do not work correctly if the reference data
395          * file does not exist, so a test using them may fail with exceptions
396          * before the reference data has been generated.
397          * \{
398          */
399         //! Reads an unsigned char value.
400         unsigned char readUChar(const char *id);
401         //! Reads an integer value.
402         int readInteger(const char *id);
403         //! Reads a 32-bit integer value.
404         int32_t readInt32(const char *id);
405         //! Reads a 64-bit integer value.
406         int64_t readInt64(const char *id);
407         //! Reads a float value.
408         float readFloat(const char *id);
409         //! Reads a double value.
410         double readDouble(const char *id);
411         //! Reads a string value.
412         std::string readString(const char *id);
413         //! \}
414
415         /*! \name Overloaded versions of simple checker methods
416          *
417          * These methods provide overloads under a single name for all the
418          * methods checkBoolean(), checkString(), checkReal() and checkVector().
419          * They are provided mainly to allow template implementations (such as
420          * checkSequence()).  Typically callers should use the individually
421          * named versions for greater clarity.
422          * \{
423          */
424         //! Check a single boolean value.
425         void checkValue(bool value, const char *id)
426         {
427             checkBoolean(value, id);
428         }
429         //! Check a single string value.
430         void checkValue(const char *value, const char *id)
431         {
432             checkString(value, id);
433         }
434         //! Check a single string value.
435         void checkValue(const std::string &value, const char *id)
436         {
437             checkString(value, id);
438         }
439         //! Check a single signed integer value
440         void checkValue(int value, const char *id)
441         {
442             checkInteger(value, id);
443         }
444         //! Check a single signed integer value of width 64 bits.
445         void checkValue(int64_t value, const char *id)
446         {
447             checkInt64(value, id);
448         }
449         //! Check a single unsigned integer value of width 64 bits.
450         void checkValue(uint64_t value, const char *id)
451         {
452             checkUInt64(value, id);
453         }
454         //! Check a single single-precision floating point value.
455         void checkValue(float value, const char *id)
456         {
457             checkFloat(value, id);
458         }
459         //! Check a single double-precision floating point value.
460         void checkValue(double value, const char *id)
461         {
462             checkDouble(value, id);
463         }
464         //! Check a vector of three integer values.
465         void checkValue(const int value[3], const char *id)
466         {
467             checkVector(value, id);
468         }
469         //! Check a vector of three single-precision floating point values.
470         void checkValue(const float value[3], const char *id)
471         {
472             checkVector(value, id);
473         }
474         //! Check a vector of three double-precision floating point values.
475         void checkValue(const double value[3], const char *id)
476         {
477             checkVector(value, id);
478         }
479         //! Check a generic key-value tree value.
480         void checkValue(const KeyValueTreeValue &value, const char *id)
481         {
482             checkKeyValueTreeValue(value, id);
483         }
484         /*!\}*/
485
486         /*! \brief
487          * Generic method to check a sequence of simple values.
488          *
489          * \tparam Iterator  Input iterator that allows multiple (two) passes.
490          *      Value type must be one of those accepted by checkValue(), or
491          *      implicitly convertible to one.
492          * \param[in] begin  Iterator to the start of the range to check.
493          * \param[in] end    Iterator to the end of the range to check.
494          * \param[in] id     Unique identifier for the sequence among its
495          *                   siblings.
496          */
497         template <class Iterator>
498         void checkSequence(Iterator begin, Iterator end, const char *id)
499         {
500             typename std::iterator_traits<Iterator>::difference_type length
501                 = std::distance(begin, end);
502             TestReferenceChecker compound(checkSequenceCompound(id, length));
503             for (Iterator i = begin; i != end; ++i)
504             {
505                 compound.checkValue(*i, nullptr);
506             }
507         }
508         /*! \brief
509          * Generic method to check a sequence of custom values.
510          *
511          * \tparam Iterator    Input iterator that allows multiple (two) passes.
512          * \tparam ItemChecker Functor to check an individual value. Signature
513          *      void(TestReferenceChecker *, const T &), where T is the value
514          *      type of \p Iterator.
515          * \param[in] begin  Iterator to the start of the range to check.
516          * \param[in] end    Iterator to the end of the range to check.
517          * \param[in] id     Unique identifier for the sequence among its
518          *                   siblings.
519          * \param[in] checkItem  Functor to check an individual item.
520          *
521          * This method creates a compound checker \c compound within which all
522          * values of the sequence are checked.  Calls \c checkItem(&compound, *i)
523          * with that compound for each iterator \c i in the range [begin, end).
524          * \p checkItem should use the various check methods in the passed
525          * checker to check each value.
526          *
527          * This method can be used to check a sequence made of compound types.
528          * Typically \p checkItem will create a compound within the passed
529          * checker to check different aspects of the value that was passed
530          * to it. Either NULL or a unique identifier string must be used for
531          * the id value of that compound. */
532         template <class Iterator, class ItemChecker>
533         void checkSequence(Iterator begin, Iterator end, const char *id,
534                            ItemChecker checkItem)
535         {
536             typename std::iterator_traits<Iterator>::difference_type length
537                 = std::distance(begin, end);
538             TestReferenceChecker compound(checkSequenceCompound(id, length));
539             for (Iterator i = begin; i != end; ++i)
540             {
541                 checkItem(&compound, *i);
542             }
543         }
544         /*! \brief
545          * Check an array of values.
546          *
547          * \tparam T  Type of values to check. Should be one of those accepted
548          *      by checkValue(), or implicitly convertible to one.
549          *
550          * \param[in] length  Number of values to check.
551          * \param[in] values  Pointer to the first value to check.
552          * \param[in] id     Unique identifier for the sequence among its
553          *                   siblings.
554          *
555          * This is a convenience method that delegates all work to
556          * checkSequence().
557          */
558         template <typename T>
559         void checkSequenceArray(size_t length, const T *values, const char *id)
560         {
561             checkSequence(values, values + length, id);
562         }
563         /*! \brief
564          * Convenience method for checking that a sequence is empty.
565          *
566          * \param[in] id     Unique identifier for the sequence among its
567          *                   siblings.
568          *
569          * This method provides a convenient solution for a case where there is
570          * implicitly a sequence to be checked, but there is no pointer
571          * available to the values since the sequence is empty.
572          * Since this method does not require the type of the values, it can be
573          * used in such cases easily.
574          */
575         void checkEmptySequence(const char *id);
576         /*! \brief
577          * Initializes a compound for a sequence of items.
578          *
579          * \param[in] id     Unique identifier for the sequence among its
580          *                   siblings.
581          * \param[in] length Number of items that will be in the sequence.
582          * \returns   Checker to use for comparison within the sequence.
583          *
584          * This method can be used to check custom sequences where
585          * checkSequence() is not appropriate.
586          */
587         TestReferenceChecker checkSequenceCompound(const char *id, size_t length);
588
589     private:
590         class Impl;
591
592         /*! \brief
593          * Constructs a checker with a specific internal state.
594          *
595          * Is private to only allow users of this class to create instances
596          * using TestReferenceData::rootChecker() or checkCompound()
597          * (or by copying).
598          */
599         explicit TestReferenceChecker(Impl *impl);
600
601         PrivateImplPointer<Impl> impl_;
602
603         /*! \brief
604          * Needed to expose the constructor only to TestReferenceData.
605          */
606         friend class TestReferenceData;
607 };
608
609 } // namespace test
610 } // namespace gmx
611
612 #endif