/Users/deen/code/yugabyte-db/src/yb/client/tablet_rpc-test.cc
Line | Count | Source |
1 | | // |
2 | | // Copyright (c) YugaByte, Inc. |
3 | | // |
4 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
5 | | // in compliance with the License. You may obtain a copy of the License at |
6 | | // |
7 | | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
10 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
11 | | // or implied. See the License for the specific language governing permissions and limitations |
12 | | // under the License. |
13 | | // |
14 | | // |
15 | | |
16 | | #include "yb/client/meta_cache.h" |
17 | | #include "yb/client/tablet_rpc.h" |
18 | | |
19 | | #include "yb/master/master_client.pb.h" |
20 | | |
21 | | #include "yb/util/test_util.h" |
22 | | #include "yb/util/trace.h" |
23 | | |
24 | | namespace yb { |
25 | | namespace client { |
26 | | namespace internal { |
27 | | |
28 | | const TabletId kTestTablet = "kTestTablet"; |
29 | | |
30 | | class TabletRpcTest : public YBTest { |
31 | | public: |
32 | 1 | TabletRpcTest() { |
33 | 1 | cloud_info_.set_placement_cloud("cloud1"); |
34 | 1 | cloud_info_.set_placement_region("datacenter1"); |
35 | 1 | cloud_info_.set_placement_zone("rack1"); |
36 | 1 | } |
37 | | |
38 | | void FillTsInfo( |
39 | | const std::string& uuid, const std::string& host, const std::string& addr, |
40 | 2 | master::TSInfoPB* ts_info) { |
41 | 2 | ts_info->set_permanent_uuid(uuid); |
42 | 2 | ts_info->mutable_cloud_info()->CopyFrom(cloud_info_); |
43 | 2 | ts_info->set_placement_uuid(""); |
44 | 2 | auto* rpc_addr = ts_info->add_private_rpc_addresses(); |
45 | 2 | rpc_addr->set_host(addr); |
46 | 2 | rpc_addr->set_port(9100); |
47 | 2 | } |
48 | | |
49 | | private: |
50 | | CloudInfoPB cloud_info_; |
51 | | }; |
52 | | |
53 | 1 | TEST_F(TabletRpcTest, TabletInvokerSelectTabletServerRace) { |
54 | | |
55 | 1 | master::TabletLocationsPB tablet_locations; |
56 | 1 | tablet_locations.set_tablet_id(kTestTablet); |
57 | 1 | tablet_locations.set_stale(false); |
58 | | |
59 | 1 | master::TabletLocationsPB_ReplicaPB replica1; |
60 | 1 | FillTsInfo("n1-uuid", "n1", "127.0.0.1", replica1.mutable_ts_info()); |
61 | | |
62 | 1 | master::TabletLocationsPB_ReplicaPB replica2; |
63 | 1 | FillTsInfo("n2-uuid", "n2", "127.0.0.2", replica2.mutable_ts_info()); |
64 | | |
65 | 1 | TabletServerMap ts_map; |
66 | | |
67 | 2 | for (auto* replica : {&replica1, &replica2}) { |
68 | 2 | replica->set_role(PeerRole::FOLLOWER); |
69 | 2 | replica->set_member_type(consensus::PeerMemberType::VOTER); |
70 | | |
71 | 2 | const auto& uuid = replica->ts_info().permanent_uuid(); |
72 | 2 | ts_map.emplace(uuid, std::make_unique<RemoteTabletServer>(uuid, nullptr, nullptr)); |
73 | 2 | } |
74 | | |
75 | 1 | Partition partition; |
76 | 1 | Partition::FromPB(tablet_locations.partition(), &partition); |
77 | 1 | internal::RemoteTabletPtr remote_tablet = new internal::RemoteTablet( |
78 | 1 | tablet_locations.tablet_id(), partition, /* partition_list_version = */ 0, |
79 | 1 | /* split_depth = */ 0, /* split_parent_id = */ ""); |
80 | | |
81 | 1 | std::atomic<bool> stop_requested{false}; |
82 | 1 | std::thread replicas_refresher( |
83 | 1 | [&stop_requested, &remote_tablet, &ts_map, &tablet_locations, &replica1, &replica2]{ |
84 | 1 | bool two_replicas = false; |
85 | 657 | while (!stop_requested) { |
86 | 656 | tablet_locations.clear_replicas(); |
87 | 656 | if (two_replicas) { |
88 | 328 | tablet_locations.add_replicas()->CopyFrom(replica1); |
89 | 328 | } |
90 | 656 | tablet_locations.add_replicas()->CopyFrom(replica2); |
91 | 656 | remote_tablet->Refresh(ts_map, tablet_locations.replicas()); |
92 | 656 | two_replicas = !two_replicas; |
93 | 656 | } |
94 | 1 | }); |
95 | | |
96 | 1 | scoped_refptr<Trace> trace(new Trace()); |
97 | | |
98 | 201 | for (int iter = 0; iter < 200; ++iter) { |
99 | 200 | internal::TabletInvoker invoker(false /* local_tserver_only */, |
100 | 200 | false /* consistent_prefix */, |
101 | 200 | nullptr /* client */, |
102 | 200 | nullptr /* command */, |
103 | 200 | nullptr /* rpc */, |
104 | 200 | remote_tablet.get(), |
105 | 200 | /* table =*/ nullptr, |
106 | 200 | nullptr /* retrier */, |
107 | 200 | trace.get()); |
108 | 200 | invoker.SelectTabletServer(); |
109 | 200 | } |
110 | | |
111 | 1 | stop_requested = true; |
112 | 1 | replicas_refresher.join(); |
113 | 1 | } |
114 | | |
115 | | } // namespace internal |
116 | | } // namespace client |
117 | | } // namespace yb |