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("bdb7f34a59dfa1592ce7f52e99f98c570c525cbd");
51 BlobFileAddition
blob_file_addition(blob_file_number
, total_blob_count
,
52 total_blob_bytes
, checksum_method
,
55 ASSERT_EQ(blob_file_addition
.GetBlobFileNumber(), blob_file_number
);
56 ASSERT_EQ(blob_file_addition
.GetTotalBlobCount(), total_blob_count
);
57 ASSERT_EQ(blob_file_addition
.GetTotalBlobBytes(), total_blob_bytes
);
58 ASSERT_EQ(blob_file_addition
.GetChecksumMethod(), checksum_method
);
59 ASSERT_EQ(blob_file_addition
.GetChecksumValue(), checksum_value
);
61 TestEncodeDecode(blob_file_addition
);
64 TEST_F(BlobFileAdditionTest
, DecodeErrors
) {
68 BlobFileAddition blob_file_addition
;
71 const Status s
= blob_file_addition
.DecodeFrom(&slice
);
72 ASSERT_TRUE(s
.IsCorruption());
73 ASSERT_TRUE(std::strstr(s
.getState(), "blob file number"));
76 constexpr uint64_t blob_file_number
= 123;
77 PutVarint64(&str
, blob_file_number
);
81 const Status s
= blob_file_addition
.DecodeFrom(&slice
);
82 ASSERT_TRUE(s
.IsCorruption());
83 ASSERT_TRUE(std::strstr(s
.getState(), "total blob count"));
86 constexpr uint64_t total_blob_count
= 4567;
87 PutVarint64(&str
, total_blob_count
);
91 const Status s
= blob_file_addition
.DecodeFrom(&slice
);
92 ASSERT_TRUE(s
.IsCorruption());
93 ASSERT_TRUE(std::strstr(s
.getState(), "total blob bytes"));
96 constexpr uint64_t total_blob_bytes
= 12345678;
97 PutVarint64(&str
, total_blob_bytes
);
101 const Status s
= blob_file_addition
.DecodeFrom(&slice
);
102 ASSERT_TRUE(s
.IsCorruption());
103 ASSERT_TRUE(std::strstr(s
.getState(), "checksum method"));
106 constexpr char checksum_method
[] = "SHA1";
107 PutLengthPrefixedSlice(&str
, checksum_method
);
111 const Status s
= blob_file_addition
.DecodeFrom(&slice
);
112 ASSERT_TRUE(s
.IsCorruption());
113 ASSERT_TRUE(std::strstr(s
.getState(), "checksum value"));
116 constexpr char checksum_value
[] = "bdb7f34a59dfa1592ce7f52e99f98c570c525cbd";
117 PutLengthPrefixedSlice(&str
, checksum_value
);
121 const Status s
= blob_file_addition
.DecodeFrom(&slice
);
122 ASSERT_TRUE(s
.IsCorruption());
123 ASSERT_TRUE(std::strstr(s
.getState(), "custom field tag"));
126 constexpr uint32_t custom_tag
= 2;
127 PutVarint32(&str
, custom_tag
);
131 const Status s
= blob_file_addition
.DecodeFrom(&slice
);
132 ASSERT_TRUE(s
.IsCorruption());
133 ASSERT_TRUE(std::strstr(s
.getState(), "custom field value"));
137 TEST_F(BlobFileAdditionTest
, ForwardCompatibleCustomField
) {
138 SyncPoint::GetInstance()->SetCallBack(
139 "BlobFileAddition::EncodeTo::CustomFields", [&](void* arg
) {
140 std::string
* output
= static_cast<std::string
*>(arg
);
142 constexpr uint32_t forward_compatible_tag
= 2;
143 PutVarint32(output
, forward_compatible_tag
);
145 PutLengthPrefixedSlice(output
, "deadbeef");
147 SyncPoint::GetInstance()->EnableProcessing();
149 constexpr uint64_t blob_file_number
= 678;
150 constexpr uint64_t total_blob_count
= 9999;
151 constexpr uint64_t total_blob_bytes
= 100000000;
152 const std::string
checksum_method("CRC32");
153 const std::string
checksum_value("3d87ff57");
155 BlobFileAddition
blob_file_addition(blob_file_number
, total_blob_count
,
156 total_blob_bytes
, checksum_method
,
159 TestEncodeDecode(blob_file_addition
);
161 SyncPoint::GetInstance()->DisableProcessing();
162 SyncPoint::GetInstance()->ClearAllCallBacks();
165 TEST_F(BlobFileAdditionTest
, ForwardIncompatibleCustomField
) {
166 SyncPoint::GetInstance()->SetCallBack(
167 "BlobFileAddition::EncodeTo::CustomFields", [&](void* arg
) {
168 std::string
* output
= static_cast<std::string
*>(arg
);
170 constexpr uint32_t forward_incompatible_tag
= (1 << 6) + 1;
171 PutVarint32(output
, forward_incompatible_tag
);
173 PutLengthPrefixedSlice(output
, "foobar");
175 SyncPoint::GetInstance()->EnableProcessing();
177 constexpr uint64_t blob_file_number
= 456;
178 constexpr uint64_t total_blob_count
= 100;
179 constexpr uint64_t total_blob_bytes
= 2000000;
180 const std::string
checksum_method("CRC32B");
181 const std::string
checksum_value("6dbdf23a");
183 BlobFileAddition
blob_file_addition(blob_file_number
, total_blob_count
,
184 total_blob_bytes
, checksum_method
,
188 blob_file_addition
.EncodeTo(&encoded
);
190 BlobFileAddition decoded_blob_file_addition
;
191 Slice
input(encoded
);
192 const Status s
= decoded_blob_file_addition
.DecodeFrom(&input
);
194 ASSERT_TRUE(s
.IsCorruption());
195 ASSERT_TRUE(std::strstr(s
.getState(), "Forward incompatible"));
197 SyncPoint::GetInstance()->DisableProcessing();
198 SyncPoint::GetInstance()->ClearAllCallBacks();
201 } // namespace ROCKSDB_NAMESPACE
203 int main(int argc
, char** argv
) {
204 ::testing::InitGoogleTest(&argc
, argv
);
205 return RUN_ALL_TESTS();