• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <chrono>
17 #include <gtest/gtest.h>
18 #include <thread>
19 
20 #include "db_common.h"
21 #include "db_constant.h"
22 #include "db_errno.h"
23 #include "distributeddb_tools_unit_test.h"
24 #include "kv_store_delegate_manager.h"
25 #include "kvdb_manager.h"
26 #include "kvdb_pragma.h"
27 #include "runtime_context.h"
28 
29 using namespace testing::ext;
30 using namespace DistributedDB;
31 using namespace DistributedDBUnitTest;
32 
33 namespace {
34     // define some variables to init a KvStoreDelegateManager object.
35     const std::string APP_ID1 = "app1";
36     const std::string USER_ID1 = "user1";
37     const Key KEY_1 = {'K', '1'};
38     KvStoreDelegateManager g_mgr(APP_ID1, USER_ID1);
39     std::string g_testDir;
40 
41     constexpr int MAX_AUTO_LAUNCH_NUM = 8;
42     constexpr uint32_t AUTO_LAUNCH_CYCLE_TIME = 6000;
43     constexpr uint32_t AUTO_LAUNCH_CHECK_TIME = (AUTO_LAUNCH_CYCLE_TIME / 2) + 500; // 500ms more than half.
44     constexpr int WAIT_FOR_RESPONSE_TIME = 200;
45     // define the g_kvDelegateCallback, used to get some information when open a kv store.
46     DBStatus g_kvStoreStatus = INVALID_ARGS;
47     KvStoreNbDelegate *g_kvStore = nullptr;
48     auto g_kvNbDelegateCallback = std::bind(&DistributedDBToolsUnitTest::KvStoreNbDelegateCallback,
49         std::placeholders::_1, std::placeholders::_2, std::ref(g_kvStoreStatus), std::ref(g_kvStore));
50 
51     const std::string SCHEMA_DEFINE1 = "{\"SCHEMA_VERSION\":\"1.0\","
52         "\"SCHEMA_MODE\":\"STRICT\","
53         "\"SCHEMA_DEFINE\":{"
54             "\"field_name1\":\"BOOL\","
55             "\"field_name2\":\"INTEGER, NOT NULL\""
56         "},"
57         "\"SCHEMA_INDEXES\":[\"$.field_name1\"]}";
58     const std::string SCHEMA_DEFINE2 = "{\"SCHEMA_VERSION\":\"1.0\","
59         "\"SCHEMA_MODE\":\"STRICT\","
60         "\"SCHEMA_DEFINE\":{"
61             "\"field_name1\":\"BOOL\","
62             "\"field_name3\":\"INTEGER, NOT NULL\""
63         "},"
64         "\"SCHEMA_INDEXES\":[\"$.field_name1\"]}";
65     class StoreCommunicatorAggregator : public ICommunicatorAggregator {
66     public:
67         // Return 0 as success. Return negative as error
Initialize(IAdapter * inAdapter,const std::shared_ptr<DBStatusAdapter> & statusAdapter)68         int Initialize(IAdapter *inAdapter, const std::shared_ptr<DBStatusAdapter> &statusAdapter) override
69         {
70             return E_OK;
71         }
72 
Finalize()73         void Finalize() override
74         {}
75 
76         // If not success, return nullptr and set outErrorNo
AllocCommunicator(uint64_t commLabel,int & outErrorNo,const std::string & userId)77         ICommunicator *AllocCommunicator(uint64_t commLabel, int &outErrorNo, const std::string &userId) override
78         {
79             outErrorNo = -E_OUT_OF_MEMORY;
80             return nullptr;
81         }
AllocCommunicator(const LabelType & commLabel,int & outErrorNo,const std::string & userId)82         ICommunicator *AllocCommunicator(const LabelType &commLabel, int &outErrorNo,
83             const std::string &userId) override
84         {
85             outErrorNo = -E_OUT_OF_MEMORY;
86             return nullptr;
87         }
88 
ReleaseCommunicator(ICommunicator * inCommunicator,const std::string & userId)89         void ReleaseCommunicator(ICommunicator *inCommunicator, const std::string &userId) override
90         {}
91 
RegCommunicatorLackCallback(const CommunicatorLackCallback & onCommLack,const Finalizer & inOper)92         int RegCommunicatorLackCallback(const CommunicatorLackCallback &onCommLack, const Finalizer &inOper) override
93         {
94             lackCallback_ = onCommLack;
95             return E_OK;
96         }
RegOnConnectCallback(const OnConnectCallback & onConnect,const Finalizer & inOper)97         int RegOnConnectCallback(const OnConnectCallback &onConnect, const Finalizer &inOper) override
98         {
99             return E_OK;
100         }
101 
PutCommLackInfo(const std::string & identifier) const102         void PutCommLackInfo(const std::string &identifier) const
103         {
104             if (lackCallback_) {
105                 std::vector<uint8_t> vect(identifier.begin(), identifier.end());
106                 lackCallback_(vect, USER_ID1);
107             }
108         }
109 
GetLocalIdentity(std::string & outTarget) const110         int GetLocalIdentity(std::string &outTarget) const override
111         {
112             return E_OK;
113         }
114     private:
115         CommunicatorLackCallback lackCallback_;
116     };
117 
118     struct AutoLaunchNotifyInfo {
Reset__anone2df07350111::AutoLaunchNotifyInfo119         void Reset()
120         {
121             triggerTimes = 0;
122         }
123         int triggerTimes = 0;
124         std::string userId;
125         std::string appId;
126         std::string storeId;
127         AutoLaunchStatus status = WRITE_CLOSED;
128     };
129     AutoLaunchNotifyInfo g_autoLaunchNotifyInfo;
130 
AutoLaunchNotifierCallback(AutoLaunchNotifyInfo & info,const std::string & userId,const std::string & appId,const std::string & storeId,AutoLaunchStatus status)131     void AutoLaunchNotifierCallback(AutoLaunchNotifyInfo &info, const std::string &userId, const std::string &appId,
132         const std::string &storeId, AutoLaunchStatus status)
133     {
134         info.triggerTimes++;
135         info.userId = userId;
136         info.appId = appId;
137         info.storeId = storeId;
138         info.status = status;
139     }
140 
141     auto g_autoLaunchNotifyFunc = std::bind(&AutoLaunchNotifierCallback, std::ref(g_autoLaunchNotifyInfo),
142         std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
143 
144     StoreCommunicatorAggregator *g_aggregator = nullptr;
145 }
146 
147 class DistributedDBInterfacesAutoLaunchTest : public testing::Test {
148 public:
149     static void SetUpTestCase(void);
150     static void TearDownTestCase(void);
151     void SetUp();
152     void TearDown();
153 };
154 
SetUpTestCase(void)155 void DistributedDBInterfacesAutoLaunchTest::SetUpTestCase(void)
156 {
157     LOGI("Start test interface auto launch test");
158     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
159     KvStoreConfig config;
160     config.dataDir = g_testDir;
161     g_mgr.SetKvStoreConfig(config);
162     g_aggregator = new (std::nothrow) StoreCommunicatorAggregator;
163     ASSERT_NE(g_aggregator, nullptr);
164     RuntimeContext::GetInstance()->SetCommunicatorAggregator(g_aggregator);
165 }
166 
TearDownTestCase(void)167 void DistributedDBInterfacesAutoLaunchTest::TearDownTestCase(void)
168 {
169     RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
170     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
171         LOGE("rm test db files error!");
172     }
173 }
174 
SetUp(void)175 void DistributedDBInterfacesAutoLaunchTest::SetUp(void)
176 {
177     DistributedDBToolsUnitTest::PrintTestCaseInfo();
178     g_kvStoreStatus = INVALID_ARGS;
179     g_kvStore = nullptr;
180 }
181 
TearDown(void)182 void DistributedDBInterfacesAutoLaunchTest::TearDown(void)
183 {
184     g_autoLaunchNotifyInfo.Reset();
185 }
186 #if !defined(OMIT_ENCRYPT) && !defined(OMIT_JSON)
187 /**
188   * @tc.name: EnableKvStoreAutoLaunch001
189   * @tc.desc: Enable the kvstore with the diff parameters.
190   * @tc.type: FUNC
191   * @tc.require: AR000DR9KU
192   * @tc.author: sunpeng
193   */
194 HWTEST_F(DistributedDBInterfacesAutoLaunchTest, EnableKvStoreAutoLaunch001, TestSize.Level1)
195 {
196     /**
197      * @tc.steps: step1. Create the kv store with passwd and no schema.
198      * @tc.expected: step1. Returns a non-null kvstore.
199      */
200     CipherPassword passwd;
201     std::vector<uint8_t> passwdVect = {'p', 's', 'd', '1'};
202     passwd.SetValue(passwdVect.data(), passwdVect.size());
203     KvStoreNbDelegate::Option option = {true, false, true, CipherType::DEFAULT, passwd, SCHEMA_DEFINE1, false};
204     std::string storeId = "test1";
205     g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback);
206     ASSERT_TRUE(g_kvStore != nullptr);
207     EXPECT_TRUE(g_kvStoreStatus == OK);
208     EXPECT_EQ(g_mgr.CloseKvStore(g_kvStore), OK);
209 
210     /**
211      * @tc.steps: step2. Enable the kv store with different password.
212      * @tc.expected: step2. Returns INVALID_PASSWD_OR_CORRUPTED_DB.
213      */
214     passwdVect = {'p', 's', 'd', '2'};
215     CipherPassword passwdOther;
216     passwdOther.SetValue(passwdVect.data(), passwdVect.size());
217     AutoLaunchOption launchOption = {true, true, CipherType::DEFAULT, passwdOther, "", false, g_testDir, nullptr};
218     DBStatus status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId,
219         launchOption, nullptr);
220     EXPECT_NE(status, OK);
221 
222     /**
223      * @tc.steps: step3. Enable the kv store with different schema.
224      * @tc.expected: step3. Returns not OK.
225      */
226     launchOption.passwd = passwd;
227     launchOption.schema = SCHEMA_DEFINE2;
228     status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId,
229         launchOption, nullptr);
230     EXPECT_NE(status, OK);
231 
232     /**
233      * @tc.steps: step4. Enable the kv store with correct parameter.
234      * @tc.expected: step4. Returns OK.
235      */
236     launchOption.passwd = passwd;
237     launchOption.schema = SCHEMA_DEFINE1;
238     status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId,
239         launchOption, nullptr);
240     EXPECT_EQ(status, OK);
241     KvStoreDelegateManager::DisableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId);
242     g_mgr.DeleteKvStore(storeId);
243 }
244 #endif
245 /**
246   * @tc.name: EnableKvStoreAutoLaunch002
247   * @tc.desc: Enable the kv store auto launch for the change of createIfNecessary.
248   * @tc.type: FUNC
249   * @tc.require: AR000DR9KU
250   * @tc.author: sunpeng
251   */
252 HWTEST_F(DistributedDBInterfacesAutoLaunchTest, EnableKvStoreAutoLaunch002, TestSize.Level1)
253 {
254     /**
255      * @tc.steps: step1. Enable the kv store with createIfNecessary is false.
256      * @tc.expected: step1. Returns not OK.
257      */
258     CipherPassword passwd;
259     std::string storeId = "test2";
260     AutoLaunchOption launchOption = {false, false, CipherType::DEFAULT, passwd, "", false, g_testDir, nullptr};
261     DBStatus status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId,
262         launchOption, nullptr);
263     EXPECT_NE(status, OK);
264     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), NOT_FOUND);
265 
266     /**
267      * @tc.steps: step2. Enable the kv store with createIfNecessary is true.
268      * @tc.expected: step2. Returns OK.
269      */
270     launchOption.createIfNecessary = true;
271     status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId,
272         launchOption, nullptr);
273     EXPECT_EQ(status, OK);
274     EXPECT_EQ(KvStoreDelegateManager::DisableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId), OK);
275     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
276 }
277 
278 namespace {
GetKvDB(const std::string & storeId)279 IKvDB *GetKvDB(const std::string &storeId)
280 {
281     KvDBProperties prop;
282     prop.SetStringProp(KvDBProperties::USER_ID, USER_ID1);
283     prop.SetStringProp(KvDBProperties::APP_ID, APP_ID1);
284     prop.SetStringProp(KvDBProperties::STORE_ID, storeId);
285     std::string identifier = DBCommon::TransferHashString(USER_ID1 + "-" + APP_ID1 + "-" + storeId);
286 
287     prop.SetStringProp(KvDBProperties::IDENTIFIER_DATA, identifier);
288     std::string identifierDir = DBCommon::TransferStringToHex(identifier);
289     prop.SetStringProp(KvDBProperties::IDENTIFIER_DIR, identifierDir);
290     prop.SetStringProp(KvDBProperties::DATA_DIR, g_testDir);
291     prop.SetIntProp(KvDBProperties::DATABASE_TYPE, KvDBProperties::SINGLE_VER_TYPE_SQLITE);
292     prop.SetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, true);
293     int errCode = E_OK;
294     return KvDBManager::OpenDatabase(prop, errCode);
295 }
296 
PutSyncData(const std::string & storeId,const Key & key,const Value & value,bool isCover)297 void PutSyncData(const std::string &storeId, const Key &key, const Value &value, bool isCover)
298 {
299     auto kvStore = static_cast<SQLiteSingleVerNaturalStore *>(GetKvDB(storeId));
300     ASSERT_NE(kvStore, nullptr);
301     int errCode;
302     auto *connection = kvStore->GetDBConnection(errCode);
303     ASSERT_NE(connection, nullptr);
304     std::vector<DataItem> vect;
305     Timestamp time = 100; // initial valid timestamp.
306     kvStore->GetMaxTimestamp(time);
307     if (isCover) {
308         time += 10; // add the diff for 10.
309     } else {
310         time -= 10; // add the diff for -10.
311     }
312     vect.push_back({key, value, time, 0, DBCommon::TransferHashString("deviceB")});
313     EXPECT_EQ(DistributedDBToolsUnitTest::PutSyncDataTest(kvStore, vect, "deviceB"), E_OK);
314     RefObject::DecObjRef(kvStore);
315     connection->Close();
316     connection = nullptr;
317 }
318 
GetSyncData(const std::string & storeId)319 void GetSyncData(const std::string &storeId)
320 {
321     auto kvStore = static_cast<SQLiteSingleVerNaturalStore *>(GetKvDB(storeId));
322     ASSERT_NE(kvStore, nullptr);
323     int errCode;
324     auto *connection = kvStore->GetDBConnection(errCode);
325     ASSERT_NE(connection, nullptr);
326 
327     std::vector<SingleVerKvEntry *> entries;
328     ContinueToken token = nullptr;
329     DataSizeSpecInfo syncDataSizeInfo = {DBConstant::MAX_VALUE_SIZE, DBConstant::MAX_HPMODE_PACK_ITEM_SIZE};
330     kvStore->GetSyncData(0, UINT64_MAX / 2, entries, token, syncDataSizeInfo); // half of the max timestamp.
331     SingleVerKvEntry::Release(entries);
332     if (token != nullptr) {
333         kvStore->ReleaseContinueToken(token);
334     }
335 
336     RefObject::DecObjRef(kvStore);
337     connection->Close();
338     connection = nullptr;
339 }
340 
PrePutDataIntoDatabase(const std::string & storeId)341 void PrePutDataIntoDatabase(const std::string &storeId)
342 {
343     KvStoreNbDelegate::Option option = {true, false, false};
344     g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback);
345     ASSERT_TRUE(g_kvStore != nullptr);
346     EXPECT_TRUE(g_kvStoreStatus == OK);
347 
348     Value value;
349     DistributedDBToolsUnitTest::GetRandomKeyValue(value);
350 
351     EXPECT_EQ(g_kvStore->Put(KEY_1, value), OK);
352     EXPECT_EQ(g_mgr.CloseKvStore(g_kvStore), OK);
353 }
354 
TriggerAutoLaunch(const std::string & storeId,bool isWriteCovered)355 void TriggerAutoLaunch(const std::string &storeId, bool isWriteCovered)
356 {
357     /**
358      * @tc.steps: step1. Enable the auto launch of the database.
359      * @tc.expected: step1. Returns OK.
360      */
361     PrePutDataIntoDatabase(storeId);
362     CipherPassword passwd;
363     KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest;
364     ASSERT_NE(observer, nullptr);
365 
366     AutoLaunchOption launchOption = {true, false, CipherType::DEFAULT, passwd, "", false, g_testDir, observer};
367     DBStatus status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId, launchOption,
368         g_autoLaunchNotifyFunc);
369     EXPECT_EQ(status, OK);
370 
371     /**
372      * @tc.steps: step2. Trigger the auto launch of the database.
373      */
374     std::string identifier = DBCommon::TransferHashString(USER_ID1 + "-" + APP_ID1 + "-" + storeId);
375     g_aggregator->PutCommLackInfo(identifier);
376     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_RESPONSE_TIME));
377     Value value;
378     DistributedDBToolsUnitTest::GetRandomKeyValue(value);
379     PutSyncData(storeId, KEY_1, value, isWriteCovered);
380     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_RESPONSE_TIME));
381     /**
382      * @tc.steps: step3. Check the notifier and the observer.
383      */
384     if (!isWriteCovered) {
385         EXPECT_EQ(g_autoLaunchNotifyInfo.triggerTimes, 0);
386     } else {
387         EXPECT_GT(g_autoLaunchNotifyInfo.triggerTimes, 0);
388         EXPECT_EQ(g_autoLaunchNotifyInfo.status, WRITE_OPENED);
389         EXPECT_GT(observer->GetCallCount(), 0UL);
390     }
391 
392     EXPECT_EQ(KvStoreDelegateManager::DisableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId), OK);
393     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_RESPONSE_TIME));
394     delete observer;
395     observer = nullptr;
396     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
397 }
398 }
399 
400 /**
401   * @tc.name: EnableKvStoreAutoLaunch003
402   * @tc.desc: test the data change and the notifier of the auto open for no data changed.
403   * @tc.type: FUNC
404   * @tc.require: AR000DR9KU
405   * @tc.author: sunpeng
406   */
407 HWTEST_F(DistributedDBInterfacesAutoLaunchTest, EnableKvStoreAutoLaunch003, TestSize.Level2)
408 {
409     /**
410      * @tc.steps: step1. Enable the auto launch of the database.
411      * @tc.steps: step2. Trigger the auto launch of the database.
412      * @tc.steps: step3. Put the data which would be dispatched into the database by sync.
413      * @tc.steps: step4. Check the notifier and the observer change.
414      * @tc.expected: step1. Returns OK.
415      * @tc.expected: step4. The notifier and the observer wouldn't be triggered.
416      */
417     TriggerAutoLaunch("test3", false);
418 }
419 
420 /**
421   * @tc.name: EnableKvStoreAutoLaunch004
422   * @tc.desc: test the data change and the notifier of the auto open for data changed.
423   * @tc.type: FUNC
424   * @tc.require: AR000DR9KU
425   * @tc.author: sunpeng
426   */
427 HWTEST_F(DistributedDBInterfacesAutoLaunchTest, EnableKvStoreAutoLaunch004, TestSize.Level2)
428 {
429     /**
430      * @tc.steps: step1. Enable the auto launch of the database.
431      * @tc.steps: step2. Trigger the auto launch of the database.
432      * @tc.steps: step3. Put the data which would overwrite into the database by sync.
433      * @tc.steps: step4. Check the notifier and the observer change.
434      * @tc.expected: step1. Returns OK.
435      * @tc.expected: step4. The notifier and the observer would be triggered.
436      */
437     TriggerAutoLaunch("test4", true);
438 }
439 
440 /**
441   * @tc.name: EnableKvStoreAutoLaunch005
442   * @tc.desc: Test enable the same database twice.
443   * @tc.type: FUNC
444   * @tc.require: AR000DR9KU
445   * @tc.author: sunpeng
446   */
447 HWTEST_F(DistributedDBInterfacesAutoLaunchTest, EnableKvStoreAutoLaunch005, TestSize.Level1)
448 {
449     /**
450      * @tc.steps: step1. Enable the kv store auto launch.
451      * @tc.expected: step1. Returns OK.
452      */
453     std::string storeId = "test5";
454     CipherPassword passwd;
455     AutoLaunchOption launchOption = {true, false, CipherType::DEFAULT, passwd, "", false, g_testDir, nullptr};
456     DBStatus status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId, launchOption,
457         nullptr);
458     EXPECT_EQ(status, OK);
459 
460     /**
461      * @tc.steps: step2. Ee-enable the kv store auto launch.
462      * @tc.expected: step2. Returns not OK.
463      */
464     status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId, launchOption,
465         nullptr);
466     EXPECT_NE(status, OK);
467     EXPECT_EQ(KvStoreDelegateManager::DisableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId), OK);
468     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
469 }
470 
471 /**
472   * @tc.name: EnableKvStoreAutoLaunch005
473   * @tc.desc: test the over limits for the enable list.
474   * @tc.type: FUNC
475   * @tc.require: AR000DR9KU
476   * @tc.author: sunpeng
477   */
478 HWTEST_F(DistributedDBInterfacesAutoLaunchTest, EnableKvStoreAutoLaunch006, TestSize.Level2)
479 {
480     /**
481      * @tc.steps: step1. Enable the 8 kv store auto launch.
482      * @tc.expected: step1. Returns OK.
483      */
484     CipherPassword passwd;
485     AutoLaunchOption launchOption = {true, false, CipherType::DEFAULT, passwd, "", false, g_testDir, nullptr};
486     for (int i = 0; i < MAX_AUTO_LAUNCH_NUM; i++) {
487         std::string storeId = "store_" + std::to_string(i + 1);
488         DBStatus status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId,
489             launchOption, nullptr);
490         EXPECT_EQ(status, OK);
491     }
492 
493     /**
494      * @tc.steps: step2. Enable the 9th kv store auto launch.
495      * @tc.expected: step2. Returns OK.
496      */
497     DBStatus status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, "store_9",
498         launchOption, nullptr);
499     EXPECT_EQ(status, OVER_MAX_LIMITS);
500 
501     /**
502      * @tc.steps: step3. Disable the 1th kv store auto launch.
503      * @tc.expected: step3. Returns OK.
504      */
505     EXPECT_EQ(KvStoreDelegateManager::DisableKvStoreAutoLaunch(USER_ID1, APP_ID1, "store_1"), OK);
506     /**
507      * @tc.steps: step4. Enable the 9th kv store auto launch.
508      * @tc.expected: step4. Returns OK.
509      */
510     status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, "store_9",
511         launchOption, nullptr);
512     EXPECT_EQ(status, OK);
513 
514     /**
515      * @tc.steps: step5. Disable all the kv stores auto launched.
516      * @tc.expected: step5. Returns OK.
517      */
518     for (int i = 1; i <= MAX_AUTO_LAUNCH_NUM; i++) {
519         std::string storeId = "store_" + std::to_string(i + 1);
520         EXPECT_EQ(KvStoreDelegateManager::DisableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId), OK);
521     }
522     /**
523      * @tc.steps: step6. Disable the kv stores which is not enabled.
524      * @tc.expected: step6. Returns NOT_FOUND.
525      */
526     EXPECT_EQ(KvStoreDelegateManager::DisableKvStoreAutoLaunch(USER_ID1, APP_ID1, "store_1"), NOT_FOUND);
527 }
528 
529 namespace {
SetAutoLaunchLifeCycleTime(const std::string & storeId,uint32_t time)530 void SetAutoLaunchLifeCycleTime(const std::string &storeId, uint32_t time)
531 {
532     LOGI("SetAutoLifeTime:%u", time);
533     auto kvStore = static_cast<SQLiteSingleVerNaturalStore *>(GetKvDB(storeId));
534     ASSERT_NE(kvStore, nullptr);
535     int errCode;
536     auto *connection = kvStore->GetDBConnection(errCode);
537     ASSERT_NE(connection, nullptr);
538     EXPECT_EQ(connection->Pragma(PRAGMA_SET_AUTO_LIFE_CYCLE, static_cast<PragmaData>(&time)), E_OK);
539     RefObject::DecObjRef(kvStore);
540     connection->Close();
541     connection = nullptr;
542 }
543 }
544 /**
545   * @tc.name: EnableKvStoreAutoLaunch007
546   * @tc.desc: test the over limits for the enable list.
547   * @tc.type: FUNC
548   * @tc.require: AR000DR9KU
549   * @tc.author: sunpeng
550   */
551 HWTEST_F(DistributedDBInterfacesAutoLaunchTest, DisableKvStoreAutoLaunch001, TestSize.Level3)
552 {
553     /**
554      * @tc.steps: step1. Enable the auto launch for 'test7'.
555      * @tc.expected: step1. Returns OK.
556      */
557     CipherPassword passwd;
558     AutoLaunchOption launchOption = {true, false, CipherType::DEFAULT, passwd, "", false, g_testDir, nullptr};
559     std::string storeId = "test7";
560     DBStatus status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId, launchOption,
561         g_autoLaunchNotifyFunc);
562     EXPECT_EQ(status, OK);
563     /**
564      * @tc.steps: step2. Disable the auto launch for 'test7'.
565      * @tc.expected: step2. Returns OK.
566      */
567     EXPECT_EQ(KvStoreDelegateManager::DisableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId), OK);
568     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_RESPONSE_TIME));
569     /**
570      * @tc.steps: step3. Trigger the auto launch and check the status of the database.
571      * @tc.expected: step3. The database was not auto launched.
572      */
573     std::string identifier = DBCommon::TransferHashString(USER_ID1 + "-" + APP_ID1 + "-" + storeId);
574     g_aggregator->PutCommLackInfo(identifier);
575     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_RESPONSE_TIME));
576     SetAutoLaunchLifeCycleTime(storeId, AUTO_LAUNCH_CYCLE_TIME);
577     Value value;
578     DistributedDBToolsUnitTest::GetRandomKeyValue(value);
579     PutSyncData(storeId, KEY_1, value, true);
580     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_RESPONSE_TIME));
581     EXPECT_EQ(g_autoLaunchNotifyInfo.triggerTimes, 0);
582     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
583 }
584 
585 /**
586   * @tc.name: AutoLaunchLifeCycle001
587   * @tc.desc: test the auto closed for the database auto launched by the msg.
588   * @tc.type: FUNC
589   * @tc.require: AR000E8S2T
590   * @tc.author: sunpeng
591   */
592 HWTEST_F(DistributedDBInterfacesAutoLaunchTest, AutoLaunchLifeCycle001, TestSize.Level3)
593 {
594     /**
595      * @tc.steps: step1. Enable the auto launch for 'test8'.
596      * @tc.expected: step1. Returns OK.
597      */
598     CipherPassword passwd;
599     AutoLaunchOption launchOption = {true, false, CipherType::DEFAULT, passwd, "", false, g_testDir, nullptr};
600     std::string storeId = "test8";
601     DBStatus status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId, launchOption,
602         g_autoLaunchNotifyFunc);
603     EXPECT_EQ(status, OK);
604 
605     /**
606      * @tc.steps: step2. Trigger the auto launch.
607      */
608     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_RESPONSE_TIME));
609     std::string identifier = DBCommon::TransferHashString(USER_ID1 + "-" + APP_ID1 + "-" + storeId);
610     g_aggregator->PutCommLackInfo(identifier);
611     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_RESPONSE_TIME));
612     SetAutoLaunchLifeCycleTime(storeId, AUTO_LAUNCH_CYCLE_TIME);
613     /**
614      * @tc.steps: step3. Put data into the database by sync.
615      */
616     Value value;
617     DistributedDBToolsUnitTest::GetRandomKeyValue(value);
618     PutSyncData(storeId, KEY_1, value, true);
619     std::this_thread::sleep_for(std::chrono::milliseconds(AUTO_LAUNCH_CHECK_TIME));
620     /**
621      * @tc.steps: step4. Check the notifier.
622      * @tc.expected: step4. notifier is triggered for the opened change.
623      */
624     EXPECT_GT(g_autoLaunchNotifyInfo.triggerTimes, 0);
625     EXPECT_NE(g_mgr.DeleteKvStore(storeId), OK);
626     g_autoLaunchNotifyInfo.Reset();
627     std::this_thread::sleep_for(std::chrono::milliseconds(AUTO_LAUNCH_CHECK_TIME));
628     /**
629      * @tc.steps: step5. Check the notifier for waiting for more than the life time of the auto launched database.
630      * @tc.expected: step5. notifier is triggered for the closed change.
631      */
632     EXPECT_GT(g_autoLaunchNotifyInfo.triggerTimes, 0);
633     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
634 
635     EXPECT_EQ(KvStoreDelegateManager::DisableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId), OK);
636     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_RESPONSE_TIME));
637 }
638 
639 namespace {
DelayAutoLaunchCycle(const std::string & storeId,bool isWrite)640 void DelayAutoLaunchCycle(const std::string &storeId, bool isWrite)
641 {
642     CipherPassword passwd;
643     AutoLaunchOption launchOption = {true, false, CipherType::DEFAULT, passwd, "", false, g_testDir, nullptr};
644     /**
645      * @tc.steps: step1. Enable the auto launch for 'test8'.
646      * @tc.expected: step1. Returns OK.
647      */
648     DBStatus status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId, launchOption,
649         nullptr);
650     EXPECT_EQ(status, OK);
651 
652     /**
653      * @tc.steps: step2. Trigger the auto launch.
654      */
655     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_RESPONSE_TIME));
656     std::string identifier = DBCommon::TransferHashString(USER_ID1 + "-" + APP_ID1 + "-" + storeId);
657     g_aggregator->PutCommLackInfo(identifier);
658     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_RESPONSE_TIME));
659     SetAutoLaunchLifeCycleTime(storeId, AUTO_LAUNCH_CYCLE_TIME);
660 
661     /**
662      * @tc.steps: step3. Write/Read the data into/from the database by sync.
663      */
664     std::this_thread::sleep_for(std::chrono::milliseconds(AUTO_LAUNCH_CHECK_TIME));
665     EXPECT_NE(g_mgr.DeleteKvStore(storeId), OK);
666     if (isWrite) {
667         Value value;
668         DistributedDBToolsUnitTest::GetRandomKeyValue(value);
669         PutSyncData(storeId, KEY_1, value, true);
670     } else {
671         GetSyncData(storeId);
672     }
673 
674     /**
675      * @tc.steps: step5. Check the status of the auto launched database.
676      * @tc.expected: step5. the life cycle of the auto launched database is prolonged by the sync operation.
677      */
678     std::this_thread::sleep_for(std::chrono::milliseconds(AUTO_LAUNCH_CHECK_TIME));
679     EXPECT_NE(g_mgr.DeleteKvStore(storeId), OK);
680 
681     std::this_thread::sleep_for(std::chrono::milliseconds(AUTO_LAUNCH_CHECK_TIME));
682     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
683 
684     EXPECT_EQ(KvStoreDelegateManager::DisableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId), OK);
685 }
686 }
687 
688 /**
689   * @tc.name: AutoLaunchLifeCycle002
690   * @tc.desc: test the over limits for the enable list.
691   * @tc.type: FUNC
692   * @tc.require: AR000E8S2T
693   * @tc.author: sunpeng
694   */
695 HWTEST_F(DistributedDBInterfacesAutoLaunchTest, AutoLaunchLifeCycle002, TestSize.Level3)
696 {
697     /**
698      * @tc.steps: step1. Enable the auto launch for 'test_9'.
699      * @tc.steps: step2. Trigger the auto launch.
700      * @tc.steps: step3. Trigger the sync writing operation.
701      * @tc.steps: step4. Check the status of the auto launched database.
702      * @tc.expected: step1. Returns OK.
703      * @tc.expected: step4. The life cycle is prolonged for the writing operation.
704      */
705     DelayAutoLaunchCycle("test_9", true);
706 }
707 
708 /**
709   * @tc.name: AutoLaunchLifeCycle003
710   * @tc.desc: test the life cycle of the auto launched database in the sync reading scene.
711   * @tc.type: FUNC
712   * @tc.require: AR000E8S2T
713   * @tc.author: sunpeng
714   */
715 HWTEST_F(DistributedDBInterfacesAutoLaunchTest, AutoLaunchLifeCycle003, TestSize.Level3)
716 {
717     /**
718      * @tc.steps: step1. Enable the auto launch for 'test_10'.
719      * @tc.steps: step2. Trigger the auto launch.
720      * @tc.steps: step3. Trigger the sync reading operation.
721      * @tc.steps: step4. Check the status of the auto launched database.
722      * @tc.expected: step1. Returns OK.
723      * @tc.expected: step4. The life cycle is prolonged for the reading operation.
724      */
725     DelayAutoLaunchCycle("test_10", false);
726 }
727