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