YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/util/test_util.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
// Base test class, with various utility functions.
33
#ifndef YB_UTIL_TEST_UTIL_H
34
#define YB_UTIL_TEST_UTIL_H
35
36
#include <dirent.h>
37
38
#include <atomic>
39
#include <string>
40
41
#include <glog/logging.h>
42
#include <gtest/gtest.h>
43
44
#include "yb/util/env.h"
45
#include "yb/util/monotime.h"
46
#include "yb/util/port_picker.h"
47
#include "yb/util/test_macros.h" // For convenience
48
49
14
#define ASSERT_EVENTUALLY(expr) do { \
50
549
  AssertEventually(expr); \
raft_consensus-itest.cc:_ZZN2yb7tserver50RaftConsensusITest_DisruptiveServerAndSlowWAL_Test8TestBodyEvENK3$_1clEv
Line
Count
Source
50
105
  AssertEventually(expr); \
periodic-test.cc:_ZZN2yb3rpc44JitteredPeriodicTimerTest_TestStartStop_Test8TestBodyEvENK3$_0clEv
Line
Count
Source
50
8
  AssertEventually(expr); \
periodic-test.cc:_ZZN2yb3rpc49JitteredPeriodicTimerTest_TestResetWithDelta_Test8TestBodyEvENK3$_1clEv
Line
Count
Source
50
88
  AssertEventually(expr); \
periodic-test.cc:_ZZN2yb3rpc49JitteredPeriodicTimerTest_TestStartWithDelta_Test8TestBodyEvENK3$_2clEv
Line
Count
Source
50
88
  AssertEventually(expr); \
periodic-test.cc:_ZZN2yb3rpc48JitteredOneShotPeriodicTimerTest_TestBasics_Test8TestBodyEvENK3$_4clEv
Line
Count
Source
50
216
  AssertEventually(expr); \
periodic-test.cc:_ZZN2yb3rpc55PeriodicTimerTest_TestCallbackRestartsOneShotTimer_Test8TestBodyEvENK3$_6clEv
Line
Count
Source
50
44
  AssertEventually(expr); \
51
14
  NO_PENDING_FATALS(); \
