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