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 #include <sstream> 11 #include "leveldb/env.h" 12 #include "leveldb/slice.h" 13 #include "util/random.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 extern int RunAllTests(); 31 32 // Return the directory to use for temporary storage. 33 extern 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 extern 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) 51 : ok_(true), fname_(f), line_(l) { 52 } 53 54 ~Tester() { 55 if (!ok_) { 56 fprintf(stderr, "%s:%d:%s\n", fname_, line_, ss_.str().c_str()); 57 exit(1); 58 } 59 } 60 61 Tester& Is(bool b, const char* msg) { 62 if (!b) { 63 ss_ << " Assertion failure " << msg; 64 ok_ = false; 65 } 66 return *this; 67 } 68 69 Tester& IsOk(const Status& s) { 70 if (!s.ok()) { 71 ss_ << " " << s.ToString(); 72 ok_ = false; 73 } 74 return *this; 75 } 76 77 #define BINARY_OP(name,op) \ 78 template <class X, class Y> \ 79 Tester& name(const X& x, const Y& y) { \ 80 if (! (x op y)) { \ 81 ss_ << " failed: " << x << (" " #op " ") << y; \ 82 ok_ = false; \ 83 } \ 84 return *this; \ 85 } 86 87 BINARY_OP(IsEq, ==) 88 BINARY_OP(IsNe, !=) 89 BINARY_OP(IsGe, >=) 90 BINARY_OP(IsGt, >) 91 BINARY_OP(IsLe, <=) 92 BINARY_OP(IsLt, <) 93 #undef BINARY_OP 94 95 // Attach the specified value to the error message if an error has occurred 96 template <class V> 97 Tester& operator<<(const V& value) { 98 if (!ok_) { 99 ss_ << " " << value; 100 } 101 return *this; 102 } 103 }; 104 105 #define ASSERT_TRUE(c) ::leveldb::test::Tester(__FILE__, __LINE__).Is((c), #c) 106 #define ASSERT_OK(s) ::leveldb::test::Tester(__FILE__, __LINE__).IsOk((s)) 107 #define ASSERT_EQ(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsEq((a),(b)) 108 #define ASSERT_NE(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsNe((a),(b)) 109 #define ASSERT_GE(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsGe((a),(b)) 110 #define ASSERT_GT(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsGt((a),(b)) 111 #define ASSERT_LE(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsLe((a),(b)) 112 #define ASSERT_LT(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsLt((a),(b)) 113 114 #define TCONCAT(a,b) TCONCAT1(a,b) 115 #define TCONCAT1(a,b) a##b 116 117 #define TEST(base,name) \ 118 class TCONCAT(_Test_,name) : public base { \ 119 public: \ 120 void _Run(); \ 121 static void _RunIt() { \ 122 TCONCAT(_Test_,name) t; \ 123 t._Run(); \ 124 } \ 125 }; \ 126 bool TCONCAT(_Test_ignored_,name) = \ 127 ::leveldb::test::RegisterTest(#base, #name, &TCONCAT(_Test_,name)::_RunIt); \ 128 void TCONCAT(_Test_,name)::_Run() 129 130 // Register the specified test. Typically not used directly, but 131 // invoked via the macro expansion of TEST. 132 extern bool RegisterTest(const char* base, const char* name, void (*func)()); 133 134 135 } // namespace test 136 } // namespace leveldb 137 138 #endif // STORAGE_LEVELDB_UTIL_TESTHARNESS_H_ 139