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