xapian-core  2.0.0
testsuite.h
Go to the documentation of this file.
1 
4 /* Copyright 1999,2000,2001 BrightStation PLC
5  * Copyright 2002,2003,2005,2006,2007,2008,2009,2013,2015,2016,2018 Olly Betts
6  * Copyright 2007 Richard Boulton
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of the
11  * License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, see
20  * <https://www.gnu.org/licenses/>.
21  */
22 
23 #ifndef XAPIAN_INCLUDED_TESTSUITE_H
24 #define XAPIAN_INCLUDED_TESTSUITE_H
25 
26 #ifndef XAPIAN_UNITTEST
27 # include "output.h"
28 # define UNITTEST_CHECK_EXCEPTION
29 #endif
30 
31 #include "stringutils.h" // For STRINGIZE().
32 
33 #include <iomanip>
34 #include <map>
35 #include <sstream>
36 #include <string>
37 #include <vector>
38 
39 #include <cfloat> // For DBL_DIG.
40 
43 class TestFail { };
44 
50 class TestSkip { };
51 
53 #define THROW_TEST_(EXCEPTION, MSG) \
54  do { \
55  if (verbose) { \
56  tout << __FILE__ ":" STRINGIZE(__LINE__) ": " << MSG << '\n'; \
57  } \
58  throw EXCEPTION(); \
59  } while (0)
60 
65 #define FAIL_TEST(MSG) THROW_TEST_(TestFail, MSG)
66 
71 #define SKIP_TEST(MSG) THROW_TEST_(TestSkip, MSG)
72 
74 struct test_desc {
76  const char *name;
77 
79  void (*run)();
80 };
81 
83 //
84 // If verbose is non-zero, then the test harness will display diagnostic output
85 // for tests which fail or skip. If it is > 1, then the diagnostic output will
86 // also be displayed for tests which pass. Individual tests may use this flag
87 // to avoid needless generation of diagnostic output in cases when it's
88 // expensive.
89 extern int verbose;
90 
92 extern const char* expected_failure;
93 
95 // Used to detect if such an exception was mishandled by the
96 // compiler/runtime.
97 extern const char * expected_exception;
98 
102 extern std::ostringstream tout;
103 
105 class test_driver {
107  void write_and_clear_tout();
108 
109  public:
113  struct result {
115  unsigned int succeeded = 0;
116 
118  unsigned int failed = 0;
119 
121  unsigned int skipped = 0;
122 
127  unsigned int xfailed = 0;
128 
133  unsigned int xpassed = 0;
134 
135  result & operator+=(const result & o) {
136  succeeded += o.succeeded;
137  failed += o.failed;
138  skipped += o.skipped;
139  xfailed += o.xfailed;
140  xpassed += o.xpassed;
141  return *this;
142  }
143 
144  void reset() {
145  succeeded = 0;
146  failed = 0;
147  skipped = 0;
148  xfailed = 0;
149  xpassed = 0;
150  }
151  };
152 
161  static void add_command_line_option(const std::string &l, char s,
162  std::string * arg);
163 
169  static void parse_command_line(int argc, char **argv);
170 
171  [[noreturn]]
172  static void usage();
173 
174  static int run(const test_desc *tests);
175 
180  test_driver(const test_desc *tests_);
181 
184  result run_tests();
185 
188  result run_tests(std::vector<std::string>::const_iterator b,
189  std::vector<std::string>::const_iterator e);
190 
194  static std::string get_srcdir();
195 
196  // Running subtotal for current backend.
197  static result subtotal;
198 
199  // Running total for the whole test run.
200  static result total;
201 
203  static void report(const test_driver::result &r, const std::string &desc);
204 
205  private:
209 
210  enum test_result {
211  XPASS = 3, XFAIL = 2, PASS = 1, FAIL = 0, SKIP = -1
212  };
213 
214  static std::map<int, std::string *> short_opts;
215 
216  static std::string opt_help;
217 
218  static std::vector<std::string> test_names;
219 
226  test_result runtest(const test_desc *test);
227 
235  result do_run_tests(std::vector<std::string>::const_iterator b,
236  std::vector<std::string>::const_iterator e);
237 
238  // abort tests at the first failure
239  static bool abort_on_error;
240 
241  // the default stream to output to
242  std::ostream out;
243 
244  // the list of tests to run.
245  const test_desc *tests;
246 
247  // how many test runs we've done - no summary if just one run
248  static int runs;
249 
250  // program name
251  static std::string argv0;
252 
253  // strings to use for colouring - empty if output isn't a tty
254  static std::string col_red, col_green, col_yellow, col_reset;
255 
256  // use \r to not advance a line when a test passes (this only
257  // really makes sense if the output is a tty)
258  static bool use_cr;
259 };
260 
265 #define TEST_AND_EXPLAIN(a, b) do {\
266  bool test_and_explain_fail_ = !(a);\
267  UNITTEST_CHECK_EXCEPTION\
268  if (test_and_explain_fail_)\
269  FAIL_TEST(STRINGIZE(a) << '\n' << b << '\n');\
270  } while (0)
271 
273 #define TEST(a) TEST_AND_EXPLAIN(a, "")
274 
276 #define TEST_EQUAL(a, b) TEST_AND_EXPLAIN(((a) == (b)), \
277  "Expected '" STRINGIZE(a) "' and '" STRINGIZE(b) "' to be equal:" \
278  " were " << (a) << " and " << (b))
279 
285 #define TEST_STRINGS_EQUAL(a, b) TEST_AND_EXPLAIN(((a) == (b)), \
286  "Expected " STRINGIZE(a) " and " STRINGIZE(b) " to be equal, were:\n\"" \
287  << (a) << "\"\n\"" << (b) << '"')
288 
290 extern bool TEST_EQUAL_DOUBLE_(double a, double b);
291 
293 #define TEST_EQUAL_DOUBLE(a, b) TEST_AND_EXPLAIN(TEST_EQUAL_DOUBLE_((a), (b)), \
294  "Expected '" STRINGIZE(a) "' and '" STRINGIZE(b) "' to be (nearly) equal:" \
295  " were " << setprecision(DBL_DIG) << (a) << " and " << (b) << ")" << setprecision(6))
296 
298 #define TEST_NOT_EQUAL_DOUBLE(a, b) TEST_AND_EXPLAIN(!TEST_EQUAL_DOUBLE_((a), (b)), \
299  "Expected '" STRINGIZE(a) "' and '" STRINGIZE(b) "' not to be (nearly) equal:" \
300  " were " << setprecision(DBL_DIG) << (a) << " and " << (b) << ")" << setprecision(6))
301 
303 #define TEST_NOT_EQUAL(a, b) TEST_AND_EXPLAIN(((a) != (b)), \
304  "Expected '" STRINGIZE(a) "' and '" STRINGIZE(b) "' not to be equal:" \
305  " were " << (a) << " and " << (b))
306 
307 // Newer test macros:
308 #include "testmacros.h"
309 
328 inline void XFAIL(const char* msg) {
329  expected_failure = msg;
330 }
331 
332 #endif // XAPIAN_INCLUDED_TESTSUITE_H
Class which is thrown when a test case fails.
Definition: testsuite.h:43
Class which is thrown when a test case is to be skipped.
Definition: testsuite.h:50
The test driver. This class takes care of running the tests.
Definition: testsuite.h:105
static std::string col_yellow
Definition: testsuite.h:254
test_driver & operator=(const test_driver &)
std::ostream out
Definition: testsuite.h:242
static bool abort_on_error
Definition: testsuite.h:239
static bool use_cr
Definition: testsuite.h:258
static void report(const test_driver::result &r, const std::string &desc)
Print summary of tests passed, failed, and skipped.
Definition: testsuite.cc:811
static std::string col_green
Definition: testsuite.h:254
static std::vector< std::string > test_names
Definition: testsuite.h:218
static result subtotal
Definition: testsuite.h:197
test_result runtest(const test_desc *test)
Runs the test function and returns its result.
Definition: testsuite.cc:333
static std::string col_red
Definition: testsuite.h:254
static std::string col_reset
Definition: testsuite.h:254
static std::string opt_help
Definition: testsuite.h:216
result run_tests()
Run all the tests supplied and return the results.
Definition: testsuite.cc:704
static void parse_command_line(int argc, char **argv)
Parse the command line arguments.
Definition: testsuite.cc:866
static std::string get_srcdir()
Read srcdir from environment and if not present, make a valiant attempt to guess a value.
Definition: testsuite.cc:135
test_driver(const test_desc *tests_)
The constructor, which sets up the test driver.
Definition: testsuite.cc:176
static int run(const test_desc *tests)
Definition: testsuite.cc:955
static void add_command_line_option(const std::string &l, char s, std::string *arg)
Add a test-specific command line option.
Definition: testsuite.cc:855
result do_run_tests(std::vector< std::string >::const_iterator b, std::vector< std::string >::const_iterator e)
The implementation used by run_tests.
Definition: testsuite.cc:711
static int runs
Definition: testsuite.h:248
static std::map< int, std::string * > short_opts
Definition: testsuite.h:214
void write_and_clear_tout()
Write out anything in tout and clear it.
Definition: testsuite.cc:125
const test_desc * tests
Definition: testsuite.h:245
static std::string argv0
Definition: testsuite.h:251
static result total
Definition: testsuite.h:200
static void usage()
Definition: testsuite.cc:792
test_driver(const test_driver &)
Prevent copying.
std::ostream operator<< template for Xapian objects
Various handy string-related helpers.
Structure holding a description of a test.
Definition: testsuite.h:74
const char * name
The name of the test.
Definition: testsuite.h:76
void(* run)()
The function to run to perform the test.
Definition: testsuite.h:79
A structure used to report the summary of tests passed and failed.
Definition: testsuite.h:113
unsigned int failed
The number of tests which failed.
Definition: testsuite.h:118
unsigned int skipped
The number of tests which were skipped.
Definition: testsuite.h:121
unsigned int xfailed
Number of tests with result XFAIL.
Definition: testsuite.h:127
unsigned int xpassed
Number of tests with result XFAIL.
Definition: testsuite.h:133
result & operator+=(const result &o)
Definition: testsuite.h:135
unsigned int succeeded
The number of tests which succeeded.
Definition: testsuite.h:115
int verbose
The global verbose flag.
Definition: testsuite.cc:79
const char * expected_failure
Set to a string explanation for testcases expected to fail.
Definition: testsuite.cc:101
const char * expected_exception
The exception type we were expecting in TEST_EXCEPTION.
Definition: testsuite.cc:99
std::ostringstream tout
The output stream.
Definition: testsuite.cc:104