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