]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/tools/trace_analyzer_test.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / rocksdb / tools / trace_analyzer_test.cc
CommitLineData
11fdf7f2
TL
1// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2// This source code is licensed under both the GPLv2 (found in the
3// COPYING file in the root directory) and Apache 2.0 License
4// (found in the LICENSE.Apache file in the root directory).
5//
6// Copyright (c) 2012 The LevelDB Authors. All rights reserved.
7// Use of this source code is governed by a BSD-style license that can be
8// found in the LICENSE file. See the AUTHORS file for names of contributors.
9
10#ifndef ROCKSDB_LITE
11#ifndef GFLAGS
12#include <cstdio>
13int main() {
14 fprintf(stderr, "Please install gflags to run trace_analyzer test\n");
15 return 1;
16}
17#else
18
19#include <chrono>
20#include <cstdio>
21#include <cstdlib>
22#include <sstream>
23#include <thread>
24
25#include "db/db_test_util.h"
f67539c2 26#include "file/read_write_util.h"
11fdf7f2
TL
27#include "rocksdb/db.h"
28#include "rocksdb/env.h"
29#include "rocksdb/status.h"
30#include "rocksdb/trace_reader_writer.h"
f67539c2
TL
31#include "test_util/testharness.h"
32#include "test_util/testutil.h"
11fdf7f2 33#include "tools/trace_analyzer_tool.h"
f67539c2 34#include "trace_replay/trace_replay.h"
11fdf7f2 35
f67539c2 36namespace ROCKSDB_NAMESPACE {
11fdf7f2
TL
37
38namespace {
39static const int kMaxArgCount = 100;
40static const size_t kArgBufferSize = 100000;
41} // namespace
42
43// The helper functions for the test
44class TraceAnalyzerTest : public testing::Test {
45 public:
46 TraceAnalyzerTest() : rnd_(0xFB) {
47 // test_path_ = test::TmpDir() + "trace_analyzer_test";
48 test_path_ = test::PerThreadDBPath("trace_analyzer_test");
f67539c2 49 env_ = ROCKSDB_NAMESPACE::Env::Default();
11fdf7f2
TL
50 env_->CreateDir(test_path_);
51 dbname_ = test_path_ + "/db";
52 }
53
494da23a 54 ~TraceAnalyzerTest() override {}
11fdf7f2
TL
55
56 void GenerateTrace(std::string trace_path) {
57 Options options;
58 options.create_if_missing = true;
59 options.merge_operator = MergeOperators::CreatePutOperator();
60 ReadOptions ro;
61 WriteOptions wo;
62 TraceOptions trace_opt;
63 DB* db_ = nullptr;
64 std::string value;
65 std::unique_ptr<TraceWriter> trace_writer;
66 Iterator* single_iter = nullptr;
67
68 ASSERT_OK(
69 NewFileTraceWriter(env_, env_options_, trace_path, &trace_writer));
70 ASSERT_OK(DB::Open(options, dbname_, &db_));
71 ASSERT_OK(db_->StartTrace(trace_opt, std::move(trace_writer)));
72
73 WriteBatch batch;
74 ASSERT_OK(batch.Put("a", "aaaaaaaaa"));
75 ASSERT_OK(batch.Merge("b", "aaaaaaaaaaaaaaaaaaaa"));
76 ASSERT_OK(batch.Delete("c"));
77 ASSERT_OK(batch.SingleDelete("d"));
78 ASSERT_OK(batch.DeleteRange("e", "f"));
79 ASSERT_OK(db_->Write(wo, &batch));
80
81 ASSERT_OK(db_->Get(ro, "a", &value));
82 single_iter = db_->NewIterator(ro);
83 single_iter->Seek("a");
84 single_iter->SeekForPrev("b");
85 delete single_iter;
86 std::this_thread::sleep_for (std::chrono::seconds(1));
87
88 db_->Get(ro, "g", &value);
89
90 ASSERT_OK(db_->EndTrace());
91
92 ASSERT_OK(env_->FileExists(trace_path));
93
94 std::unique_ptr<WritableFile> whole_f;
95 std::string whole_path = test_path_ + "/0.txt";
96 ASSERT_OK(env_->NewWritableFile(whole_path, &whole_f, env_options_));
97 std::string whole_str = "0x61\n0x62\n0x63\n0x64\n0x65\n0x66\n";
98 ASSERT_OK(whole_f->Append(whole_str));
99 delete db_;
100 ASSERT_OK(DestroyDB(dbname_, options));
101 }
102
103 void RunTraceAnalyzer(const std::vector<std::string>& args) {
104 char arg_buffer[kArgBufferSize];
105 char* argv[kMaxArgCount];
106 int argc = 0;
107 int cursor = 0;
108
109 for (const auto& arg : args) {
110 ASSERT_LE(cursor + arg.size() + 1, kArgBufferSize);
111 ASSERT_LE(argc + 1, kMaxArgCount);
112 snprintf(arg_buffer + cursor, arg.size() + 1, "%s", arg.c_str());
113
114 argv[argc++] = arg_buffer + cursor;
115 cursor += static_cast<int>(arg.size()) + 1;
116 }
117
f67539c2 118 ASSERT_EQ(0, ROCKSDB_NAMESPACE::trace_analyzer_tool(argc, argv));
11fdf7f2
TL
119 }
120
121 void CheckFileContent(const std::vector<std::string>& cnt,
122 std::string file_path, bool full_content) {
123 ASSERT_OK(env_->FileExists(file_path));
124 std::unique_ptr<SequentialFile> f_ptr;
125 ASSERT_OK(env_->NewSequentialFile(file_path, &f_ptr, env_options_));
126
127 std::string get_line;
128 std::istringstream iss;
129 bool has_data = true;
130 std::vector<std::string> result;
131 uint32_t count;
132 Status s;
f67539c2
TL
133 std::unique_ptr<FSSequentialFile> file =
134 NewLegacySequentialFileWrapper(f_ptr);
135 SequentialFileReader sf_reader(std::move(file), file_path,
136 4096 /* filereadahead_size */);
137
138 for (count = 0; ReadOneLine(&iss, &sf_reader, &get_line, &has_data, &s);
11fdf7f2
TL
139 ++count) {
140 ASSERT_OK(s);
141 result.push_back(get_line);
142 }
143
144 ASSERT_EQ(cnt.size(), result.size());
145 for (int i = 0; i < static_cast<int>(result.size()); i++) {
146 if (full_content) {
147 ASSERT_EQ(result[i], cnt[i]);
148 } else {
149 ASSERT_EQ(result[i][0], cnt[i][0]);
150 }
151 }
152
153 return;
154 }
155
156 void AnalyzeTrace(std::vector<std::string>& paras_diff,
157 std::string output_path, std::string trace_path) {
158 std::vector<std::string> paras = {"./trace_analyzer",
159 "-convert_to_human_readable_trace",
160 "-output_key_stats",
161 "-output_access_count_stats",
162 "-output_prefix=test",
163 "-output_prefix_cut=1",
164 "-output_time_series",
165 "-output_value_distribution",
166 "-output_qps_stats",
167 "-no_key",
168 "-no_print"};
169 for (auto& para : paras_diff) {
170 paras.push_back(para);
171 }
172 Status s = env_->FileExists(trace_path);
173 if (!s.ok()) {
174 GenerateTrace(trace_path);
175 }
176 env_->CreateDir(output_path);
177 RunTraceAnalyzer(paras);
178 }
179
f67539c2 180 ROCKSDB_NAMESPACE::Env* env_;
11fdf7f2
TL
181 EnvOptions env_options_;
182 std::string test_path_;
183 std::string dbname_;
184 Random rnd_;
185};
186
187TEST_F(TraceAnalyzerTest, Get) {
188 std::string trace_path = test_path_ + "/trace";
189 std::string output_path = test_path_ + "/get";
190 std::string file_path;
191 std::vector<std::string> paras = {"-analyze_get"};
192 paras.push_back("-output_dir=" + output_path);
193 paras.push_back("-trace_path=" + trace_path);
194 paras.push_back("-key_space_dir=" + test_path_);
195 AnalyzeTrace(paras, output_path, trace_path);
196
197 // check the key_stats file
198 std::vector<std::string> k_stats = {"0 10 0 1 1.000000", "0 10 1 1 1.000000"};
199 file_path = output_path + "/test-get-0-accessed_key_stats.txt";
200 CheckFileContent(k_stats, file_path, true);
201
202 // Check the access count distribution
203 std::vector<std::string> k_dist = {"access_count: 1 num: 2"};
204 file_path = output_path + "/test-get-0-accessed_key_count_distribution.txt";
205 CheckFileContent(k_dist, file_path, true);
206
207 // Check the trace sequence
208 std::vector<std::string> k_sequence = {"1", "5", "2", "3", "4",
209 "0", "6", "7", "0"};
210 file_path = output_path + "/test-human_readable_trace.txt";
211 CheckFileContent(k_sequence, file_path, false);
212
213 // Check the prefix
214 std::vector<std::string> k_prefix = {"0 0 0 0.000000 0.000000 0x30",
215 "1 1 1 1.000000 1.000000 0x61"};
216 file_path = output_path + "/test-get-0-accessed_key_prefix_cut.txt";
217 CheckFileContent(k_prefix, file_path, true);
218
219 // Check the time series
220 std::vector<std::string> k_series = {"0 1533000630 0", "0 1533000630 1"};
221 file_path = output_path + "/test-get-0-time_series.txt";
222 CheckFileContent(k_series, file_path, false);
223
224 // Check the accessed key in whole key space
225 std::vector<std::string> k_whole_access = {"0 1"};
226 file_path = output_path + "/test-get-0-whole_key_stats.txt";
227 CheckFileContent(k_whole_access, file_path, true);
228
229 // Check the whole key prefix cut
230 std::vector<std::string> k_whole_prefix = {"0 0x61", "1 0x62", "2 0x63",
231 "3 0x64", "4 0x65", "5 0x66"};
232 file_path = output_path + "/test-get-0-whole_key_prefix_cut.txt";
233 CheckFileContent(k_whole_prefix, file_path, true);
234
235 // Check the overall qps
236 std::vector<std::string> all_qps = {"1 0 0 0 0 0 0 0 1"};
237 file_path = output_path + "/test-qps_stats.txt";
238 CheckFileContent(all_qps, file_path, true);
239
240 // Check the qps of get
241 std::vector<std::string> get_qps = {"1"};
242 file_path = output_path + "/test-get-0-qps_stats.txt";
243 CheckFileContent(get_qps, file_path, true);
244
245 // Check the top k qps prefix cut
246 std::vector<std::string> top_qps = {"At time: 0 with QPS: 1",
247 "The prefix: 0x61 Access count: 1"};
248 file_path = output_path + "/test-get-0-accessed_top_k_qps_prefix_cut.txt";
249 CheckFileContent(top_qps, file_path, true);
250}
251
252// Test analyzing of Put
253TEST_F(TraceAnalyzerTest, Put) {
254 std::string trace_path = test_path_ + "/trace";
255 std::string output_path = test_path_ + "/put";
256 std::string file_path;
257 std::vector<std::string> paras = {"-analyze_put"};
258 paras.push_back("-output_dir=" + output_path);
259 paras.push_back("-trace_path=" + trace_path);
260 paras.push_back("-key_space_dir=" + test_path_);
261 AnalyzeTrace(paras, output_path, trace_path);
262
263 // check the key_stats file
264 std::vector<std::string> k_stats = {"0 9 0 1 1.000000"};
265 file_path = output_path + "/test-put-0-accessed_key_stats.txt";
266 CheckFileContent(k_stats, file_path, true);
267
268 // Check the access count distribution
269 std::vector<std::string> k_dist = {"access_count: 1 num: 1"};
270 file_path = output_path + "/test-put-0-accessed_key_count_distribution.txt";
271 CheckFileContent(k_dist, file_path, true);
272
273 // Check the trace sequence
274 std::vector<std::string> k_sequence = {"1", "5", "2", "3", "4",
275 "0", "6", "7", "0"};
276 file_path = output_path + "/test-human_readable_trace.txt";
277 CheckFileContent(k_sequence, file_path, false);
278
279 // Check the prefix
280 std::vector<std::string> k_prefix = {"0 0 0 0.000000 0.000000 0x30"};
281 file_path = output_path + "/test-put-0-accessed_key_prefix_cut.txt";
282 CheckFileContent(k_prefix, file_path, true);
283
284 // Check the time series
285 std::vector<std::string> k_series = {"1 1533056278 0"};
286 file_path = output_path + "/test-put-0-time_series.txt";
287 CheckFileContent(k_series, file_path, false);
288
289 // Check the accessed key in whole key space
290 std::vector<std::string> k_whole_access = {"0 1"};
291 file_path = output_path + "/test-put-0-whole_key_stats.txt";
292 CheckFileContent(k_whole_access, file_path, true);
293
294 // Check the whole key prefix cut
295 std::vector<std::string> k_whole_prefix = {"0 0x61", "1 0x62", "2 0x63",
296 "3 0x64", "4 0x65", "5 0x66"};
297 file_path = output_path + "/test-put-0-whole_key_prefix_cut.txt";
298 CheckFileContent(k_whole_prefix, file_path, true);
299
300 // Check the overall qps
301 std::vector<std::string> all_qps = {"1 1 0 0 0 0 0 0 2"};
302 file_path = output_path + "/test-qps_stats.txt";
303 CheckFileContent(all_qps, file_path, true);
304
305 // Check the qps of Put
306 std::vector<std::string> get_qps = {"1"};
307 file_path = output_path + "/test-put-0-qps_stats.txt";
308 CheckFileContent(get_qps, file_path, true);
309
310 // Check the top k qps prefix cut
311 std::vector<std::string> top_qps = {"At time: 0 with QPS: 1",
312 "The prefix: 0x61 Access count: 1"};
313 file_path = output_path + "/test-put-0-accessed_top_k_qps_prefix_cut.txt";
314 CheckFileContent(top_qps, file_path, true);
315
316 // Check the value size distribution
317 std::vector<std::string> value_dist = {
318 "Number_of_value_size_between 0 and 16 is: 1"};
319 file_path = output_path + "/test-put-0-accessed_value_size_distribution.txt";
320 CheckFileContent(value_dist, file_path, true);
321}
322
323// Test analyzing of delete
324TEST_F(TraceAnalyzerTest, Delete) {
325 std::string trace_path = test_path_ + "/trace";
326 std::string output_path = test_path_ + "/delete";
327 std::string file_path;
328 std::vector<std::string> paras = {"-analyze_delete"};
329 paras.push_back("-output_dir=" + output_path);
330 paras.push_back("-trace_path=" + trace_path);
331 paras.push_back("-key_space_dir=" + test_path_);
332 AnalyzeTrace(paras, output_path, trace_path);
333
334 // check the key_stats file
335 std::vector<std::string> k_stats = {"0 0 0 1 1.000000"};
336 file_path = output_path + "/test-delete-0-accessed_key_stats.txt";
337 CheckFileContent(k_stats, file_path, true);
338
339 // Check the access count distribution
340 std::vector<std::string> k_dist = {"access_count: 1 num: 1"};
341 file_path =
342 output_path + "/test-delete-0-accessed_key_count_distribution.txt";
343 CheckFileContent(k_dist, file_path, true);
344
345 // Check the trace sequence
346 std::vector<std::string> k_sequence = {"1", "5", "2", "3", "4",
347 "0", "6", "7", "0"};
348 file_path = output_path + "/test-human_readable_trace.txt";
349 CheckFileContent(k_sequence, file_path, false);
350
351 // Check the prefix
352 std::vector<std::string> k_prefix = {"0 0 0 0.000000 0.000000 0x30"};
353 file_path = output_path + "/test-delete-0-accessed_key_prefix_cut.txt";
354 CheckFileContent(k_prefix, file_path, true);
355
356 // Check the time series
357 std::vector<std::string> k_series = {"2 1533000630 0"};
358 file_path = output_path + "/test-delete-0-time_series.txt";
359 CheckFileContent(k_series, file_path, false);
360
361 // Check the accessed key in whole key space
362 std::vector<std::string> k_whole_access = {"2 1"};
363 file_path = output_path + "/test-delete-0-whole_key_stats.txt";
364 CheckFileContent(k_whole_access, file_path, true);
365
366 // Check the whole key prefix cut
367 std::vector<std::string> k_whole_prefix = {"0 0x61", "1 0x62", "2 0x63",
368 "3 0x64", "4 0x65", "5 0x66"};
369 file_path = output_path + "/test-delete-0-whole_key_prefix_cut.txt";
370 CheckFileContent(k_whole_prefix, file_path, true);
371
372 // Check the overall qps
373 std::vector<std::string> all_qps = {"1 1 1 0 0 0 0 0 3"};
374 file_path = output_path + "/test-qps_stats.txt";
375 CheckFileContent(all_qps, file_path, true);
376
377 // Check the qps of Delete
378 std::vector<std::string> get_qps = {"1"};
379 file_path = output_path + "/test-delete-0-qps_stats.txt";
380 CheckFileContent(get_qps, file_path, true);
381
382 // Check the top k qps prefix cut
383 std::vector<std::string> top_qps = {"At time: 0 with QPS: 1",
384 "The prefix: 0x63 Access count: 1"};
385 file_path = output_path + "/test-delete-0-accessed_top_k_qps_prefix_cut.txt";
386 CheckFileContent(top_qps, file_path, true);
387}
388
389// Test analyzing of Merge
390TEST_F(TraceAnalyzerTest, Merge) {
391 std::string trace_path = test_path_ + "/trace";
392 std::string output_path = test_path_ + "/merge";
393 std::string file_path;
394 std::vector<std::string> paras = {"-analyze_merge"};
395 paras.push_back("-output_dir=" + output_path);
396 paras.push_back("-trace_path=" + trace_path);
397 paras.push_back("-key_space_dir=" + test_path_);
398 AnalyzeTrace(paras, output_path, trace_path);
399
400 // check the key_stats file
401 std::vector<std::string> k_stats = {"0 20 0 1 1.000000"};
402 file_path = output_path + "/test-merge-0-accessed_key_stats.txt";
403 CheckFileContent(k_stats, file_path, true);
404
405 // Check the access count distribution
406 std::vector<std::string> k_dist = {"access_count: 1 num: 1"};
407 file_path = output_path + "/test-merge-0-accessed_key_count_distribution.txt";
408 CheckFileContent(k_dist, file_path, true);
409
410 // Check the trace sequence
411 std::vector<std::string> k_sequence = {"1", "5", "2", "3", "4",
412 "0", "6", "7", "0"};
413 file_path = output_path + "/test-human_readable_trace.txt";
414 CheckFileContent(k_sequence, file_path, false);
415
416 // Check the prefix
417 std::vector<std::string> k_prefix = {"0 0 0 0.000000 0.000000 0x30"};
418 file_path = output_path + "/test-merge-0-accessed_key_prefix_cut.txt";
419 CheckFileContent(k_prefix, file_path, true);
420
421 // Check the time series
422 std::vector<std::string> k_series = {"5 1533000630 0"};
423 file_path = output_path + "/test-merge-0-time_series.txt";
424 CheckFileContent(k_series, file_path, false);
425
426 // Check the accessed key in whole key space
427 std::vector<std::string> k_whole_access = {"1 1"};
428 file_path = output_path + "/test-merge-0-whole_key_stats.txt";
429 CheckFileContent(k_whole_access, file_path, true);
430
431 // Check the whole key prefix cut
432 std::vector<std::string> k_whole_prefix = {"0 0x61", "1 0x62", "2 0x63",
433 "3 0x64", "4 0x65", "5 0x66"};
434 file_path = output_path + "/test-merge-0-whole_key_prefix_cut.txt";
435 CheckFileContent(k_whole_prefix, file_path, true);
436
437 // Check the overall qps
438 std::vector<std::string> all_qps = {"1 1 1 0 0 1 0 0 4"};
439 file_path = output_path + "/test-qps_stats.txt";
440 CheckFileContent(all_qps, file_path, true);
441
442 // Check the qps of Merge
443 std::vector<std::string> get_qps = {"1"};
444 file_path = output_path + "/test-merge-0-qps_stats.txt";
445 CheckFileContent(get_qps, file_path, true);
446
447 // Check the top k qps prefix cut
448 std::vector<std::string> top_qps = {"At time: 0 with QPS: 1",
449 "The prefix: 0x62 Access count: 1"};
450 file_path = output_path + "/test-merge-0-accessed_top_k_qps_prefix_cut.txt";
451 CheckFileContent(top_qps, file_path, true);
452
453 // Check the value size distribution
454 std::vector<std::string> value_dist = {
455 "Number_of_value_size_between 0 and 24 is: 1"};
456 file_path =
457 output_path + "/test-merge-0-accessed_value_size_distribution.txt";
458 CheckFileContent(value_dist, file_path, true);
459}
460
461// Test analyzing of SingleDelete
462TEST_F(TraceAnalyzerTest, SingleDelete) {
463 std::string trace_path = test_path_ + "/trace";
464 std::string output_path = test_path_ + "/single_delete";
465 std::string file_path;
466 std::vector<std::string> paras = {"-analyze_single_delete"};
467 paras.push_back("-output_dir=" + output_path);
468 paras.push_back("-trace_path=" + trace_path);
469 paras.push_back("-key_space_dir=" + test_path_);
470 AnalyzeTrace(paras, output_path, trace_path);
471
472 // check the key_stats file
473 std::vector<std::string> k_stats = {"0 0 0 1 1.000000"};
474 file_path = output_path + "/test-single_delete-0-accessed_key_stats.txt";
475 CheckFileContent(k_stats, file_path, true);
476
477 // Check the access count distribution
478 std::vector<std::string> k_dist = {"access_count: 1 num: 1"};
479 file_path =
480 output_path + "/test-single_delete-0-accessed_key_count_distribution.txt";
481 CheckFileContent(k_dist, file_path, true);
482
483 // Check the trace sequence
484 std::vector<std::string> k_sequence = {"1", "5", "2", "3", "4",
485 "0", "6", "7", "0"};
486 file_path = output_path + "/test-human_readable_trace.txt";
487 CheckFileContent(k_sequence, file_path, false);
488
489 // Check the prefix
490 std::vector<std::string> k_prefix = {"0 0 0 0.000000 0.000000 0x30"};
491 file_path = output_path + "/test-single_delete-0-accessed_key_prefix_cut.txt";
492 CheckFileContent(k_prefix, file_path, true);
493
494 // Check the time series
495 std::vector<std::string> k_series = {"3 1533000630 0"};
496 file_path = output_path + "/test-single_delete-0-time_series.txt";
497 CheckFileContent(k_series, file_path, false);
498
499 // Check the accessed key in whole key space
500 std::vector<std::string> k_whole_access = {"3 1"};
501 file_path = output_path + "/test-single_delete-0-whole_key_stats.txt";
502 CheckFileContent(k_whole_access, file_path, true);
503
504 // Check the whole key prefix cut
505 std::vector<std::string> k_whole_prefix = {"0 0x61", "1 0x62", "2 0x63",
506 "3 0x64", "4 0x65", "5 0x66"};
507 file_path = output_path + "/test-single_delete-0-whole_key_prefix_cut.txt";
508 CheckFileContent(k_whole_prefix, file_path, true);
509
510 // Check the overall qps
511 std::vector<std::string> all_qps = {"1 1 1 1 0 1 0 0 5"};
512 file_path = output_path + "/test-qps_stats.txt";
513 CheckFileContent(all_qps, file_path, true);
514
515 // Check the qps of SingleDelete
516 std::vector<std::string> get_qps = {"1"};
517 file_path = output_path + "/test-single_delete-0-qps_stats.txt";
518 CheckFileContent(get_qps, file_path, true);
519
520 // Check the top k qps prefix cut
521 std::vector<std::string> top_qps = {"At time: 0 with QPS: 1",
522 "The prefix: 0x64 Access count: 1"};
523 file_path =
524 output_path + "/test-single_delete-0-accessed_top_k_qps_prefix_cut.txt";
525 CheckFileContent(top_qps, file_path, true);
526}
527
528// Test analyzing of delete
529TEST_F(TraceAnalyzerTest, DeleteRange) {
530 std::string trace_path = test_path_ + "/trace";
531 std::string output_path = test_path_ + "/range_delete";
532 std::string file_path;
533 std::vector<std::string> paras = {"-analyze_range_delete"};
534 paras.push_back("-output_dir=" + output_path);
535 paras.push_back("-trace_path=" + trace_path);
536 paras.push_back("-key_space_dir=" + test_path_);
537 AnalyzeTrace(paras, output_path, trace_path);
538
539 // check the key_stats file
540 std::vector<std::string> k_stats = {"0 0 0 1 1.000000", "0 0 1 1 1.000000"};
541 file_path = output_path + "/test-range_delete-0-accessed_key_stats.txt";
542 CheckFileContent(k_stats, file_path, true);
543
544 // Check the access count distribution
545 std::vector<std::string> k_dist = {"access_count: 1 num: 2"};
546 file_path =
547 output_path + "/test-range_delete-0-accessed_key_count_distribution.txt";
548 CheckFileContent(k_dist, file_path, true);
549
550 // Check the trace sequence
551 std::vector<std::string> k_sequence = {"1", "5", "2", "3", "4",
552 "0", "6", "7", "0"};
553 file_path = output_path + "/test-human_readable_trace.txt";
554 CheckFileContent(k_sequence, file_path, false);
555
556 // Check the prefix
557 std::vector<std::string> k_prefix = {"0 0 0 0.000000 0.000000 0x30",
558 "1 1 1 1.000000 1.000000 0x65"};
559 file_path = output_path + "/test-range_delete-0-accessed_key_prefix_cut.txt";
560 CheckFileContent(k_prefix, file_path, true);
561
562 // Check the time series
563 std::vector<std::string> k_series = {"4 1533000630 0", "4 1533060100 1"};
564 file_path = output_path + "/test-range_delete-0-time_series.txt";
565 CheckFileContent(k_series, file_path, false);
566
567 // Check the accessed key in whole key space
568 std::vector<std::string> k_whole_access = {"4 1", "5 1"};
569 file_path = output_path + "/test-range_delete-0-whole_key_stats.txt";
570 CheckFileContent(k_whole_access, file_path, true);
571
572 // Check the whole key prefix cut
573 std::vector<std::string> k_whole_prefix = {"0 0x61", "1 0x62", "2 0x63",
574 "3 0x64", "4 0x65", "5 0x66"};
575 file_path = output_path + "/test-range_delete-0-whole_key_prefix_cut.txt";
576 CheckFileContent(k_whole_prefix, file_path, true);
577
578 // Check the overall qps
579 std::vector<std::string> all_qps = {"1 1 1 1 2 1 0 0 7"};
580 file_path = output_path + "/test-qps_stats.txt";
581 CheckFileContent(all_qps, file_path, true);
582
583 // Check the qps of DeleteRange
584 std::vector<std::string> get_qps = {"2"};
585 file_path = output_path + "/test-range_delete-0-qps_stats.txt";
586 CheckFileContent(get_qps, file_path, true);
587
588 // Check the top k qps prefix cut
589 std::vector<std::string> top_qps = {"At time: 0 with QPS: 2",
590 "The prefix: 0x65 Access count: 1",
591 "The prefix: 0x66 Access count: 1"};
592 file_path =
593 output_path + "/test-range_delete-0-accessed_top_k_qps_prefix_cut.txt";
594 CheckFileContent(top_qps, file_path, true);
595}
596
597// Test analyzing of Iterator
598TEST_F(TraceAnalyzerTest, Iterator) {
599 std::string trace_path = test_path_ + "/trace";
600 std::string output_path = test_path_ + "/iterator";
601 std::string file_path;
602 std::vector<std::string> paras = {"-analyze_iterator"};
603 paras.push_back("-output_dir=" + output_path);
604 paras.push_back("-trace_path=" + trace_path);
605 paras.push_back("-key_space_dir=" + test_path_);
606 AnalyzeTrace(paras, output_path, trace_path);
607
608 // Check the output of Seek
609 // check the key_stats file
610 std::vector<std::string> k_stats = {"0 0 0 1 1.000000"};
611 file_path = output_path + "/test-iterator_Seek-0-accessed_key_stats.txt";
612 CheckFileContent(k_stats, file_path, true);
613
614 // Check the access count distribution
615 std::vector<std::string> k_dist = {"access_count: 1 num: 1"};
616 file_path =
617 output_path + "/test-iterator_Seek-0-accessed_key_count_distribution.txt";
618 CheckFileContent(k_dist, file_path, true);
619
620 // Check the trace sequence
621 std::vector<std::string> k_sequence = {"1", "5", "2", "3", "4",
622 "0", "6", "7", "0"};
623 file_path = output_path + "/test-human_readable_trace.txt";
624 CheckFileContent(k_sequence, file_path, false);
625
626 // Check the prefix
627 std::vector<std::string> k_prefix = {"0 0 0 0.000000 0.000000 0x30"};
628 file_path = output_path + "/test-iterator_Seek-0-accessed_key_prefix_cut.txt";
629 CheckFileContent(k_prefix, file_path, true);
630
631 // Check the time series
632 std::vector<std::string> k_series = {"6 1 0"};
633 file_path = output_path + "/test-iterator_Seek-0-time_series.txt";
634 CheckFileContent(k_series, file_path, false);
635
636 // Check the accessed key in whole key space
637 std::vector<std::string> k_whole_access = {"0 1"};
638 file_path = output_path + "/test-iterator_Seek-0-whole_key_stats.txt";
639 CheckFileContent(k_whole_access, file_path, true);
640
641 // Check the whole key prefix cut
642 std::vector<std::string> k_whole_prefix = {"0 0x61", "1 0x62", "2 0x63",
643 "3 0x64", "4 0x65", "5 0x66"};
644 file_path = output_path + "/test-iterator_Seek-0-whole_key_prefix_cut.txt";
645 CheckFileContent(k_whole_prefix, file_path, true);
646
647 // Check the overall qps
648 std::vector<std::string> all_qps = {"1 1 1 1 2 1 1 1 9"};
649 file_path = output_path + "/test-qps_stats.txt";
650 CheckFileContent(all_qps, file_path, true);
651
652 // Check the qps of Iterator_Seek
653 std::vector<std::string> get_qps = {"1"};
654 file_path = output_path + "/test-iterator_Seek-0-qps_stats.txt";
655 CheckFileContent(get_qps, file_path, true);
656
657 // Check the top k qps prefix cut
658 std::vector<std::string> top_qps = {"At time: 0 with QPS: 1",
659 "The prefix: 0x61 Access count: 1"};
660 file_path =
661 output_path + "/test-iterator_Seek-0-accessed_top_k_qps_prefix_cut.txt";
662 CheckFileContent(top_qps, file_path, true);
663
664 // Check the output of SeekForPrev
665 // check the key_stats file
666 k_stats = {"0 0 0 1 1.000000"};
667 file_path =
668 output_path + "/test-iterator_SeekForPrev-0-accessed_key_stats.txt";
669 CheckFileContent(k_stats, file_path, true);
670
671 // Check the access count distribution
672 k_dist = {"access_count: 1 num: 1"};
673 file_path =
674 output_path +
675 "/test-iterator_SeekForPrev-0-accessed_key_count_distribution.txt";
676 CheckFileContent(k_dist, file_path, true);
677
678 // Check the prefix
679 k_prefix = {"0 0 0 0.000000 0.000000 0x30"};
680 file_path =
681 output_path + "/test-iterator_SeekForPrev-0-accessed_key_prefix_cut.txt";
682 CheckFileContent(k_prefix, file_path, true);
683
684 // Check the time series
685 k_series = {"7 0 0"};
686 file_path = output_path + "/test-iterator_SeekForPrev-0-time_series.txt";
687 CheckFileContent(k_series, file_path, false);
688
689 // Check the accessed key in whole key space
690 k_whole_access = {"1 1"};
691 file_path = output_path + "/test-iterator_SeekForPrev-0-whole_key_stats.txt";
692 CheckFileContent(k_whole_access, file_path, true);
693
694 // Check the whole key prefix cut
695 k_whole_prefix = {"0 0x61", "1 0x62", "2 0x63", "3 0x64", "4 0x65", "5 0x66"};
696 file_path =
697 output_path + "/test-iterator_SeekForPrev-0-whole_key_prefix_cut.txt";
698 CheckFileContent(k_whole_prefix, file_path, true);
699
700 // Check the qps of Iterator_SeekForPrev
701 get_qps = {"1"};
702 file_path = output_path + "/test-iterator_SeekForPrev-0-qps_stats.txt";
703 CheckFileContent(get_qps, file_path, true);
704
705 // Check the top k qps prefix cut
706 top_qps = {"At time: 0 with QPS: 1", "The prefix: 0x62 Access count: 1"};
707 file_path = output_path +
708 "/test-iterator_SeekForPrev-0-accessed_top_k_qps_prefix_cut.txt";
709 CheckFileContent(top_qps, file_path, true);
710}
711
f67539c2 712} // namespace ROCKSDB_NAMESPACE
11fdf7f2
TL
713
714int main(int argc, char** argv) {
715 ::testing::InitGoogleTest(&argc, argv);
716 return RUN_ALL_TESTS();
717}
718#endif // GFLAG
719#else
720#include <stdio.h>
721
722int main(int /*argc*/, char** /*argv*/) {
723 fprintf(stderr, "Trace_analyzer test is not supported in ROCKSDB_LITE\n");
724 return 0;
725}
726
727#endif // !ROCKSDB_LITE return RUN_ALL_TESTS();