2 * This file is part of the GROMACS molecular simulation package.
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.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
35 /*! \libinternal \file
37 * Functionality for writing tests that can produce their own reference data.
39 * \author Teemu Murtola <teemu.murtola@gmail.com>
41 * \ingroup module_testutils
43 #ifndef GMX_TESTUTILS_REFDATA_H
44 #define GMX_TESTUTILS_REFDATA_H
49 #include "gromacs/utility/basedefinitions.h"
50 #include "gromacs/utility/classhelpers.h"
60 class FloatingPointTolerance
;
62 /*! \libinternal \brief
63 * Mode of operation for reference data handling.
65 * There should be no need to use this type outside the test utility module.
67 * \ingroup module_testutils
69 enum ReferenceDataMode
72 * Compare to existing reference data.
74 * If reference data does not exist, or if the test results differ from
75 * those in the reference data, the test fails.
79 * Create missing reference data.
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.
85 erefdataCreateMissing
,
87 * Update reference data, overwriting old data.
89 * Tests utilizing reference data should always pass in this mode unless
90 * there is an I/O error.
95 /*! \libinternal \brief
96 * Initializes reference data handling.
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.
102 * This function is automatically called by initTestUtils().
104 * \ingroup module_testutils
106 void initReferenceData(Options
*options
);
108 class TestReferenceChecker
;
110 /*! \libinternal \brief
111 * Handles creation of and comparison to test reference data.
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.
128 * Simple example (using Google Test):
130 int functionToTest(int param);
132 TEST(MyTest, SimpleTest)
134 gmx::test::TestReferenceData data;
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");
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).
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).
156 * \ingroup module_testutils
158 class TestReferenceData
162 * Initializes the reference data in the global mode.
166 * Initializes the reference data in a specific mode.
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.
175 explicit TestReferenceData(ReferenceDataMode mode
);
177 * Frees reference data structures.
179 * In the current implementation, this function writes the reference
180 * data out if necessary.
182 ~TestReferenceData();
184 //! Returns true if reference data is currently being written.
185 bool isWriteMode() const;
188 * Returns a root-level checker object for comparisons.
190 * Each call returns an independent instance.
192 TestReferenceChecker
rootChecker();
197 PrivateImplPointer
<Impl
> impl_
;
200 /*! \libinternal \brief
201 * Handles comparison to test reference data.
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
214 * For usage example, see TestReferenceData.
216 * Copies of this class behave have independent internal state.
219 * \ingroup module_testutils
221 class TestReferenceChecker
225 * Creates a deep copy of the other checker.
227 TestReferenceChecker(const TestReferenceChecker
&other
);
228 ~TestReferenceChecker();
230 //! Assigns a test reference checker.
231 TestReferenceChecker
&operator=(const TestReferenceChecker
&other
);
233 //! Returns true if reference data is currently being written.
234 bool isWriteMode() const;
237 * Sets the tolerance for floating-point comparisons.
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.
246 void setDefaultTolerance(const FloatingPointTolerance
&tolerance
);
249 * Checks whether a data item is present.
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.
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.
259 * If isWriteMode() returns true, the check always succeeds and the
260 * return value is \p bPresent.
262 * The main use of this method is to assign meaning for missing
263 * reference data. Example use:
265 if (checker.checkPresent(bHaveVelocities, "Velocities"))
267 // <check the velocities>
271 bool checkPresent(bool bPresent
, const char *id
);
274 * Initializes comparison of a group of related data items.
276 * \param[in] type Informational type for the compound.
277 * \param[in] id Unique identifier for the compound among its
279 * \returns Checker to use for comparison within the compound.
281 * All checks performed with the returned checker only
282 * need to have unique ids within the compound, not globally.
284 * Compound structures can be nested.
286 TestReferenceChecker
checkCompound(const char *type
, const char *id
);
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
);
295 * Check a multi-line string value.
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.
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
);
324 /*! \name Overloaded versions of simple checker methods
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.
333 //! Check a single boolean value.
334 void checkValue(bool value
, const char *id
)
336 checkBoolean(value
, id
);
338 //! Check a single string value.
339 void checkValue(const char *value
, const char *id
)
341 checkString(value
, id
);
343 //! Check a single string value.
344 void checkValue(const std::string
&value
, const char *id
)
346 checkString(value
, id
);
348 //! Check a single integer value.
349 void checkValue(int value
, const char *id
)
351 checkInteger(value
, id
);
353 //! Check a single integer value.
354 void checkValue(gmx_int64_t value
, const char *id
)
356 checkInt64(value
, id
);
358 //! Check a single integer value.
359 void checkValue(gmx_uint64_t value
, const char *id
)
361 checkUInt64(value
, id
);
363 //! Check a single single-precision floating point value.
364 void checkValue(float value
, const char *id
)
366 checkFloat(value
, id
);
368 //! Check a single double-precision floating point value.
369 void checkValue(double value
, const char *id
)
371 checkDouble(value
, id
);
373 //! Check a vector of three integer values.
374 void checkValue(const int value
[3], const char *id
)
376 checkVector(value
, id
);
378 //! Check a vector of three single-precision floating point values.
379 void checkValue(const float value
[3], const char *id
)
381 checkVector(value
, id
);
383 //! Check a vector of three double-precision floating point values.
384 void checkValue(const double value
[3], const char *id
)
386 checkVector(value
, id
);
391 * Generic method to check a sequence of simple values.
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
401 template <class Iterator
>
402 void checkSequence(Iterator begin
, Iterator end
, const char *id
)
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
)
409 compound
.checkValue(*i
, NULL
);
413 * Generic method to check a sequence of custom values.
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
423 * \param[in] checkItem Functor to check an individual item.
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.
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.
435 template <class Iterator
, class ItemChecker
>
436 void checkSequence(Iterator begin
, Iterator end
, const char *id
,
437 ItemChecker checkItem
)
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
)
444 checkItem(&compound
, *i
);
448 * Check an array of values.
450 * \tparam T Type of values to check. Should be one of those accepted
451 * by checkValue(), or implicitly convertible to one.
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
458 * This is a convenience method that delegates all work to
461 template <typename T
>
462 void checkSequenceArray(size_t length
, const T
*values
, const char *id
)
464 checkSequence(values
, values
+ length
, id
);
467 * Convenience method for checking that a sequence is empty.
469 * \param[in] id Unique identifier for the sequence among its
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.
478 void checkEmptySequence(const char *id
);
480 * Initializes a compound for a sequence of items.
482 * \param[in] id Unique identifier for the sequence among its
484 * \param[in] length Number of items that will be in the sequence.
485 * \returns Checker to use for comparison within the sequence.
487 * This method can be used to check custom sequences where
488 * checkSequence() is not appropriate.
490 TestReferenceChecker
checkSequenceCompound(const char *id
, size_t length
);
496 * Constructs a checker with a specific internal state.
498 * Is private to only allow users of this class to create instances
499 * using TestReferenceData::rootChecker() or checkCompound()
502 explicit TestReferenceChecker(Impl
*impl
);
504 PrivateImplPointer
<Impl
> impl_
;
507 * Needed to expose the constructor only to TestReferenceData.
509 friend class TestReferenceData
;