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).
6 #include "db/blob/blob_file_addition.h"
12 #include "test_util/sync_point.h"
13 #include "test_util/testharness.h"
14 #include "util/coding.h"
16 namespace ROCKSDB_NAMESPACE
{
18 class BlobFileAdditionTest
: public testing::Test
{
20 static void TestEncodeDecode(const BlobFileAddition
& blob_file_addition
) {
22 blob_file_addition
.EncodeTo(&encoded
);
24 BlobFileAddition decoded
;
26 ASSERT_OK(decoded
.DecodeFrom(&input
));
28 ASSERT_EQ(blob_file_addition
, decoded
);
32 TEST_F(BlobFileAdditionTest
, Empty
) {
33 BlobFileAddition blob_file_addition
;
35 ASSERT_EQ(blob_file_addition
.GetBlobFileNumber(), kInvalidBlobFileNumber
);
36 ASSERT_EQ(blob_file_addition
.GetTotalBlobCount(), 0);
37 ASSERT_EQ(blob_file_addition
.GetTotalBlobBytes(), 0);
38 ASSERT_TRUE(blob_file_addition
.GetChecksumMethod().empty());
39 ASSERT_TRUE(blob_file_addition
.GetChecksumValue().empty());
41 TestEncodeDecode(blob_file_addition
);
44 TEST_F(BlobFileAdditionTest
, NonEmpty
) {
45 constexpr uint64_t blob_file_number
= 123;
46 constexpr uint64_t total_blob_count
= 2;
47 constexpr uint64_t total_blob_bytes
= 123456;
48 const std::string
checksum_method("SHA1");
49 const std::string
checksum_value(
50 "\xbd\xb7\xf3\x4a\x59\xdf\xa1\x59\x2c\xe7\xf5\x2e\x99\xf9\x8c\x57\x0c\x52"
53 BlobFileAddition
blob_file_addition(blob_file_number
, total_blob_count
,
54 total_blob_bytes
, checksum_method
,
57 ASSERT_EQ(blob_file_addition
.GetBlobFileNumber(), blob_file_number
);
58 ASSERT_EQ(blob_file_addition
.GetTotalBlobCount(), total_blob_count
);
59 ASSERT_EQ(blob_file_addition
.GetTotalBlobBytes(), total_blob_bytes
);
60 ASSERT_EQ(blob_file_addition
.GetChecksumMethod(), checksum_method
);
61 ASSERT_EQ(blob_file_addition
.GetChecksumValue(), checksum_value
);
63 TestEncodeDecode(blob_file_addition
);
66 TEST_F(BlobFileAdditionTest
, DecodeErrors
) {
70 BlobFileAddition blob_file_addition
;
73 const Status s
= blob_file_addition
.DecodeFrom(&slice
);
74 ASSERT_TRUE(s
.IsCorruption());
75 ASSERT_TRUE(std::strstr(s
.getState(), "blob file number"));
78 constexpr uint64_t blob_file_number
= 123;
79 PutVarint64(&str
, blob_file_number
);
83 const Status s
= blob_file_addition
.DecodeFrom(&slice
);
84 ASSERT_TRUE(s
.IsCorruption());
85 ASSERT_TRUE(std::strstr(s
.getState(), "total blob count"));
88 constexpr uint64_t total_blob_count
= 4567;
89 PutVarint64(&str
, total_blob_count
);
93 const Status s
= blob_file_addition
.DecodeFrom(&slice
);
94 ASSERT_TRUE(s
.IsCorruption());
95 ASSERT_TRUE(std::strstr(s
.getState(), "total blob bytes"));
98 constexpr uint64_t total_blob_bytes
= 12345678;
99 PutVarint64(&str
, total_blob_bytes
);
103 const Status s
= blob_file_addition
.DecodeFrom(&slice
);
104 ASSERT_TRUE(s
.IsCorruption());
105 ASSERT_TRUE(std::strstr(s
.getState(), "checksum method"));
108 constexpr char checksum_method
[] = "SHA1";
109 PutLengthPrefixedSlice(&str
, checksum_method
);
113 const Status s
= blob_file_addition
.DecodeFrom(&slice
);
114 ASSERT_TRUE(s
.IsCorruption());
115 ASSERT_TRUE(std::strstr(s
.getState(), "checksum value"));
118 constexpr char checksum_value
[] =
119 "\xbd\xb7\xf3\x4a\x59\xdf\xa1\x59\x2c\xe7\xf5\x2e\x99\xf9\x8c\x57\x0c\x52"
121 PutLengthPrefixedSlice(&str
, checksum_value
);
125 const Status s
= blob_file_addition
.DecodeFrom(&slice
);
126 ASSERT_TRUE(s
.IsCorruption());
127 ASSERT_TRUE(std::strstr(s
.getState(), "custom field tag"));
130 constexpr uint32_t custom_tag
= 2;
131 PutVarint32(&str
, custom_tag
);
135 const Status s
= blob_file_addition
.DecodeFrom(&slice
);
136 ASSERT_TRUE(s
.IsCorruption());
137 ASSERT_TRUE(std::strstr(s
.getState(), "custom field value"));
141 TEST_F(BlobFileAdditionTest
, ForwardCompatibleCustomField
) {
142 SyncPoint::GetInstance()->SetCallBack(
143 "BlobFileAddition::EncodeTo::CustomFields", [&](void* arg
) {
144 std::string
* output
= static_cast<std::string
*>(arg
);
146 constexpr uint32_t forward_compatible_tag
= 2;
147 PutVarint32(output
, forward_compatible_tag
);
149 PutLengthPrefixedSlice(output
, "deadbeef");
151 SyncPoint::GetInstance()->EnableProcessing();
153 constexpr uint64_t blob_file_number
= 678;
154 constexpr uint64_t total_blob_count
= 9999;
155 constexpr uint64_t total_blob_bytes
= 100000000;
156 const std::string
checksum_method("CRC32");
157 const std::string
checksum_value("\x3d\x87\xff\x57");
159 BlobFileAddition
blob_file_addition(blob_file_number
, total_blob_count
,
160 total_blob_bytes
, checksum_method
,
163 TestEncodeDecode(blob_file_addition
);
165 SyncPoint::GetInstance()->DisableProcessing();
166 SyncPoint::GetInstance()->ClearAllCallBacks();
169 TEST_F(BlobFileAdditionTest
, ForwardIncompatibleCustomField
) {
170 SyncPoint::GetInstance()->SetCallBack(
171 "BlobFileAddition::EncodeTo::CustomFields", [&](void* arg
) {
172 std::string
* output
= static_cast<std::string
*>(arg
);
174 constexpr uint32_t forward_incompatible_tag
= (1 << 6) + 1;
175 PutVarint32(output
, forward_incompatible_tag
);
177 PutLengthPrefixedSlice(output
, "foobar");
179 SyncPoint::GetInstance()->EnableProcessing();
181 constexpr uint64_t blob_file_number
= 456;
182 constexpr uint64_t total_blob_count
= 100;
183 constexpr uint64_t total_blob_bytes
= 2000000;
184 const std::string
checksum_method("CRC32B");
185 const std::string
checksum_value("\x6d\xbd\xf2\x3a");
187 BlobFileAddition
blob_file_addition(blob_file_number
, total_blob_count
,
188 total_blob_bytes
, checksum_method
,
192 blob_file_addition
.EncodeTo(&encoded
);
194 BlobFileAddition decoded_blob_file_addition
;
195 Slice
input(encoded
);
196 const Status s
= decoded_blob_file_addition
.DecodeFrom(&input
);
198 ASSERT_TRUE(s
.IsCorruption());
199 ASSERT_TRUE(std::strstr(s
.getState(), "Forward incompatible"));
201 SyncPoint::GetInstance()->DisableProcessing();
202 SyncPoint::GetInstance()->ClearAllCallBacks();
205 } // namespace ROCKSDB_NAMESPACE
207 int main(int argc
, char** argv
) {
208 ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
209 ::testing::InitGoogleTest(&argc
, argv
);
210 return RUN_ALL_TESTS();