@@ -32,16 +32,11 @@ class BlobDescriptorTest : public testing::Test {
3232 pool_ = GetDefaultPool ();
3333 ASSERT_OK_AND_ASSIGN (descriptor_,
3434 BlobDescriptor::Create (" test_uri" , /* offset=*/ 1024 , /* length=*/ 2048 ));
35-
36- std::vector<char > bytes = {1 , 8 , 0 , 0 , 0 , 116 , 101 , 115 , 116 , 95 , 117 , 114 , 105 , 0 , 4 ,
37- 0 , 0 , 0 , 0 , 0 , 0 , 0 , 8 , 0 , 0 , 0 , 0 , 0 , 0 };
38- java_serialized_ = std::string (bytes.data (), bytes.size ());
3935 }
4036
4137 private:
4238 std::shared_ptr<MemoryPool> pool_;
4339 std::unique_ptr<BlobDescriptor> descriptor_;
44- std::string java_serialized_;
4540};
4641
4742TEST_F (BlobDescriptorTest, TestConstructorAndGetters) {
@@ -50,16 +45,35 @@ TEST_F(BlobDescriptorTest, TestConstructorAndGetters) {
5045 ASSERT_EQ (descriptor_->Length (), 2048 );
5146}
5247
53- TEST_F (BlobDescriptorTest, TestSerializeDeserializeAndCompatibilityWithJava) {
54- auto serialized = descriptor_->Serialize (pool_);
55- std::string serialized_str (serialized->data (), serialized->size ());
56- ASSERT_EQ (serialized_str, java_serialized_);
48+ TEST_F (BlobDescriptorTest, TestDeserializeCompatibilityForJavaWithVersion1) {
49+ std::vector<char > bytes = {1 , 8 , 0 , 0 , 0 , 116 , 101 , 115 , 116 , 95 , 117 , 114 , 105 , 0 , 4 ,
50+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 8 , 0 , 0 , 0 , 0 , 0 , 0 };
51+ auto java_serialized = std::string (bytes.data (), bytes.size ());
52+
53+ ASSERT_OK_AND_ASSIGN (auto descriptor, BlobDescriptor::Deserialize (java_serialized.data (),
54+ java_serialized.size ()));
55+ ASSERT_EQ (descriptor->Version (), (int8_t )1 );
56+ ASSERT_EQ (descriptor->Uri (), " test_uri" );
57+ ASSERT_EQ (descriptor->Offset (), 1024 );
58+ ASSERT_EQ (descriptor->Length (), 2048 );
59+ }
5760
58- ASSERT_OK_AND_ASSIGN (auto restored_descriptor,
59- BlobDescriptor::Deserialize (serialized->data (), serialized->size ()));
60- ASSERT_EQ (restored_descriptor->Uri (), " test_uri" );
61- ASSERT_EQ (restored_descriptor->Offset (), 1024 );
62- ASSERT_EQ (restored_descriptor->Length (), 2048 );
61+ TEST_F (BlobDescriptorTest, TestDeserializeCompatibilityForJavaWithVersion2) {
62+ std::vector<char > bytes = {2 , 67 , 83 , 69 , 68 , 66 , 79 , 76 , 66 , 8 , 0 , 0 , 0 ,
63+ 116 , 101 , 115 , 116 , 95 , 117 , 114 , 105 , 0 , 4 , 0 , 0 , 0 ,
64+ 0 , 0 , 0 , 0 , 8 , 0 , 0 , 0 , 0 , 0 , 0 };
65+ auto java_serialized = std::string (bytes.data (), bytes.size ());
66+
67+ ASSERT_OK_AND_ASSIGN (auto descriptor, BlobDescriptor::Deserialize (java_serialized.data (),
68+ java_serialized.size ()));
69+ ASSERT_EQ (descriptor->Version (), (int8_t )2 );
70+ ASSERT_EQ (descriptor->Uri (), " test_uri" );
71+ ASSERT_EQ (descriptor->Offset (), 1024 );
72+ ASSERT_EQ (descriptor->Length (), 2048 );
73+
74+ PAIMON_UNIQUE_PTR<Bytes> cpp_serialized = descriptor->Serialize (pool_);
75+ ASSERT_EQ (cpp_serialized->size (), bytes.size ());
76+ ASSERT_EQ (*(cpp_serialized->data ()), *(bytes.data ()));
6377}
6478
6579TEST_F (BlobDescriptorTest, TestSerializeDeserializeWithEmptyUri) {
@@ -92,9 +106,10 @@ TEST_F(BlobDescriptorTest, TestInvalidParameters) {
92106 ASSERT_OK_AND_ASSIGN (std::unique_ptr<BlobDescriptor> descriptor,
93107 BlobDescriptor::Create (/* uri=*/ " test" , /* offset=*/ 1 , /* length=*/ 2 ));
94108 auto serialized = descriptor->Serialize (pool_);
95- (*serialized)[0 ] = ' \x02 ' ;
96- ASSERT_NOK_WITH_MSG (BlobDescriptor::Deserialize (serialized->data (), serialized->size ()),
97- " Expecting BlobDescriptor version to be 1, but found 2" );
109+ (*serialized)[0 ] = ' \x03 ' ;
110+ ASSERT_NOK_WITH_MSG (
111+ BlobDescriptor::Deserialize (serialized->data (), serialized->size ()),
112+ " Expecting BlobDescriptor version to be less than or equal to 2, but found 3" );
98113 }
99114 // Test deserialize invalid buffer size
100115 {
@@ -118,7 +133,7 @@ TEST_F(BlobDescriptorTest, TestInvalidParameters) {
118133TEST_F (BlobDescriptorTest, TestToString) {
119134 std::string debug_str = descriptor_->ToString ();
120135 ASSERT_FALSE (debug_str.empty ());
121- ASSERT_TRUE (debug_str.find (" version=1 " ) != std::string::npos);
136+ ASSERT_TRUE (debug_str.find (" version=2 " ) != std::string::npos);
122137 ASSERT_TRUE (debug_str.find (" uri='test_uri'" ) != std::string::npos);
123138 ASSERT_TRUE (debug_str.find (" offset=1024" ) != std::string::npos);
124139 ASSERT_TRUE (debug_str.find (" length=2048" ) != std::string::npos);
@@ -140,4 +155,71 @@ TEST_F(BlobDescriptorTest, TestRoundTripConsistency) {
140155 ASSERT_EQ (second_restored->Length (), 2048 );
141156}
142157
158+ TEST_F (BlobDescriptorTest, TestIsBlobDescriptorWithValidDescriptor) {
159+ // A valid v2 descriptor should be recognized
160+ auto serialized = descriptor_->Serialize (pool_);
161+ ASSERT_OK_AND_ASSIGN (bool result,
162+ BlobDescriptor::IsBlobDescriptor (serialized->data (), serialized->size ()));
163+ ASSERT_TRUE (result);
164+ }
165+
166+ TEST_F (BlobDescriptorTest, TestIsBlobDescriptorWithTooShortBuffer) {
167+ // Buffer shorter than 9 bytes should return false
168+ std::vector<char > short_buffer = {0x02 , 0x43 , 0x53 , 0x45 , 0x44 , 0x42 , 0x4F , 0x4C };
169+ ASSERT_OK_AND_ASSIGN (
170+ bool result, BlobDescriptor::IsBlobDescriptor (short_buffer.data (), short_buffer.size ()));
171+ ASSERT_FALSE (result);
172+
173+ // Empty buffer
174+ ASSERT_OK_AND_ASSIGN (bool empty_result, BlobDescriptor::IsBlobDescriptor (nullptr , 0 ));
175+ ASSERT_FALSE (empty_result);
176+ }
177+
178+ TEST_F (BlobDescriptorTest, TestIsBlobDescriptorWithFutureVersion) {
179+ // Version > CURRENT_VERSION should return false (not an error)
180+ auto serialized = descriptor_->Serialize (pool_);
181+ (*serialized)[0 ] = ' \x03 ' ; // set version to 3 (> CURRENT_VERSION)
182+ ASSERT_OK_AND_ASSIGN (bool result,
183+ BlobDescriptor::IsBlobDescriptor (serialized->data (), serialized->size ()));
184+ ASSERT_FALSE (result);
185+ }
186+
187+ TEST_F (BlobDescriptorTest, TestIsBlobDescriptorWithWrongMagic) {
188+ // Wrong magic number should return false
189+ auto serialized = descriptor_->Serialize (pool_);
190+ // Corrupt the magic bytes (bytes 1-8)
191+ (*serialized)[1 ] = ' \x00 ' ;
192+ (*serialized)[2 ] = ' \x00 ' ;
193+ ASSERT_OK_AND_ASSIGN (bool result,
194+ BlobDescriptor::IsBlobDescriptor (serialized->data (), serialized->size ()));
195+ ASSERT_FALSE (result);
196+ }
197+
198+ TEST_F (BlobDescriptorTest, TestIsBlobDescriptorWithRandomData) {
199+ // Random data that doesn't match blob descriptor format
200+ std::vector<char > random_data = {0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 , 0x09 };
201+ ASSERT_OK_AND_ASSIGN (bool result,
202+ BlobDescriptor::IsBlobDescriptor (random_data.data (), random_data.size ()));
203+ ASSERT_FALSE (result);
204+ }
205+
206+ TEST_F (BlobDescriptorTest, TestIsBlobDescriptorWithVersion1Data) {
207+ // v1 data: version=1, followed by uri_length (not magic), should return false
208+ // because reading bytes 1-8 as magic won't match MAGIC constant
209+ std::vector<char > v1_bytes = {1 , 8 , 0 , 0 , 0 , 116 , 101 , 115 , 116 , 95 , 117 , 114 , 105 , 0 , 4 ,
210+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 8 , 0 , 0 , 0 , 0 , 0 , 0 };
211+ ASSERT_OK_AND_ASSIGN (bool result,
212+ BlobDescriptor::IsBlobDescriptor (v1_bytes.data (), v1_bytes.size ()));
213+ ASSERT_FALSE (result);
214+ }
215+
216+ TEST_F (BlobDescriptorTest, TestIsBlobDescriptorWithExactly9Bytes) {
217+ // Exactly 9 bytes with valid version and magic should return true
218+ // version=2, magic=0x424C4F4244455343 in little-endian
219+ std::vector<char > minimal = {0x02 , 0x43 , 0x53 , 0x45 , 0x44 , 0x42 , 0x4F , 0x4C , 0x42 };
220+ ASSERT_OK_AND_ASSIGN (bool result,
221+ BlobDescriptor::IsBlobDescriptor (minimal.data (), minimal.size ()));
222+ ASSERT_TRUE (result);
223+ }
224+
143225} // namespace paimon::test
0 commit comments