]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
11fdf7f2 TL |
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). | |
7c673cae FG |
5 | // |
6 | // Copyright (c) 2011 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 | #include "db/version_edit.h" | |
f67539c2 TL |
11 | #include "test_util/sync_point.h" |
12 | #include "test_util/testharness.h" | |
494da23a | 13 | #include "util/coding.h" |
20effc67 | 14 | #include "util/string_util.h" |
7c673cae | 15 | |
f67539c2 | 16 | namespace ROCKSDB_NAMESPACE { |
7c673cae FG |
17 | |
18 | static void TestEncodeDecode(const VersionEdit& edit) { | |
19 | std::string encoded, encoded2; | |
20 | edit.EncodeTo(&encoded); | |
21 | VersionEdit parsed; | |
22 | Status s = parsed.DecodeFrom(encoded); | |
23 | ASSERT_TRUE(s.ok()) << s.ToString(); | |
24 | parsed.EncodeTo(&encoded2); | |
25 | ASSERT_EQ(encoded, encoded2); | |
26 | } | |
27 | ||
28 | class VersionEditTest : public testing::Test {}; | |
29 | ||
30 | TEST_F(VersionEditTest, EncodeDecode) { | |
31 | static const uint64_t kBig = 1ull << 50; | |
32 | static const uint32_t kBig32Bit = 1ull << 30; | |
33 | ||
34 | VersionEdit edit; | |
35 | for (int i = 0; i < 4; i++) { | |
36 | TestEncodeDecode(edit); | |
37 | edit.AddFile(3, kBig + 300 + i, kBig32Bit + 400 + i, 0, | |
38 | InternalKey("foo", kBig + 500 + i, kTypeValue), | |
39 | InternalKey("zoo", kBig + 600 + i, kTypeDeletion), | |
f67539c2 TL |
40 | kBig + 500 + i, kBig + 600 + i, false, kInvalidBlobFileNumber, |
41 | 888, 678, "234", "crc32c"); | |
7c673cae FG |
42 | edit.DeleteFile(4, kBig + 700 + i); |
43 | } | |
44 | ||
45 | edit.SetComparatorName("foo"); | |
46 | edit.SetLogNumber(kBig + 100); | |
47 | edit.SetNextFile(kBig + 200); | |
48 | edit.SetLastSequence(kBig + 1000); | |
49 | TestEncodeDecode(edit); | |
50 | } | |
51 | ||
52 | TEST_F(VersionEditTest, EncodeDecodeNewFile4) { | |
53 | static const uint64_t kBig = 1ull << 50; | |
54 | ||
55 | VersionEdit edit; | |
56 | edit.AddFile(3, 300, 3, 100, InternalKey("foo", kBig + 500, kTypeValue), | |
57 | InternalKey("zoo", kBig + 600, kTypeDeletion), kBig + 500, | |
f67539c2 TL |
58 | kBig + 600, true, kInvalidBlobFileNumber, |
59 | kUnknownOldestAncesterTime, kUnknownFileCreationTime, | |
60 | kUnknownFileChecksum, kUnknownFileChecksumFuncName); | |
7c673cae FG |
61 | edit.AddFile(4, 301, 3, 100, InternalKey("foo", kBig + 501, kTypeValue), |
62 | InternalKey("zoo", kBig + 601, kTypeDeletion), kBig + 501, | |
f67539c2 TL |
63 | kBig + 601, false, kInvalidBlobFileNumber, |
64 | kUnknownOldestAncesterTime, kUnknownFileCreationTime, | |
65 | kUnknownFileChecksum, kUnknownFileChecksumFuncName); | |
7c673cae FG |
66 | edit.AddFile(5, 302, 0, 100, InternalKey("foo", kBig + 502, kTypeValue), |
67 | InternalKey("zoo", kBig + 602, kTypeDeletion), kBig + 502, | |
f67539c2 TL |
68 | kBig + 602, true, kInvalidBlobFileNumber, 666, 888, |
69 | kUnknownFileChecksum, kUnknownFileChecksumFuncName); | |
70 | edit.AddFile(5, 303, 0, 100, InternalKey("foo", kBig + 503, kTypeBlobIndex), | |
71 | InternalKey("zoo", kBig + 603, kTypeBlobIndex), kBig + 503, | |
72 | kBig + 603, true, 1001, kUnknownOldestAncesterTime, | |
73 | kUnknownFileCreationTime, kUnknownFileChecksum, | |
74 | kUnknownFileChecksumFuncName); | |
75 | ; | |
7c673cae FG |
76 | |
77 | edit.DeleteFile(4, 700); | |
78 | ||
79 | edit.SetComparatorName("foo"); | |
80 | edit.SetLogNumber(kBig + 100); | |
81 | edit.SetNextFile(kBig + 200); | |
82 | edit.SetLastSequence(kBig + 1000); | |
83 | TestEncodeDecode(edit); | |
84 | ||
85 | std::string encoded, encoded2; | |
86 | edit.EncodeTo(&encoded); | |
87 | VersionEdit parsed; | |
88 | Status s = parsed.DecodeFrom(encoded); | |
89 | ASSERT_TRUE(s.ok()) << s.ToString(); | |
90 | auto& new_files = parsed.GetNewFiles(); | |
91 | ASSERT_TRUE(new_files[0].second.marked_for_compaction); | |
92 | ASSERT_TRUE(!new_files[1].second.marked_for_compaction); | |
93 | ASSERT_TRUE(new_files[2].second.marked_for_compaction); | |
f67539c2 TL |
94 | ASSERT_TRUE(new_files[3].second.marked_for_compaction); |
95 | ASSERT_EQ(3u, new_files[0].second.fd.GetPathId()); | |
96 | ASSERT_EQ(3u, new_files[1].second.fd.GetPathId()); | |
97 | ASSERT_EQ(0u, new_files[2].second.fd.GetPathId()); | |
98 | ASSERT_EQ(0u, new_files[3].second.fd.GetPathId()); | |
99 | ASSERT_EQ(kInvalidBlobFileNumber, | |
100 | new_files[0].second.oldest_blob_file_number); | |
101 | ASSERT_EQ(kInvalidBlobFileNumber, | |
102 | new_files[1].second.oldest_blob_file_number); | |
103 | ASSERT_EQ(kInvalidBlobFileNumber, | |
104 | new_files[2].second.oldest_blob_file_number); | |
105 | ASSERT_EQ(1001, new_files[3].second.oldest_blob_file_number); | |
7c673cae FG |
106 | } |
107 | ||
108 | TEST_F(VersionEditTest, ForwardCompatibleNewFile4) { | |
109 | static const uint64_t kBig = 1ull << 50; | |
110 | VersionEdit edit; | |
111 | edit.AddFile(3, 300, 3, 100, InternalKey("foo", kBig + 500, kTypeValue), | |
112 | InternalKey("zoo", kBig + 600, kTypeDeletion), kBig + 500, | |
f67539c2 TL |
113 | kBig + 600, true, kInvalidBlobFileNumber, |
114 | kUnknownOldestAncesterTime, kUnknownFileCreationTime, | |
115 | kUnknownFileChecksum, kUnknownFileChecksumFuncName); | |
7c673cae FG |
116 | edit.AddFile(4, 301, 3, 100, InternalKey("foo", kBig + 501, kTypeValue), |
117 | InternalKey("zoo", kBig + 601, kTypeDeletion), kBig + 501, | |
f67539c2 TL |
118 | kBig + 601, false, kInvalidBlobFileNumber, 686, 868, "234", |
119 | "crc32c"); | |
7c673cae FG |
120 | edit.DeleteFile(4, 700); |
121 | ||
122 | edit.SetComparatorName("foo"); | |
123 | edit.SetLogNumber(kBig + 100); | |
124 | edit.SetNextFile(kBig + 200); | |
125 | edit.SetLastSequence(kBig + 1000); | |
126 | ||
127 | std::string encoded; | |
128 | ||
129 | // Call back function to add extra customized builds. | |
130 | bool first = true; | |
f67539c2 | 131 | ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack( |
7c673cae FG |
132 | "VersionEdit::EncodeTo:NewFile4:CustomizeFields", [&](void* arg) { |
133 | std::string* str = reinterpret_cast<std::string*>(arg); | |
134 | PutVarint32(str, 33); | |
135 | const std::string str1 = "random_string"; | |
136 | PutLengthPrefixedSlice(str, str1); | |
137 | if (first) { | |
138 | first = false; | |
139 | PutVarint32(str, 22); | |
140 | const std::string str2 = "s"; | |
141 | PutLengthPrefixedSlice(str, str2); | |
142 | } | |
143 | }); | |
f67539c2 | 144 | ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing(); |
7c673cae | 145 | edit.EncodeTo(&encoded); |
f67539c2 | 146 | ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->DisableProcessing(); |
7c673cae FG |
147 | |
148 | VersionEdit parsed; | |
149 | Status s = parsed.DecodeFrom(encoded); | |
150 | ASSERT_TRUE(s.ok()) << s.ToString(); | |
151 | ASSERT_TRUE(!first); | |
152 | auto& new_files = parsed.GetNewFiles(); | |
153 | ASSERT_TRUE(new_files[0].second.marked_for_compaction); | |
154 | ASSERT_TRUE(!new_files[1].second.marked_for_compaction); | |
f67539c2 TL |
155 | ASSERT_EQ(3u, new_files[0].second.fd.GetPathId()); |
156 | ASSERT_EQ(3u, new_files[1].second.fd.GetPathId()); | |
7c673cae FG |
157 | ASSERT_EQ(1u, parsed.GetDeletedFiles().size()); |
158 | } | |
159 | ||
160 | TEST_F(VersionEditTest, NewFile4NotSupportedField) { | |
161 | static const uint64_t kBig = 1ull << 50; | |
162 | VersionEdit edit; | |
163 | edit.AddFile(3, 300, 3, 100, InternalKey("foo", kBig + 500, kTypeValue), | |
164 | InternalKey("zoo", kBig + 600, kTypeDeletion), kBig + 500, | |
f67539c2 TL |
165 | kBig + 600, true, kInvalidBlobFileNumber, |
166 | kUnknownOldestAncesterTime, kUnknownFileCreationTime, | |
167 | kUnknownFileChecksum, kUnknownFileChecksumFuncName); | |
7c673cae FG |
168 | |
169 | edit.SetComparatorName("foo"); | |
170 | edit.SetLogNumber(kBig + 100); | |
171 | edit.SetNextFile(kBig + 200); | |
172 | edit.SetLastSequence(kBig + 1000); | |
173 | ||
174 | std::string encoded; | |
175 | ||
176 | // Call back function to add extra customized builds. | |
f67539c2 | 177 | ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack( |
7c673cae FG |
178 | "VersionEdit::EncodeTo:NewFile4:CustomizeFields", [&](void* arg) { |
179 | std::string* str = reinterpret_cast<std::string*>(arg); | |
180 | const std::string str1 = "s"; | |
181 | PutLengthPrefixedSlice(str, str1); | |
182 | }); | |
f67539c2 | 183 | ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing(); |
7c673cae | 184 | edit.EncodeTo(&encoded); |
f67539c2 | 185 | ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->DisableProcessing(); |
7c673cae FG |
186 | |
187 | VersionEdit parsed; | |
188 | Status s = parsed.DecodeFrom(encoded); | |
189 | ASSERT_NOK(s); | |
190 | } | |
191 | ||
192 | TEST_F(VersionEditTest, EncodeEmptyFile) { | |
193 | VersionEdit edit; | |
f67539c2 TL |
194 | edit.AddFile(0, 0, 0, 0, InternalKey(), InternalKey(), 0, 0, false, |
195 | kInvalidBlobFileNumber, kUnknownOldestAncesterTime, | |
196 | kUnknownFileCreationTime, kUnknownFileChecksum, | |
197 | kUnknownFileChecksumFuncName); | |
7c673cae FG |
198 | std::string buffer; |
199 | ASSERT_TRUE(!edit.EncodeTo(&buffer)); | |
200 | } | |
201 | ||
202 | TEST_F(VersionEditTest, ColumnFamilyTest) { | |
203 | VersionEdit edit; | |
204 | edit.SetColumnFamily(2); | |
205 | edit.AddColumnFamily("column_family"); | |
206 | edit.SetMaxColumnFamily(5); | |
207 | TestEncodeDecode(edit); | |
208 | ||
209 | edit.Clear(); | |
210 | edit.SetColumnFamily(3); | |
211 | edit.DropColumnFamily(); | |
212 | TestEncodeDecode(edit); | |
213 | } | |
214 | ||
11fdf7f2 TL |
215 | TEST_F(VersionEditTest, MinLogNumberToKeep) { |
216 | VersionEdit edit; | |
217 | edit.SetMinLogNumberToKeep(13); | |
218 | TestEncodeDecode(edit); | |
219 | ||
220 | edit.Clear(); | |
221 | edit.SetMinLogNumberToKeep(23); | |
222 | TestEncodeDecode(edit); | |
223 | } | |
224 | ||
225 | TEST_F(VersionEditTest, AtomicGroupTest) { | |
226 | VersionEdit edit; | |
227 | edit.MarkAtomicGroup(1); | |
228 | TestEncodeDecode(edit); | |
229 | } | |
230 | ||
494da23a TL |
231 | TEST_F(VersionEditTest, IgnorableField) { |
232 | VersionEdit ve; | |
233 | std::string encoded; | |
234 | ||
235 | // Size of ignorable field is too large | |
236 | PutVarint32Varint64(&encoded, 2 /* kLogNumber */, 66); | |
237 | // This is a customized ignorable tag | |
238 | PutVarint32Varint64(&encoded, | |
239 | 0x2710 /* A field with kTagSafeIgnoreMask set */, | |
240 | 5 /* fieldlength 5 */); | |
241 | encoded += "abc"; // Only fills 3 bytes, | |
242 | ASSERT_NOK(ve.DecodeFrom(encoded)); | |
243 | ||
244 | encoded.clear(); | |
245 | // Error when seeing unidentified tag that is not ignorable | |
246 | PutVarint32Varint64(&encoded, 2 /* kLogNumber */, 66); | |
247 | // This is a customized ignorable tag | |
248 | PutVarint32Varint64(&encoded, 666 /* A field with kTagSafeIgnoreMask unset */, | |
249 | 3 /* fieldlength 3 */); | |
250 | encoded += "abc"; // Fill 3 bytes | |
251 | PutVarint32Varint64(&encoded, 3 /* next file number */, 88); | |
252 | ASSERT_NOK(ve.DecodeFrom(encoded)); | |
253 | ||
254 | // Safely ignore an identified but safely ignorable entry | |
255 | encoded.clear(); | |
256 | PutVarint32Varint64(&encoded, 2 /* kLogNumber */, 66); | |
257 | // This is a customized ignorable tag | |
258 | PutVarint32Varint64(&encoded, | |
259 | 0x2710 /* A field with kTagSafeIgnoreMask set */, | |
260 | 3 /* fieldlength 3 */); | |
261 | encoded += "abc"; // Fill 3 bytes | |
262 | PutVarint32Varint64(&encoded, 3 /* kNextFileNumber */, 88); | |
263 | ||
264 | ASSERT_OK(ve.DecodeFrom(encoded)); | |
265 | ||
f67539c2 TL |
266 | ASSERT_TRUE(ve.HasLogNumber()); |
267 | ASSERT_TRUE(ve.HasNextFile()); | |
268 | ASSERT_EQ(66, ve.GetLogNumber()); | |
269 | ASSERT_EQ(88, ve.GetNextFile()); | |
494da23a TL |
270 | } |
271 | ||
f67539c2 TL |
272 | TEST_F(VersionEditTest, DbId) { |
273 | VersionEdit edit; | |
274 | edit.SetDBId("ab34-cd12-435f-er00"); | |
275 | TestEncodeDecode(edit); | |
276 | ||
277 | edit.Clear(); | |
278 | edit.SetDBId("34ba-cd12-435f-er01"); | |
279 | TestEncodeDecode(edit); | |
280 | } | |
281 | ||
20effc67 TL |
282 | TEST_F(VersionEditTest, BlobFileAdditionAndGarbage) { |
283 | VersionEdit edit; | |
284 | ||
285 | const std::string checksum_method_prefix = "Hash"; | |
286 | const std::string checksum_value_prefix = "Value"; | |
287 | ||
288 | for (uint64_t blob_file_number = 1; blob_file_number <= 10; | |
289 | ++blob_file_number) { | |
290 | const uint64_t total_blob_count = blob_file_number << 10; | |
291 | const uint64_t total_blob_bytes = blob_file_number << 20; | |
292 | ||
293 | std::string checksum_method(checksum_method_prefix); | |
294 | AppendNumberTo(&checksum_method, blob_file_number); | |
295 | ||
296 | std::string checksum_value(checksum_value_prefix); | |
297 | AppendNumberTo(&checksum_value, blob_file_number); | |
298 | ||
299 | edit.AddBlobFile(blob_file_number, total_blob_count, total_blob_bytes, | |
300 | checksum_method, checksum_value); | |
301 | ||
302 | const uint64_t garbage_blob_count = total_blob_count >> 2; | |
303 | const uint64_t garbage_blob_bytes = total_blob_bytes >> 1; | |
304 | ||
305 | edit.AddBlobFileGarbage(blob_file_number, garbage_blob_count, | |
306 | garbage_blob_bytes); | |
307 | } | |
308 | ||
309 | TestEncodeDecode(edit); | |
310 | } | |
311 | ||
312 | TEST_F(VersionEditTest, AddWalEncodeDecode) { | |
313 | VersionEdit edit; | |
314 | for (uint64_t log_number = 1; log_number <= 20; log_number++) { | |
315 | WalMetadata meta; | |
316 | bool has_size = rand() % 2 == 0; | |
317 | if (has_size) { | |
318 | meta.SetSyncedSizeInBytes(rand() % 1000); | |
319 | } | |
320 | edit.AddWal(log_number, meta); | |
321 | } | |
322 | TestEncodeDecode(edit); | |
323 | } | |
324 | ||
325 | TEST_F(VersionEditTest, AddWalDecodeBadLogNumber) { | |
326 | std::string encoded; | |
327 | PutVarint32(&encoded, Tag::kWalAddition); | |
328 | ||
329 | { | |
330 | // No log number. | |
331 | VersionEdit edit; | |
332 | Status s = edit.DecodeFrom(encoded); | |
333 | ASSERT_TRUE(s.IsCorruption()); | |
334 | ASSERT_TRUE(s.ToString().find("Error decoding WAL log number") != | |
335 | std::string::npos) | |
336 | << s.ToString(); | |
337 | } | |
338 | ||
339 | { | |
340 | // log number should be varint64, | |
341 | // but we only encode 128 which is not a valid representation of varint64. | |
342 | char c = 0; | |
343 | unsigned char* ptr = reinterpret_cast<unsigned char*>(&c); | |
344 | *ptr = 128; | |
345 | encoded.append(1, c); | |
346 | VersionEdit edit; | |
347 | Status s = edit.DecodeFrom(encoded); | |
348 | ASSERT_TRUE(s.IsCorruption()); | |
349 | ASSERT_TRUE(s.ToString().find("Error decoding WAL log number") != | |
350 | std::string::npos) | |
351 | << s.ToString(); | |
352 | } | |
353 | } | |
354 | ||
355 | TEST_F(VersionEditTest, AddWalDecodeBadTag) { | |
356 | constexpr WalNumber kLogNumber = 100; | |
357 | constexpr uint64_t kSizeInBytes = 100; | |
358 | ||
359 | std::string encoded_without_tag; | |
360 | PutVarint32(&encoded_without_tag, Tag::kWalAddition); | |
361 | PutVarint64(&encoded_without_tag, kLogNumber); | |
362 | ||
363 | { | |
364 | // No tag. | |
365 | VersionEdit edit; | |
366 | Status s = edit.DecodeFrom(encoded_without_tag); | |
367 | ASSERT_TRUE(s.IsCorruption()); | |
368 | ASSERT_TRUE(s.ToString().find("Error decoding tag") != std::string::npos) | |
369 | << s.ToString(); | |
370 | } | |
371 | ||
372 | { | |
373 | // Only has size tag, no terminate tag. | |
374 | std::string encoded_with_size = encoded_without_tag; | |
375 | PutVarint32(&encoded_with_size, | |
376 | static_cast<uint32_t>(WalAdditionTag::kSyncedSize)); | |
377 | PutVarint64(&encoded_with_size, kSizeInBytes); | |
378 | VersionEdit edit; | |
379 | Status s = edit.DecodeFrom(encoded_with_size); | |
380 | ASSERT_TRUE(s.IsCorruption()); | |
381 | ASSERT_TRUE(s.ToString().find("Error decoding tag") != std::string::npos) | |
382 | << s.ToString(); | |
383 | } | |
384 | ||
385 | { | |
386 | // Only has terminate tag. | |
387 | std::string encoded_with_terminate = encoded_without_tag; | |
388 | PutVarint32(&encoded_with_terminate, | |
389 | static_cast<uint32_t>(WalAdditionTag::kTerminate)); | |
390 | VersionEdit edit; | |
391 | ASSERT_OK(edit.DecodeFrom(encoded_with_terminate)); | |
392 | auto& wal_addition = edit.GetWalAdditions()[0]; | |
393 | ASSERT_EQ(wal_addition.GetLogNumber(), kLogNumber); | |
394 | ASSERT_FALSE(wal_addition.GetMetadata().HasSyncedSize()); | |
395 | } | |
396 | } | |
397 | ||
398 | TEST_F(VersionEditTest, AddWalDecodeNoSize) { | |
399 | constexpr WalNumber kLogNumber = 100; | |
400 | ||
401 | std::string encoded; | |
402 | PutVarint32(&encoded, Tag::kWalAddition); | |
403 | PutVarint64(&encoded, kLogNumber); | |
404 | PutVarint32(&encoded, static_cast<uint32_t>(WalAdditionTag::kSyncedSize)); | |
405 | // No real size after the size tag. | |
406 | ||
407 | { | |
408 | // Without terminate tag. | |
409 | VersionEdit edit; | |
410 | Status s = edit.DecodeFrom(encoded); | |
411 | ASSERT_TRUE(s.IsCorruption()); | |
412 | ASSERT_TRUE(s.ToString().find("Error decoding WAL file size") != | |
413 | std::string::npos) | |
414 | << s.ToString(); | |
415 | } | |
416 | ||
417 | { | |
418 | // With terminate tag. | |
419 | PutVarint32(&encoded, static_cast<uint32_t>(WalAdditionTag::kTerminate)); | |
420 | VersionEdit edit; | |
421 | Status s = edit.DecodeFrom(encoded); | |
422 | ASSERT_TRUE(s.IsCorruption()); | |
423 | // The terminate tag is misunderstood as the size. | |
424 | ASSERT_TRUE(s.ToString().find("Error decoding tag") != std::string::npos) | |
425 | << s.ToString(); | |
426 | } | |
427 | } | |
428 | ||
429 | TEST_F(VersionEditTest, AddWalDebug) { | |
430 | constexpr int n = 2; | |
431 | constexpr std::array<uint64_t, n> kLogNumbers{{10, 20}}; | |
432 | constexpr std::array<uint64_t, n> kSizeInBytes{{100, 200}}; | |
433 | ||
434 | VersionEdit edit; | |
435 | for (int i = 0; i < n; i++) { | |
436 | edit.AddWal(kLogNumbers[i], WalMetadata(kSizeInBytes[i])); | |
437 | } | |
438 | ||
439 | const WalAdditions& wals = edit.GetWalAdditions(); | |
440 | ||
441 | ASSERT_TRUE(edit.IsWalAddition()); | |
442 | ASSERT_EQ(wals.size(), n); | |
443 | for (int i = 0; i < n; i++) { | |
444 | const WalAddition& wal = wals[i]; | |
445 | ASSERT_EQ(wal.GetLogNumber(), kLogNumbers[i]); | |
446 | ASSERT_EQ(wal.GetMetadata().GetSyncedSizeInBytes(), kSizeInBytes[i]); | |
447 | } | |
448 | ||
449 | std::string expected_str = "VersionEdit {\n"; | |
450 | for (int i = 0; i < n; i++) { | |
451 | std::stringstream ss; | |
452 | ss << " WalAddition: log_number: " << kLogNumbers[i] | |
453 | << " synced_size_in_bytes: " << kSizeInBytes[i] << "\n"; | |
454 | expected_str += ss.str(); | |
455 | } | |
456 | expected_str += " ColumnFamily: 0\n}\n"; | |
457 | ASSERT_EQ(edit.DebugString(true), expected_str); | |
458 | ||
459 | std::string expected_json = "{\"EditNumber\": 4, \"WalAdditions\": ["; | |
460 | for (int i = 0; i < n; i++) { | |
461 | std::stringstream ss; | |
462 | ss << "{\"LogNumber\": " << kLogNumbers[i] << ", " | |
463 | << "\"SyncedSizeInBytes\": " << kSizeInBytes[i] << "}"; | |
464 | if (i < n - 1) ss << ", "; | |
465 | expected_json += ss.str(); | |
466 | } | |
467 | expected_json += "], \"ColumnFamily\": 0}"; | |
468 | ASSERT_EQ(edit.DebugJSON(4, true), expected_json); | |
469 | } | |
470 | ||
471 | TEST_F(VersionEditTest, DeleteWalEncodeDecode) { | |
472 | VersionEdit edit; | |
473 | edit.DeleteWalsBefore(rand() % 100); | |
474 | TestEncodeDecode(edit); | |
475 | } | |
476 | ||
477 | TEST_F(VersionEditTest, DeleteWalDebug) { | |
478 | constexpr int n = 2; | |
479 | constexpr std::array<uint64_t, n> kLogNumbers{{10, 20}}; | |
480 | ||
481 | VersionEdit edit; | |
482 | edit.DeleteWalsBefore(kLogNumbers[n - 1]); | |
483 | ||
484 | const WalDeletion& wal = edit.GetWalDeletion(); | |
485 | ||
486 | ASSERT_TRUE(edit.IsWalDeletion()); | |
487 | ASSERT_EQ(wal.GetLogNumber(), kLogNumbers[n - 1]); | |
488 | ||
489 | std::string expected_str = "VersionEdit {\n"; | |
490 | { | |
491 | std::stringstream ss; | |
492 | ss << " WalDeletion: log_number: " << kLogNumbers[n - 1] << "\n"; | |
493 | expected_str += ss.str(); | |
494 | } | |
495 | expected_str += " ColumnFamily: 0\n}\n"; | |
496 | ASSERT_EQ(edit.DebugString(true), expected_str); | |
497 | ||
498 | std::string expected_json = "{\"EditNumber\": 4, \"WalDeletion\": "; | |
499 | { | |
500 | std::stringstream ss; | |
501 | ss << "{\"LogNumber\": " << kLogNumbers[n - 1] << "}"; | |
502 | expected_json += ss.str(); | |
503 | } | |
504 | expected_json += ", \"ColumnFamily\": 0}"; | |
505 | ASSERT_EQ(edit.DebugJSON(4, true), expected_json); | |
506 | } | |
507 | ||
f67539c2 | 508 | } // namespace ROCKSDB_NAMESPACE |
7c673cae FG |
509 | |
510 | int main(int argc, char** argv) { | |
511 | ::testing::InitGoogleTest(&argc, argv); | |
512 | return RUN_ALL_TESTS(); | |
513 | } |