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 <array>
17 #include <cstdlib>
18 #include <ctime>
19 #include <iostream>
20 #include <sstream>
21 #include <string>
22
23 #include <unistd.h>
24
25 #include <gtest/gtest.h>
26
27 #include "hilog/log.h"
28
29 #undef LOG_DOMAIN
30 #define LOG_DOMAIN 0xD002D00
31
32 #undef LOG_TAG
33 #define LOG_TAG "HILOGTEST_C"
34
35 using namespace testing::ext;
36
37 namespace OHOS {
38 namespace HiviewDFX {
39 namespace HiLogTest {
40 const HiLogLabel LABEL = { LOG_CORE, 0xD002D00, "HILOGTEST_CPP" };
41 static constexpr unsigned int SOME_LOGS = 10;
42 static constexpr unsigned int MORE_LOGS = 100;
43
44 enum LogInterfaceType {
45 DEBUG_METHOD = 0,
46 INFO_METHOD = 1,
47 WARN_METHOD = 2,
48 ERROR_METHOD = 3,
49 FATAL_METHOD = 4,
50 METHODS_NUMBER = 5,
51 };
52
53 using LogMethodFunc = std::function<void(const std::string &msg)>;
54
55 static const std::array<LogMethodFunc, METHODS_NUMBER> LOG_C_METHODS = {
__anon855251b20102() 56 [] (const std::string &msg) {
57 HILOG_DEBUG(LOG_CORE, "%{public}s", msg.c_str());
58 },
__anon855251b20202() 59 [] (const std::string &msg) {
60 HILOG_INFO(LOG_CORE, "%{public}s", msg.c_str());
61 },
__anon855251b20302() 62 [] (const std::string &msg) {
63 HILOG_WARN(LOG_CORE, "%{public}s", msg.c_str());
64 },
__anon855251b20402() 65 [] (const std::string &msg) {
66 HILOG_ERROR(LOG_CORE, "%{public}s", msg.c_str());
67 },
__anon855251b20502() 68 [] (const std::string &msg) {
69 HILOG_FATAL(LOG_CORE, "%{public}s", msg.c_str());
70 },
71 };
72
73 static const std::array<LogMethodFunc, METHODS_NUMBER> LOG_CPP_METHODS = {
__anon855251b20602() 74 [] (const std::string &msg) {
75 HiLog::Debug(LABEL, "%{public}s", msg.c_str());
76 },
__anon855251b20702() 77 [] (const std::string &msg) {
78 HiLog::Info(LABEL, "%{public}s", msg.c_str());
79 },
__anon855251b20802() 80 [] (const std::string &msg) {
81 HiLog::Warn(LABEL, "%{public}s", msg.c_str());
82 },
__anon855251b20902() 83 [] (const std::string &msg) {
84 HiLog::Error(LABEL, "%{public}s", msg.c_str());
85 },
__anon855251b20a02() 86 [] (const std::string &msg) {
87 HiLog::Fatal(LABEL, "%{public}s", msg.c_str());
88 },
89 };
90
PopenToString(const std::string & command)91 static std::string PopenToString(const std::string &command)
92 {
93 std::string str;
94 constexpr int bufferSize = 1024;
95 FILE *fp = popen(command.c_str(), "re");
96 if (fp != nullptr) {
97 char buf[bufferSize] = {0};
98 size_t n = fread(buf, 1, sizeof(buf), fp);
99 while (n > 0) {
100 str.append(buf, n);
101 n = fread(buf, 1, sizeof(buf), fp);
102 }
103 pclose(fp);
104 }
105 return str;
106 }
107
108 class HiLogNDKTest : public testing::Test {
109 public:
SetUpTestCase()110 static void SetUpTestCase() {};
TearDownTestCase()111 static void TearDownTestCase() {};
112 void SetUp();
TearDown()113 void TearDown() {};
114 };
115
SetUp()116 void HiLogNDKTest::SetUp()
117 {
118 PopenToString("hilog -r");
119 }
120
RandomStringGenerator()121 static std::string RandomStringGenerator()
122 {
123 std::string str;
124 int logLen = 16;
125 char index;
126 for (int i = 0; i < logLen; ++i) {
127 index = rand() % ('z' - 'a') + 'a';
128 str.append(1, index);
129 }
130 return str;
131 }
132
HiLogWriteTest(LogInterfaceType methodType,unsigned int count,const std::array<LogMethodFunc,METHODS_NUMBER> & logMethods)133 static void HiLogWriteTest(LogInterfaceType methodType, unsigned int count,
134 const std::array<LogMethodFunc, METHODS_NUMBER> &logMethods)
135 {
136 std::string logMsg(RandomStringGenerator());
137 for (unsigned int i = 0; i < count; ++i) {
138 logMethods.at(methodType)(logMsg + std::to_string(i));
139 }
140 usleep(1000); /* 1000: sleep 1 ms */
141 std::string logMsgs = PopenToString("/system/bin/hilog -x");
142 unsigned int realCount = 0;
143 std::stringstream ss(logMsgs);
144 std::string str;
145 while (!ss.eof()) {
146 getline(ss, str);
147 if (str.find(logMsg) != std::string::npos) {
148 ++realCount;
149 }
150 }
151 unsigned int allowedLeastLogCount = count - count * 1 / 10; /* 1 / 10: loss rate less than 10% */
152 if (methodType == DEBUG_METHOD) {
153 allowedLeastLogCount = 0; /* 0: debug log is allowed to be closed */
154 }
155 EXPECT_GE(realCount, allowedLeastLogCount);
156 }
157
158 /**
159 * @tc.name: Dfx_HiLogNDKTest_PrintDebugLog_001
160 * @tc.desc: Call HILOG_DEBUG to print logs.
161 * @tc.type: FUNC
162 */
163 HWTEST_F(HiLogNDKTest, PrintDebugLog_001, TestSize.Level1)
164 {
165 /**
166 * @tc.steps: step1. Call HILOG_DEBUG to print logs and call hilog to read it
167 * @tc.expected: step1. Logs can be printed only if hilog.debug is enabled.
168 */
169 HiLogWriteTest(DEBUG_METHOD, SOME_LOGS, LOG_C_METHODS);
170 }
171
172 /**
173 * @tc.name: Dfx_HiLogNDKTest_PrintInfoLog_001
174 * @tc.desc: Call HILOG_INFO to print logs.
175 * @tc.type: FUNC
176 */
177 HWTEST_F(HiLogNDKTest, PrintInfoLog_001, TestSize.Level1)
178 {
179 /**
180 * @tc.steps: step1. Call HILOG_INFO to print logs and call hilog to read it
181 * @tc.expected: step1. Logs printed without loss.
182 */
183 HiLogWriteTest(INFO_METHOD, SOME_LOGS, LOG_C_METHODS);
184 }
185
186 /**
187 * @tc.name: Dfx_HiLogNDKTest_PrintWarnLog_001
188 * @tc.desc: Call HILOG_WARN to print logs.
189 * @tc.type: FUNC
190 */
191 HWTEST_F(HiLogNDKTest, PrintWarnLog_001, TestSize.Level1)
192 {
193 /**
194 * @tc.steps: step1. Call HILOG_WARN to print logs and call hilog to read it
195 * @tc.expected: step1. Logs printed without loss.
196 */
197 HiLogWriteTest(WARN_METHOD, SOME_LOGS, LOG_C_METHODS);
198 }
199
200 /**
201 * @tc.name: Dfx_HiLogNDKTest_PrintErrorLog_001
202 * @tc.desc: Call HILOG_ERROR to print logs.
203 * @tc.type: FUNC
204 */
205 HWTEST_F(HiLogNDKTest, PrintErrorLog_001, TestSize.Level1)
206 {
207 /**
208 * @tc.steps: step1. Call HILOG_ERROR to print logs and call hilog to read it
209 * @tc.expected: step1. Logs printed without loss.
210 */
211 HiLogWriteTest(ERROR_METHOD, SOME_LOGS, LOG_C_METHODS);
212 }
213
214 /**
215 * @tc.name: Dfx_HiLogNDKTest_PrintFatalLog_001
216 * @tc.desc: Call HILOG_FATAL to print logs.
217 * @tc.type: FUNC
218 */
219 HWTEST_F(HiLogNDKTest, PrintFatalLog_001, TestSize.Level1)
220 {
221 /**
222 * @tc.steps: step1. Call HILOG_FATAL to print logs and call hilog to read it
223 * @tc.expected: step1. Logs printed without loss.
224 */
225 HiLogWriteTest(FATAL_METHOD, SOME_LOGS, LOG_C_METHODS);
226 }
227
228 /**
229 * @tc.name: Dfx_HiLogNDKTest_LogLossCheck_001
230 * @tc.desc: HiLog log loss rate must less than 10%.
231 * @tc.type: FUNC
232 */
233 HWTEST_F(HiLogNDKTest, LogLossCheck_001, TestSize.Level1)
234 {
235 /**
236 * @tc.steps: step1. Call HILOG_INFO to print logs and call hilog to read it
237 * @tc.expected: step1. Calculate log loss rate and it should less than 10%
238 */
239 HiLogWriteTest(INFO_METHOD, MORE_LOGS, LOG_C_METHODS);
240 }
241
242 /**
243 * @tc.name: Dfx_HiLogNDKTest_PrintDebugLog_002
244 * @tc.desc: Call HiLog::Debug to print logs.
245 * @tc.type: FUNC
246 */
247 HWTEST_F(HiLogNDKTest, PrintDebugLog_002, TestSize.Level1)
248 {
249 /**
250 * @tc.steps: step1. Call HiLog::Debug to print logs and call hilog to read it
251 * @tc.expected: step1. Logs can be printed only if hilog.debug is enabled.
252 */
253 HiLogWriteTest(DEBUG_METHOD, SOME_LOGS, LOG_CPP_METHODS);
254 }
255
256 /**
257 * @tc.name: Dfx_HiLogNDKTest_PrintInfoLog_002
258 * @tc.desc: Call HiLog::Info to print logs.
259 * @tc.type: FUNC
260 */
261 HWTEST_F(HiLogNDKTest, PrintInfoLog_002, TestSize.Level1)
262 {
263 /**
264 * @tc.steps: step1. Call HiLog::Info to print logs and call hilog to read it
265 * @tc.expected: step1. Logs printed without loss.
266 */
267 HiLogWriteTest(INFO_METHOD, SOME_LOGS, LOG_CPP_METHODS);
268 }
269
270 /**
271 * @tc.name: Dfx_HiLogNDKTest_PrintWarnLog_002
272 * @tc.desc: Call HiLog::Warn print logs.
273 * @tc.type: FUNC
274 */
275 HWTEST_F(HiLogNDKTest, PrintWarnLog_002, TestSize.Level1)
276 {
277 /**
278 * @tc.steps: step1. Call HiLog::Warn to print logs and call hilog to read it
279 * @tc.expected: step1. Logs printed without loss.
280 */
281 HiLogWriteTest(WARN_METHOD, SOME_LOGS, LOG_CPP_METHODS);
282 }
283
284 /**
285 * @tc.name: Dfx_HiLogNDKTest_PrintErrorLog_002
286 * @tc.desc: Call HiLog::Error to print logs.
287 * @tc.type: FUNC
288 */
289 HWTEST_F(HiLogNDKTest, PrintErrorLog_002, TestSize.Level1)
290 {
291 /**
292 * @tc.steps: step1. Call HiLog::Error to print logs and call hilog to read it
293 * @tc.expected: step1. Logs printed without loss.
294 */
295 HiLogWriteTest(ERROR_METHOD, SOME_LOGS, LOG_CPP_METHODS);
296 }
297
298 /**
299 * @tc.name: Dfx_HiLogNDKTest_PrintFatalLog_002
300 * @tc.desc: Call HiLog::Fatal to print logs.
301 * @tc.type: FUNC
302 */
303 HWTEST_F(HiLogNDKTest, PrintFatalLog_002, TestSize.Level1)
304 {
305 /**
306 * @tc.steps: step1. Call HiLog::Fatal to print logs and call hilog to read it
307 * @tc.expected: step1. Logs printed without loss.
308 */
309 HiLogWriteTest(FATAL_METHOD, SOME_LOGS, LOG_CPP_METHODS);
310 }
311
312 /**
313 * @tc.name: Dfx_HiLogNDKTest_LogLossCheck_002
314 * @tc.desc: HiLog log loss rate must less than 10%
315 * @tc.type: FUNC
316 */
317 HWTEST_F(HiLogNDKTest, LogLossCheck_002, TestSize.Level1)
318 {
319 /**
320 * @tc.steps: step1. Call HiLog::Info to print logs and call hilog to read it
321 * @tc.expected: step1. Calculate log loss rate and it should less than 10%
322 */
323 HiLogWriteTest(INFO_METHOD, MORE_LOGS, LOG_CPP_METHODS);
324 }
325
326 /**
327 * @tc.name: Dfx_HiLogNDKTest_IsLoggable_001
328 * @tc.desc: Check whether is loggable for each log level
329 * @tc.type: FUNC
330 */
331 HWTEST_F(HiLogNDKTest, IsLoggable_001, TestSize.Level1)
332 {
333 /**
334 * @tc.steps: step1. Call HiLogIsLoggable to check whether is loggable for each log level.
335 * @tc.expected: step1. LOG_DEBUG and lower level should return false, and others return true.
336 */
337 EXPECT_TRUE(HiLogIsLoggable(0xD002D00, LOG_TAG, LOG_DEBUG));
338 EXPECT_TRUE(HiLogIsLoggable(0xD002D00, LOG_TAG, LOG_INFO));
339 EXPECT_TRUE(HiLogIsLoggable(0xD002D00, LOG_TAG, LOG_WARN));
340 EXPECT_TRUE(HiLogIsLoggable(0xD002D00, LOG_TAG, LOG_ERROR));
341 EXPECT_TRUE(HiLogIsLoggable(0xD002D00, LOG_TAG, LOG_FATAL));
342 EXPECT_TRUE(HiLogIsLoggable(0xD002D00, "abc", LOG_WARN));
343 }
344
345 } // namespace HiLogTest
346 } // namespace HiviewDFX
347 } // namespace OHOS
348