1179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Copyright (c) 2011 The LevelDB Authors. All rights reserved. 2179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Use of this source code is governed by a BSD-style license that can be 3179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// found in the LICENSE file. See the AUTHORS file for names of contributors. 4179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 5179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#ifndef STORAGE_LEVELDB_UTIL_TESTHARNESS_H_ 6179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#define STORAGE_LEVELDB_UTIL_TESTHARNESS_H_ 7179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 8179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include <stdio.h> 9179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include <stdlib.h> 10179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include <sstream> 11fbd97aa4c5325eace57d24b89845b9581bac9324jorlow@chromium.org#include "leveldb/env.h" 12fbd97aa4c5325eace57d24b89845b9581bac9324jorlow@chromium.org#include "leveldb/slice.h" 13179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "util/random.h" 14179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 15179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgnamespace leveldb { 16179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgnamespace test { 17179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 187e50a01f8a2820ed7a50c673b5affe0131560ff5gabor@google.com// Run some of the tests registered by the TEST() macro. If the 197e50a01f8a2820ed7a50c673b5affe0131560ff5gabor@google.com// environment variable "LEVELDB_TESTS" is not set, runs all tests. 207e50a01f8a2820ed7a50c673b5affe0131560ff5gabor@google.com// Otherwise, runs only the tests whose name contains the value of 217e50a01f8a2820ed7a50c673b5affe0131560ff5gabor@google.com// "LEVELDB_TESTS" as a substring. E.g., suppose the tests are: 227e50a01f8a2820ed7a50c673b5affe0131560ff5gabor@google.com// TEST(Foo, Hello) { ... } 237e50a01f8a2820ed7a50c673b5affe0131560ff5gabor@google.com// TEST(Foo, World) { ... } 247e50a01f8a2820ed7a50c673b5affe0131560ff5gabor@google.com// LEVELDB_TESTS=Hello will run the first test 257e50a01f8a2820ed7a50c673b5affe0131560ff5gabor@google.com// LEVELDB_TESTS=o will run both tests 267e50a01f8a2820ed7a50c673b5affe0131560ff5gabor@google.com// LEVELDB_TESTS=Junk will run no tests 277e50a01f8a2820ed7a50c673b5affe0131560ff5gabor@google.com// 28179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Returns 0 if all tests pass. 29179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Dies or returns a non-zero value if some test fails. 30179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgextern int RunAllTests(); 31179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 32179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Return the directory to use for temporary storage. 33179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgextern std::string TmpDir(); 34179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 35179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Return a randomization seed for this run. Typically returns the 36179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// same number on repeated invocations of this binary, but automated 37179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// runs may be able to vary the seed. 38179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgextern int RandomSeed(); 39179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 40179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// An instance of Tester is allocated to hold temporary state during 41179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// the execution of an assertion. 42179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgclass Tester { 43179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org private: 44179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org bool ok_; 45179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org const char* fname_; 46179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org int line_; 47179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org std::stringstream ss_; 48179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 49179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org public: 50179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Tester(const char* f, int l) 51179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org : ok_(true), fname_(f), line_(l) { 52179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 53179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 54179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ~Tester() { 55179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (!ok_) { 56179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org fprintf(stderr, "%s:%d:%s\n", fname_, line_, ss_.str().c_str()); 57179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org exit(1); 58179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 59179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 60179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 61179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Tester& Is(bool b, const char* msg) { 62179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (!b) { 63179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ss_ << " Assertion failure " << msg; 64179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ok_ = false; 65179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 66179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return *this; 67179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 68179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 69179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Tester& IsOk(const Status& s) { 70179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (!s.ok()) { 71179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ss_ << " " << s.ToString(); 72179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ok_ = false; 73179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 74179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return *this; 75179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 76179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 77179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#define BINARY_OP(name,op) \ 78179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org template <class X, class Y> \ 79179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Tester& name(const X& x, const Y& y) { \ 80179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (! (x op y)) { \ 81179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ss_ << " failed: " << x << (" " #op " ") << y; \ 82179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ok_ = false; \ 83179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } \ 84179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return *this; \ 85179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 86179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 87179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org BINARY_OP(IsEq, ==) 88179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org BINARY_OP(IsNe, !=) 89179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org BINARY_OP(IsGe, >=) 90179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org BINARY_OP(IsGt, >) 91179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org BINARY_OP(IsLe, <=) 92179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org BINARY_OP(IsLt, <) 93179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#undef BINARY_OP 94179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 95179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org // Attach the specified value to the error message if an error has occurred 96179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org template <class V> 97179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org Tester& operator<<(const V& value) { 98179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org if (!ok_) { 99179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ss_ << " " << value; 100179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 101179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org return *this; 102179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } 103179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}; 104179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 105179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#define ASSERT_TRUE(c) ::leveldb::test::Tester(__FILE__, __LINE__).Is((c), #c) 106179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#define ASSERT_OK(s) ::leveldb::test::Tester(__FILE__, __LINE__).IsOk((s)) 107179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#define ASSERT_EQ(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsEq((a),(b)) 108179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#define ASSERT_NE(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsNe((a),(b)) 109179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#define ASSERT_GE(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsGe((a),(b)) 110179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#define ASSERT_GT(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsGt((a),(b)) 111179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#define ASSERT_LE(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsLe((a),(b)) 112179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#define ASSERT_LT(a,b) ::leveldb::test::Tester(__FILE__, __LINE__).IsLt((a),(b)) 113179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 114179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#define TCONCAT(a,b) TCONCAT1(a,b) 115179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#define TCONCAT1(a,b) a##b 116179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 117179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#define TEST(base,name) \ 118179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgclass TCONCAT(_Test_,name) : public base { \ 119179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org public: \ 120179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org void _Run(); \ 121179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org static void _RunIt() { \ 122179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org TCONCAT(_Test_,name) t; \ 123179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org t._Run(); \ 124179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org } \ 125179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}; \ 126179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgbool TCONCAT(_Test_ignored_,name) = \ 127179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org ::leveldb::test::RegisterTest(#base, #name, &TCONCAT(_Test_,name)::_RunIt); \ 128179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgvoid TCONCAT(_Test_,name)::_Run() 129179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 130179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// Register the specified test. Typically not used directly, but 131179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// invoked via the macro expansion of TEST. 132179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgextern bool RegisterTest(const char* base, const char* name, void (*func)()); 133179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 134179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 13545b9940be332834440bd5299419f396e38085ebehans@chromium.org} // namespace test 13645b9940be332834440bd5299419f396e38085ebehans@chromium.org} // namespace leveldb 137179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org 138179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#endif // STORAGE_LEVELDB_UTIL_TESTHARNESS_H_ 139