1 /*
2 * Copyright (c) 2021-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
16 #include "gtest/gtest.h"
17
18 #include <thread>
19
20 #include "utils.h"
21
22 #include "device_profile_errors.h"
23 #include "distributed_device_profile_client.h"
24 #include "nlohmann/json.hpp"
25
26 namespace OHOS {
27 namespace DeviceProfile {
28 using namespace std::chrono_literals;
29 using namespace testing;
30 using namespace testing::ext;
31
32 namespace {
33 const int32_t UT_ERROR = -1;
34 }
35 class EventSubscribeTest : public testing::Test {
36 public:
37 static void SetUpTestCase();
38 static void TearDownTestCase();
39 void SetUp();
40 void TearDown();
41 };
42
SetUpTestCase()43 void EventSubscribeTest::SetUpTestCase()
44 {
45 DistributedDeviceProfileClient::GetInstance().DeleteDeviceProfile("111111");
46 }
47
TearDownTestCase()48 void EventSubscribeTest::TearDownTestCase()
49 {
50 }
51
SetUp()52 void EventSubscribeTest::SetUp()
53 {
54 }
55
TearDown()56 void EventSubscribeTest::TearDown()
57 {
58 }
59
60 class ProfileEventCallback : public IProfileEventCallback {
61 public:
62 ProfileEventCallback() = default;
63 ~ProfileEventCallback() = default;
64
OnSyncCompleted(const SyncResult & syncResults)65 void OnSyncCompleted(const SyncResult& syncResults) override
66 {
67 }
68
OnProfileChanged(const ProfileChangeNotification & changeNotification)69 void OnProfileChanged(const ProfileChangeNotification& changeNotification) override
70 {
71 if (!subServiceIds_.empty()) {
72 const auto& profileEntries = changeNotification.GetProfileEntries();
73 for (const auto& ProfileEntry : profileEntries) {
74 auto key = ProfileEntry.key;
75 DTEST_LOG << "key: " << key << std::endl;
76 auto iter = std::find(subServiceIds_.begin(), subServiceIds_.end(), key);
77 EXPECT_TRUE(iter != subServiceIds_.end());
78 numNotifications_++;
79 }
80 }
81 }
82
SetSubServiceIds(const std::list<std::string> & subServiceIds)83 void SetSubServiceIds(const std::list<std::string>& subServiceIds)
84 {
85 subServiceIds_ = subServiceIds;
86 }
87
GetNotificationNum() const88 int32_t GetNotificationNum() const
89 {
90 return numNotifications_;
91 }
92
93 private:
94 std::list<std::string> subServiceIds_;
95 int32_t numNotifications_ {0};
96 };
97
PutFakeStorage()98 int32_t PutFakeStorage()
99 {
100 ServiceCharacteristicProfile profile;
101 profile.SetServiceId("fakeStorage");
102 profile.SetServiceType("fakeStorage");
103 nlohmann::json j;
104 j["capacity"] = 0;
105 profile.SetCharacteristicProfileJson(j.dump());
106 return DistributedDeviceProfileClient::GetInstance().PutDeviceProfile(profile);
107 }
108
PutFakeSystem()109 int32_t PutFakeSystem()
110 {
111 ServiceCharacteristicProfile profile;
112 profile.SetServiceId("fakeSystem");
113 profile.SetServiceType("fakeSystem");
114 nlohmann::json j;
115 j["harmonyVersion"] = "2.2.0";
116 profile.SetCharacteristicProfileJson(j.dump());
117 return DistributedDeviceProfileClient::GetInstance().PutDeviceProfile(profile);
118 }
119
MockSubscribeEvents(const std::shared_ptr<ProfileEventCallback> & eventCb,const std::list<std::string> & serviceIds,const std::string & deviceId)120 int32_t MockSubscribeEvents(const std::shared_ptr<ProfileEventCallback>& eventCb,
121 const std::list<std::string>& serviceIds, const std::string& deviceId)
122 {
123 if (eventCb == nullptr) {
124 return UT_ERROR;
125 }
126 eventCb->SetSubServiceIds(serviceIds);
127 ExtraInfo extraInfo;
128 extraInfo["deviceId"] = deviceId;
129 extraInfo["serviceIds"] = serviceIds;
130
131 std::list<SubscribeInfo> subscribeInfos;
132 SubscribeInfo eventChange;
133 eventChange.profileEvent = ProfileEvent::EVENT_PROFILE_CHANGED;
134 eventChange.extraInfo = std::move(extraInfo);
135 subscribeInfos.emplace_back(eventChange);
136
137 SubscribeInfo eventSync;
138 eventSync.profileEvent = ProfileEvent::EVENT_SYNC_COMPLETED;
139 subscribeInfos.emplace_back(eventSync);
140
141 std::list<ProfileEvent> failedEvents;
142 return DistributedDeviceProfileClient::GetInstance().SubscribeProfileEvents(
143 subscribeInfos, eventCb, failedEvents);
144 }
145
MockUnsubscribeEvents(const std::shared_ptr<ProfileEventCallback> & eventCb)146 int32_t MockUnsubscribeEvents(const std::shared_ptr<ProfileEventCallback>& eventCb)
147 {
148 if (eventCb == nullptr) {
149 return UT_ERROR;
150 }
151 std::list<ProfileEvent> profileEvents;
152 profileEvents.emplace_back(ProfileEvent::EVENT_PROFILE_CHANGED);
153 profileEvents.emplace_back(ProfileEvent::EVENT_SYNC_COMPLETED);
154 std::list<ProfileEvent> failedEvents;
155 return DistributedDeviceProfileClient::GetInstance().UnsubscribeProfileEvents(
156 profileEvents, eventCb, failedEvents);
157 }
158
MockSubscribeEvent(const std::shared_ptr<ProfileEventCallback> & eventCb,const std::list<std::string> & serviceIds,const std::string & deviceId)159 int32_t MockSubscribeEvent(const std::shared_ptr<ProfileEventCallback>& eventCb,
160 const std::list<std::string>& serviceIds, const std::string& deviceId)
161 {
162 if (eventCb == nullptr) {
163 return UT_ERROR;
164 }
165 eventCb->SetSubServiceIds(serviceIds);
166 ExtraInfo extraInfo;
167 extraInfo["deviceId"] = deviceId;
168 extraInfo["serviceIds"] = serviceIds;
169
170 SubscribeInfo subscribeInfo;
171 subscribeInfo.profileEvent = ProfileEvent::EVENT_PROFILE_CHANGED;
172 subscribeInfo.extraInfo = std::move(extraInfo);
173 return DistributedDeviceProfileClient::GetInstance().SubscribeProfileEvent(subscribeInfo, eventCb);
174 }
175
176 /**
177 * @tc.name: Subscribe001
178 * @tc.desc: subscribe a service and put a service profile
179 * @tc.type: FUNC
180 */
181 HWTEST_F(EventSubscribeTest, Subscribe001, TestSize.Level2)
182 {
183 auto callback = std::make_shared<ProfileEventCallback>();
184 if (MockSubscribeEvent(callback, {"fakeStorage"}, "")) {
185 EXPECT_TRUE(MockSubscribeEvent(callback, {"fakeStorage"}, ""));
186 DTEST_LOG << "subscribe failed" << std::endl;
187 return;
188 }
189
190 int32_t errCode = PutFakeStorage();
191 EXPECT_EQ(errCode, ERR_OK);
192 if (errCode == ERR_OK) {
193 DTEST_LOG << "put succeeded" << std::endl;
194 std::this_thread::sleep_for(1s);
195 EXPECT_TRUE(callback->GetNotificationNum() == 1);
196 }
197 }
198
199 /**
200 * @tc.name: Subscribe002
201 * @tc.desc: subscribe a service and put a unsubscribed service
202 * @tc.type: FUNC
203 */
204 HWTEST_F(EventSubscribeTest, Subscribe002, TestSize.Level2)
205 {
206 auto callback = std::make_shared<ProfileEventCallback>();
207 if (MockSubscribeEvent(callback, {"fakeSystem"}, "")) {
208 EXPECT_TRUE(MockSubscribeEvent(callback, {"fakeSystem"}, ""));
209 DTEST_LOG << "subscribe failed" << std::endl;
210 return;
211 }
212 int32_t errCode = PutFakeStorage();
213 EXPECT_EQ(errCode, ERR_OK);
214 if (errCode == ERR_OK) {
215 DTEST_LOG << "put succeeded" << std::endl;
216 std::this_thread::sleep_for(1s);
217 EXPECT_TRUE(callback->GetNotificationNum() == 0);
218 }
219 }
220
221 /**
222 * @tc.name: Subscribe003
223 * @tc.desc: subscribe services and put service
224 * @tc.type: FUNC
225 */
226 HWTEST_F(EventSubscribeTest, Subscribe003, TestSize.Level2)
227 {
228 auto callback = std::make_shared<ProfileEventCallback>();
229 std::list<std::string> serviceIds = {"fakeStorage", "fakeSystem"};
230 if (MockSubscribeEvents(callback, serviceIds, "") != ERR_OK) {
231 EXPECT_NE(MockSubscribeEvents(callback, serviceIds, ""), ERR_OK);
232 DTEST_LOG << "subscribe failed" << std::endl;
233 return;
234 }
235 int32_t errCode = PutFakeSystem();
236 EXPECT_EQ(errCode, ERR_OK);
237 if (errCode == ERR_OK) {
238 DTEST_LOG << "put succeeded" << std::endl;
239 std::this_thread::sleep_for(1s);
240 EXPECT_TRUE(callback->GetNotificationNum() == 1);
241 }
242 }
243
244 /**
245 * @tc.name: Subscribe004
246 * @tc.desc: subscribe with invalid deviceId
247 * @tc.type: FUNC
248 */
249 HWTEST_F(EventSubscribeTest, Subscribe004, TestSize.Level2)
250 {
251 auto callback = std::make_shared<ProfileEventCallback>();
252 std::list<std::string> serviceIds = {"fakeStorage", "fakeSystem"};
253 if (MockSubscribeEvent(callback, serviceIds, "fake_device_id") != ERR_OK) {
254 EXPECT_NE(MockSubscribeEvent(callback, serviceIds, "fake_device_id"), ERR_OK);
255 DTEST_LOG << "subscribe failed" << std::endl;
256 return;
257 }
258 int32_t errCode = PutFakeStorage();
259 EXPECT_EQ(errCode, ERR_OK);
260 if (errCode == ERR_OK) {
261 DTEST_LOG << "put succeeded" << std::endl;
262 std::this_thread::sleep_for(1s);
263 EXPECT_TRUE(callback->GetNotificationNum() == 0);
264 }
265 }
266
267 /**
268 * @tc.name: Subscribe005
269 * @tc.desc: subscribe services and put services
270 * @tc.type: FUNC
271 */
272 HWTEST_F(EventSubscribeTest, Subscribe005, TestSize.Level2)
273 {
274 auto callback = std::make_shared<ProfileEventCallback>();
275 /**
276 * @tc.steps: step1. subscribe change event with two services
277 */
278 std::list<std::string> serviceIds = {"fakeStorage", "fakeSystem"};
279 if (MockSubscribeEvent(callback, serviceIds, "") != ERR_OK) {
280 EXPECT_NE(MockSubscribeEvent(callback, serviceIds, ""), ERR_OK);
281 DTEST_LOG << "subscribe failed" << std::endl;
282 return;
283 }
284
285 /**
286 * @tc.steps: step2. put service profile which is subscribed
287 * @tc.expected: step2. got one notification.
288 */
289 int32_t errCode = PutFakeStorage();
290 EXPECT_EQ(errCode, ERR_OK);
291 if (errCode == ERR_OK) {
292 DTEST_LOG << "put succeeded" << std::endl;
293 std::this_thread::sleep_for(1s);
294 EXPECT_TRUE(callback->GetNotificationNum() == 1);
295 }
296 /**
297 * @tc.steps: step3. put the other subscribed service profile
298 * @tc.expected: step3. got notification again.
299 */
300 errCode = PutFakeSystem();
301 EXPECT_EQ(errCode, ERR_OK);
302 if (errCode == ERR_OK) {
303 DTEST_LOG << "put succeeded" << std::endl;
304 std::this_thread::sleep_for(1s);
305 EXPECT_TRUE(callback->GetNotificationNum() == 2);
306 }
307 }
308
309 /**
310 * @tc.name: Subscribe006
311 * @tc.desc: subscribe with duplicated events
312 * @tc.type: FUNC
313 */
314 HWTEST_F(EventSubscribeTest, Subscribe006, TestSize.Level0)
315 {
316 auto callback = std::make_shared<ProfileEventCallback>();
317 std::list<SubscribeInfo> subscribeInfos;
318 ExtraInfo extraInfo;
319 extraInfo["deviceId"] = "";
320 extraInfo["serviceIds"] = {"fakeSystem"};
321
322 SubscribeInfo eventChange;
323 eventChange.profileEvent = ProfileEvent::EVENT_PROFILE_CHANGED;
324 eventChange.extraInfo = std::move(extraInfo);
325 subscribeInfos.emplace_back(eventChange);
326 subscribeInfos.emplace_back(eventChange);
327
328 std::list<ProfileEvent> failedEvents;
329 int32_t errCode = DistributedDeviceProfileClient::GetInstance().SubscribeProfileEvents(
330 subscribeInfos, callback, failedEvents);
331 EXPECT_TRUE(errCode == ERR_DP_INVALID_PARAMS);
332 }
333
334 /**
335 * @tc.name: Unsubscribe001
336 * @tc.desc: unsubscribe event which is not subscribed yet
337 * @tc.type: FUNC
338 */
339 HWTEST_F(EventSubscribeTest, Unsubscribe001, TestSize.Level0)
340 {
341 auto callback = std::make_shared<ProfileEventCallback>();
342 int32_t errCode = DistributedDeviceProfileClient::GetInstance().UnsubscribeProfileEvent(
343 ProfileEvent::EVENT_PROFILE_CHANGED, callback);
344 EXPECT_TRUE(errCode == ERR_DP_NOT_SUBSCRIBED);
345 }
346
347 /**
348 * @tc.name: Unsubscribe002
349 * @tc.desc: unsubscribe events which are not subscribed yet
350 * @tc.type: FUNC
351 */
352 HWTEST_F(EventSubscribeTest, Unsubscribe002, TestSize.Level0)
353 {
354 auto callback = std::make_shared<ProfileEventCallback>();
355 int32_t errCode = MockUnsubscribeEvents(callback);
356 EXPECT_TRUE(errCode == ERR_DP_NOT_SUBSCRIBED);
357 }
358
359 /**
360 * @tc.name: SubscribeWithUnsusbscribe001
361 * @tc.desc: subscribe events and then unsubscribe one
362 * @tc.type: FUNC
363 */
364 HWTEST_F(EventSubscribeTest, SubscribeWithUnsusbscribe001, TestSize.Level2)
365 {
366 auto callback = std::make_shared<ProfileEventCallback>();
367
368 /**
369 * @tc.steps: step1. subscribe sync and change event
370 */
371 std::list<std::string> serviceIds = {"fakeStorage", "fakeSystem"};
372 if (MockSubscribeEvents(callback, serviceIds, "") != ERR_OK) {
373 EXPECT_NE(MockSubscribeEvents(callback, serviceIds, ""), ERR_OK);
374 DTEST_LOG << "subscribe failed" << std::endl;
375 return;
376 }
377
378 /**
379 * @tc.steps: step2. put service profile which is subscribed
380 * @tc.expected: step2. got one notification.
381 */
382 int32_t errCode = PutFakeSystem();
383 EXPECT_EQ(errCode, ERR_OK);
384 if (errCode == ERR_OK) {
385 DTEST_LOG << "put succeeded" << std::endl;
386 std::this_thread::sleep_for(1s);
387 EXPECT_TRUE(callback->GetNotificationNum() == 1);
388 }
389
390 /**
391 * @tc.steps: step3. unsubscribe sync event
392 */
393 errCode = DistributedDeviceProfileClient::GetInstance().UnsubscribeProfileEvent(
394 ProfileEvent::EVENT_SYNC_COMPLETED, callback);
395 if (errCode != ERR_OK) {
396 EXPECT_NE(errCode, ERR_OK);
397 DTEST_LOG << "unsubscribe failed" << std::endl;
398 return;
399 }
400 EXPECT_EQ(errCode, ERR_OK);
401
402 /**
403 * @tc.steps: step4. put the other subscribed service profile
404 * @tc.expected: step4. got notification again.
405 */
406 errCode = PutFakeStorage();
407 EXPECT_EQ(errCode, ERR_OK);
408 if (errCode == ERR_OK) {
409 DTEST_LOG << "put succeeded" << std::endl;
410 std::this_thread::sleep_for(1s);
411 EXPECT_TRUE(callback->GetNotificationNum() == 2);
412 }
413 }
414
415 /**
416 * @tc.name: SubscribeWithUnsusbscribe002
417 * @tc.desc: subscribe events and then unsubscribe all
418 * @tc.type: FUNC
419 */
420 HWTEST_F(EventSubscribeTest, SubscribeWithUnsusbscribe002, TestSize.Level2)
421 {
422 auto callback = std::make_shared<ProfileEventCallback>();
423
424 /**
425 * @tc.steps: step1. subscribe sync and change event
426 */
427 std::list<std::string> serviceIds = {"fakeStorage", "fakeSystem"};
428 if (MockSubscribeEvents(callback, serviceIds, "") != ERR_OK) {
429 EXPECT_NE(MockSubscribeEvents(callback, serviceIds, ""), ERR_OK);
430 DTEST_LOG << "subscribe failed" << std::endl;
431 return;
432 }
433
434 /**
435 * @tc.steps: step2. put service profile which is subscribed
436 * @tc.expected: step2. got one notification.
437 */
438 int32_t errCode = PutFakeSystem();
439 EXPECT_EQ(errCode, ERR_OK);
440 if (errCode == ERR_OK) {
441 DTEST_LOG << "put succeeded" << std::endl;
442 std::this_thread::sleep_for(1s);
443 EXPECT_TRUE(callback->GetNotificationNum() == 1);
444 }
445
446 /**
447 * @tc.steps: step3. unsubscribe all events
448 */
449 if (MockUnsubscribeEvents(callback) != ERR_OK) {
450 EXPECT_NE(MockUnsubscribeEvents(callback), ERR_OK);
451 DTEST_LOG << "unsubscribe failed" << std::endl;
452 return;
453 }
454
455 /**
456 * @tc.steps: step4. put a subscribed service profile
457 * @tc.expected: step4. can't receive notification.
458 */
459 errCode = PutFakeStorage();
460 EXPECT_EQ(errCode, ERR_OK);
461 if (errCode == ERR_OK) {
462 DTEST_LOG << "put succeeded" << std::endl;
463 std::this_thread::sleep_for(1s);
464 EXPECT_TRUE(callback->GetNotificationNum() == 1);
465 }
466 }
467
468 /**
469 * @tc.name: SubDeviceProfile_001
470 * @tc.desc: sub device profile
471 * @tc.type: FUNC
472 * @tc.require: I51HKG
473 */
474 HWTEST_F(EventSubscribeTest, UnsubDeviceProfile_001, TestSize.Level3)
475 {
476 auto callback = std::make_shared<ProfileEventCallback>();
477 std::list<ProfileEvent> profileEvents;
478 profileEvents.emplace_back(ProfileEvent::EVENT_PROFILE_CHANGED);
479 std::list<ProfileEvent> failedEvents;
480 auto result = DistributedDeviceProfileClient::GetInstance().UnsubscribeProfileEvents(
481 profileEvents, callback, failedEvents);
482 DTEST_LOG << "result: " << result << std::endl;
483 EXPECT_NE(result, ERR_INVALID_DATA);
484 }
485 }
486 }