Minor clean up for refdata.*
[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, 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  * \author Teemu Murtola <teemu.murtola@gmail.com>
40  * \inlibraryapi
41  * \ingroup module_testutils
42  */
43 #ifndef GMX_TESTUTILS_REFDATA_H
44 #define GMX_TESTUTILS_REFDATA_H
45
46 #include <iterator>
47 #include <string>
48
49 #include "gromacs/utility/basedefinitions.h"
50 #include "gromacs/utility/classhelpers.h"
51
52 namespace gmx
53 {
54
55 class Options;
56
57 namespace test
58 {
59
60 class FloatingPointTolerance;
61
62 /*! \libinternal \brief
63  * Mode of operation for reference data handling.
64  *
65  * There should be no need to use this type outside the test utility module.
66  *
67  * \ingroup module_testutils
68  */
69 enum ReferenceDataMode
70 {
71     /*! \brief
72      * Compare to existing reference data.
73      *
74      * If reference data does not exist, or if the test results differ from
75      * those in the reference data, the test fails.
76      */
77     erefdataCompare,
78     /*! \brief
79      * Create missing reference data.
80      *
81      * If reference data does not exist for a test, that test behaves as if
82      * ::erefdataUpdateAll had been specified.  Tests for which reference data
83      * exists, behave like with ::erefdataCompare.
84      */
85     erefdataCreateMissing,
86     /*! \brief
87      * Update reference data, overwriting old data.
88      *
89      * Tests utilizing reference data should always pass in this mode unless
90      * there is an I/O error.
91      */
92     erefdataUpdateAll
93 };
94
95 /*! \libinternal \brief
96  * Initializes reference data handling.
97  *
98  * Adds command-line options to \p options to set the reference data mode.
99  * By default, ::erefdataCompare is used, but ``--ref-data create`` or
100  * ``--ref-data update`` can be used to change it.
101  *
102  * This function is automatically called by initTestUtils().
103  *
104  * \ingroup module_testutils
105  */
106 void initReferenceData(Options *options);
107
108 class TestReferenceChecker;
109
110 /*! \libinternal \brief
111  * Handles creation of and comparison to test reference data.
112  *
113  * This class provides functionality to use the same code to generate reference
114  * data and then on later runs compare the results of the code against that
115  * reference.  The mode in which the class operates (writing reference data or
116  * comparing against existing data) is set with parseReferenceDataArgs(), which
117  * is automatically called when using the testutils module to implement tests.
118  * Tests only need to create an instance of TestReferenceData, obtain a
119  * TestReferenceChecker using the rootChecker() method and use the various
120  * check*() methods in TestReferenceChecker to indicate values to check.  If
121  * the test is running in reference data creation mode, it will produce an XML
122  * file with the values recorder.  In comparison mode, it will read that same
123  * XML file and produce a Google Test non-fatal assertion for every discrepancy
124  * it detects with the reference data (including missing reference data file or
125  * individual item).  Exceptions derived from TestException are thrown for I/O
126  * errors and syntax errors in the reference data.
127  *
128  * Simple example (using Google Test):
129  * \code
130    int functionToTest(int param);
131
132    TEST(MyTest, SimpleTest)
133    {
134        gmx::test::TestReferenceData data;
135
136        gmx::test::TestReferenceChecker checker(data.rootChecker());
137        checker.checkInteger(functionToTest(3), "ValueWith3");
138        checker.checkInteger(functionToTest(5), "ValueWith5");
139        gmx::test::TestReferenceChecker compound(
140                checker.checkCompound("CustomCompound", "Item"));
141        compound.checkInteger(function2ToTest(3), "ValueWith3");
142        compound.checkInteger(function2ToTest(5), "ValueWith5");
143        checker.checkInteger(functionToTest(4), "ValueWith4");
144    }
145  * \endcode
146  *
147  * If rootChecker() is never called, no comparison is done (i.e., missing
148  * reference data file is not reported as an error, nor is empty reference data
149  * file created in write mode).
150  *
151  * For floating-point comparisons, the reference data should be generated in
152  * double precision (currently, no warning is provided even if this is not the
153  * case, but the double precision tests will then very likely fail).
154  *
155  * \inlibraryapi
156  * \ingroup module_testutils
157  */
158 class TestReferenceData
159 {
160     public:
161         /*! \brief
162          * Initializes the reference data in the global mode.
163          */
164         TestReferenceData();
165         /*! \brief
166          * Initializes the reference data in a specific mode.
167          *
168          * This function is only useful for self-testing the reference data
169          * framework.  As such, it also puts the framework in a state where it
170          * logs additional internal information for failures to help diagnosing
171          * problems in the framework, and stores the reference data in a
172          * temporary directory instead of the source tree.
173          * The default constructor should be used in tests utilizing this class.
174          */
175         explicit TestReferenceData(ReferenceDataMode mode);
176         /*! \brief
177          * Frees reference data structures.
178          *
179          * In the current implementation, this function writes the reference
180          * data out if necessary.
181          */
182         ~TestReferenceData();
183
184         //! Returns true if reference data is currently being written.
185         bool isWriteMode() const;
186
187         /*! \brief
188          * Returns a root-level checker object for comparisons.
189          *
190          * Each call returns an independent instance.
191          */
192         TestReferenceChecker rootChecker();
193
194     private:
195         class Impl;
196
197         PrivateImplPointer<Impl> impl_;
198 };
199
200 /*! \libinternal \brief
201  * Handles comparison to test reference data.
202  *
203  * Every check*() method takes an id string as the last parameter.  This id is
204  * used to uniquely identify the value in the reference data, and it makes the
205  * output XML more human-friendly and more robust to errors.  The id can be
206  * NULL; in this case, multiple elements with no id are created, and they will
207  * be matched in the same order as in which they are created.  The
208  * checkCompound() method can be used to create a set of reference values
209  * grouped together.  In this case, all check*() calls using the returned child
210  * TestReferenceChecker object will create the reference data within this
211  * group, and the ids only need to be unique within the compound.  Compounds
212  * can be nested.
213  *
214  * For usage example, see TestReferenceData.
215  *
216  * Copies of this class behave have independent internal state.
217  *
218  * \inlibraryapi
219  * \ingroup module_testutils
220  */
221 class TestReferenceChecker
222 {
223     public:
224         /*! \brief
225          * Creates a deep copy of the other checker.
226          */
227         TestReferenceChecker(const TestReferenceChecker &other);
228         ~TestReferenceChecker();
229
230         //! Assigns a test reference checker.
231         TestReferenceChecker &operator=(const TestReferenceChecker &other);
232
233         //! Returns true if reference data is currently being written.
234         bool isWriteMode() const;
235
236         /*! \brief
237          * Sets the tolerance for floating-point comparisons.
238          *
239          * All following floating-point comparisons using this checker will use
240          * the new tolerance.  Child checkers created with checkCompound()
241          * will inherit the tolerance from their parent checker at the time
242          * checkCompound() is called.
243          *
244          * Does not throw.
245          */
246         void setDefaultTolerance(const FloatingPointTolerance &tolerance);
247
248         /*! \brief
249          * Checks whether a data item is present.
250          *
251          * \param[in] bPresent  Whether to check for presence or absence.
252          * \param[in] id        Unique identifier of the item to check.
253          * \returns   true if bPresent was true and the data item was found.
254          *
255          * If \p bPresent is true, checks that a data item with \p id is
256          * present, otherwise checks that the data item is absent.
257          * If the check fails, a non-fatal Google Test assertion is generated.
258          *
259          * If isWriteMode() returns true, the check always succeeds and the
260          * return value is \p bPresent.
261          *
262          * The main use of this method is to assign meaning for missing
263          * reference data.  Example use:
264          * \code
265            if (checker.checkPresent(bHaveVelocities, "Velocities"))
266            {
267                // <check the velocities>
268            }
269          * \endcode
270          */
271         bool checkPresent(bool bPresent, const char *id);
272
273         /*! \brief
274          * Initializes comparison of a group of related data items.
275          *
276          * \param[in] type Informational type for the compound.
277          * \param[in] id   Unique identifier for the compound among its
278          *                 siblings.
279          * \returns   Checker to use for comparison within the compound.
280          *
281          * All checks performed with the returned checker only
282          * need to have unique ids within the compound, not globally.
283          *
284          * Compound structures can be nested.
285          */
286         TestReferenceChecker checkCompound(const char *type, const char *id);
287
288         //! Check a single boolean value.
289         void checkBoolean(bool value, const char *id);
290         //! Check a single string value.
291         void checkString(const char *value, const char *id);
292         //! Check a single string value.
293         void checkString(const std::string &value, const char *id);
294         /*! \brief
295          * Check a multi-line string value.
296          *
297          * This method works as checkString(), but should be used for long
298          * strings that may contain, e.g., newlines.  Typically used to check
299          * formatted output, and attempts to make the output XML such that it
300          * is easier to edit by hand to set the desired output formatting.
301          */
302         void checkStringBlock(const std::string &value, const char *id);
303         //! Check a single integer value.
304         void checkInteger(int value, const char *id);
305         //! Check a single int64 value.
306         void checkInt64(gmx_int64_t value, const char *id);
307         //! Check a single uint64 value.
308         void checkUInt64(gmx_uint64_t value, const char *id);
309         //! Check a single single-precision floating point value.
310         void checkFloat(float value, const char *id);
311         //! Check a single double-precision floating point value.
312         void checkDouble(double value, const char *id);
313         //! Check a single floating point value.
314         void checkReal(float value, const char *id);
315         //! Check a single floating point value.
316         void checkReal(double value, const char *id);
317         //! Check a vector of three integer values.
318         void checkVector(const int value[3], const char *id);
319         //! Check a vector of three single-precision floating point values.
320         void checkVector(const float value[3], const char *id);
321         //! Check a vector of three double-precision floating point values.
322         void checkVector(const double value[3], const char *id);
323
324         /*! \name Overloaded versions of simple checker methods
325          *
326          * These methods provide overloads under a single name for all the
327          * methods checkBoolean(), checkString(), checkReal() and checkVector().
328          * They are provided mainly to allow template implementations (such as
329          * checkSequence()).  Typically callers should use the individually
330          * named versions for greater clarity.
331          * \{
332          */
333         //! Check a single boolean value.
334         void checkValue(bool value, const char *id)
335         {
336             checkBoolean(value, id);
337         }
338         //! Check a single string value.
339         void checkValue(const char *value, const char *id)
340         {
341             checkString(value, id);
342         }
343         //! Check a single string value.
344         void checkValue(const std::string &value, const char *id)
345         {
346             checkString(value, id);
347         }
348         //! Check a single integer value.
349         void checkValue(int value, const char *id)
350         {
351             checkInteger(value, id);
352         }
353         //! Check a single integer value.
354         void checkValue(gmx_int64_t value, const char *id)
355         {
356             checkInt64(value, id);
357         }
358         //! Check a single integer value.
359         void checkValue(gmx_uint64_t value, const char *id)
360         {
361             checkUInt64(value, id);
362         }
363         //! Check a single single-precision floating point value.
364         void checkValue(float value, const char *id)
365         {
366             checkFloat(value, id);
367         }
368         //! Check a single double-precision floating point value.
369         void checkValue(double value, const char *id)
370         {
371             checkDouble(value, id);
372         }
373         //! Check a vector of three integer values.
374         void checkValue(const int value[3], const char *id)
375         {
376             checkVector(value, id);
377         }
378         //! Check a vector of three single-precision floating point values.
379         void checkValue(const float value[3], const char *id)
380         {
381             checkVector(value, id);
382         }
383         //! Check a vector of three double-precision floating point values.
384         void checkValue(const double value[3], const char *id)
385         {
386             checkVector(value, id);
387         }
388         /*!\}*/
389
390         /*! \brief
391          * Generic method to check a sequence of simple values.
392          *
393          * \tparam Iterator  Input iterator that allows multiple (two) passes.
394          *      Value type must be one of those accepted by checkValue(), or
395          *      implicitly convertible to one.
396          * \param[in] begin  Iterator to the start of the range to check.
397          * \param[in] end    Iterator to the end of the range to check.
398          * \param[in] id     Unique identifier for the sequence among its
399          *                   siblings.
400          */
401         template <class Iterator>
402         void checkSequence(Iterator begin, Iterator end, const char *id)
403         {
404             typename std::iterator_traits<Iterator>::difference_type length
405                 = std::distance(begin, end);
406             TestReferenceChecker compound(checkSequenceCompound(id, length));
407             for (Iterator i = begin; i != end; ++i)
408             {
409                 compound.checkValue(*i, NULL);
410             }
411         }
412         /*! \brief
413          * Generic method to check a sequence of custom values.
414          *
415          * \tparam Iterator    Input iterator that allows multiple (two) passes.
416          * \tparam ItemChecker Functor to check an individual value. Signature
417          *      void(TestReferenceChecker *, const T &), where T is the value
418          *      type of \p Iterator.
419          * \param[in] begin  Iterator to the start of the range to check.
420          * \param[in] end    Iterator to the end of the range to check.
421          * \param[in] id     Unique identifier for the sequence among its
422          *                   siblings.
423          * \param[in] checkItem  Functor to check an individual item.
424          *
425          * This method creates a compound checker \c compound within which all
426          * values of the sequence are checked.  Calls \c checkItem(&compound, *i)
427          * with that compound for each iterator \c i in the range [begin, end).
428          * \p checkItem should use the various check methods in the passed
429          * checker to check each value.
430          *
431          * This method can be used to check a sequence made of compound types.
432          * Typically \p checkItem will create a compound within the passed
433          * checker to check different aspects of the passed in value.
434          */
435         template <class Iterator, class ItemChecker>
436         void checkSequence(Iterator begin, Iterator end, const char *id,
437                            ItemChecker checkItem)
438         {
439             typename std::iterator_traits<Iterator>::difference_type length
440                 = std::distance(begin, end);
441             TestReferenceChecker compound(checkSequenceCompound(id, length));
442             for (Iterator i = begin; i != end; ++i)
443             {
444                 checkItem(&compound, *i);
445             }
446         }
447         /*! \brief
448          * Check an array of values.
449          *
450          * \tparam T  Type of values to check. Should be one of those accepted
451          *      by checkValue(), or implicitly convertible to one.
452          *
453          * \param[in] length  Number of values to check.
454          * \param[in] values  Pointer to the first value to check.
455          * \param[in] id     Unique identifier for the sequence among its
456          *                   siblings.
457          *
458          * This is a convenience method that delegates all work to
459          * checkSequence().
460          */
461         template <typename T>
462         void checkSequenceArray(size_t length, const T *values, const char *id)
463         {
464             checkSequence(values, values + length, id);
465         }
466         /*! \brief
467          * Convenience method for checking that a sequence is empty.
468          *
469          * \param[in] id     Unique identifier for the sequence among its
470          *                   siblings.
471          *
472          * This method provides a convenient solution for a case where there is
473          * implicitly a sequence to be checked, but there is no pointer
474          * available to the values since the sequence is empty.
475          * Since this method does not require the type of the values, it can be
476          * used in such cases easily.
477          */
478         void checkEmptySequence(const char *id);
479         /*! \brief
480          * Initializes a compound for a sequence of items.
481          *
482          * \param[in] id     Unique identifier for the sequence among its
483          *                   siblings.
484          * \param[in] length Number of items that will be in the sequence.
485          * \returns   Checker to use for comparison within the sequence.
486          *
487          * This method can be used to check custom sequences where
488          * checkSequence() is not appropriate.
489          */
490         TestReferenceChecker checkSequenceCompound(const char *id, size_t length);
491
492     private:
493         class Impl;
494
495         /*! \brief
496          * Constructs a checker with a specific internal state.
497          *
498          * Is private to only allow users of this class to create instances
499          * using TestReferenceData::rootChecker() or checkCompound()
500          * (or by copying).
501          */
502         explicit TestReferenceChecker(Impl *impl);
503
504         PrivateImplPointer<Impl> impl_;
505
506         /*! \brief
507          * Needed to expose the constructor only to TestReferenceData.
508          */
509         friend class TestReferenceData;
510 };
511
512 } // namespace test
513 } // namespace gmx
514
515 #endif