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