• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifdef RELATIONAL_STORE
16 #include <gtest/gtest.h>
17 
18 #include "data_transformer.h"
19 #include "data_value.h"
20 #include "db_errno.h"
21 #include "distributeddb/result_set.h"
22 #include "distributeddb_tools_unit_test.h"
23 #include "log_print.h"
24 #include "relational_result_set_impl.h"
25 #include "relational_row_data.h"
26 #include "relational_row_data_impl.h"
27 #include "relational_row_data_set.h"
28 #include "relational_store_sqlite_ext.h"
29 #include "types_export.h"
30 
31 using namespace testing::ext;
32 using namespace DistributedDB;
33 using namespace DistributedDBUnitTest;
34 using namespace std;
35 
36 namespace {
37 string g_testDir;
38 string g_storePath;
39 string g_tableName { "data" };
40 
41 const vector<uint8_t> BLOB_VALUE { 'a', 'b', 'l', 'o', 'b', '\0', 'e', 'n', 'd' };
42 const double DOUBLE_VALUE = 1.123456;  // 1.123456 for test
43 const int64_t INT64_VALUE = 123456;  // 123456 for test
44 const std::string STR_VALUE = "I'm a string.";
45 
46 DataValue g_blobValue;
47 DataValue g_doubleValue;
48 DataValue g_int64Value;
49 DataValue g_nullValue;
50 DataValue g_strValue;
51 
InitGlobalValue()52 void InitGlobalValue()
53 {
54     Blob *blob = new (std::nothrow) Blob();
55     blob->WriteBlob(BLOB_VALUE.data(), BLOB_VALUE.size());
56     g_blobValue.Set(blob);
57 
58     g_doubleValue = DOUBLE_VALUE;
59     g_int64Value = INT64_VALUE;
60     g_strValue = STR_VALUE;
61 }
62 
CreateDBAndTable()63 void CreateDBAndTable()
64 {
65     sqlite3 *db = nullptr;
66     int errCode = sqlite3_open(g_storePath.c_str(), &db);
67     if (errCode != SQLITE_OK) {
68         LOGE("open db failed:%d", errCode);
69         sqlite3_close(db);
70         return;
71     }
72 
73     const string sql =
74         "PRAGMA journal_mode=WAL;"
75         "CREATE TABLE " + g_tableName + "(key INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, value INTEGER);";
76     char *zErrMsg = nullptr;
77     errCode = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &zErrMsg);
78     if (errCode != SQLITE_OK) {
79         LOGE("sql error:%s", zErrMsg);
80         sqlite3_free(zErrMsg);
81     }
82     sqlite3_close(db);
83 }
84 }
85 
86 class DistributedDBRelationalResultSetTest : public testing::Test {
87 public:
88     static void SetUpTestCase();
89     static void TearDownTestCase();
90     void SetUp();
91     void TearDown();
92 };
93 
SetUpTestCase(void)94 void DistributedDBRelationalResultSetTest::SetUpTestCase(void)
95 {
96     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
97     InitGlobalValue();
98     g_storePath = g_testDir + "/relationalResultSetTest.db";
99     LOGI("The test db is:%s", g_testDir.c_str());
100 }
101 
TearDownTestCase(void)102 void DistributedDBRelationalResultSetTest::TearDownTestCase(void) {}
103 
SetUp(void)104 void DistributedDBRelationalResultSetTest::SetUp(void)
105 {
106     DistributedDBToolsUnitTest::PrintTestCaseInfo();
107     CreateDBAndTable();
108 }
109 
TearDown(void)110 void DistributedDBRelationalResultSetTest::TearDown(void)
111 {
112     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
113         LOGE("rm test db files error.");
114     }
115 }
116 
117 /**
118  * @tc.name: SerializeAndDeserialize
119  * @tc.desc: Serialize and deserialize.
120  * @tc.type: FUNC
121  * @tc.require:
122  * @tc.author: lidongwei
123  */
124 HWTEST_F(DistributedDBRelationalResultSetTest, SerializeAndDeserialize, TestSize.Level1)
125 {
126     RowData data1 {g_strValue, g_int64Value, g_doubleValue, g_blobValue, g_nullValue};
127     RowData data2 {g_nullValue, g_blobValue, g_doubleValue, g_int64Value, g_strValue};  // data1.reverse()
128 
129     auto rowDataImpl1 = new (std::nothrow) RelationalRowDataImpl(std::move(data1));
130     auto rowDataImpl2 = new (std::nothrow) RelationalRowDataImpl(std::move(data2));
131 
132     /**
133      * @tc.steps: step1. Create a row data set which contains two row data;
134      * @tc.expected: OK.
135      */
136     RelationalRowDataSet rowDataSet1;
137     rowDataSet1.SetColNames({"column 1", "column 2", "column 3", "column 4", "column 5"});
138     rowDataSet1.Insert(rowDataImpl1);
139     rowDataSet1.Insert(rowDataImpl2);
140 
141     /**
142      * @tc.steps: step2. Serialize the row data set;
143      * @tc.expected: Serialize OK.
144      */
145     auto bufferLength = rowDataSet1.CalcLength();
146     vector<uint8_t> buffer1(bufferLength);
147     Parcel parcel1(buffer1.data(), buffer1.size());
148     ASSERT_EQ(rowDataSet1.Serialize(parcel1), E_OK);
149     ASSERT_FALSE(parcel1.IsError());
150 
151     /**
152      * @tc.steps: step3. Deserialize the row data set;
153      * @tc.expected: Deserialize OK.
154      */
155     vector<uint8_t> buffer2 = buffer1;
156     Parcel parcel2(buffer2.data(), buffer2.size());
157     RelationalRowDataSet rowDataSet2;
158     ASSERT_EQ(rowDataSet2.DeSerialize(parcel2), E_OK);
159     ASSERT_FALSE(parcel2.IsError());
160 
161     /**
162      * @tc.steps: step4. Compare the deserialized row data set with the original;
163      * @tc.expected: Compare OK. They are the same.
164      */
165     std::vector<std::string> colNames {"column 1", "column 2", "column 3", "column 4", "column 5"};
166     EXPECT_EQ(rowDataSet2.GetColNames(), colNames);
167 
168     // test the second row. if the second row ok, the first row is likely ok
169     StorageType type = StorageType::STORAGE_TYPE_NONE;
170     EXPECT_EQ(rowDataSet2.Get(1)->GetType(0, type), E_OK);
171     EXPECT_EQ(type, StorageType::STORAGE_TYPE_NULL);
172 
173     vector<uint8_t> desBlob;
174     EXPECT_EQ(rowDataSet2.Get(1)->Get(1, desBlob), E_OK);
175     EXPECT_EQ(desBlob, BLOB_VALUE);
176 
177     double desDoub;
178     EXPECT_EQ(rowDataSet2.Get(1)->Get(2, desDoub), E_OK);
179     EXPECT_EQ(desDoub, DOUBLE_VALUE);
180 
181     int64_t desInt64;
182     EXPECT_EQ(rowDataSet2.Get(1)->Get(3, desInt64), E_OK);
183     EXPECT_EQ(desInt64, INT64_VALUE);
184 
185     std::string desStr;
186     EXPECT_EQ(rowDataSet2.Get(1)->Get(4, desStr), E_OK);
187     EXPECT_EQ(desStr, STR_VALUE);
188 }
189 
190 /**
191  * @tc.name: Put
192  * @tc.desc: Test put into result set
193  * @tc.type: FUNC
194  * @tc.require:
195  * @tc.author: lidongwei
196  */
197 HWTEST_F(DistributedDBRelationalResultSetTest, Put, TestSize.Level1)
198 {
199     RowData data1 {g_strValue, g_int64Value, g_doubleValue, g_blobValue, g_nullValue};
200     RowData data2 {g_nullValue, g_blobValue, g_doubleValue, g_int64Value, g_strValue};  // data1.reverse()
201     RowData data3 {g_strValue, g_int64Value, g_doubleValue, g_blobValue, g_nullValue};
202 
203     auto rowDataImpl1 = new (std::nothrow) RelationalRowDataImpl(std::move(data1));
204     auto rowDataImpl2 = new (std::nothrow) RelationalRowDataImpl(std::move(data2));
205     auto rowDataImpl3 = new (std::nothrow) RelationalRowDataImpl(std::move(data3));
206     /**
207      * @tc.steps: step1. Create 2 row data set which contains 3 row data totally;
208      * @tc.expected: OK.
209      */
210     RelationalRowDataSet rowDataSet1;
211     rowDataSet1.Insert(rowDataImpl1);
212 
213     RelationalRowDataSet rowDataSet2;
214     rowDataSet2.SetRowData({ rowDataImpl2, rowDataImpl3 });
215 
216     /**
217      * @tc.steps: step2. Put row data set;
218      * @tc.expected: The count is in expect.
219      */
220     RelationalResultSetImpl resultSet;
221     resultSet.Put("", 1, std::move(rowDataSet2));
222     resultSet.Put("", 2, std::move(rowDataSet1));
223     EXPECT_EQ(resultSet.GetCount(), 3);
224 }
225 
226 /**
227  * @tc.name: EmptyResultSet
228  * @tc.desc: Empty result set.
229  * @tc.type: FUNC
230  * @tc.require:
231  * @tc.author: lidongwei
232  */
233 HWTEST_F(DistributedDBRelationalResultSetTest, EmptyResultSet, TestSize.Level1)
234 {
235     ResultSet *resultSet = new (std::nothrow) RelationalResultSetImpl;
236     ASSERT_NE(resultSet, nullptr);
237 
238     EXPECT_EQ(resultSet->GetCount(), 0);        // 0 row data
239     EXPECT_EQ(resultSet->GetPosition(), -1);    // the init position=-1
240     EXPECT_FALSE(resultSet->MoveToFirst());     // move fail. position=-1
241     EXPECT_FALSE(resultSet->MoveToLast());      // move fail. position=-1
242     EXPECT_FALSE(resultSet->MoveToNext());      // move fail. position=-1
243     EXPECT_FALSE(resultSet->MoveToPrevious());  // move fail. position=-1
244     EXPECT_FALSE(resultSet->Move(1));           // move fail. position=-1
245     EXPECT_FALSE(resultSet->MoveToPosition(0)); // move fail. position=1
246     EXPECT_FALSE(resultSet->IsFirst());         // position=1, not the first one
247     EXPECT_FALSE(resultSet->IsLast());          // position=1, not the last one
248     EXPECT_TRUE(resultSet->IsBeforeFirst());    // empty result set, always true
249     EXPECT_TRUE(resultSet->IsAfterLast());      // empty result set, always true
250     EXPECT_FALSE(resultSet->IsClosed());        // not closed
251     Entry entry;
252     EXPECT_EQ(resultSet->GetEntry(entry), DBStatus::NOT_SUPPORT);   // for relational result set, not support get entry.
253     ResultSet::ColumnType columnType;
254     EXPECT_EQ(resultSet->GetColumnType(0, columnType), DBStatus::NOT_FOUND);       // the invalid position
255     int columnIndex = -1;
256     EXPECT_EQ(resultSet->GetColumnIndex("", columnIndex), DBStatus::NOT_FOUND);     // empty result set
257     int64_t value = 0;
258     EXPECT_EQ(resultSet->Get(0, value), DBStatus::NOT_FOUND);  // the invalid position
259     std::map<std::string, VariantData> data;
260     EXPECT_EQ(resultSet->GetRow(data), DBStatus::NOT_FOUND);   // the invalid position
261     delete resultSet;
262 }
263 
264 /**
265  * @tc.name: NormalResultSet
266  * @tc.desc: Normal result set.
267  * @tc.type: FUNC
268  * @tc.require:
269  * @tc.author: lidongwei
270  */
271 HWTEST_F(DistributedDBRelationalResultSetTest, NormalResultSet, TestSize.Level1)
272 {
273     auto *resultSet = new (std::nothrow) RelationalResultSetImpl;
274     ASSERT_NE(resultSet, nullptr);
275 
276     /**
277      * @tc.steps: step1. Create a result set which contains two row data;
278      * @tc.expected: OK.
279      */
280     RelationalRowDataSet rowDataSet1;
281     EXPECT_EQ(rowDataSet1.Insert(new (std::nothrow) RelationalRowDataImpl({g_strValue, g_int64Value})), E_OK);
282     RelationalRowDataSet rowDataSet2;
283     rowDataSet2.SetColNames({"column 1", "column 2"});
284     EXPECT_EQ(rowDataSet2.Insert(new (std::nothrow) RelationalRowDataImpl({g_nullValue, g_blobValue})), E_OK);
285 
286     EXPECT_EQ(resultSet->Put("", 2, std::move(rowDataSet2)), E_OK);  // the second one
287     EXPECT_EQ(resultSet->Put("", 1, std::move(rowDataSet1)), E_OK);  // the first one
288 
289     /**
290      * @tc.steps: step2. Check the result set;
291      * @tc.expected: All the interface is running in expect.
292      */
293     EXPECT_EQ(resultSet->GetCount(), 2);        // two row data
294     EXPECT_EQ(resultSet->GetPosition(), -1);    // the init position=-1
295     EXPECT_TRUE(resultSet->MoveToFirst());      // move ok. position=0
296     EXPECT_TRUE(resultSet->MoveToLast());       // move ok. position=1
297     EXPECT_FALSE(resultSet->MoveToNext());      // move fail. position=2
298     EXPECT_TRUE(resultSet->MoveToPrevious());   // move ok. position=1
299     EXPECT_FALSE(resultSet->Move(1));           // move fail. position=2
300     EXPECT_TRUE(resultSet->MoveToPosition(0));  // move ok. position=0
301     EXPECT_TRUE(resultSet->IsFirst());          // position=0, the first one
302     EXPECT_FALSE(resultSet->IsLast());          // position=0, not the last one
303     EXPECT_FALSE(resultSet->IsBeforeFirst());   // position=0, not before the first
304     EXPECT_FALSE(resultSet->IsAfterLast());     // position=0, not after the last
305     EXPECT_FALSE(resultSet->IsClosed());        // not closed
306 
307     Entry entry;
308     EXPECT_EQ(resultSet->GetEntry(entry), DBStatus::NOT_SUPPORT);   // for relational result set, not support get entry.
309 
310     ResultSet::ColumnType columnType;
311     EXPECT_EQ(resultSet->GetColumnType(0, columnType), DBStatus::OK);
312     EXPECT_EQ(columnType, ResultSet::ColumnType::STRING);
313 
314     std::vector<std::string> expectCols { "column 1", "column 2" };
315     std::vector<std::string> colNames;
316     resultSet->GetColumnNames(colNames);
317     EXPECT_EQ(colNames, expectCols);
318 
319     int columnIndex = -1;
320     EXPECT_EQ(resultSet->GetColumnIndex("", columnIndex), DBStatus::NONEXISTENT);  // the invalid column name
321     EXPECT_EQ(resultSet->GetColumnIndex("column 1", columnIndex), DBStatus::OK);
322     EXPECT_EQ(columnIndex, 0);
323 
324     int64_t value = 0;
325     EXPECT_EQ(resultSet->Get(1, value), DBStatus::OK);
326     EXPECT_EQ(value, INT64_VALUE);
327 
328     std::map<std::string, VariantData> data;
329     EXPECT_EQ(resultSet->GetRow(data), DBStatus::OK);
330     EXPECT_EQ(std::get<std::string>(data["column 1"]), STR_VALUE);
331     EXPECT_EQ(std::get<int64_t>(data["column 2"]), INT64_VALUE);
332     delete resultSet;
333 }
334 
335 
336 HWTEST_F(DistributedDBRelationalResultSetTest, Test001, TestSize.Level1)
337 {
338     auto *resultSet = new (std::nothrow) RelationalResultSetImpl;
339     ASSERT_NE(resultSet, nullptr);
340 
341     /**
342      * @tc.steps: step1. Create a result set which contains two row data;
343      * @tc.expected: OK.
344      */
345     RelationalRowDataSet rowDataSet1;
346     RowData rowData = {g_blobValue, g_doubleValue, g_int64Value, g_nullValue, g_strValue};
347     EXPECT_EQ(rowDataSet1.Insert(new (std::nothrow) RelationalRowDataImpl(std::move(rowData))), E_OK);
348     EXPECT_EQ(resultSet->Put("", 1, std::move(rowDataSet1)), E_OK);  // the first one
349 
350     EXPECT_EQ(resultSet->MoveToFirst(), true);
351     ResultSet::ColumnType columnType;
352     EXPECT_EQ(resultSet->GetColumnType(0, columnType), DBStatus::OK);
353     EXPECT_EQ(columnType, ResultSet::ColumnType::BLOB);
354     EXPECT_EQ(resultSet->GetColumnType(1, columnType), DBStatus::OK);
355     EXPECT_EQ(columnType, ResultSet::ColumnType::DOUBLE);
356     EXPECT_EQ(resultSet->GetColumnType(2, columnType), DBStatus::OK);
357     EXPECT_EQ(columnType, ResultSet::ColumnType::INT64);
358     EXPECT_EQ(resultSet->GetColumnType(3, columnType), DBStatus::OK);
359     EXPECT_EQ(columnType, ResultSet::ColumnType::NULL_VALUE);
360     EXPECT_EQ(resultSet->GetColumnType(4, columnType), DBStatus::OK);
361     EXPECT_EQ(columnType, ResultSet::ColumnType::STRING);
362 
363     delete resultSet;
364 }
365 
366 /**
367  * @tc.name: ResultSetTest001
368  * @tc.desc: Test get rowData and close
369  * @tc.type: FUNC
370  * @tc.require:
371  * @tc.author: chenchaohao
372  */
373 HWTEST_F(DistributedDBRelationalResultSetTest, ResultSetTest001, TestSize.Level0)
374 {
375     auto *resultSet = new (std::nothrow) RelationalResultSetImpl;
376     ASSERT_NE(resultSet, nullptr);
377 
378     /**
379      * @tc.steps: step1. Create a result set which contains five row data;
380      * @tc.expected: OK.
381      */
382     RelationalRowDataSet rowDataSet1;
383     RowData rowData = {g_blobValue, g_doubleValue, g_int64Value, g_nullValue, g_strValue};
384     rowDataSet1.SetColNames({"column 1", "column 2", "column 3", "column 4", "column 5"});
385     EXPECT_EQ(rowDataSet1.Insert(new (std::nothrow) RelationalRowDataImpl(std::move(rowData))), E_OK);
386     EXPECT_EQ(resultSet->Put("", 1, std::move(rowDataSet1)), E_OK);  // the first one
387     EXPECT_EQ(resultSet->MoveToFirst(), true);
388 
389     /**
390      * @tc.steps: step2. Check data
391      * @tc.expected: OK.
392      */
393     std::map<std::string, VariantData> data;
394     EXPECT_EQ(resultSet->GetRow(data), DBStatus::OK);
395     EXPECT_EQ(std::get<std::vector<uint8_t>>(data["column 1"]), BLOB_VALUE);
396     EXPECT_EQ(std::get<double>(data["column 2"]), DOUBLE_VALUE);
397     EXPECT_EQ(std::get<int64_t>(data["column 3"]), INT64_VALUE);
398     EXPECT_EQ(std::get<std::string>(data["column 5"]), STR_VALUE);
399 
400     /**
401      * @tc.steps: step3. Check close twice
402      * @tc.expected: OK.
403      */
404     resultSet->Close();
405     EXPECT_EQ(resultSet->GetCount(), 0);
406     resultSet->Close();
407     EXPECT_EQ(resultSet->GetCount(), 0);
408 
409     delete resultSet;
410 }
411 
412 /**
413  * @tc.name: ResultSetTest002
414  * @tc.desc: Test get data in null resultSet
415  * @tc.type: FUNC
416  * @tc.require:
417  * @tc.author: chenchaohao
418  */
419 HWTEST_F(DistributedDBRelationalResultSetTest, ResultSetTest002, TestSize.Level0)
420 {
421     auto *resultSet = new (std::nothrow) RelationalResultSetImpl;
422     ASSERT_NE(resultSet, nullptr);
423 
424     /**
425      * @tc.steps: step1. check whether status is not found when get null resultSet
426      * @tc.expected: OK.
427      */
428     std::vector<uint8_t> blob;
429     EXPECT_EQ(resultSet->Get(0, blob), DBStatus::NOT_FOUND);
430     std::string strValue = "";
431     EXPECT_EQ(resultSet->Get(0, strValue), DBStatus::NOT_FOUND);
432     int64_t intValue = 0;
433     EXPECT_EQ(resultSet->Get(0, intValue), DBStatus::NOT_FOUND);
434     double doubleValue = 0.0;
435     EXPECT_EQ(resultSet->Get(0, doubleValue), DBStatus::NOT_FOUND);
436     bool isNull = true;
437     EXPECT_EQ(resultSet->IsColumnNull(0, isNull), DBStatus::NOT_FOUND);
438 
439     delete resultSet;
440 }
441 
442 /**
443  * @tc.name: SerializeTest001
444  * @tc.desc: Test Serialize func
445  * @tc.type: FUNC
446  * @tc.require:
447  * @tc.author: tiansimiao
448  */
449 HWTEST_F(DistributedDBRelationalResultSetTest, SerializeTest001, TestSize.Level0)
450 {
451     DataValue dataValue;
452     dataValue.ResetValue();
453     RowData rowData;
454     rowData.push_back(dataValue);
455     RelationalRowDataImpl row(std::move(rowData));
456     Parcel parcel(nullptr, 0);
457     EXPECT_EQ(row.Serialize(parcel), -E_PARSE_FAIL);
458 }
459 
460 /**
461  * @tc.name: SerializeTest002
462  * @tc.desc: Test Serialize func
463  * @tc.type: FUNC
464  * @tc.require:
465  * @tc.author: tiansimiao
466  */
467 HWTEST_F(DistributedDBRelationalResultSetTest, SerializeTest002, TestSize.Level0)
468 {
469     std::string largeString(DBConstant::MAX_SET_VALUE_SIZE + 1, 'a');
470     DataValue dataValue;
471     dataValue.SetText(largeString);
472     RowData rowData;
473     rowData.push_back(dataValue);
474     RelationalRowDataImpl row(std::move(rowData));
475     uint32_t parcelSize = DBConstant::MAX_SET_VALUE_SIZE;
476     uint8_t* buffer = new(std::nothrow) uint8_t[parcelSize];
477     ASSERT_NE(buffer, nullptr);
478     Parcel parcel(buffer, parcelSize);
479     EXPECT_EQ(row.Serialize(parcel), -E_PARSE_FAIL);
480     delete[] buffer;
481 }
482 
483 /**
484  * @tc.name: DeSerializeTest001
485  * @tc.desc: Test DeSerialize func
486  * @tc.type: FUNC
487  * @tc.require:
488  * @tc.author: tiansimiao
489  */
490 HWTEST_F(DistributedDBRelationalResultSetTest, DeSerializeTest001, TestSize.Level0)
491 {
492     uint8_t buffer[100] = {0};
493     Parcel parcelA(buffer, 100);
494     EXPECT_FALSE(parcelA.IsError());
495     uint32_t size = 1;
496     (void)parcelA.WriteUInt32(size);
497     EXPECT_FALSE(parcelA.IsError());
498     uint32_t type = static_cast<uint32_t>(StorageType::STORAGE_TYPE_NONE);
499     (void)parcelA.WriteUInt32(type);
500     EXPECT_FALSE(parcelA.IsError());
501     RelationalRowDataImpl row;
502     Parcel parcelB(buffer, 100);
503     EXPECT_EQ(row.DeSerialize(parcelB), -E_PARSE_FAIL);
504 }
505 
506 /**
507  * @tc.name: DeSerializeTest002
508  * @tc.desc: Test DeSerialize func
509  * @tc.type: FUNC
510  * @tc.require:
511  * @tc.author: tiansimiao
512  */
513 HWTEST_F(DistributedDBRelationalResultSetTest, DeSerializeTest002, TestSize.Level0)
514 {
515     /**
516      *  @tc.steps: step1. Set totalLen as the critical condition.
517      *  satisfies the write condition (parcelLen is less than totalLen), but does not meet the byte alignment condition
518      *  parcelLen is 12 after writing, after byte alignment it becomes 16, which is greater than totalLen.
519      */
520     uint8_t buffer[12] = {0}; // Set totalLen as 12
521     Parcel parcelA(buffer, 12);
522     uint32_t size = 1;
523     (void)parcelA.WriteUInt32(size);
524     EXPECT_FALSE(parcelA.IsError());
525     uint32_t type = static_cast<uint32_t>(StorageType::STORAGE_TYPE_NULL);
526     (void)parcelA.WriteUInt32(type);
527     EXPECT_FALSE(parcelA.IsError());
528     RelationalRowDataImpl row;
529     Parcel parcelB(buffer, 12);
530     EXPECT_EQ(row.DeSerialize(parcelB), -E_PARSE_FAIL);
531 }
532 
533 /**
534  * @tc.name: GetTypeTest001
535  * @tc.desc: Test GetType func
536  * @tc.type: FUNC
537  * @tc.require:
538  * @tc.author: tiansimiao
539  */
540 HWTEST_F(DistributedDBRelationalResultSetTest, GetTypeTest001, TestSize.Level0)
541 {
542     DistributedDB::RowData data;
543     DistributedDB::DataValue value;
544     value.SetText("test");
545     data.emplace_back(std::move(value));
546     DistributedDB::RelationalRowDataImpl row(std::move(data));
547     DistributedDB::StorageType type;
548     EXPECT_EQ(row.GetType(-1, type), -E_NONEXISTENT);
549     EXPECT_EQ(row.GetType(3, type), -E_NONEXISTENT);
550 }
551 
552 /**
553  * @tc.name: GetTest001
554  * @tc.desc: Test Get func
555  * @tc.type: FUNC
556  * @tc.require:
557  * @tc.author: tiansimiao
558  */
559 HWTEST_F(DistributedDBRelationalResultSetTest, GetTest001, TestSize.Level0)
560 {
561     DistributedDB::RowData data;
562     DistributedDB::DataValue value;
563     value.SetText("test");
564     data.emplace_back(std::move(value));
565     DistributedDB::RelationalRowDataImpl row(std::move(data));
566     int64_t intValue;
567     double doubleValue;
568     std::string stringValueResult;
569     std::vector<uint8_t> blobValueResult;
570     EXPECT_EQ(row.Get(-1, intValue), -E_NONEXISTENT);
571     EXPECT_EQ(row.Get(1, intValue), -E_NONEXISTENT);
572     EXPECT_EQ(row.Get(-1, doubleValue), -E_NONEXISTENT);
573     EXPECT_EQ(row.Get(1, doubleValue), -E_NONEXISTENT);
574     EXPECT_EQ(row.Get(-1, stringValueResult), -E_NONEXISTENT);
575     EXPECT_EQ(row.Get(1, stringValueResult), -E_NONEXISTENT);
576     EXPECT_EQ(row.Get(-1, blobValueResult), -E_NONEXISTENT);
577     EXPECT_EQ(row.Get(1, blobValueResult), -E_NONEXISTENT);
578 }
579 
580 /**
581  * @tc.name: GetTest002
582  * @tc.desc: Test Get func
583  * @tc.type: FUNC
584  * @tc.require:
585  * @tc.author: tiansimiao
586  */
587 HWTEST_F(DistributedDBRelationalResultSetTest, GetTest002, TestSize.Level0)
588 {
589     DistributedDB::RowData data;
590     DistributedDB::DataValue value;
591     value.SetText("test");
592     data.emplace_back(std::move(value));
593     DistributedDB::RelationalRowDataImpl row(std::move(data));
594     int64_t intValue;
595     EXPECT_EQ(row.Get(0, intValue), -E_TYPE_MISMATCH);
596     double doubleValue;
597     EXPECT_EQ(row.Get(0, doubleValue), -E_TYPE_MISMATCH);
598 }
599 
600 /**
601  * @tc.name: GetTest003
602  * @tc.desc: Test Get func
603  * @tc.type: FUNC
604  * @tc.require:
605  * @tc.author: tiansimiao
606  */
607 HWTEST_F(DistributedDBRelationalResultSetTest, GetTest003, TestSize.Level0)
608 {
609     DistributedDB::RowData data;
610     DistributedDB::DataValue value;
611     int64_t intValue = 10;
612     value.GetInt64(intValue);
613     data.emplace_back(std::move(value));
614     DistributedDB::RelationalRowDataImpl row(std::move(data));
615     std::string stringValueResult;
616     EXPECT_EQ(row.Get(0, stringValueResult), -E_TYPE_MISMATCH);
617     std::vector<uint8_t> blobValueResult;
618     EXPECT_EQ(row.Get(0, blobValueResult), -E_TYPE_MISMATCH);
619 }
620 
621 /**
622  * @tc.name: BinlogSupportTest001
623  * @tc.desc: Test binlog support API return values as expected
624  * @tc.type: FUNC
625  * @tc.require:
626  * @tc.author: hongyangliu
627  */
628 HWTEST_F(DistributedDBRelationalResultSetTest, BinlogSupportTest001, TestSize.Level0)
629 {
630     EXPECT_EQ(sqlite3_is_support_binlog(nullptr), SQLITE_ERROR);
631     EXPECT_EQ(sqlite3_is_support_binlog(""), sqlite3_is_support_binlog(" "));
632 }
633 
634 /**
635  * @tc.name: CompressSupportTest001
636  * @tc.desc: Test sqlite open with different vfs option return values as expected
637  * @tc.type: FUNC
638  * @tc.require:
639  * @tc.author: hongyangliu
640  */
641 HWTEST_F(DistributedDBRelationalResultSetTest, CompressSupportTest001, TestSize.Level0)
642 {
643     sqlite3 *db = nullptr;
644     uint32_t openOption = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX;
645     /**
646      * @tc.steps: step1. sqlite open with both filepath and vfs as null
647      * @tc.expected: no crash
648      */
649     ASSERT_NO_FATAL_FAILURE(sqlite3_open_v2(nullptr, &db, openOption, nullptr));
650     sqlite3_close_v2(db);
651     db = nullptr;
652     /**
653      * @tc.steps: step2. sqlite open with null filepath and random vfs
654      * @tc.expected: no crash
655      */
656     ASSERT_NO_FATAL_FAILURE(sqlite3_open_v2(nullptr, &db, openOption, "non-exist"));
657     sqlite3_close_v2(db);
658     db = nullptr;
659     /**
660      * @tc.steps: step3. sqlite open with null filepath and compress vfs
661      * @tc.expected: no crash
662      */
663     ASSERT_NO_FATAL_FAILURE(sqlite3_open_v2(nullptr, &db, openOption, "compressvfs"));
664     sqlite3_close_v2(db);
665     db = nullptr;
666     /**
667      * @tc.steps: step4. sqlite open with a regular file with no vfs
668      * @tc.expected: open ok
669      */
670     EXPECT_EQ(sqlite3_open_v2(g_storePath.c_str(), &db, openOption, nullptr), SQLITE_OK);
671     sqlite3_close_v2(db);
672     db = nullptr;
673     /**
674      * @tc.steps: step5. sqlite open with a non-whitelist file using compress vfs
675      * @tc.expected: open ok
676      */
677     std::string nonWhiteDb = g_testDir + "/nonWhiteList.db";
678     EXPECT_EQ(sqlite3_open_v2(nonWhiteDb.c_str(), &db, openOption, "compressvfs"), SQLITE_OK);
679     sqlite3_close_v2(db);
680     db = nullptr;
681     /**
682      * @tc.steps: step6. sqlite open with a whitelist file using compress vfs
683      * @tc.expected: no crash
684      */
685     std::string whitelistDb = g_testDir + "/test.db";
686     ASSERT_NO_FATAL_FAILURE(sqlite3_open_v2(whitelistDb.c_str(), &db, openOption, "compressvfs"));
687     sqlite3_close_v2(db);
688     db = nullptr;
689 }
690 #endif
691