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