25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
4.5 KiB

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