1 /*
2 * Copyright (c) 2023 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 #ifdef USE_RD_KERNEL
16 #include <fcntl.h>
17 #include <gtest/gtest.h>
18 #include <sys/mman.h>
19 #include <unistd.h>
20
21 #include "db_common.h"
22 #include "distributeddb_data_generate_unit_test.h"
23 #include "distributeddb_tools_unit_test.h"
24 #include "kvdb_manager.h"
25 #include "platform_specific.h"
26 #include "process_system_api_adapter_impl.h"
27 #include "runtime_context.h"
28
29 using namespace testing::ext;
30 using namespace DistributedDB;
31 using namespace DistributedDBUnitTest;
32 using namespace std;
33
34 namespace {
35 enum {
36 SCHEMA_TYPE1 = 1,
37 SCHEMA_TYPE2
38 };
39 // define some variables to init a KvStoreDelegateManager object.
40 KvStoreDelegateManager g_mgr(APP_ID, USER_ID);
41 string g_testDir;
42 KvStoreConfig g_config;
43
44 DBStatus g_kvDelegateStatus = INVALID_ARGS;
45
46 KvStoreNbDelegate *g_kvNbDelegatePtr = nullptr;
47 auto g_kvNbDelegateCallback = bind(&DistributedDBToolsUnitTest::KvStoreNbDelegateCallback,
48 placeholders::_1, placeholders::_2, std::ref(g_kvDelegateStatus), std::ref(g_kvNbDelegatePtr));
49 #ifndef OMIT_JSON
GenerateValidSchemaString(std::string & string,int num=SCHEMA_TYPE1)50 void GenerateValidSchemaString(std::string &string, int num = SCHEMA_TYPE1)
51 {
52 switch (num) {
53 case SCHEMA_TYPE1:
54 string = "{\"SCHEMA_VERSION\":\"1.0\","
55 "\"SCHEMA_MODE\":\"STRICT\","
56 "\"SCHEMA_DEFINE\":{"
57 "\"field_name1\":\"BOOL\","
58 "\"field_name2\":{"
59 "\"field_name3\":\"INTEGER, NOT NULL\","
60 "\"field_name4\":\"LONG, DEFAULT 100\","
61 "\"field_name5\":\"DOUBLE, NOT NULL, DEFAULT 3.14\","
62 "\"field_name6\":\"STRING, NOT NULL, DEFAULT '3.1415'\","
63 "\"field_name7\":[],"
64 "\"field_name8\":{}"
65 "}"
66 "},"
67 "\"SCHEMA_INDEXES\":[\"$.field_name1\", \"$.field_name2.field_name6\"]}";
68 break;
69 case SCHEMA_TYPE2:
70 string = "{\"SCHEMA_VERSION\":\"1.0\","
71 "\"SCHEMA_MODE\":\"STRICT\","
72 "\"SCHEMA_DEFINE\":{"
73 "\"field_name1\":\"LONG, DEFAULT 100\","
74 "\"field_name2\":{"
75 "\"field_name3\":\"INTEGER, NOT NULL\","
76 "\"field_name4\":\"LONG, DEFAULT 100\","
77 "\"field_name5\":\"DOUBLE, NOT NULL, DEFAULT 3.14\","
78 "\"field_name6\":\"STRING, NOT NULL, DEFAULT '3.1415'\""
79 "}"
80 "},"
81 "\"SCHEMA_INDEXES\":[\"$.field_name1\", \"$.field_name2.field_name6\"]}";
82 break;
83 default:
84 return;
85 }
86 }
87 #endif
88 }
89
90 class DistributedDBInterfacesDatabaseRdKernelTest : public testing::Test {
91 public:
92 static void SetUpTestCase(void);
93 static void TearDownTestCase(void);
94 void SetUp();
95 void TearDown();
96 };
97
SetUpTestCase(void)98 void DistributedDBInterfacesDatabaseRdKernelTest::SetUpTestCase(void)
99 {
100 DistributedDBToolsUnitTest::TestDirInit(g_testDir);
101 g_config.dataDir = g_testDir;
102 g_mgr.SetKvStoreConfig(g_config);
103 RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(nullptr);
104 }
105
TearDownTestCase(void)106 void DistributedDBInterfacesDatabaseRdKernelTest::TearDownTestCase(void)
107 {
108 RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(nullptr);
109 }
110
SetUp(void)111 void DistributedDBInterfacesDatabaseRdKernelTest::SetUp(void)
112 {
113 DistributedDBToolsUnitTest::PrintTestCaseInfo();
114 }
115
TearDown(void)116 void DistributedDBInterfacesDatabaseRdKernelTest::TearDown(void)
117 {
118 if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
119 LOGE("rm test db files error!");
120 }
121 }
122
123 /**
124 * @tc.name: GetKvStore003
125 * @tc.desc: Get kv store through different SecurityOption, abnormal or normal.
126 * @tc.type: FUNC
127 * @tc.require: AR000EV1G2
128 * @tc.author: liuwenkai
129 */
130 HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, GetKvStore003, TestSize.Level1)
131 {
132 /**
133 * @tc.steps: step1. Obtain the kvStore through the GetKvStore interface of the delegate manager
134 * using the parameter secOption(abnormal).
135 * @tc.expected: step1. Returns a null kvstore and error code is not OK.
136 */
137 std::shared_ptr<IProcessSystemApiAdapter> g_adapter = std::make_shared<ProcessSystemApiAdapterImpl>();
138 RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(g_adapter);
139 KvStoreNbDelegate::Option option;
140 option.storageEngineType = GAUSSDB_RD;
141 int abnormalNum = -100;
142 option.secOption.securityLabel = abnormalNum;
143 option.secOption.securityFlag = abnormalNum;
144 g_mgr.GetKvStore("distributed_getkvstore_003", option, g_kvNbDelegateCallback);
145 ASSERT_TRUE(g_kvNbDelegatePtr == nullptr);
146 EXPECT_TRUE(g_kvDelegateStatus != OK);
147
148 /**
149 * @tc.steps: step2. Obtain the kvStore through the GetKvStore interface of the delegate manager
150 * using the parameter secOption(normal).
151 * @tc.expected: step2. Returns a non-null kvstore and error code is OK.
152 */
153 option.secOption.securityLabel = S3;
154 option.secOption.securityFlag = 0;
155 g_mgr.GetKvStore("distributed_getkvstore_003", option, g_kvNbDelegateCallback);
156 ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
157 EXPECT_TRUE(g_kvDelegateStatus == OK);
158 KvStoreNbDelegate *kvNbDelegatePtr1 = g_kvNbDelegatePtr;
159
160 /**
161 * @tc.steps: step3. Obtain the kvStore through the GetKvStore interface of the delegate manager
162 * using the parameter secOption(normal but not same as last).
163 * @tc.expected: step3. Returns a null kvstore and error code is not OK.
164 */
165 option.secOption.securityLabel = S3;
166 option.secOption.securityFlag = 1;
167 g_mgr.GetKvStore("distributed_getkvstore_003", option, g_kvNbDelegateCallback);
168 ASSERT_TRUE(g_kvNbDelegatePtr == nullptr);
169 EXPECT_TRUE(g_kvDelegateStatus != OK);
170
171 /**
172 * @tc.steps: step4. Obtain the kvStore through the GetKvStore interface of the delegate manager
173 * using the parameter secOption(normal and same as last).
174 * @tc.expected: step4. Returns a non-null kvstore and error code is OK.
175 */
176 option.secOption.securityLabel = S3;
177 option.secOption.securityFlag = 0;
178 g_mgr.GetKvStore("distributed_getkvstore_003", option, g_kvNbDelegateCallback);
179 ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
180 EXPECT_TRUE(g_kvDelegateStatus == OK);
181
182 string retStoreId = g_kvNbDelegatePtr->GetStoreId();
183 EXPECT_TRUE(retStoreId == "distributed_getkvstore_003");
184
185 EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
186 EXPECT_EQ(g_mgr.CloseKvStore(kvNbDelegatePtr1), OK);
187 g_kvNbDelegatePtr = nullptr;
188 EXPECT_TRUE(g_mgr.DeleteKvStore("distributed_getkvstore_003") == OK);
189 }
190
191 /**
192 * @tc.name: GetKvStore004
193 * @tc.desc: Get kv store parameters with Observer and Notifier, then trigger callback.
194 * @tc.type: FUNC
195 * @tc.require: AR000EV1G2
196 * @tc.author: liuwenkai
197 */
198 HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, GetKvStore004, TestSize.Level1)
199 {
200 /**
201 * @tc.steps: step1. Obtain the kvStore through the GetKvStore interface of the delegate manager
202 * using the parameter observer, notifier, key.
203 * @tc.expected: step1. Returns a non-null kvstore and error code is OK.
204 */
205 KvStoreNbDelegate::Option option;
206 option.storageEngineType = GAUSSDB_RD;
207 KvStoreObserverUnitTest *observer = new (std::nothrow) KvStoreObserverUnitTest;
208 ASSERT_NE(observer, nullptr);
209 Key key;
210 Value value1;
211 Value value2;
212 key.push_back(1);
213 value1.push_back(1);
214 value2.push_back(2);
215 option.key = key;
216 option.observer = observer;
217 option.mode = OBSERVER_CHANGES_NATIVE;
218 int sleepTime = 100;
219 g_mgr.GetKvStore("distributed_getkvstore_004", option, g_kvNbDelegateCallback);
220 ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
221 EXPECT_TRUE(g_kvDelegateStatus == OK);
222
223 /**
224 * @tc.steps: step2. Put(k1,v1) to db and check the observer info.
225 * @tc.expected: step2. Put successfully and trigger notifier callback.
226 */
227 EXPECT_TRUE(g_kvNbDelegatePtr->Put(key, value1) == OK);
228 std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
229 LOGI("observer count:%lu", observer->GetCallCount());
230 EXPECT_TRUE(observer->GetCallCount() == 1);
231
232 /**
233 * @tc.steps: step3. put(k1,v2) to db and check the observer info.
234 * @tc.expected: step3. put successfully
235 */
236 EXPECT_TRUE(g_kvNbDelegatePtr->Put(key, value2) == OK);
237 std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
238 LOGI("observer count:%lu", observer->GetCallCount());
239 EXPECT_TRUE(observer->GetCallCount() == 2);
240
241 EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
242 g_kvNbDelegatePtr = nullptr;
243 delete observer;
244 observer = nullptr;
245 EXPECT_TRUE(g_mgr.DeleteKvStore("distributed_getkvstore_004") == OK);
246 }
247
248 /**
249 * @tc.name: GetKvStore005
250 * @tc.desc: Get kv store parameters with rd shared mode
251 * @tc.type: FUNC
252 * @tc.require:
253 * @tc.author: zhuwentao
254 */
255 HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, GetKvStore005, TestSize.Level1)
256 {
257 /**
258 * @tc.steps: step1. open db with share mode and readOnly is false
259 * @tc.expected: step1. open ok
260 */
261 KvStoreNbDelegate::Option option;
262 option.storageEngineType = GAUSSDB_RD;
263 option.rdconfig.readOnly = false;
264 g_mgr.GetKvStore("distributed_getkvstore_005", option, g_kvNbDelegateCallback);
265 EXPECT_TRUE(g_kvDelegateStatus == OK);
266 ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
267 /**
268 * @tc.steps: step2. Put into the database some data.
269 * @tc.expected: step2. Put returns OK.
270 */
271 std::vector<Key> keys;
272 std::vector<Key> values;
273 uint32_t totalSize = 20u; // 20 items
274 for (size_t i = 0; i < totalSize; i++) {
275 Entry entry;
276 DistributedDBToolsUnitTest::GetRandomKeyValue(entry.key, static_cast<uint32_t>(i + 1));
277 DistributedDBToolsUnitTest::GetRandomKeyValue(entry.value);
278 EXPECT_EQ(g_kvNbDelegatePtr->Put(entry.key, entry.value), OK);
279 keys.push_back(entry.key);
280 values.push_back(entry.value);
281 }
282 /**
283 * @tc.steps: step3. Get kv ok
284 * @tc.expected: step3. returns OK
285 */
286 for (size_t i = 0; i < keys.size(); i++) {
287 Value value;
288 EXPECT_EQ(g_kvNbDelegatePtr->Get(keys[i], value), OK);
289 EXPECT_TRUE(value == values[i]);
290 }
291 EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
292 }
293
294 /**
295 * @tc.name: GetKvStore006
296 * @tc.desc: Get kv store parameters with rd shared mode
297 * @tc.type: FUNC
298 * @tc.require:
299 * @tc.author: zhuwentao
300 */
301 HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, GetKvStore006, TestSize.Level1)
302 {
303 /**
304 * @tc.steps: step1. open db with share mode and readOnly is true
305 * @tc.expected: step1. open ok
306 */
307 KvStoreNbDelegate::Option option;
308 option.storageEngineType = GAUSSDB_RD;
309 option.rdconfig.readOnly = false;
310 /**
311 * @tc.steps: step2. write db handle write data and close
312 * @tc.expected: step2. close ok
313 */
314 g_mgr.GetKvStore("distributed_getkvstore_006", option, g_kvNbDelegateCallback);
315 EXPECT_TRUE(g_kvDelegateStatus == OK);
316 ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
317 Entry entry = {{'1', '2'}};
318 EXPECT_EQ(g_kvNbDelegatePtr->Put(entry.key, entry.value), OK);
319 EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
320
321 /**
322 * @tc.steps: step3. read db handle open
323 * @tc.expected: step3. open ok
324 */
325 option.rdconfig.readOnly = true;
326 g_mgr.GetKvStore("distributed_getkvstore_006", option, g_kvNbDelegateCallback);
327 EXPECT_TRUE(g_kvDelegateStatus == OK);
328 ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
329 /**
330 * @tc.steps: step4. read db handle put entry
331 * @tc.expected: step4. return not ok
332 */
333 EXPECT_EQ(g_kvNbDelegatePtr->Put(entry.key, entry.value), NO_PERMISSION);
334 EXPECT_EQ(g_kvNbDelegatePtr->PutBatch({entry}), NO_PERMISSION);
335 EXPECT_EQ(g_kvNbDelegatePtr->Delete(entry.key), NO_PERMISSION);
336 EXPECT_EQ(g_kvNbDelegatePtr->DeleteBatch({entry.key}), NO_PERMISSION);
337 /**
338 * @tc.steps: step5. read db handle get entry and close
339 * @tc.expected: step5. return not ok
340 */
341 Value value;
342 EXPECT_EQ(g_kvNbDelegatePtr->Get(entry.key, value), OK);
343 EXPECT_TRUE(value == entry.value);
344 EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
345 }
346
347 /**
348 * @tc.name: GetKvStore007
349 * @tc.desc: Get kv store parameters with wrong rd shared mode
350 * @tc.type: FUNC
351 * @tc.require:
352 * @tc.author: zhuwentao
353 */
354 HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, GetKvStore007, TestSize.Level1)
355 {
356 /**
357 * @tc.steps: step1. open db with not share mode and readOnly is true
358 * @tc.expected: step1. open not ok
359 */
360 KvStoreNbDelegate::Option option;
361 option.storageEngineType = GAUSSDB_RD;
362 option.rdconfig.readOnly = true;
363 g_mgr.GetKvStore("distributed_getkvstore_007", option, g_kvNbDelegateCallback);
364 EXPECT_EQ(g_kvDelegateStatus, INVALID_ARGS);
365 ASSERT_EQ(g_kvNbDelegatePtr, nullptr);
366 }
367
368 /**
369 * @tc.name: GetKvStore008
370 * @tc.desc: Get kv store parameters with use Integrity check
371 * @tc.type: FUNC
372 * @tc.require:
373 * @tc.author: zhuwentao
374 */
375 HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, GetKvStore008, TestSize.Level1)
376 {
377 /**
378 * @tc.steps: step1. open db and readOnly is false and IntegrityCheck is true
379 * @tc.expected: step1. open ok
380 */
381 KvStoreNbDelegate::Option option;
382 option.storageEngineType = GAUSSDB_RD;
383 option.isNeedIntegrityCheck = true;
384 option.isNeedRmCorruptedDb = true;
385 g_mgr.GetKvStore("distributed_getkvstore_009", option, g_kvNbDelegateCallback);
386 EXPECT_TRUE(g_kvDelegateStatus == OK);
387 ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
388 EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
389
390 /**
391 * @tc.steps: step2. make db damaged and open db
392 * @tc.expected: step2. open ok
393 */
394 std::string identifier = KvStoreDelegateManager::GetKvStoreIdentifier(USER_ID, APP_ID,
395 "distributed_getkvstore_009");
396 std::string dbFliePath = DistributedDBToolsUnitTest::GetKvNbStoreDirectory(identifier,
397 "single_ver/main/gen_natural_store.db", g_testDir);
398 DistributedDBToolsUnitTest::ModifyDatabaseFile(dbFliePath);
399
400 g_mgr.GetKvStore("distributed_getkvstore_009", option, g_kvNbDelegateCallback);
401 EXPECT_TRUE(g_kvDelegateStatus == OK);
402 ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
403 EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
404 }
405
406 /**
407 * @tc.name: GetKvStore009
408 * @tc.desc: Get kv store parameters use Integrity check and RmCorruptedDb
409 * @tc.type: FUNC
410 * @tc.require:
411 * @tc.author: zhuwentao
412 */
413 HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, GetKvStore009, TestSize.Level1)
414 {
415 /**
416 * @tc.steps: step1. open db and readOnly is false and RmCorruptedDb false
417 * @tc.expected: step1. open ok
418 */
419 KvStoreNbDelegate::Option option;
420 option.storageEngineType = GAUSSDB_RD;
421 option.isNeedIntegrityCheck = true;
422 g_mgr.GetKvStore("distributed_getkvstore_010", option, g_kvNbDelegateCallback);
423 EXPECT_TRUE(g_kvDelegateStatus == OK);
424 ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
425 EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
426
427 g_mgr.GetKvStore("distributed_getkvstore_010", option, g_kvNbDelegateCallback);
428 EXPECT_TRUE(g_kvDelegateStatus == OK);
429 ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
430 EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
431 }
432
433 /**
434 * @tc.name: GetKvStore010
435 * @tc.desc: Get kv store parameters when crcCheck is true and not create db
436 * @tc.type: FUNC
437 * @tc.require:
438 * @tc.author: zhuwentao
439 */
440 HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, GetKvStore010, TestSize.Level1)
441 {
442 /**
443 * @tc.steps: step1. open db
444 * @tc.expected: step1. open not ok
445 */
446 KvStoreNbDelegate::Option option;
447 option.storageEngineType = GAUSSDB_RD;
448 option.createIfNecessary = false;
449 option.isNeedIntegrityCheck = true;
450 option.rdconfig.readOnly = true;
451 g_mgr.GetKvStore("distributed_getkvstore_011", option, g_kvNbDelegateCallback);
452 EXPECT_TRUE(g_kvDelegateStatus == INVALID_ARGS);
453 ASSERT_TRUE(g_kvNbDelegatePtr == nullptr);
454 }
455
456 /**
457 * @tc.name: GetKvStore013
458 * @tc.desc: Get kv store parameters in readOnly mode and RmCorruptedDb is true
459 * @tc.type: FUNC
460 * @tc.require:
461 * @tc.author: zhuwentao
462 */
463 HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, GetKvStore013, TestSize.Level1)
464 {
465 /**
466 * @tc.steps: step1. open db and readOnly is true and RmCorruptedDb true
467 * @tc.expected: step1. open ok
468 */
469 KvStoreNbDelegate::Option option;
470 option.storageEngineType = GAUSSDB_RD;
471 option.isNeedIntegrityCheck = true;
472 option.isNeedRmCorruptedDb = true;
473 option.rdconfig.readOnly = true;
474 g_mgr.GetKvStore("distributed_getkvstore_013", option, g_kvNbDelegateCallback);
475 EXPECT_TRUE(g_kvDelegateStatus == INVALID_ARGS);
476 ASSERT_TRUE(g_kvNbDelegatePtr == nullptr);
477 }
478
479 /**
480 * @tc.name: GetKvStoreWithInvalidOption001
481 * @tc.desc: Get kv store with invalid option.storageEngineType
482 * @tc.type:
483 * @tc.require:
484 * @tc.author: wanyi
485 */
486 HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, GetKvStoreWithInvalidOption001, TestSize.Level1)
487 {
488 /**
489 * @tc.steps: step1. Get kv store with invalid null option.storageEngineType
490 * @tc.expected: step1. INVALID_ARGS
491 */
492 KvStoreNbDelegate::Option option;
493 option.storageEngineType = "";
494 g_mgr.GetKvStore("GetKvStoreWithInvalidOption001", option, g_kvNbDelegateCallback);
495 ASSERT_TRUE(g_kvNbDelegatePtr == nullptr);
496 EXPECT_TRUE(g_kvDelegateStatus == INVALID_ARGS);
497
498 /**
499 * @tc.steps: step2. Get kv store with invalid option.storageEngineType
500 * @tc.expected: step2. INVALID_ARGS
501 */
502 option.storageEngineType = "invalidType";
503 g_mgr.GetKvStore("GetKvStoreWithInvalidOption001", option, g_kvNbDelegateCallback);
504 ASSERT_TRUE(g_kvNbDelegatePtr == nullptr);
505 EXPECT_TRUE(g_kvDelegateStatus == INVALID_ARGS);
506 }
507
508 /**
509 * @tc.name: RepeatCloseKvStore001
510 * @tc.desc: Close the kv store repeatedly and check the database.
511 * @tc.type: FUNC
512 * @tc.require: AR000C2F0C AR000CQDV7
513 * @tc.author: wangbingquan
514 */
515 HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, RepeatCloseKvStore001, TestSize.Level2)
516 {
517 /**
518 * @tc.steps: step1. Obtain the kvStore through the GetKvStore interface of
519 * the delegate manager using the parameter createIfNecessary(true)
520 * @tc.expected: step1. Returns a non-null kvstore and error code is OK.
521 */
522 KvStoreNbDelegate::Option option;
523 option.storageEngineType = GAUSSDB_RD;
524 g_mgr.GetKvStore("RepeatCloseKvStore_001", option, g_kvNbDelegateCallback);
525 ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
526 EXPECT_TRUE(g_kvDelegateStatus == OK);
527 static const size_t totalSize = 50;
528
529 /**
530 * @tc.steps: step2. Put into the database some data.
531 * @tc.expected: step2. Put returns OK.
532 */
533 std::vector<Key> keys;
534 for (size_t i = 0; i < totalSize; i++) {
535 Entry entry;
536 DistributedDBToolsUnitTest::GetRandomKeyValue(entry.key, static_cast<uint32_t>(i + 1));
537 DistributedDBToolsUnitTest::GetRandomKeyValue(entry.value);
538 EXPECT_EQ(g_kvNbDelegatePtr->Put(entry.key, entry.value), OK);
539 keys.push_back(entry.key);
540 }
541
542 /**
543 * @tc.steps: step3. Delete the data from the database, and close the database, reopen the database and
544 * get the data.
545 * @tc.expected: step3. Delete returns OK, Close returns OK and Get returns NOT_FOUND.
546 */
547 for (size_t i = 0; i < keys.size(); i++) {
548 Value value;
549 EXPECT_EQ(g_kvNbDelegatePtr->Delete(keys[i]), OK);
550 EXPECT_EQ(g_kvNbDelegatePtr->Get(keys[i], value), NOT_FOUND);
551 EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
552 g_mgr.GetKvStore("RepeatCloseKvStore_001", option, g_kvNbDelegateCallback);
553 EXPECT_EQ(g_kvNbDelegatePtr->Get(keys[i], value), NOT_FOUND);
554 }
555 EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
556 /**
557 * @tc.steps: step4. Delete the kvstore created before.
558 * @tc.expected: step4. Delete returns OK.
559 */
560 EXPECT_EQ(g_mgr.DeleteKvStore("RepeatCloseKvStore_001"), OK);
561 }
562 #ifndef OMIT_JSON
563 /**
564 * @tc.name: CreatKvStoreWithSchema001
565 * @tc.desc: Create non-memory KvStore with schema, check if create success.
566 * @tc.type: FUNC
567 * @tc.require: AR000DR9K2
568 * @tc.author: weifeng
569 */
570 HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, CreatKvStoreWithSchema001, TestSize.Level1)
571 {
572 /**
573 * @tc.steps: step1. create a new db(non-memory, non-encrypt), with valid schema;
574 * @tc.expected: step1. Returns a null kvstore and error code is NOT_SUPPORT.
575 */
576 KvStoreNbDelegate::Option option;
577 option.storageEngineType = GAUSSDB_RD;
578 GenerateValidSchemaString(option.schema);
579 g_mgr.GetKvStore("CreatKvStoreWithSchema_001", option, g_kvNbDelegateCallback);
580 ASSERT_TRUE(g_kvNbDelegatePtr == nullptr);
581 EXPECT_TRUE(g_kvDelegateStatus == NOT_SUPPORT);
582 g_kvNbDelegatePtr = nullptr;
583 }
584 #endif
585 /**
586 * @tc.name: OpenKvStoreWithStoreOnly001
587 * @tc.desc: open the kv store with the option that createDirByStoreIdOnly is true.
588 * @tc.type: FUNC
589 * @tc.require: AR000DR9K2
590 * @tc.author: wangbingquan
591 */
592 HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, OpenKvStoreWithStoreOnly001, TestSize.Level1)
593 {
594 /**
595 * @tc.steps: step1. open the kv store with the option that createDirByStoreIdOnly is true.
596 * @tc.expected: step1. Returns OK.
597 */
598 KvStoreNbDelegate::Option option;
599 option.createDirByStoreIdOnly = true;
600 option.storageEngineType = GAUSSDB_RD;
601 g_mgr.GetKvStore("StoreOnly001", option, g_kvNbDelegateCallback);
602 ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
603 EXPECT_TRUE(g_kvDelegateStatus == OK);
604 auto kvStorePtr = g_kvNbDelegatePtr;
605 /**
606 * @tc.steps: step2. open the same store with the option that createDirByStoreIdOnly is false.
607 * @tc.expected: step2. Returns NOT OK.
608 */
609 option.createDirByStoreIdOnly = false;
610 g_kvNbDelegatePtr = nullptr;
611 g_mgr.GetKvStore("StoreOnly001", option, g_kvNbDelegateCallback);
612 EXPECT_EQ(g_kvDelegateStatus, INVALID_ARGS);
613 /**
614 * @tc.steps: step3. close the kvstore and delete the kv store;
615 * @tc.expected: step3. Returns OK.
616 */
617 EXPECT_EQ(g_mgr.CloseKvStore(kvStorePtr), OK);
618 kvStorePtr = nullptr;
619 EXPECT_EQ(g_mgr.DeleteKvStore("StoreOnly001"), OK);
620 }
621
622 /**
623 * @tc.name: GetDBWhileOpened001
624 * @tc.desc: open the kv store with the option that createDirByStoreIdOnly is true.
625 * @tc.type: FUNC
626 * @tc.require: AR000E8S2V
627 * @tc.author: wangbingquan
628 */
629 HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, GetDBWhileOpened001, TestSize.Level1)
630 {
631 /**
632 * @tc.steps: step1. Get the connection.
633 * @tc.expected: step1. Returns OK.
634 */
635 KvDBProperties property;
636 std::string storeId = "openTest";
637 std::string origId = USER_ID + "-" + APP_ID + "-" + storeId;
638 std::string identifier = DBCommon::TransferHashString(origId);
639 std::string hexDir = DBCommon::TransferStringToHex(identifier);
640 property.SetStringProp(KvDBProperties::IDENTIFIER_DATA, identifier);
641 property.SetStringProp(KvDBProperties::IDENTIFIER_DIR, hexDir);
642 property.SetStringProp(KvDBProperties::DATA_DIR, g_testDir);
643 property.SetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, true);
644 property.SetIntProp(KvDBProperties::DATABASE_TYPE, KvDBProperties::SINGLE_VER_TYPE_RD_KERNAL);
645 property.SetBoolProp(KvDBProperties::MEMORY_MODE, false);
646 property.SetBoolProp(KvDBProperties::ENCRYPTED_MODE, false);
647 property.SetBoolProp(KvDBProperties::CREATE_DIR_BY_STORE_ID_ONLY, true);
648 property.SetStringProp(KvDBProperties::APP_ID, APP_ID);
649 property.SetStringProp(KvDBProperties::USER_ID, USER_ID);
650 property.SetStringProp(KvDBProperties::APP_ID, storeId);
651
652 int errCode = E_OK;
653 auto connection1 = KvDBManager::GetDatabaseConnection(property, errCode, false);
654 EXPECT_EQ(errCode, E_OK);
655 /**
656 * @tc.steps: step2. Get the connection with the para: isNeedIfOpened is false.
657 * @tc.expected: step2. Returns -E_ALREADY_OPENED.
658 */
659 auto connection2 = KvDBManager::GetDatabaseConnection(property, errCode, false);
660 EXPECT_EQ(errCode, -E_ALREADY_OPENED);
661 EXPECT_EQ(connection2, nullptr);
662
663 /**
664 * @tc.steps: step3. Get the connection with the para: isNeedIfOpened is true.
665 * @tc.expected: step3. Returns E_OK.
666 */
667 auto connection3 = KvDBManager::GetDatabaseConnection(property, errCode, true);
668 EXPECT_EQ(errCode, E_OK);
669 EXPECT_NE(connection3, nullptr);
670
671 KvDBManager::ReleaseDatabaseConnection(connection1);
672 KvDBManager::ReleaseDatabaseConnection(connection3);
673 EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
674 }
675 namespace {
OpenCloseDatabase(const std::string & storeId)676 void OpenCloseDatabase(const std::string &storeId)
677 {
678 KvStoreNbDelegate::Option option;
679 option.storageEngineType = GAUSSDB_RD;
680 DBStatus status;
681 KvStoreNbDelegate *delegate = nullptr;
682 auto nbDelegateCallback = bind(&DistributedDBToolsUnitTest::KvStoreNbDelegateCallback,
683 placeholders::_1, placeholders::_2, std::ref(status), std::ref(delegate));
684 int totalNum = 0;
685 for (size_t i = 0; i < 100; i++) { // cycle 100 times.
686 g_mgr.GetKvStore(storeId, option, nbDelegateCallback);
687 if (delegate != nullptr) {
688 totalNum++;
689 }
690 g_mgr.CloseKvStore(delegate);
691 delegate = nullptr;
692 std::this_thread::sleep_for(std::chrono::milliseconds(1));
693 }
694 LOGD("Succeed %d times", totalNum);
695 }
696
FreqOpenClose001()697 void FreqOpenClose001()
698 {
699 std::string storeId = "FrqOpenClose001";
700 std::thread t1(OpenCloseDatabase, storeId);
701 std::thread t2(OpenCloseDatabase, storeId);
702 std::thread t3(OpenCloseDatabase, storeId);
703 std::thread t4(OpenCloseDatabase, storeId);
704 t1.join();
705 t2.join();
706 t3.join();
707 t4.join();
708 EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
709 }
710
FreqOpenCloseDel001()711 void FreqOpenCloseDel001()
712 {
713 std::string storeId = "FrqOpenCloseDelete001";
714 std::thread t1(OpenCloseDatabase, storeId);
715 std::thread t2([&]() {
716 for (int i = 0; i < 10000; i++) { // loop 10000 times
717 DBStatus status = g_mgr.DeleteKvStore(storeId);
718 LOGI("delete res %d", status);
719 EXPECT_TRUE(status == OK || status == BUSY || status == NOT_FOUND);
720 }
721 });
722 t1.join();
723 t2.join();
724 }
725 }
726
727 /**
728 * @tc.name: FreqOpenCloseDel001
729 * @tc.desc: Open/close/delete the kv store concurrently.
730 * @tc.type: FUNC
731 * @tc.require: AR000DR9K2
732 * @tc.author: wangbingquan
733 */
734 HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, FreqOpenCloseDel001, TestSize.Level2)
735 {
736 ASSERT_NO_FATAL_FAILURE(FreqOpenCloseDel001());
737 }
738
739 /**
740 * @tc.name: FreqOpenClose001
741 * @tc.desc: Open and close the kv store concurrently.
742 * @tc.type: FUNC
743 * @tc.require: AR000DR9K2
744 * @tc.author: wangbingquan
745 */
746 HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, FreqOpenClose001, TestSize.Level2)
747 {
748 ASSERT_NO_FATAL_FAILURE(FreqOpenClose001());
749 }
750
751 /**
752 * @tc.name: CheckKvStoreDir001
753 * @tc.desc: Delete the kv store with the option that createDirByStoreIdOnly is true.
754 * @tc.type: FUNC
755 * @tc.require: AR000CQDV7
756 * @tc.author: wangbingquan
757 */
758 HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, CheckKvStoreDir001, TestSize.Level1)
759 {
760 /**
761 * @tc.steps: step1. open the kv store with the option that createDirByStoreIdOnly is true.
762 * @tc.expected: step1. Returns OK.
763 */
764 KvStoreNbDelegate::Option option;
765 option.storageEngineType = GAUSSDB_RD;
766 option.createDirByStoreIdOnly = true;
767 const std::string storeId("StoreOnly002");
768 g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback);
769 ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
770 EXPECT_TRUE(g_kvDelegateStatus == OK);
771 std::string testSubDir;
772 EXPECT_EQ(KvStoreDelegateManager::GetDatabaseDir(storeId, testSubDir), OK);
773 std::string dataBaseDir = g_testDir + "/" + testSubDir;
774 EXPECT_GE(access(dataBaseDir.c_str(), F_OK), 0);
775
776 /**
777 * @tc.steps: step2. delete the kv store, and check the directory.
778 * @tc.expected: step2. the directory is removed.
779 */
780 EXPECT_EQ(g_mgr.CloseKvStore(g_kvNbDelegatePtr), OK);
781 g_kvNbDelegatePtr = nullptr;
782 EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
783 LOGI("[%s]", dataBaseDir.c_str());
784 ASSERT_EQ(OS::CheckPathExistence(dataBaseDir), false);
785 }
786
787 /**
788 * @tc.name: CompressionRate1
789 * @tc.desc: Open the kv store with invalid compressionRate and open successfully.
790 * @tc.type: FUNC
791 * @tc.require: AR000G3QTT
792 * @tc.author: lidongwei
793 */
794 HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, CompressionRate1, TestSize.Level1)
795 {
796 /**
797 * @tc.steps: step1. Open the kv store with the option that comressionRate is invalid.
798 * @tc.expected: step1. Open kv store failed. Returns DB_ERROR.
799 */
800 KvStoreNbDelegate::Option option;
801 option.storageEngineType = GAUSSDB_RD;
802 option.compressionRate = 0; // 0 is invalid.
803 const std::string storeId("CompressionRate1");
804 g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback);
805 ASSERT_TRUE(g_kvNbDelegatePtr == nullptr);
806 EXPECT_TRUE(g_kvDelegateStatus == NOT_SUPPORT);
807
808 g_mgr.CloseKvStore(g_kvNbDelegatePtr);
809 g_kvNbDelegatePtr = nullptr;
810 EXPECT_EQ(g_mgr.DeleteKvStore(storeId), NOT_FOUND);
811 }
812
813 /**
814 * @tc.name: CompressionRate2
815 * @tc.desc: Open the kv store with again with different compression option.
816 * @tc.type: FUNC
817 * @tc.require:
818 * @tc.author: lianhuix
819 */
820 HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, CompressionRate2, TestSize.Level1)
821 {
822 /**
823 * @tc.steps: step1. Open the kv store with the option that comressionRate is invalid.
824 * @tc.expected: step1. Open kv store successfully. Returns OK.
825 */
826 KvStoreNbDelegate::Option option;
827 option.storageEngineType = GAUSSDB_RD;
828 option.compressionRate = 70; // 70 compression rate.
829 const std::string storeId("CompressionRate1");
830 g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback);
831 ASSERT_TRUE(g_kvNbDelegatePtr == nullptr);
832 EXPECT_TRUE(g_kvDelegateStatus == NOT_SUPPORT);
833
834 /**
835 * @tc.steps: step2. Open again with different compression option
836 * @tc.expected: step2. Open kv store failed. Returns NOT_SUPPORT.
837 */
838 DBStatus status;
839 KvStoreNbDelegate *delegate = nullptr;
840 auto callback = bind(&DistributedDBToolsUnitTest::KvStoreNbDelegateCallback,
841 placeholders::_1, placeholders::_2, std::ref(status), std::ref(delegate));
842
843 option.compressionRate = 80; // 80 compression rate.
844 g_mgr.GetKvStore(storeId, option, callback);
845 ASSERT_TRUE(delegate == nullptr);
846 EXPECT_TRUE(status == NOT_SUPPORT);
847
848 option.isNeedCompressOnSync = false;
849 option.compressionRate = 70; // 70 compression rate.
850 g_mgr.GetKvStore(storeId, option, callback);
851 ASSERT_TRUE(delegate == nullptr);
852 EXPECT_TRUE(status == NOT_SUPPORT);
853
854 /**
855 * @tc.steps: step3. Close kv store
856 * @tc.expected: step3. NOT_FOUND.
857 */
858 g_mgr.CloseKvStore(g_kvNbDelegatePtr);
859 g_kvNbDelegatePtr = nullptr;
860 EXPECT_EQ(g_mgr.DeleteKvStore(storeId), NOT_FOUND);
861 }
862
863 HWTEST_F(DistributedDBInterfacesDatabaseRdKernelTest, DataInterceptor1, TestSize.Level1)
864 {
865 /**
866 * @tc.steps: step1. Open the kv store with the option that comressionRate is invalid.
867 * @tc.expected: step1. Open kv store successfully. Returns OK.
868 */
869 KvStoreNbDelegate::Option option;
870 option.storageEngineType = GAUSSDB_RD;
871 const std::string storeId("DataInterceptor1");
872 g_mgr.GetKvStore(storeId, option, g_kvNbDelegateCallback);
873 ASSERT_TRUE(g_kvNbDelegatePtr != nullptr);
874 EXPECT_TRUE(g_kvDelegateStatus == OK);
875
876 auto interceptorCallback = [] (InterceptedData &data, const std::string &sourceID,
__anonf069fc440502(InterceptedData &data, const std::string &sourceID, const std::string &targetId) 877 const std::string &targetId) -> int {
878 return OK;
879 };
880
881 EXPECT_EQ(g_kvNbDelegatePtr->SetPushDataInterceptor(interceptorCallback), NOT_SUPPORT);
882
883 g_mgr.CloseKvStore(g_kvNbDelegatePtr);
884 g_kvNbDelegatePtr = nullptr;
885 EXPECT_EQ(g_mgr.DeleteKvStore(storeId), OK);
886 }
887 #endif // USE_RD_KERNEL