1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <condition_variable>
17 #include <gtest/gtest.h>
18 #include <thread>
19 
20 #include "db_constant.h"
21 #include "db_common.h"
22 #include "distributeddb_data_generate_unit_test.h"
23 #include "distributeddb_tools_unit_test.h"
24 #include "kv_store_nb_delegate.h"
25 #include "kv_virtual_device.h"
26 #include "platform_specific.h"
27 
28 using namespace testing::ext;
29 using namespace DistributedDB;
30 using namespace DistributedDBUnitTest;
31 using namespace std;
32 
33 namespace {
34     string g_testDir;
35     const string STORE_ID = "kv_stroe_permission_sync_test";
36     const int WAIT_TIME = 1000;
37     const std::string DEVICE_A = "real_device";
38     const std::string DEVICE_B = "deviceB";
39     const std::string DEVICE_C = "deviceC";
40 
41     KvStoreDelegateManager g_mgr(APP_ID, USER_ID);
42     KvStoreConfig g_config;
43     DistributedDBToolsUnitTest g_tool;
44     DBStatus g_kvDelegateStatus = INVALID_ARGS;
45     KvStoreNbDelegate* g_kvDelegatePtr = nullptr;
46     VirtualCommunicatorAggregator* g_communicatorAggregator = nullptr;
47     KvVirtualDevice *g_deviceB = nullptr;
48     KvVirtualDevice *g_deviceC = nullptr;
49 
50     // the type of g_kvDelegateCallback is function<void(DBStatus, KvStoreDelegate*)>
51     auto g_kvDelegateCallback = bind(&DistributedDBToolsUnitTest::KvStoreNbDelegateCallback,
52         placeholders::_1, placeholders::_2, std::ref(g_kvDelegateStatus), std::ref(g_kvDelegatePtr));
53 }
54 
55 class DistributedDBSingleVerP2PPermissionSyncTest : public testing::Test {
56 public:
57     static void SetUpTestCase(void);
58     static void TearDownTestCase(void);
59     void SetUp();
60     void TearDown();
61 };
62 
SetUpTestCase(void)63 void DistributedDBSingleVerP2PPermissionSyncTest::SetUpTestCase(void)
64 {
65     /**
66      * @tc.setup: Init datadir and Virtual Communicator.
67      */
68     DistributedDBToolsUnitTest::TestDirInit(g_testDir);
69     g_config.dataDir = g_testDir;
70     g_mgr.SetKvStoreConfig(g_config);
71 
72     string dir = g_testDir + "/single_ver";
73     DIR* dirTmp = opendir(dir.c_str());
74     if (dirTmp == nullptr) {
75         OS::MakeDBDirectory(dir);
76     } else {
77         closedir(dirTmp);
78     }
79 
80     g_communicatorAggregator = new (std::nothrow) VirtualCommunicatorAggregator();
81     ASSERT_TRUE(g_communicatorAggregator != nullptr);
82     RuntimeContext::GetInstance()->SetCommunicatorAggregator(g_communicatorAggregator);
83 }
84 
TearDownTestCase(void)85 void DistributedDBSingleVerP2PPermissionSyncTest::TearDownTestCase(void)
86 {
87     /**
88      * @tc.teardown: Release virtual Communicator and clear data dir.
89      */
90     if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) {
91         LOGE("rm test db files error!");
92     }
93     RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr);
94 }
95 
SetUp(void)96 void DistributedDBSingleVerP2PPermissionSyncTest::SetUp(void)
97 {
98     DistributedDBToolsUnitTest::PrintTestCaseInfo();
99     /**
100      * @tc.setup: create virtual device B and C, and get a KvStoreNbDelegate as deviceA
101      */
102     KvStoreNbDelegate::Option option;
103     g_mgr.GetKvStore(STORE_ID, option, g_kvDelegateCallback);
104     ASSERT_TRUE(g_kvDelegateStatus == OK);
105     ASSERT_TRUE(g_kvDelegatePtr != nullptr);
106     g_deviceB = new (std::nothrow) KvVirtualDevice(DEVICE_B);
107     ASSERT_TRUE(g_deviceB != nullptr);
108     VirtualSingleVerSyncDBInterface *syncInterfaceB = new (std::nothrow) VirtualSingleVerSyncDBInterface();
109     ASSERT_TRUE(syncInterfaceB != nullptr);
110     ASSERT_EQ(g_deviceB->Initialize(g_communicatorAggregator, syncInterfaceB), E_OK);
111 
112     g_deviceC = new (std::nothrow) KvVirtualDevice(DEVICE_C);
113     ASSERT_TRUE(g_deviceC != nullptr);
114     VirtualSingleVerSyncDBInterface *syncInterfaceC = new (std::nothrow) VirtualSingleVerSyncDBInterface();
115     ASSERT_TRUE(syncInterfaceC != nullptr);
116     ASSERT_EQ(g_deviceC->Initialize(g_communicatorAggregator, syncInterfaceC), E_OK);
117 
118     auto permissionCheckCallback = [] (const std::string &userId, const std::string &appId, const std::string &storeId,
119         const std::string &deviceId, uint8_t flag) -> bool {
120             return true;
121         };
122     EXPECT_EQ(g_mgr.SetPermissionCheckCallback(permissionCheckCallback), OK);
123 }
124 
TearDown(void)125 void DistributedDBSingleVerP2PPermissionSyncTest::TearDown(void)
126 {
127     /**
128      * @tc.teardown: Release device A, B, C
129      */
130     if (g_kvDelegatePtr != nullptr) {
131         ASSERT_EQ(g_mgr.CloseKvStore(g_kvDelegatePtr), OK);
132         g_kvDelegatePtr = nullptr;
133         DBStatus status = g_mgr.DeleteKvStore(STORE_ID);
134         LOGD("delete kv store status %d", status);
135         ASSERT_TRUE(status == OK);
136     }
137     if (g_deviceB != nullptr) {
138         delete g_deviceB;
139         g_deviceB = nullptr;
140     }
141     if (g_deviceC != nullptr) {
142         delete g_deviceC;
143         g_deviceC = nullptr;
144     }
145     PermissionCheckCallbackV2 nullCallback;
146     EXPECT_EQ(g_mgr.SetPermissionCheckCallback(nullCallback), OK);
147 }
148 
149 /**
150   * @tc.name: PermissionCheck001
151   * @tc.desc: deviceA PermissionCheck not pass test, SYNC_MODE_PUSH_ONLY
152   * @tc.type: FUNC
153   * @tc.require: AR000D4876
154   * @tc.author: wangchuanqing
155   */
156 HWTEST_F(DistributedDBSingleVerP2PPermissionSyncTest, PermissionCheck001, TestSize.Level3)
157 {
158     /**
159      * @tc.steps: step1. SetPermissionCheckCallback
160      * @tc.expected: step1. return OK.
161      */
162     auto permissionCheckCallback = [] (const std::string &userId, const std::string &appId, const std::string &storeId,
__anone28338ea0302(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) 163         const std::string &deviceId, uint8_t flag) -> bool {
164             if (flag & CHECK_FLAG_SEND) {
165                 LOGD("in RunPermissionCheck callback func, check not pass, flag:%d", flag);
166                 return false;
167             } else {
168                 LOGD("in RunPermissionCheck callback func, check pass, flag:%d", flag);
169                 return true;
170             }
171         };
172     EXPECT_EQ(g_mgr.SetPermissionCheckCallback(permissionCheckCallback), OK);
173     DBStatus status = OK;
174     std::vector<std::string> devices;
175     devices.push_back(g_deviceB->GetDeviceId());
176     devices.push_back(g_deviceC->GetDeviceId());
177 
178     /**
179      * @tc.steps: step2. deviceA put {k1, v1}
180      */
181     Key key = {'1'};
182     Value value = {'1'};
183     status = g_kvDelegatePtr->Put(key, value);
184     ASSERT_TRUE(status == OK);
185 
186     /**
187      * @tc.steps: step3. deviceA call sync and wait
188      * @tc.expected: step3. sync should return OK.
189      */
190     std::map<std::string, DBStatus> result;
191     status = g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PUSH_ONLY, result);
192     ASSERT_TRUE(status == OK);
193 
194     /**
195      * @tc.expected: step3. onComplete should be called,
196      * status == PERMISSION_CHECK_FORBID_SYNC, deviceB and deviceC do not have {k1, v1}
197      */
198     ASSERT_TRUE(result.size() == devices.size());
199     for (const auto &pair : result) {
200         LOGD("dev %s, status %d", pair.first.c_str(), pair.second);
201         EXPECT_TRUE(pair.second == PERMISSION_CHECK_FORBID_SYNC);
202     }
203     VirtualDataItem item;
204     g_deviceB->GetData(key, item);
205     EXPECT_TRUE(item.value.empty());
206     g_deviceC->GetData(key, item);
207     EXPECT_TRUE(item.value.empty());
208     PermissionCheckCallbackV2 nullCallback;
209     EXPECT_EQ(g_mgr.SetPermissionCheckCallback(nullCallback), OK);
210 }
211 
212 /**
213   * @tc.name: PermissionCheck002
214   * @tc.desc: deviceA PermissionCheck not pass test, SYNC_MODE_PULL_ONLY
215   * @tc.type: FUNC
216   * @tc.require: AR000D4876
217   * @tc.author: wangchuanqing
218   */
219 HWTEST_F(DistributedDBSingleVerP2PPermissionSyncTest, PermissionCheck002, TestSize.Level3)
220 {
221     /**
222      * @tc.steps: step1. SetPermissionCheckCallback
223      * @tc.expected: step1. return OK.
224      */
225     auto permissionCheckCallback = [] (const std::string &userId, const std::string &appId, const std::string &storeId,
__anone28338ea0402(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) 226         const std::string &deviceId, uint8_t flag) -> bool {
227             if (flag & CHECK_FLAG_RECEIVE) {
228                 LOGD("in RunPermissionCheck callback func, check not pass, flag:%d", flag);
229                 return false;
230             } else {
231                 LOGD("in RunPermissionCheck callback func, check pass, flag:%d", flag);
232                 return true;
233             }
234         };
235 
236     EXPECT_EQ(g_mgr.SetPermissionCheckCallback(permissionCheckCallback), OK);
237 
238     DBStatus status = OK;
239     std::vector<std::string> devices;
240     devices.push_back(g_deviceB->GetDeviceId());
241     devices.push_back(g_deviceC->GetDeviceId());
242 
243     /**
244      * @tc.steps: step2. deviceB put {k1, v1}
245      */
246     Key key = {'1'};
247     Value value = {'1'};
248     g_deviceB->PutData(key, value, 0, 0);
249 
250     /**
251      * @tc.steps: step2. deviceB put {k2, v2}
252      */
253     Key key2 = {'2'};
254     Value value2 = {'2'};
255     g_deviceC->PutData(key2, value2, 0, 0);
256     ASSERT_TRUE(status == OK);
257 
258     /**
259      * @tc.steps: step3. deviceA call pull sync
260      * @tc.expected: step3. sync should return OK.
261      */
262     std::map<std::string, DBStatus> result;
263     status = g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PULL_ONLY, result);
264     ASSERT_TRUE(status == OK);
265 
266     /**
267      * @tc.expected: step3. onComplete should be called,
268      * status == PERMISSION_CHECK_FORBID_SYNC, DeviceA do not have {k1, VALUE_1}, {K2. VALUE_2}
269      */
270     ASSERT_TRUE(result.size() == devices.size());
271     for (const auto &pair : result) {
272         LOGD("dev %s, status %d", pair.first.c_str(), pair.second);
273         EXPECT_TRUE(pair.second == PERMISSION_CHECK_FORBID_SYNC);
274     }
275     Value value3;
276     EXPECT_EQ(g_kvDelegatePtr->Get(key, value3), NOT_FOUND);
277     EXPECT_EQ(g_kvDelegatePtr->Get(key2, value3), NOT_FOUND);
278     PermissionCheckCallbackV2 nullCallback;
279     EXPECT_EQ(g_mgr.SetPermissionCheckCallback(nullCallback), OK);
280 }
281 
282 /**
283   * @tc.name: PermissionCheck003
284   * @tc.desc: deviceA PermissionCheck not pass test, SYNC_MODE_PUSH_PULL
285   * @tc.type: FUNC
286   * @tc.require: AR000D4876
287   * @tc.author: wangchuanqing
288   */
289 HWTEST_F(DistributedDBSingleVerP2PPermissionSyncTest, PermissionCheck003, TestSize.Level3)
290 {
291     /**
292      * @tc.steps: step1. SetPermissionCheckCallback
293      * @tc.expected: step1. return OK.
294      */
295     auto permissionCheckCallback = [] (const std::string &userId, const std::string &appId, const std::string &storeId,
__anone28338ea0502(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) 296         const std::string &deviceId, uint8_t flag) -> bool {
297             if (flag & (CHECK_FLAG_SEND | CHECK_FLAG_RECEIVE)) {
298                 LOGD("in RunPermissionCheck callback func, check not pass, flag:%d", flag);
299                 return false;
300             } else {
301                 LOGD("in RunPermissionCheck callback func, check pass, flag:%d", flag);
302                 return true;
303             }
304         };
305     EXPECT_EQ(g_mgr.SetPermissionCheckCallback(permissionCheckCallback), OK);
306 
307     std::vector<std::string> devices;
308     devices.push_back(g_deviceB->GetDeviceId());
309     devices.push_back(g_deviceC->GetDeviceId());
310 
311     /**
312      * @tc.steps: step2. deviceA put {k1, v1}
313      */
314     Key key1 = {'1'};
315     Value value1 = {'1'};
316     DBStatus status = g_kvDelegatePtr->Put(key1, value1);
317     EXPECT_TRUE(status == OK);
318 
319     /**
320      * @tc.steps: step2. deviceB put {k2, v2}
321      */
322     Key key2 = {'2'};
323     Value value2 = {'2'};
324     g_deviceB->PutData(key2, value2, 0, 0);
325 
326     /**
327      * @tc.steps: step2. deviceB put {k3, v3}
328      */
329     Key key3 = {'3'};
330     Value value3 = {'3'};
331     g_deviceC->PutData(key3, value3, 0, 0);
332 
333     /**
334      * @tc.steps: step3. deviceA call push_pull sync
335      * @tc.expected: step3. sync should return OK.
336      * onComplete should be called, status == PERMISSION_CHECK_FORBID_SYNC
337      */
338     std::map<std::string, DBStatus> result;
339     status = g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PUSH_PULL, result);
340     ASSERT_TRUE(status == OK);
341 
342     ASSERT_TRUE(result.size() == devices.size());
343     for (const auto &pair : result) {
344         LOGD("dev %s, status %d", pair.first.c_str(), pair.second);
345         EXPECT_TRUE(pair.second == PERMISSION_CHECK_FORBID_SYNC);
346     }
347 
348     /**
349      * @tc.expected: step3. DeviceA only have {k1. v1}
350      *      DeviceB only have {k2. v2}, DeviceC only have {k3. v3}
351      */
352     Value value4;
353     EXPECT_TRUE(g_kvDelegatePtr->Get(key2, value4) == NOT_FOUND);
354     EXPECT_TRUE(g_kvDelegatePtr->Get(key3, value4) == NOT_FOUND);
355 
356     VirtualDataItem item1;
357     g_deviceB->GetData(key1, item1);
358     EXPECT_TRUE(item1.value.empty());
359     g_deviceB->GetData(key3, item1);
360     EXPECT_TRUE(item1.value.empty());
361 
362     VirtualDataItem item2;
363     g_deviceC->GetData(key1, item2);
364     EXPECT_TRUE(item1.value.empty());
365     g_deviceC->GetData(key2, item2);
366     EXPECT_TRUE(item2.value.empty());
367     PermissionCheckCallbackV2 nullCallback;
368     EXPECT_EQ(g_mgr.SetPermissionCheckCallback(nullCallback), OK);
369 }
370 
371 /**
372   * @tc.name: PermissionCheck004
373   * @tc.desc: deviceB and deviceC PermissionCheck not pass test, SYNC_MODE_PUSH_ONLY
374   * @tc.type: FUNC
375   * @tc.require: AR000D4876
376   * @tc.author: wangchuanqing
377   */
378 HWTEST_F(DistributedDBSingleVerP2PPermissionSyncTest, PermissionCheck004, TestSize.Level3)
379 {
380     /**
381      * @tc.steps: step1. SetPermissionCheckCallback
382      * @tc.expected: step1. return OK.
383      */
384     auto permissionCheckCallback = [] (const std::string &userId, const std::string &appId, const std::string &storeId,
__anone28338ea0602(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) 385         const std::string &deviceId, uint8_t flag) -> bool {
386             if (flag & CHECK_FLAG_RECEIVE) {
387                 LOGD("in RunPermissionCheck callback func, check not pass, flag:%d", flag);
388                 return false;
389             } else {
390                 LOGD("in RunPermissionCheck callback func, check pass, flag:%d", flag);
391                 return true;
392             }
393         };
394     EXPECT_EQ(g_mgr.SetPermissionCheckCallback(permissionCheckCallback), OK);
395     DBStatus status = OK;
396     std::vector<std::string> devices;
397     devices.push_back(g_deviceB->GetDeviceId());
398     devices.push_back(g_deviceC->GetDeviceId());
399 
400     /**
401      * @tc.steps: step2. deviceA put {k1, v1}
402      */
403     Key key = {'1'};
404     Value value = {'1'};
405     status = g_kvDelegatePtr->Put(key, value);
406     ASSERT_TRUE(status == OK);
407 
408     /**
409      * @tc.steps: step3. deviceA call sync and wait
410      * @tc.expected: step3. sync should return OK.
411      */
412     std::map<std::string, DBStatus> result;
413     status = g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PUSH_ONLY, result);
414     ASSERT_TRUE(status == OK);
415 
416     /**
417      * @tc.expected: step3. onComplete should be called,
418      * status == PERMISSION_CHECK_FORBID_SYNC, deviceB and deviceC do not have {k1, v1}
419      */
420     ASSERT_TRUE(result.size() == devices.size());
421     for (const auto &pair : result) {
422         LOGD("dev %s, status %d", pair.first.c_str(), pair.second);
423         EXPECT_TRUE(pair.second == PERMISSION_CHECK_FORBID_SYNC);
424     }
425     VirtualDataItem item;
426     g_deviceB->GetData(key, item);
427     EXPECT_TRUE(item.value.empty());
428     g_deviceC->GetData(key, item);
429     EXPECT_TRUE(item.value.empty());
430     PermissionCheckCallbackV2 nullCallback;
431     EXPECT_EQ(g_mgr.SetPermissionCheckCallback(nullCallback), OK);
432 }
433 
434 /**
435   * @tc.name: PermissionCheck005
436   * @tc.desc: deviceB and deviceC PermissionCheck not pass test, SYNC_MODE_PULL_ONLY
437   * @tc.type: FUNC
438   * @tc.require: AR000D4876
439   * @tc.author: wangchuanqing
440   */
441 HWTEST_F(DistributedDBSingleVerP2PPermissionSyncTest, PermissionCheck005, TestSize.Level3)
442 {
443     /**
444      * @tc.steps: step1. SetPermissionCheckCallback
445      * @tc.expected: step1. return OK.
446      */
447     auto permissionCheckCallback = [] (const std::string &userId, const std::string &appId, const std::string &storeId,
__anone28338ea0702(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) 448         const std::string &deviceId, uint8_t flag) -> bool {
449             if (flag & CHECK_FLAG_SEND) {
450                 LOGD("in RunPermissionCheck callback func, check not pass, flag:%d", flag);
451                 return false;
452             } else {
453                 LOGD("in RunPermissionCheck callback func, check pass, flag:%d", flag);
454                 return true;
455             }
456         };
457     EXPECT_EQ(g_mgr.SetPermissionCheckCallback(permissionCheckCallback), OK);
458 
459     DBStatus status = OK;
460     std::vector<std::string> devices;
461     devices.push_back(g_deviceB->GetDeviceId());
462     devices.push_back(g_deviceC->GetDeviceId());
463 
464     /**
465      * @tc.steps: step2. deviceB put {k1, v1}
466      */
467     Key key = {'1'};
468     Value value = {'1'};
469     g_deviceB->PutData(key, value, 0, 0);
470 
471     /**
472      * @tc.steps: step2. deviceB put {k2, v2}
473      */
474     Key key2 = {'2'};
475     Value value2 = {'2'};
476     g_deviceC->PutData(key2, value2, 0, 0);
477     ASSERT_TRUE(status == OK);
478 
479     /**
480      * @tc.steps: step3. deviceA call pull sync
481      * @tc.expected: step3. sync should return OK.
482      */
483     std::map<std::string, DBStatus> result;
484     status = g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PULL_ONLY, result);
485     ASSERT_TRUE(status == OK);
486 
487     /**
488      * @tc.expected: step3. onComplete should be called,
489      * status == PERMISSION_CHECK_FORBID_SYNC, DeviceA do not have {k1, VALUE_1}, {K2. VALUE_2}
490      */
491     ASSERT_TRUE(result.size() == devices.size());
492     for (const auto &pair : result) {
493         LOGD("dev %s, status %d", pair.first.c_str(), pair.second);
494         EXPECT_TRUE(pair.second == PERMISSION_CHECK_FORBID_SYNC);
495     }
496     Value value3;
497     EXPECT_EQ(g_kvDelegatePtr->Get(key, value3), NOT_FOUND);
498     EXPECT_EQ(g_kvDelegatePtr->Get(key2, value3), NOT_FOUND);
499     PermissionCheckCallbackV2 nullCallback;
500     EXPECT_EQ(g_mgr.SetPermissionCheckCallback(nullCallback), OK);
501 }
502 
503 /**
504   * @tc.name: PermissionCheck006
505   * @tc.desc: deviceA PermissionCheck deviceB not pass, deviceC pass
506   * @tc.type: FUNC
507   * @tc.require: AR000EJJOJ
508   * @tc.author: wangchuanqing
509   */
510 HWTEST_F(DistributedDBSingleVerP2PPermissionSyncTest, PermissionCheck006, TestSize.Level3)
511 {
512     /**
513      * @tc.steps: step1. SetPermissionCheckCallback
514      * @tc.expected: step1. return OK.
515      */
516     auto permissionCheckCallback = [] (const std::string &userId, const std::string &appId, const std::string &storeId,
__anone28338ea0802(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) 517         const std::string &deviceId, uint8_t flag) -> bool {
518             if (deviceId == g_deviceB->GetDeviceId()) {
519                 LOGD("in RunPermissionCheck callback func, check not pass, flag:%d", flag);
520                 return false;
521             } else {
522                 LOGD("in RunPermissionCheck callback func, check pass, flag:%d", flag);
523                 return true;
524             }
525         };
526     EXPECT_EQ(g_mgr.SetPermissionCheckCallback(permissionCheckCallback), OK);
527     DBStatus status = OK;
528     std::vector<std::string> devices;
529     devices.push_back(g_deviceB->GetDeviceId());
530     devices.push_back(g_deviceC->GetDeviceId());
531 
532     /**
533      * @tc.steps: step2. deviceA put {k1, v1}
534      */
535     Key key = {'1'};
536     Value value = {'1'};
537     status = g_kvDelegatePtr->Put(key, value);
538     ASSERT_TRUE(status == OK);
539 
540     /**
541      * @tc.steps: step3. deviceA call sync and wait
542      * @tc.expected: step3. sync should return OK.
543      */
544     std::map<std::string, DBStatus> result;
545     status = g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PUSH_ONLY, result);
546     ASSERT_TRUE(status == OK);
547 
548     /**
549      * @tc.expected: step3. onComplete should be called,
550      * status == PERMISSION_CHECK_FORBID_SYNC, deviceB and deviceC do not have {k1, v1}
551      */
552     ASSERT_TRUE(result.size() == devices.size());
553     for (const auto &pair : result) {
554         LOGD("dev %s, status %d", pair.first.c_str(), pair.second);
555         if (g_deviceB->GetDeviceId() == pair.first) {
556             EXPECT_TRUE(pair.second == PERMISSION_CHECK_FORBID_SYNC);
557         } else {
558             EXPECT_TRUE(pair.second == OK);
559         }
560     }
561     VirtualDataItem item;
562     g_deviceB->GetData(key, item);
563     EXPECT_TRUE(item.value.empty());
564     g_deviceC->GetData(key, item);
565     EXPECT_TRUE(item.value == value);
566     PermissionCheckCallbackV2 nullCallback;
567     EXPECT_EQ(g_mgr.SetPermissionCheckCallback(nullCallback), OK);
568 }
569 
570 /**
571   * @tc.name: PermissionCheck007
572   * @tc.desc: deviceA PermissionCheck, deviceB not pass, deviceC pass in SYNC_MODE_AUTO_PUSH
573   * @tc.type: FUNC
574   * @tc.require: AR000G3RLS
575   * @tc.author: zhuwentao
576   */
577 HWTEST_F(DistributedDBSingleVerP2PPermissionSyncTest, PermissionCheck007, TestSize.Level3)
578 {
579     /**
580      * @tc.steps: step1. SetPermissionCheckCallback
581      * @tc.expected: step1. return OK.
582      */
583     auto permissionCheckCallback = [] (const std::string &userId, const std::string &appId, const std::string &storeId,
__anone28338ea0902(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) 584         const std::string &deviceId, uint8_t flag) -> bool {
585             if (deviceId == g_deviceC->GetDeviceId() &&
586                 (flag & (CHECK_FLAG_RECEIVE | CHECK_FLAG_AUTOSYNC))) {
587                 LOGD("in RunPermissionCheck callback func, check not pass, flag:%d", flag);
588                 return false;
589             } else {
590                 LOGD("in RunPermissionCheck callback func, check pass, flag:%d", flag);
591                 return true;
592             }
593         };
594     EXPECT_EQ(g_mgr.SetPermissionCheckCallback(permissionCheckCallback), OK);
595     DBStatus status = OK;
596     std::vector<std::string> devices;
597     devices.push_back(g_deviceB->GetDeviceId());
598     devices.push_back(g_deviceC->GetDeviceId());
599     /**
600      * @tc.steps: step2. deviceA set auto sync
601      */
602     bool autoSync = true;
603     PragmaData data = static_cast<PragmaData>(&autoSync);
604     status = g_kvDelegatePtr->Pragma(AUTO_SYNC, data);
605     ASSERT_EQ(status, OK);
606 
607     /**
608      * @tc.steps: step3. deviceA put {k1, v1}, and sleep 1s
609      */
610     Key key = {'1'};
611     Value value = {'1'};
612     status = g_kvDelegatePtr->Put(key, value);
613     ASSERT_TRUE(status == OK);
614     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
615 
616     /**
617      * @tc.steps: step3. check value in device B and not in device C.
618      */
619     VirtualDataItem item;
620     g_deviceC->GetData(key, item);
621     EXPECT_TRUE(item.value.empty());
622     g_deviceB->GetData(key, item);
623     EXPECT_TRUE(item.value == value);
624     PermissionCheckCallbackV2 nullCallback;
625     EXPECT_EQ(g_mgr.SetPermissionCheckCallback(nullCallback), OK);
626 }
627 
628 /**
629 +  * @tc.name: PermissionCheck008
630 +  * @tc.desc: deviceA PermissionCheck, deviceB not pass, deviceC pass in SYNC_MODE_AUTO_PULL
631 +  * @tc.type: FUNC
632 +  * @tc.require: AR000G3RLS
633 +  * @tc.author: zhangqiquan
634 +  */
635 HWTEST_F(DistributedDBSingleVerP2PPermissionSyncTest, PermissionCheck008, TestSize.Level3)
636 {
637     /**
638      * @tc.steps: step1. SetPermissionCheckCallback
639      * @tc.expected: step1. return OK.
640      */
641     auto permissionCheckCallback = [] (const std::string &userId, const std::string &appId, const std::string &storeId,
__anone28338ea0a02(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) 642         const std::string &deviceId, uint8_t flag) -> bool {
643             if (deviceId == g_deviceC->GetDeviceId() &&
644                 (flag & CHECK_FLAG_SPONSOR)) {
645                 LOGD("in RunPermissionCheck callback func, check not pass, flag:%d", flag);
646                 return false;
647             } else {
648                 LOGD("in RunPermissionCheck callback func, check pass, flag:%d", flag);
649                 return true;
650             }
651         };
652     EXPECT_EQ(g_mgr.SetPermissionCheckCallback(permissionCheckCallback), OK);
653     DBStatus status = OK;
654     std::vector<std::string> devices;
655     devices.push_back(g_deviceB->GetDeviceId());
656     devices.push_back(g_deviceC->GetDeviceId());
657 
658     /**
659      * @tc.steps: step2. deviceB put {k1, v1}
660      */
661     Key key = {'1'};
662     Value value = {'1'};
663     g_deviceB->PutData(key, value, 0, 0);
664 
665     /**
666      * @tc.steps: step2. device put {k2, v2}
667      */
668     Key key2 = {'2'};
669     Value value2 = {'2'};
670     g_deviceC->PutData(key2, value2, 0, 0);
671     ASSERT_TRUE(status == OK);
672 
673     /**
674      * @tc.steps: step3. deviceA call push sync
675      * @tc.expected: step3. sync should return OK.
676      */
677     std::map<std::string, DBStatus> result;
678     status = g_tool.SyncTest(g_kvDelegatePtr, devices, SYNC_MODE_PULL_ONLY, result);
679     ASSERT_TRUE(status == OK);
680     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
681 
682     /**
683      * @tc.expected: step4. onComplete should be called,
684      * status == PERMISSION_CHECK_FORBID_SYNC, deviceB and deviceC do not have {k1, v1}
685      */
686     ASSERT_TRUE(result.size() == devices.size());
687     for (const auto &pair : result) {
688         LOGD("dev %s, status %d", pair.first.c_str(), pair.second);
689         if (g_deviceC->GetDeviceId() == pair.first) {
690                 EXPECT_TRUE(pair.second == PERMISSION_CHECK_FORBID_SYNC);
691             } else {
692                 EXPECT_TRUE(pair.second == OK);
693         }
694     }
695     /**
696      * @tc.steps: step5. check value in device A
697      */
698     Value value4;
699     EXPECT_TRUE(g_kvDelegatePtr->Get(key, value4) == OK);
700     EXPECT_TRUE(g_kvDelegatePtr->Get(key2, value4) == NOT_FOUND);
701     PermissionCheckCallbackV2 nullCallback;
702     EXPECT_EQ(g_mgr.SetPermissionCheckCallback(nullCallback), OK);
703 }
704 
705 /**
706   * @tc.name: PermissionCheck009
707   * @tc.desc: different runpermissioncheck call return different value
708   * @tc.type: FUNC
709   * @tc.require: AR000D4876
710   * @tc.author: zhuwentao
711   */
712 HWTEST_F(DistributedDBSingleVerP2PPermissionSyncTest, PermissionCheck009, TestSize.Level3)
713 {
714     /**
715      * @tc.steps: step1. SetPermissionCheckCallback
716      * @tc.expected: step1. return OK.
717      */
718     int count = 1;
719     auto permissionCheckCallback = [&count] (const std::string &userId, const std::string &appId,
__anone28338ea0b02(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) 720         const std::string &storeId, const std::string &deviceId, uint8_t flag) -> bool {
721             (void)userId;
722             (void)appId;
723             (void)storeId;
724             (void)deviceId;
725             if (flag & CHECK_FLAG_SEND) {
726                 bool result = count % 2;
727                 LOGD("in RunPermissionCheck callback, check result:%d, flag:%d", result, flag);
728                 count++;
729                 return result;
730             }
731             LOGD("in RunPermissionCheck callback, check pass, flag:%d", flag);
732             return true;
733         };
734     EXPECT_EQ(g_mgr.SetPermissionCheckCallback(permissionCheckCallback), OK);
735     std::vector<std::string> devices = {g_deviceB->GetDeviceId()};
736     /**
737      * @tc.steps: step2. deviceA call sync three times and not wait
738      * @tc.expected: step2. sync should return OK.
739      */
740     std::map<std::string, DBStatus> result;
741     ASSERT_TRUE(g_kvDelegatePtr->Sync(devices, SYNC_MODE_PUSH_ONLY,
__anone28338ea0c02(const std::map<std::string, DBStatus>& statusMap) 742         [&result](const std::map<std::string, DBStatus>& statusMap) {
743             result = statusMap;
744         }, false) == OK);
745     std::map<std::string, DBStatus> result2;
746     ASSERT_TRUE(g_kvDelegatePtr->Sync(devices, SYNC_MODE_PUSH_ONLY,
__anone28338ea0d02(const std::map<std::string, DBStatus>& statusMap) 747         [&result2](const std::map<std::string, DBStatus>& statusMap) {
748             result2 = statusMap;
749         }, false) == OK);
750     std::map<std::string, DBStatus> result3;
751     ASSERT_TRUE(g_kvDelegatePtr->Sync(devices, SYNC_MODE_PUSH_ONLY,
__anone28338ea0e02(const std::map<std::string, DBStatus>& statusMap) 752         [&result3](const std::map<std::string, DBStatus>& statusMap) {
753             result3 = statusMap;
754         }, false) == OK);
755     std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME));
756     /**
757      * @tc.expected: step3. onComplete should be called,
758      * status is : OK, PERMISSION_CHECK_FORBID_SYNC, OK
759      */
760     ASSERT_TRUE(result.size() == devices.size());
761     for (const auto &pair : result) {
762         EXPECT_TRUE(pair.second == OK);
763     }
764     ASSERT_TRUE(result2.size() == devices.size());
765     for (const auto &pair : result2) {
766         EXPECT_TRUE(pair.second == PERMISSION_CHECK_FORBID_SYNC);
767     }
768     ASSERT_TRUE(result3.size() == devices.size());
769     for (const auto &pair : result3) {
770         EXPECT_TRUE(pair.second == OK);
771     }
772     PermissionCheckCallbackV2 nullCallback;
773     EXPECT_EQ(g_mgr.SetPermissionCheckCallback(nullCallback), OK);
774 }
775 
776 /**
777   * @tc.name: PermissionCheck010
778   * @tc.desc: permission check cost lot of time and return false
779   * @tc.type: FUNC
780   * @tc.require: AR000D4876
781   * @tc.author: zhangqiquan
782   */
783 HWTEST_F(DistributedDBSingleVerP2PPermissionSyncTest, PermissionCheck010, TestSize.Level3)
784 {
785     /**
786      * @tc.steps: step1. SetPermissionCheckCallback
787      * @tc.expected: step1. return OK.
788      */
789     int count = 0;
790     auto permissionCheckCallback = [&count] (const std::string &userId, const std::string &appId,
__anone28338ea0f02(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) 791         const std::string &storeId, const std::string &deviceId, uint8_t flag) -> bool {
792         std::this_thread::sleep_for(std::chrono::seconds(1));
793         count++;
794         LOGD("check permission %d", count);
795         return count > 1;
796     };
797     EXPECT_EQ(g_mgr.SetPermissionCheckCallback(permissionCheckCallback), OK);
798     /**
799      * @tc.steps: step2. put (k1, v1)
800      * @tc.expected: step2. return OK.
801      */
802     Key k1 = {'k', '1'};
803     Value v1 = {'v', '1'};
804     EXPECT_EQ(g_kvDelegatePtr->Put(k1, v1), OK);
805     /**
806      * @tc.steps: step3. sync to DEVICE_B twice
807      * @tc.expected: step3. return OK.
808      */
809     std::vector<std::string> devices;
810     devices.push_back(DEVICE_B);
811     EXPECT_TRUE(g_kvDelegatePtr->Sync(devices, SYNC_MODE_PUSH_ONLY, nullptr, false) == OK);
812     EXPECT_TRUE(g_kvDelegatePtr->Sync(devices, SYNC_MODE_PUSH_ONLY, nullptr, true) == OK);
813     /**
814      * @tc.steps: step4. (k1, v1) exist in DeviceB
815      * @tc.expected: step4. get return OK.
816      */
817     VirtualDataItem actualValue;
818     EXPECT_EQ(g_deviceB->GetData(k1, actualValue), E_OK);
819     EXPECT_EQ(v1, actualValue.value);
820     PermissionCheckCallbackV2 nullCallback = nullptr;
821     EXPECT_EQ(g_mgr.SetPermissionCheckCallback(nullCallback), OK);
822 }