YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/util/test_macros.h
Line
Count
Source (jump to first uncovered line)
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
//
18
// The following only applies to changes made to this file as part of YugaByte development.
19
//
20
// Portions Copyright (c) YugaByte, Inc.
21
//
22
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
23
// in compliance with the License.  You may obtain a copy of the License at
24
//
25
// http://www.apache.org/licenses/LICENSE-2.0
26
//
27
// Unless required by applicable law or agreed to in writing, software distributed under the License
28
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
29
// or implied.  See the License for the specific language governing permissions and limitations
30
// under the License.
31
//
32
#ifndef YB_UTIL_TEST_MACROS_H
33
#define YB_UTIL_TEST_MACROS_H
34
35
#include <set>
36
#include <sstream>
37
#include <string>
38
39
#include <boost/preprocessor/cat.hpp>
40
41
#include <gtest/gtest.h> // For SUCCEED/FAIL
42
43
#include "yb/util/tostring.h"
44
#include "yb/gutil/stl_util.h"  // For VectorToSet
45
46
namespace yb {
47
namespace util {
48
49
template<typename T>
50
std::string TEST_SetDifferenceStr(const std::set<T>& expected, const std::set<T>& actual) {
51
  std::set<T> only_in_expected, only_in_actual;
52
  for (const auto& expected_item : expected) {
53
    if (!actual.count(expected_item)) {
54
      only_in_expected.insert(expected_item);
55
    }
56
  }
57
58
  for (const auto& actual_item : actual) {
59
    if (!expected.count(actual_item)) {
60
      only_in_actual.insert(actual_item);
61
    }
62
  }
63
64
  std::ostringstream result;
65
  if (!only_in_expected.empty()) {
66
    result << "only in the expected set: " << yb::ToString(only_in_expected);
67
  }
68
  if (!only_in_actual.empty()) {
69
    if (result.tellp() > 0) {
70
      result << "; ";
71
    }
72
    result << "only in the actual set: " << yb::ToString(only_in_actual);
73
  }
74
  if (result.tellp() == 0) {
75
    return "no differences";
76
  }
77
  return result.str();
78
}
79
80
}  // namespace util
81
}  // namespace yb
82
83
// ASSERT_NO_FATAL_FAILURE is just too long to type.
84
#define NO_FATALS(expr) \
85
  ASSERT_NO_FATAL_FAILURE(expr)
86
87
// Detect fatals in the surrounding scope. NO_FATALS() only checks for fatals
88
// in the expression passed to it.
89
#define NO_PENDING_FATALS() \
90
  if (testing::Test::HasFatalFailure()) { return; }
91
92
// ASSERT_NO_FATAL_FAILURE is just too long to type.
93
5.42k
#define ASSERT_NO_FATALS ASSERT_NO_FATAL_FAILURE
94
95
// We are using "const auto" for storing the status so that the same macros work for both YB and
96
// RocksDB's Status types.
97
98
796k
#define ASSERT_OK(status) do { \
99
796k
    auto&& _assert_status = (
status122k
); \
remote_bootstrap_session-test.cc:yb::tserver::RemoteBootstrapSessionTest::SetUpTabletPeer()::$_0::operator()() const
Line
Count
Source
99
28
    auto&& _assert_status = (status); \
Unexecuted instantiation: cdc_test_util.cc:yb::cdc::WaitUntilWalRetentionSecs(std::__1::function<int ()>, unsigned int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_0::operator()() const
yb_table_test_base.cc:yb::integration_tests::YBTableTestBase::WaitForLoadBalanceCompletion(yb::MonoDelta)::$_0::operator()() const
Line
Count
Source
99
1.29k
    auto&& _assert_status = (status); \
yb_table_test_base.cc:yb::integration_tests::YBTableTestBase::WaitForLoadBalanceCompletion(yb::MonoDelta)::$_1::operator()() const
Line
Count
Source
99
1.07k
    auto&& _assert_status = (status); \
100
796k
    if (_assert_status.ok()) { \
101
796k
      SUCCEED(); \
102
796k
    } else { \
103
747
      FAIL() << "Bad status: " << StatusToString(_assert_status);  \
104
747
    } \
105
796k
  } while (
0796k
)
106
107
#define ASSERT_NOK(s) ASSERT_FALSE((s).ok())
108
109
#define ASSERT_OK_PREPEND(status, msg) do { \
110
  auto&& _assert_status = (status); \
