/Users/deen/code/yugabyte-db/src/yb/master/master-test-util.cc
Line | Count | Source (jump to first uncovered line) |
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/master/master-test-util.h" |
17 | | |
18 | | #include <gtest/gtest.h> |
19 | | |
20 | | #include "yb/client/yb_table_name.h" |
21 | | |
22 | | #include "yb/common/wire_protocol.h" |
23 | | |
24 | | #include "yb/master/catalog_manager_if.h" |
25 | | #include "yb/master/master_client.pb.h" |
26 | | #include "yb/master/master_ddl.pb.h" |
27 | | #include "yb/master/mini_master.h" |
28 | | |
29 | | #include "yb/util/net/net_fwd.h" |
30 | | #include "yb/util/status.h" |
31 | | #include "yb/util/stopwatch.h" |
32 | | #include "yb/util/test_macros.h" |
33 | | |
34 | | DECLARE_int32(yb_num_shards_per_tserver); |
35 | | |
36 | | namespace yb { |
37 | | namespace master { |
38 | | |
39 | | Status WaitForRunningTabletCount(MiniMaster* mini_master, |
40 | | const client::YBTableName& table_name, |
41 | | int expected_count, |
42 | 0 | GetTableLocationsResponsePB* resp) { |
43 | 0 | int wait_time = 1000; |
44 | |
|
45 | 0 | SCOPED_LOG_TIMING(INFO, Format("waiting for tablet count of $0", expected_count)); |
46 | 0 | while (true) { |
47 | 0 | GetTableLocationsRequestPB req; |
48 | 0 | resp->Clear(); |
49 | 0 | table_name.SetIntoTableIdentifierPB(req.mutable_table()); |
50 | 0 | req.set_max_returned_locations(expected_count); |
51 | 0 | RETURN_NOT_OK(mini_master->catalog_manager().GetTableLocations(&req, resp)); |
52 | 0 | if (resp->tablet_locations_size() >= expected_count) { |
53 | 0 | bool is_stale = false; |
54 | 0 | for (const TabletLocationsPB& loc : resp->tablet_locations()) { |
55 | 0 | is_stale |= loc.stale(); |
56 | 0 | } |
57 | |
|
58 | 0 | if (!is_stale) { |
59 | 0 | return Status::OK(); |
60 | 0 | } |
61 | 0 | } |
62 | | |
63 | 0 | LOG(INFO) << "Waiting for " << expected_count << " tablets for table " |
64 | 0 | << table_name.ToString() << ". So far we have " << resp->tablet_locations_size(); |
65 | |
|
66 | 0 | SleepFor(MonoDelta::FromMicroseconds(wait_time)); |
67 | 0 | wait_time = std::min(wait_time * 5 / 4, 1000000); |
68 | 0 | } |
69 | | |
70 | | // Unreachable. |
71 | 0 | LOG(FATAL) << "Reached unreachable section"; |
72 | 0 | return STATUS(RuntimeError, "Unreachable statement"); // Suppress compiler warnings. |
73 | 0 | } |
74 | | |
75 | | void CreateTabletForTesting(MiniMaster* mini_master, |
76 | | const client::YBTableName& table_name, |
77 | | const Schema& schema, |
78 | | string* tablet_id, |
79 | 2 | string* table_id) { |
80 | 2 | { |
81 | 2 | CreateNamespaceRequestPB req; |
82 | 2 | CreateNamespaceResponsePB resp; |
83 | 2 | req.set_name(table_name.resolved_namespace_name()); |
84 | | |
85 | 2 | const Status s = mini_master->catalog_manager().CreateNamespace( |
86 | 2 | &req, &resp, /* rpc::RpcContext* */ nullptr); |
87 | 4 | ASSERT_TRUE(s.ok() || s.IsAlreadyPresent()) << " status=" << s.ToString(); |
88 | 2 | } |
89 | 2 | { |
90 | 2 | CreateTableRequestPB req; |
91 | 2 | CreateTableResponsePB resp; |
92 | | |
93 | 2 | req.set_name(table_name.table_name()); |
94 | 2 | req.mutable_namespace_()->set_name(table_name.resolved_namespace_name()); |
95 | | |
96 | 2 | SchemaToPB(schema, req.mutable_schema()); |
97 | 2 | ASSERT_OK(mini_master->catalog_manager().CreateTable( |
98 | 2 | &req, &resp, /* rpc::RpcContext* */ nullptr)); |
99 | 2 | } |
100 | | |
101 | 2 | int wait_time = 1000; |
102 | 2 | bool is_table_created = false; |
103 | 118 | for (int i = 0; i < 80; ++i116 ) { |
104 | 116 | IsCreateTableDoneRequestPB req; |
105 | 116 | IsCreateTableDoneResponsePB resp; |
106 | | |
107 | 116 | table_name.SetIntoTableIdentifierPB(req.mutable_table()); |
108 | 116 | ASSERT_OK(mini_master->catalog_manager().IsCreateTableDone(&req, &resp)); |
109 | 116 | if (resp.done()) { |
110 | 0 | is_table_created = true; |
111 | 0 | break; |
112 | 0 | } |
113 | | |
114 | 116 | VLOG(1) << "Waiting for table '" << table_name.ToString() << "'to be created"0 ; |
115 | | |
116 | 116 | SleepFor(MonoDelta::FromMicroseconds(wait_time)); |
117 | 116 | wait_time = std::min(wait_time * 5 / 4, 1000000); |
118 | 116 | } |
119 | 2 | ASSERT_TRUE(is_table_created); |
120 | | |
121 | 0 | { |
122 | 0 | GetTableSchemaRequestPB req; |
123 | 0 | GetTableSchemaResponsePB resp; |
124 | 0 | table_name.SetIntoTableIdentifierPB(req.mutable_table()); |
125 | 0 | ASSERT_OK(mini_master->catalog_manager().GetTableSchema(&req, &resp)); |
126 | 0 | ASSERT_TRUE(resp.create_table_done()); |
127 | 0 | if (table_id != nullptr) { |
128 | 0 | *table_id = resp.identifier().table_id(); |
129 | 0 | } |
130 | 0 | } |
131 | | |
132 | 0 | GetTableLocationsResponsePB resp; |
133 | 0 | ASSERT_OK(WaitForRunningTabletCount( |
134 | 0 | mini_master, table_name, FLAGS_yb_num_shards_per_tserver, &resp)); |
135 | 0 | *tablet_id = resp.tablet_locations(0).tablet_id(); |
136 | 0 | LOG(INFO) << "Got tablet " << *tablet_id << " for table " << table_name.ToString(); |
137 | 0 | } |
138 | | |
139 | | } // namespace master |
140 | | } // namespace yb |