YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/integration-tests/mini_cluster.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
33
#ifndef YB_INTEGRATION_TESTS_MINI_CLUSTER_H_
34
#define YB_INTEGRATION_TESTS_MINI_CLUSTER_H_
35
36
#include <chrono>
37
#include <memory>
38
#include <string>
39
#include <thread>
40
#include <unordered_set>
41
#include <vector>
42
43
#include "yb/client/client_fwd.h"
44
45
#include "yb/gutil/macros.h"
46
47
#include "yb/integration-tests/mini_cluster_base.h"
48
49
#include "yb/master/master_fwd.h"
50
#include "yb/master/master_client.fwd.h"
51
52
#include "yb/tablet/tablet_fwd.h"
53
54
#include "yb/tserver/tserver_fwd.h"
55
#include "yb/tserver/tablet_server_options.h"
56
57
#include "yb/util/env.h"
58
#include "yb/util/port_picker.h"
59
#include "yb/util/tsan_util.h"
60
61
namespace yb {
62
63
namespace master {
64
class MiniMaster;
65
}
66
67
namespace server {
68
class SkewedClockDeltaChanger;
69
}
70
71
namespace tserver {
72
class MiniTabletServer;
73
}
74
75
struct MiniClusterOptions {
76
  // Number of master servers.
77
  size_t num_masters = 1;
78
79
  // Number of TS to start.
80
  size_t num_tablet_servers = 1;
81
82
  // Number of drives to use on TS.
83
  int num_drives = 1;
84
85
  Env* master_env = Env::Default();
86
87
  // Custom Env and rocksdb::Env to be used by MiniTabletServer,
88
  // otherwise MiniTabletServer will use own Env and rocksdb::Env.
89
  Env* ts_env = nullptr;
90
  rocksdb::Env* ts_rocksdb_env = nullptr;
91
92
  // Directory in which to store data.
93
  // Default: empty string, which auto-generates a unique path for this cluster.
94
  // The default may only be used from a gtest unit test.
95
  std::string data_root{};
96
97
  // Cluster id used to create fs path when we create tests with multiple clusters.
98
  std::string cluster_id{};
99
};
100
101
// An in-process cluster with a MiniMaster and a configurable
102
// number of MiniTabletServers for use in tests.
103
class MiniCluster : public MiniClusterBase {
104
 public:
105
  typedef std::vector<std::shared_ptr<master::MiniMaster> > MiniMasters;
106
  typedef std::vector<std::shared_ptr<tserver::MiniTabletServer> > MiniTabletServers;
107
  typedef std::vector<uint16_t> Ports;
108
  typedef MiniClusterOptions Options;
109
110
  explicit MiniCluster(const MiniClusterOptions& options);
111
  ~MiniCluster();
112
113
  // Start a cluster with a Master and 'num_tablet_servers' TabletServers.
114
  // All servers run on the loopback interface with ephemeral ports.
115
  CHECKED_STATUS Start(
116
      const std::vector<tserver::TabletServerOptions>& extra_tserver_options =
117
      std::vector<tserver::TabletServerOptions>());
118
119
  // Like the previous method but performs initialization synchronously, i.e.
120
  // this will wait for all TS's to be started and initialized. Tests should
121
  // use this if they interact with tablets immediately after Start();
122
  CHECKED_STATUS StartSync();
123
124
  // Stop and restart the mini cluster synchronously. The cluster's persistent state will be kept.
125
  CHECKED_STATUS RestartSync();
126
127
  void Shutdown();
128
  CHECKED_STATUS FlushTablets(
129
      tablet::FlushMode mode = tablet::FlushMode::kSync,
130
      tablet::FlushFlags flags = tablet::FlushFlags::kAllDbs);
131
  CHECKED_STATUS CompactTablets();
132
  CHECKED_STATUS SwitchMemtables();
133
  CHECKED_STATUS CleanTabletLogs();
134
135
  // Shuts down masters only.
136
  void ShutdownMasters();
137
138
  // Setup a consensus configuration of distributed masters, with count specified in
139
  // 'options'. Requires that a reserve RPC port is specified in
140
  // 'options' for each master.
141
  CHECKED_STATUS StartMasters();
142
143
  // Add a new TS to the cluster. The new TS is started.
144
  // Requires that the master is already running.
145
  CHECKED_STATUS AddTabletServer(const tserver::TabletServerOptions& extra_opts);
146
147
  // Same as above, but get options from flags.
148
  CHECKED_STATUS AddTabletServer();
149
150
  CHECKED_STATUS AddTServerToBlacklist(const tserver::MiniTabletServer& ts);
151
  CHECKED_STATUS ClearBlacklist();
152
153
  // If this cluster is configured for a single non-distributed
154
  // master, return the single master. Exits with a CHECK failure if
155
  // there are multiple masters.
156
165
  master::MiniMaster* mini_master() {
157
165
    CHECK_EQ(mini_masters_.size(), 1);
158
165
    return mini_master(0);
159
165
  }
160
161
  // Returns the leader Master for this MiniCluster or error if none can be
162
  // elected within kMasterLeaderElectionWaitTimeSeconds. May block until a leader Master is ready.
163
  Result<master::MiniMaster*> GetLeaderMiniMaster();
164
165
  ssize_t LeaderMasterIdx();
166
167
  // Returns the Master at index 'idx' for this MiniCluster.
168
  master::MiniMaster* mini_master(size_t idx);
169
170
  // Return number of mini masters.
171
3.45k
  size_t num_masters() const { return mini_masters_.size(); }
172
173
  // Returns the TabletServer at index 'idx' of this MiniCluster.
174
  // 'idx' must be between 0 and 'num_tablet_servers' -1.
175
  tserver::MiniTabletServer* mini_tablet_server(size_t idx);
176
177
  tserver::MiniTabletServer* find_tablet_server(const std::string& uuid);
178
179
4
  const MiniTabletServers& mini_tablet_servers() { return mini_tablet_servers_; }
180
181
1.98k
  size_t num_tablet_servers() const { return mini_tablet_servers_.size(); }
182
183
0
  const Ports& tserver_web_ports() const { return tserver_web_ports_; }
184
185
  std::string GetMasterFsRoot(size_t indx);
186
187
  std::string GetTabletServerFsRoot(size_t idx);
188
189
  std::string GetTabletServerDrive(size_t idx, int drive_index);
190
191
  // The comma separated string of the master adresses host/ports from current list of masters.
192
  std::string GetMasterAddresses() const;
193
194
    // The comma separated string of the tserver adresses host/ports from current list of tservers.
195
  std::string GetTserverHTTPAddresses() const;
196
197
  std::vector<std::shared_ptr<tablet::TabletPeer>> GetTabletPeers(size_t idx);
198
199
  tserver::TSTabletManager* GetTabletManager(size_t idx);
200
201
  // Wait for the given tablet to have 'expected_count' replicas
202
  // reported on the master. Returns the locations in '*locations'.
203
  // Requires that the master has started;
204
  // Returns a bad Status if the tablet does not reach the required count
205
  // within kTabletReportWaitTimeSeconds.
206
  CHECKED_STATUS WaitForReplicaCount(const std::string& tablet_id,
207
                                     int expected_count,
208
                                     master::TabletLocationsPB* locations);
209
210
  // Wait until the number of registered tablet servers reaches the given
211
  // count. Returns Status::TimedOut if the desired count is not achieved
212
  // within kRegistrationWaitTimeSeconds.
213
  CHECKED_STATUS WaitForTabletServerCount(size_t count);
214
  CHECKED_STATUS WaitForTabletServerCount(
215
      size_t count, std::vector<std::shared_ptr<master::TSDescriptor>>* descs);
216
217
  // Wait for all tablet servers to be registered. Returns Status::TimedOut if the desired count is
218
  // not achieved within kRegistrationWaitTimeSeconds.
219
  CHECKED_STATUS WaitForAllTabletServers();
220
221
15
  uint16_t AllocateFreePort() {
222
15
    return port_picker_.AllocateFreePort();
223
15
  }
224
225
 private:
226
227
  void ConfigureClientBuilder(client::YBClientBuilder* builder) override;
228
229
  Result<HostPort> DoGetLeaderMasterBoundRpcAddr() override;
230
231
  // Allocates ports for the given daemon type and saves them to the ports vector. Does not
232
  // overwrite values in the ports vector that are non-zero already.
233
  void AllocatePortsForDaemonType(std::string daemon_type,
234
                                  size_t num_daemons,
235
                                  std::string port_type,
236
                                  std::vector<uint16_t>* ports);
237
238
  // Picks free ports for the necessary number of masters / tservers and saves those ports in
239
  // {master,tserver}_{rpc,web}_ports_ vectors. Values of 0 for the number of masters / tservers
240
  // mean we pick the maximum number of masters/tservers that we already know we'll need.
241
  void EnsurePortsAllocated(size_t new_num_masters = 0, size_t num_tservers = 0);
242
243
  const MiniClusterOptions options_;
244
  const std::string fs_root_;
245
246
  Ports master_rpc_ports_;
247
  Ports master_web_ports_;
248
  Ports tserver_rpc_ports_;
249
  Ports tserver_web_ports_;
250
251
  MiniMasters mini_masters_;
252
  MiniTabletServers mini_tablet_servers_;
253
254
  PortPicker port_picker_;
255
};
256
257
MUST_USE_RESULT std::vector<server::SkewedClockDeltaChanger> SkewClocks(
258
    MiniCluster* cluster, std::chrono::milliseconds clock_skew);
259
260
MUST_USE_RESULT std::vector<server::SkewedClockDeltaChanger> JumpClocks(
261
    MiniCluster* cluster, std::chrono::milliseconds delta);
262
263
void StepDownAllTablets(MiniCluster* cluster);
264
void StepDownRandomTablet(MiniCluster* cluster);
265
266
YB_DEFINE_ENUM(ListPeersFilter, (kAll)(kLeaders)(kNonLeaders));
267
268
std::unordered_set<std::string> ListTabletIdsForTable(
269
    MiniCluster* cluster, const std::string& table_id);
270
271
std::unordered_set<std::string> ListActiveTabletIdsForTable(
272
    MiniCluster* cluster, const std::string& table_id);
273
274
std::vector<std::shared_ptr<tablet::TabletPeer>> ListTabletPeers(
275
    MiniCluster* cluster, ListPeersFilter filter);
276
277
std::vector<std::shared_ptr<tablet::TabletPeer>> ListTabletPeers(
278
    MiniCluster* cluster,
279
    const std::function<bool(const std::shared_ptr<tablet::TabletPeer>&)>& filter);
280
281
std::vector<tablet::TabletPeerPtr> ListTableTabletPeers(
282
    MiniCluster* cluster, const TableId& table_id);
283
284
// By active tablet here we mean tablet is ready or going to be ready to serve read/write requests,
285
// i.e. not yet completed split or deleted (tombstoned).
286
std::vector<tablet::TabletPeerPtr> ListTableActiveTabletLeadersPeers(
287
    MiniCluster* cluster, const TableId& table_id);
288
289
std::vector<tablet::TabletPeerPtr> ListTableActiveTabletPeers(
290
    MiniCluster* cluster, const TableId& table_id);
291
std::vector<tablet::TabletPeerPtr> ListTableInactiveSplitTabletPeers(
292
    MiniCluster* cluster, const TableId& table_id);
293
294
std::vector<tablet::TabletPeerPtr> ListActiveTabletLeadersPeers(
295
    MiniCluster* cluster);
296
297
Result<std::vector<tablet::TabletPeerPtr>> WaitForTableActiveTabletLeadersPeers(
298
    MiniCluster* cluster, const TableId& table_id, size_t num_active_leaders,
299
    MonoDelta timeout = std::chrono::seconds(30) * kTimeMultiplier);
300
301
CHECKED_STATUS WaitUntilTabletHasLeader(
302
    MiniCluster* cluster, const std::string& tablet_id, MonoTime deadline);
303
304
CHECKED_STATUS WaitForLeaderOfSingleTablet(
305
    MiniCluster* cluster, tablet::TabletPeerPtr leader, MonoDelta duration,
306
    const std::string& description);
307
308
CHECKED_STATUS WaitUntilMasterHasLeader(MiniCluster* cluster, MonoDelta deadline);
309
310
YB_STRONGLY_TYPED_BOOL(ForceStepDown);
311
312
CHECKED_STATUS StepDown(
313
    tablet::TabletPeerPtr leader, const std::string& new_leader_uuid,
314
    ForceStepDown force_step_down);
315
316
// Waits until all tablet peers of the specified cluster are in the Running state.
317
// And total number of those peers equals to the number of tablet servers for each known tablet.
318
CHECKED_STATUS WaitAllReplicasReady(MiniCluster* cluster, MonoDelta timeout);
319
320
// Waits until all tablet peers of specified cluster have the specified index in their log.
321
// And total number of those peers equals to the number of tablet servers for each known tablet.
322
CHECKED_STATUS WaitAllReplicasHaveIndex(MiniCluster* cluster, int64_t index, MonoDelta timeout);
323
324
std::thread RestartsThread(
325
    MiniCluster* cluster, CoarseDuration interval, std::atomic<bool>* stop_flag);
326
327
std::vector<rocksdb::DB*> GetAllRocksDbs(MiniCluster* cluster, bool include_intents = true);
328
329
int NumTotalRunningCompactions(MiniCluster* cluster);
330
331
int NumRunningFlushes(MiniCluster* cluster);
332
333
Result<scoped_refptr<master::TableInfo>> FindTable(
334
    MiniCluster* cluster, const client::YBTableName& table_name);
335
336
CHECKED_STATUS WaitForInitDb(MiniCluster* cluster);
337
338
using TabletPeerFilter = std::function<bool(const tablet::TabletPeer*)>;
339
size_t CountIntents(MiniCluster* cluster, const TabletPeerFilter& filter = TabletPeerFilter());
340
341
tserver::MiniTabletServer* FindTabletLeader(MiniCluster* cluster, const TabletId& tablet_id);
342
343
void ShutdownAllTServers(MiniCluster* cluster);
344
CHECKED_STATUS StartAllTServers(MiniCluster* cluster);
345
void ShutdownAllMasters(MiniCluster* cluster);
346
CHECKED_STATUS StartAllMasters(MiniCluster* cluster);
347
348
YB_DEFINE_ENUM(Connectivity, (kOn)(kOff));
349
350
CHECKED_STATUS BreakConnectivity(MiniCluster* cluster, size_t idx1, size_t idx2);
351
CHECKED_STATUS SetupConnectivity(
352
    MiniCluster* cluster, size_t idx1, size_t idx2, Connectivity connectivity);
353
Result<size_t> ServerWithLeaders(MiniCluster* cluster);
354
355
// Sets FLAGS_rocksdb_compact_flush_rate_limit_bytes_per_sec and also adjusts rate limiter
356
// for already created tablets.
357
void SetCompactFlushRateLimitBytesPerSec(MiniCluster* cluster, size_t bytes_per_sec);
358
359
CHECKED_STATUS WaitAllReplicasSynchronizedWithLeader(
360
    MiniCluster* cluster, CoarseTimePoint deadline);
361
362
}  // namespace yb
363
364
#endif /* YB_INTEGRATION_TESTS_MINI_CLUSTER_H_ */