111
  if (_assert_status.ok()) { \
112
    SUCCEED(); \
113
  } else { \
114
    FAIL() << (msg) << " - status: " << StatusToString(_assert_status);  \
115
  } \
116
} while (0)
117
118
#ifdef EXPECT_OK
119
#undef EXPECT_OK
120
#endif
121
122
870
#define EXPECT_OK(status) do { \
123
870
    auto&& _s = (status); \
124
870
    if (_s.ok()) { \
125
870
      SUCCEED(); \
126
870
    } else { \
127
0
      ADD_FAILURE() << "Bad status: " << StatusToString(_s);  \
128
0
    } \
129
870
  } while (0)
130
131
#define EXPECT_NOT_OK(s) EXPECT_FALSE((s).ok())
132
133
// Like the above, but doesn't record successful
134
// tests.
135
5.14k
#define ASSERT_OK_FAST(status) do {      \
136
5.14k
    auto&& _assert_status = (status); \
137
5.14k
    if (!_assert_status.ok()) { \
138
0
      FAIL() << "Bad status: " << StatusToString(_assert_status);  \
139
0
    } \
140
5.14k
  } while (0)
141
142
#define ASSERT_NO_ERROR(ec) \
143
  do { \
144
    auto&& _ec = (ec); \
145
    if (!_ec) { \
146
      SUCCEED(); \
147
    } else { \
148
      FAIL() << "Unexpected error: " << ec.message(); \
149
    } \
150
  } while (false)
151
152
#define EXPECT_NO_ERROR(ec) \
153
  do { \
154
    auto&& _ec = (ec); \
155
    if (!_ec) { \
156
      SUCCEED(); \
157
    } else { \
158
      ADD_FAILURE() << "Unexpected error: " << ec.message(); \
159
    } \
160
  } while (false)
161
162
#ifdef THREAD_SANITIZER
163
#define ASSERT_PERF_LE(lhs, rhs) do { (void)(lhs); (void)(rhs); } while(false)
164
#define EXPECT_PERF_LE(lhs, rhs) do { (void)(lhs); (void)(rhs); } while(false)
165
#else
166
#define ASSERT_PERF_LE(lhs, rhs) ASSERT_LE(lhs, rhs)
167
#define EXPECT_PERF_LE(lhs, rhs) EXPECT_LE(lhs, rhs)
168
#endif
169
170
#define ASSERT_STR_CONTAINS(str, substr) do { \
171
  std::string _s = (str); \
172
  if (_s.find((substr)) == std::string::npos) { \
173
    FAIL() << "Expected to find substring '" << (substr) \
174
    << "'. Got: '" << _s << "'"; \
175
  } \
176
  } while (0)
177
178
#define ASSERT_STR_NOT_CONTAINS(str, substr) do { \
179
  std::string _s = (str); \
180
  if (_s.find((substr)) != std::string::npos) { \
181
    FAIL() << "Expected not to find substring '" << (substr) \
182
    << "'. Got: '" << _s << "'"; \
183
  } \
184
  } while (0)
185
186
0
inline std::string FindFirstDiff(const std::string& lhs, const std::string& rhs) {
187
0
  size_t min_len = std::min(lhs.size(), rhs.size());
188
0
  size_t i = 0;
189
0
  for (; i != min_len; ++i) {
190
0
    if (lhs[i] != rhs[i]) {
191
0
      break;
192
0
    }
193
0
  }
194
0
  return lhs.substr(i, std::min<size_t>(lhs.size() - i, 32)) + " vs " +
195
0
         rhs.substr(i, std::min<size_t>(rhs.size() - i, 32));
196
0
}
197
198
1
#define ASSERT_STR_EQ(lhs, rhs) do { \
199
1
    std::string _lhs = (lhs); \
200
1
    std::string _rhs = (rhs); \
201
2
    ASSERT_EQ(lhs, rhs) << "First diff: " << FindFirstDiff(lhs, rhs); \
202
1
  } while (0)
203
204
#define ASSERT_FILE_EXISTS(env, path) do { \
205
  std::string _s = (path); \
206
  ASSERT_TRUE(env->FileExists(_s)) \
207
    << "Expected file to exist: " << _s; \
