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 ¶m, 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 ¶m)
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 }