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