208
  } while (0)
209
210
#define ASSERT_FILE_NOT_EXISTS(env, path) do { \
211
  std::string _s = (path); \
212
  ASSERT_FALSE(env->FileExists(_s)) \
213
    << "Expected file not to exist: " << _s; \
214
  } while (0)
215
216
// Wrappers around ASSERT_EQ and EXPECT_EQ that trim expected and actual strings and outputs
217
// expected and actual values without any escaping. We're also printing a stack trace to allow
218
// easier debugging.
219
#define _ASSERT_EXPECT_STR_EQ_VERBOSE_COMMON_SETUP(expected, actual) \
220
207k
    const auto expected_tmp = ::yb::util::TrimStr(yb::util::LeftShiftTextBlock(expected)); \
221
207k
    const auto actual_tmp = ::yb::util::TrimStr(yb::util::LeftShiftTextBlock(actual));
222
223
#define _ASSERT_EXPECT_STR_EQ_VERBOSE_COMMON_MSG \
224
0
    "\nActual (trimmed):\n" << actual_tmp \
225
0
        << "\n\nExpected (trimmed):\n" << expected_tmp;
226
227
#define ASSERT_STR_EQ_VERBOSE_TRIMMED(expected, actual) \
228
207k
  do { \
229
207k
    _ASSERT_EXPECT_STR_EQ_VERBOSE_COMMON_SETUP(expected, actual) \
230
414k
    ASSERT_EQ(expected_tmp, actual_tmp) << 
_ASSERT_EXPECT_STR_EQ_VERBOSE_COMMON_MSG0
; \
231
207k
  } while(0)
232
233
#define ASSERT_SETS_EQ(expected_set, actual_set) \
234
  do { \
235
    auto&& expected_set_computed = (expected_set); \
236
    auto&& actual_set_computed = (actual_set); \
237
    if (expected_set_computed != actual_set_computed) { \
238
      FAIL() << "Expected " \
239
             << BOOST_PP_STRINGIZE(actual_set) << " to be equal to " \
240
             << BOOST_PP_STRINGIZE(expected_set) << ". Differences: " \
241
             << ::yb::util::TEST_SetDifferenceStr(expected_set_computed, actual_set_computed); \
242
    } \
243
  } while (0)
244
245
// Compare vectors of "comparable" values that can be put inside an std::set. Because they are
246
// comparable, we also show the differences between the set of elements in vectors, which is
247
// sometimes the only way to see what is different.
248
//
249
// Using a simple name ASSERT_VECTORS_EQ for this macro rather than a more verbose and precise but
250
// more confusing such as ASSERT_VECTORS_OF_COMPARABLE_EQ.
251
//
252
// Google Test says "do not use this in your code" about GTEST_PRED_FORMAT2_, but we need to use it
253
// to correctly propagate the raw text of expressions to the error message. We pass the string
254
// representation of the actual macro parameters but the ..._computed values as values (to avoid
255
// multiple evaluations).
256
//
257
// Here are macros from gtest that were used to construct the implementation below:
258
//
259
// ASSERT_EQ -> GTEST_ASSERT_EQ -> ASSERT_PRED_FORMAT2 -> GTEST_PRED_FORMAT2_ -> GTEST_ASSERT_
260
#define ASSERT_VECTORS_EQ(expected_vector, actual_vector) \
261
  do { \
262
    auto&& expected_vector_computed = (expected_vector); \
263
    auto&& actual_vector_computed = (actual_vector); \
264
    auto expected_set = ::yb::VectorToSet(expected_vector_computed); \
265
    auto actual_set = ::yb::VectorToSet(actual_vector_computed); \
266
    GTEST_ASSERT_( \
267
        ::testing::internal::EqHelper<GTEST_IS_NULL_LITERAL_(expected_vector)>::Compare( \
268
            BOOST_PP_STRINGIZE(expected_vector), \
269
            BOOST_PP_STRINGIZE(actual_vector), \
270
            expected_vector_computed, \
271
            actual_vector_computed), \
272
        GTEST_FATAL_FAILURE_) \
273
        << "Differences (as sets): " \
274
        << ::yb::util::TEST_SetDifferenceStr(expected_set, actual_set); \
275
  } while (0)
