xapian-core  1.4.27
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, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
21  * USA
22  */
23 
24 #ifndef OM_HGUARD_TESTSUITE_H
25 #define OM_HGUARD_TESTSUITE_H
26 
27 #include "noreturn.h"
28 
29 #ifndef XAPIAN_UNITTEST
30 # include "output.h"
31 # define UNITTEST_CHECK_EXCEPTION
32 #endif
33 
34 #include "stringutils.h" // For STRINGIZE().
35 
36 #include <iomanip>
37 #include <map>
38 #include <sstream>
39 #include <string>
40 #include <vector>
41 
42 #include <cfloat> // For DBL_DIG.
43 
46 class TestFail { };
47 
53 class TestSkip { };
54 
56 #define THROW_TEST_(EXCEPTION, MSG) \
57  do { \
58  if (verbose) { \
59  tout << __FILE__ ":" STRINGIZE(__LINE__) ": " << MSG << '\n'; \
60  } \
61  throw EXCEPTION(); \
62  } while (0)
63 
68 #define FAIL_TEST(MSG) THROW_TEST_(TestFail, MSG)
69 
74 #define SKIP_TEST(MSG) THROW_TEST_(TestSkip, MSG)
75 
77 struct test_desc {
79  const char *name;
80 
82  void (*run)();
83 };
84 
86 //
87 // If verbose is non-zero, then the test harness will display diagnostic output
88 // for tests which fail or skip. If it is > 1, then the diagnostic output will
89 // also be displayed for tests which pass. Individual tests may use this flag
90 // to avoid needless generation of diagnostic output in cases when it's
91 // expensive.
92 extern int verbose;
93 
95 extern const char* expected_failure;
96 
98 // Used to detect if such an exception was mishandled by the
99 // compiler/runtime.
100 extern const char * expected_exception;
101 
105 extern std::ostringstream tout;
106 
108 class test_driver {
110  void write_and_clear_tout();
111 
112  public:
116  struct result {
118  unsigned int succeeded = 0;
119 
121  unsigned int failed = 0;
122 
124  unsigned int skipped = 0;
125 
130  unsigned int xfailed = 0;
131 
136  unsigned int xpassed = 0;
137 
138  result & operator+=(const result & o) {
139  succeeded += o.succeeded;
140  failed += o.failed;
141  skipped += o.skipped;
142  xfailed += o.xfailed;
143  xpassed += o.xpassed;
144  return *this;
145  }
146 
147  void reset() {
148  succeeded = 0;
149  failed = 0;
150  skipped = 0;
151  xfailed = 0;
152  xpassed = 0;
153  }
154  };
155 
164  static void add_command_line_option(const std::string &l, char s,
165  std::string * arg);
166 
172  static void parse_command_line(int argc, char **argv);
173 
174  XAPIAN_NORETURN(static void usage());
175 
176  static int run(const test_desc *tests);
177 
182  test_driver(const test_desc *tests_);
183 
186  result run_tests();
187 
190  result run_tests(std::vector<std::string>::const_iterator b,
191  std::vector<std::string>::const_iterator e);
192 
196  static std::string get_srcdir();
197 
198  // Running subtotal for current backend.
199  static result subtotal;
200 
201  // Running total for the whole test run.
202  static result total;
203 
205  static void report(const test_driver::result &r, const std::string &desc);
206 
207  private:
209  test_driver(const test_driver &);
210  test_driver & operator=(const test_driver &);
211 
212  enum test_result {
213  XPASS = 3, XFAIL = 2, PASS = 1, FAIL = 0, SKIP = -1
214  };
215 
216  static std::map<int, std::string *> short_opts;
217 
218  static std::string opt_help;
219 
220  static std::vector<std::string> test_names;
221 
228  test_result runtest(const test_desc *test);
229 
237  result do_run_tests(std::vector<std::string>::const_iterator b,
238  std::vector<std::string>::const_iterator e);
239 
240  // abort tests at the first failure
241  static bool abort_on_error;
242 
243  // the default stream to output to
244  std::ostream out;
245 
246  // the list of tests to run.
247  const test_desc *tests;
248 
249  // how many test runs we've done - no summary if just one run
250  static int runs;
251 
252  // program name
253  static std::string argv0;
254 
255  // strings to use for colouring - empty if output isn't a tty
256  static std::string col_red, col_green, col_yellow, col_reset;
257 
258  // use \r to not advance a line when a test passes (this only
259  // really makes sense if the output is a tty)
260  static bool use_cr;
261 };
262 
267 #define TEST_AND_EXPLAIN(a, b) do {\
268  bool test_and_explain_fail_ = !(a);\
269  UNITTEST_CHECK_EXCEPTION\
270  if (test_and_explain_fail_)\
271  FAIL_TEST(STRINGIZE(a) << '\n' << b << '\n');\
272  } while (0)
273 
275 #define TEST(a) TEST_AND_EXPLAIN(a, "")
276 
278 #define TEST_EQUAL(a, b) TEST_AND_EXPLAIN(((a) == (b)), \
279  "Expected '" STRINGIZE(a) "' and '" STRINGIZE(b) "' to be equal:" \
280  " were " << (a) << " and " << (b))
281 
287 #define TEST_STRINGS_EQUAL(a, b) TEST_AND_EXPLAIN(((a) == (b)), \
288  "Expected " STRINGIZE(a) " and " STRINGIZE(b) " to be equal, were:\n\"" \
289  << (a) << "\"\n\"" << (b) << '"')
290 
292 extern bool TEST_EQUAL_DOUBLE_(double a, double b);
293 
295 #define TEST_EQUAL_DOUBLE(a, b) TEST_AND_EXPLAIN(TEST_EQUAL_DOUBLE_((a), (b)), \
296  "Expected '" STRINGIZE(a) "' and '" STRINGIZE(b) "' to be (nearly) equal:" \
297  " were " << setprecision(DBL_DIG) << (a) << " and " << (b) << ")" << setprecision(6))
298 
300 #define TEST_NOT_EQUAL_DOUBLE(a, b) TEST_AND_EXPLAIN(!TEST_EQUAL_DOUBLE_((a), (b)), \
301  "Expected '" STRINGIZE(a) "' and '" STRINGIZE(b) "' not to be (nearly) equal:" \
302  " were " << setprecision(DBL_DIG) << (a) << " and " << (b) << ")" << setprecision(6))
303 
305 #define TEST_NOT_EQUAL(a, b) TEST_AND_EXPLAIN(((a) != (b)), \
306  "Expected '" STRINGIZE(a) "' and '" STRINGIZE(b) "' not to be equal:" \
307  " were " << (a) << " and " << (b))
308 
309 #define DEFINE_TESTCASE(S,COND) void test_##S()
310 
311 // Newer test macros:
312 #include "testmacros.h"
313 
332 inline void XFAIL(const char* msg) {
333  expected_failure = msg;
334 }
335 
336 #endif // OM_HGUARD_TESTSUITE_H
static bool use_cr
Definition: testsuite.h:260
static std::string argv0
Definition: testsuite.h:253
Define the XAPIAN_NORETURN macro.
std::ostream operator<< template for Xapian objects
unsigned int xfailed
Number of tests with result XFAIL.
Definition: testsuite.h:130
static std::string col_yellow
Definition: testsuite.h:256
Class which is thrown when a test case fails.
Definition: testsuite.h:46
bool TEST_EQUAL_DOUBLE_(double a, double b)
Helper function for TEST_EQUAL_DOUBLE macro.
Definition: testsuite.cc:928
unsigned int xpassed
Number of tests with result XFAIL.
Definition: testsuite.h:136
const char * expected_failure
Set to a string explanation for testcases expected to fail.
Definition: testsuite.cc:101
static std::map< int, std::string * > short_opts
Definition: testsuite.h:216
static result subtotal
Definition: testsuite.h:199
const char * expected_exception
The exception type we were expecting in TEST_EXCEPTION.
Definition: testsuite.cc:99
Macros for testing conditions hold.
std::ostream out
Definition: testsuite.h:244
unsigned int succeeded
The number of tests which succeeded.
Definition: testsuite.h:118
void XFAIL(const char *msg)
Mark a testcase as expected to fail.
Definition: testsuite.h:332
static result total
Definition: testsuite.h:202
unsigned int failed
The number of tests which failed.
Definition: testsuite.h:121
static const test_desc tests[]
The lists of tests to perform.
static int runs
Definition: testsuite.h:250
static std::string opt_help
Definition: testsuite.h:218
static std::vector< std::string > test_names
Definition: testsuite.h:220
const test_desc * tests
Definition: testsuite.h:247
static bool abort_on_error
Definition: testsuite.h:241
int verbose
The global verbose flag.
Definition: testsuite.cc:79
std::ostringstream tout
The output stream.
Definition: testsuite.cc:104
Various handy helpers which std::string really should provide.
A structure used to report the summary of tests passed and failed.
Definition: testsuite.h:116
Structure holding a description of a test.
Definition: testsuite.h:77
result & operator+=(const result &o)
Definition: testsuite.h:138
The test driver. This class takes care of running the tests.
Definition: testsuite.h:108
const char * name
The name of the test.
Definition: testsuite.h:79
unsigned int skipped
The number of tests which were skipped.
Definition: testsuite.h:124
Class which is thrown when a test case is to be skipped.
Definition: testsuite.h:53