• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 <random>
21 #include <sstream>
22 #include <string>
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 0x2D00
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 static constexpr uint16_t SOME_LOGS = 10;
42 static constexpr uint16_t MORE_LOGS = 100;
43 static constexpr uint16_t OVER_LOGS = 1000;
44 
45 enum LogInterfaceType {
46     DEBUG_METHOD = 0,
47     INFO_METHOD = 1,
48     WARN_METHOD = 2,
49     ERROR_METHOD = 3,
50     FATAL_METHOD = 4,
51     METHODS_NUMBER = 5,
52 };
53 
54 using LogMethodFunc = std::function<void(const std::string &msg)>;
55 
56 static const std::array<LogMethodFunc, METHODS_NUMBER> LOG_C_METHODS = {
__anon3a528b480102() 57     [] (const std::string &msg) {
58         OH_LOG_DEBUG(LOG_APP, "%{public}s", msg.c_str());
59     },
__anon3a528b480202() 60     [] (const std::string &msg) {
61         OH_LOG_INFO(LOG_APP, "%{public}s", msg.c_str());
62     },
__anon3a528b480302() 63     [] (const std::string &msg) {
64         OH_LOG_WARN(LOG_APP, "%{public}s", msg.c_str());
65     },
__anon3a528b480402() 66     [] (const std::string &msg) {
67         OH_LOG_ERROR(LOG_APP, "%{public}s", msg.c_str());
68     },
__anon3a528b480502() 69     [] (const std::string &msg) {
70         OH_LOG_FATAL(LOG_APP, "%{public}s", msg.c_str());
71     },
72 };
73 
PopenToString(const std::string & command)74 static std::string PopenToString(const std::string &command)
75 {
76     std::string str;
77     constexpr int bufferSize = 1024;
78     FILE *fp = popen(command.c_str(), "re");
79     if (fp != nullptr) {
80         char buf[bufferSize] = {0};
81         size_t n = fread(buf, 1, sizeof(buf), fp);
82         while (n > 0) {
83             str.append(buf, n);
84             n = fread(buf, 1, sizeof(buf), fp);
85         }
86         pclose(fp);
87     }
88     std::cout << "PopenToString res: " << str << std::endl;
89     return str;
90 }
91 
92 class HiLogNDKZTest : public testing::Test {
93 public:
94     static void SetUpTestCase();
TearDownTestCase()95     static void TearDownTestCase() {}
96     void SetUp();
TearDown()97     void TearDown() {}
98 };
99 
SetUpTestCase()100 void HiLogNDKZTest::SetUpTestCase()
101 {
102     (void)PopenToString("hilog -Q pidoff");
103     (void)PopenToString("hilog -Q domainoff");
104 }
105 
SetUp()106 void HiLogNDKZTest::SetUp()
107 {
108     (void)PopenToString("hilog -r");
109 }
110 
111 
RandomNum()112 uint64_t RandomNum()
113 {
114     std::random_device seed;
115     std::mt19937_64 gen(seed());
116     std::uniform_int_distribution<uint64_t> dis(0, std::numeric_limits<uint64_t>::max());
117     return dis(gen);
118 }
119 
RandomStringGenerator()120 static std::string RandomStringGenerator()
121 {
122     std::string str;
123     int logLen = 16;
124     char index;
125     for (int i = 0; i < logLen; ++i) {
126         index = RandomNum() % ('z' - 'a') + 'a';
127         str.append(1, index);
128     }
129     return str;
130 }
131 
HilogPrint(LogInterfaceType methodType,uint16_t count,const std::array<LogMethodFunc,METHODS_NUMBER> & logMethods)132 static uint16_t HilogPrint(LogInterfaceType methodType, uint16_t count,
133     const std::array<LogMethodFunc, METHODS_NUMBER> &logMethods)
134 {
135     std::string logMsg(RandomStringGenerator());
136     for (uint16_t i = 0; i < count; ++i) {
137         logMethods.at(methodType)(logMsg + std::to_string(i));
138     }
139     usleep(1000); /* 1000: sleep 1 ms */
140     std::string logMsgs = PopenToString("/system/bin/hilog -x");
141     uint16_t realCount = 0;
142     std::stringstream ss(logMsgs);
143     std::string str;
144     while (!ss.eof()) {
145         getline(ss, str);
146         if (str.find(logMsg) != std::string::npos) {
147             ++realCount;
148         }
149     }
150     return realCount;
151 }
152 
HiLogWriteTest(LogInterfaceType methodType,uint16_t count,const std::array<LogMethodFunc,METHODS_NUMBER> & logMethods)153 static void HiLogWriteTest(LogInterfaceType methodType, uint16_t count,
154     const std::array<LogMethodFunc, METHODS_NUMBER> &logMethods)
155 {
156     uint16_t realCount = HilogPrint(methodType, count, logMethods);
157     uint16_t allowedLeastLogCount = count - count * 1 / 10; /* 1 / 10: loss rate less than 10% */
158     if (methodType == DEBUG_METHOD) {
159         allowedLeastLogCount = 0; /* 0: debug log is allowed to be closed */
160     }
161     EXPECT_GE(realCount, allowedLeastLogCount);
162 }
163 
HiLogWriteFailedTest(LogInterfaceType methodType,uint16_t count,const std::array<LogMethodFunc,METHODS_NUMBER> & logMethods)164 static inline void HiLogWriteFailedTest(LogInterfaceType methodType, uint16_t count,
165     const std::array<LogMethodFunc, METHODS_NUMBER> &logMethods)
166 {
167     EXPECT_EQ(HilogPrint(methodType, count, logMethods), 0);
168 }
169 
FlowCtlTest(const std::string keyWord)170 static void FlowCtlTest(const std::string keyWord)
171 {
172     const std::string str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
173     for (uint16_t i = 0; i < OVER_LOGS; ++i) {
174         OH_LOG_INFO(LOG_APP, "%{public}s:%{public}d", str.c_str(), i);
175     }
176     sleep(1); /* 1: sleep 1 s */
177     OH_LOG_INFO(LOG_APP, "%{public}s", str.c_str());
178     std::string logMsgs = PopenToString("hilog -x -T LOGLIMIT");
179     EXPECT_TRUE(logMsgs.find(keyWord) != std::string::npos);
180 }
181 
182 /**
183  * @tc.name: Dfx_HiLogNDKZTest_PrintDebugLog_001
184  * @tc.desc: Call OH_LOG_DEBUG to print logs.
185  * @tc.type: FUNC
186  */
187 HWTEST_F(HiLogNDKZTest, PrintDebugLog_001, TestSize.Level1)
188 {
189     /**
190      * @tc.steps: step1. Call OH_LOG_DEBUG to print logs and call hilog to read it
191      * @tc.expected: step1. Logs can be printed only if hilog.debug is enabled.
192      */
193     HiLogWriteTest(DEBUG_METHOD, SOME_LOGS, LOG_C_METHODS);
194 }
195 
196 /**
197  * @tc.name: Dfx_HiLogNDKZTest_PrintInfoLog_001
198  * @tc.desc: Call OH_LOG_INFO to print logs.
199  * @tc.type: FUNC
200  */
201 HWTEST_F(HiLogNDKZTest, PrintInfoLog_001, TestSize.Level1)
202 {
203     /**
204      * @tc.steps: step1. Call OH_LOG_INFO to print logs and call hilog to read it
205      * @tc.expected: step1. Logs printed without loss.
206      */
207     HiLogWriteTest(INFO_METHOD, SOME_LOGS, LOG_C_METHODS);
208 }
209 
210 /**
211  * @tc.name: Dfx_HiLogNDKZTest_PrintWarnLog_001
212  * @tc.desc: Call OH_LOG_WARN to print logs.
213  * @tc.type: FUNC
214  */
215 HWTEST_F(HiLogNDKZTest, PrintWarnLog_001, TestSize.Level1)
216 {
217     /**
218      * @tc.steps: step1. Call OH_LOG_WARN to print logs and call hilog to read it
219      * @tc.expected: step1. Logs printed without loss.
220      */
221     HiLogWriteTest(WARN_METHOD, SOME_LOGS, LOG_C_METHODS);
222 }
223 
224 /**
225  * @tc.name: Dfx_HiLogNDKZTest_PrintErrorLog_001
226  * @tc.desc: Call OH_LOG_ERROR to print logs.
227  * @tc.type: FUNC
228  */
229 HWTEST_F(HiLogNDKZTest, PrintErrorLog_001, TestSize.Level1)
230 {
231     /**
232      * @tc.steps: step1. Call OH_LOG_ERROR to print logs and call hilog to read it
233      * @tc.expected: step1. Logs printed without loss.
234      */
235     HiLogWriteTest(ERROR_METHOD, SOME_LOGS, LOG_C_METHODS);
236 }
237 
238 /**
239  * @tc.name: Dfx_HiLogNDKZTest_PrintFatalLog_001
240  * @tc.desc: Call OH_LOG_FATAL to print logs.
241  * @tc.type: FUNC
242  */
243 HWTEST_F(HiLogNDKZTest, PrintFatalLog_001, TestSize.Level1)
244 {
245     /**
246      * @tc.steps: step1. Call OH_LOG_FATAL to print logs and call hilog to read it
247      * @tc.expected: step1. Logs printed without loss.
248      */
249     HiLogWriteTest(FATAL_METHOD, SOME_LOGS, LOG_C_METHODS);
250 }
251 
252 /**
253  * @tc.name: Dfx_HiLogNDKZTest_LogLossCheck_001
254  * @tc.desc: HiLog log loss rate must less than 10%.
255  * @tc.type: FUNC
256  */
257 HWTEST_F(HiLogNDKZTest, LogLossCheck_001, TestSize.Level1)
258 {
259     /**
260      * @tc.steps: step1. Call OH_LOG_INFO to print logs and call hilog to read it
261      * @tc.expected: step1. Calculate log loss rate and it should less than 10%
262      */
263     HiLogWriteTest(INFO_METHOD, MORE_LOGS, LOG_C_METHODS);
264 }
265 
266 /**
267  * @tc.name: Dfx_HiLogNDKZTest_IsLoggable_001
268  * @tc.desc: Check whether is loggable for each log level
269  * @tc.type: FUNC
270  */
271 HWTEST_F(HiLogNDKZTest, IsLoggable_001, TestSize.Level1)
272 {
273     /**
274      * @tc.steps: step1. Call OH_LOG_IsLoggable to check whether is loggable for each log level.
275      * @tc.expected: step1. LOG_DEBUG and lower level should return false in release version, and others return true.
276      */
277     if (OHOS::system::GetParameter("hilog.loggable.global", "D") == "D") {
278         EXPECT_TRUE(OH_LOG_IsLoggable(0x2D00, LOG_TAG, LOG_DEBUG));
279     } else {
280         EXPECT_FALSE(OH_LOG_IsLoggable(0x2D00, LOG_TAG, LOG_DEBUG));
281     }
282     EXPECT_TRUE(OH_LOG_IsLoggable(0x2D00, LOG_TAG, LOG_INFO));
283     EXPECT_TRUE(OH_LOG_IsLoggable(0x2D00, LOG_TAG, LOG_WARN));
284     EXPECT_TRUE(OH_LOG_IsLoggable(0x2D00, LOG_TAG, LOG_ERROR));
285     EXPECT_TRUE(OH_LOG_IsLoggable(0x2D00, LOG_TAG, LOG_FATAL));
286     EXPECT_TRUE(OH_LOG_IsLoggable(0x2D00, "abc", LOG_WARN));
287 }
288 
289 
290 /**
291  * @tc.name: Dfx_HiLogNDKZTest_hilogSocketTest
292  * @tc.desc: Query hilog socket rights
293  * @tc.type: FUNC
294  * @tc.require:issueI5NU7F
295  */
296 HWTEST_F(HiLogNDKZTest, hilogSocketTest, TestSize.Level1)
297 {
298     std::string str;
299     std::string hilogControlRights = "srw-rw----";
300     std::string logMsgs = PopenToString("ls -al //dev/unix/socket/hilogControl");
301     std::stringstream ss(logMsgs);
302     getline(ss, str);
303     EXPECT_TRUE(str.find(hilogControlRights) != std::string::npos);
304 }
305 
306 /**
307  * @tc.name: Dfx_HiLogNDKZTest_pidFlowCtrlTest
308  * @tc.desc: hilog pidFlowCtrlTest
309  * @tc.type: FUNC
310  */
311 HWTEST_F(HiLogNDKZTest, pidFlowCtrlTest, TestSize.Level1)
312 {
313     (void)PopenToString("hilog -Q pidon");
314     const std::string pidCtrlLog = "DROPPED";
315     FlowCtlTest(pidCtrlLog);
316     (void)PopenToString("hilog -Q pidoff");
317 }
318 
319 /**
320  * @tc.name: Dfx_HiLogNDKZTest_SetMinLevelTest
321  * @tc.desc: hilog setMinLevelTest
322  * @tc.type: FUNC
323  */
324 HWTEST_F(HiLogNDKZTest, setMinLevelTest, TestSize.Level1)
325 {
326     HiLogWriteTest(INFO_METHOD, SOME_LOGS, LOG_C_METHODS);
327     OH_LOG_SetMinLogLevel(LOG_WARN);
328     HiLogWriteFailedTest(INFO_METHOD, SOME_LOGS, LOG_C_METHODS);
329     OH_LOG_SetMinLogLevel(LOG_DEBUG);
330     HiLogWriteFailedTest(DEBUG_METHOD, SOME_LOGS, LOG_C_METHODS);
331     HiLogWriteTest(INFO_METHOD, SOME_LOGS, LOG_C_METHODS);
332 }
333 
334 } // namespace HiLogTest
335 } // namespace HiviewDFX
336 } // namespace OHOS
337