/Users/deen/code/yugabyte-db/src/yb/rocksdb/tools/reduce_levels_test.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
2 | | // This source code is licensed under the BSD-style license found in the |
3 | | // LICENSE file in the root directory of this source tree. An additional grant |
4 | | // of patent rights can be found in the PATENTS file in the same directory. |
5 | | // |
6 | | // The following only applies to changes made to this file as part of YugaByte development. |
7 | | // |
8 | | // Portions Copyright (c) YugaByte, Inc. |
9 | | // |
10 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
11 | | // in compliance with the License. You may obtain a copy of the License at |
12 | | // |
13 | | // http://www.apache.org/licenses/LICENSE-2.0 |
14 | | // |
15 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
16 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
17 | | // or implied. See the License for the specific language governing permissions and limitations |
18 | | // under the License. |
19 | | // |
20 | | |
21 | | #ifndef ROCKSDB_LITE |
22 | | |
23 | | #include "yb/rocksdb/db.h" |
24 | | #include "yb/rocksdb/db/db_impl.h" |
25 | | #include "yb/rocksdb/db/version_set.h" |
26 | | #include "yb/rocksdb/tools/ldb_cmd.h" |
27 | | #include "yb/rocksdb/util/logging.h" |
28 | | #include "yb/rocksdb/util/testutil.h" |
29 | | #include "yb/rocksdb/util/testharness.h" |
30 | | |
31 | | #include "yb/util/test_util.h" |
32 | | |
33 | | namespace rocksdb { |
34 | | |
35 | | class ReduceLevelTest : public RocksDBTest { |
36 | | public: |
37 | 3 | ReduceLevelTest() { |
38 | 3 | dbname_ = test::TmpDir() + "/db_reduce_levels_test"; |
39 | 3 | CHECK_OK(DestroyDB(dbname_, Options())); |
40 | 3 | db_ = nullptr; |
41 | 3 | } |
42 | | |
43 | | Status OpenDB(bool create_if_missing, int levels); |
44 | | |
45 | 6 | Status Put(const std::string& k, const std::string& v) { |
46 | 6 | return db_->Put(WriteOptions(), k, v); |
47 | 6 | } |
48 | | |
49 | 12 | std::string Get(const std::string& k) { |
50 | 12 | ReadOptions options; |
51 | 12 | std::string result; |
52 | 12 | Status s = db_->Get(options, k, &result); |
53 | 12 | if (s.IsNotFound()) { |
54 | 0 | result = "NOT_FOUND"; |
55 | 12 | } else if (!s.ok()) { |
56 | 0 | result = s.ToString(); |
57 | 0 | } |
58 | 12 | return result; |
59 | 12 | } |
60 | | |
61 | 6 | Status Flush() { |
62 | 6 | if (db_ == nullptr) { |
63 | 0 | return STATUS(InvalidArgument, "DB not opened."); |
64 | 0 | } |
65 | 6 | DBImpl* db_impl = reinterpret_cast<DBImpl*>(db_); |
66 | 6 | return db_impl->TEST_FlushMemTable(); |
67 | 6 | } |
68 | | |
69 | 5 | void MoveL0FileToLevel(int level) { |
70 | 5 | DBImpl* db_impl = reinterpret_cast<DBImpl*>(db_); |
71 | 18 | for (int i = 0; i < level; ++i) { |
72 | 13 | ASSERT_OK(db_impl->TEST_CompactRange(i, nullptr, nullptr)); |
73 | 13 | } |
74 | 5 | } |
75 | | |
76 | 14 | void CloseDB() { |
77 | 14 | if (db_ != nullptr) { |
78 | 14 | delete db_; |
79 | 14 | db_ = nullptr; |
80 | 14 | } |
81 | 14 | } |
82 | | |
83 | | bool ReduceLevels(int target_level); |
84 | | |
85 | 14 | int FilesOnLevel(int level) { |
86 | 14 | std::string property; |
87 | 14 | EXPECT_TRUE(db_->GetProperty( |
88 | 14 | "rocksdb.num-files-at-level" + NumberToString(level), &property)); |
89 | 14 | return atoi(property.c_str()); |
90 | 14 | } |
91 | | |
92 | | private: |
93 | | std::string dbname_; |
94 | | DB* db_; |
95 | | }; |
96 | | |
97 | 14 | Status ReduceLevelTest::OpenDB(bool create_if_missing, int num_levels) { |
98 | 14 | rocksdb::Options opt; |
99 | 14 | opt.num_levels = num_levels; |
100 | 14 | opt.create_if_missing = create_if_missing; |
101 | 14 | rocksdb::Status st = rocksdb::DB::Open(opt, dbname_, &db_); |
102 | 14 | if (!st.ok()) { |
103 | 0 | fprintf(stderr, "Can't open the db:%s\n", st.ToString().c_str()); |
104 | 0 | } |
105 | 14 | return st; |
106 | 14 | } |
107 | | |
108 | 8 | bool ReduceLevelTest::ReduceLevels(int target_level) { |
109 | 8 | std::vector<std::string> args = rocksdb::ReduceDBLevelsCommand::PrepareArgs( |
110 | 8 | dbname_, target_level, false); |
111 | 8 | LDBCommand* level_reducer = |
112 | 8 | LDBCommand::InitFromCmdLineArgs(args, Options(), LDBOptions(), nullptr); |
113 | 8 | level_reducer->Run(); |
114 | 8 | bool is_succeed = level_reducer->GetExecuteState().IsSucceed(); |
115 | 8 | delete level_reducer; |
116 | 8 | return is_succeed; |
117 | 8 | } |
118 | | |
119 | 1 | TEST_F(ReduceLevelTest, Last_Level) { |
120 | 1 | ASSERT_OK(OpenDB(true, 4)); |
121 | 1 | ASSERT_OK(Put("aaaa", "11111")); |
122 | 1 | ASSERT_OK(Flush()); |
123 | 1 | MoveL0FileToLevel(3); |
124 | 1 | ASSERT_EQ(FilesOnLevel(3), 1); |
125 | 1 | CloseDB(); |
126 | | |
127 | 1 | ASSERT_TRUE(ReduceLevels(3)); |
128 | 1 | ASSERT_OK(OpenDB(true, 3)); |
129 | 1 | ASSERT_EQ(FilesOnLevel(2), 1); |
130 | 1 | CloseDB(); |
131 | | |
132 | 1 | ASSERT_TRUE(ReduceLevels(2)); |
133 | 1 | ASSERT_OK(OpenDB(true, 2)); |
134 | 1 | ASSERT_EQ(FilesOnLevel(1), 1); |
135 | 1 | CloseDB(); |
136 | 1 | } |
137 | | |
138 | 1 | TEST_F(ReduceLevelTest, Top_Level) { |
139 | 1 | ASSERT_OK(OpenDB(true, 5)); |
140 | 1 | ASSERT_OK(Put("aaaa", "11111")); |
141 | 1 | ASSERT_OK(Flush()); |
142 | 1 | ASSERT_EQ(FilesOnLevel(0), 1); |
143 | 1 | CloseDB(); |
144 | | |
145 | 1 | ASSERT_TRUE(ReduceLevels(4)); |
146 | 1 | ASSERT_OK(OpenDB(true, 4)); |
147 | 1 | CloseDB(); |
148 | | |
149 | 1 | ASSERT_TRUE(ReduceLevels(3)); |
150 | 1 | ASSERT_OK(OpenDB(true, 3)); |
151 | 1 | CloseDB(); |
152 | | |
153 | 1 | ASSERT_TRUE(ReduceLevels(2)); |
154 | 1 | ASSERT_OK(OpenDB(true, 2)); |
155 | 1 | CloseDB(); |
156 | 1 | } |
157 | | |
158 | 1 | TEST_F(ReduceLevelTest, All_Levels) { |
159 | 1 | ASSERT_OK(OpenDB(true, 5)); |
160 | 1 | ASSERT_OK(Put("a", "a11111")); |
161 | 1 | ASSERT_OK(Flush()); |
162 | 1 | MoveL0FileToLevel(4); |
163 | 1 | ASSERT_EQ(FilesOnLevel(4), 1); |
164 | 1 | CloseDB(); |
165 | | |
166 | 1 | ASSERT_OK(OpenDB(true, 5)); |
167 | 1 | ASSERT_OK(Put("b", "b11111")); |
168 | 1 | ASSERT_OK(Flush()); |
169 | 1 | MoveL0FileToLevel(3); |
170 | 1 | ASSERT_EQ(FilesOnLevel(3), 1); |
171 | 1 | ASSERT_EQ(FilesOnLevel(4), 1); |
172 | 1 | CloseDB(); |
173 | | |
174 | 1 | ASSERT_OK(OpenDB(true, 5)); |
175 | 1 | ASSERT_OK(Put("c", "c11111")); |
176 | 1 | ASSERT_OK(Flush()); |
177 | 1 | MoveL0FileToLevel(2); |
178 | 1 | ASSERT_EQ(FilesOnLevel(2), 1); |
179 | 1 | ASSERT_EQ(FilesOnLevel(3), 1); |
180 | 1 | ASSERT_EQ(FilesOnLevel(4), 1); |
181 | 1 | CloseDB(); |
182 | | |
183 | 1 | ASSERT_OK(OpenDB(true, 5)); |
184 | 1 | ASSERT_OK(Put("d", "d11111")); |
185 | 1 | ASSERT_OK(Flush()); |
186 | 1 | MoveL0FileToLevel(1); |
187 | 1 | ASSERT_EQ(FilesOnLevel(1), 1); |
188 | 1 | ASSERT_EQ(FilesOnLevel(2), 1); |
189 | 1 | ASSERT_EQ(FilesOnLevel(3), 1); |
190 | 1 | ASSERT_EQ(FilesOnLevel(4), 1); |
191 | 1 | CloseDB(); |
192 | | |
193 | 1 | ASSERT_TRUE(ReduceLevels(4)); |
194 | 1 | ASSERT_OK(OpenDB(true, 4)); |
195 | 1 | ASSERT_EQ("a11111", Get("a")); |
196 | 1 | ASSERT_EQ("b11111", Get("b")); |
197 | 1 | ASSERT_EQ("c11111", Get("c")); |
198 | 1 | ASSERT_EQ("d11111", Get("d")); |
199 | 1 | CloseDB(); |
200 | | |
201 | 1 | ASSERT_TRUE(ReduceLevels(3)); |
202 | 1 | ASSERT_OK(OpenDB(true, 3)); |
203 | 1 | ASSERT_EQ("a11111", Get("a")); |
204 | 1 | ASSERT_EQ("b11111", Get("b")); |
205 | 1 | ASSERT_EQ("c11111", Get("c")); |
206 | 1 | ASSERT_EQ("d11111", Get("d")); |
207 | 1 | CloseDB(); |
208 | | |
209 | 1 | ASSERT_TRUE(ReduceLevels(2)); |
210 | 1 | ASSERT_OK(OpenDB(true, 2)); |
211 | 1 | ASSERT_EQ("a11111", Get("a")); |
212 | 1 | ASSERT_EQ("b11111", Get("b")); |
213 | 1 | ASSERT_EQ("c11111", Get("c")); |
214 | 1 | ASSERT_EQ("d11111", Get("d")); |
215 | 1 | CloseDB(); |
216 | 1 | } |
217 | | |
218 | | } // namespace rocksdb |
219 | | |
220 | 13.2k | int main(int argc, char** argv) { |
221 | 13.2k | ::testing::InitGoogleTest(&argc, argv); |
222 | 13.2k | return RUN_ALL_TESTS(); |
223 | 13.2k | } |
224 | | |
225 | | #else |
226 | | #include <stdio.h> |
227 | | |
228 | | int main(int argc, char** argv) { |
229 | | fprintf(stderr, "SKIPPED as LDBCommand is not supported in ROCKSDB_LITE\n"); |
230 | | return 0; |
231 | | } |
232 | | |
233 | | #endif // !ROCKSDB_LITE |