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