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 
16 #ifndef OMIT_MULTI_VER
17 #include <gtest/gtest.h>
18 
19 #include "sqlite_import.h"
20 #include "db_common.h"
21 #include "db_constant.h"
22 #include "distributeddb_data_generate_unit_test.h"
23 #include "distributeddb_tools_unit_test.h"
24 #include "kvdb_manager.h"
25 #include "multi_ver_natural_store_transfer_data.h"
26 #include "sqlite_local_kvdb_connection.h"
27 
28 using namespace testing::ext;
29 using namespace DistributedDB;
30 using namespace DistributedDBUnitTest;
31 using namespace std;
32 
33 namespace {
34     string g_testDir;
35     SQLiteLocalKvDBConnection *g_connection = nullptr;
36     CipherPassword g_passwd;
37     CipherPassword g_passwd2;
38     std::vector<uint8_t> g_passwdVect = {'p', 's', 'd', '1'};
39     std::vector<uint8_t> g_passwdVect2 = {'p', 's', 'd', '2'};
40     const std::string SHA256_ALGO_SQL = "PRAGMA codec_hmac_algo=SHA256";
41     const std::string SHA1_ALGO_SQL = "PRAGMA codec_hmac_algo=SHA1";
42     const std::string USER_VERSION_SQL = "PRAGMA user_version;";
43     const std::string SET_USER_VERSION_SQL = "PRAGMA user_version=100;";
44     const std::string SHA1_ALGO_ATTACH_SQL = "PRAGMA cipher_default_attach_hmac_algo=SHA1;";
45     const std::string SHA256_ALGO_ATTACH_SQL = "PRAGMA cipher_default_attach_hmac_algo=SHA256;";
46 
47     std::string g_createTableSql1 = R""(create table student_1 (
48             id      INTEGER PRIMARY KEY,
49             name    STRING,
50             level   INTGER,
51             score   INTGER
52         ))"";
53     std::string g_createTableSql2 = R""(create table student_2 (
54             id      INTEGER,
55             age     STRING
56         ))"";
57     std::string g_inerstDataSql1 = "insert into student_1 (id, name, level, score) values (1001, 'xue', 2, 95);";
58     std::string g_inerstDataSql2 = "insert into student_1 (id, name, level, score) values (1002, 'xue', 2, 95);";
59     std::string g_inerstDataSql3 = "insert into student_2 (id, age) values (1001, 11);";
60     std::string g_inerstDataSql4 = "insert into student_2 (id, age) values (1002, 12);";
61     std::string g_deleteDataSql = "delete from student_1 where id='1001';";
62     std::string g_createViewSql = "create view studentView as select * from student_1;";
63     std::string g_createIndexSql = "create index in_id on student_2(id);";
64     std::string g_deleteViewSql = "drop view studentView;";
65     std::string g_dropTableSql1 = "drop table student_2;";
66     std::string g_dropTableSql2 = "drop table student_1;";
67     std::string g_dropIndex = "drop index in_id;";
68     std::string g_dbFile;
69     std::string g_tableName;
70     int g_callbackTimes = 0;
DropCallback(sqlite3 * db,const char * tableName,const char * dbName)71     void DropCallback(sqlite3 *db, const char *tableName, const char *dbName)
72     {
73         auto filepath = sqlite3_db_filename(static_cast<sqlite3 *>(db), dbName);
74         if (filepath == nullptr) {
75             return;
76         }
77         EXPECT_EQ(g_dbFile, std::string(filepath));
78         EXPECT_EQ(g_tableName, std::string(tableName));
79         g_callbackTimes++;
80     }
81 }
82 
83 class DistributedDBStorageDataOperationTest : public testing::Test {
84 public:
85     static void SetUpTestCase(void);
86     static void TearDownTestCase(void);
87     void SetUp();
88     void TearDown();
89 };
90 
SetUpTestCase(void)91 void DistributedDBStorageDataOperationTest::SetUpTestCase(void)
92 {
93     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
94     g_passwd.SetValue(g_passwdVect.data(), g_passwdVect.size());
95     g_passwd2.SetValue(g_passwdVect2.data(), g_passwdVect2.size());
96 }
97 
TearDownTestCase(void)98 void DistributedDBStorageDataOperationTest::TearDownTestCase(void)
99 {
100     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
101         LOGE("rm test db files error!");
102     }
103 }
104 
SetUp(void)105 void DistributedDBStorageDataOperationTest::SetUp(void)
106 {
107     DistributedDBToolsUnitTest::PrintTestCaseInfo();
108     KvDBProperties properties;
109     properties.SetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, true);
110     properties.SetIntProp(KvDBProperties::DATABASE_TYPE, KvDBProperties::LOCAL_TYPE_SQLITE);
111     properties.SetStringProp(KvDBProperties::DATA_DIR, g_testDir);
112     properties.SetStringProp(KvDBProperties::STORE_ID, "test");
113     properties.SetStringProp(KvDBProperties::IDENTIFIER_DIR, "test");
114 
115     int errCode = E_OK;
116     g_connection = static_cast<SQLiteLocalKvDBConnection *>(KvDBManager::GetDatabaseConnection(properties, errCode));
117     EXPECT_EQ(errCode, E_OK);
118 }
119 
TearDown(void)120 void DistributedDBStorageDataOperationTest::TearDown(void)
121 {
122     if (g_connection != nullptr) {
123         g_connection->Close();
124         g_connection = nullptr;
125     }
126     return;
127 }
128 
129 /**
130   * @tc.name: Insert001
131   * @tc.desc: Insert a record into a distributed db
132   * @tc.type: FUNC
133   * @tc.require: AR000CQDV8 AR000CQDVB
134   * @tc.author: huangnaigu
135   */
136 HWTEST_F(DistributedDBStorageDataOperationTest, Insert001, TestSize.Level1)
137 {
138     EXPECT_NE(g_connection, nullptr);
139     if (g_connection == nullptr) {
140         return;
141     }
142 
143     Key key(3, 'w');
144     Value value;
145     value.assign(8, 87);
146     IOption option;
147 
148     /**
149      * @tc.steps:step1. Put a kv into database
150      * @tc.expected: step1. Return OK.
151      */
152     int errCode = g_connection->Put(option, key, value);
153     EXPECT_EQ(errCode, E_OK);
154 
155     Value valueRead;
156     valueRead.clear();
157 
158     /**
159      * @tc.steps:step2. Get k from database
160      * @tc.expected: step2. Return OK. The size is right.
161      */
162     errCode = g_connection->Get(option, key, valueRead);
163     EXPECT_EQ(errCode, E_OK);
164     EXPECT_EQ(valueRead.size(), 8UL);
165 
166     for (auto iter = valueRead.begin(); iter != valueRead.end(); iter++) {
167         EXPECT_EQ(*iter, 87);
168     }
169 }
170 
171 /**
172   * @tc.name: InsertBatch001
173   * @tc.desc: Insert some records into a distributed db
174   * @tc.type: FUNC
175   * @tc.require: AR000CQDV9 AR000CQDVE
176   * @tc.author: huangnaigu
177   */
178 HWTEST_F(DistributedDBStorageDataOperationTest, InsertBatch001, TestSize.Level1)
179 {
180     EXPECT_NE(g_connection, nullptr);
181     if (g_connection == nullptr) {
182         return;
183     }
184 
185     Key key(3, 'w');
186     Value value;
187     value.assign(8, 87);
188     IOption option;
189 
190     Entry entry;
191     entry.key = key;
192     entry.value = value;
193 
194     std::vector<Entry> entries;
195     entries.push_back(entry);
196 
197     entry.key.push_back('q');
198     entry.value.assign(6, 76);
199     entries.push_back(entry);
200 
201     /**
202      * @tc.steps:step1. PutBatch series kv into database
203      * @tc.expected: step1. Return OK.
204      */
205     int errCode = g_connection->PutBatch(option, entries);
206     EXPECT_EQ(errCode, E_OK);
207 
208     std::vector<Entry> entriesRead;
209     Key keyRead(3, 'w');
210     entriesRead.clear();
211 
212     /**
213      * @tc.steps:step2. Get k from database by GetEntries
214      * @tc.expected: step2. Return OK. The size is right.
215      */
216     errCode = g_connection->GetEntries(option, keyRead, entriesRead);
217     EXPECT_EQ(errCode, E_OK);
218     EXPECT_EQ(entriesRead.size(), 2UL);
219 
220     if (entriesRead.size() > 2) {
221         EXPECT_EQ(entriesRead[0].value.size(), 8UL);
222         EXPECT_EQ(entriesRead[1].value.size(), 6UL);
223     }
224 }
225 
226 /**
227   * @tc.name: Clear001
228   * @tc.desc: Clear some records from a distributed db
229   * @tc.type: FUNC
230   * @tc.require: AR000BVTO6 AR000CQDVA
231   * @tc.author: huangnaigu
232   */
233 HWTEST_F(DistributedDBStorageDataOperationTest, Clear001, TestSize.Level1)
234 {
235     EXPECT_NE(g_connection, nullptr);
236     if (g_connection == nullptr) {
237         return;
238     }
239 
240     Key key(3, 'w');
241     Value value;
242     value.assign(8, 87);
243     IOption option;
244 
245     Entry entry;
246     entry.key = key;
247     entry.value = value;
248 
249     std::vector<Entry> entries;
250     entries.push_back(entry);
251 
252     entry.key.push_back('q');
253     entry.value.assign(6, 76);
254     entries.push_back(entry);
255 
256     /**
257      * @tc.steps:step1. PutBatch series kv into database
258      * @tc.expected: step1. Return OK.
259      */
260     int errCode = g_connection->PutBatch(option, entries);
261     EXPECT_EQ(errCode, E_OK);
262 
263     std::vector<Entry> entriesRead;
264     Key keyRead(3, 'w');
265     entriesRead.clear();
266 
267     /**
268      * @tc.steps:step2. Get k from database by GetEntries
269      * @tc.expected: step2. Return OK. The size is right.
270      */
271     errCode = g_connection->GetEntries(option, keyRead, entriesRead);
272     EXPECT_EQ(errCode, E_OK);
273     EXPECT_EQ(entriesRead.size(), 2UL);
274 
275     if (entriesRead.size() > 2) {
276         EXPECT_EQ(entriesRead[0].value.size(), 8UL);
277         EXPECT_EQ(entriesRead[1].value.size(), 6UL);
278     }
279 
280     /**
281      * @tc.steps:step3. Clear all data from database
282      * @tc.expected: step3. Return OK.
283      */
284     errCode = g_connection->Clear(option);
285     EXPECT_EQ(errCode, E_OK);
286 
287     /**
288      * @tc.steps:step2. Get k from database by GetEntries
289      * @tc.expected: step2. Return E_NOT_FOUND. The result size is 0.
290      */
291     entriesRead.clear();
292     errCode = g_connection->GetEntries(option, keyRead, entriesRead);
293     EXPECT_EQ(errCode, -E_NOT_FOUND);
294     EXPECT_EQ(entriesRead.size(), 0UL);
295 }
296 
297 /**
298   * @tc.name: Delete001
299   * @tc.desc: Delete a record from a distributed db
300   * @tc.type: FUNC
301   * @tc.require: AR000CQDVF AR000CQDVB
302   * @tc.author: huangnaigu
303   */
304 HWTEST_F(DistributedDBStorageDataOperationTest, Delete001, TestSize.Level1)
305 {
306     EXPECT_NE(g_connection, nullptr);
307     if (g_connection == nullptr) {
308         return;
309     }
310 
311     Key key(3, 'w');
312     Value value;
313     value.assign(8, 87);
314     IOption option;
315 
316     Entry entry;
317     entry.key = key;
318     entry.value = value;
319 
320     std::vector<Entry> entries;
321     entries.push_back(entry);
322 
323     entry.key.push_back('q');
324     entry.value.assign(6, 76);
325     entries.push_back(entry);
326 
327     /**
328      * @tc.steps:step1. PutBatch series kv into database
329      * @tc.expected: step1. Return OK.
330      */
331     int errCode = g_connection->PutBatch(option, entries);
332     EXPECT_EQ(errCode, E_OK);
333 
334     /**
335      * @tc.steps:step2. Get k from database by GetEntries
336      * @tc.expected: step2. Return OK. The size is right.
337      */
338     Value valueRead;
339     errCode = g_connection->Get(option, entry.key, valueRead);
340     EXPECT_EQ(errCode, E_OK);
341     EXPECT_EQ(valueRead.size(), 6UL);
342 
343     std::vector<Entry> entriesRead;
344     Key keyRead(3, 'w');
345     entriesRead.clear();
346 
347     /**
348      * @tc.steps:step3. Get k from database by GetEntries
349      * @tc.expected: step3. Return E_OK. The result size is right.
350      */
351     errCode = g_connection->GetEntries(option, keyRead, entriesRead);
352     EXPECT_EQ(errCode, E_OK);
353     EXPECT_EQ(entriesRead.size(), 2UL);
354 
355     if (entriesRead.size() > 2) {
356         EXPECT_EQ(entriesRead[0].value.size(), 8UL);
357         EXPECT_EQ(entriesRead[1].value.size(), 6UL);
358     }
359 
360     /**
361      * @tc.steps:step3. Delete k from database
362      * @tc.expected: step3. Return E_OK.
363      */
364     errCode = g_connection->Delete(option, key);
365     EXPECT_EQ(errCode, E_OK);
366 
367     entriesRead.clear();
368 
369     /**
370      * @tc.steps:step3. Get k from database by GetEntries
371      * @tc.expected: step3. Return E_OK. The result size is reduction 1.
372      */
373     errCode = g_connection->GetEntries(option, keyRead, entriesRead);
374     EXPECT_EQ(errCode, E_OK);
375     EXPECT_EQ(entriesRead.size(), 1UL);
376 }
377 
378 /**
379   * @tc.name: DeleteBatch001
380   * @tc.desc: Delete some records from a distributed db
381   * @tc.type: FUNC
382   * @tc.require: AR000CQDVG AR000CQDVB
383   * @tc.author: huangnaigu
384   */
385 HWTEST_F(DistributedDBStorageDataOperationTest, DeleteBatch001, TestSize.Level1)
386 {
387     EXPECT_NE(g_connection, nullptr);
388     if (g_connection == nullptr) {
389         return;
390     }
391 
392     Key key(3, 'w');
393     Value value;
394     value.assign(8, 87);
395     IOption option;
396 
397     Entry entry;
398     entry.key = key;
399     entry.value = value;
400 
401     std::vector<Entry> entries;
402     entries.push_back(entry);
403 
404     entry.key.push_back('q');
405     entry.value.assign(6, 76);
406     entries.push_back(entry);
407 
408     /**
409      * @tc.steps:step1. PutBatch series kv into database
410      * @tc.expected: step1. Return OK.
411      */
412     int errCode = g_connection->PutBatch(option, entries);
413     EXPECT_EQ(errCode, E_OK);
414 
415     std::vector<Entry> entriesRead;
416     Key keyRead(3, 'w');
417     entriesRead.clear();
418 
419     /**
420      * @tc.steps:step2. Get k from database by GetEntries
421      * @tc.expected: step2. Return E_OK. The result size is right.
422      */
423     errCode = g_connection->GetEntries(option, keyRead, entriesRead);
424     EXPECT_EQ(errCode, E_OK);
425     EXPECT_EQ(entriesRead.size(), 2UL);
426 
427     if (entriesRead.size() > 2) {
428         EXPECT_EQ(entriesRead[0].value.size(), 8UL);
429         EXPECT_EQ(entriesRead[1].value.size(), 6UL);
430     }
431 
432     std::vector<Key> keys;
433     Key keyTmp = key;
434 
435     keys.push_back(keyTmp);
436     keyTmp.push_back('q');
437     keys.push_back(keyTmp);
438 
439     /**
440      * @tc.steps:step3. DeleteBatch keys from database by DeleteBatch
441      * @tc.expected: step3. Return E_OK.
442      */
443     errCode = g_connection->DeleteBatch(option, keys);
444     EXPECT_EQ(errCode, E_OK);
445 
446     entriesRead.clear();
447 
448     /**
449      * @tc.steps:step3. Get k from database by GetEntries
450      * @tc.expected: step3. Return E_OK. The result size is 0.
451      */
452     errCode = g_connection->GetEntries(option, keyRead, entriesRead);
453     EXPECT_EQ(errCode, -E_NOT_FOUND);
454     EXPECT_EQ(entriesRead.size(), 0UL);
455 }
456 
CheckSplitData(const Value & oriValue,const uint32_t numBlock,std::map<ValueSliceHash,Value> & valueDic,Value & savedValue)457 static void CheckSplitData(const Value &oriValue, const uint32_t numBlock,
458     std::map<ValueSliceHash, Value> &valueDic, Value &savedValue)
459 {
460     MultiVerValueObject valueObject;
461     MultiVerNaturalStoreTransferData transferData;
462     std::vector<Value> partValues;
463     int errCode = transferData.SegmentAndTransferValueToHash(oriValue, partValues);
464     // Default threshold
465     if (oriValue.size() <= DistributedDB::DBConstant::MAX_VALUE_SIZE) {
466         valueObject.SetFlag(0);
467         valueObject.SetValue(oriValue);
468         valueObject.GetSerialData(savedValue);
469         EXPECT_EQ(errCode, -E_UNEXPECTED_DATA);
470         EXPECT_EQ(partValues.size(), numBlock);
471         return;
472     }
473     EXPECT_EQ(errCode, E_OK);
474     EXPECT_EQ(partValues.size(), numBlock);
475 
476     valueObject.SetFlag(MultiVerValueObject::HASH_FLAG);
477     std::vector<ValueSliceHash> hashValues;
478     ValueSliceHash hashValue;
479     for (const auto &value : partValues) {
480         errCode = DBCommon::CalcValueHash(value, hashValue);
481         EXPECT_EQ(errCode, E_OK);
482 
483         // prepare for recover
484         valueDic[hashValue] = value;
485         hashValues.push_back(std::move(hashValue));
486     }
487 
488     valueObject.SetValueHash(hashValues);
489     valueObject.GetSerialData(savedValue);
490 
491     return;
492 }
493 
CheckRecoverData(const Value & savedValue,std::map<ValueSliceHash,Value> & valueDic,Value & checkValue)494 static void CheckRecoverData(const Value &savedValue, std::map<ValueSliceHash, Value> &valueDic,
495     Value &checkValue)
496 {
497     Value value;
498     MultiVerValueObject valueObject;
499     EXPECT_EQ(valueObject.DeSerialData(savedValue), E_OK);
500     if (!valueObject.IsHash()) {
501         EXPECT_EQ(valueObject.GetValue(value), E_OK);
502     }
503 
504     std::vector<ValueSliceHash> sliceHashVect;
505     EXPECT_EQ(valueObject.GetValueHash(sliceHashVect), E_OK);
506 
507     value.reserve(valueObject.GetDataLength());
508     for (const auto &item : sliceHashVect) {
509         Value itemValue = valueDic[item];
510         value.insert(value.end(), itemValue.begin(), itemValue.end());
511     }
512 
513     EXPECT_EQ(value, checkValue);
514     return;
515 }
516 
517 /**
518   * @tc.name: BlockDataIndex001
519   * @tc.desc: Determine the block threshold of the database.
520   * @tc.type: FUNC
521   * @tc.require: AR000CQDTT SR000CQDTR
522   * @tc.author: sunpeng
523   */
524 HWTEST_F(DistributedDBStorageDataOperationTest, BlockDataIndex001, TestSize.Level1)
525 {
526     /**
527      * @tc.steps:step1/2/3. Put 100B 1K 100k size of unique value into database
528      */
529     Value value1;
530     DistributedDBToolsUnitTest::GetRandomKeyValue(value1, 100); // 100B
531     Value value2;
532     DistributedDBToolsUnitTest::GetRandomKeyValue(value2, 1024); // 1K
533     Value value3;
534     DistributedDBToolsUnitTest::GetRandomKeyValue(value3, 1024 * 100); // 100K
535 
536     IOption option;
537     option.dataType = IOption::SYNC_DATA;
538     int errCode = g_connection->Put(option, KEY_1, value1);
539     EXPECT_EQ(errCode, E_OK);
540     errCode = g_connection->Put(option, KEY_2, value2);
541     EXPECT_EQ(errCode, E_OK);
542     errCode = g_connection->Put(option, KEY_3, value3);
543     EXPECT_EQ(errCode, E_OK);
544 
545     /**
546      * @tc.steps:step4. Check split status
547      * @tc.expected: step4. Value1 not cut, value2 cut into 1 block, value3 cut into 2 blocks.
548      */
549     std::map<ValueSliceHash, Value> valueDic;
550     Value savedValue1;
551     CheckSplitData(value1, 0ul, valueDic, savedValue1);
552     Value savedValue2;
553     CheckSplitData(value2, 0ul, valueDic, savedValue2);
554     Value savedValue3;
555     CheckSplitData(value3, 0ul, valueDic, savedValue3);
556 
557     /**
558      * @tc.steps:step5. Get the original before key
559      * @tc.expected: step5. Return the right original value.
560      */
561     Value valueRead;
562     valueRead.clear();
563     errCode = g_connection->Get(option, KEY_1, valueRead);
564     EXPECT_EQ(errCode, E_OK);
565     EXPECT_EQ(value1, valueRead);
566     valueRead.clear();
567     errCode = g_connection->Get(option, KEY_2, valueRead);
568     EXPECT_EQ(errCode, E_OK);
569     EXPECT_EQ(value2, valueRead);
570     valueRead.clear();
571     errCode = g_connection->Get(option, KEY_3, valueRead);
572     EXPECT_EQ(errCode, E_OK);
573     EXPECT_EQ(value3, valueRead);
574 }
575 
576 /**
577   * @tc.name: CutValueIntoBlock001
578   * @tc.desc: Database block size test
579   * @tc.type: FUNC
580   * @tc.require: AR000CQDTS AR000CQDTU
581   * @tc.author: sunpeng
582   */
583 HWTEST_F(DistributedDBStorageDataOperationTest, CutValueIntoBlock001, TestSize.Level1)
584 {
585     /**
586      * @tc.steps:step1/2/3/4. Put 100B 1K 100k 64k size of unique value into database
587      */
588     Value value1;
589     DistributedDBToolsUnitTest::GetRandomKeyValue(value1, 100); // 100B
590     Value value2;
591     DistributedDBToolsUnitTest::GetRandomKeyValue(value2, 1024); // 1K
592     Value value3;
593     DistributedDBToolsUnitTest::GetRandomKeyValue(value3, 1024 * 100); // 100k
594     Value value4;
595     DistributedDBToolsUnitTest::GetRandomKeyValue(value4, 1024 * 64); // 64K
596 
597     /**
598      * @tc.steps:step4. Split and check repeat value block.
599      * @tc.expected: step4. No repeat block.
600      */
601     IOption option;
602     option.dataType = IOption::SYNC_DATA;
603     int errCode = g_connection->Put(option, KEY_1, value1);
604     EXPECT_EQ(errCode, E_OK);
605     errCode = g_connection->Put(option, KEY_2, value2);
606     EXPECT_EQ(errCode, E_OK);
607     errCode = g_connection->Put(option, KEY_3, value3);
608     EXPECT_EQ(errCode, E_OK);
609     errCode = g_connection->Put(option, KEY_4, value4);
610     EXPECT_EQ(errCode, E_OK);
611 
612     std::map<ValueSliceHash, Value> valueDic;
613     Value savedValue;
614     CheckSplitData(value1, 0ul, valueDic, savedValue);
615     CheckRecoverData(savedValue, valueDic, value1);
616 
617     valueDic.clear();
618     savedValue.clear();
619     CheckSplitData(value2, 0ul, valueDic, savedValue);
620     CheckRecoverData(savedValue, valueDic, value2);
621 
622     valueDic.clear();
623     savedValue.clear();
624     CheckSplitData(value3, 0ul, valueDic, savedValue);
625     CheckRecoverData(savedValue, valueDic, value3);
626     EXPECT_EQ(valueDic.size(), 0ul);
627 
628     valueDic.clear();
629     savedValue.clear();
630     CheckSplitData(value4, 0ul, valueDic, savedValue);
631     CheckRecoverData(savedValue, valueDic, value4);
632 }
633 
634 /**
635   * @tc.name: CutValueIntoBlock002
636   * @tc.desc: Block data index
637   * @tc.type: FUNC
638   * @tc.require: AR000CQDTT AR000CQDTV
639   * @tc.author: sunpeng
640   */
641 HWTEST_F(DistributedDBStorageDataOperationTest, CutValueIntoBlock002, TestSize.Level1)
642 {
643     /**
644      * @tc.steps:step1/2/3. Put 64k 100k 200k size of value into database(some blocks are repeated).
645      */
646     Value valueTemp;
647     DistributedDBToolsUnitTest::GetRandomKeyValue(valueTemp, 1024 * 36); // 36K add 64K equal 100K
648 
649     Value value1;
650     DistributedDBToolsUnitTest::GetRandomKeyValue(value1, 1024 * 64); // 64K
651     Value value2;
652     value2.insert(value2.end(), value1.begin(), value1.end());
653     value2.insert(value2.end(), valueTemp.begin(), valueTemp.end());
654 
655     Value value3;
656     // repeat twice value1 in front of value3
657     for (int i = 0; i < 2; i++) {
658         value3.insert(value3.end(), value1.begin(), value1.end());
659     }
660     value3.insert(value3.end(), valueTemp.begin(), valueTemp.end());
661     value3.insert(value3.end(), valueTemp.begin(), valueTemp.end());
662 
663     IOption option;
664     option.dataType = IOption::SYNC_DATA;
665     int errCode = g_connection->Put(option, KEY_1, value1);
666     EXPECT_EQ(errCode, E_OK);
667     errCode = g_connection->Put(option, KEY_2, value2);
668     EXPECT_EQ(errCode, E_OK);
669     errCode = g_connection->Put(option, KEY_3, value3);
670     EXPECT_EQ(errCode, E_OK);
671 
672     /**
673      * @tc.steps:step4. Split and check repeat value block.
674      * @tc.expected: step4. Duplicate blocks are eliminated
675      */
676     std::map<ValueSliceHash, Value> valueDic;
677     Value savedValue;
678     CheckSplitData(value3, 0ul, valueDic, savedValue);
679     CheckRecoverData(savedValue, valueDic, value3);
680     EXPECT_EQ(valueDic.size(), 0ul);
681 
682     savedValue.clear();
683     CheckSplitData(value1, 0ul, valueDic, savedValue);
684     CheckRecoverData(savedValue, valueDic, value1);
685     EXPECT_EQ(valueDic.size(), 0ul);
686 
687     savedValue.clear();
688     CheckSplitData(value2, 0ul, valueDic, savedValue);
689     CheckRecoverData(savedValue, valueDic, value2);
690     EXPECT_EQ(valueDic.size(), 0ul);
691 }
692 
693 /**
694   * @tc.name: ShaAlgoEncryptTest001
695   * @tc.desc: Test sqlite sha algo
696   * @tc.type: FUNC
697   * @tc.require: AR000HI2JS
698   * @tc.author: zhuwentao
699   */
700 HWTEST_F(DistributedDBStorageDataOperationTest, ShaAlgoEncryptTest001, TestSize.Level1)
701 {
702     sqlite3 *db = nullptr;
703     /**
704      * @tc.steps: step1. use sha256 to open db
705      * * @tc.expected: step1. interface return ok
706     */
707     uint64_t flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
708     std::string fileUrl = g_testDir + "/ShaAlgoEncryptTest001.db";
709     EXPECT_EQ(sqlite3_open_v2(fileUrl.c_str(), &db, flag, nullptr), SQLITE_OK);
710     EXPECT_EQ(SQLiteUtils::SetKeyInner(db, CipherType::AES_256_GCM, g_passwd, DBConstant::DEFAULT_ITER_TIMES), E_OK);
711     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, SHA256_ALGO_SQL), E_OK);
712     ASSERT_TRUE(SQLiteUtils::ExecuteRawSQL(db, SET_USER_VERSION_SQL) == E_OK);
713     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, USER_VERSION_SQL), E_OK);
714     /**
715      * @tc.steps: step2. close db
716      * * @tc.expected: step2. interface return ok
717     */
718     sqlite3_close_v2(db);
719     db = nullptr;
720     /**
721      * @tc.steps: step1. use sha1 to open db
722      * * @tc.expected: step1. interface return not ok
723     */
724     EXPECT_EQ(sqlite3_open_v2(fileUrl.c_str(), &db, flag, nullptr), SQLITE_OK);
725     EXPECT_EQ(SQLiteUtils::SetKeyInner(db, CipherType::AES_256_GCM, g_passwd, DBConstant::DEFAULT_ITER_TIMES), E_OK);
726     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, SHA1_ALGO_SQL), E_OK);
727     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, USER_VERSION_SQL), -E_INVALID_PASSWD_OR_CORRUPTED_DB);
728     sqlite3_close_v2(db);
729 }
730 
731 /**
732   * @tc.name: ShaAlgoEncryptTest002
733   * @tc.desc: Test sqlite sha algo in attach mode
734   * @tc.type: FUNC
735   * @tc.require: AR000HI2JS
736   * @tc.author: zhuwentao
737   */
738 HWTEST_F(DistributedDBStorageDataOperationTest, ShaAlgoEncryptTest002, TestSize.Level1)
739 {
740     sqlite3 *db = nullptr;
741     /**
742      * @tc.steps: step1. use sha256 to open db
743      * * @tc.expected: step1. interface return ok
744     */
745     uint64_t flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
746     std::string fileUrl = g_testDir + "/ShaAlgoEncryptTest002_attach.db";
747     EXPECT_EQ(sqlite3_open_v2(fileUrl.c_str(), &db, flag, nullptr), SQLITE_OK);
748     EXPECT_EQ(SQLiteUtils::SetKeyInner(db, CipherType::AES_256_GCM, g_passwd, DBConstant::DEFAULT_ITER_TIMES), E_OK);
749     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, SHA256_ALGO_SQL), E_OK);
750     ASSERT_TRUE(SQLiteUtils::ExecuteRawSQL(db, SET_USER_VERSION_SQL) == E_OK);
751     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, USER_VERSION_SQL), E_OK);
752     /**
753      * @tc.steps: step2. close db
754      * * @tc.expected: step2. interface return ok
755     */
756     sqlite3_close_v2(db);
757     db = nullptr;
758     /**
759      * @tc.steps: step3. open new db and attach old db
760      * * @tc.expected: step3. interface return ok
761     */
762     std::string fileUrl2 = g_testDir + "/ShaAlgoEncryptTest002.db";
763     EXPECT_EQ(sqlite3_open_v2(fileUrl2.c_str(), &db, flag, nullptr), SQLITE_OK);
764     EXPECT_EQ(SQLiteUtils::SetKeyInner(db, CipherType::AES_256_GCM, g_passwd2, DBConstant::DEFAULT_ITER_TIMES), E_OK);
765     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, SHA256_ALGO_SQL), E_OK);
766     ASSERT_TRUE(SQLiteUtils::ExecuteRawSQL(db, SET_USER_VERSION_SQL) == E_OK);
767     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, USER_VERSION_SQL), E_OK);
768     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, SHA256_ALGO_ATTACH_SQL), E_OK);
769     std::string attachName = "EncryptTest002";
770     EXPECT_EQ(SQLiteUtils::AttachNewDatabaseInner(db, CipherType::AES_256_GCM, g_passwd, fileUrl, attachName), E_OK);
771     /**
772      * @tc.steps: step4. close db
773      * * @tc.expected: step4. interface return ok
774     */
775     sqlite3_close_v2(db);
776 }
777 
778 /**
779   * @tc.name: ShaAlgoEncryptTest003
780   * @tc.desc: Test sqlite sha algo in attach mode
781   * @tc.type: FUNC
782   * @tc.require: AR000HI2JS
783   * @tc.author: zhuwentao
784   */
785 HWTEST_F(DistributedDBStorageDataOperationTest, ShaAlgoEncryptTest003, TestSize.Level1)
786 {
787     sqlite3 *db = nullptr;
788     /**
789      * @tc.steps: step1. use sha256 to open db
790      * * @tc.expected: step1. interface return ok
791     */
792     uint64_t flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
793     std::string fileUrl = g_testDir + "/ShaAlgoEncryptTest003_attach.db";
794     EXPECT_EQ(sqlite3_open_v2(fileUrl.c_str(), &db, flag, nullptr), SQLITE_OK);
795     EXPECT_EQ(SQLiteUtils::SetKeyInner(db, CipherType::AES_256_GCM, g_passwd, DBConstant::DEFAULT_ITER_TIMES), E_OK);
796     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, SHA1_ALGO_SQL), E_OK);
797     ASSERT_TRUE(SQLiteUtils::ExecuteRawSQL(db, SET_USER_VERSION_SQL) == E_OK);
798     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, USER_VERSION_SQL), E_OK);
799     /**
800      * @tc.steps: step2. close db
801      * * @tc.expected: step2. interface return ok
802     */
803     sqlite3_close_v2(db);
804     db = nullptr;
805     /**
806      * @tc.steps: step3. open new db and attach old db
807      * * @tc.expected: step3. interface return ok
808     */
809     std::string fileUrl2 = g_testDir + "/ShaAlgoEncryptTest003.db";
810     EXPECT_EQ(sqlite3_open_v2(fileUrl2.c_str(), &db, flag, nullptr), SQLITE_OK);
811     EXPECT_EQ(SQLiteUtils::SetKeyInner(db, CipherType::AES_256_GCM, g_passwd2, DBConstant::DEFAULT_ITER_TIMES), E_OK);
812     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, SHA256_ALGO_SQL), E_OK);
813     ASSERT_TRUE(SQLiteUtils::ExecuteRawSQL(db, SET_USER_VERSION_SQL) == E_OK);
814     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, USER_VERSION_SQL), E_OK);
815     std::string attachName = "EncryptTest003";
816     EXPECT_EQ(SQLiteUtils::AttachNewDatabase(db, CipherType::AES_256_GCM, g_passwd, fileUrl, attachName), E_OK);
817     /**
818      * @tc.steps: step4. close db
819      * * @tc.expected: step4. interface return ok
820     */
821     sqlite3_close_v2(db);
822 }
823 
824 /**
825   * @tc.name: ShaAlgoEncryptTest004
826   * @tc.desc: Test unnormal sql
827   * @tc.type: FUNC
828   * @tc.require: AR000HI2JS
829   * @tc.author: zhuwentao
830   */
831 HWTEST_F(DistributedDBStorageDataOperationTest, ShaAlgoEncryptTest004, TestSize.Level1)
832 {
833     sqlite3 *db = nullptr;
834     std::string fileUrl = g_testDir + "/ShaAlgoEncryptTest004.db";
835     std::string attachName = "EncryptTest004";
836     SQLiteUtils::AttachNewDatabase(db, CipherType::AES_256_GCM, g_passwd, fileUrl, attachName);
837     EXPECT_NE(SQLiteUtils::SetKeyInner(db, static_cast<CipherType>(3), g_passwd, DBConstant::DEFAULT_ITER_TIMES), E_OK);
838     uint64_t flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
839     EXPECT_EQ(sqlite3_open_v2(fileUrl.c_str(), &db, flag, nullptr), SQLITE_OK);
840     EXPECT_NE(SQLiteUtils::SetKey(db, static_cast<CipherType>(3), g_passwd, DBConstant::DEFAULT_ITER_TIMES), E_OK);
841     EXPECT_NE(SQLiteUtils::SetKeyInner(db, static_cast<CipherType>(3), g_passwd, DBConstant::DEFAULT_ITER_TIMES), E_OK);
842     EXPECT_EQ(SQLiteUtils::SetKey(db, CipherType::AES_256_GCM, g_passwd, DBConstant::DEFAULT_ITER_TIMES), E_OK);
843     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, SHA1_ALGO_SQL), E_OK);
844     ASSERT_TRUE(SQLiteUtils::ExecuteRawSQL(db, SET_USER_VERSION_SQL) == E_OK);
845     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, USER_VERSION_SQL), E_OK);
846     sqlite3_close_v2(db);
847     db = nullptr;
848 
849     std::string fileUrl2 = g_testDir + "/ShaAlgoEncryptTest004_attach.db";
850     EXPECT_EQ(sqlite3_open_v2(fileUrl2.c_str(), &db, flag, nullptr), SQLITE_OK);
851     EXPECT_EQ(SQLiteUtils::SetKeyInner(db, CipherType::AES_256_GCM, g_passwd2, DBConstant::DEFAULT_ITER_TIMES), E_OK);
852     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, SHA256_ALGO_SQL), E_OK);
853     EXPECT_NE(SQLiteUtils::AttachNewDatabase(db, CipherType::AES_256_GCM, g_passwd2, fileUrl, attachName), E_OK);
854     sqlite3_close_v2(db);
855     db = nullptr;
856 }
857 
858 /**
859   * @tc.name: DeleteTableCallbackTest001
860   * @tc.desc: Test drop table callback
861   * @tc.type: FUNC
862   * @tc.require: AR000HI2JS
863   * @tc.author: zhuwentao
864   */
865 HWTEST_F(DistributedDBStorageDataOperationTest, DeleteTableCallbackTest001, TestSize.Level0)
866 {
867     sqlite3 *db = nullptr;
868     /**
869      * @tc.steps: step1. use sha256 to open db
870      * * @tc.expected: step1. interface return ok
871     */
872     uint64_t flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
873     std::string fileUrl = g_testDir + "/DeleteTableCallbackTest001.db";
874     EXPECT_EQ(sqlite3_open_v2(fileUrl.c_str(), &db, flag, nullptr), SQLITE_OK);
875     EXPECT_EQ(SQLiteUtils::SetKeyInner(db, CipherType::AES_256_GCM, g_passwd, DBConstant::DEFAULT_ITER_TIMES), E_OK);
876     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, SHA256_ALGO_SQL), E_OK);
877     ASSERT_TRUE(SQLiteUtils::ExecuteRawSQL(db, SET_USER_VERSION_SQL) == E_OK);
878     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, USER_VERSION_SQL), E_OK);
879     EXPECT_EQ(sqlite3_set_droptable_handle(db, DropCallback), E_OK);
880     /**
881      * @tc.steps: step1. exec some sql
882      * * @tc.expected: step1. interface return ok
883     */
884     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_createTableSql1), E_OK);
885     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_createTableSql2), E_OK);
886     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_inerstDataSql1), E_OK);
887     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_inerstDataSql2), E_OK);
888     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_inerstDataSql3), E_OK);
889     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_inerstDataSql4), E_OK);
890     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_createViewSql), E_OK);
891     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_createIndexSql), E_OK);
892     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_deleteViewSql), E_OK);
893     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_dropIndex), E_OK);
894     EXPECT_EQ(g_callbackTimes, 0);
895     g_dbFile = fileUrl;
896     g_tableName = "student_2";
897     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_dropTableSql1), E_OK);
898     EXPECT_EQ(g_callbackTimes, 1);
899     g_tableName = "student_1";
900     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_dropTableSql2), E_OK);
901     EXPECT_EQ(g_callbackTimes, 2);
902     sqlite3_close_v2(db);
903     db = nullptr;
904 }
905 
906 /**
907   * @tc.name: DropTableCallbakTest001
908   * @tc.desc: Test drop table in attach mode
909   * @tc.type: FUNC
910   * @tc.require: AR000HI2JS
911   * @tc.author: zhuwentao
912   */
913 HWTEST_F(DistributedDBStorageDataOperationTest, DeleteTableCallbackTest002, TestSize.Level0)
914 {
915     sqlite3 *db = nullptr;
916     g_callbackTimes = 0;
917     /**
918      * @tc.steps: step1. use sha256 to open db
919      * * @tc.expected: step1. interface return ok
920     */
921     uint64_t flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
922     std::string fileUrl = g_testDir + "/DeleteTableCallbackAttachTest002.db";
923     EXPECT_EQ(sqlite3_open_v2(fileUrl.c_str(), &db, flag, nullptr), SQLITE_OK);
924     EXPECT_EQ(SQLiteUtils::SetKeyInner(db, CipherType::AES_256_GCM, g_passwd, DBConstant::DEFAULT_ITER_TIMES), E_OK);
925     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, SHA256_ALGO_SQL), E_OK);
926     ASSERT_TRUE(SQLiteUtils::ExecuteRawSQL(db, SET_USER_VERSION_SQL) == E_OK);
927     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, USER_VERSION_SQL), E_OK);
928     EXPECT_EQ(sqlite3_set_droptable_handle(db, DropCallback), E_OK);
929     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_createTableSql1), E_OK);
930     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_createTableSql2), E_OK);
931     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_inerstDataSql1), E_OK);
932     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_inerstDataSql2), E_OK);
933     /**
934      * @tc.steps: step2. close db
935      * * @tc.expected: step2. interface return ok
936     */
937     sqlite3_close_v2(db);
938     db = nullptr;
939     /**
940      * @tc.steps: step3. open new db and attach old db
941      * * @tc.expected: step3. interface return ok
942     */
943     std::string fileUrl2 = g_testDir + "/DeleteTableCallbackTest002.db";
944     EXPECT_EQ(sqlite3_open_v2(fileUrl2.c_str(), &db, flag, nullptr), SQLITE_OK);
945     EXPECT_EQ(SQLiteUtils::SetKeyInner(db, CipherType::AES_256_GCM, g_passwd2, DBConstant::DEFAULT_ITER_TIMES), E_OK);
946     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, SHA256_ALGO_SQL), E_OK);
947     ASSERT_TRUE(SQLiteUtils::ExecuteRawSQL(db, SET_USER_VERSION_SQL) == E_OK);
948     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, USER_VERSION_SQL), E_OK);
949     EXPECT_EQ(sqlite3_set_droptable_handle(db, DropCallback), E_OK);
950     std::string attachName = "AttachTest002";
951     EXPECT_EQ(SQLiteUtils::AttachNewDatabase(db, CipherType::AES_256_GCM, g_passwd, fileUrl, attachName), E_OK);
952     /**
953      * @tc.steps: step4. exec some sql
954      * * @tc.expected: step4. interface return ok
955     */
956     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_createTableSql1), E_OK);
957     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_createTableSql2), E_OK);
958     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_inerstDataSql1), E_OK);
959     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_inerstDataSql2), E_OK);
960     EXPECT_EQ(g_callbackTimes, 0);
961     std::string dropTableSql1 = "drop table " + attachName + ".student_2;";
962     std::string dropTableSql2 = "drop table student_1;";
963     g_dbFile = fileUrl;
964     g_tableName = "student_2";
965     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, dropTableSql1), E_OK);
966     EXPECT_EQ(g_callbackTimes, 1);
967     g_dbFile = fileUrl2;
968     g_tableName = "student_1";
969     EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, dropTableSql2), E_OK);
970     EXPECT_EQ(g_callbackTimes, 2);
971     sqlite3_close_v2(db);
972     db = nullptr;
973 }
974 #endif // OMIT_MULTI_VER