/Users/deen/code/yugabyte-db/src/yb/tools/rocksdb_dump_test.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 <sstream>  | 
15  |  | #include <string>  | 
16  |  |  | 
17  |  | #include <gtest/gtest.h>  | 
18  |  |  | 
19  |  | #include "yb/client/client.h"  | 
20  |  | #include "yb/client/schema.h"  | 
21  |  | #include "yb/client/session.h"  | 
22  |  | #include "yb/client/table.h"  | 
23  |  | #include "yb/client/table_creator.h"  | 
24  |  | #include "yb/client/yb_op.h"  | 
25  |  |  | 
26  |  | #include "yb/integration-tests/mini_cluster.h"  | 
27  |  | #include "yb/integration-tests/yb_mini_cluster_test_base.h"  | 
28  |  |  | 
29  |  | #include "yb/tablet/tablet_metadata.h"  | 
30  |  | #include "yb/tablet/tablet_peer.h"  | 
31  |  |  | 
32  |  | #include "yb/tools/data_gen_util.h"  | 
33  |  |  | 
34  |  | #include "yb/util/file_system.h"  | 
35  |  | #include "yb/util/path_util.h"  | 
36  |  | #include "yb/util/random.h"  | 
37  |  | #include "yb/util/random_util.h"  | 
38  |  | #include "yb/util/result.h"  | 
39  |  | #include "yb/util/subprocess.h"  | 
40  |  | #include "yb/util/test_util.h"  | 
41  |  |  | 
42  |  | using namespace std::literals;  | 
43  |  |  | 
44  |  | namespace yb { | 
45  |  | namespace tools { | 
46  |  |  | 
47  |  | using client::YBClient;  | 
48  |  | using client::YBClientBuilder;  | 
49  |  | using client::YBSchema;  | 
50  |  | using client::YBSchemaBuilder;  | 
51  |  | using client::YBTableCreator;  | 
52  |  | using client::YBTableName;  | 
53  |  | using client::YBTable;  | 
54  |  |  | 
55  |  | static const char* const kTabletUtilToolName = "rocksdb_dump";  | 
56  |  | static const char* const kNamespace = "rocksdb_dump_test_namespace";  | 
57  |  | static const char* const kTableName = "my_table";  | 
58  |  | static constexpr int32_t kNumTablets = 1;  | 
59  |  | static constexpr int32_t kNumTabletServers = 1;  | 
60  |  | static const char* const kRandomFileName = "randomfilename";  | 
61  |  |  | 
62  |  | class RocksDbDumpTest : public YBMiniClusterTestBase<MiniCluster> { | 
63  |  |  public:  | 
64  | 0  |   RocksDbDumpTest() : random_(0) { | 
65  | 0  |   }  | 
66  |  |  | 
67  | 0  |   void SetUp() override { | 
68  | 0  |     YBMiniClusterTestBase::SetUp();  | 
69  | 0  |     MiniClusterOptions opts;  | 
70  |  | 
  | 
71  | 0  |     opts.num_tablet_servers = kNumTabletServers;  | 
72  |  | 
  | 
73  | 0  |     cluster_.reset(new MiniCluster(opts));  | 
74  | 0  |     ASSERT_OK(cluster_->Start());  | 
75  |  | 
  | 
76  | 0  |     YBSchema schema;  | 
77  | 0  |     YBSchemaBuilder b;  | 
78  | 0  |     b.AddColumn("k")->Type(INT64)->NotNull()->HashPrimaryKey(); | 
79  | 0  |     ASSERT_OK(b.Build(&schema));  | 
80  |  | 
  | 
81  | 0  |     client_ = ASSERT_RESULT(cluster_->CreateClient());  | 
82  |  |  | 
83  |  |     // Create the namespace.  | 
84  | 0  |     ASSERT_OK(client_->CreateNamespace(kNamespace));  | 
85  |  |  | 
86  |  |     // Create the table.  | 
87  | 0  |     const YBTableName table_name(YQL_DATABASE_CQL, kNamespace, kTableName);  | 
88  | 0  |     ASSERT_OK(client_  | 
89  | 0  |         ->NewTableCreator()  | 
90  | 0  |         ->table_name(table_name)  | 
91  | 0  |         .table_type(client::YBTableType::YQL_TABLE_TYPE)  | 
92  | 0  |         .schema(&schema)  | 
93  | 0  |         .num_tablets(kNumTablets)  | 
94  | 0  |         .wait(true)  | 
95  | 0  |         .Create());  | 
96  |  | 
  | 
97  | 0  |     ASSERT_OK(client_->OpenTable(table_name, &table_));  | 
98  | 0  |   }  | 
99  |  |  | 
100  | 0  |   void DoTearDown() override { | 
101  | 0  |     client_.reset();  | 
102  | 0  |     cluster_->Shutdown();  | 
103  | 0  |   }  | 
104  |  |  | 
105  |  |  protected:  | 
106  |  |  | 
107  | 0  |   CHECKED_STATUS WriteData() { | 
108  | 0  |     auto session = client_->NewSession();  | 
109  | 0  |     session->SetTimeout(5s);  | 
110  |  | 
  | 
111  | 0  |     std::shared_ptr<client::YBqlWriteOp> insert(table_->NewQLWrite());  | 
112  | 0  |     auto req = insert->mutable_request();  | 
113  | 0  |     GenerateDataForRow(table_->schema(), 17 /* record_id */, &random_, req);  | 
114  |  | 
  | 
115  | 0  |     session->Apply(insert);  | 
116  | 0  |     RETURN_NOT_OK(session->Flush());  | 
117  | 0  |     return Status::OK();  | 
118  | 0  |   }  | 
119  |  |  | 
120  | 0  |   Result<string> GetTabletDbPath() { | 
121  | 0  |     for (const auto& peer : cluster_->GetTabletPeers(0)) { | 
122  | 0  |       if (peer->table_type() == TableType::YQL_TABLE_TYPE) { | 
123  | 0  |         return peer->tablet_metadata()->rocksdb_dir();  | 
124  | 0  |       }  | 
125  | 0  |     }  | 
126  | 0  |     return STATUS(IllegalState, "Did not find tablet peer with YCQL table");  | 
127  | 0  |   }  | 
128  |  |  | 
129  |  |   std::unique_ptr<YBClient> client_;  | 
130  |  |   std::shared_ptr<YBTable> table_;  | 
131  |  |   Random random_;  | 
132  |  | };  | 
133  |  |  | 
134  |  |  | 
135  | 0  | TEST_F(RocksDbDumpTest, VerifySingleKeyIsFound) { | 
136  | 0  |   string output;  | 
137  | 0  |   ASSERT_OK(WriteData());  | 
138  | 0  |   ASSERT_OK(cluster_->FlushTablets(tablet::FlushMode::kSync, tablet::FlushFlags::kAll));  | 
139  | 0  |   string db_path = ASSERT_RESULT(GetTabletDbPath());  | 
140  |  | 
  | 
141  | 0  |   string output_path = strings::Substitute(  | 
142  | 0  |       "$0/$1", ASSERT_RESULT(Env::Default()->GetTestDirectory()), kRandomFileName);  | 
143  |  | 
  | 
144  | 0  |   vector<string> argv = { | 
145  | 0  |     GetToolPath(kTabletUtilToolName),  | 
146  | 0  |     "--db_path",  | 
147  | 0  |     db_path,  | 
148  | 0  |     "--dump_location",  | 
149  | 0  |     output_path  | 
150  | 0  |   };  | 
151  |  |   // Running the rocksdb_dump without failure means the tool was able to parse the persisted db  | 
152  |  |   // state correctly.  | 
153  | 0  |   ASSERT_OK(Subprocess::Call(argv));  | 
154  | 0  | }  | 
155  |  |  | 
156  |  | } // namespace tools  | 
157  |  | } // namespace yb  |