276
277
// A wrapper around EXPECT_EQ that trims expected and actual strings and outputs expected and actual
278
// values without any escaping.
279
#define EXPECT_STR_EQ_VERBOSE_TRIMMED(expected, actual) \
280
  do { \
281
    _ASSERT_EXPECT_STR_EQ_VERBOSE_COMMON_SETUP(expected, actual) \
282
    EXPECT_EQ(expected_tmp, actual_tmp) << _ASSERT_EXPECT_STR_EQ_VERBOSE_COMMON_MSG; \
283
  } while(0)
284
285
#define YB_ASSERT_TRUE(condition) \
286
  GTEST_TEST_BOOLEAN_((condition) ? true : false, #condition, false, true, \
287
                      GTEST_FATAL_FAILURE_)
288
289
#define VERIFY_EQ(expected_expr, actual_expr) \
290
  do { \
291
    auto&& expected = (expected_expr); \
292
    auto&& actual = (actual_expr); \
293
    if (expected != actual) { \
294
      return ::testing::internal::EqFailure( \
295
          BOOST_PP_STRINGIZE(expected_expr), \
296
          BOOST_PP_STRINGIZE(actual_expr), \
297
          ::testing::internal::FormatForComparisonFailureMessage(expected, actual), \
298
          ::testing::internal::FormatForComparisonFailureMessage(actual, expected), \
299
          false); \
300
    } \
301
  } while (false) \
302
  /**/
303
304
#define ASSERT_VERIFY(expr) \
305
  do { \
306
    auto&& result = (expr); \
307
    if (!result) { \
308
      FAIL() << result.message(); \
309
    } \
310
  } while (false) \
311
  /**/
312
313
// Asserts that expr is not null, returns expr in case of success.
314
#define ASSERT_NOTNULL(expr) \
315
  __extension__ ({ \
316
    auto&& result = (expr); \
317
    if (result == nullptr) { \
318
      FAIL() << "Unexpected nullptr"; \
319
    } \
320
    std::move(result); \
321
  }) \
322
  /**/
323
324
#define CURRENT_TEST_NAME() \
325
12
  ::testing::UnitTest::GetInstance()->current_test_info()->name()
326
327
#define CURRENT_TEST_CASE_NAME() \
328
0
  ::testing::UnitTest::GetInstance()->current_test_info()->test_case_name()
329
330
#define CURRENT_TEST_CASE_AND_TEST_NAME_STR() \
331
  (std::string(CURRENT_TEST_CASE_NAME()) + '.' + CURRENT_TEST_NAME())
332
333
#define YB_DISABLE_TEST(test_name) BOOST_PP_CAT(DISABLED_, test_name)
334
335
#ifdef __APPLE__
336
#define YB_DISABLE_TEST_ON_MACOS(test_name) YB_DISABLE_TEST(test_name)
337
#else
338
#define YB_DISABLE_TEST_ON_MACOS(test_name) test_name
339
#endif
340
341
#ifdef THREAD_SANITIZER
342
#define YB_DISABLE_TEST_IN_TSAN(test_name) YB_DISABLE_TEST(test_name)
343
#else
344
#define YB_DISABLE_TEST_IN_TSAN(test_name) test_name
345
#endif
346
347
#if defined(THREAD_SANITIZER) || defined(ADDRESS_SANITIZER)
348
#define YB_DISABLE_TEST_IN_SANITIZERS(test_name) YB_DISABLE_TEST(test_name)
349
#else
350
#define YB_DISABLE_TEST_IN_SANITIZERS(test_name) test_name
351
#endif
352
353
#if defined(__APPLE__) || defined(THREAD_SANITIZER) || defined(ADDRESS_SANITIZER)
354
#define YB_DISABLE_TEST_IN_SANITIZERS_OR_MAC(test_name) YB_DISABLE_TEST(test_name)
355
#else
356
#define YB_DISABLE_TEST_IN_SANITIZERS_OR_MAC(test_name) test_name
357
#endif
358
359
// TODO: use GTEST_SKIP() here when we upgrade gtest.
360
#define YB_SKIP_TEST_IN_TSAN() do { \
361
    if (::yb::IsTsan()) { \
362
      LOG(INFO) << "This test is skipped in TSAN"; \
363
      return; \
364
    } \
365
  } while (false)
366
367
#endif  // YB_UTIL_TEST_MACROS_H