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