1 /*
2 * Copyright (c) 2021-2022 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 "debug_logger_test.h"
16
17 #include <random>
18
19 #include <debug_logger.h>
20 #include <gtest/gtest_prod.h>
21
22 using namespace testing::ext;
23 namespace OHOS {
24 namespace Developtools {
25 namespace HiPerf {
26 DebugLevel DebugLogger::debugLevel_ = DEFAULT_LOG_LEVEL;
27 bool DebugLogger::logDisabled_ = false;
28
29 class DebugLoggerTest : public testing::Test {
30 public:
31 static void SetUpTestCase(void);
32 static void TearDownTestCase(void);
33 void SetUp();
34 void TearDown();
35 void LogLevelTest(DebugLevel testlevel, bool useStdout = false);
36 const std::string TEST_LOG_MESSAGE = "<HELLO_TEST_LOG_MESSAGE>";
37 std::random_device rd_;
38 };
39
SetUpTestCase()40 void DebugLoggerTest::SetUpTestCase()
41 {
42 DebugLogger::GetInstance()->Reset();
43 }
44
TearDownTestCase()45 void DebugLoggerTest::TearDownTestCase()
46 {
47 DebugLogger::GetInstance()->Reset();
48 }
49
SetUp()50 void DebugLoggerTest::SetUp() {}
51
TearDown()52 void DebugLoggerTest::TearDown() {}
53
LogLevelTest(DebugLevel testlevel,bool useStdout)54 void DebugLoggerTest::LogLevelTest(DebugLevel testlevel, bool useStdout)
55 {
56 StdoutRecord stdoutRecord;
57 std::string log;
58 // backup
59 DebugLogger::GetInstance()->exitOnFatal_ = false;
60 DebugLevel oldLevel = DebugLogger::GetInstance()->GetLogLevel();
61 DebugLogger::GetInstance()->SetLogLevel(testlevel);
62
63 const std::string logMessage =
64 TEST_LOG_MESSAGE + std::to_string(rd_()) + std::to_string(testlevel);
65
66 if (useStdout) {
67 stdoutRecord.Start();
68 }
69
70 HLOGF("%s", logMessage.c_str());
71 HLOGE("%s", logMessage.c_str());
72 HLOGW("%s", logMessage.c_str());
73 HLOGI("%s", logMessage.c_str());
74 HLOGD("%s", logMessage.c_str());
75 HLOGV("%s", logMessage.c_str());
76 HLOGM("%s", logMessage.c_str());
77
78 if (useStdout) {
79 log = stdoutRecord.Stop();
80 } else {
81 fflush(DebugLogger::GetInstance()->file_);
82 log = ReadFileToString(DebugLogger::GetInstance()->logPath_);
83 }
84
85 // we have 7 level log
86 // so the logout line is : (all log level - curr log level) + curr log level self
87 if (testlevel > LEVEL_FATAL or DebugLogger::GetInstance()->enableHilog_ or
88 DebugLogger::GetInstance()->logDisabled_) {
89 EXPECT_EQ(SubStringCount(log, logMessage), 0u);
90 } else {
91 EXPECT_EQ(SubStringCount(log, logMessage),
92 static_cast<size_t>(LEVEL_FATAL) - static_cast<size_t>(testlevel) + 1u);
93 }
94 if (HasFailure()) {
95 HLOGD("LogLevelTest failed. testlevel is %d, logMessage is '%s'", testlevel,
96 logMessage.c_str());
97 if (useStdout) {
98 printf("%s", log.c_str());
99 }
100 }
101 // restore
102 DebugLogger::GetInstance()->SetLogLevel(oldLevel);
103 DebugLogger::GetInstance()->exitOnFatal_ = true;
104 }
105
106 /**
107 * @tc.name: Log
108 * @tc.desc:
109 * @tc.type: FUNC
110 */
111 HWTEST_F(DebugLoggerTest, Log, TestSize.Level1)
112 {
113 DebugLogger::GetInstance()->SetMixLogOutput(true);
114 StdoutRecord stdoutRecord;
115 std::string log;
116
117 stdoutRecord.Start();
118 HLOGD("123");
119 log = stdoutRecord.Stop();
120 ASSERT_TRUE(log.size() >= 4u);
121 EXPECT_STREQ(log.substr(log.size() - 4u).c_str(), "123\n");
122
123 stdoutRecord.Start();
124 HLOGD("%% %% %%");
125 log = stdoutRecord.Stop();
126 EXPECT_STREQ(log.substr(log.size() - 6u).c_str(), "% % %\n");
127
128 DebugLogger::GetInstance()->SetMixLogOutput(false);
129
130 stdoutRecord.Start();
131 printf("123\n");
132 log = stdoutRecord.Stop();
133 EXPECT_STREQ(log.c_str(), "123\n");
134
135 stdoutRecord.Start();
136 printf("%% %% %%\n");
137 log = stdoutRecord.Stop();
138 EXPECT_STREQ(log.c_str(), "% % %\n");
139 }
140
141 /**
142 * @tc.name: SetMixLogOutput
143 * @tc.desc:
144 * @tc.type: FUNC
145 */
146 HWTEST_F(DebugLoggerTest, SetMixLogOutput, TestSize.Level1)
147 {
148 DebugLogger::GetInstance()->SetMixLogOutput(true);
149 for (int loglevel = LEVEL_MUCH; loglevel < LEVEL_MAX; loglevel++) {
150 LogLevelTest(static_cast<DebugLevel>(loglevel), true);
151 }
152
153 DebugLogger::GetInstance()->SetMixLogOutput(false);
154 for (int loglevel = LEVEL_MUCH; loglevel < LEVEL_MAX; loglevel++) {
155 LogLevelTest(static_cast<DebugLevel>(loglevel), false);
156 }
157 }
158
159 /**
160 * @tc.name: SetLogLevel
161 * @tc.desc:
162 * @tc.type: FUNC
163 */
164 HWTEST_F(DebugLoggerTest, SetLogLevel, TestSize.Level1)
165 {
166 for (int loglevel = LEVEL_MUCH; loglevel < LEVEL_MAX; loglevel++) {
167 LogLevelTest(static_cast<DebugLevel>(loglevel));
168 }
169 }
170
171 /**
172 * @tc.name: GetInstance
173 * @tc.desc:
174 * @tc.type: FUNC
175 */
176 HWTEST_F(DebugLoggerTest, GetInstance, TestSize.Level1)
177 {
178 EXPECT_NE(DebugLogger::GetInstance(), nullptr);
179 }
180
181 /**
182 * @tc.name: SetLogPath
183 * @tc.desc:
184 * @tc.type: FUNC
185 */
186 HWTEST_F(DebugLoggerTest, SetLogPath, TestSize.Level1)
187 {
188 const std::string logFile1 = "log1.txt";
189 const std::string logFile2 = "log2.txt";
190 const std::string logFile3 = "log3.txt";
191
192 EXPECT_EQ(access(DEFAULT_LOG_PATH.c_str(), F_OK), 0);
193
194 DebugLogger::GetInstance()->SetLogPath(logFile1);
195 EXPECT_NE(access(DEFAULT_LOG_PATH.c_str(), F_OK), 0);
196 EXPECT_EQ(access(logFile1.c_str(), F_OK), 0);
197
198 DebugLogger::GetInstance()->SetLogPath(logFile2);
199 EXPECT_NE(access(logFile1.c_str(), F_OK), 0);
200 EXPECT_EQ(access(logFile2.c_str(), F_OK), 0);
201
202 DebugLogger::GetInstance()->SetLogPath(logFile3);
203 EXPECT_NE(access(logFile2.c_str(), F_OK), 0);
204 EXPECT_EQ(access(logFile3.c_str(), F_OK), 0);
205
206 DebugLogger::GetInstance()->SetLogPath(DEFAULT_LOG_PATH);
207 EXPECT_NE(access(logFile3.c_str(), F_OK), 0);
208 EXPECT_EQ(access(DEFAULT_LOG_PATH.c_str(), F_OK), 0);
209 }
210
211 /**
212 * @tc.name: SetLogPath
213 * @tc.desc:
214 * @tc.type: FUNC
215 */
216 HWTEST_F(DebugLoggerTest, SetLogTags, TestSize.Level1)
217 {
218 const std::string errorLogTag = "errtag";
219 const std::string errorLogTags = "errtag,errtag,errtag";
220 const std::string mixLogTags = "errtag,errtag,DebugTest,errtag";
221 const std::string logTags = "DebugTest:T,DebugTest:V";
222
223 DebugLogger::GetInstance()->SetLogTags("DebugTest");
224
225 EXPECT_EQ(DebugLogger::GetInstance()->ShouldLog(LEVEL_MUCH, "DebugTest"), true);
226 EXPECT_EQ(DebugLogger::GetInstance()->ShouldLog(LEVEL_DEBUG, "DebugTest"), true);
227
228 EXPECT_EQ(DebugLogger::GetInstance()->ShouldLog(LEVEL_MUCH, errorLogTag), false);
229 EXPECT_EQ(DebugLogger::GetInstance()->ShouldLog(LEVEL_DEBUG, errorLogTag), true);
230
231 DebugLogger::GetInstance()->SetLogTags(errorLogTags);
232
233 EXPECT_EQ(DebugLogger::GetInstance()->ShouldLog(LEVEL_MUCH, "DebugTest"), false);
234 EXPECT_EQ(DebugLogger::GetInstance()->ShouldLog(LEVEL_DEBUG, "DebugTest"), true);
235
236 EXPECT_EQ(DebugLogger::GetInstance()->ShouldLog(LEVEL_MUCH, errorLogTag), true);
237 EXPECT_EQ(DebugLogger::GetInstance()->ShouldLog(LEVEL_DEBUG, errorLogTag), true);
238
239 DebugLogger::GetInstance()->SetLogTags(mixLogTags);
240
241 EXPECT_EQ(DebugLogger::GetInstance()->ShouldLog(LEVEL_MUCH, "DebugTest"), true);
242 EXPECT_EQ(DebugLogger::GetInstance()->ShouldLog(LEVEL_DEBUG, "DebugTest"), true);
243
244 DebugLogger::GetInstance()->SetLogTags(logTags);
245
246 EXPECT_EQ(DebugLogger::GetInstance()->ShouldLog(LEVEL_MUCH, "DebugTest"), false);
247 EXPECT_EQ(DebugLogger::GetInstance()->ShouldLog(LEVEL_VERBOSE, "DebugTest"), true);
248
249 // back to default
250 DebugLogger::GetInstance()->SetLogTags("");
251 }
252
253 /**
254 * @tc.name: Disable
255 * @tc.desc:
256 * @tc.type: FUNC
257 */
258 HWTEST_F(DebugLoggerTest, Disable, TestSize.Level1)
259 {
260 HLOGD("log disabled");
261 DebugLogger::GetInstance()->Disable(true);
262 ASSERT_EQ(DebugLogger::GetInstance()->logDisabled_, true);
263 for (int loglevel = LEVEL_MUCH; loglevel < LEVEL_MAX; loglevel++) {
264 LogLevelTest(static_cast<DebugLevel>(loglevel));
265 }
266 ASSERT_EQ(DebugLogger::GetInstance()->logDisabled_, true);
267
268 HLOGD("log enabled");
269 DebugLogger::GetInstance()->Disable(false);
270 ASSERT_EQ(DebugLogger::GetInstance()->logDisabled_, false);
271 for (int loglevel = LEVEL_MUCH; loglevel < LEVEL_MAX; loglevel++) {
272 LogLevelTest(static_cast<DebugLevel>(loglevel));
273 }
274 }
275
276 /**
277 * @tc.name: EnableHiLog
278 * @tc.desc:
279 * @tc.type: FUNC
280 */
281 HWTEST_F(DebugLoggerTest, EnableHiLog, TestSize.Level1)
282 {
283 #if is_ohos
284 DebugLogger::GetInstance()->EnableHiLog(true);
285 for (int loglevel = LEVEL_MUCH; loglevel < LEVEL_MAX; loglevel++) {
286 LogLevelTest(static_cast<DebugLevel>(loglevel));
287 }
288 DebugLogger::GetInstance()->EnableHiLog(false);
289 #endif
290 }
291 } // namespace HiPerf
292 } // namespace Developtools
293 } // namespace OHOS
294