• 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 
ClearOnlineLabel()115         void ClearOnlineLabel() override
116         {
117         }
118     private:
119         CommunicatorLackCallback lackCallback_;
120     };
121 
122     struct AutoLaunchNotifyInfo {
Reset__anon67d44c970111::AutoLaunchNotifyInfo123         void Reset()
124         {
125             triggerTimes = 0;
126         }
127         int triggerTimes = 0;
128         std::string userId;
129         std::string appId;
130         std::string storeId;
131         AutoLaunchStatus status = WRITE_CLOSED;
132     };
133     AutoLaunchNotifyInfo g_autoLaunchNotifyInfo;
134 
AutoLaunchNotifierCallback(AutoLaunchNotifyInfo & info,const std::string & userId,const std::string & appId,const std::string & storeId,AutoLaunchStatus status)135     void AutoLaunchNotifierCallback(AutoLaunchNotifyInfo &info, const std::string &userId, const std::string &appId,
136         const std::string &storeId, AutoLaunchStatus status)
137     {
138         info.triggerTimes++;
139         info.userId = userId;
140         info.appId = appId;
141         info.storeId = storeId;
142         info.status = status;
143     }
144 
145     auto g_autoLaunchNotifyFunc = std::bind(&AutoLaunchNotifierCallback, std::ref(g_autoLaunchNotifyInfo),
146         std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
147 
148     StoreCommunicatorAggregator *g_aggregator = nullptr;
149 }
150 
151 class DistributedDBInterfacesAutoLaunchTest : public testing::Test {
152 public:
153     static void SetUpTestCase(void);
154     static void TearDownTestCase(void);
155     void SetUp();
156     void TearDown();
157 };
158 
SetUpTestCase(void)159 void DistributedDBInterfacesAutoLaunchTest::SetUpTestCase(void)
160 {
161     LOGI("Start test interface auto launch test");
162     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
163     KvStoreConfig config;
164     config.dataDir = g_testDir;
165     g_mgr.SetKvStoreConfig(config);
166     g_aggregator = new (std::nothrow) StoreCommunicatorAggregator;
167     ASSERT_NE(g_aggregator, nullptr);
168     RuntimeContext::GetInstance()->SetCommunicatorAggregator(g_aggregator);
169 }
170 
TearDownTestCase(void)171 void DistributedDBInterfacesAutoLaunchTest::TearDownTestCase(void)
172 {
173     RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
174     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
175         LOGE("rm test db files error!");
176     }
177 }
178 
SetUp(void)179 void DistributedDBInterfacesAutoLaunchTest::SetUp(void)
180 {
181     DistributedDBToolsUnitTest::PrintTestCaseInfo();
182     g_kvStoreStatus = INVALID_ARGS;
183     g_kvStore = nullptr;
184 }
185 
TearDown(void)186 void DistributedDBInterfacesAutoLaunchTest::TearDown(void)
187 {
188     g_autoLaunchNotifyInfo.Reset();
189 }
190 #if !defined(OMIT_ENCRYPT) && !defined(OMIT_JSON)
191 /**
192   * @tc.name: EnableKvStoreAutoLaunch001
193   * @tc.desc: Enable the kvstore with the diff parameters.
194   * @tc.type: FUNC
195   * @tc.require:
196   * @tc.author: sunpeng
197   */
198 HWTEST_F(DistributedDBInterfacesAutoLaunchTest, EnableKvStoreAutoLaunch001, TestSize.Level1)
199 {
200     /**
201      * @tc.steps: step1. Create the kv store with passwd and no schema.
202      * @tc.expected: step1. Returns a non-null kvstore.
203      */
204     CipherPassword passwd;
205     std::vector<uint8_t> passwdVect = {'p', 's', 'd', '1'};
206     passwd.SetValue(passwdVect.data(), passwdVect.size());
207     KvStoreNbDelegate::Option option = {true, false, true, CipherType::DEFAULT, passwd, SCHEMA_DEFINE1, false};
208     std::string storeId = "test1";
209     g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback);
210     ASSERT_TRUE(g_kvStore != nullptr);
211     EXPECT_TRUE(g_kvStoreStatus == OK);
212     EXPECT_EQ(g_mgr.CloseKvStore(g_kvStore), OK);
213 
214     /**
215      * @tc.steps: step2. Enable the kv store with different password.
216      * @tc.expected: step2. Returns INVALID_PASSWD_OR_CORRUPTED_DB.
217      */
218     passwdVect = {'p', 's', 'd', '2'};
219     CipherPassword passwdOther;
220     passwdOther.SetValue(passwdVect.data(), passwdVect.size());
221     AutoLaunchOption launchOption = {true, true, CipherType::DEFAULT, passwdOther, "", false, g_testDir, nullptr};
222     DBStatus status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId,
223         launchOption, nullptr);
224     EXPECT_NE(status, OK);
225 
226     /**
227      * @tc.steps: step3. Enable the kv store with different schema.
228      * @tc.expected: step3. Returns not OK.
229      */
230     launchOption.passwd = passwd;
231     launchOption.schema = SCHEMA_DEFINE2;
232     status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId,
233         launchOption, nullptr);
234     EXPECT_NE(status, OK);
235 
236     /**
237      * @tc.steps: step4. Enable the kv store with correct parameter.
238      * @tc.expected: step4. Returns OK.
239      */
240     launchOption.passwd = passwd;
241     launchOption.schema = SCHEMA_DEFINE1;
242     status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId,
243         launchOption, nullptr);
244     EXPECT_EQ(status, OK);
245     KvStoreDelegateManager::DisableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId);
246     g_mgr.DeleteKvStore(storeId);
247 }
248 #endif
249 /**
250   * @tc.name: EnableKvStoreAutoLaunch002
251   * @tc.desc: Enable the kv store auto launch for the change of createIfNecessary.
252   * @tc.type: FUNC
253   * @tc.require:
254   * @tc.author: sunpeng
255   */
256 HWTEST_F(DistributedDBInterfacesAutoLaunchTest, EnableKvStoreAutoLaunch002, TestSize.Level1)
257 {
258     /**
259      * @tc.steps: step1. Enable the kv store with createIfNecessary is false.
260      * @tc.expected: step1. Returns not OK.
261      */
262     CipherPassword passwd;
263     std::string storeId = "test2";
264     AutoLaunchOption launchOption = {false, false, CipherType::DEFAULT, passwd, "", false, g_testDir, nullptr};
265     DBStatus status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId,
266         launchOption, nullptr);
267     EXPECT_NE(status, OK);
268     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), NOT_FOUND);
269 
270     /**
271      * @tc.steps: step2. Enable the kv store with createIfNecessary is true.
272      * @tc.expected: step2. Returns OK.
273      */
274     launchOption.createIfNecessary = true;
275     status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId,
276         launchOption, nullptr);
277     EXPECT_EQ(status, OK);
278     EXPECT_EQ(KvStoreDelegateManager::DisableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId), OK);
279     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
280 }
281 
282 namespace {
GetKvDB(const std::string & storeId)283 IKvDB *GetKvDB(const std::string &storeId)
284 {
285     KvDBProperties prop;
286     prop.SetStringProp(KvDBProperties::USER_ID, USER_ID1);
287     prop.SetStringProp(KvDBProperties::APP_ID, APP_ID1);
288     prop.SetStringProp(KvDBProperties::STORE_ID, storeId);
289     std::string identifier = DBCommon::TransferHashString(USER_ID1 + "-" + APP_ID1 + "-" + storeId);
290 
291     prop.SetStringProp(KvDBProperties::IDENTIFIER_DATA, identifier);
292     std::string identifierDir = DBCommon::TransferStringToHex(identifier);
293     prop.SetStringProp(KvDBProperties::IDENTIFIER_DIR, identifierDir);
294     prop.SetStringProp(KvDBProperties::DATA_DIR, g_testDir);
295     prop.SetIntProp(KvDBProperties::DATABASE_TYPE, KvDBProperties::SINGLE_VER_TYPE_SQLITE);
296     prop.SetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, true);
297     int errCode = E_OK;
298     return KvDBManager::OpenDatabase(prop, errCode);
299 }
300 
PutSyncData(const std::string & storeId,const Key & key,const Value & value,bool isCover)301 void PutSyncData(const std::string &storeId, const Key &key, const Value &value, bool isCover)
302 {
303     auto kvStore = static_cast<SQLiteSingleVerNaturalStore *>(GetKvDB(storeId));
304     ASSERT_NE(kvStore, nullptr);
305     int errCode;
306     auto *connection = kvStore->GetDBConnection(errCode);
307     ASSERT_NE(connection, nullptr);
308     std::vector<DataItem> vect;
309     Timestamp time = 100; // initial valid timestamp.
310     kvStore->GetMaxTimestamp(time);
311     if (isCover) {
312         time += 10; // add the diff for 10.
313     } else {
314         time -= 10; // add the diff for -10.
315     }
316     vect.push_back({key, value, time, 0, DBCommon::TransferHashString("deviceB")});
317     EXPECT_EQ(DistributedDBToolsUnitTest::PutSyncDataTest(kvStore, vect, "deviceB"), E_OK);
318     RefObject::DecObjRef(kvStore);
319     connection->Close();
320     connection = nullptr;
321 }
322 
GetSyncData(const std::string & storeId)323 void GetSyncData(const std::string &storeId)
324 {
325     auto kvStore = static_cast<SQLiteSingleVerNaturalStore *>(GetKvDB(storeId));
326     ASSERT_NE(kvStore, nullptr);
327     int errCode;
328     auto *connection = kvStore->GetDBConnection(errCode);
329     ASSERT_NE(connection, nullptr);
330 
331     std::vector<SingleVerKvEntry *> entries;
332     ContinueToken token = nullptr;
333     DataSizeSpecInfo syncDataSizeInfo = {DBConstant::MAX_VALUE_SIZE, DBConstant::MAX_HPMODE_PACK_ITEM_SIZE};
334     kvStore->GetSyncData(0, UINT64_MAX / 2, entries, token, syncDataSizeInfo); // half of the max timestamp.
335     SingleVerKvEntry::Release(entries);
336     if (token != nullptr) {
337         kvStore->ReleaseContinueToken(token);
338     }
339 
340     RefObject::DecObjRef(kvStore);
341     connection->Close();
342     connection = nullptr;
343 }
344 
PrePutDataIntoDatabase(const std::string & storeId)345 void PrePutDataIntoDatabase(const std::string &storeId)
346 {
347     KvStoreNbDelegate::Option option = {true, false, false};
348     g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback);
349     ASSERT_TRUE(g_kvStore != nullptr);
350     EXPECT_TRUE(g_kvStoreStatus == OK);
351 
352     Value value;
353     DistributedDBToolsUnitTest::GetRandomKeyValue(value);
354 
355     EXPECT_EQ(g_kvStore->Put(KEY_1, value), OK);
356     EXPECT_EQ(g_mgr.CloseKvStore(g_kvStore), OK);
357 }
358 
TriggerAutoLaunch(const std::string & storeId,bool isWriteCovered)359 void TriggerAutoLaunch(const std::string &storeId, bool isWriteCovered)
360 {
361     /**
362      * @tc.steps: step1. Enable the auto launch of the database.
363      * @tc.expected: step1. Returns OK.
364      */
365     PrePutDataIntoDatabase(storeId);
366     CipherPassword passwd;
367     KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest;
368     ASSERT_NE(observer, nullptr);
369 
370     AutoLaunchOption launchOption = {true, false, CipherType::DEFAULT, passwd, "", false, g_testDir, observer};
371     DBStatus status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId, launchOption,
372         g_autoLaunchNotifyFunc);
373     EXPECT_EQ(status, OK);
374 
375     /**
376      * @tc.steps: step2. Trigger the auto launch of the database.
377      */
378     std::string identifier = DBCommon::TransferHashString(USER_ID1 + "-" + APP_ID1 + "-" + storeId);
379     g_aggregator->PutCommLackInfo(identifier);
380     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_RESPONSE_TIME));
381     Value value;
382     DistributedDBToolsUnitTest::GetRandomKeyValue(value);
383     PutSyncData(storeId, KEY_1, value, isWriteCovered);
384     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_RESPONSE_TIME));
385     /**
386      * @tc.steps: step3. Check the notifier and the observer.
387      */
388     if (!isWriteCovered) {
389         EXPECT_EQ(g_autoLaunchNotifyInfo.triggerTimes, 0);
390     } else {
391         EXPECT_GT(g_autoLaunchNotifyInfo.triggerTimes, 0);
392         EXPECT_EQ(g_autoLaunchNotifyInfo.status, WRITE_OPENED);
393         EXPECT_GT(observer->GetCallCount(), 0UL);
394     }
395 
396     EXPECT_EQ(KvStoreDelegateManager::DisableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId), OK);
397     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_RESPONSE_TIME));
398     delete observer;
399     observer = nullptr;
400     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
401 }
402 }
403 
404 /**
405   * @tc.name: EnableKvStoreAutoLaunch003
406   * @tc.desc: test the data change and the notifier of the auto open for no data changed.
407   * @tc.type: FUNC
408   * @tc.require:
409   * @tc.author: sunpeng
410   */
411 HWTEST_F(DistributedDBInterfacesAutoLaunchTest, EnableKvStoreAutoLaunch003, TestSize.Level2)
412 {
413     /**
414      * @tc.steps: step1. Enable the auto launch of the database.
415      * @tc.steps: step2. Trigger the auto launch of the database.
416      * @tc.steps: step3. Put the data which would be dispatched into the database by sync.
417      * @tc.steps: step4. Check the notifier and the observer change.
418      * @tc.expected: step1. Returns OK.
419      * @tc.expected: step4. The notifier and the observer wouldn't be triggered.
420      */
421     TriggerAutoLaunch("test3", false);
422 }
423 
424 /**
425   * @tc.name: EnableKvStoreAutoLaunch004
426   * @tc.desc: test the data change and the notifier of the auto open for data changed.
427   * @tc.type: FUNC
428   * @tc.require:
429   * @tc.author: sunpeng
430   */
431 HWTEST_F(DistributedDBInterfacesAutoLaunchTest, EnableKvStoreAutoLaunch004, TestSize.Level2)
432 {
433     /**
434      * @tc.steps: step1. Enable the auto launch of the database.
435      * @tc.steps: step2. Trigger the auto launch of the database.
436      * @tc.steps: step3. Put the data which would overwrite into the database by sync.
437      * @tc.steps: step4. Check the notifier and the observer change.
438      * @tc.expected: step1. Returns OK.
439      * @tc.expected: step4. The notifier and the observer would be triggered.
440      */
441     TriggerAutoLaunch("test4", true);
442 }
443 
444 /**
445   * @tc.name: EnableKvStoreAutoLaunch005
446   * @tc.desc: Test enable the same database twice.
447   * @tc.type: FUNC
448   * @tc.require:
449   * @tc.author: sunpeng
450   */
451 HWTEST_F(DistributedDBInterfacesAutoLaunchTest, EnableKvStoreAutoLaunch005, TestSize.Level1)
452 {
453     /**
454      * @tc.steps: step1. Enable the kv store auto launch.
455      * @tc.expected: step1. Returns OK.
456      */
457     std::string storeId = "test5";
458     CipherPassword passwd;
459     AutoLaunchOption launchOption = {true, false, CipherType::DEFAULT, passwd, "", false, g_testDir, nullptr};
460     DBStatus status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId, launchOption,
461         nullptr);
462     EXPECT_EQ(status, OK);
463 
464     /**
465      * @tc.steps: step2. Ee-enable the kv store auto launch.
466      * @tc.expected: step2. Returns not OK.
467      */
468     status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId, launchOption,
469         nullptr);
470     EXPECT_NE(status, OK);
471     EXPECT_EQ(KvStoreDelegateManager::DisableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId), OK);
472     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
473 }
474 
475 /**
476   * @tc.name: EnableKvStoreAutoLaunch005
477   * @tc.desc: test the over limits for the enable list.
478   * @tc.type: FUNC
479   * @tc.require:
480   * @tc.author: sunpeng
481   */
482 HWTEST_F(DistributedDBInterfacesAutoLaunchTest, EnableKvStoreAutoLaunch006, TestSize.Level2)
483 {
484     /**
485      * @tc.steps: step1. Enable the 8 kv store auto launch.
486      * @tc.expected: step1. Returns OK.
487      */
488     CipherPassword passwd;
489     AutoLaunchOption launchOption = {true, false, CipherType::DEFAULT, passwd, "", false, g_testDir, nullptr};
490     for (int i = 0; i < MAX_AUTO_LAUNCH_NUM; i++) {
491         std::string storeId = "store_" + std::to_string(i + 1);
492         DBStatus status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId,
493             launchOption, nullptr);
494         EXPECT_EQ(status, OK);
495     }
496 
497     /**
498      * @tc.steps: step2. Enable the 9th kv store auto launch.
499      * @tc.expected: step2. Returns OK.
500      */
501     DBStatus status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, "store_9",
502         launchOption, nullptr);
503     EXPECT_EQ(status, OVER_MAX_LIMITS);
504 
505     /**
506      * @tc.steps: step3. Disable the 1th kv store auto launch.
507      * @tc.expected: step3. Returns OK.
508      */
509     EXPECT_EQ(KvStoreDelegateManager::DisableKvStoreAutoLaunch(USER_ID1, APP_ID1, "store_1"), OK);
510     /**
511      * @tc.steps: step4. Enable the 9th kv store auto launch.
512      * @tc.expected: step4. Returns OK.
513      */
514     status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, "store_9",
515         launchOption, nullptr);
516     EXPECT_EQ(status, OK);
517 
518     /**
519      * @tc.steps: step5. Disable all the kv stores auto launched.
520      * @tc.expected: step5. Returns OK.
521      */
522     for (int i = 1; i <= MAX_AUTO_LAUNCH_NUM; i++) {
523         std::string storeId = "store_" + std::to_string(i + 1);
524         EXPECT_EQ(KvStoreDelegateManager::DisableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId), OK);
525     }
526     /**
527      * @tc.steps: step6. Disable the kv stores which is not enabled.
528      * @tc.expected: step6. Returns NOT_FOUND.
529      */
530     EXPECT_EQ(KvStoreDelegateManager::DisableKvStoreAutoLaunch(USER_ID1, APP_ID1, "store_1"), NOT_FOUND);
531 }
532 
533 namespace {
SetAutoLaunchLifeCycleTime(const std::string & storeId,uint32_t time)534 void SetAutoLaunchLifeCycleTime(const std::string &storeId, uint32_t time)
535 {
536     LOGI("SetAutoLifeTime:%u", time);
537     auto kvStore = static_cast<SQLiteSingleVerNaturalStore *>(GetKvDB(storeId));
538     ASSERT_NE(kvStore, nullptr);
539     int errCode;
540     auto *connection = kvStore->GetDBConnection(errCode);
541     ASSERT_NE(connection, nullptr);
542     EXPECT_EQ(connection->Pragma(PRAGMA_SET_AUTO_LIFE_CYCLE, static_cast<PragmaData>(&time)), E_OK);
543     RefObject::DecObjRef(kvStore);
544     connection->Close();
545     connection = nullptr;
546 }
547 }
548 /**
549   * @tc.name: EnableKvStoreAutoLaunch007
550   * @tc.desc: test the over limits for the enable list.
551   * @tc.type: FUNC
552   * @tc.require:
553   * @tc.author: sunpeng
554   */
555 HWTEST_F(DistributedDBInterfacesAutoLaunchTest, DisableKvStoreAutoLaunch001, TestSize.Level3)
556 {
557     /**
558      * @tc.steps: step1. Enable the auto launch for 'test7'.
559      * @tc.expected: step1. Returns OK.
560      */
561     CipherPassword passwd;
562     AutoLaunchOption launchOption = {true, false, CipherType::DEFAULT, passwd, "", false, g_testDir, nullptr};
563     std::string storeId = "test7";
564     DBStatus status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId, launchOption,
565         g_autoLaunchNotifyFunc);
566     EXPECT_EQ(status, OK);
567     /**
568      * @tc.steps: step2. Disable the auto launch for 'test7'.
569      * @tc.expected: step2. Returns OK.
570      */
571     EXPECT_EQ(KvStoreDelegateManager::DisableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId), OK);
572     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_RESPONSE_TIME));
573     /**
574      * @tc.steps: step3. Trigger the auto launch and check the status of the database.
575      * @tc.expected: step3. The database was not auto launched.
576      */
577     std::string identifier = DBCommon::TransferHashString(USER_ID1 + "-" + APP_ID1 + "-" + storeId);
578     g_aggregator->PutCommLackInfo(identifier);
579     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_RESPONSE_TIME));
580     SetAutoLaunchLifeCycleTime(storeId, AUTO_LAUNCH_CYCLE_TIME);
581     Value value;
582     DistributedDBToolsUnitTest::GetRandomKeyValue(value);
583     PutSyncData(storeId, KEY_1, value, true);
584     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_RESPONSE_TIME));
585     EXPECT_EQ(g_autoLaunchNotifyInfo.triggerTimes, 0);
586     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
587 }
588 
589 /**
590   * @tc.name: AutoLaunchLifeCycle001
591   * @tc.desc: test the auto closed for the database auto launched by the msg.
592   * @tc.type: FUNC
593   * @tc.require:
594   * @tc.author: sunpeng
595   */
596 HWTEST_F(DistributedDBInterfacesAutoLaunchTest, AutoLaunchLifeCycle001, TestSize.Level3)
597 {
598     /**
599      * @tc.steps: step1. Enable the auto launch for 'test8'.
600      * @tc.expected: step1. Returns OK.
601      */
602     CipherPassword passwd;
603     AutoLaunchOption launchOption = {true, false, CipherType::DEFAULT, passwd, "", false, g_testDir, nullptr};
604     std::string storeId = "test8";
605     DBStatus status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId, launchOption,
606         g_autoLaunchNotifyFunc);
607     EXPECT_EQ(status, OK);
608 
609     /**
610      * @tc.steps: step2. Trigger the auto launch.
611      */
612     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_RESPONSE_TIME));
613     std::string identifier = DBCommon::TransferHashString(USER_ID1 + "-" + APP_ID1 + "-" + storeId);
614     g_aggregator->PutCommLackInfo(identifier);
615     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_RESPONSE_TIME));
616     SetAutoLaunchLifeCycleTime(storeId, AUTO_LAUNCH_CYCLE_TIME);
617     /**
618      * @tc.steps: step3. Put data into the database by sync.
619      */
620     Value value;
621     DistributedDBToolsUnitTest::GetRandomKeyValue(value);
622     PutSyncData(storeId, KEY_1, value, true);
623     std::this_thread::sleep_for(std::chrono::milliseconds(AUTO_LAUNCH_CHECK_TIME));
624     /**
625      * @tc.steps: step4. Check the notifier.
626      * @tc.expected: step4. notifier is triggered for the opened change.
627      */
628     EXPECT_GT(g_autoLaunchNotifyInfo.triggerTimes, 0);
629     EXPECT_NE(g_mgr.DeleteKvStore(storeId), OK);
630     g_autoLaunchNotifyInfo.Reset();
631     std::this_thread::sleep_for(std::chrono::milliseconds(AUTO_LAUNCH_CHECK_TIME));
632     /**
633      * @tc.steps: step5. Check the notifier for waiting for more than the life time of the auto launched database.
634      * @tc.expected: step5. notifier is triggered for the closed change.
635      */
636     EXPECT_GT(g_autoLaunchNotifyInfo.triggerTimes, 0);
637     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
638 
639     EXPECT_EQ(KvStoreDelegateManager::DisableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId), OK);
640     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_RESPONSE_TIME));
641 }
642 
643 namespace {
DelayAutoLaunchCycle(const std::string & storeId,bool isWrite)644 void DelayAutoLaunchCycle(const std::string &storeId, bool isWrite)
645 {
646     CipherPassword passwd;
647     AutoLaunchOption launchOption = {true, false, CipherType::DEFAULT, passwd, "", false, g_testDir, nullptr};
648     /**
649      * @tc.steps: step1. Enable the auto launch for 'test8'.
650      * @tc.expected: step1. Returns OK.
651      */
652     DBStatus status = KvStoreDelegateManager::EnableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId, launchOption,
653         nullptr);
654     EXPECT_EQ(status, OK);
655 
656     /**
657      * @tc.steps: step2. Trigger the auto launch.
658      */
659     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_RESPONSE_TIME));
660     std::string identifier = DBCommon::TransferHashString(USER_ID1 + "-" + APP_ID1 + "-" + storeId);
661     g_aggregator->PutCommLackInfo(identifier);
662     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_RESPONSE_TIME));
663     SetAutoLaunchLifeCycleTime(storeId, AUTO_LAUNCH_CYCLE_TIME);
664 
665     /**
666      * @tc.steps: step3. Write/Read the data into/from the database by sync.
667      */
668     std::this_thread::sleep_for(std::chrono::milliseconds(AUTO_LAUNCH_CHECK_TIME));
669     EXPECT_NE(g_mgr.DeleteKvStore(storeId), OK);
670     if (isWrite) {
671         Value value;
672         DistributedDBToolsUnitTest::GetRandomKeyValue(value);
673         PutSyncData(storeId, KEY_1, value, true);
674     } else {
675         GetSyncData(storeId);
676     }
677 
678     /**
679      * @tc.steps: step5. Check the status of the auto launched database.
680      * @tc.expected: step5. the life cycle of the auto launched database is prolonged by the sync operation.
681      */
682     std::this_thread::sleep_for(std::chrono::milliseconds(AUTO_LAUNCH_CHECK_TIME));
683     EXPECT_NE(g_mgr.DeleteKvStore(storeId), OK);
684 
685     std::this_thread::sleep_for(std::chrono::milliseconds(AUTO_LAUNCH_CHECK_TIME));
686     EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
687 
688     EXPECT_EQ(KvStoreDelegateManager::DisableKvStoreAutoLaunch(USER_ID1, APP_ID1, storeId), OK);
689 }
690 }
691 
692 /**
693   * @tc.name: AutoLaunchLifeCycle002
694   * @tc.desc: test the over limits for the enable list.
695   * @tc.type: FUNC
696   * @tc.require:
697   * @tc.author: sunpeng
698   */
699 HWTEST_F(DistributedDBInterfacesAutoLaunchTest, AutoLaunchLifeCycle002, TestSize.Level3)
700 {
701     /**
702      * @tc.steps: step1. Enable the auto launch for 'test_9'.
703      * @tc.steps: step2. Trigger the auto launch.
704      * @tc.steps: step3. Trigger the sync writing operation.
705      * @tc.steps: step4. Check the status of the auto launched database.
706      * @tc.expected: step1. Returns OK.
707      * @tc.expected: step4. The life cycle is prolonged for the writing operation.
708      */
709     DelayAutoLaunchCycle("test_9", true);
710 }
711 
712 /**
713   * @tc.name: AutoLaunchLifeCycle003
714   * @tc.desc: test the life cycle of the auto launched database in the sync reading scene.
715   * @tc.type: FUNC
716   * @tc.require:
717   * @tc.author: sunpeng
718   */
719 HWTEST_F(DistributedDBInterfacesAutoLaunchTest, AutoLaunchLifeCycle003, TestSize.Level3)
720 {
721     /**
722      * @tc.steps: step1. Enable the auto launch for 'test_10'.
723      * @tc.steps: step2. Trigger the auto launch.
724      * @tc.steps: step3. Trigger the sync reading operation.
725      * @tc.steps: step4. Check the status of the auto launched database.
726      * @tc.expected: step1. Returns OK.
727      * @tc.expected: step4. The life cycle is prolonged for the reading operation.
728      */
729     DelayAutoLaunchCycle("test_10", false);
730 }
731