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 EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK);
85 db = nullptr;
86 RelationalStoreDelegate::Option option;
87 return mgr.OpenStore(dbPath, STORE_ID_1, option, rdbDelegatePtr);
88 }
89
CloseDelegate(KvStoreNbDelegate * & delegatePtr,KvStoreDelegateManager & mgr,std::string storeID)90 void CloseDelegate(KvStoreNbDelegate *&delegatePtr, KvStoreDelegateManager &mgr, std::string storeID)
91 {
92 if (delegatePtr == nullptr) {
93 return;
94 }
95 EXPECT_EQ(mgr.CloseKvStore(delegatePtr), OK);
96 delegatePtr = nullptr;
97 EXPECT_EQ(mgr.DeleteKvStore(storeID), OK);
98 }
99
CloseDelegate(RelationalStoreDelegate * & delegatePtr,RelationalStoreManager & mgr)100 void CloseDelegate(RelationalStoreDelegate *&delegatePtr, RelationalStoreManager &mgr)
101 {
102 if (delegatePtr == nullptr) {
103 return;
104 }
105 EXPECT_EQ(mgr.CloseStore(delegatePtr), OK);
106 delegatePtr = nullptr;
107 }
108 }
109
110 class DistributedDBSingleVerDLPTest : public testing::Test {
111 public:
112 static void SetUpTestCase(void);
113 static void TearDownTestCase(void);
114 void SetUp();
115 void TearDown();
116 };
117
SetUpTestCase(void)118 void DistributedDBSingleVerDLPTest::SetUpTestCase(void)
119 {
120 /**
121 * @tc.setup: Init datadir and Virtual Communicator.
122 */
123 std::string testDir;
124 DistributedDBToolsUnitTest::TestDirInit(testDir);
125 if (g_testDir == nullptr) {
126 g_testDir = std::make_shared<std::string>(testDir);
127 }
128
129 g_communicatorAggregator = new (std::nothrow) VirtualCommunicatorAggregator();
130 ASSERT_TRUE(g_communicatorAggregator != nullptr);
131 RuntimeContext::GetInstance()->SetCommunicatorAggregator(g_communicatorAggregator);
132 }
133
TearDownTestCase(void)134 void DistributedDBSingleVerDLPTest::TearDownTestCase(void)
135 {
136 /**
137 * @tc.teardown: Release virtual Communicator and clear data dir.
138 */
139 if (g_testDir != nullptr && DistributedDBToolsUnitTest::RemoveTestDbFiles(*g_testDir) != 0) {
140 LOGE("rm test db files error!");
141 }
142 RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
143 }
144
SetUp(void)145 void DistributedDBSingleVerDLPTest::SetUp(void)
146 {
147 DistributedDBToolsUnitTest::PrintTestCaseInfo();
148 g_deviceB = new (std::nothrow) KvVirtualDevice(DEVICE_B);
149 ASSERT_TRUE(g_deviceB != nullptr);
150 VirtualSingleVerSyncDBInterface *syncInterfaceB = new (std::nothrow) VirtualSingleVerSyncDBInterface();
151 ASSERT_TRUE(syncInterfaceB != nullptr);
152 ASSERT_EQ(g_deviceB->Initialize(g_communicatorAggregator, syncInterfaceB), E_OK);
153 }
154
TearDown(void)155 void DistributedDBSingleVerDLPTest::TearDown(void)
156 {
157 if (g_deviceB != nullptr) {
158 delete g_deviceB;
159 g_deviceB = nullptr;
160 }
161 PermissionCheckCallbackV3 nullCallback = nullptr;
162 RuntimeConfig::SetPermissionCheckCallback(nullCallback);
163 SyncActivationCheckCallbackV2 activeCallBack = nullptr;
164 RuntimeConfig::SetSyncActivationCheckCallback(activeCallBack);
165 RuntimeConfig::SetPermissionConditionCallback(nullptr);
166 }
167
168 /**
169 * @tc.name: SameDelegateTest001
170 * @tc.desc: Test kv delegate open with diff instanceID.
171 * @tc.type: FUNC
172 * @tc.require: SR000H0JSC
173 * @tc.author: zhangqiquan
174 */
175 HWTEST_F(DistributedDBSingleVerDLPTest, SameDelegateTest001, TestSize.Level1)
176 {
177 KvStoreDelegateManager mgr1(APP_ID, USER_ID, INSTANCE_ID_1);
178 KvStoreNbDelegate *delegatePtr1 = nullptr;
179 EXPECT_EQ(OpenDelegate("/dlp1", delegatePtr1, mgr1), OK);
180 ASSERT_NE(delegatePtr1, nullptr);
181
182 KvStoreDelegateManager mgr2(APP_ID, USER_ID, INSTANCE_ID_2);
183 KvStoreNbDelegate *delegatePtr2 = nullptr;
184 EXPECT_EQ(OpenDelegate("/dlp2", delegatePtr2, mgr2), OK);
185 ASSERT_NE(delegatePtr2, nullptr);
186
187 Key key1 = {'k', '1'};
188 Value value1 = {'v', '1'};
189 delegatePtr1->Put(key1, value1);
190 Key key2 = {'k', '2'};
191 Value value2 = {'v', '2'};
192 delegatePtr2->Put(key2, value2);
193
194 Value value;
195 EXPECT_EQ(delegatePtr1->Get(key1, value), OK);
196 EXPECT_EQ(value1, value);
197 EXPECT_EQ(delegatePtr2->Get(key2, value), OK);
198 EXPECT_EQ(value2, value);
199
200 EXPECT_EQ(delegatePtr1->Get(key2, value), NOT_FOUND);
201 EXPECT_EQ(delegatePtr2->Get(key1, value), NOT_FOUND);
202
203 CloseDelegate(delegatePtr1, mgr1, STORE_ID_1);
204 CloseDelegate(delegatePtr2, mgr2, STORE_ID_1);
205 }
206
207 /**
208 * @tc.name: SameDelegateTest002
209 * @tc.desc: Test rdb delegate open with diff instanceID.
210 * @tc.type: FUNC
211 * @tc.require: SR000H0JSC
212 * @tc.author: zhangqiquan
213 */
214 HWTEST_F(DistributedDBSingleVerDLPTest, SameDelegateTest002, TestSize.Level1)
215 {
216 RelationalStoreManager mgr1(APP_ID, USER_ID, INSTANCE_ID_1);
217 RelationalStoreDelegate *rdbDelegatePtr1 = nullptr;
218 EXPECT_EQ(OpenDelegate("/dlp1", rdbDelegatePtr1, mgr1), OK);
219 ASSERT_NE(rdbDelegatePtr1, nullptr);
220
221 RelationalStoreManager mgr2(APP_ID, USER_ID, INSTANCE_ID_2);
222 RelationalStoreDelegate *rdbDelegatePtr2 = nullptr;
223 EXPECT_EQ(OpenDelegate("/dlp2", rdbDelegatePtr2, mgr2), OK);
224 ASSERT_NE(rdbDelegatePtr2, nullptr);
225
226 CloseDelegate(rdbDelegatePtr1, mgr1);
227 CloseDelegate(rdbDelegatePtr2, mgr2);
228 }
229
230 /**
231 * @tc.name: DlpDelegateCRUDTest001
232 * @tc.desc: Test dlp delegate crud function.
233 * @tc.type: FUNC
234 * @tc.require: SR000H0JSC
235 * @tc.author: zhangqiquan
236 */
237 HWTEST_F(DistributedDBSingleVerDLPTest, DlpDelegateCRUDTest001, TestSize.Level1)
238 {
239 KvStoreDelegateManager mgr1(APP_ID, USER_ID, INSTANCE_ID_1);
240 KvStoreNbDelegate *delegatePtr1 = nullptr;
241 EXPECT_EQ(OpenDelegate("/dlp1", delegatePtr1, mgr1), OK);
242 ASSERT_NE(delegatePtr1, nullptr);
243
244 Key key1 = {'k', '1'};
245 Value value1 = {'v', '1'};
246 delegatePtr1->Put(key1, value1);
247
248 Value value;
249 EXPECT_EQ(delegatePtr1->Get(key1, value), OK);
250 EXPECT_EQ(value1, value);
251
252 Value value2 = {'v', '2'};
253 delegatePtr1->Put(key1, value2);
254 EXPECT_EQ(delegatePtr1->Get(key1, value), OK);
255 EXPECT_EQ(value2, value);
256
257 EXPECT_EQ(delegatePtr1->Delete(key1), OK);
258 EXPECT_EQ(delegatePtr1->Get(key1, value), NOT_FOUND);
259
260 CloseDelegate(delegatePtr1, mgr1, STORE_ID_1);
261 }
262
263 /**
264 * @tc.name: SandboxDelegateSync001
265 * @tc.desc: Test dlp delegate sync function.
266 * @tc.type: FUNC
267 * @tc.require: SR000H0JSC
268 * @tc.author: zhangqiquan
269 */
270 HWTEST_F(DistributedDBSingleVerDLPTest, SandboxDelegateSync001, TestSize.Level1)
271 {
272 KvStoreDelegateManager mgr1(APP_ID, USER_ID, INSTANCE_ID_1);
__anon80cb88940302(const PermissionCheckParam ¶m, uint8_t flag) 273 RuntimeConfig::SetPermissionCheckCallback([](const PermissionCheckParam ¶m, uint8_t flag) {
274 if ((flag & PermissionCheckFlag::CHECK_FLAG_RECEIVE) != 0) {
275 bool res = false;
276 if (param.extraConditions.find(KEY_INSTANCE_ID) != param.extraConditions.end()) {
277 res = param.extraConditions.at(KEY_INSTANCE_ID) == std::to_string(INSTANCE_ID_1);
278 }
279 return res;
280 }
281 if (param.userId != USER_ID || param.appId != APP_ID || param.storeId != STORE_ID_1 ||
282 (param.instanceId != INSTANCE_ID_1 && param.instanceId != 0)) {
283 return false;
284 }
285 return true;
286 });
__anon80cb88940402(const PermissionConditionParam ¶m) 287 RuntimeConfig::SetPermissionConditionCallback([](const PermissionConditionParam ¶m) {
288 std::map<std::string, std::string> res;
289 res.emplace(KEY_INSTANCE_ID, std::to_string(INSTANCE_ID_1));
290 return res;
291 });
292
293 KvStoreNbDelegate *delegatePtr1 = nullptr;
294 EXPECT_EQ(OpenDelegate("/dlp1", delegatePtr1, mgr1), OK);
295 ASSERT_NE(delegatePtr1, nullptr);
296
297 Key key1 = {'k', '1'};
298 Value value1 = {'v', '1'};
299 delegatePtr1->Put(key1, value1);
300
301 std::map<std::string, DBStatus> result;
302 DBStatus status = g_tool.SyncTest(delegatePtr1, { DEVICE_B }, SYNC_MODE_PUSH_ONLY, result);
303 EXPECT_TRUE(status == OK);
304 EXPECT_EQ(result[DEVICE_B], OK);
305
306 CloseDelegate(delegatePtr1, mgr1, STORE_ID_1);
307 }
308
309 /**
310 * @tc.name: SandboxDelegateSync002
311 * @tc.desc: Test dlp delegate sync active if callback return true.
312 * @tc.type: FUNC
313 * @tc.require: SR000H0JSC
314 * @tc.author: zhangqiquan
315 */
316 HWTEST_F(DistributedDBSingleVerDLPTest, SandboxDelegateSync002, TestSize.Level1)
317 {
318 KvStoreDelegateManager mgr1(APP_ID, USER_ID, INSTANCE_ID_1);
__anon80cb88940502(const ActivationCheckParam ¶m) 319 RuntimeConfig::SetSyncActivationCheckCallback([](const ActivationCheckParam ¶m) {
320 if (param.userId == USER_ID && param.appId == APP_ID && param.storeId == STORE_ID_1 &&
321 param.instanceId == INSTANCE_ID_1) {
322 return true;
323 }
324 return false;
325 });
326
327 KvStoreNbDelegate *delegatePtr1 = nullptr;
328 EXPECT_EQ(OpenDelegate("/dlp1", delegatePtr1, mgr1, true), OK);
329 ASSERT_NE(delegatePtr1, nullptr);
330
331 std::map<std::string, DBStatus> result;
332 DBStatus status = g_tool.SyncTest(delegatePtr1, { DEVICE_B }, SYNC_MODE_PUSH_ONLY, result);
333 EXPECT_EQ(status, OK);
334 EXPECT_EQ(result[DEVICE_B], OK);
335
336 CloseDelegate(delegatePtr1, mgr1, STORE_ID_1);
337 }