YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/integration-tests/placement_info-itest.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) YugaByte, Inc.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
4
// in compliance with the License.  You may obtain a copy of the License at
5
//
6
// http://www.apache.org/licenses/LICENSE-2.0
7
//
8
// Unless required by applicable law or agreed to in writing, software distributed under the License
9
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
10
// or implied.  See the License for the specific language governing permissions and limitations
11
// under the License.
12
//
13
14
#include "yb/client/client-internal.h"
15
#include "yb/client/client.h"
16
#include "yb/client/meta_cache.h"
17
#include "yb/client/schema.h"
18
#include "yb/client/table_creator.h"
19
20
#include "yb/integration-tests/mini_cluster.h"
21
22
#include "yb/master/master_client.proxy.h"
23
#include "yb/master/master_defaults.h"
24
#include "yb/master/mini_master.h"
25
26
#include "yb/rpc/messenger.h"
27
#include "yb/rpc/proxy.h"
28
#include "yb/rpc/rpc_controller.h"
29
30
#include "yb/tserver/mini_tablet_server.h"
31
#include "yb/tserver/tablet_server.h"
32
33
#include "yb/util/result.h"
34
#include "yb/util/status_log.h"
35
#include "yb/util/test_util.h"
36
37
DECLARE_bool(TEST_check_broadcast_address);
38
39
namespace yb {
40
namespace client {
41
42
class PlacementInfoTest : public YBTest {
43
 public:
44
2
  PlacementInfoTest() {}
45
46
0
  ~PlacementInfoTest() {}
47
48
  const int kNumTservers = 3;
49
50
 protected:
51
2
  void SetUp() override {
52
2
    FLAGS_TEST_check_broadcast_address = false;
53
54
2
    YBTest::SetUp();
55
2
    MiniClusterOptions opts;
56
2
    opts.num_masters = 1;
57
2
    opts.num_tablet_servers = kNumTservers;
58
59
    // Start tservers with different placement information.
60
2
    std::vector<tserver::TabletServerOptions> tserver_opts;
61
8
    for (int i = 0; i < kNumTservers; i++) {
62
6
      auto opts = tserver::TabletServerOptions::CreateTabletServerOptions();
63
6
      ASSERT_OK(opts);
64
6
      opts->SetPlacement("aws", PlacementRegion(i), PlacementZone(i));
65
6
      tserver_opts.push_back(*opts);
66
6
    }
67
68
2
    cluster_.reset(new MiniCluster(opts));
69
2
    ASSERT_OK(cluster_->Start(tserver_opts));
70
0
    for (size_t i = 0; i < cluster_->num_tablet_servers(); i++) {
71
0
      std::string ts_uuid = cluster_->mini_tablet_server(i)->server()->fs_manager()->uuid();
72
0
      ts_uuid_to_index_.emplace(ts_uuid, i);
73
0
    }
74
75
0
    client_ = ASSERT_RESULT(cluster_->CreateClient());
76
0
    rpc::MessengerBuilder bld("Client");
77
0
    client_messenger_ = ASSERT_RESULT(bld.Build());
78
0
    rpc::ProxyCache proxy_cache(client_messenger_.get());
79
0
    proxy_.reset(new master::MasterClientProxy(
80
0
        &proxy_cache, ASSERT_RESULT(cluster_->GetLeaderMiniMaster())->bound_rpc_addr()));
81
82
    // Create the table.
83
0
    YBSchema schema;
84
0
    YBSchemaBuilder b;
85
0
    b.AddColumn("key")->Type(INT32)->NotNull()->PrimaryKey();
86
0
    b.AddColumn("int_val")->Type(INT32)->NotNull();
87
0
    CHECK_OK(b.Build(&schema));
88
0
    std::unique_ptr<YBTableCreator> table_creator(client_->NewTableCreator());
89
0
    table_name_ = std::make_unique<YBTableName>(YQL_DATABASE_CQL, "test_tablet_locations");
90
0
    table_name_->set_namespace_name(yb::master::kSystemNamespaceName);
91
0
    CHECK_OK(table_creator->table_name(*table_name_)
92
0
                 .schema(&schema)
93
0
                 .hash_schema(YBHashSchema::kMultiColumnHash)
94
0
                 .wait(true)
95
0
                 .num_tablets(1)
96
0
                 .Create());
97
98
0
  }
99
100
6
  std::string PlacementRegion(int ts_index) {
101
6
    return strings::Substitute("region$0", ts_index);
102
6
  }
103
104
6
  std::string PlacementZone(int ts_index) {
105
6
    return strings::Substitute("zone$0", ts_index);
106
6
  }
107
108
0
  void TearDown() override {
109
0
    client_messenger_->Shutdown();
110
0
    client_.reset();
111
0
    if (cluster_) {
112
0
      cluster_->Shutdown();
113
0
      cluster_.reset();
114
0
    }
115
116
0
    YBTest::TearDown();
117
0
  }
118
119
0
  void GetTabletLocations(master::TabletLocationsPB* tablet_locations) {
120
    // Retrieve tablets.
121
0
    rpc::RpcController controller;
122
0
    master::GetTableLocationsRequestPB req;
123
0
    master::GetTableLocationsResponsePB resp;
124
0
    table_name_->SetIntoTableIdentifierPB(req.mutable_table());
125
0
    ASSERT_OK(proxy_->GetTableLocations(req, &resp, &controller));
126
127
    // Verify tablet information.
128
0
    ASSERT_EQ(1, resp.tablet_locations_size());
129
0
    *tablet_locations = resp.tablet_locations(0);
130
0
    ASSERT_EQ(kNumTservers, tablet_locations->replicas_size());
131
0
  }
132
133
  void ValidateSelectTServer(const std::string& client_uuid, const std::string& placement_zone,
134
                             const std::string& placement_region,
135
                             int expected_ts_index,
136
0
                             internal::RemoteTablet* remote_tablet) {
137
0
    CloudInfoPB cloud_info;
138
0
    cloud_info.set_placement_zone(placement_zone);
139
0
    cloud_info.set_placement_region(placement_region);
140
141
0
    YBClientBuilder client_builder;
142
0
    client_builder.set_tserver_uuid(client_uuid);
143
0
    client_builder.set_cloud_info_pb(cloud_info);
144
0
    client_builder.add_master_server_addr(
145
0
        ASSERT_RESULT(cluster_->GetLeaderMiniMaster())->bound_rpc_addr_str());
146
0
    auto client = CHECK_RESULT(client_builder.Build());
147
148
    // Select tserver.
149
0
    vector<internal::RemoteTabletServer *> candidates;
150
0
    internal::RemoteTabletServer *tserver = client->data_->SelectTServer(
151
0
        remote_tablet, YBClient::ReplicaSelection::CLOSEST_REPLICA, std::set<string>(),
152
0
        &candidates);
153
0
    ASSERT_EQ(expected_ts_index, ts_uuid_to_index_[tserver->permanent_uuid()])
154
0
        << "Client UUID: " << client_uuid << ", zone: " << placement_zone
155
0
        << ", region: " << placement_region;
156
0
  }
157
158
  std::unique_ptr<MiniCluster> cluster_;
159
  std::unique_ptr<YBClient> client_;
160
  std::unique_ptr<master::MasterClientProxy> proxy_;
161
  std::unique_ptr<rpc::Messenger> client_messenger_;
162
  std::map<std::string, int> ts_uuid_to_index_;
163
  std::unique_ptr<YBTableName> table_name_;
164
};
165
166
TEST_F(PlacementInfoTest, TestTabletLocations) {
167
  master::TabletLocationsPB tablet_locations;
168
  GetTabletLocations(&tablet_locations);
169
  for (int i = 0; i < tablet_locations.replicas_size(); i++) {
170
    // Find the ts by uuid.
171
    auto cloud_info = tablet_locations.replicas(i).ts_info().cloud_info();
172
    auto ts_uuid = tablet_locations.replicas(i).ts_info().permanent_uuid();
173
    auto it = ts_uuid_to_index_.find(ts_uuid);
174
    int ts_index = (*it).second;
175
    ASSERT_TRUE(it != ts_uuid_to_index_.end());
176
177
    // Remove it from the map to ensure we look through all ts uuids.
178
    ts_uuid_to_index_.erase(it);
179
180
    ASSERT_EQ("aws", cloud_info.placement_cloud());
181
    ASSERT_EQ(PlacementRegion(ts_index), cloud_info.placement_region());
182
    ASSERT_EQ(PlacementZone(ts_index), cloud_info.placement_zone());
183
  }
184
  ASSERT_EQ(0, ts_uuid_to_index_.size());
185
}
186
187
0
TEST_F(PlacementInfoTest, TestSelectTServer) {
188
0
  master::TabletLocationsPB tablet_locations;
189
0
  GetTabletLocations(&tablet_locations);
190
191
0
  Partition partition;
192
0
  Partition::FromPB(tablet_locations.partition(), &partition);
193
0
  internal::RemoteTabletPtr remote_tablet = new internal::RemoteTablet(
194
0
      tablet_locations.tablet_id(), partition, /* partition_list_version = */ 0,
195
0
      /* split_depth = */ 0, /* split_parent_id = */ "");
196
197
  // Build remote tserver map.
198
0
  internal::TabletServerMap tserver_map;
199
0
  for (const master::TabletLocationsPB::ReplicaPB& replica : tablet_locations.replicas()) {
200
0
    tserver_map.emplace(replica.ts_info().permanent_uuid(),
201
0
                        std::make_unique<internal::RemoteTabletServer>(replica.ts_info()));
202
0
  }
203
204
  // Refresh replicas for RemoteTablet.
205
0
  remote_tablet->Refresh(tserver_map, tablet_locations.replicas());
206
207
0
  for (int ts_index = 0; ts_index < kNumTservers; ts_index++) {
208
0
    auto uuid = cluster_->mini_tablet_server(ts_index)->server()->permanent_uuid();
209
0
    auto zone = PlacementZone(ts_index);
210
0
    auto region = PlacementRegion(ts_index);
211
0
    ValidateSelectTServer(uuid, "", "", ts_index, remote_tablet.get());
212
0
    ValidateSelectTServer("", zone, region, ts_index, remote_tablet.get());
213
0
    ValidateSelectTServer("", "", region, ts_index, remote_tablet.get());
214
0
    ValidateSelectTServer(
215
0
        uuid, PlacementZone((ts_index + 1) % kNumTservers),
216
0
        PlacementRegion((ts_index + 2) % kNumTservers), ts_index, remote_tablet.get());
217
0
  }
218
0
}
219
220
} // namespace client
221
} // namespace yb