1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <gtest/gtest.h>
17 #include <thread>
18 #include <fcntl.h>
19 
20 #include "db_common.h"
21 #include "db_constant.h"
22 #include "db_errno.h"
23 #include "distributeddb_data_generate_unit_test.h"
24 #include "kv_store_nb_delegate_impl.h"
25 #include "platform_specific.h"
26 #include "process_system_api_adapter_impl.h"
27 #include "sqlite_single_ver_natural_store.h"
28 #include "sqlite_single_ver_natural_store_connection.h"
29 #include "storage_engine_manager.h"
30 
31 using namespace testing::ext;
32 using namespace DistributedDB;
33 using namespace DistributedDBUnitTest;
34 using namespace std;
35 
36 namespace {
37     string g_testDir;
38     KvStoreDelegateManager g_mgr(APP_ID, USER_ID);
39     KvStoreConfig g_config;
40     KvDBProperties g_property;
41     KvStoreNbDelegate *g_kvNbDelegatePtr = nullptr;
42     DBStatus g_kvDelegateStatus = INVALID_ARGS;
43     SQLiteSingleVerNaturalStore *g_store = nullptr;
44     DistributedDB::SQLiteSingleVerNaturalStoreConnection *g_connection = nullptr;
45     const string STORE_ID = STORE_ID_SYNC;
46     const int TIME_LAG = 100;
47     const std::string DEVICE_ID_1 = "ABC";
48     auto g_kvNbDelegateCallback = bind(&DistributedDBToolsUnitTest::KvStoreNbDelegateCallback,
49         placeholders::_1, placeholders::_2, std::ref(g_kvDelegateStatus), std::ref(g_kvNbDelegatePtr));
50 }
51 
52 class DistributedDBDeviceIdentifierTest : public testing::Test {
53 public:
54     static void SetUpTestCase(void);
55     static void TearDownTestCase(void);
56     void SetUp();
57     void TearDown();
58 };
59 
SetUpTestCase(void)60 void DistributedDBDeviceIdentifierTest::SetUpTestCase(void)
61 {
62     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
63     g_config.dataDir = g_testDir;
64     g_mgr.SetKvStoreConfig(g_config);
65 
66     string dir = g_testDir + STORE_ID + "/" + DBConstant::SINGLE_SUB_DIR;
67     DIR *dirTmp = opendir(dir.c_str());
68     if (dirTmp == nullptr) {
69         OS::MakeDBDirectory(dir);
70     } else {
71         closedir(dirTmp);
72     }
73     g_property.SetStringProp(KvDBProperties::DATA_DIR, g_testDir);
74     g_property.SetStringProp(KvDBProperties::STORE_ID, STORE_ID);
75     g_property.SetIntProp(KvDBProperties::DATABASE_TYPE, KvDBProperties::SINGLE_VER_TYPE_SQLITE);
76 }
77 
TearDownTestCase(void)78 void DistributedDBDeviceIdentifierTest::TearDownTestCase(void)
79 {
80     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir + STORE_ID + "/" + DBConstant::SINGLE_SUB_DIR) != 0) {
81         LOGE("rm test db files error!");
82     }
83     RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(nullptr);
84     std::this_thread::sleep_for(std::chrono::milliseconds(TIME_LAG));
85 }
86 
SetUp(void)87 void DistributedDBDeviceIdentifierTest::SetUp(void)
88 {
89     DistributedDBToolsUnitTest::PrintTestCaseInfo();
90     KvStoreNbDelegate::Option option = {true, false, false};
91     g_mgr.GetKvStore(STORE_ID, option, g_kvNbDelegateCallback);
92     EXPECT_TRUE(g_kvDelegateStatus == OK);
93     ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
94 
95     g_store = new (std::nothrow) SQLiteSingleVerNaturalStore;
96     ASSERT_NE(g_store, nullptr);
97     ASSERT_EQ(g_store->Open(g_property), E_OK);
98 
99     int erroCode = E_OK;
100     g_connection = static_cast<SQLiteSingleVerNaturalStoreConnection *>(g_store->GetDBConnection(erroCode));
101     ASSERT_NE(g_connection, nullptr);
102     g_store->DecObjRef(g_store);
103     EXPECT_EQ(erroCode, E_OK);
104 }
105 
TearDown(void)106 void DistributedDBDeviceIdentifierTest::TearDown(void)
107 {
108     if (g_connection != nullptr) {
109         g_connection->Close();
110     }
111 
112     g_store = nullptr;
113 
114     if (g_kvNbDelegatePtr != nullptr) {
115         EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
116         g_kvNbDelegatePtr = nullptr;
117         EXPECT_TRUE(g_mgr.DeleteKvStore(STORE_ID) == OK);
118     }
119     std::this_thread::sleep_for(std::chrono::milliseconds(TIME_LAG));
120 }
121 
122 /**
123   * @tc.name: DeviceIdentifier001
124   * @tc.desc: Set pragma to be GET_DEVICE_IDENTIFIER_OF_ENTRY,
125   * set Key to be null and origDevice to be false, expect return INVALID_ARGS.
126   * @tc.type: FUNC
127   * @tc.require: AR000D08KV
128   * @tc.author: maokeheng
129   */
130 HWTEST_F(DistributedDBDeviceIdentifierTest, DeviceIdentifier001, TestSize.Level1)
131 {
132     /**
133      * @tc.steps:step1. Sync 1K data from DEVICE_B into database, with Key= KEY_1, and Value = VALUE_1.
134      * @tc.expected: step1. Expect return true.
135      */
136     g_kvNbDelegatePtr->Put(KEY_1, VALUE_1);
137 
138     /**
139      * @tc.steps:step2. Set PragmaCmd to be GET_DEVICE_IDENTIFIER_OF_ENTRY, and set input key to be null
140      * @tc.expected: step2. Expect return INVALID_ARGS.
141      */
142     Key keyNull;
143     PragmaEntryDeviceIdentifier param;
144     param.key = keyNull;
145     param.origDevice = false;
146     PragmaData input = static_cast<void *>(&param);
147     EXPECT_EQ(g_kvNbDelegatePtr->Pragma(GET_DEVICE_IDENTIFIER_OF_ENTRY, input), INVALID_ARGS);
148 }
149 
150 /**
151   * @tc.name: DeviceIdentifier002
152   * @tc.desc: Set pragma to be GET_DEVICE_IDENTIFIER_OF_ENTRY,
153   * set Key to be null and origDevice to be true, expect return INVALID_ARGS.
154   * @tc.type: FUNC
155   * @tc.require: AR000D08KV
156   * @tc.author: maokeheng
157   */
158 HWTEST_F(DistributedDBDeviceIdentifierTest, DeviceIdentifier002, TestSize.Level1)
159 {
160     /**
161      * @tc.steps:step1. Sync 1K data from DEVICE_B into database, with Key= KEY_1, and Value = VALUE_1.
162      * @tc.expected: step1. Expect return true.
163      */
164     g_kvNbDelegatePtr->Put(KEY_1, VALUE_1);
165 
166     /**
167      * @tc.steps:step2. Set PragmaCmd to be GET_DEVICE_IDENTIFIER_OF_ENTRY, and set input key to be null
168      * @tc.expected: step2. Expect return INVALID_ARGS.
169      */
170     Key keyNull;
171     PragmaEntryDeviceIdentifier param;
172     param.key = keyNull;
173     param.origDevice = true;
174     PragmaData input = static_cast<void *>(&param);
175     EXPECT_EQ(g_kvNbDelegatePtr->Pragma(GET_DEVICE_IDENTIFIER_OF_ENTRY, input), INVALID_ARGS);
176 }
177 
178 /**
179   * @tc.name: DeviceIdentifier003
180   * @tc.desc: Set pragma to be GET_DEVICE_IDENTIFIER_OF_ENTRY and origDevice to be false.
181   * Check if a non-existing key will return NOT_FOUND.
182   * @tc.type: FUNC
183   * @tc.require: AR000D08KV
184   * @tc.author: maokeheng
185   */
186 HWTEST_F(DistributedDBDeviceIdentifierTest, DeviceIdentifier003, TestSize.Level1)
187 {
188     /**
189      * @tc.steps:step1. Sync 1K data from DEVICE_B into database, with Key= KEY_1, and Value = VALUE_1.
190      * @tc.expected: step1. Expect return true.
191      */
192     g_kvNbDelegatePtr->Put(KEY_1, VALUE_1);
193     /**
194      * @tc.steps:step2. Set PragmaCmd to be GET_DEVICE_IDENTIFIER_OF_ENTRY, and set Key= Key_2
195      * @tc.expected: step2. Expect return NOT_FOUND.
196      */
197     PragmaEntryDeviceIdentifier param;
198     param.key = KEY_2;
199     param.origDevice = false;
200     PragmaData input = static_cast<void *>(&param);
201     EXPECT_EQ(g_kvNbDelegatePtr->Pragma(GET_DEVICE_IDENTIFIER_OF_ENTRY, input), NOT_FOUND);
202 }
203 
204 /**
205   * @tc.name: DeviceIdentifier004
206   * @tc.desc: Set pragma to be GET_DEVICE_IDENTIFIER_OF_ENTRY and origDevice to be true.
207   * Check if a non-existing key will return NOT_FOUND.
208   * @tc.type: FUNC
209   * @tc.require: AR000D08KV
210   * @tc.author: maokeheng
211   */
212 HWTEST_F(DistributedDBDeviceIdentifierTest, DeviceIdentifier004, TestSize.Level1)
213 {
214     /**
215      * @tc.steps:step1. Sync 1K data from DEVICE_B into database, with Key= KEY_1, and Value = VALUE_1.
216      * @tc.expected: step1. Expect return true.
217      */
218     g_kvNbDelegatePtr->Put(KEY_1, VALUE_1);
219     /**
220      * @tc.steps:step2. Set PragmaCmd to be GET_DEVICE_IDENTIFIER_OF_ENTRY, and set Key= Key_2
221      * @tc.expected: step2. Expect return NOT_FOUND.
222      */
223     PragmaEntryDeviceIdentifier param;
224     param.key = KEY_2;
225     param.origDevice = true;
226     PragmaData input = static_cast<void *>(&param);
227     EXPECT_EQ(g_kvNbDelegatePtr->Pragma(GET_DEVICE_IDENTIFIER_OF_ENTRY, input), NOT_FOUND);
228 }
229 
230 /**
231   * @tc.name: DeviceIdentifier005
232   * @tc.desc: Set pragma to be GET_DEVICE_IDENTIFIER_OF_ENTRY and origDevice to be false. check if returns OK.
233   * @tc.type: FUNC
234   * @tc.require: AR000D08KV
235   * @tc.author: maokeheng
236   */
237 HWTEST_F(DistributedDBDeviceIdentifierTest, DeviceIdentifier005, TestSize.Level1)
238 {
239     /**
240      * @tc.steps:step1. Sync 1K data from DEVICE_B into database, with Key= KEY_1, and Value = VALUE_1.
241      * @tc.expected: step1. Expect return true.
242      */
243     g_kvNbDelegatePtr->Put(KEY_1, VALUE_1);
244     /**
245      * @tc.steps:step2. Set PragmaCmd = GET_DEVICE_IDENTIFIER_OF_ENTRY, Key= Key_1, origDevice = false.
246      * @tc.expected: step2. Expect return deviceIdentifier is the same as deviceIdentifier of DEVICE_B.
247      */
248     PragmaEntryDeviceIdentifier param;
249     param.key = KEY_1;
250     param.origDevice = false;
251     PragmaData input = static_cast<void *>(&param);
252     EXPECT_EQ(g_kvNbDelegatePtr->Pragma(GET_DEVICE_IDENTIFIER_OF_ENTRY, input), OK);
253 }
254 
255 /**
256   * @tc.name: DeviceIdentifier006
257   * @tc.desc: Set pragma to be GET_DEVICE_IDENTIFIER_OF_ENTRY and origDevice to be true. check if returns OK.
258   * @tc.type: FUNC
259   * @tc.require: AR000D08KV
260   * @tc.author: maokeheng
261   */
262 HWTEST_F(DistributedDBDeviceIdentifierTest, DeviceIdentifier006, TestSize.Level1)
263 {
264     /**
265      * @tc.steps:step1. Sync 1K data from DEVICE_B into database, with Key= KEY_1, and Value = VALUE_1.
266      * @tc.expected: step1. Expect return true.
267      */
268     g_kvNbDelegatePtr->Put(KEY_1, VALUE_1);
269     /**
270      * @tc.steps:step2. Set PragmaCmd = GET_DEVICE_IDENTIFIER_OF_ENTRY, Key= Key_1, origDevice = false.
271      * @tc.expected: step2. Expect return deviceIdentifier is the same as deviceIdentifier of DEVICE_B.
272      */
273     PragmaEntryDeviceIdentifier param;
274     param.key = KEY_1;
275     param.origDevice = true;
276     PragmaData input = static_cast<void *>(&param);
277     EXPECT_EQ(g_kvNbDelegatePtr->Pragma(GET_DEVICE_IDENTIFIER_OF_ENTRY, input), OK);
278 }
279 
280 /**
281   * @tc.name: DeviceIdentifier007
282   * @tc.desc: Set pragma to be GET_IDENTIFIER_OF_DEVICE. check if empty deviceID returns INVALID_ARGS.
283   * @tc.type: FUNC
284   * @tc.require: AR000D08KV
285   * @tc.author: maokeheng
286   */
287 HWTEST_F(DistributedDBDeviceIdentifierTest, DeviceIdentifier007, TestSize.Level1)
288 {
289     /**
290      * @tc.steps:step1. Set PragmaCmd = GET_IDENTIFIER_OF_DEVICE, deviceID= NULL.
291      * @tc.expected: step1. Expect return INVALID_ARGS.
292      */
293     PragmaDeviceIdentifier param;
294     param.deviceID = "";
295     PragmaData input = static_cast<void *>(&param);
296     EXPECT_EQ(g_kvNbDelegatePtr->Pragma(GET_IDENTIFIER_OF_DEVICE, input), INVALID_ARGS);
297 }
298 
299 /**
300   * @tc.name: DeviceIdentifier008
301   * @tc.desc: Set pragma to be GET_IDENTIFIER_OF_DEVICE. check if deviceIdentifier matches deviceID.
302   * @tc.type: FUNC
303   * @tc.require: AR000D08KV
304   * @tc.author: maokeheng
305   */
306 HWTEST_F(DistributedDBDeviceIdentifierTest, DeviceIdentifier008, TestSize.Level1)
307 {
308     /**
309      * @tc.steps:step1. Set PragmaCmd = GET_IDENTIFIER_OF_DEVICE, deviceID = DEVICE_ID_1
310      * @tc.expected: step1. Expect return deviceIdentifier is the same as deviceIdentifier of DEVICE_ID_1.
311      */
312     PragmaDeviceIdentifier param;
313     param.deviceID = DEVICE_ID_1;
314     PragmaData input = static_cast<void *>(&param);
315     EXPECT_EQ(g_kvNbDelegatePtr->Pragma(GET_IDENTIFIER_OF_DEVICE, input), OK);
316     EXPECT_EQ(param.deviceIdentifier, DBCommon::TransferHashString(DEVICE_ID_1));
317 }
318 
319 /**
320   * @tc.name: ErrDbTest001
321   * @tc.desc: Initialize check when the database is not opened
322   * @tc.type: FUNC
323   * @tc.require:
324   * @tc.author: bty
325   */
326 HWTEST_F(DistributedDBDeviceIdentifierTest, ErrDbTest001, TestSize.Level1)
327 {
328     /**
329      * @tc.steps: step1. Initialize an empty db and register nullptr callback
330      * @tc.expected: step1. Expect return not nullptr
331      */
332     SQLiteSingleVerNaturalStore *errStore = new (std::nothrow) SQLiteSingleVerNaturalStore;
333     ASSERT_NE(errStore, nullptr);
334 
335     /**
336      * @tc.steps: step2. Get db handle
337      * @tc.expected: step2. Expect return nullptr
338      */
339     int errCode;
340     EXPECT_EQ(errStore->GetHandle(false, errCode), nullptr);
341 
342     /**
343      * @tc.steps: step3. Check db integrity
344      * @tc.expected: step3. Expect return -E_INVALID_DB
345      */
346     EXPECT_EQ(errStore->CheckIntegrity(), -E_INVALID_DB);
347 
348     /**
349      * @tc.steps: step4. Check cache db mode
350      * @tc.expected: step4. Expect return false
351      */
352     EXPECT_FALSE(errStore->IsCacheDBMode());
353     EXPECT_FALSE(errStore->IsExtendedCacheDBMode());
354 
355     errStore->KillAndDecObjRef(errStore);
356 }
357 
358 /**
359   * @tc.name: ErrDbTest002
360   * @tc.desc: Register check when the database is not opened
361   * @tc.type: FUNC
362   * @tc.require:
363   * @tc.author: bty
364   */
365 HWTEST_F(DistributedDBDeviceIdentifierTest, ErrDbTest002, TestSize.Level1)
366 {
367     /**
368      * @tc.steps: step1. Initialize an empty db
369      * @tc.expected: step1. Expect return not nullptr
370      */
371     std::unique_ptr<SQLiteSingleVerNaturalStore> errStore = std::make_unique<SQLiteSingleVerNaturalStore>();
372     ASSERT_NE(errStore, nullptr);
373 
374     /**
375      * @tc.steps: step2. Check register nullptr callback
376      * @tc.expected: step2. Expect return E_OK
377      */
378     EXPECT_EQ(errStore->RegisterLifeCycleCallback(nullptr), E_OK);
379 
380     /**
381      * @tc.steps: step3. Check register Conflict type
382      * @tc.expected: step3. Expect return -E_NOT_SUPPORT
383      */
384     RegisterFuncType funcType = RegisterFuncType::OBSERVER_SINGLE_VERSION_NS_PUT_EVENT;
385     EXPECT_EQ(errStore->TransConflictTypeToRegisterFunctionType(0, funcType), -E_NOT_SUPPORT);
386 
387     /**
388      * @tc.steps: step4. Check register Observer type
389      * @tc.expected: step4. Expect return -E_NOT_SUPPORT
390      */
391     EXPECT_EQ(errStore->TransObserverTypeToRegisterFunctionType(0, funcType), -E_NOT_SUPPORT);
392 }
393 
394 /**
395   * @tc.name: ErrDbTest003
396   * @tc.desc: Export and Import check when the database is not opened
397   * @tc.type: FUNC
398   * @tc.require:
399   * @tc.author: bty
400   */
401 HWTEST_F(DistributedDBDeviceIdentifierTest, ErrDbTest003, TestSize.Level1)
402 {
403     /**
404      * @tc.steps: step1. Initialize an empty db
405      * @tc.expected: step1. Expect return not nullptr
406      */
407     std::unique_ptr<SQLiteSingleVerNaturalStore> errStore = std::make_unique<SQLiteSingleVerNaturalStore>();
408     ASSERT_NE(errStore, nullptr);
409 
410     /**
411      * @tc.steps: step2. Export
412      * @tc.expected: step2. Expect return -E_INVALID_DB
413      */
414     CipherPassword passwd;
415     EXPECT_EQ(errStore->Export(g_testDir, passwd), -E_INVALID_DB);
416 
417     /**
418      * @tc.steps: step3. Import
419      * @tc.expected: step3. Expect return -E_INVALID_DB
420      */
421     EXPECT_EQ(errStore->Import(g_testDir, passwd), -E_INVALID_DB);
422 
423     /**
424      * @tc.steps: step4. Reset key
425      * @tc.expected: step4. Expect return -E_INVALID_DB
426      */
427     EXPECT_EQ(errStore->Rekey(passwd), -E_INVALID_DB);
428 }
429 
430 /**
431   * @tc.name: ErrDbTest004
432   * @tc.desc: Check the interface of operation data when the database is not opened
433   * @tc.type: FUNC
434   * @tc.require:
435   * @tc.author: bty
436   */
437 HWTEST_F(DistributedDBDeviceIdentifierTest, ErrDbTest004, TestSize.Level1)
438 {
439     /**
440      * @tc.steps: step1. Initialize an empty db
441      * @tc.expected: step1. Expect return not nullptr
442      */
443     std::unique_ptr<SQLiteSingleVerNaturalStore> errStore = std::make_unique<SQLiteSingleVerNaturalStore>();
444     ASSERT_NE(errStore, nullptr);
445 
446     /**
447      * @tc.steps: step2. Get all meta keys
448      * @tc.expected: step2. Expect return -E_INVALID_DB
449      */
450     std::vector<Key> keys;
451     EXPECT_EQ(errStore->GetAllMetaKeys(keys), -E_INVALID_DB);
452 
453     /**
454      * @tc.steps: step3. Delete meta data if the Key is empty
455      * @tc.expected: step3. Expect return -E_INVALID_ARGS
456      */
457     Key key;
458     keys.push_back(key);
459     EXPECT_EQ(errStore->DeleteMetaData(keys), -E_INVALID_ARGS);
460 
461     /**
462      * @tc.steps: step4. Delete meta data if the Key is not empty
463      * @tc.expected: step4. Expect return -E_INVALID_DB
464      */
465     keys.front().push_back('A');
466     EXPECT_EQ(errStore->DeleteMetaData(keys), -E_INVALID_DB);
467 
468     /**
469      * @tc.steps: step5. put meta data
470      * @tc.expected: step5. Expect return -E_INVALID_DB
471      */
472     Value values;
473     EXPECT_EQ(errStore->PutMetaData(keys.front(), values, false), -E_INVALID_DB);
474 
475     /**
476      * @tc.steps: step6. Test remove device data
477      * @tc.expected: step6. Expect return -E_INVALID_ARGS
478      */
479     std::string deviceName;
480     EXPECT_EQ(errStore->RemoveDeviceData(deviceName, false), -E_INVALID_ARGS);
481 }
482 
483 /**
484   * @tc.name: ErrDbTest005
485   * @tc.desc: Test sync data when the database is not opened
486   * @tc.type: FUNC
487   * @tc.require:
488   * @tc.author: bty
489   */
490 HWTEST_F(DistributedDBDeviceIdentifierTest, ErrDbTest005, TestSize.Level1)
491 {
492     std::unique_ptr<SQLiteSingleVerNaturalStore> errStore = std::make_unique<SQLiteSingleVerNaturalStore>();
493     ASSERT_NE(errStore, nullptr);
494     ContinueToken token = nullptr;
495     std::vector<DataItem> dataItems;
496     DataSizeSpecInfo info = {DBConstant::MAX_SYNC_BLOCK_SIZE + 1, 0};
497     EXPECT_EQ(errStore->GetSyncDataNext(dataItems, token, info), -E_INVALID_ARGS);
498     info.blockSize = 0;
499     EXPECT_EQ(errStore->GetSyncDataNext(dataItems, token, info), -E_INVALID_ARGS);
500     errStore->ReleaseContinueToken(token);
501 }
502 
503 /**
504   * @tc.name: StorageEngineTest001
505   * @tc.desc: Test cache db remove data
506   * @tc.type: FUNC
507   * @tc.require:
508   * @tc.author: bty
509   */
510 HWTEST_F(DistributedDBDeviceIdentifierTest, StorageEngineTest001, TestSize.Level1)
511 {
512     int errCode = E_OK;
513     SQLiteSingleVerStorageEngine *storageEngine =
514         static_cast<SQLiteSingleVerStorageEngine *>(StorageEngineManager::GetStorageEngine(g_property, errCode));
515     ASSERT_EQ(errCode, E_OK);
516     ASSERT_NE(storageEngine, nullptr);
517     storageEngine->SetEngineState(EngineState::CACHEDB);
518     EXPECT_NE(g_store->RemoveDeviceData("device1", false), E_OK);
519     storageEngine->Release();
520 }
521 
522 namespace {
StorageEngineTest002()523 void StorageEngineTest002()
524 {
525     std::string exportFileName = g_testDir + "/" + STORE_ID + ".dump";
526     int fd = open(exportFileName.c_str(), (O_WRONLY | O_CREAT), (S_IRUSR | S_IWUSR | S_IRGRP));
527     ASSERT_TRUE(fd >= 0);
528     g_store->Dump(fd);
529     close(fd);
530     OS::RemoveDBDirectory(exportFileName);
531 }
532 }
533 
534 /**
535   * @tc.name: StorageEngineTest002
536   * @tc.desc: Test the interface of Dump
537   * @tc.type: FUNC
538   * @tc.require:
539   * @tc.author: bty
540   */
541 HWTEST_F(DistributedDBDeviceIdentifierTest, StorageEngineTest002, TestSize.Level1)
542 {
543     ASSERT_NO_FATAL_FAILURE(StorageEngineTest002());
544 }
545 
546 /**
547   * @tc.name: StorageEngineTest003
548   * @tc.desc: Test the accuracy of CacheRecordVersion
549   * @tc.type: FUNC
550   * @tc.require:
551   * @tc.author: bty
552   */
553 HWTEST_F(DistributedDBDeviceIdentifierTest, StorageEngineTest003, TestSize.Level1)
554 {
555     uint64_t curVersion = g_store->GetCacheRecordVersion();
556     g_store->IncreaseCacheRecordVersion();
557     EXPECT_EQ(g_store->GetCacheRecordVersion(), curVersion + 1);
558     EXPECT_EQ(g_store->GetAndIncreaseCacheRecordVersion(), curVersion + 1);
559     EXPECT_EQ(g_store->GetCacheRecordVersion(), curVersion + 2);
560 
561     curVersion = 0;
562     std::unique_ptr<SQLiteSingleVerNaturalStore> store2 = std::make_unique<SQLiteSingleVerNaturalStore>();
563     ASSERT_NE(store2, nullptr);
564     EXPECT_EQ(store2->GetCacheRecordVersion(), curVersion);
565     store2->IncreaseCacheRecordVersion();
566     EXPECT_EQ(store2->GetCacheRecordVersion(), curVersion);
567 }
568 
569 /**
570   * @tc.name: StorageEngineTest004
571   * @tc.desc: Modify parameter initialization StorageEngine
572   * @tc.type: FUNC
573   * @tc.require:
574   * @tc.author: bty
575   */
576 HWTEST_F(DistributedDBDeviceIdentifierTest, StorageEngineTest004, TestSize.Level1)
577 {
578     /**
579      * @tc.steps: step1. Get storageEngine
580      * @tc.expected: step1. Expect return E_OK
581      */
582     int errCode = E_OK;
583     SQLiteSingleVerStorageEngine *storageEngine =
584         static_cast<SQLiteSingleVerStorageEngine *>(StorageEngineManager::GetStorageEngine(g_property, errCode));
585     ASSERT_EQ(errCode, E_OK);
586     ASSERT_NE(storageEngine, nullptr);
587 
588     /**
589      * @tc.steps: step2. Set the wrong min write num
590      * @tc.expected: step2. Expect -E_INVALID_ARGS
591      */
592     StorageEngineAttr poolSize = {17, 1, 1, 1};  // 17 means the maximum value is exceeded, 1 is the normal value
593     OpenDbProperties option;
594     EXPECT_EQ(storageEngine->InitSQLiteStorageEngine(poolSize, option), -E_INVALID_ARGS);
595 
596     /**
597      * @tc.steps: step3. Set the correct min write num
598      * @tc.expected: step3. Expect E_OK
599      */
600     poolSize.minWriteNum = 1;
601     EXPECT_EQ(storageEngine->InitSQLiteStorageEngine(poolSize, option), E_OK);
602 
603     /**
604      * @tc.steps: step4. Change the Engine State
605      * @tc.expected: step4. Expect E_OK
606      */
607     EngineState engineState = {EngineState::CACHEDB};
608     storageEngine->SetEngineState(engineState);
609     EXPECT_EQ(storageEngine->InitSQLiteStorageEngine(poolSize, option), E_OK);
610 
611     storageEngine->Release();
612 }
613 
614 /**
615   * @tc.name: StorageEngineTest005
616   * @tc.desc: Set adapter to check engine
617   * @tc.type: FUNC
618   * @tc.require:
619   * @tc.author: bty
620   */
621 HWTEST_F(DistributedDBDeviceIdentifierTest, StorageEngineTest005, TestSize.Level1)
622 {
623     std::shared_ptr<ProcessSystemApiAdapterImpl> adapter = std::make_shared<ProcessSystemApiAdapterImpl>();
624     EXPECT_TRUE(adapter != nullptr);
625     RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(adapter);
626     int errCode = E_OK;
627     SQLiteSingleVerStorageEngine *storageEngine =
628         static_cast<SQLiteSingleVerStorageEngine *>(StorageEngineManager::GetStorageEngine(g_property, errCode));
629     ASSERT_NE(storageEngine, nullptr);
630     EXPECT_EQ(storageEngine->CheckEngineOption(g_property), E_OK);
631     RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(nullptr);
632 }
633 
634 /**
635   * @tc.name: StorageEngineTest006
636   * @tc.desc: Check the engine Option after setting the schema
637   * @tc.type: FUNC
638   * @tc.require:
639   * @tc.author: bty
640   */
641 HWTEST_F(DistributedDBDeviceIdentifierTest, StorageEngineTest006, TestSize.Level1)
642 {
643     /**
644      * @tc.steps: step1. First parse the schema, then set the KvDBProperties
645      * @tc.expected: step1. Expect return -E_SCHEMA_MISMATCH
646      */
647     int errCode = E_OK;
648     SQLiteSingleVerStorageEngine *storageEngine =
649         static_cast<SQLiteSingleVerStorageEngine *>(StorageEngineManager::GetStorageEngine(g_property, errCode));
650     ASSERT_NE(storageEngine, nullptr);
651     KvDBProperties prop;
652     prop.SetStringProp(KvDBProperties::DATA_DIR, g_property.GetStringProp(KvDBProperties::DATA_DIR, ""));
653     prop.SetStringProp(KvDBProperties::STORE_ID, g_property.GetStringProp(KvDBProperties::STORE_ID, ""));
654     prop.SetIntProp(KvDBProperties::DATABASE_TYPE, g_property.GetIntProp(KvDBProperties::DATABASE_TYPE, 0));
655     string schemaString =
656         "{\"SCHEMA_VERSION\":\"1.0\","
657         "\"SCHEMA_MODE\":\"STRICT\","
658         "\"SCHEMA_DEFINE\":{"
659         "\"field_name1\":\"BOOL\"},"
660         "\"SCHEMA_INDEXES\":[\"$.field_name1\"]}";
661     SchemaObject schema;
662     schema.ParseFromSchemaString(schemaString);
663     prop.SetSchema(schema);
664     EXPECT_EQ(storageEngine->CheckEngineOption(prop), -E_SCHEMA_MISMATCH);
665 
666     /**
667      * @tc.steps: step2. Set the error Schema for the option
668      * @tc.expected: step2. Expect return -E_SCHEMA_MISMATCH
669      */
670     OpenDbProperties option;
671     option.schema = "errorSchema";
672     StorageEngineAttr poolSize = {1, 1, 1, 1};  // 1 is the valid size
673     EXPECT_EQ(storageEngine->InitSQLiteStorageEngine(poolSize, option), E_OK);
674     EXPECT_EQ(storageEngine->CheckEngineOption(prop), -E_SCHEMA_MISMATCH);
675 
676     /**
677      * @tc.steps: step3. Set the correct Schema for the option
678      * @tc.expected: step3. Expect return E_OK
679      */
680     option.schema = schemaString;
681     EXPECT_EQ(storageEngine->InitSQLiteStorageEngine(poolSize, option), E_OK);
682     EXPECT_EQ(storageEngine->CheckEngineOption(prop), E_OK);
683 
684     storageEngine->Release();
685 }
686 
687 /**
688   * @tc.name: StorageEngineTest007
689   * @tc.desc: Export and import after changing engine state
690   * @tc.type: FUNC
691   * @tc.require:
692   * @tc.author: bty
693   */
694 HWTEST_F(DistributedDBDeviceIdentifierTest, StorageEngineTest007, TestSize.Level1)
695 {
696     /**
697      * @tc.steps: step1. Get storage engine
698      * @tc.expected: step1. Expect E_OK
699      */
700     int errCode = E_OK;
701     SQLiteSingleVerStorageEngine *storageEngine =
702         static_cast<SQLiteSingleVerStorageEngine *>(StorageEngineManager::GetStorageEngine(g_property, errCode));
703     ASSERT_EQ(errCode, E_OK);
704     ASSERT_NE(storageEngine, nullptr);
705 
706     /**
707      * @tc.steps: step2. Change engine state to cache db
708      * @tc.expected: step2. Expect -E_NOT_SUPPORT
709      */
710     storageEngine->SetEngineState(EngineState::CACHEDB);
711     CipherPassword passwd;
712     string filePath = g_testDir + "/store_export.db";
713     EXPECT_EQ(g_store->Export(filePath, passwd), -E_NOT_SUPPORT);
714     EXPECT_EQ(g_store->Import(filePath, passwd), -E_NOT_SUPPORT);
715     EXPECT_EQ(g_store->Rekey(passwd), -E_NOT_SUPPORT);
716 
717     /**
718      * @tc.steps: step3. Change engine state to INVALID
719      * @tc.expected: step3. Expect -E_BUSY
720      */
721     storageEngine->SetEngineState(EngineState::INVALID);
722     EXPECT_EQ(g_store->Export(filePath, passwd), -E_BUSY);
723     EXPECT_EQ(g_store->Import(filePath, passwd), -E_BUSY);
724     EXPECT_EQ(g_store->Rekey(passwd), -E_BUSY);
725     storageEngine->Release();
726 }
727 
728 /**
729   * @tc.name: StorageEngineTest008
730   * @tc.desc: add and remove sub after changing engine state
731   * @tc.type: FUNC
732   * @tc.require:
733   * @tc.author: bty
734   */
735 HWTEST_F(DistributedDBDeviceIdentifierTest, StorageEngineTest008, TestSize.Level1)
736 {
737     /**
738      * @tc.steps: step1. Get storage engine
739      * @tc.expected: step1. Expect E_OK
740      */
741     int errCode = E_OK;
742     SQLiteSingleVerStorageEngine *storageEngine =
743         static_cast<SQLiteSingleVerStorageEngine *>(StorageEngineManager::GetStorageEngine(g_property, errCode));
744     ASSERT_EQ(errCode, E_OK);
745     ASSERT_NE(storageEngine, nullptr);
746 
747     /**
748      * @tc.steps: step2. Change engine state to cache db
749      * @tc.expected: step2. Expect E_OK
750      */
751     storageEngine->SetEngineState(EngineState::CACHEDB);
752     Query query = Query::Select();
753     QueryObject queryObj(query);
754     std::string sub = "123";
755     EXPECT_EQ(g_store->AddSubscribe(sub, queryObj, true), E_OK);
756 
757     /**
758      * @tc.steps: step3. Remove subscribe from cache db
759      * @tc.expected: step3. Expect -1
760      */
761     std::vector<std::string> subs;
762     subs.push_back(sub);
763     EXPECT_EQ(g_store->RemoveSubscribe(subs), -1);
764     storageEngine->Release();
765 }