testharness.h raw
1 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. See the AUTHORS file for names of contributors.
4
5 #ifndef STORAGE_LEVELDB_UTIL_TESTHARNESS_H_
6 #define STORAGE_LEVELDB_UTIL_TESTHARNESS_H_
7
8 #include <stdio.h>
9 #include <stdlib.h>
10
11 #include <sstream>
12
13 #include "leveldb/status.h"
14
15 namespace leveldb {
16 namespace test {
17
18 // Run some of the tests registered by the TEST() macro. If the
19 // environment variable "LEVELDB_TESTS" is not set, runs all tests.
20 // Otherwise, runs only the tests whose name contains the value of
21 // "LEVELDB_TESTS" as a substring. E.g., suppose the tests are:
22 // TEST(Foo, Hello) { ... }
23 // TEST(Foo, World) { ... }
24 // LEVELDB_TESTS=Hello will run the first test
25 // LEVELDB_TESTS=o will run both tests
26 // LEVELDB_TESTS=Junk will run no tests
27 //
28 // Returns 0 if all tests pass.
29 // Dies or returns a non-zero value if some test fails.
30 int RunAllTests();
31
32 // Return the directory to use for temporary storage.
33 std::string TmpDir();
34
35 // Return a randomization seed for this run. Typically returns the
36 // same number on repeated invocations of this binary, but automated
37 // runs may be able to vary the seed.
38 int RandomSeed();
39
40 // An instance of Tester is allocated to hold temporary state during
41 // the execution of an assertion.
42 class Tester {
43 private:
44 bool ok_;
45 const char* fname_;
46 int line_;
47 std::stringstream ss_;
48
49 public:
50 Tester(const char* f, int l) : ok_(true), fname_(f), line_(l) {}
51
52 ~Tester() {
53 if (!ok_) {
54 fprintf(stderr, "%s:%d:%s\n", fname_, line_, ss_.str().c_str());
55 exit(1);
56 }
57 }
58
59 Tester& Is(bool b, const char* msg) {
60 if (!b) {
61 ss_ << " Assertion failure " << msg;
62 ok_ = false;
63 }
64 return *this;
65 }
66
67 Tester& IsOk(const Status& s) {
68 if (!s.ok()) {
69 ss_ << " " << s.ToString();
70 ok_ = false;
71 }
72 return *this;
73 }
74
75 #define BINARY_OP(name, op) \
76 template <class X, class Y> \
77 Tester& name(const X& x, const Y& y) { \
78 if (!(x op y)) { \
79 ss_ << " failed: " << x << (" " #op " ") << y; \
80 ok_ = false; \
81 } \
82 return *this; \
83 }
84
85 BINARY_OP(IsEq, ==)
86 BINARY_OP(IsNe, !=)
87 BINARY_OP(IsGe, >=)
88 BINARY_OP(IsGt, >)
89 BINARY_OP(IsLe, <=)
90 BINARY_OP(IsLt, <)
91 #undef BINARY_OP
92
93 // Attach the specified value to the error message if an error has occurred
94 template <class V>
95 Tester& operator<<(const V& value) {
96 if (!ok_) {
97 ss_ << " " << value;
98 }
99 return *this;
100 }
101 };
102
103 #define ASSERT_TRUE(c) ::leveldb::test::Tester(__FILE__, __LINE__).Is((c), #c)
104 #define ASSERT_OK(s) ::leveldb::test::Tester(__FILE__, __LINE__).IsOk((s))
105 #define ASSERT_EQ(a, b) \
106 ::leveldb::test::Tester(__FILE__, __LINE__).IsEq((a), (b))
107 #define ASSERT_NE(a, b) \
108 ::leveldb::test::Tester(__FILE__, __LINE__).IsNe((a), (b))
109 #define ASSERT_GE(a, b) \
110 ::leveldb::test::Tester(__FILE__, __LINE__).IsGe((a), (b))
111 #define ASSERT_GT(a, b) \
112 ::leveldb::test::Tester(__FILE__, __LINE__).IsGt((a), (b))
113 #define ASSERT_LE(a, b) \
114 ::leveldb::test::Tester(__FILE__, __LINE__).IsLe((a), (b))
115 #define ASSERT_LT(a, b) \
116 ::leveldb::test::Tester(__FILE__, __LINE__).IsLt((a), (b))
117
118 #define TCONCAT(a, b) TCONCAT1(a, b)
119 #define TCONCAT1(a, b) a##b
120
121 #define TEST(base, name) \
122 class TCONCAT(_Test_, name) : public base { \
123 public: \
124 void _Run(); \
125 static void _RunIt() { \
126 TCONCAT(_Test_, name) t; \
127 t._Run(); \
128 } \
129 }; \
130 bool TCONCAT(_Test_ignored_, name) = ::leveldb::test::RegisterTest( \
131 #base, #name, &TCONCAT(_Test_, name)::_RunIt); \
132 void TCONCAT(_Test_, name)::_Run()
133
134 // Register the specified test. Typically not used directly, but
135 // invoked via the macro expansion of TEST.
136 bool RegisterTest(const char* base, const char* name, void (*func)());
137
138 } // namespace test
139 } // namespace leveldb
140
141 #endif // STORAGE_LEVELDB_UTIL_TESTHARNESS_H_
142