1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <gtest/gtest.h>
17 #include "auto_launch.h"
18 #include "db_common.h"
19 #include "db_errno.h"
20 #include "distributeddb_tools_unit_test.h"
21 #include "kv_store_nb_conflict_data.h"
22 #include "kvdb_manager.h"
23 #include "kvdb_pragma.h"
24 #include "log_print.h"
25 #include "platform_specific.h"
26 #include "runtime_config.h"
27 #include "virtual_communicator_aggregator.h"
28 
29 using namespace std;
30 using namespace testing::ext;
31 using namespace DistributedDB;
32 using namespace DistributedDBUnitTest;
33 
34 namespace {
35     const std::string APP_ID = "appId";
36     const std::string USER_ID = "userId";
37     const std::string STORE_ID_0 = "storeId0";
38     const std::string STORE_ID_1 = "storeId1";
39     const std::string STORE_ID_2 = "storeId2";
40     const std::string STORE_ID_3 = "storeId3";
41     const std::string STORE_ID_4 = "storeId4";
42     const std::string STORE_ID_5 = "storeId5";
43     const std::string STORE_ID_6 = "storeId6";
44     const std::string STORE_ID_7 = "storeId7";
45     const std::string STORE_ID_8 = "storeId8";
46     string g_testDir;
47     KvStoreDelegateManager g_mgr(APP_ID, USER_ID);
48     KvStoreConfig g_config;
49     VirtualCommunicatorAggregator *g_communicatorAggregator = nullptr;
50 
51     const int TEST_ENABLE_CNT = 10; // 10 time
52     const int TEST_ONLINE_CNT = 200; // 10 time
53     const int WAIT_TIME = 1000; // 1000ms
54     const int LIFE_CYCLE_TIME = 5000; // 5000ms
55     const int WAIT_SHORT_TIME = 200; // 20ms
56     const Timestamp TIME_ADD = 1000; // not zero is ok
57     const std::string REMOTE_DEVICE_ID = "remote_device";
58     const std::string THIS_DEVICE = "real_device";
59 
60     const Key KEY1{'k', 'e', 'y', '1'};
61     const Key KEY2{'k', 'e', 'y', '2'};
62     const Value VALUE1{'v', 'a', 'l', 'u', 'e', '1'};
63     const Value VALUE2{'v', 'a', 'l', 'u', 'e', '2'};
64     KvDBProperties g_propA;
65     KvDBProperties g_propB;
66     KvDBProperties g_propC;
67     KvDBProperties g_propD;
68     KvDBProperties g_propE;
69     KvDBProperties g_propF;
70     KvDBProperties g_propG;
71     KvDBProperties g_propH;
72     KvDBProperties g_propI;
73     std::string g_identifierA;
74     std::string g_identifierB;
75     std::string g_identifierC;
76     std::string g_identifierD;
77     std::string g_identifierE;
78     std::string g_identifierF;
79     std::string g_identifierG;
80     std::string g_identifierH;
81     std::string g_identifierI;
82     std::string g_dualIdentifierA;
83     std::string g_dualIdentifierB;
84     std::string g_dualIdentifierC;
85     std::string g_dualIdentifierD;
86     std::string g_dualIdentifierE;
87     std::string g_dualIdentifierF;
88     std::string g_dualIdentifierG;
89     std::string g_dualIdentifierH;
90     std::string g_dualIdentifierI;
91 }
92 
93 class DistributedDBAutoLaunchUnitTest : public testing::Test {
94 public:
95     static void SetUpTestCase(void);
96     static void TearDownTestCase(void);
97     void SetUp();
TearDown()98     void TearDown() {};
99 };
100 
SetUpTestCase(void)101 void DistributedDBAutoLaunchUnitTest::SetUpTestCase(void)
102 {
103     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
104     g_config.dataDir = g_testDir;
105     g_mgr.SetKvStoreConfig(g_config);
106 
107     string dir = g_testDir;
108     DIR *dirTmp = opendir(dir.c_str());
109     if (dirTmp == nullptr) {
110         OS::MakeDBDirectory(dir);
111     } else {
112         closedir(dirTmp);
113     }
114     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(
115         g_testDir + "/" + DBCommon::TransferStringToHex(g_identifierA) + "/single_ver") != 0) {
116         LOGE("rm test db files error!");
117     }
118     g_communicatorAggregator = new (std::nothrow) VirtualCommunicatorAggregator();
119     ASSERT_TRUE(g_communicatorAggregator != nullptr);
120     RuntimeContext::GetInstance()->SetCommunicatorAggregator(g_communicatorAggregator);
121 }
122 
TearDownTestCase(void)123 void DistributedDBAutoLaunchUnitTest::TearDownTestCase(void)
124 {
125     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(
126         g_testDir + "/" + DBCommon::TransferStringToHex(g_identifierA) + "/single_ver") != 0) {
127         LOGE("rm test db files error!");
128     }
129     RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
130 }
131 
GetProperty(KvDBProperties & prop,std::string & identifier,std::string storeId,std::string & dualIdentifier)132 static void GetProperty(KvDBProperties &prop, std::string &identifier, std::string storeId, std::string &dualIdentifier)
133 {
134     prop.SetStringProp(KvDBProperties::USER_ID, USER_ID);
135     prop.SetStringProp(KvDBProperties::APP_ID, APP_ID);
136     prop.SetStringProp(KvDBProperties::STORE_ID, storeId);
137     identifier = DBCommon::TransferHashString(USER_ID + "-" + APP_ID + "-" + storeId);
138     prop.SetStringProp(KvDBProperties::IDENTIFIER_DATA, identifier);
139     dualIdentifier = DBCommon::TransferHashString(APP_ID + "-" + storeId);
140     prop.SetStringProp(KvDBProperties::DUAL_TUPLE_IDENTIFIER_DATA, dualIdentifier);
141     std::string identifierDirA = DBCommon::TransferStringToHex(identifier);
142     prop.SetStringProp(KvDBProperties::IDENTIFIER_DIR, identifierDirA);
143     prop.SetStringProp(KvDBProperties::DATA_DIR, g_testDir);
144     prop.SetIntProp(KvDBProperties::DATABASE_TYPE, KvDBProperties::SINGLE_VER_TYPE_SQLITE);
145     prop.SetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, true);
146     prop.SetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, false);
147 }
148 
SetUp(void)149 void DistributedDBAutoLaunchUnitTest::SetUp(void)
150 {
151     DistributedDBToolsUnitTest::PrintTestCaseInfo();
152     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(
153         g_testDir + "/" + DBCommon::TransferStringToHex(g_identifierA) + "/single_ver") != 0) {
154         LOGE("rm test db files error!");
155     }
156     GetProperty(g_propA, g_identifierA, STORE_ID_0, g_dualIdentifierA);
157     GetProperty(g_propB, g_identifierB, STORE_ID_1, g_dualIdentifierB);
158     GetProperty(g_propC, g_identifierC, STORE_ID_2, g_dualIdentifierC);
159     GetProperty(g_propD, g_identifierD, STORE_ID_3, g_dualIdentifierD);
160     GetProperty(g_propE, g_identifierE, STORE_ID_4, g_dualIdentifierE);
161     GetProperty(g_propF, g_identifierF, STORE_ID_5, g_dualIdentifierF);
162     GetProperty(g_propG, g_identifierG, STORE_ID_6, g_dualIdentifierG);
163     GetProperty(g_propH, g_identifierH, STORE_ID_7, g_dualIdentifierH);
164     GetProperty(g_propI, g_identifierI, STORE_ID_8, g_dualIdentifierI);
165 }
166 
PutSyncData(const KvDBProperties & prop,const Key & key,const Value & value)167 static void PutSyncData(const KvDBProperties &prop, const Key &key, const Value &value)
168 {
169     int errCode = E_OK;
170     auto kvStore = static_cast<SQLiteSingleVerNaturalStore *>(KvDBManager::OpenDatabase(prop, errCode));
171     ASSERT_NE(kvStore, nullptr);
172     auto *connection = kvStore->GetDBConnection(errCode);
173     ASSERT_NE(connection, nullptr);
174     std::vector<DataItem> vect;
175     Timestamp time;
176     kvStore->GetMaxTimestamp(time);
177     time += TIME_ADD;
178     LOGD("time:%" PRIu64, time);
179     vect.push_back({key, value, time, 0, DBCommon::TransferHashString(REMOTE_DEVICE_ID)});
180     EXPECT_EQ(DistributedDBToolsUnitTest::PutSyncDataTest(kvStore, vect, REMOTE_DEVICE_ID), E_OK);
181     RefObject::DecObjRef(kvStore);
182     connection->Close();
183     connection = nullptr;
184 }
185 
SetLifeCycleTime(const KvDBProperties & prop)186 static void SetLifeCycleTime(const KvDBProperties &prop)
187 {
188     int errCode = E_OK;
189     auto kvStore = static_cast<SQLiteSingleVerNaturalStore *>(KvDBManager::OpenDatabase(prop, errCode));
190     ASSERT_NE(kvStore, nullptr);
191     auto *connection = kvStore->GetDBConnection(errCode);
192     ASSERT_NE(connection, nullptr);
193     uint32_t time = LIFE_CYCLE_TIME;
194     EXPECT_EQ(connection->Pragma(PRAGMA_SET_AUTO_LIFE_CYCLE, static_cast<PragmaData>(&time)), E_OK);
195     RefObject::DecObjRef(kvStore);
196     connection->Close();
197     connection = nullptr;
198 }
199 
200 /**
201  * @tc.name: AutoLaunch001
202  * @tc.desc: basic enable/disable func
203  * @tc.type: FUNC
204  * @tc.require: AR000E8S2T
205  * @tc.author: wangchuanqing
206  */
207 HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch001, TestSize.Level3)
208 {
209     /**
210      * @tc.steps: step1. right param A enable
211      * @tc.expected: step1. success.
212      */
213     AutoLaunchOption option;
214     option.notifier = nullptr;
215     int errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propA, nullptr, option);
216     EXPECT_TRUE(errCode == E_OK);
217 
218     /**
219      * @tc.steps: step2. wrong param B enable
220      * @tc.expected: step2. failed.
221      */
222     g_propB.SetStringProp(KvDBProperties::IDENTIFIER_DATA, "");
223     errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propB, nullptr, option);
224     EXPECT_TRUE(errCode != E_OK);
225 
226     /**
227      * @tc.steps: step3. right param C enable
228      * @tc.expected: step3. success.
229      */
230     errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propC, nullptr, option);
231     EXPECT_TRUE(errCode == E_OK);
232 
233     /**
234      * @tc.steps: step4. param A disable
235      * @tc.expected: step4. E_OK.
236      */
237     errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierA, g_dualIdentifierA, USER_ID);
238     EXPECT_TRUE(errCode == E_OK);
239 
240     /**
241      * @tc.steps: step5. param B disable
242      * @tc.expected: step5. -E_NOT_FOUND.
243      */
244     errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierB, g_dualIdentifierB, USER_ID);
245     EXPECT_TRUE(errCode == -E_NOT_FOUND);
246 
247     /**
248      * @tc.steps: step6. param C disable
249      * @tc.expected: step6. E_OK.
250      */
251     errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierC, g_dualIdentifierC, USER_ID);
252     EXPECT_TRUE(errCode == E_OK);
253 }
254 
255 /**
256  * @tc.name: AutoLaunch002
257  * @tc.desc: online callback
258  * @tc.type: FUNC
259  * @tc.require: AR000E8S2T
260  * @tc.author: wangchuanqing
261  */
262 HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch002, TestSize.Level3)
263 {
264     std::mutex cvMutex;
265     std::condition_variable cv;
266     bool finished = false;
267     std::map<const std::string, AutoLaunchStatus> statusMap;
268 
269     auto notifier = [&cvMutex, &cv, &finished, &statusMap] (const std::string &userId, const std::string &appId,
__anonaf6a41ef0202(const std::string &userId, const std::string &appId, const std::string &storeId, AutoLaunchStatus status) 270         const std::string &storeId, AutoLaunchStatus status) {
271             LOGD("int AutoLaunch002 notifier status:%d", status);
272             std::string identifier = DBCommon::TransferHashString(userId + "-" + appId + "-" + storeId);
273             std::unique_lock<std::mutex> lock(cvMutex);
274             statusMap[identifier] = status;
275             LOGD("int AutoLaunch002 notifier statusMap.size():%zu", statusMap.size());
276             if (statusMap.size() == 2) { // A and B
277                 finished = true;
278                 cv.notify_one();
279             }
280         };
281     KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest;
282     ASSERT_TRUE(observer != nullptr);
283     /**
284      * @tc.steps: step1. right param A B enable
285      * @tc.expected: step1. success.
286      */
287     AutoLaunchOption option;
288     option.notifier = nullptr;
289     option.observer = observer;
290     EXPECT_TRUE(RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propA, notifier, option) == E_OK);
291     EXPECT_TRUE(RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propB, notifier, option) == E_OK);
292 
293     /**
294      * @tc.steps: step2. RunOnConnectCallback
295      * @tc.expected: step2. success.
296      */
297     g_communicatorAggregator->RunOnConnectCallback(REMOTE_DEVICE_ID, true);
298     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
299 
300     /**
301      * @tc.steps: step3. PutSyncData
302      * @tc.expected: step3. notifier WRITE_OPENED
303      */
304     PutSyncData(g_propA, KEY1, VALUE1);
305     PutSyncData(g_propB, KEY1, VALUE1);
306     {
307         std::unique_lock<std::mutex> lock(cvMutex);
__anonaf6a41ef0302null308         cv.wait(lock, [&finished] {return finished;});
309         EXPECT_TRUE(statusMap[g_identifierA] == WRITE_OPENED);
310         EXPECT_TRUE(statusMap[g_identifierB] == WRITE_OPENED);
311         statusMap.clear();
312         finished = false;
313     }
314     EXPECT_TRUE(observer->GetCallCount() == 2); // A and B
315     delete observer;
316     /**
317      * @tc.steps: step4. param A B disable
318      * @tc.expected: step4. notifier WRITE_CLOSED
319      */
320     EXPECT_TRUE(RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierA, g_dualIdentifierA, USER_ID)
321         == E_OK);
322     EXPECT_TRUE(RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierB, g_dualIdentifierB, USER_ID)
323         == E_OK);
324 
325     std::unique_lock<std::mutex> lock(cvMutex);
__anonaf6a41ef0402null326     cv.wait(lock, [&finished] {return finished;});
327     EXPECT_TRUE(statusMap[g_identifierA] == WRITE_CLOSED);
328     EXPECT_TRUE(statusMap[g_identifierB] == WRITE_CLOSED);
329     g_communicatorAggregator->RunOnConnectCallback(REMOTE_DEVICE_ID, false);
330 }
331 
332 /**
333  * @tc.name: AutoLaunch003
334  * @tc.desc: CommunicatorLackCallback
335  * @tc.type: FUNC
336  * @tc.require: AR000E8S2T
337  * @tc.author: wangchuanqing
338  */
339 HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch003, TestSize.Level3)
340 {
341     std::mutex cvMutex;
342     std::condition_variable cv;
343     bool finished = false;
344     std::map<const std::string, AutoLaunchStatus> statusMap;
345 
346     auto notifier = [&cvMutex, &cv, &finished, &statusMap] (const std::string &userId, const std::string &appId,
__anonaf6a41ef0502(const std::string &userId, const std::string &appId, const std::string &storeId, AutoLaunchStatus status) 347         const std::string &storeId, AutoLaunchStatus status) {
348             LOGD("int AutoLaunch002 notifier status:%d", status);
349             std::string identifier = DBCommon::TransferHashString(userId + "-" + appId + "-" + storeId);
350             std::unique_lock<std::mutex> lock(cvMutex);
351             statusMap[identifier] = status;
352             LOGD("int AutoLaunch002 notifier statusMap.size():%zu", statusMap.size());
353             finished = true;
354             cv.notify_one();
355         };
356     KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest;
357     ASSERT_TRUE(observer != nullptr);
358 
359     /**
360      * @tc.steps: step1. right param A B enable
361      * @tc.expected: step1. success.
362      */
363     AutoLaunchOption option;
364     option.notifier = nullptr;
365     option.observer = observer;
366     int errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propA, notifier, option);
367     EXPECT_TRUE(errCode == E_OK);
368     errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propB, notifier, option);
369     EXPECT_TRUE(errCode == E_OK);
370 
371     /**
372      * @tc.steps: step2. RunCommunicatorLackCallback
373      * @tc.expected: step2. success.
374      */
375     LabelType label(g_identifierA.begin(), g_identifierA.end());
376     g_communicatorAggregator->RunCommunicatorLackCallback(label);
377     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
378 
379     /**
380      * @tc.steps: step3. PutSyncData
381      * @tc.expected: step3. notifier WRITE_OPENED
382      */
383     PutSyncData(g_propA, KEY2, VALUE2);
384     {
385         std::unique_lock<std::mutex> lock(cvMutex);
__anonaf6a41ef0602null386         cv.wait(lock, [&finished] {return finished;});
387         EXPECT_TRUE(statusMap[g_identifierA] == WRITE_OPENED);
388         statusMap.clear();
389         finished = false;
390     }
391     EXPECT_TRUE(observer->GetCallCount() == 1); // only A
392     delete observer;
393     /**
394      * @tc.steps: step4. param A B disable
395      * @tc.expected: step4. notifier WRITE_CLOSED
396      */
397     errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierB, g_dualIdentifierB, USER_ID);
398     EXPECT_TRUE(errCode == E_OK);
399     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
400     errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierA, g_dualIdentifierA, USER_ID);
401     EXPECT_TRUE(errCode == E_OK);
402 
403     std::unique_lock<std::mutex> lock(cvMutex);
__anonaf6a41ef0702null404     cv.wait(lock, [&finished] {return finished;});
405     EXPECT_TRUE(statusMap[g_identifierA] == WRITE_CLOSED);
406     EXPECT_TRUE(statusMap.size() == 1);
407 }
408 
409 /**
410  * @tc.name: AutoLaunch004
411  * @tc.desc: basic enable/disable func
412  * @tc.type: FUNC
413  * @tc.require: AR000E8S2T
414  * @tc.author: wangchuanqing
415  */
416 HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch004, TestSize.Level3)
417 {
418     /**
419      * @tc.steps: step1. right param A~H enable
420      * @tc.expected: step1. success.
421      */
422     AutoLaunchOption option;
423     option.notifier = nullptr;
424     EXPECT_TRUE(RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propA, nullptr, option) == E_OK);
425     EXPECT_TRUE(RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propB, nullptr, option) == E_OK);
426     EXPECT_TRUE(RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propC, nullptr, option) == E_OK);
427     EXPECT_TRUE(RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propD, nullptr, option) == E_OK);
428     EXPECT_TRUE(RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propE, nullptr, option) == E_OK);
429     EXPECT_TRUE(RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propF, nullptr, option) == E_OK);
430     EXPECT_TRUE(RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propG, nullptr, option) == E_OK);
431     EXPECT_TRUE(RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propH, nullptr, option) == E_OK);
432 
433     /**
434      * @tc.steps: step2. right param I enable
435      * @tc.expected: step2. -E_MAX_LIMITS.
436      */
437     int errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propI, nullptr, option);
438     EXPECT_TRUE(errCode == -E_MAX_LIMITS);
439 
440     /**
441      * @tc.steps: step3. param A disable
442      * @tc.expected: step3. E_OK.
443      */
444     errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierA, g_dualIdentifierA, USER_ID);
445     EXPECT_TRUE(errCode == E_OK);
446 
447     /**
448      * @tc.steps: step4. right param I enable
449      * @tc.expected: step4. E_OK.
450      */
451     errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propI, nullptr, option);
452     EXPECT_TRUE(errCode == E_OK);
453 
454     /**
455      * @tc.steps: step6. param B~I disable
456      * @tc.expected: step6. E_OK.
457      */
458     errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierB, g_dualIdentifierB, USER_ID);
459     EXPECT_TRUE(errCode == E_OK);
460     errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierC, g_dualIdentifierC, USER_ID);
461     EXPECT_TRUE(errCode == E_OK);
462     errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierD, g_dualIdentifierD, USER_ID);
463     EXPECT_TRUE(errCode == E_OK);
464     errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierE, g_dualIdentifierE, USER_ID);
465     EXPECT_TRUE(errCode == E_OK);
466     errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierF, g_dualIdentifierF, USER_ID);
467     EXPECT_TRUE(errCode == E_OK);
468     errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierG, g_dualIdentifierG, USER_ID);
469     EXPECT_TRUE(errCode == E_OK);
470     errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierH, g_dualIdentifierH, USER_ID);
471     EXPECT_TRUE(errCode == E_OK);
472     errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierI, g_dualIdentifierI, USER_ID);
473     EXPECT_TRUE(errCode == E_OK);
474 }
475 
476 /**
477  * @tc.name: AutoLaunch005
478  * @tc.desc: online device before enable
479  * @tc.type: FUNC
480  * @tc.require: AR000E8S2T
481  * @tc.author: wangchuanqing
482  */
483 HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch005, TestSize.Level3)
484 {
485     std::mutex cvMutex;
486     std::condition_variable cv;
487     bool finished = false;
488     std::map<const std::string, AutoLaunchStatus> statusMap;
489 
490     auto notifier = [&cvMutex, &cv, &finished, &statusMap] (const std::string &userId, const std::string &appId,
__anonaf6a41ef0802(const std::string &userId, const std::string &appId, const std::string &storeId, AutoLaunchStatus status) 491         const std::string &storeId, AutoLaunchStatus status) {
492             LOGD("int AutoLaunch002 notifier status:%d", status);
493             std::string identifier = DBCommon::TransferHashString(userId + "-" + appId + "-" + storeId);
494             std::unique_lock<std::mutex> lock(cvMutex);
495             statusMap[identifier] = status;
496             LOGD("int AutoLaunch002 notifier statusMap.size():%zu", statusMap.size());
497             finished = true;
498             cv.notify_one();
499         };
500     KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest;
501     ASSERT_TRUE(observer != nullptr);
502     /**
503      * @tc.steps: step1. RunOnConnectCallback
504      * @tc.expected: step1. success.
505      */
506     g_communicatorAggregator->RunOnConnectCallback(REMOTE_DEVICE_ID, true);
507     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
508 
509     /**
510      * @tc.steps: step2. right param A enable
511      * @tc.expected: step2. success.
512      */
513     AutoLaunchOption option;
514     option.notifier = nullptr;
515     option.observer = observer;
516     int errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propA, notifier, option);
517     EXPECT_TRUE(errCode == E_OK);
518 
519     /**
520      * @tc.steps: step3. PutSyncData
521      * @tc.expected: step3. notifier WRITE_OPENED
522      */
523     PutSyncData(g_propA, KEY1, VALUE1);
524     {
525         std::unique_lock<std::mutex> lock(cvMutex);
__anonaf6a41ef0902null526         cv.wait(lock, [&finished] {return finished;});
527         EXPECT_TRUE(statusMap[g_identifierA] == WRITE_OPENED);
528         statusMap.clear();
529         finished = false;
530     }
531     EXPECT_TRUE(observer->GetCallCount() == 1); // only A
532     /**
533      * @tc.steps: step4. param A  disable
534      * @tc.expected: step4. notifier WRITE_CLOSED
535      */
536     std::string identifierA = g_propA.GetStringProp(KvDBProperties::DUAL_TUPLE_IDENTIFIER_DATA, "");
537     std::string userIdA = g_propA.GetStringProp(KvDBProperties::USER_ID, "");
538     errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierA, g_dualIdentifierB, USER_ID);
539     EXPECT_TRUE(errCode == E_OK);
540 
541     std::unique_lock<std::mutex> lock(cvMutex);
__anonaf6a41ef0a02null542     cv.wait(lock, [&finished] {return finished;});
543     EXPECT_TRUE(statusMap[g_identifierA] == WRITE_CLOSED);
544     delete observer;
545     g_communicatorAggregator->RunOnConnectCallback(REMOTE_DEVICE_ID, false);
546 }
547 
548 /**
549  * @tc.name: AutoLaunch006
550  * @tc.desc: online callback
551  * @tc.type: FUNC
552  * @tc.require: AR000E8S2T
553  * @tc.author: wangchuanqing
554  */
555 HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch006, TestSize.Level3)
556 {
557     auto notifier = [] (const std::string &userId, const std::string &appId,
__anonaf6a41ef0b02(const std::string &userId, const std::string &appId, const std::string &storeId, AutoLaunchStatus status) 558         const std::string &storeId, AutoLaunchStatus status) {
559             LOGD("int AutoLaunch006 notifier status:%d", status);
560         };
561     KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest;
562     ASSERT_TRUE(observer != nullptr);
563     std::mutex cvLock;
564     std::condition_variable cv;
565     bool threadIsWorking = true;
__anonaf6a41ef0c02() 566     thread aggregatorThread([&cvLock, &cv, &threadIsWorking]() {
567             LabelType label(g_identifierA.begin(), g_identifierA.end());
568             for (int i = 0; i < TEST_ONLINE_CNT; i++) {
569                 g_communicatorAggregator->RunOnConnectCallback(REMOTE_DEVICE_ID, true);
570                 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_SHORT_TIME));
571                 g_communicatorAggregator->RunOnConnectCallback(REMOTE_DEVICE_ID, false);
572                 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_SHORT_TIME));
573                 g_communicatorAggregator->RunCommunicatorLackCallback(label);
574                 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_SHORT_TIME));
575                 LOGD("AutoLaunch006 thread i:%d", i);
576             }
577             std::unique_lock<std::mutex> lock(cvLock);
578             threadIsWorking = false;
579             cv.notify_one();
580         });
581     aggregatorThread.detach();
582     AutoLaunchOption option;
583     option.notifier = nullptr;
584     option.observer = observer;
585     for (int i = 0; i < TEST_ENABLE_CNT; i++) {
586         int errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propA, notifier, option);
587         EXPECT_TRUE(errCode == E_OK);
588         errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propB, notifier, option);
589         EXPECT_TRUE(errCode == E_OK);
590 
591         errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierA, g_dualIdentifierA, USER_ID);
592         EXPECT_TRUE(errCode == E_OK);
593         errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierB, g_dualIdentifierB, USER_ID);
594         EXPECT_TRUE(errCode == E_OK);
595         LOGD("AutoLaunch006 disable i:%d", i);
596     }
597     std::unique_lock<std::mutex> lock(cvLock);
__anonaf6a41ef0d02null598     cv.wait(lock, [&threadIsWorking] { return !threadIsWorking; });
599 
600     delete observer;
601     observer = nullptr;
602     g_communicatorAggregator->RunOnConnectCallback(REMOTE_DEVICE_ID, false);
603 }
604 
605 namespace {
606 std::mutex g_cvMutex;
607 std::condition_variable g_cv;
608 bool g_finished = false;
609 std::map<const std::string, AutoLaunchStatus> g_statusMap;
ConflictNotifierCallback(const KvStoreNbConflictData & data)610 void ConflictNotifierCallback(const KvStoreNbConflictData &data)
611 {
612     LOGD("in ConflictNotifierCallback");
613     Key key;
614     Value oldValue;
615     Value newValue;
616     data.GetKey(key);
617     data.GetValue(KvStoreNbConflictData::ValueType::OLD_VALUE, oldValue);
618     data.GetValue(KvStoreNbConflictData::ValueType::NEW_VALUE, newValue);
619     EXPECT_EQ(key, KEY1);
620     EXPECT_EQ(oldValue, VALUE1);
621     EXPECT_EQ(newValue, VALUE2);
622     g_finished = true;
623     g_cv.notify_one();
624 }
625 
TestAutoLaunchNotifier(const std::string & userId,const std::string & appId,const std::string & storeId,AutoLaunchStatus status)626 void TestAutoLaunchNotifier(const std::string &userId, const std::string &appId, const std::string &storeId,
627     AutoLaunchStatus status)
628 {
629     LOGD("int AutoLaunchNotifier, status:%d", status);
630     std::string identifier = DBCommon::TransferHashString(userId + "-" + appId + "-" + storeId);
631     std::unique_lock<std::mutex> lock(g_cvMutex);
632     g_statusMap[identifier] = status;
633     g_finished = true;
634     g_cv.notify_one();
635 };
636 
AutoLaunchCallBack(const std::string & identifier,AutoLaunchParam & param,KvStoreObserverUnitTest * observer,bool ret)637 bool AutoLaunchCallBack(const std::string &identifier, AutoLaunchParam &param, KvStoreObserverUnitTest *observer,
638     bool ret)
639 {
640     LOGD("int AutoLaunchCallBack");
641     EXPECT_TRUE(identifier == g_identifierA);
642     param.userId = USER_ID;
643     param.appId = APP_ID;
644     param.storeId = STORE_ID_0;
645     CipherPassword passwd;
646     param.option = {true, false, CipherType::DEFAULT, passwd, "", false, g_testDir, observer,
647         CONFLICT_FOREIGN_KEY_ONLY, ConflictNotifierCallback};
648     param.notifier = TestAutoLaunchNotifier;
649     return ret;
650 }
651 
AutoLaunchCallBackBadParam(const std::string & identifier,AutoLaunchParam & param)652 bool AutoLaunchCallBackBadParam(const std::string &identifier, AutoLaunchParam &param)
653 {
654     LOGD("int AutoLaunchCallBack");
655     EXPECT_TRUE(identifier == g_identifierA);
656     param.notifier = TestAutoLaunchNotifier;
657     return true;
658 }
659 }
660 
661 /**
662  * @tc.name: AutoLaunch007
663  * @tc.desc: enhancement callback return true
664  * @tc.type: FUNC
665  * @tc.require: AR000EPARJ
666  * @tc.author: wangchuanqing
667  */
668 HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch007, TestSize.Level3)
669 {
670     KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest;
671     ASSERT_TRUE(observer != nullptr);
672     /**
673      * @tc.steps: step1. SetAutoLaunchRequestCallback
674      * @tc.expected: step1. success.
675      */
676     RuntimeContext::GetInstance()->SetAutoLaunchRequestCallback(
677         std::bind(AutoLaunchCallBack, std::placeholders::_1, std::placeholders::_2, observer, true),
678         DBTypeInner::DB_KV);
679     /**
680      * @tc.steps: step2. RunCommunicatorLackCallback
681      * @tc.expected: step2. success.
682      */
683     LabelType label(g_identifierA.begin(), g_identifierA.end());
684     g_communicatorAggregator->RunCommunicatorLackCallback(label);
685     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
686     /**
687      * @tc.steps: step3. PutSyncData key1 value1
688      * @tc.expected: step3. notifier WRITE_OPENED
689      */
690     PutSyncData(g_propA, KEY1, VALUE1);
691     {
692         std::unique_lock<std::mutex> lock(g_cvMutex);
__anonaf6a41ef0f02null693         g_cv.wait(lock, [] {return g_finished;});
694         EXPECT_TRUE(g_statusMap[g_identifierA] == WRITE_OPENED);
695         g_statusMap.clear();
696         g_finished = false;
697     }
698     EXPECT_TRUE(observer->GetCallCount() == 1); // only A
699     /**
700      * @tc.steps: step4. PutSyncData key1 value2
701      * @tc.expected: step4. ConflictNotifierCallback
702      */
703     PutSyncData(g_propA, KEY1, VALUE2);
704     {
705         std::unique_lock<std::mutex> lock(g_cvMutex);
__anonaf6a41ef1002null706         g_cv.wait(lock, [] {return g_finished;});
707         g_finished = false;
708     }
709     /**
710      * @tc.steps: step5. wait life cycle ,db close
711      * @tc.expected: step5. notifier WRITE_CLOSED
712      */
713     SetLifeCycleTime(g_propA);
714     {
715         std::unique_lock<std::mutex> lock(g_cvMutex);
__anonaf6a41ef1102null716         g_cv.wait(lock, [] {return g_finished;});
717         EXPECT_TRUE(g_statusMap[g_identifierA] == WRITE_CLOSED);
718         g_statusMap.clear();
719         g_finished = false;
720     }
721     RuntimeContext::GetInstance()->SetAutoLaunchRequestCallback(nullptr, DBTypeInner::DB_KV);
722     delete observer;
723 }
724 
725 /**
726  * @tc.name: AutoLaunch008
727  * @tc.desc: enhancement callback return false
728  * @tc.type: FUNC
729  * @tc.require: AR000EPARJ
730  * @tc.author: wangchuanqing
731  */
732 HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch008, TestSize.Level3)
733 {
734     KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest;
735     ASSERT_TRUE(observer != nullptr);
736     /**
737      * @tc.steps: step1. SetAutoLaunchRequestCallback
738      * @tc.expected: step1. success.
739      */
740     RuntimeContext::GetInstance()->SetAutoLaunchRequestCallback(
741         std::bind(AutoLaunchCallBack, std::placeholders::_1, std::placeholders::_2, observer, false),
742         DBTypeInner::DB_KV);
743     /**
744      * @tc.steps: step2. RunCommunicatorLackCallback
745      * @tc.expected: step2. success.
746      */
747     LabelType label(g_identifierA.begin(), g_identifierA.end());
748     g_communicatorAggregator->RunCommunicatorLackCallback(label);
749     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
750     /**
751      * @tc.steps: step3. PutSyncData key1 value1
752      * @tc.expected: step3. db not open
753      */
754     PutSyncData(g_propA, KEY1, VALUE1);
755     PutSyncData(g_propA, KEY1, VALUE2);
756 
757     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
758     EXPECT_TRUE(observer->GetCallCount() == 0);
759     EXPECT_TRUE(g_finished == false);
760     RuntimeContext::GetInstance()->SetAutoLaunchRequestCallback(nullptr, DBTypeInner::DB_KV);
761     delete observer;
762 }
763 
764 /**
765  * @tc.name: AutoLaunch009
766  * @tc.desc: enhancement callback return bad param
767  * @tc.type: FUNC
768  * @tc.require: AR000EPARJ
769  */
770 HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch009, TestSize.Level3)
771 {
772     KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest;
773     ASSERT_TRUE(observer != nullptr);
774     /**
775      * @tc.steps: step1. SetAutoLaunchRequestCallback
776      * @tc.expected: step1. success.
777      */
778     RuntimeContext::GetInstance()->SetAutoLaunchRequestCallback(AutoLaunchCallBackBadParam, DBTypeInner::DB_KV);
779     /**
780      * @tc.steps: step2. RunCommunicatorLackCallback
781      * @tc.expected: step2. success.
782      */
783     LabelType label(g_identifierA.begin(), g_identifierA.end());
784     g_communicatorAggregator->RunCommunicatorLackCallback(label);
785     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
786     /**
787      * @tc.steps: step3. PutSyncData key1 value1
788      * @tc.expected: step3. db not open, notify INVALID_PARAM
789      */
790     PutSyncData(g_propA, KEY1, VALUE1);
791     PutSyncData(g_propA, KEY1, VALUE2);
792     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
793     EXPECT_TRUE(observer->GetCallCount() == 0);
794     {
795         std::unique_lock<std::mutex> lock(g_cvMutex);
__anonaf6a41ef1202null796         g_cv.wait(lock, [] {return g_finished;});
797         EXPECT_TRUE(g_statusMap[DBCommon::TransferHashString("--")] == INVALID_PARAM);
798         g_statusMap.clear();
799         g_finished = false;
800     }
801     RuntimeContext::GetInstance()->SetAutoLaunchRequestCallback(nullptr, DBTypeInner::DB_KV);
802     delete observer;
803 }
804 
805 /**
806  * @tc.name: AutoLaunch010
807  * @tc.desc: enhancement nullptr callback
808  * @tc.type: FUNC
809  * @tc.require: AR000EPARJ
810  * @tc.author: wangchuanqing
811  */
812 HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch010, TestSize.Level3)
813 {
814     KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest;
815     ASSERT_TRUE(observer != nullptr);
816     /**
817      * @tc.steps: step1. SetAutoLaunchRequestCallback, then set nullptr
818      * @tc.expected: step1. success.
819      */
820     RuntimeContext::GetInstance()->SetAutoLaunchRequestCallback(
821         std::bind(AutoLaunchCallBack, std::placeholders::_1, std::placeholders::_2, observer, false),
822         DBTypeInner::DB_KV);
823 
824     RuntimeContext::GetInstance()->SetAutoLaunchRequestCallback(nullptr, DBTypeInner::DB_KV);
825     /**
826      * @tc.steps: step2. RunCommunicatorLackCallback
827      * @tc.expected: step2. success.
828      */
829     LabelType label(g_identifierA.begin(), g_identifierA.end());
830     g_communicatorAggregator->RunCommunicatorLackCallback(label);
831     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
832     /**
833      * @tc.steps: step3. PutSyncData key1 value1
834      * @tc.expected: step3. db not open
835      */
836     PutSyncData(g_propA, KEY1, VALUE1);
837     PutSyncData(g_propA, KEY1, VALUE2);
838     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
839     EXPECT_TRUE(observer->GetCallCount() == 0);
840     EXPECT_TRUE(g_finished == false);
841     RuntimeContext::GetInstance()->SetAutoLaunchRequestCallback(nullptr, DBTypeInner::DB_KV);
842     delete observer;
843 }
844 
845 /**
846  * @tc.name: AutoLaunch011
847  * @tc.desc: enhancement GetKvStoreIdentifier
848  * @tc.type: FUNC
849  * @tc.require: AR000EPARJ
850  * @tc.author: wangchuanqing
851  */
852 HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch011, TestSize.Level3)
853 {
854     EXPECT_EQ(KvStoreDelegateManager::GetKvStoreIdentifier("", APP_ID, STORE_ID_0), "");
855     EXPECT_EQ(RuntimeConfig::GetStoreIdentifier("", APP_ID, STORE_ID_0), "");
856     EXPECT_EQ(KvStoreDelegateManager::GetKvStoreIdentifier(
857         USER_ID, APP_ID, STORE_ID_0), DBCommon::TransferHashString(USER_ID + "-" + APP_ID + "-" + STORE_ID_0));
858     EXPECT_EQ(RuntimeConfig::GetStoreIdentifier(USER_ID, APP_ID, STORE_ID_0),
859         DBCommon::TransferHashString(USER_ID + "-" + APP_ID + "-" + STORE_ID_0));
860 }
861 
862 /**
863  * @tc.name: AutoLaunch012
864  * @tc.desc: CommunicatorLackCallback
865  * @tc.type: FUNC
866  * @tc.require: AR000E8S2T
867  * @tc.author: wangchuanqing
868  */
869 HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch012, TestSize.Level3)
870 {
871     /**
872      * @tc.steps: step1. right param A B enable
873      * @tc.expected: step1. success.
874      */
875     AutoLaunchOption option;
876     option.notifier = ConflictNotifierCallback;
877     option.conflictType = CONFLICT_FOREIGN_KEY_ONLY;
878     int errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propA, TestAutoLaunchNotifier, option);
879     EXPECT_TRUE(errCode == E_OK);
880     AutoLaunchOption option1;
881     option1.notifier = nullptr;
882     errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propB, nullptr, option1);
883     EXPECT_TRUE(errCode == E_OK);
884 
885     /**
886      * @tc.steps: step2. RunCommunicatorLackCallback
887      * @tc.expected: step2. success.
888      */
889     LabelType label(g_identifierA.begin(), g_identifierA.end());
890     g_communicatorAggregator->RunCommunicatorLackCallback(label);
891     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
892     PutSyncData(g_propA, KEY1, VALUE1);
893     {
894         std::unique_lock<std::mutex> lock(g_cvMutex);
__anonaf6a41ef1302null895         g_cv.wait(lock, [] {return g_finished;});
896         EXPECT_TRUE(g_statusMap[g_identifierA] == WRITE_OPENED);
897         g_statusMap.clear();
898         g_finished = false;
899     }
900     /**
901      * @tc.steps: step3. PutSyncData key1 value2
902      * @tc.expected: step3. ConflictNotifierCallback
903      */
904     PutSyncData(g_propA, KEY1, VALUE2);
905     {
906         std::unique_lock<std::mutex> lock(g_cvMutex);
__anonaf6a41ef1402null907         g_cv.wait(lock, [] {return g_finished;});
908         g_finished = false;
909     }
910     /**
911      * @tc.steps: step4. wait life cycle ,db close
912      * @tc.expected: step4. notifier WRITE_CLOSED
913      */
914     SetLifeCycleTime(g_propA);
915     {
916         std::unique_lock<std::mutex> lock(g_cvMutex);
__anonaf6a41ef1502null917         g_cv.wait(lock, [] {return g_finished;});
918         EXPECT_TRUE(g_statusMap[g_identifierA] == WRITE_CLOSED);
919         g_statusMap.clear();
920         g_finished = false;
921     }
922     /**
923      * @tc.steps: step5. param A B disable
924      * @tc.expected: step5. OK
925      */
926     std::string identifierA = g_propA.GetStringProp(KvDBProperties::DUAL_TUPLE_IDENTIFIER_DATA, "");
927     std::string userIdA = g_propA.GetStringProp(KvDBProperties::USER_ID, "");
928     std::string identifierB = g_propB.GetStringProp(KvDBProperties::DUAL_TUPLE_IDENTIFIER_DATA, "");
929     std::string userIdB = g_propB.GetStringProp(KvDBProperties::USER_ID, "");
930     errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierB, g_dualIdentifierB, USER_ID);
931     EXPECT_TRUE(errCode == E_OK);
932     errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierA, g_dualIdentifierA, USER_ID);
933     EXPECT_TRUE(errCode == E_OK);
934 }
935 
936 /**
937  * @tc.name: AutoLaunch013
938  * @tc.desc: online callback
939  * @tc.type: FUNC
940  * @tc.require: AR000E8S2T
941  * @tc.author: wangchuanqing
942  */
943 HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch013, TestSize.Level3)
944 {
945     auto notifier = [] (const std::string &userId, const std::string &appId,
__anonaf6a41ef1602(const std::string &userId, const std::string &appId, const std::string &storeId, AutoLaunchStatus status) 946         const std::string &storeId, AutoLaunchStatus status) {
947             LOGD("int AutoLaunch013 notifier status:%d", status);
948         };
949     /**
950      * @tc.steps: step1. right param b c enable, a SetAutoLaunchRequestCallback
951      * @tc.expected: step1. success.
952      */
953     AutoLaunchOption option;
954     option.notifier = nullptr;
955     EXPECT_TRUE(RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propB, notifier, option) == E_OK);
956     EXPECT_TRUE(RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(g_propC, notifier, option) == E_OK);
957 
958     KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest;
959     ASSERT_TRUE(observer != nullptr);
960     RuntimeContext::GetInstance()->SetAutoLaunchRequestCallback(
961         std::bind(AutoLaunchCallBack, std::placeholders::_1, std::placeholders::_2, observer, true),
962         DBTypeInner::DB_KV);
963 
964     /**
965      * @tc.steps: step2. RunOnConnectCallback RunCommunicatorLackCallback
966      * @tc.expected: step2. success.
967      */
968     g_communicatorAggregator->RunOnConnectCallback(REMOTE_DEVICE_ID, true);
969     LabelType label(g_identifierA.begin(), g_identifierA.end());
970     g_communicatorAggregator->RunCommunicatorLackCallback(label);
971     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
972 
973     /**
974      * @tc.steps: step3. PutSyncData
975      * @tc.expected: step3. notifier WRITE_OPENED
976      */
977     PutSyncData(g_propA, KEY1, VALUE1);
978     PutSyncData(g_propB, KEY1, VALUE1);
979     PutSyncData(g_propC, KEY1, VALUE1);
980     {
981         std::unique_lock<std::mutex> lock(g_cvMutex);
__anonaf6a41ef1702null982         g_cv.wait(lock, [] {return g_finished;});
983         EXPECT_TRUE(g_statusMap[g_identifierA] == WRITE_OPENED);
984         g_statusMap.clear();
985         g_finished = false;
986     }
987     /**
988      * @tc.steps: step4. PutSyncData key1 value2
989      * @tc.expected: step4. ConflictNotifierCallback
990      */
991     PutSyncData(g_propA, KEY1, VALUE2);
992     {
993         std::unique_lock<std::mutex> lock(g_cvMutex);
__anonaf6a41ef1802null994         g_cv.wait(lock, [] {return g_finished;});
995         g_finished = false;
996     }
997     /**
998      * @tc.steps: step5. wait life cycle ,db close
999      * @tc.expected: step5. notifier WRITE_CLOSED
1000      */
1001     SetLifeCycleTime(g_propA);
1002     {
1003         std::unique_lock<std::mutex> lock(g_cvMutex);
__anonaf6a41ef1902null1004         g_cv.wait(lock, [] {return g_finished;});
1005         EXPECT_TRUE(g_statusMap[g_identifierA] == WRITE_CLOSED);
1006         g_statusMap.clear();
1007         g_finished = false;
1008     }
1009     RuntimeContext::GetInstance()->SetAutoLaunchRequestCallback(nullptr, DBTypeInner::DB_KV);
1010     delete observer;
1011     /**
1012      * @tc.steps: step4. param A B disable
1013      * @tc.expected: step4. notifier WRITE_CLOSED
1014      */
1015     EXPECT_TRUE(RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierB, g_dualIdentifierB, USER_ID)
1016         == E_OK);
1017     EXPECT_TRUE(RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(g_identifierC, g_dualIdentifierC, USER_ID)
1018         == E_OK);
1019     g_communicatorAggregator->RunOnConnectCallback(REMOTE_DEVICE_ID, false);
1020 }
1021 
1022 /**
1023  * @tc.name: AutoLaunch014
1024  * @tc.desc: enhancement callback and release auto launch connection
1025  * @tc.type: FUNC
1026  * @tc.require: AR000I0EKP
1027  */
1028 HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch014, TestSize.Level3)
1029 {
1030     /**
1031      * @tc.steps: step1. SetAutoLaunchRequestCallback
1032      * @tc.expected: step1. success.
1033      */
1034     KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest;
1035     ASSERT_TRUE(observer != nullptr);
1036     RuntimeConfig::SetAutoLaunchRequestCallback(
1037         std::bind(AutoLaunchCallBack, std::placeholders::_1, std::placeholders::_2, observer, true), DBType::DB_KV);
1038 
1039     /**
1040      * @tc.steps: step2. RunCommunicatorLackCallback
1041      * @tc.expected: step2. success.
1042      */
1043     LabelType label(g_identifierA.begin(), g_identifierA.end());
1044     g_communicatorAggregator->RunCommunicatorLackCallback(label);
1045     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
1046 
1047     /**
1048      * @tc.steps: step3. PutSyncData key1 value1
1049      * @tc.expected: step3. db open, notify WRITE_OPENED
1050      */
1051     PutSyncData(g_propA, KEY1, VALUE1);
1052     PutSyncData(g_propA, KEY1, VALUE2);
1053     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
1054     EXPECT_EQ(observer->GetCallCount(), 2u); // 2: observer count
1055     {
1056         std::unique_lock<std::mutex> lock(g_cvMutex);
__anonaf6a41ef1a02null1057         g_cv.wait(lock, [] {return g_finished;});
1058         EXPECT_TRUE(g_statusMap[g_identifierA] == WRITE_OPENED);
1059         g_statusMap.clear();
1060         g_finished = false;
1061     }
1062 
1063     /**
1064      * @tc.steps: step4. Release autolaunch db connection
1065      * @tc.expected: step3. success
1066      */
1067     RuntimeConfig::SetAutoLaunchRequestCallback(nullptr, DBType::DB_KV);
1068     RuntimeConfig::ReleaseAutoLaunch(USER_ID, APP_ID, STORE_ID_0, DBType::DB_KV);
1069     EXPECT_EQ(g_statusMap[DBCommon::TransferHashString(USER_ID + "-" + APP_ID + "-" + STORE_ID_0)],
1070         AutoLaunchStatus::WRITE_CLOSED);
1071     delete observer;
1072 }
1073 
1074 /**
1075  * @tc.name: AutoLaunch015
1076  * @tc.desc: release auto launch connection when autolaunch execute
1077  * @tc.type: FUNC
1078  * @tc.require: AR000I0EKP
1079  */
1080 HWTEST_F(DistributedDBAutoLaunchUnitTest, AutoLaunch015, TestSize.Level3)
1081 {
1082     /**
1083      * @tc.steps: step1. SetAutoLaunchRequestCallback
1084      * @tc.expected: step1. success.
1085      */
1086     KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest;
1087     ASSERT_TRUE(observer != nullptr);
1088     RuntimeConfig::SetAutoLaunchRequestCallback(
1089         std::bind(AutoLaunchCallBack, std::placeholders::_1, std::placeholders::_2, observer, true), DBType::DB_KV);
1090 
__anonaf6a41ef1b02() 1091     std::thread th ([&]() {
1092         /**
1093          * @tc.steps: step2. RunCommunicatorLackCallback
1094          * @tc.expected: step2. success.
1095          */
1096         LabelType label(g_identifierA.begin(), g_identifierA.end());
1097         g_communicatorAggregator->RunCommunicatorLackCallback(label);
1098         std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
1099     });
1100 
1101     /**
1102      * @tc.steps: step4. Release autolaunch db connection
1103      * @tc.expected: step3. success
1104      */
1105     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
1106     RuntimeConfig::SetAutoLaunchRequestCallback(nullptr, DBType::DB_KV);
1107     RuntimeConfig::ReleaseAutoLaunch(USER_ID, APP_ID, STORE_ID_0, DBType::DB_KV);
1108 
1109     th.join();
1110     delete observer;
1111 }