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 #include "event_logger_catcher_test.h"
16
17 #include <ctime>
18 #include <fstream>
19 #include <iostream>
20 #include <memory>
21
22 #include <fcntl.h>
23 #include <semaphore.h>
24 #include <sys/ipc.h>
25 #include <sys/prctl.h>
26 #include <sys/sem.h>
27 #include <sys/stat.h>
28 #include <sys/types.h>
29 #include <sys/wait.h>
30 #include <unistd.h>
31
32 #include "securec.h"
33
34 #include "common_utils.h"
35 #include "file_util.h"
36
37 #include "event_log_task.h"
38 #include "event_logger.h"
39 using namespace testing::ext;
40 using namespace OHOS::HiviewDFX;
41
SetUp()42 void EventloggerCatcherTest::SetUp()
43 {
44 /**
45 * @tc.setup: create an event loop and multiple event handlers
46 */
47 printf("SetUp.\n");
48 printf("path_ is %s\n", path_.c_str());
49
50 sleep(1);
51 isSelinuxEnabled_ = false;
52 char buffer[BUF_SIZE_64] = {'\0'};
53 FILE* fp = popen("getenforce", "r");
54 if (fp != nullptr) {
55 fgets(buffer, sizeof(buffer), fp);
56 std::string str = buffer;
57 printf("buffer is %s\n", str.c_str());
58 if (str.find("Enforcing") != str.npos) {
59 printf("Enforcing %s\n", str.c_str());
60 isSelinuxEnabled_ = true;
61 } else {
62 printf("This isn't Enforcing %s\n", str.c_str());
63 }
64 pclose(fp);
65 } else {
66 printf("fp == nullptr\n");
67 }
68 system("setenforce 0");
69
70 constexpr mode_t defaultLogDirMode = 0770;
71 if (!FileUtil::FileExists(path_)) {
72 FileUtil::ForceCreateDirectory(path_);
73 FileUtil::ChangeModeDirectory(path_, defaultLogDirMode);
74 }
75 }
76
TearDown()77 void EventloggerCatcherTest::TearDown()
78 {
79 /**
80 * @tc.teardown: destroy the event loop we have created
81 */
82 if (isSelinuxEnabled_) {
83 system("setenforce 1");
84 isSelinuxEnabled_ = false;
85 }
86
87 printf("TearDown.\n");
88 }
89
GetFdSize(int32_t fd)90 int EventloggerCatcherTest::GetFdSize(int32_t fd)
91 {
92 struct stat fileStat;
93 if (fstat(fd, &fileStat) == -1) {
94 return 0;
95 }
96 return fileStat.st_size;
97 }
98
GetFormatTime(unsigned long timestamp)99 std::string EventloggerCatcherTest::GetFormatTime(unsigned long timestamp)
100 {
101 struct tm tm;
102 time_t ts;
103 /* 20: the length of 'YYYYmmddHHMMSS' */
104 int strLen = 20;
105 ts = timestamp;
106 localtime_r(&ts, &tm);
107 char buf[strLen];
108
109 (void)memset_s(buf, strLen, 0, strLen);
110 strftime(buf, strLen - 1, "%Y%m%d%H%M%S", &tm);
111 return std::string(buf, strlen(buf));
112 }
113
JudgmentsFileSize(int minQuantity,const std::string sender)114 int EventloggerCatcherTest::JudgmentsFileSize(int minQuantity, const std::string sender)
115 {
116 constexpr mode_t defaultLogFileMode = 0644;
117 std::string logPath = path_ + "/" + logFile_;
118 auto fd2 = open(logPath.c_str(), O_RDONLY, defaultLogFileMode);
119 if (fd2 < 0) {
120 printf("second, Fail to create %s. fd2 == %d\n", logFile_.c_str(), fd2);
121 return RETURN_OPEN_FAIL2;
122 }
123 auto size = GetFdSize(fd2);
124 printf("%s, file size %d\n", sender.c_str(), size);
125 if (size < minQuantity) {
126 printf("error %s, less than size %d\n", sender.c_str(), minQuantity);
127 close(fd2);
128 return RETURN_LESS_THAN_SIZE;
129 }
130 return fd2;
131 }
132
StartCreate(const std::string sender,const std::string name,const std::string action,int pid,const std::string packageName,int interval,int minQuantity)133 int EventloggerCatcherTest::StartCreate(const std::string sender, const std::string name, const std::string action,
134 int pid, const std::string packageName, int interval, int minQuantity)
135 {
136 auto eventlogger = std::make_unique<EventLogger>();
137 std::string jsonStr = R"~({"domain_":"demo","name_":")~" + name + R"~(","pid_":)~" +
138 std::to_string(pid) + R"~(,"tid_":6527,"PACKAGE_NAME":")~" + packageName + R"~("})~";
139 auto event = std::make_shared<SysEvent>("sender", nullptr, jsonStr);
140 event->ParseJson();
141 std::time_t timeTmp = 0;
142 time(&timeTmp);
143 event->happenTime_ = timeTmp;
144 event->SetValue("eventLog_action", action);
145 event->SetValue("eventLog_interval", interval);
146
147 printf("pid is %d, pid_ %d; packageName is %s, PACKAGE_NAME %s\n",
148 pid, event->GetPid(), packageName.c_str(), event->GetEventValue("PACKAGE_NAME").c_str());
149
150 std::string idStr = event->eventName_;
151 logFile_ = idStr + "-" + GetFormatTime(event->happenTime_) + ".log";
152
153 constexpr mode_t defaultLogFileMode = 0644;
154 std::string logPath = path_ + "/" + logFile_;
155 printf("logPath is %s\n", logPath.c_str());
156 auto fd = open(logPath.c_str(), O_CREAT | O_WRONLY | O_TRUNC, defaultLogFileMode);
157 if (fd < 0) {
158 printf("Fail to create %s. fd == %d\n", logFile_.c_str(), fd);
159 return RETURN_OPEN_FAIL;
160 }
161
162 auto logTask = std::make_unique<EventLogTask>(fd, event);
163 logTask->AddLog(event->GetValue("eventLog_action"));
164 auto ret = logTask->StartCompose();
165 if (ret != EventLogTask::TASK_SUCCESS) {
166 printf("capture fail %d", ret);
167 close(fd);
168 return RETURN_TASK_NO_SUCCESS;
169 }
170 close(fd);
171
172 printf("logTask LogSize is %ld\n", logTask->GetLogSize());
173 if (logTask->GetLogSize() < minQuantity) {
174 printf("error LogSize less than %d\n", minQuantity);
175 return RETURN_TASK_LESS_THAN_SIZE;
176 }
177 return 0;
178 }
179
180 /**
181 * @tc.name: EventloggerCatcherTest001
182 * @tc.desc: parse a correct config file and check result
183 * @tc.type: FUNC
184 * @tc.require: AR000FT62O
185 */
186 HWTEST_F(EventloggerCatcherTest, EventloggerCatcherTest001, TestSize.Level3)
187 {
188 /**
189 * @tc.steps: step1. create event handler and events
190 */
191 constexpr int minQuantity = 8000;
192 int pid = CommonUtils::GetPidByName("foundation");
193 auto ret = StartCreate("EventloggerCatcherTest001", "TEST01_SYS_STACKTRACE",
194 "s", pid, "foundation", 0, minQuantity);
195 if (ret < 0) {
196 printf("EventloggerCatcherTest001 StartCreate is error ret == %d\n", ret);
197 FAIL();
198 }
199
200 auto fd = JudgmentsFileSize(minQuantity, "EventloggerCatcherTest001");
201 if (fd < 0) {
202 printf("EventloggerCatcherTest001 JudgmentsFileSize is error ret == %d\n", fd);
203 FAIL();
204 }
205
206 char readTmp[BUF_SIZE_256];
207 ret = -1;
208 while (read(fd, readTmp, BUF_SIZE_256)) {
209 std::string tmp = readTmp;
210 if (tmp.find("system/bin") != tmp.npos) {
211 ret = 0;
212 break;
213 }
214 }
215
216 if (ret < 0) {
217 printf("not find Key Messages\n");
218 close(fd);
219 FAIL();
220 }
221 close(fd);
222 }
223
224 /**
225 * @tc.name: EventloggerCatcherTest002
226 * @tc.desc: parse a correct config file and check result
227 * @tc.type: FUNC
228 * @tc.require: AR000FT62O
229 */
230 HWTEST_F(EventloggerCatcherTest, EventloggerCatcherTest002, TestSize.Level3)
231 {
232 /**
233 * @tc.steps: step1. create event handler and events
234 */
235 printf("EventloggerCatcherTest002 start\n");
236
237 int pid = -1;
238 const int memSize = 1024*3;
239 if ((pid = fork()) < 0) {
240 printf("Fork error, err:%d", errno);
241 FAIL();
242 }
243
244 // Creating a process with high usage
245 if (pid == 0) {
246 prctl(PR_SET_NAME, "EventlogTest02");
247 prctl(PR_SET_PDEATHSIG, SIGKILL);
248 printf("Fork pid == 0, child process\n");
249 int volatile temp[memSize] = {0};
250 while (true) {
251 int i = 0;
252 while (i < memSize) {
253 temp[i] = i & 0x234567;
254 i++;
255 }
256 }
257 }
258
259 sleep(6);
260 constexpr int minQuantity = 500;
261 auto ret = StartCreate("EventloggerCatcherTest002", "TEST02_CPU", "cmd:c",
262 pid, "EventlogTest02", 0, minQuantity);
263
264 if (ret < 0) {
265 printf("EventloggerCatcherTest002 StartCreate is error ret == %d\n", ret);
266 FAIL();
267 }
268
269 auto fd = JudgmentsFileSize(minQuantity, "EventloggerCatcherTest002");
270 if (fd < 0) {
271 printf("EventloggerCatcherTest002 JudgmentsFileSize is error ret == %d\n", fd);
272 FAIL();
273 }
274
275 char readTmp[BUF_SIZE_256];
276 ret = -1;
277 while (read(fd, readTmp, BUF_SIZE_256)) {
278 std::string tmp = readTmp;
279 if (tmp.find("[cpuusage]") != tmp.npos) {
280 ret = 0;
281 break;
282 }
283 }
284
285 if (ret < 0) {
286 printf("not find Key Messages\n");
287 close(fd);
288 FAIL();
289 }
290 close(fd);
291 }
292
293 /**
294 * @tc.name: EventloggerCatcherTest003
295 * @tc.desc: parse a correct config file and check result
296 * @tc.type: FUNC
297 * @tc.require: AR000FT62O
298 */
299 HWTEST_F(EventloggerCatcherTest, EventloggerCatcherTest003, TestSize.Level3)
300 {
301 /**
302 * @tc.steps: step1. create event handler and events
303 */
304
305 int pid = -1;
306 const int memSize = 1024*3;
307 if ((pid = fork()) < 0) {
308 printf("Fork error, err:%d", errno);
309 FAIL();
310 }
311
312 // Creating a process with high memory
313 if (pid == 0) {
314 prctl(PR_SET_NAME, "EventlogTest03");
315 prctl(PR_SET_PDEATHSIG, SIGKILL);
316 printf("Fork pid == 0, child process\n");
317 int volatile temp[memSize] = {0};
318 while (true) {
319 int i = 0;
320 while (i < memSize) {
321 temp[i] = i & 0x234567;
322 i++;
323 }
324 }
325 }
326
327 sleep(6);
328 constexpr int minQuantity = 500;
329 auto ret = StartCreate("EventloggerCatcherTest003", "TEST03_MEM", "cmd:m",
330 pid, "EventlogTest03", 0, minQuantity);
331 if (ret < 0) {
332 printf("EventloggerCatcherTest003 is error ret == %d\n", ret);
333 FAIL();
334 }
335
336 auto fd = JudgmentsFileSize(minQuantity, "EventloggerCatcherTest003");
337 if (fd < 0) {
338 printf("EventloggerCatcherTest003 JudgmentsFileSize is error ret == %d\n", fd);
339 FAIL();
340 }
341
342 char readTmp[BUF_SIZE_256];
343 ret = -1;
344 while (read(fd, readTmp, BUF_SIZE_256)) {
345 std::string tmp = readTmp;
346 if (tmp.find("[memory]") != tmp.npos) {
347 ret = 0;
348 break;
349 }
350 }
351
352 if (ret < 0) {
353 printf("not find Key Messages\n");
354 close(fd);
355 FAIL();
356 }
357 close(fd);
358 }
359