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