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