1 /*
2  * Copyright (c) 2021-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 <gtest/gtest.h>
17 
18 #include <thread>
19 #include "datetime_ex.h"
20 #include "common_event_command.h"
21 #include "common_event_manager.h"
22 #include "common_event_subscriber.h"
23 #include "nativetoken_kit.h"
24 #include "token_setproc.h"
25 
26 using namespace testing::ext;
27 using namespace OHOS;
28 using namespace OHOS::EventFwk;
29 
30 namespace {
31 const std::string STRING_EVENT = "com.ces.event";
32 const std::string STRING_CODE = "1024";
33 const std::string STRING_CODE_TWO = "2048";
34 const std::string STRING_DATA = "data";
35 const std::string STRING_DATA_TWO = "data_two";
36 const std::string STRING_DEVICE_ID_001 = "device_001";
37 const std::string STRING_DEVICE_ID_002 = "device_002";
38 const std::string STRING_DEVICE_ID_003 = "device_003";
39 const int32_t TIME_DELAY_FOR_SERVICES = 2;
40 const time_t TIME_OUT_SECONDS_LIMIT = 5;
41 std::mutex mtx;
42 
ExecuteCommand(const std::string & command)43 std::string ExecuteCommand(const std::string &command)
44 {
45     std::string result = "";
46     FILE *file = popen(command.c_str(), "r");
47 
48     // wait for services
49     std::this_thread::sleep_for(std::chrono::seconds(TIME_DELAY_FOR_SERVICES));
50 
51     if (file != nullptr) {
52         char commandResult[1024] = {0};
53         while ((fgets(commandResult, sizeof(commandResult), file)) != nullptr) {
54             result.append(commandResult);
55         }
56         pclose(file);
57         file = nullptr;
58     }
59 
60     return result;
61 }
62 }  // namespace
63 
64 class CemCommandPublishSystemTest : public ::testing::Test {
65 public:
66     static void SetUpTestCase();
67     static void TearDownTestCase();
68     void SetUp() override;
69     void TearDown() override;
70 };
71 
SetUpTestCase()72 void CemCommandPublishSystemTest::SetUpTestCase()
73 {
74     uint64_t tokenId;
75     const char **perms = new const char *[1];
76     perms[0] = "ohos.permission.COMMONEVEVT_STICKY"; // system_core
77     NativeTokenInfoParams infoInstance = {
78         .dcapsNum = 0,
79         .permsNum = 1,
80         .aclsNum = 0,
81         .dcaps = nullptr,
82         .perms = perms,
83         .acls = nullptr,
84         .aplStr = "system_basic",
85     };
86 
87     infoInstance.processName = "common_event_command_dump_system_test";
88     tokenId = GetAccessTokenId(&infoInstance);
89     SetSelfTokenID(tokenId);
90     delete[] perms;
91 }
92 
TearDownTestCase()93 void CemCommandPublishSystemTest::TearDownTestCase()
94 {}
95 
SetUp()96 void CemCommandPublishSystemTest::SetUp()
97 {
98     // reset optind to 0
99     optind = 0;
100 }
101 
TearDown()102 void CemCommandPublishSystemTest::TearDown()
103 {}
104 
105 class CommonEventSubscriberTest : public CommonEventSubscriber {
106 public:
CommonEventSubscriberTest(const CommonEventSubscribeInfo & subscribeInfo)107     explicit CommonEventSubscriberTest(const CommonEventSubscribeInfo &subscribeInfo)
108         : CommonEventSubscriber(subscribeInfo)
109     {}
110 
~CommonEventSubscriberTest()111     ~CommonEventSubscriberTest()
112     {}
113 
OnReceiveEvent(const CommonEventData & commonEventData)114     void OnReceiveEvent(const CommonEventData &commonEventData)
115     {
116         GTEST_LOG_(INFO) << "OnReceiveEvent";
117 
118         std::string deviceId = GetSubscribeInfo().GetDeviceId();
119         GTEST_LOG_(INFO) << "deviceId = " << deviceId;
120 
121         int32_t code = commonEventData.GetCode();
122         GTEST_LOG_(INFO) << "code = " << code;
123 
124         std::string data = commonEventData.GetData();
125         GTEST_LOG_(INFO) << "data = " << data;
126 
127         if (deviceId == STRING_DEVICE_ID_001) {
128             if (atoi(STRING_CODE.c_str()) == code && STRING_DATA == data) {
129                 mtx.unlock();
130             }
131         } else if (deviceId == STRING_DEVICE_ID_002) {
132             if (atoi(STRING_CODE_TWO.c_str()) == code) {
133                 mtx.unlock();
134             }
135         } else if (deviceId == STRING_DEVICE_ID_003) {
136             if (STRING_DATA_TWO == data) {
137                 mtx.unlock();
138             }
139         } else {
140             mtx.unlock();
141         }
142     }
143 };
144 
145 /**
146  * @tc.number: Cem_Command_Publish_SystemTest_0100
147  * @tc.name: ExecCommand
148  * @tc.desc: Verify the "cem publish -e <name>" command.
149  */
150 HWTEST_F(CemCommandPublishSystemTest, Cem_Command_Publish_SystemTest_0100, Function | MediumTest | Level1)
151 {
152     /* Subscribe */
153 
154     // make matching skills
155     MatchingSkills matchingSkills;
156     matchingSkills.AddEvent(STRING_EVENT);
157 
158     // make subscribe info
159     CommonEventSubscribeInfo subscribeInfo(matchingSkills);
160 
161     // make a subscriber object
162     auto subscriberTestPtr = std::make_shared<CommonEventSubscriberTest>(subscribeInfo);
163     // subscribe a common event
164     CommonEventManager::SubscribeCommonEvent(subscriberTestPtr);
165 
166     // lock the mutex
167     mtx.lock();
168 
169     // publish a common event
170     std::string command = "cem publish -e " + STRING_EVENT;
171     std::string commandResult = ExecuteCommand(command);
172 
173     EXPECT_EQ(commandResult, STRING_PUBLISH_COMMON_EVENT_OK);
174 
175     // record start time of publishing
176     struct tm startTime = {0};
177     EXPECT_EQ(OHOS::GetSystemCurrentTime(&startTime), true);
178 
179     // record current time
180     struct tm doingTime = {0};
181     int64_t seconds = 0;
182 
183     while (!mtx.try_lock()) {
184         // get current time and compare it with the start time
185         EXPECT_EQ(OHOS::GetSystemCurrentTime(&doingTime), true);
186         seconds = OHOS::GetSecondsBetween(startTime, doingTime);
187         if (seconds >= TIME_OUT_SECONDS_LIMIT) {
188             break;
189         }
190     }
191 
192     // unsubscribe the common event
193     CommonEventManager::UnSubscribeCommonEvent(subscriberTestPtr);
194 
195     // expect the subscriber could receive the event within 5 seconds.
196     EXPECT_LT(seconds, TIME_OUT_SECONDS_LIMIT);
197 
198     // unlock the mutex
199     mtx.unlock();
200 }
201 
202 /**
203  * @tc.number: Cem_Command_Publish_SystemTest_0200
204  * @tc.name: ExecCommand
205  * @tc.desc: Verify the "cem publish -e <name> -c <code> -d <data>" command.
206  */
207 HWTEST_F(CemCommandPublishSystemTest, Cem_Command_Publish_SystemTest_0200, Function | MediumTest | Level1)
208 {
209     /* Subscribe */
210 
211     // make matching skills
212     MatchingSkills matchingSkills;
213     matchingSkills.AddEvent(STRING_EVENT);
214 
215     // make subscribe info
216     CommonEventSubscribeInfo subscribeInfo(matchingSkills);
217 
218     // set device id
219     subscribeInfo.SetDeviceId(STRING_DEVICE_ID_001);
220 
221     // make a subscriber object
222     auto subscriberTestPtr = std::make_shared<CommonEventSubscriberTest>(subscribeInfo);
223     // subscribe a common event
224     CommonEventManager::SubscribeCommonEvent(subscriberTestPtr);
225 
226     // lock the mutex
227     mtx.lock();
228 
229     // publish a common event with code and data
230     std::string command = "cem publish -e " + STRING_EVENT + " -c " + STRING_CODE + " -d " + STRING_DATA;
231     std::string commandResult = ExecuteCommand(command);
232 
233     EXPECT_EQ(commandResult, STRING_PUBLISH_COMMON_EVENT_OK);
234 
235     // record start time of publishing
236     struct tm startTime = {0};
237     EXPECT_EQ(OHOS::GetSystemCurrentTime(&startTime), true);
238 
239     // record current time
240     struct tm doingTime = {0};
241     int64_t seconds = 0;
242 
243     while (!mtx.try_lock()) {
244         // get current time and compare it with the start time
245         EXPECT_EQ(OHOS::GetSystemCurrentTime(&doingTime), true);
246         seconds = OHOS::GetSecondsBetween(startTime, doingTime);
247         if (seconds >= TIME_OUT_SECONDS_LIMIT) {
248             break;
249         }
250     }
251 
252     // unsubscribe the common event
253     CommonEventManager::UnSubscribeCommonEvent(subscriberTestPtr);
254 
255     // expect the subscriber could receive the event within 5 seconds.
256     EXPECT_LT(seconds, TIME_OUT_SECONDS_LIMIT);
257 
258     // unlock the mutex
259     mtx.unlock();
260 }
261 
262 /**
263  * @tc.number: Cem_Command_Publish_SystemTest_0300
264  * @tc.name: ExecCommand
265  * @tc.desc: Verify the "cem publish -e <name> -c <code>" command.
266  */
267 HWTEST_F(CemCommandPublishSystemTest, Cem_Command_Publish_SystemTest_0300, Function | MediumTest | Level1)
268 {
269     /* Subscribe */
270 
271     // make matching skills
272     MatchingSkills matchingSkills;
273     matchingSkills.AddEvent(STRING_EVENT);
274 
275     // make subscribe info
276     CommonEventSubscribeInfo subscribeInfo(matchingSkills);
277 
278     // set device id
279     subscribeInfo.SetDeviceId(STRING_DEVICE_ID_002);
280 
281     // make a subscriber object
282     auto subscriberTestPtr = std::make_shared<CommonEventSubscriberTest>(subscribeInfo);
283     // subscribe a common event
284     CommonEventManager::SubscribeCommonEvent(subscriberTestPtr);
285 
286     // lock the mutex
287     mtx.lock();
288 
289     // publish a common event with code and data
290     std::string command = "cem publish -e " + STRING_EVENT + " -c " + STRING_CODE_TWO;
291     std::string commandResult = ExecuteCommand(command);
292 
293     EXPECT_EQ(commandResult, STRING_PUBLISH_COMMON_EVENT_OK);
294 
295     // record start time of publishing
296     struct tm startTime = {0};
297     EXPECT_EQ(OHOS::GetSystemCurrentTime(&startTime), true);
298 
299     // record current time
300     struct tm doingTime = {0};
301     int64_t seconds = 0;
302 
303     while (!mtx.try_lock()) {
304         // get current time and compare it with the start time
305         EXPECT_EQ(OHOS::GetSystemCurrentTime(&doingTime), true);
306         seconds = OHOS::GetSecondsBetween(startTime, doingTime);
307         if (seconds >= TIME_OUT_SECONDS_LIMIT) {
308             break;
309         }
310     }
311 
312     // unsubscribe the common event
313     CommonEventManager::UnSubscribeCommonEvent(subscriberTestPtr);
314 
315     // expect the subscriber could receive the event within 5 seconds.
316     EXPECT_LT(seconds, TIME_OUT_SECONDS_LIMIT);
317 
318     // unlock the mutex
319     mtx.unlock();
320 }
321 
322 /**
323  * @tc.number: Cem_Command_Publish_SystemTest_0400
324  * @tc.name: ExecCommand
325  * @tc.desc: Verify the "cem publish -e <name> -d <data>" command.
326  */
327 HWTEST_F(CemCommandPublishSystemTest, Cem_Command_Publish_SystemTest_0400, Function | MediumTest | Level1)
328 {
329     /* Subscribe */
330 
331     // make matching skills
332     MatchingSkills matchingSkills;
333     matchingSkills.AddEvent(STRING_EVENT);
334 
335     // make subscribe info
336     CommonEventSubscribeInfo subscribeInfo(matchingSkills);
337 
338     // set device id
339     subscribeInfo.SetDeviceId(STRING_DEVICE_ID_003);
340 
341     // make a subscriber object
342     auto subscriberTestPtr = std::make_shared<CommonEventSubscriberTest>(subscribeInfo);
343     // subscribe a common event
344     CommonEventManager::SubscribeCommonEvent(subscriberTestPtr);
345 
346     // lock the mutex
347     mtx.lock();
348 
349     // publish a common event with code and data
350     std::string command = "cem publish -e " + STRING_EVENT + " -d " + STRING_DATA_TWO;
351     std::string commandResult = ExecuteCommand(command);
352 
353     EXPECT_EQ(commandResult, STRING_PUBLISH_COMMON_EVENT_OK);
354 
355     // record start time of publishing
356     struct tm startTime = {0};
357     EXPECT_EQ(OHOS::GetSystemCurrentTime(&startTime), true);
358 
359     // record current time
360     struct tm doingTime = {0};
361     int64_t seconds = 0;
362 
363     while (!mtx.try_lock()) {
364         // get current time and compare it with the start time
365         EXPECT_EQ(OHOS::GetSystemCurrentTime(&doingTime), true);
366         seconds = OHOS::GetSecondsBetween(startTime, doingTime);
367         if (seconds >= TIME_OUT_SECONDS_LIMIT) {
368             break;
369         }
370     }
371 
372     // unsubscribe the common event
373     CommonEventManager::UnSubscribeCommonEvent(subscriberTestPtr);
374 
375     // expect the subscriber could receive the event within 5 seconds.
376     EXPECT_LT(seconds, TIME_OUT_SECONDS_LIMIT);
377 
378     // unlock the mutex
379     mtx.unlock();
380 }
381