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