• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "parameters.h"
29 
30 #undef LOG_DOMAIN
31 #define LOG_DOMAIN 0xD002D00
32 
33 #undef LOG_TAG
34 #define LOG_TAG "HILOGTEST_C"
35 
36 using namespace testing::ext;
37 
38 namespace OHOS {
39 namespace HiviewDFX {
40 namespace HiLogTest {
41 const HiLogLabel APP_LABEL = { LOG_APP, 0x002a, "HILOGTEST_CPP" };
42 const HiLogLabel LABEL = { LOG_CORE, 0xD002D00, "HILOGTEST_CPP" };
43 const HiLogLabel ILLEGAL_DOMAIN_LABEL = { LOG_CORE, 0xD00EEEE, "HILOGTEST_CPP" };
44 static constexpr unsigned int SOME_LOGS = 10;
45 static constexpr unsigned int MORE_LOGS = 100;
46 static constexpr unsigned int OVER_LOGS = 1000;
47 
48 enum LogInterfaceType {
49     DEBUG_METHOD = 0,
50     INFO_METHOD = 1,
51     WARN_METHOD = 2,
52     ERROR_METHOD = 3,
53     FATAL_METHOD = 4,
54     METHODS_NUMBER = 5,
55 };
56 
57 using LogMethodFunc = std::function<void(const std::string &msg)>;
58 
59 static const std::array<LogMethodFunc, METHODS_NUMBER> LOG_C_METHODS = {
__anon0caaf0ac0102() 60     [] (const std::string &msg) {
61         HILOG_DEBUG(LOG_CORE, "%{public}s", msg.c_str());
62     },
__anon0caaf0ac0202() 63     [] (const std::string &msg) {
64         HILOG_INFO(LOG_CORE, "%{public}s", msg.c_str());
65     },
__anon0caaf0ac0302() 66     [] (const std::string &msg) {
67         HILOG_WARN(LOG_CORE, "%{public}s", msg.c_str());
68     },
__anon0caaf0ac0402() 69     [] (const std::string &msg) {
70         HILOG_ERROR(LOG_CORE, "%{public}s", msg.c_str());
71     },
__anon0caaf0ac0502() 72     [] (const std::string &msg) {
73         HILOG_FATAL(LOG_CORE, "%{public}s", msg.c_str());
74     },
75 };
76 
77 static const std::array<LogMethodFunc, METHODS_NUMBER> LOG_CPP_METHODS = {
__anon0caaf0ac0602() 78     [] (const std::string &msg) {
79         HiLog::Debug(LABEL, "%{public}s", msg.c_str());
80     },
__anon0caaf0ac0702() 81     [] (const std::string &msg) {
82         HiLog::Info(LABEL, "%{public}s", msg.c_str());
83     },
__anon0caaf0ac0802() 84     [] (const std::string &msg) {
85         HiLog::Warn(LABEL, "%{public}s", msg.c_str());
86     },
__anon0caaf0ac0902() 87     [] (const std::string &msg) {
88         HiLog::Error(LABEL, "%{public}s", msg.c_str());
89     },
__anon0caaf0ac0a02() 90     [] (const std::string &msg) {
91         HiLog::Fatal(LABEL, "%{public}s", msg.c_str());
92     },
93 };
94 
PopenToString(const std::string & command)95 static std::string PopenToString(const std::string &command)
96 {
97     std::string str;
98     constexpr int bufferSize = 1024;
99     FILE *fp = popen(command.c_str(), "re");
100     if (fp != nullptr) {
101         char buf[bufferSize] = {0};
102         size_t n = fread(buf, 1, sizeof(buf), fp);
103         while (n > 0) {
104             str.append(buf, n);
105             n = fread(buf, 1, sizeof(buf), fp);
106         }
107         pclose(fp);
108     }
109     std::cout << "PopenToString res: " << str << std::endl;
110     return str;
111 }
112 
113 class HiLogNDKTest : public testing::Test {
114 public:
115     static void SetUpTestCase();
TearDownTestCase()116     static void TearDownTestCase() {}
117     void SetUp();
TearDown()118     void TearDown() {}
119 };
120 
SetUpTestCase()121 void HiLogNDKTest::SetUpTestCase()
122 {
123     (void)PopenToString("hilog -Q pidoff");
124     (void)PopenToString("hilog -Q domainoff");
125 }
126 
SetUp()127 void HiLogNDKTest::SetUp()
128 {
129     (void)PopenToString("hilog -r");
130 }
131 
RandomStringGenerator()132 static std::string RandomStringGenerator()
133 {
134     std::string str;
135     int logLen = 16;
136     char index;
137     for (int i = 0; i < logLen; ++i) {
138         index = rand() % ('z' - 'a') + 'a';
139         str.append(1, index);
140     }
141     return str;
142 }
143 
HiLogWriteTest(LogInterfaceType methodType,unsigned int count,const std::array<LogMethodFunc,METHODS_NUMBER> & logMethods)144 static void HiLogWriteTest(LogInterfaceType methodType, unsigned int count,
145     const std::array<LogMethodFunc, METHODS_NUMBER> &logMethods)
146 {
147     std::string logMsg(RandomStringGenerator());
148     for (unsigned int i = 0; i < count; ++i) {
149         logMethods.at(methodType)(logMsg + std::to_string(i));
150     }
151     usleep(1000); /* 1000: sleep 1 ms */
152     std::string logMsgs = PopenToString("/system/bin/hilog -x");
153     unsigned int realCount = 0;
154     std::stringstream ss(logMsgs);
155     std::string str;
156     while (!ss.eof()) {
157         getline(ss, str);
158         if (str.find(logMsg) != std::string::npos) {
159             ++realCount;
160         }
161     }
162     unsigned int allowedLeastLogCount = count - count * 1 / 10; /* 1 / 10: loss rate less than 10% */
163     if (methodType == DEBUG_METHOD) {
164         allowedLeastLogCount = 0; /* 0: debug log is allowed to be closed */
165     }
166     EXPECT_GE(realCount, allowedLeastLogCount);
167 }
168 
FlowCtlTest(const HiLogLabel & label,const std::string keyWord)169 static void FlowCtlTest(const HiLogLabel &label, const std::string keyWord)
170 {
171     const std::string str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
172     for (unsigned int i = 0; i < OVER_LOGS; ++i) {
173         HiLog::Info(label, "%{public}s:%{public}d", str.c_str(), i);
174     }
175     sleep(1); /* 1: sleep 1 s */
176     HiLog::Info(label, "%{public}s", str.c_str());
177     std::string logMsgs = PopenToString("hilog -x -T LOGLIMIT");
178     EXPECT_TRUE(logMsgs.find(keyWord) != std::string::npos);
179 }
180 
181 /**
182  * @tc.name: Dfx_HiLogNDKTest_PrintDebugLog_001
183  * @tc.desc: Call HILOG_DEBUG to print logs.
184  * @tc.type: FUNC
185  */
186 HWTEST_F(HiLogNDKTest, PrintDebugLog_001, TestSize.Level1)
187 {
188     /**
189      * @tc.steps: step1. Call HILOG_DEBUG to print logs and call hilog to read it
190      * @tc.expected: step1. Logs can be printed only if hilog.debug is enabled.
191      */
192     HiLogWriteTest(DEBUG_METHOD, SOME_LOGS, LOG_C_METHODS);
193 }
194 
195 /**
196  * @tc.name: Dfx_HiLogNDKTest_PrintInfoLog_001
197  * @tc.desc: Call HILOG_INFO to print logs.
198  * @tc.type: FUNC
199  */
200 HWTEST_F(HiLogNDKTest, PrintInfoLog_001, TestSize.Level1)
201 {
202     /**
203      * @tc.steps: step1. Call HILOG_INFO to print logs and call hilog to read it
204      * @tc.expected: step1. Logs printed without loss.
205      */
206     HiLogWriteTest(INFO_METHOD, SOME_LOGS, LOG_C_METHODS);
207 }
208 
209 /**
210  * @tc.name: Dfx_HiLogNDKTest_PrintWarnLog_001
211  * @tc.desc: Call HILOG_WARN to print logs.
212  * @tc.type: FUNC
213  */
214 HWTEST_F(HiLogNDKTest, PrintWarnLog_001, TestSize.Level1)
215 {
216     /**
217      * @tc.steps: step1. Call HILOG_WARN to print logs and call hilog to read it
218      * @tc.expected: step1. Logs printed without loss.
219      */
220     HiLogWriteTest(WARN_METHOD, SOME_LOGS, LOG_C_METHODS);
221 }
222 
223 /**
224  * @tc.name: Dfx_HiLogNDKTest_PrintErrorLog_001
225  * @tc.desc: Call HILOG_ERROR to print logs.
226  * @tc.type: FUNC
227  */
228 HWTEST_F(HiLogNDKTest, PrintErrorLog_001, TestSize.Level1)
229 {
230     /**
231      * @tc.steps: step1. Call HILOG_ERROR to print logs and call hilog to read it
232      * @tc.expected: step1. Logs printed without loss.
233      */
234     HiLogWriteTest(ERROR_METHOD, SOME_LOGS, LOG_C_METHODS);
235 }
236 
237 /**
238  * @tc.name: Dfx_HiLogNDKTest_PrintFatalLog_001
239  * @tc.desc: Call HILOG_FATAL to print logs.
240  * @tc.type: FUNC
241  */
242 HWTEST_F(HiLogNDKTest, PrintFatalLog_001, TestSize.Level1)
243 {
244     /**
245      * @tc.steps: step1. Call HILOG_FATAL to print logs and call hilog to read it
246      * @tc.expected: step1. Logs printed without loss.
247      */
248     HiLogWriteTest(FATAL_METHOD, SOME_LOGS, LOG_C_METHODS);
249 }
250 
251 /**
252  * @tc.name: Dfx_HiLogNDKTest_LogLossCheck_001
253  * @tc.desc: HiLog log loss rate must less than 10%.
254  * @tc.type: FUNC
255  */
256 HWTEST_F(HiLogNDKTest, LogLossCheck_001, TestSize.Level1)
257 {
258     /**
259      * @tc.steps: step1. Call HILOG_INFO to print logs and call hilog to read it
260      * @tc.expected: step1. Calculate log loss rate and it should less than 10%
261      */
262     HiLogWriteTest(INFO_METHOD, MORE_LOGS, LOG_C_METHODS);
263 }
264 
265 /**
266  * @tc.name: Dfx_HiLogNDKTest_PrintDebugLog_002
267  * @tc.desc: Call HiLog::Debug to print logs.
268  * @tc.type: FUNC
269  */
270 HWTEST_F(HiLogNDKTest, PrintDebugLog_002, TestSize.Level1)
271 {
272     /**
273      * @tc.steps: step1. Call HiLog::Debug to print logs and call hilog to read it
274      * @tc.expected: step1. Logs can be printed only if hilog.debug is enabled.
275      */
276     HiLogWriteTest(DEBUG_METHOD, SOME_LOGS, LOG_CPP_METHODS);
277 }
278 
279 /**
280  * @tc.name: Dfx_HiLogNDKTest_PrintInfoLog_002
281  * @tc.desc: Call HiLog::Info to print logs.
282  * @tc.type: FUNC
283  */
284 HWTEST_F(HiLogNDKTest, PrintInfoLog_002, TestSize.Level1)
285 {
286     /**
287      * @tc.steps: step1. Call HiLog::Info to print logs and call hilog to read it
288      * @tc.expected: step1. Logs printed without loss.
289      */
290     HiLogWriteTest(INFO_METHOD, SOME_LOGS, LOG_CPP_METHODS);
291 }
292 
293 /**
294  * @tc.name: Dfx_HiLogNDKTest_PrintWarnLog_002
295  * @tc.desc: Call HiLog::Warn print logs.
296  * @tc.type: FUNC
297  */
298 HWTEST_F(HiLogNDKTest, PrintWarnLog_002, TestSize.Level1)
299 {
300     /**
301      * @tc.steps: step1. Call HiLog::Warn to print logs and call hilog to read it
302      * @tc.expected: step1. Logs printed without loss.
303      */
304     HiLogWriteTest(WARN_METHOD, SOME_LOGS, LOG_CPP_METHODS);
305 }
306 
307 /**
308  * @tc.name: Dfx_HiLogNDKTest_PrintErrorLog_002
309  * @tc.desc: Call HiLog::Error to print logs.
310  * @tc.type: FUNC
311  */
312 HWTEST_F(HiLogNDKTest, PrintErrorLog_002, TestSize.Level1)
313 {
314     /**
315      * @tc.steps: step1. Call HiLog::Error to print logs and call hilog to read it
316      * @tc.expected: step1. Logs printed without loss.
317      */
318     HiLogWriteTest(ERROR_METHOD, SOME_LOGS, LOG_CPP_METHODS);
319 }
320 
321 /**
322  * @tc.name: Dfx_HiLogNDKTest_PrintFatalLog_002
323  * @tc.desc: Call HiLog::Fatal to print logs.
324  * @tc.type: FUNC
325  */
326 HWTEST_F(HiLogNDKTest, PrintFatalLog_002, TestSize.Level1)
327 {
328     /**
329      * @tc.steps: step1. Call HiLog::Fatal to print logs and call hilog to read it
330      * @tc.expected: step1. Logs printed without loss.
331      */
332     HiLogWriteTest(FATAL_METHOD, SOME_LOGS, LOG_CPP_METHODS);
333 }
334 
335 /**
336  * @tc.name: Dfx_HiLogNDKTest_LogLossCheck_002
337  * @tc.desc: HiLog log loss rate must less than 10%
338  * @tc.type: FUNC
339  */
340 HWTEST_F(HiLogNDKTest, LogLossCheck_002, TestSize.Level1)
341 {
342     /**
343      * @tc.steps: step1. Call HiLog::Info to print logs and call hilog to read it
344      * @tc.expected: step1. Calculate log loss rate and it should less than 10%
345      */
346     HiLogWriteTest(INFO_METHOD, MORE_LOGS, LOG_CPP_METHODS);
347 }
348 
349 /**
350  * @tc.name: Dfx_HiLogNDKTest_IsLoggable_001
351  * @tc.desc: Check whether is loggable for each log level
352  * @tc.type: FUNC
353  */
354 HWTEST_F(HiLogNDKTest, IsLoggable_001, TestSize.Level1)
355 {
356     /**
357      * @tc.steps: step1. Call HiLogIsLoggable to check whether is loggable for each log level.
358      * @tc.expected: step1. LOG_DEBUG and lower level should return false in release version, and others return true.
359      */
360     if (OHOS::system::GetParameter("hilog.loggable.global", "D") == "D") {
361         EXPECT_TRUE(HiLogIsLoggable(0xD002D00, LOG_TAG, LOG_DEBUG));
362     } else {
363         EXPECT_FALSE(HiLogIsLoggable(0xD002D00, LOG_TAG, LOG_DEBUG));
364     }
365     EXPECT_TRUE(HiLogIsLoggable(0xD002D00, LOG_TAG, LOG_INFO));
366     EXPECT_TRUE(HiLogIsLoggable(0xD002D00, LOG_TAG, LOG_WARN));
367     EXPECT_TRUE(HiLogIsLoggable(0xD002D00, LOG_TAG, LOG_ERROR));
368     EXPECT_TRUE(HiLogIsLoggable(0xD002D00, LOG_TAG, LOG_FATAL));
369     EXPECT_TRUE(HiLogIsLoggable(0xD002D00, "abc", LOG_WARN));
370 }
371 
372 /**
373  * @tc.name: Dfx_HiLogNDKTest_DomainCheck_001
374  * @tc.desc: test illegal domainID
375  * @tc.type: FUNC
376  * @tc.require:issueI5NU4L
377  */
378 HWTEST_F(HiLogNDKTest, DomainCheck_001, TestSize.Level1)
379 {
380     (void)PopenToString("param set hilog.debug.on false");
381     (void)PopenToString("param set persist.sys.hilog.debug.on false");
382     std::string logMsg(RandomStringGenerator());
383     for (unsigned int i = 0; i < SOME_LOGS; ++i) {
384         HiLog::Info(ILLEGAL_DOMAIN_LABEL, "%{public}s", logMsg.c_str());
385     }
386     usleep(1000); /* 1000: sleep 1 ms */
387     std::string logMsgs = PopenToString("/system/bin/hilog -x");
388     unsigned int realCount = 0;
389     std::stringstream ss(logMsgs);
390     std::string str;
391     while (!ss.eof()) {
392         getline(ss, str);
393         if (str.find(logMsg) != std::string::npos) {
394             ++realCount;
395         }
396     }
397     EXPECT_EQ(realCount, 0);
398 }
399 
400 /**
401  * @tc.name: Dfx_HiLogNDKTest_hilogSocketTest
402  * @tc.desc: Query hilog socket rights
403  * @tc.type: FUNC
404  * @tc.require:issueI5NU7F
405  */
406 HWTEST_F(HiLogNDKTest, hilogSocketTest, TestSize.Level1)
407 {
408     std::string str;
409     std::string hilogControlRights = "srw-rw----";
410     std::string logMsgs = PopenToString("ls -al //dev/unix/socket/hilogControl");
411     std::stringstream ss(logMsgs);
412     getline(ss, str);
413     EXPECT_TRUE(str.find(hilogControlRights) != std::string::npos);
414 }
415 
416 /**
417  * @tc.name: Dfx_HiLogNDKTest_pidFlowCtrlTest
418  * @tc.desc: hilog pidFlowCtrlTest
419  * @tc.type: FUNC
420  */
421 HWTEST_F(HiLogNDKTest, pidFlowCtrlTest, TestSize.Level1)
422 {
423     (void)PopenToString("hilog -Q pidon");
424     const std::string pidCtrlLog = "DROPPED";
425     FlowCtlTest(APP_LABEL, pidCtrlLog);
426     (void)PopenToString("hilog -Q pidoff");
427 }
428 
429 /**
430  * @tc.name: Dfx_HiLogNDKTest_domainFlowCtrlTest
431  * @tc.desc: hilog domainFlowCtrlTest
432  * @tc.type: FUNC
433  */
434 HWTEST_F(HiLogNDKTest, domainFlowCtrlTest, TestSize.Level1)
435 {
436     (void)PopenToString("hilog -Q domainon");
437     const std::string domainCtrlLog = "dropped";
438     FlowCtlTest(LABEL, domainCtrlLog);
439     (void)PopenToString("hilog -Q domainoff");
440 }
441 } // namespace HiLogTest
442 } // namespace HiviewDFX
443 } // namespace OHOS
444