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