52
14
} while (0)
53
54
namespace yb {
55
namespace rpc {
56
57
class Messenger;
58
59
} // namespace rpc
60
61
// Our test string literals contain "\x00" that is treated as a C-string null-terminator.
62
// So we need to call the std::string constructor that takes the length argument.
63
0
#define BINARY_STRING(s) std::string((s), sizeof(s) - 1)
64
65
class YBTest : public ::testing::Test {
66
 public:
67
  YBTest();
68
69
  // Env passed in from subclass, for tests that run in-memory.
70
  explicit YBTest(Env *env);
71
72
  virtual ~YBTest();
73
74
  virtual void SetUp() override;
75
76
 protected:
77
  // Returns absolute path based on a unit test-specific work directory, given
78
  // a relative path. Useful for writing test files that should be deleted after
79
  // the test ends.
80
  std::string GetTestPath(const std::string& relative_path);
81
82
108
  uint16_t AllocateFreePort() { return port_picker_.AllocateFreePort(); }
83
84
  std::unique_ptr<Env> env_;
85
  google::FlagSaver flag_saver_;  // Reset flags on every test.
86
  PortPicker port_picker_;
87
88
 private:
89
  std::string test_dir_;
90
};
91
92
// Returns true if slow tests are runtime-enabled.
93
bool AllowSlowTests();
94
95
// Override the given gflag to the new value, only in the case that
96
// slow tests are enabled and the user hasn't otherwise overridden
97
// it on the command line.
98
// Example usage:
99
//
100
// OverrideFlagForSlowTests(
101
//     "client_inserts_per_thread",
102
//     strings::Substitute("$0", FLAGS_client_inserts_per_thread * 100));
103
//
104
void OverrideFlagForSlowTests(const std::string& flag_name,
105
                              const std::string& new_value);
106
107
// Call srand() with a random seed based on the current time, reporting
108
// that seed to the logs. The time-based seed may be overridden by passing
109
// --test_random_seed= from the CLI in order to reproduce a failed randomized
110
// test. Returns the seed.
111
int SeedRandom();
112
113
// Return a per-test directory in which to store test data. Guaranteed to
114
// return the same directory every time for a given unit test.
115
//
116
// May only be called from within a gtest unit test.
117
std::string GetTestDataDirectory();
118
119
// Wait until 'f()' succeeds without adding any GTest 'fatal failures'.
120
// For example:
121
//
122
//   AssertEventually([]() {
123
//     ASSERT_GT(ReadValueOfMetric(), 10);
124
//   });
125
//
126
// The function is run in a loop with exponential backoff, capped at once
127
// a second.
128
//
129
// To check whether AssertEventually() eventually succeeded, call
130
// NO_PENDING_FATALS() afterward, or use ASSERT_EVENTUALLY() which performs
131
// this check automatically.
132
void AssertEventually(const std::function<void(void)>& f,
133
                      const MonoDelta& timeout = MonoDelta::FromSeconds(30));
134
135
// Logs some of the differences between the two given vectors. This can be used immediately before
136
// asserting that two vectors are equal to make debugging easier.
137
template<typename T>
138
21
void LogVectorDiff(const std::vector<T>& expected, const std::vector<T>& actual) {
139
21
  if (expected.size() != actual.size()) {
140
0
    LOG(WARNING) << "Expected size: " << expected.size() << ", actual size: " << actual.size();
141
0
    const std::vector<T> *bigger_vector, *smaller_vector;
142
0
    const char *bigger_vector_desc;
143
0
    if (expected.size() > actual.size()) {
144
0
      bigger_vector = &expected;
145
0
      bigger_vector_desc = "expected";
146
0
      smaller_vector = &actual;
147
0
    } else {
148
0
      bigger_vector = &actual;
149
0
      bigger_vector_desc = "actual";
150
0
      smaller_vector = &expected;
151
0
    }
152
153
0
    for (auto i = smaller_vector->size();
154
0
         i < min(smaller_vector->size() + 16, bigger_vector->size());
155
0
         ++i) {
156
0
      LOG(WARNING) << bigger_vector_desc << "[" << i << "]: " << (*bigger_vector)[i];
157
0
    }
158
0
  }
159
21
  int num_differences_logged = 0;
160
21
  size_t num_differences_left = 0;
161
21
  size_t min_size = min(expected.size(), actual.size());
162
68
  for (size_t i = 0; i < min_size; ++i) {
163
47
    if (expected[i] != actual[i]) {
164
0
      if (num_differences_logged < 16) {
165
0
        LOG(WARNING) << "expected[" << i << "]: " << expected[i];
166
0
        LOG(WARNING) << "actual  [" << i << "]: " << actual[i];
167
0
        ++num_differences_logged;
168
0
      } else {
169
0
        ++num_differences_left;
170
0
      }
171
0
    }
172
47
  }
173
21
  if (num_differences_left > 0) {
174
0
    if (expected.size() == actual.size()) {
175
0
      LOG(WARNING) << num_differences_left << " more differences omitted";
176
0
    } else {
177
0
      LOG(WARNING) << num_differences_left << " more differences in the first " << min_size
178
0
      << " elements omitted";
179
0
    }
180
0
  }
181
21
}
182
183
namespace test_util {
184
185
constexpr int kDefaultInitialWaitMs = 1;
186
constexpr double kDefaultWaitDelayMultiplier = 1.1;
187
constexpr int kDefaultMaxWaitDelayMs = 2000;
188
189
} // namespace test_util
190
191
// Waits for the given condition to be true or until the provided deadline happens.
192
CHECKED_STATUS Wait(
193
    const std::function<Result<bool>()>& condition,
194
    MonoTime deadline,
195
    const std::string& description,
196
    MonoDelta initial_delay = MonoDelta::FromMilliseconds(test_util::kDefaultInitialWaitMs),
197
    double delay_multiplier = test_util::kDefaultWaitDelayMultiplier,
198
    MonoDelta max_delay = MonoDelta::FromMilliseconds(test_util::kDefaultMaxWaitDelayMs));
199
200
CHECKED_STATUS Wait(
201
    const std::function<Result<bool>()>& condition,
202
    CoarseTimePoint deadline,
203
    const std::string& description,
204
    MonoDelta initial_delay = MonoDelta::FromMilliseconds(test_util::kDefaultInitialWaitMs),
205
    double delay_multiplier = test_util::kDefaultWaitDelayMultiplier,
206
    MonoDelta max_delay = MonoDelta::FromMilliseconds(test_util::kDefaultMaxWaitDelayMs));
207
208
CHECKED_STATUS LoggedWait(
209
    const std::function<Result<bool>()>& condition,
210
    CoarseTimePoint deadline,
211
    const std::string& description,
212
    MonoDelta initial_delay = MonoDelta::FromMilliseconds(test_util::kDefaultInitialWaitMs),
213
    double delay_multiplier = test_util::kDefaultWaitDelayMultiplier,
214
    MonoDelta max_delay = MonoDelta::FromMilliseconds(test_util::kDefaultMaxWaitDelayMs));
215
216
// Waits for the given condition to be true or until the provided timeout has expired.
217
CHECKED_STATUS WaitFor(
218
    const std::function<Result<bool>()>& condition,
219
    MonoDelta timeout,
220
    const std::string& description,
221
    MonoDelta initial_delay = MonoDelta::FromMilliseconds(test_util::kDefaultInitialWaitMs),
222
    double delay_multiplier = test_util::kDefaultWaitDelayMultiplier,
223
    MonoDelta max_delay = MonoDelta::FromMilliseconds(test_util::kDefaultMaxWaitDelayMs));
224
225
CHECKED_STATUS LoggedWaitFor(
226
    const std::function<Result<bool>()>& condition,
227
    MonoDelta timeout,
228
    const std::string& description,
229
    MonoDelta initial_delay = MonoDelta::FromMilliseconds(test_util::kDefaultInitialWaitMs),
230
    double delay_multiplier = test_util::kDefaultWaitDelayMultiplier,
231
    MonoDelta max_delay = MonoDelta::FromMilliseconds(test_util::kDefaultMaxWaitDelayMs));
232
233
// Return the path of a yb-tool.
234
std::string GetToolPath(const std::string& rel_path, const std::string& tool_name);
235
236
1
inline std::string GetToolPath(const std::string& tool_name) {
237
1
  return GetToolPath("../bin", tool_name);
238
1
}
239
240
0
inline std::string GetPgToolPath(const std::string& tool_name) {
241
0
  return GetToolPath("../postgres/bin", tool_name);
242
0
}
243
244
int CalcNumTablets(size_t num_tablet_servers);
245
246
template<uint32_t limit>
247
struct LengthLimitedStringPrinter {
248
  explicit LengthLimitedStringPrinter(const std::string& str_)
249
0
      : str(str_) {
250
0
  }
251
  const std::string& str;
252
};
253
254
using Max500CharsPrinter = LengthLimitedStringPrinter<500>;
255
256
template<uint32_t limit>
257
0
std::ostream& operator<<(std::ostream& os, const LengthLimitedStringPrinter<limit>& printer) {
258
0
  const auto& s = printer.str;
259
0
  if (s.length() <= limit) {
260
0
    return os << s;
261
0
  }
262
0
  return os.write(s.c_str(), limit) << "... (" << (s.length() - limit) << " more characters)";
263
0
}
264
265
class StopOnFailure {
266
 public:
267
0
  explicit StopOnFailure(std::atomic<bool>* stop) : stop_(*stop) {}
268
269
  StopOnFailure(const StopOnFailure&) = delete;
270
  void operator=(const StopOnFailure&) = delete;
271
272
0
  ~StopOnFailure() {
273
0
    if (!success_) {
274
0
      stop_.store(true, std::memory_order_release);
275
0
    }
276
0
  }
277
278
0
  void Success() {
279
0
    success_ = true;
280
0
  }
281
 private:
282
  bool success_ = false;
283
  std::atomic<bool>& stop_;
284
};
285
286
} // namespace yb
287
288
// Gives ability to define custom parent class for test fixture.
289
#define TEST_F_EX(test_case_name, test_name, parent_class) \
290
  GTEST_TEST_(test_case_name, test_name, parent_class, \
291
              ::testing::internal::GetTypeId<test_case_name>())
292
293
#endif  // YB_UTIL_TEST_UTIL_H