• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "kv_general_ut.h"
17 #include "process_communicator_test_stub.h"
18 
19 namespace DistributedDB {
20 using namespace testing::ext;
21 using namespace DistributedDB;
22 using namespace DistributedDBUnitTest;
23 
24 class DistributedDBKvMultiUserSyncTest : public KVGeneralUt {
25 protected:
26     void PrepareData();
27     void SyncStep1();
28     void SyncStep2();
29     void SyncStep3();
30     static void SetTargetUserId(const std::string &deviceId, const std::string &userId);
31     static constexpr const char *DEVICE_A = "DEVICE_A";
32     static constexpr const char *DEVICE_B = "DEVICE_B";
33     static constexpr const char *USER_ID_1 = "USER_ID_1";
34     static constexpr const char *USER_ID_2 = "USER_ID_2";
35     static constexpr const char *USER_ID_3 = "USER_ID_3";
36 };
37 
CheckData(KvStoreNbDelegate * delegate,const Key & key,const Value & expectValue)38 void CheckData(KvStoreNbDelegate *delegate, const Key &key, const Value &expectValue)
39 {
40     Value actualValue;
41     if (expectValue.empty()) {
42         EXPECT_EQ(delegate->Get(key, actualValue), NOT_FOUND);
43     } else {
44         EXPECT_EQ(delegate->Get(key, actualValue), OK);
45         EXPECT_EQ(actualValue, expectValue);
46     }
47 }
48 
SetTargetUserId(const std::string & deviceId,const std::string & userId)49 void DistributedDBKvMultiUserSyncTest::SetTargetUserId(const std::string &deviceId, const std::string &userId)
50 {
51     ICommunicatorAggregator *communicatorAggregator = nullptr;
52     RuntimeContext::GetInstance()->GetCommunicatorAggregator(communicatorAggregator);
53     ASSERT_NE(communicatorAggregator, nullptr);
54     auto virtualCommunicatorAggregator = static_cast<VirtualCommunicatorAggregator*>(communicatorAggregator);
55     auto communicator = static_cast<VirtualCommunicator*>(virtualCommunicatorAggregator->GetCommunicator(deviceId));
56     ASSERT_NE(communicator, nullptr);
57     communicator->SetTargetUserId(userId);
58 }
59 
PrepareData()60 void DistributedDBKvMultiUserSyncTest::PrepareData()
61 {
62     KvStoreNbDelegate::Option option;
63     option.syncDualTupleMode = true;
64     SetOption(option);
65 
66     StoreInfo storeInfo1 = {USER_ID_1, STORE_ID_1, APP_ID};
67     ASSERT_EQ(BasicUnitTest::InitDelegate(storeInfo1, DEVICE_A), E_OK);
68     auto store1 = GetDelegate(storeInfo1);
69     ASSERT_NE(store1, nullptr);
70 
71     StoreInfo storeInfo2 = {USER_ID_2, STORE_ID_1, APP_ID};
72     ASSERT_EQ(BasicUnitTest::InitDelegate(storeInfo2, DEVICE_A), E_OK);
73     auto store2 = GetDelegate(storeInfo2);
74     ASSERT_NE(store2, nullptr);
75 
76     EXPECT_EQ(store1->Put(KEY_1, VALUE_1), OK);
77     EXPECT_EQ(store1->Put(KEY_2, VALUE_2), OK);
78     EXPECT_EQ(store1->Put(KEY_3, VALUE_3), OK);
79     EXPECT_EQ(store2->Put(KEY_4, VALUE_4), OK);
80 
81     CheckData(store1, KEY_1, VALUE_1);
82     CheckData(store1, KEY_2, VALUE_2);
83     CheckData(store1, KEY_3, VALUE_3);
84     CheckData(store2, KEY_4, VALUE_4);
85     ASSERT_EQ(KVGeneralUt::CloseDelegate(storeInfo1), E_OK);
86     ASSERT_EQ(KVGeneralUt::CloseDelegate(storeInfo2), E_OK);
87 }
88 
SyncStep1()89 void DistributedDBKvMultiUserSyncTest::SyncStep1()
90 {
91     StoreInfo storeInfo1 = {USER_ID_1, STORE_ID_1, APP_ID};
92     ASSERT_EQ(BasicUnitTest::InitDelegate(storeInfo1, DEVICE_A), E_OK);
93     auto store1 = GetDelegate(storeInfo1);
94     ASSERT_NE(store1, nullptr);
95 
96     StoreInfo storeInfo3 = {USER_ID_1, STORE_ID_2, APP_ID};
97     ASSERT_EQ(BasicUnitTest::InitDelegate(storeInfo3, DEVICE_B), E_OK);
98     auto store3 = GetDelegate(storeInfo3);
99     ASSERT_NE(store3, nullptr);
100 
101     SetTargetUserId(DEVICE_A, USER_ID_1);
102     SetTargetUserId(DEVICE_B, USER_ID_1);
103     BlockPush(storeInfo1, storeInfo3);
104 
105     CheckData(store3, KEY_1, VALUE_1);
106     CheckData(store3, KEY_2, VALUE_2);
107     CheckData(store3, KEY_3, VALUE_3);
108 
109     ASSERT_EQ(KVGeneralUt::CloseDelegate(storeInfo1), E_OK);
110     ASSERT_EQ(KVGeneralUt::CloseDelegate(storeInfo3), E_OK);
111 }
112 
SyncStep2()113 void DistributedDBKvMultiUserSyncTest::SyncStep2()
114 {
115     StoreInfo storeInfo2 = {USER_ID_2, STORE_ID_1, APP_ID};
116     ASSERT_EQ(BasicUnitTest::InitDelegate(storeInfo2, DEVICE_A), E_OK);
117     auto store2 = GetDelegate(storeInfo2);
118     ASSERT_NE(store2, nullptr);
119 
120     StoreInfo storeInfo4 = {USER_ID_2, STORE_ID_2, APP_ID};
121     ASSERT_EQ(BasicUnitTest::InitDelegate(storeInfo4, DEVICE_B), E_OK);
122     auto store4 = GetDelegate(storeInfo4);
123     ASSERT_NE(store4, nullptr);
124 
125     SetTargetUserId(DEVICE_A, USER_ID_2);
126     SetTargetUserId(DEVICE_B, USER_ID_2);
127     BlockPush(storeInfo2, storeInfo4);
128 
129     CheckData(store4, KEY_1, {});
130     CheckData(store4, KEY_2, {});
131     CheckData(store4, KEY_3, {});
132     CheckData(store4, KEY_4, VALUE_4);
133 
134     ASSERT_EQ(KVGeneralUt::CloseDelegate(storeInfo2), E_OK);
135     ASSERT_EQ(KVGeneralUt::CloseDelegate(storeInfo4), E_OK);
136 }
137 
SyncStep3()138 void DistributedDBKvMultiUserSyncTest::SyncStep3()
139 {
140     StoreInfo storeInfo1 = {USER_ID_1, STORE_ID_1, APP_ID};
141     ASSERT_EQ(BasicUnitTest::InitDelegate(storeInfo1, DEVICE_A), E_OK);
142     auto store1 = GetDelegate(storeInfo1);
143     ASSERT_NE(store1, nullptr);
144 
145     StoreInfo storeInfo4 = {USER_ID_2, STORE_ID_2, APP_ID};
146     ASSERT_EQ(BasicUnitTest::InitDelegate(storeInfo4, DEVICE_B), E_OK);
147     auto store4 = GetDelegate(storeInfo4);
148     ASSERT_NE(store4, nullptr);
149 
150     SetTargetUserId(DEVICE_A, USER_ID_2);
151     SetTargetUserId(DEVICE_B, USER_ID_1);
152     BlockPush(storeInfo1, storeInfo4);
153 
154     CheckData(store4, KEY_1, VALUE_1);
155     CheckData(store4, KEY_2, VALUE_2);
156     CheckData(store4, KEY_3, VALUE_3);
157     CheckData(store4, KEY_4, VALUE_4);
158 
159     ASSERT_EQ(KVGeneralUt::CloseDelegate(storeInfo1), E_OK);
160     ASSERT_EQ(KVGeneralUt::CloseDelegate(storeInfo4), E_OK);
161 }
162 
163 /**
164  * @tc.name: NormalSyncTest001
165  * @tc.desc: Test normal sync.
166  * @tc.type: FUNC
167  * @tc.require:
168  * @tc.author: liaoyonghuang
169  */
170 HWTEST_F(DistributedDBKvMultiUserSyncTest, NormalSyncTest001, TestSize.Level1)
171 {
172     /**
173      * @tc.steps: step1. (devA, user1) put 3 records, (devA, user2) put 1 record
174      * @tc.expected: step1. OK.
175      */
176     PrepareData();
177     /**
178      * @tc.steps: step2. (devA, user1) sync to (devB, user1)
179      * @tc.expected: step2. OK.
180      */
181     SyncStep1();
182     /**
183      * @tc.steps: step3. (devA, user2) put 3 records, (devB, user2) put 1 record
184      * @tc.expected: step3. OK.
185      */
186     SyncStep2();
187     /**
188      * @tc.steps: step4. (devA, user1) put 3 records, (devB, user2) put 1 record
189      * @tc.expected: step4. OK.
190      */
191     SyncStep3();
192 }
193 
194 /**
195  * @tc.name: NormalSyncTest002
196  * @tc.desc: Test sync with low version target.
197  * @tc.type: FUNC
198  * @tc.require:
199  * @tc.author: liaoyonghuang
200  */
201 HWTEST_F(DistributedDBKvMultiUserSyncTest, NormalSyncTest002, TestSize.Level0)
202 {
203     /**
204      * @tc.steps: step1. Init process communicator
205      * @tc.expected: step1. OK.
206      */
207     KvStoreNbDelegate::Option option;
208     option.syncDualTupleMode = true;
209     SetOption(option);
210     std::shared_ptr<ProcessCommunicatorTestStub> processCommunicator =
211         std::make_shared<ProcessCommunicatorTestStub>();
212     processCommunicator->SetDataHeadInfo({DBStatus::LOW_VERSION_TARGET, 0u});
213     SetProcessCommunicator(processCommunicator);
214 
215     /**
216      * @tc.steps: step2. (devA, user1) put 1 record and sync to (devB, user2)
217      * @tc.expected: step2. OK.
218      */
219     StoreInfo storeInfo1 = {USER_ID_1, STORE_ID_1, APP_ID};
220     ASSERT_EQ(BasicUnitTest::InitDelegate(storeInfo1, DEVICE_A), E_OK);
221     auto store1 = GetDelegate(storeInfo1);
222     ASSERT_NE(store1, nullptr);
223     EXPECT_EQ(store1->Put(KEY_1, VALUE_1), OK);
224 
225     StoreInfo storeInfo2 = {USER_ID_2, STORE_ID_2, APP_ID};
226     ASSERT_EQ(BasicUnitTest::InitDelegate(storeInfo2, DEVICE_B), E_OK);
227     auto store2 = GetDelegate(storeInfo2);
228     ASSERT_NE(store2, nullptr);
229 
230     SetTargetUserId(DEVICE_A, USER_ID_2);
231     SetTargetUserId(DEVICE_B, USER_ID_1);
232     UserInfo userInfo = {.receiveUser = USER_ID_2, .sendUser = USER_ID_1};
233     processCommunicator->SetDataUserInfo({{userInfo}});
234     BlockPush(storeInfo1, storeInfo2);
235 
236     CheckData(store2, KEY_1, VALUE_1);
237 
238     ASSERT_EQ(KVGeneralUt::CloseDelegate(storeInfo2), E_OK);
239 
240     /**
241      * @tc.steps: step3. (devA, user1) put 1 record and sync to (devB, user3)
242      * @tc.expected: step3. OK.
243      */
244     StoreInfo storeInfo3 = {USER_ID_3, STORE_ID_2, APP_ID};
245     ASSERT_EQ(BasicUnitTest::InitDelegate(storeInfo3, DEVICE_B), E_OK);
246     auto store3 = GetDelegate(storeInfo3);
247     ASSERT_NE(store3, nullptr);
248 
249     EXPECT_EQ(store1->Put(KEY_2, VALUE_2), OK);
250 
251     SetTargetUserId(DEVICE_A, USER_ID_3);
252     SetTargetUserId(DEVICE_B, USER_ID_1);
253     userInfo = {.receiveUser = USER_ID_3, .sendUser = USER_ID_1};
254     processCommunicator->SetDataUserInfo({{userInfo}});
255     BlockPush(storeInfo1, storeInfo3);
256 
257     CheckData(store3, KEY_2, VALUE_2);
258 
259     ASSERT_EQ(KVGeneralUt::CloseDelegate(storeInfo1), E_OK);
260     ASSERT_EQ(KVGeneralUt::CloseDelegate(storeInfo3), E_OK);
261 }
262 
263 /**
264  * @tc.name: NormalSyncTest003
265  * @tc.desc: deviceA:user1 put 2 records and sync to deviceB, deviceA:user1 delete 1 records, deviceA:user2 put
266  * 2 records and sync to deviceB, deviceA:user1 sync to deviceB.
267  * @tc.type: FUNC
268  * @tc.require:
269  * @tc.author: liaoyonghuang
270  */
271 HWTEST_F(DistributedDBKvMultiUserSyncTest, NormalSyncTest003, TestSize.Level0)
272 {
273     /**
274      * @tc.steps: step1. set option
275      * @tc.expected: step1. OK.
276      */
277     KvStoreNbDelegate::Option option;
278     option.syncDualTupleMode = true;
279     option.conflictResolvePolicy = DEVICE_COLLABORATION;
280     SetOption(option);
281 
282     /**
283      * @tc.steps: step2. deviceA:user1 put 10 records and sync to deviceB, deviceA:user1 delete 1 records
284      * @tc.expected: step2. OK.
285      */
286     StoreInfo storeInfo1 = {USER_ID_1, STORE_ID_1, APP_ID};
287     ASSERT_EQ(BasicUnitTest::InitDelegate(storeInfo1, DEVICE_A), E_OK);
288     auto store1 = GetDelegate(storeInfo1);
289     ASSERT_NE(store1, nullptr);
290     EXPECT_EQ(store1->Put(KEY_1, VALUE_1), OK);
291     EXPECT_EQ(store1->Put(KEY_2, VALUE_2), OK);
292 
293     StoreInfo storeInfo3 = {USER_ID_3, STORE_ID_2, APP_ID};
294     ASSERT_EQ(BasicUnitTest::InitDelegate(storeInfo3, DEVICE_B), E_OK);
295     auto store3 = GetDelegate(storeInfo3);
296     ASSERT_NE(store3, nullptr);
297 
298     SetTargetUserId(DEVICE_A, USER_ID_3);
299     SetTargetUserId(DEVICE_B, USER_ID_1);
300     BlockPush(storeInfo1, storeInfo3);
301     EXPECT_EQ(store1->Delete(KEY_1), OK);
302     ASSERT_EQ(KVGeneralUt::CloseDelegate(storeInfo1), E_OK);
303 
304     /**
305      * @tc.steps: step3. deviceA:user2 put 2 records and sync to deviceB
306      * @tc.expected: step3. OK.
307      */
308     ASSERT_EQ(KVGeneralUt::CloseDelegate(storeInfo1), E_OK);
309 
310     StoreInfo storeInfo2 = {USER_ID_2, STORE_ID_1, APP_ID};
311     ASSERT_EQ(BasicUnitTest::InitDelegate(storeInfo2, DEVICE_A), E_OK);
312     auto store2 = GetDelegate(storeInfo2);
313     ASSERT_NE(store2, nullptr);
314     EXPECT_EQ(store2->Put(KEY_1, VALUE_1), OK);
315     EXPECT_EQ(store2->Put(KEY_2, VALUE_2), OK);
316 
317     SetTargetUserId(DEVICE_A, USER_ID_3);
318     SetTargetUserId(DEVICE_B, USER_ID_2);
319     BlockPush(storeInfo2, storeInfo3);
320     ASSERT_EQ(KVGeneralUt::CloseDelegate(storeInfo2), E_OK);
321 
322     /**
323      * @tc.steps: step4. deviceA:user1 sync to deviceB.
324      * @tc.expected: step4. OK.
325      */
326     ASSERT_EQ(BasicUnitTest::InitDelegate(storeInfo1, DEVICE_A), E_OK);
327     BlockPush(storeInfo1, storeInfo3);
328     Value actualValue;
329     EXPECT_EQ(store3->Get(KEY_1, actualValue), NOT_FOUND);
330     ASSERT_EQ(KVGeneralUt::CloseDelegate(storeInfo1), E_OK);
331     ASSERT_EQ(KVGeneralUt::CloseDelegate(storeInfo3), E_OK);
332 }
333 
334 /**
335  * @tc.name: InvalidSync001
336  * @tc.desc: Test sync with empty target user.
337  * @tc.type: FUNC
338  * @tc.require:
339  * @tc.author: liaoyonghuang
340  */
341 HWTEST_F(DistributedDBKvMultiUserSyncTest, InvalidSync001, TestSize.Level0)
342 {
343     /**
344      * @tc.steps: step1. (devA, user1) put 3 records, (devA, user2) put 1 record
345      * @tc.expected: step1. OK.
346      */
347     KvStoreNbDelegate::Option option;
348     option.syncDualTupleMode = true;
349     SetOption(option);
350     StoreInfo storeInfo1 = {USER_ID_1, STORE_ID_1, APP_ID};
351     ASSERT_EQ(BasicUnitTest::InitDelegate(storeInfo1, DEVICE_A), E_OK);
352     auto store1 = GetDelegate(storeInfo1);
353     ASSERT_NE(store1, nullptr);
354 
355     StoreInfo storeInfo2 = {USER_ID_2, STORE_ID_1, APP_ID};
356     ASSERT_EQ(BasicUnitTest::InitDelegate(storeInfo2, DEVICE_B), E_OK);
357     auto store2 = GetDelegate(storeInfo2);
358     ASSERT_NE(store2, nullptr);
359 
360     EXPECT_EQ(store1->Put(KEY_1, VALUE_1), OK);
361     EXPECT_EQ(store1->Put(KEY_2, VALUE_2), OK);
362     EXPECT_EQ(store1->Put(KEY_3, VALUE_3), OK);
363     EXPECT_EQ(store2->Put(KEY_4, VALUE_4), OK);
364 
365     CheckData(store1, KEY_1, VALUE_1);
366     CheckData(store1, KEY_2, VALUE_2);
367     CheckData(store1, KEY_3, VALUE_3);
368     CheckData(store2, KEY_4, VALUE_4);
369     /**
370      * @tc.steps: step2. set empty target user and sync
371      * @tc.expected: step2. return OK.
372      */
373     SetTargetUserId(DEVICE_A, "");
374     BlockPush(storeInfo1, storeInfo2);
375     ASSERT_EQ(KVGeneralUt::CloseDelegate(storeInfo1), E_OK);
376     ASSERT_EQ(KVGeneralUt::CloseDelegate(storeInfo2), E_OK);
377 }
378 }