• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 <condition_variable>
17 #include <gtest/gtest.h>
18 #include <thread>
19 
20 #include "db_constant.h"
21 #include "distributeddb_data_generate_unit_test.h"
22 #include "distributeddb_tools_unit_test.h"
23 #include "kv_store_nb_delegate.h"
24 #include "kv_virtual_device.h"
25 #include "platform_specific.h"
26 #include "relational_store_manager.h"
27 #include "runtime_config.h"
28 
29 using namespace testing::ext;
30 using namespace DistributedDB;
31 using namespace DistributedDBUnitTest;
32 using namespace std;
33 
34 namespace {
35     std::shared_ptr<std::string> g_testDir = nullptr;
36     VirtualCommunicatorAggregator* g_communicatorAggregator = nullptr;
37     const std::string DEVICE_A = "real_device";
38     const std::string DEVICE_B = "deviceB";
39     const std::string KEY_INSTANCE_ID = "INSTANCE_ID";
40     KvVirtualDevice *g_deviceB = nullptr;
41     DistributedDBToolsUnitTest g_tool;
42 
OpenDelegate(const std::string & dlpPath,KvStoreNbDelegate * & delegatePtr,KvStoreDelegateManager & mgr,bool syncDualTupleMode=false)43     DBStatus OpenDelegate(const std::string &dlpPath, KvStoreNbDelegate *&delegatePtr,
44         KvStoreDelegateManager &mgr, bool syncDualTupleMode = false)
45     {
46         if (g_testDir == nullptr) {
47             return DB_ERROR;
48         }
49         std::string dbPath = *g_testDir + dlpPath;
50         KvStoreConfig storeConfig;
51         storeConfig.dataDir = dbPath;
52         OS::MakeDBDirectory(dbPath);
53         mgr.SetKvStoreConfig(storeConfig);
54 
55         string dir = dbPath + "/single_ver";
56         DIR* dirTmp = opendir(dir.c_str());
57         if (dirTmp == nullptr) {
58             OS::MakeDBDirectory(dir);
59         } else {
60             closedir(dirTmp);
61         }
62 
63         KvStoreNbDelegate::Option option;
64         option.syncDualTupleMode = syncDualTupleMode;
65         DBStatus res = OK;
66         mgr.GetKvStore(STORE_ID_1, option, [&delegatePtr, &res](DBStatus status, KvStoreNbDelegate *delegate) {
67             delegatePtr = delegate;
68             res = status;
69         });
70         return res;
71     }
72 
OpenDelegate(const std::string & dlpPath,RelationalStoreDelegate * & rdbDelegatePtr,RelationalStoreManager & mgr)73     DBStatus OpenDelegate(const std::string &dlpPath, RelationalStoreDelegate *&rdbDelegatePtr,
74         RelationalStoreManager &mgr)
75     {
76         if (g_testDir == nullptr) {
77             return DB_ERROR;
78         }
79         std::string dbDir = *g_testDir + dlpPath;
80         OS::MakeDBDirectory(dbDir);
81         std::string dbPath = dbDir + "/test.db";
82         auto db = RelationalTestUtils::CreateDataBase(dbPath);
83         EXPECT_EQ(sqlite3_exec(db, "PRAGMA journal_mode=WAL;", nullptr, nullptr, nullptr), SQLITE_OK);
84         RelationalStoreDelegate::Option option;
85         return mgr.OpenStore(dbPath, STORE_ID_1, option, rdbDelegatePtr);
86     }
87 
CloseDelegate(KvStoreNbDelegate * & delegatePtr,KvStoreDelegateManager & mgr,std::string storeID)88     void CloseDelegate(KvStoreNbDelegate *&delegatePtr, KvStoreDelegateManager &mgr, std::string storeID)
89     {
90         if (delegatePtr == nullptr) {
91             return;
92         }
93         EXPECT_EQ(mgr.CloseKvStore(delegatePtr), OK);
94         delegatePtr = nullptr;
95         EXPECT_EQ(mgr.DeleteKvStore(storeID), OK);
96     }
97 
CloseDelegate(RelationalStoreDelegate * & delegatePtr,RelationalStoreManager & mgr)98     void CloseDelegate(RelationalStoreDelegate *&delegatePtr, RelationalStoreManager &mgr)
99     {
100         if (delegatePtr == nullptr) {
101             return;
102         }
103         EXPECT_EQ(mgr.CloseStore(delegatePtr), OK);
104         delegatePtr = nullptr;
105     }
106 }
107 
108 class DistributedDBSingleVerDLPTest : public testing::Test {
109 public:
110     static void SetUpTestCase(void);
111     static void TearDownTestCase(void);
112     void SetUp();
113     void TearDown();
114 };
115 
SetUpTestCase(void)116 void DistributedDBSingleVerDLPTest::SetUpTestCase(void)
117 {
118     /**
119      * @tc.setup: Init datadir and Virtual Communicator.
120      */
121     std::string testDir;
122     DistributedDBToolsUnitTest::TestDirInit(testDir);
123     if (g_testDir == nullptr) {
124         g_testDir = std::make_shared<std::string>(testDir);
125     }
126 
127     g_communicatorAggregator = new (std::nothrow) VirtualCommunicatorAggregator();
128     ASSERT_TRUE(g_communicatorAggregator != nullptr);
129     RuntimeContext::GetInstance()->SetCommunicatorAggregator(g_communicatorAggregator);
130 }
131 
TearDownTestCase(void)132 void DistributedDBSingleVerDLPTest::TearDownTestCase(void)
133 {
134     /**
135      * @tc.teardown: Release virtual Communicator and clear data dir.
136      */
137     if (g_testDir != nullptr && DistributedDBToolsUnitTest::RemoveTestDbFiles(*g_testDir) != 0) {
138         LOGE("rm test db files error!");
139     }
140     RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
141 }
142 
SetUp(void)143 void DistributedDBSingleVerDLPTest::SetUp(void)
144 {
145     DistributedDBToolsUnitTest::PrintTestCaseInfo();
146     g_deviceB = new (std::nothrow) KvVirtualDevice(DEVICE_B);
147     ASSERT_TRUE(g_deviceB != nullptr);
148     VirtualSingleVerSyncDBInterface *syncInterfaceB = new (std::nothrow) VirtualSingleVerSyncDBInterface();
149     ASSERT_TRUE(syncInterfaceB != nullptr);
150     ASSERT_EQ(g_deviceB->Initialize(g_communicatorAggregator, syncInterfaceB), E_OK);
151 }
152 
TearDown(void)153 void DistributedDBSingleVerDLPTest::TearDown(void)
154 {
155     if (g_deviceB != nullptr) {
156         delete g_deviceB;
157         g_deviceB = nullptr;
158     }
159     PermissionCheckCallbackV3 nullCallback = nullptr;
160     RuntimeConfig::SetPermissionCheckCallback(nullCallback);
161     SyncActivationCheckCallbackV2 activeCallBack = nullptr;
162     RuntimeConfig::SetSyncActivationCheckCallback(activeCallBack);
163     RuntimeConfig::SetPermissionConditionCallback(nullptr);
164 }
165 
166 /**
167  * @tc.name: SameDelegateTest001
168  * @tc.desc: Test kv delegate open with diff instanceID.
169  * @tc.type: FUNC
170  * @tc.require: SR000H0JSC
171  * @tc.author: zhangqiquan
172  */
173 HWTEST_F(DistributedDBSingleVerDLPTest, SameDelegateTest001, TestSize.Level1)
174 {
175     KvStoreDelegateManager mgr1(APP_ID, USER_ID, INSTANCE_ID_1);
176     KvStoreNbDelegate *delegatePtr1 = nullptr;
177     EXPECT_EQ(OpenDelegate("/dlp1", delegatePtr1, mgr1), OK);
178     ASSERT_NE(delegatePtr1, nullptr);
179 
180     KvStoreDelegateManager mgr2(APP_ID, USER_ID, INSTANCE_ID_2);
181     KvStoreNbDelegate *delegatePtr2 = nullptr;
182     EXPECT_EQ(OpenDelegate("/dlp2", delegatePtr2, mgr2), OK);
183     ASSERT_NE(delegatePtr2, nullptr);
184 
185     Key key1 = {'k', '1'};
186     Value value1 = {'v', '1'};
187     delegatePtr1->Put(key1, value1);
188     Key key2 = {'k', '2'};
189     Value value2 = {'v', '2'};
190     delegatePtr2->Put(key2, value2);
191 
192     Value value;
193     EXPECT_EQ(delegatePtr1->Get(key1, value), OK);
194     EXPECT_EQ(value1, value);
195     EXPECT_EQ(delegatePtr2->Get(key2, value), OK);
196     EXPECT_EQ(value2, value);
197 
198     EXPECT_EQ(delegatePtr1->Get(key2, value), NOT_FOUND);
199     EXPECT_EQ(delegatePtr2->Get(key1, value), NOT_FOUND);
200 
201     CloseDelegate(delegatePtr1, mgr1, STORE_ID_1);
202     CloseDelegate(delegatePtr2, mgr2, STORE_ID_1);
203 }
204 
205 /**
206  * @tc.name: SameDelegateTest002
207  * @tc.desc: Test rdb delegate open with diff instanceID.
208  * @tc.type: FUNC
209  * @tc.require: SR000H0JSC
210  * @tc.author: zhangqiquan
211  */
212 HWTEST_F(DistributedDBSingleVerDLPTest, SameDelegateTest002, TestSize.Level1)
213 {
214     RelationalStoreManager mgr1(APP_ID, USER_ID, INSTANCE_ID_1);
215     RelationalStoreDelegate *rdbDelegatePtr1 = nullptr;
216     EXPECT_EQ(OpenDelegate("/dlp1", rdbDelegatePtr1, mgr1), OK);
217     ASSERT_NE(rdbDelegatePtr1, nullptr);
218 
219     RelationalStoreManager mgr2(APP_ID, USER_ID, INSTANCE_ID_2);
220     RelationalStoreDelegate *rdbDelegatePtr2 = nullptr;
221     EXPECT_EQ(OpenDelegate("/dlp2", rdbDelegatePtr2, mgr2), OK);
222     ASSERT_NE(rdbDelegatePtr2, nullptr);
223 
224     CloseDelegate(rdbDelegatePtr1, mgr1);
225     CloseDelegate(rdbDelegatePtr2, mgr2);
226 }
227 
228 /**
229  * @tc.name: DlpDelegateCRUDTest001
230  * @tc.desc: Test dlp delegate crud function.
231  * @tc.type: FUNC
232  * @tc.require: SR000H0JSC
233  * @tc.author: zhangqiquan
234  */
235 HWTEST_F(DistributedDBSingleVerDLPTest, DlpDelegateCRUDTest001, TestSize.Level1)
236 {
237     KvStoreDelegateManager mgr1(APP_ID, USER_ID, INSTANCE_ID_1);
238     KvStoreNbDelegate *delegatePtr1 = nullptr;
239     EXPECT_EQ(OpenDelegate("/dlp1", delegatePtr1, mgr1), OK);
240     ASSERT_NE(delegatePtr1, nullptr);
241 
242     Key key1 = {'k', '1'};
243     Value value1 = {'v', '1'};
244     delegatePtr1->Put(key1, value1);
245 
246     Value value;
247     EXPECT_EQ(delegatePtr1->Get(key1, value), OK);
248     EXPECT_EQ(value1, value);
249 
250     Value value2 = {'v', '2'};
251     delegatePtr1->Put(key1, value2);
252     EXPECT_EQ(delegatePtr1->Get(key1, value), OK);
253     EXPECT_EQ(value2, value);
254 
255     EXPECT_EQ(delegatePtr1->Delete(key1), OK);
256     EXPECT_EQ(delegatePtr1->Get(key1, value), NOT_FOUND);
257 
258     CloseDelegate(delegatePtr1, mgr1, STORE_ID_1);
259 }
260 
261 /**
262  * @tc.name: SandboxDelegateSync001
263  * @tc.desc: Test dlp delegate sync function.
264  * @tc.type: FUNC
265  * @tc.require: SR000H0JSC
266  * @tc.author: zhangqiquan
267  */
268 HWTEST_F(DistributedDBSingleVerDLPTest, SandboxDelegateSync001, TestSize.Level1)
269 {
270     KvStoreDelegateManager mgr1(APP_ID, USER_ID, INSTANCE_ID_1);
__anon698725dc0302(const PermissionCheckParam &param, uint8_t flag) 271     RuntimeConfig::SetPermissionCheckCallback([](const PermissionCheckParam &param, uint8_t flag) {
272         if ((flag & PermissionCheckFlag::CHECK_FLAG_RECEIVE) != 0) {
273             bool res = false;
274             if (param.extraConditions.find(KEY_INSTANCE_ID) != param.extraConditions.end()) {
275                 res = param.extraConditions.at(KEY_INSTANCE_ID) == std::to_string(INSTANCE_ID_1);
276             }
277             return res;
278         }
279         if (param.userId != USER_ID || param.appId != APP_ID || param.storeId != STORE_ID_1 ||
280             (param.instanceId != INSTANCE_ID_1 && param.instanceId != 0)) {
281             return false;
282         }
283         return true;
284     });
__anon698725dc0402(const PermissionConditionParam &param) 285     RuntimeConfig::SetPermissionConditionCallback([](const PermissionConditionParam &param) {
286         std::map<std::string, std::string> res;
287         res.emplace(KEY_INSTANCE_ID, std::to_string(INSTANCE_ID_1));
288         return res;
289     });
290 
291     KvStoreNbDelegate *delegatePtr1 = nullptr;
292     EXPECT_EQ(OpenDelegate("/dlp1", delegatePtr1, mgr1), OK);
293     ASSERT_NE(delegatePtr1, nullptr);
294 
295     Key key1 = {'k', '1'};
296     Value value1 = {'v', '1'};
297     delegatePtr1->Put(key1, value1);
298 
299     std::map<std::string, DBStatus> result;
300     DBStatus status = g_tool.SyncTest(delegatePtr1, { DEVICE_B }, SYNC_MODE_PUSH_ONLY, result);
301     EXPECT_TRUE(status == OK);
302     EXPECT_EQ(result[DEVICE_B], OK);
303 
304     CloseDelegate(delegatePtr1, mgr1, STORE_ID_1);
305 }
306 
307 /**
308  * @tc.name: SandboxDelegateSync002
309  * @tc.desc: Test dlp delegate sync active if callback return true.
310  * @tc.type: FUNC
311  * @tc.require: SR000H0JSC
312  * @tc.author: zhangqiquan
313  */
314 HWTEST_F(DistributedDBSingleVerDLPTest, SandboxDelegateSync002, TestSize.Level1)
315 {
316     KvStoreDelegateManager mgr1(APP_ID, USER_ID, INSTANCE_ID_1);
__anon698725dc0502(const ActivationCheckParam &param) 317     RuntimeConfig::SetSyncActivationCheckCallback([](const ActivationCheckParam &param) {
318         if (param.userId == USER_ID && param.appId == APP_ID && param.storeId == STORE_ID_1 &&
319             param.instanceId == INSTANCE_ID_1) {
320             return true;
321         }
322         return false;
323     });
324 
325     KvStoreNbDelegate *delegatePtr1 = nullptr;
326     EXPECT_EQ(OpenDelegate("/dlp1", delegatePtr1, mgr1, true), OK);
327     ASSERT_NE(delegatePtr1, nullptr);
328 
329     std::map<std::string, DBStatus> result;
330     DBStatus status = g_tool.SyncTest(delegatePtr1, { DEVICE_B }, SYNC_MODE_PUSH_ONLY, result);
331     EXPECT_EQ(status, OK);
332     EXPECT_EQ(result[DEVICE_B], OK);
333 
334     CloseDelegate(delegatePtr1, mgr1, STORE_ID_1);
335 }