/Users/deen/code/yugabyte-db/src/yb/integration-tests/test_workload.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 | | #ifndef YB_INTEGRATION_TESTS_TEST_WORKLOAD_H_ |
33 | | #define YB_INTEGRATION_TESTS_TEST_WORKLOAD_H_ |
34 | | |
35 | | #include "yb/client/client_fwd.h" |
36 | | #include "yb/client/table.h" |
37 | | #include "yb/client/yb_table_name.h" |
38 | | |
39 | | #include "yb/common/transaction.pb.h" |
40 | | |
41 | | #include "yb/util/monotime.h" |
42 | | |
43 | | namespace yb { |
44 | | |
45 | | class MiniClusterBase; |
46 | | class Thread; |
47 | | |
48 | | struct TestWorkloadOptions { |
49 | | static const client::YBTableName kDefaultTableName; |
50 | | |
51 | | size_t payload_bytes = 11; |
52 | | int num_write_threads = 4; |
53 | | int num_read_threads = 0; |
54 | | int write_batch_size = 50; |
55 | | int write_interval_millis = 0; |
56 | | int ttl = -1; |
57 | | int table_ttl = -1; |
58 | | MonoDelta default_rpc_timeout = std::chrono::seconds(60); |
59 | | std::chrono::milliseconds write_timeout = std::chrono::seconds(20); |
60 | | bool timeout_allowed = false; |
61 | | bool not_found_allowed = false; |
62 | | bool pathological_one_row_enabled = false; |
63 | | bool sequential_write = false; |
64 | | bool insert_failures_allowed = true; |
65 | | bool retry_on_restart_required_error = false; |
66 | | bool read_only_written_keys = false; |
67 | | IsolationLevel isolation_level = IsolationLevel::NON_TRANSACTIONAL; |
68 | | |
69 | | int num_tablets = 1; |
70 | | client::YBTableName table_name = kDefaultTableName; |
71 | | |
72 | 7.48k | bool is_transactional() const { return isolation_level != IsolationLevel::NON_TRANSACTIONAL; } |
73 | 15 | bool has_table_ttl() const { return table_ttl != -1; } |
74 | | }; |
75 | | |
76 | | // Utility class for generating a workload against a test cluster. |
77 | | // |
78 | | // The actual data inserted is random, and thus can't be verified for |
79 | | // integrity. However, this is still useful in conjunction with ClusterVerifier |
80 | | // to verify that replicas do not diverge. |
81 | | class TestWorkload { |
82 | | public: |
83 | | explicit TestWorkload(MiniClusterBase* cluster); |
84 | | ~TestWorkload(); |
85 | | |
86 | | TestWorkload(TestWorkload&& rhs); |
87 | | |
88 | | void operator=(TestWorkload&& rhs); |
89 | | |
90 | | void set_payload_bytes(size_t n) { |
91 | | options_.payload_bytes = n; |
92 | | } |
93 | | |
94 | 0 | void set_num_read_threads(int n) { |
95 | 0 | options_.num_read_threads = n; |
96 | 0 | } |
97 | | |
98 | | void set_num_write_threads(int n) { |
99 | | options_.num_write_threads = n; |
100 | | } |
101 | | |
102 | | void set_write_batch_size(int s) { |
103 | | options_.write_batch_size = s; |
104 | | } |
105 | | |
106 | | void set_write_interval_millis(int t) { |
107 | | options_.write_interval_millis = t; |
108 | | } |
109 | | |
110 | 0 | void set_ttl(int ttl) { |
111 | 0 | options_.ttl = ttl; |
112 | 0 | } |
113 | | |
114 | 0 | void set_table_ttl(int ttl_sec) { |
115 | 0 | options_.table_ttl = ttl_sec; |
116 | 0 | } |
117 | | |
118 | | void set_client_default_rpc_timeout_millis(int t) { |
119 | | options_.default_rpc_timeout = MonoDelta::FromMilliseconds(t); |
120 | | } |
121 | | |
122 | 0 | void set_write_timeout(std::chrono::milliseconds value) { |
123 | 0 | options_.write_timeout = value; |
124 | 0 | } |
125 | | |
126 | | void set_write_timeout_millis(int64_t t) { |
127 | | options_.write_timeout = std::chrono::milliseconds(t); |
128 | | } |
129 | | |
130 | | // Set whether to fail if we see a TimedOut() error inserting a row. |
131 | | // By default, this triggers a CHECK failure. |
132 | | void set_timeout_allowed(bool allowed) { |
133 | | options_.timeout_allowed = allowed; |
134 | | } |
135 | | |
136 | | // Set whether to fail if we see a NotFound() error inserting a row. |
137 | | // This sort of error is triggered if the table is deleted while the workload |
138 | | // is running. |
139 | | // By default, this triggers a CHECK failure. |
140 | | void set_not_found_allowed(bool allowed) { |
141 | | options_.not_found_allowed = allowed; |
142 | | } |
143 | | |
144 | | // Set the number of tablets for the table created by this workload. |
145 | | // The split points are evenly distributed through positive int32s. |
146 | | void set_num_tablets(int tablets) { |
147 | | CHECK_GE(tablets, 1); |
148 | | options_.num_tablets = tablets; |
149 | | } |
150 | | |
151 | | void set_table_name(const client::YBTableName& table_name) { |
152 | | options_.table_name = table_name; |
153 | | } |
154 | | |
155 | | const client::YBTableName& table_name() const { |
156 | | return options_.table_name; |
157 | | } |
158 | | |
159 | | client::YBClient& client() const; |
160 | | |
161 | 0 | void set_pathological_one_row_enabled(bool enabled) { |
162 | 0 | options_.pathological_one_row_enabled = enabled; |
163 | 0 | } |
164 | | |
165 | | void set_sequential_write(bool value) { |
166 | | options_.sequential_write = value; |
167 | | } |
168 | | |
169 | 0 | void set_insert_failures_allowed(bool value) { |
170 | 0 | options_.insert_failures_allowed = value; |
171 | 0 | } |
172 | | |
173 | 0 | void set_retry_on_restart_required_error(const bool value) { |
174 | 0 | options_.retry_on_restart_required_error = value; |
175 | 0 | } |
176 | | |
177 | | // Only read keys which have been successfully written. |
178 | | // REQUIRED: works only when sequential_write is set and we have write threads to generate keys |
179 | | // to read. |
180 | 0 | void set_read_only_written_keys(const bool value) { |
181 | 0 | options_.read_only_written_keys = value; |
182 | 0 | } |
183 | | |
184 | | void set_transactional(IsolationLevel isolation_level, client::TransactionPool* pool); |
185 | | |
186 | | // Sets up the internal client and creates the table which will be used for |
187 | | // writing, if it doesn't already exist. |
188 | | void Setup(client::YBTableType table_type = client::YBTableType::YQL_TABLE_TYPE); |
189 | | |
190 | | // Start the write workload. |
191 | | void Start(); |
192 | | |
193 | | // Stop the writers and wait for them to exit. |
194 | | void StopAndJoin(); |
195 | | |
196 | | void Stop(); |
197 | | |
198 | | void Join(); |
199 | | |
200 | | void WaitInserted(int64_t required); |
201 | | |
202 | | // Return the number of rows inserted so far. This may be called either |
203 | | // during or after the write workload. |
204 | | int64_t rows_inserted() const; |
205 | | |
206 | | int64_t rows_insert_failed() const; |
207 | | |
208 | | int64_t rows_read_ok() const; |
209 | | |
210 | | int64_t rows_read_empty() const; |
211 | | |
212 | | int64_t rows_read_error() const; |
213 | | |
214 | | int64_t rows_read_try_again() const; |
215 | | |
216 | | // Return the number of batches in which we have successfully inserted at |
217 | | // least one row. |
218 | | int64_t batches_completed() const; |
219 | | |
220 | | private: |
221 | | class State; |
222 | | |
223 | | TestWorkloadOptions options_; |
224 | | std::unique_ptr<State> state_; |
225 | | }; |
226 | | |
227 | | } // namespace yb |
228 | | #endif // YB_INTEGRATION_TESTS_TEST_WORKLOAD_H_ |