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