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 #define HILOG_TAG "OptionDebugTest"
16 
17 #include "option_debug_test.h"
18 
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21 #include <random>
22 
23 #include <hilog/log.h>
24 
25 using namespace testing::ext;
26 using namespace std;
27 using namespace OHOS::HiviewDFX;
28 namespace OHOS {
29 namespace Developtools {
30 namespace HiPerf {
31 class OptionDebugTest : public testing::Test {
32 public:
33     static void SetUpTestCase(void);
34     static void TearDownTestCase(void);
35     void SetUp();
36     void TearDown();
37     const std::string TEST_LOG_MESSAGE = "<HELLO_TEST_LOG_MESSAGE>";
38     void LogLevelTest(std::vector<std::string> args, DebugLevel level, bool result = true);
39     default_random_engine rnd_;
40 };
41 
SetUpTestCase()42 void OptionDebugTest::SetUpTestCase()
43 {
44     DebugLogger::GetInstance()->Reset();
45 }
46 
TearDownTestCase()47 void OptionDebugTest::TearDownTestCase()
48 {
49     DebugLogger::GetInstance()->Reset();
50 }
51 
SetUp()52 void OptionDebugTest::SetUp()
53 {
54     Option::ClearMainOptions();
55     SubCommand::RegisterSubCommand(TEST_CMD_NOTHING,
56                                    std::make_unique<SubCommandTest>(TEST_CMD_NOTHING));
57     RegisterMainCommandDebug();
58 }
59 
TearDown()60 void OptionDebugTest::TearDown()
61 {
62     SubCommand::ClearSubCommands();
63     Option::ClearMainOptions();
64 }
65 
LogLevelTest(std::vector<std::string> args, const DebugLevel testlevel, bool result)66 void OptionDebugTest::LogLevelTest(std::vector<std::string> args, const DebugLevel testlevel, bool result)
67 {
68     // backup
69     DebugLevel oldLevel = DebugLogger::GetInstance()->GetLogLevel();
70     EXPECT_EQ(Command::DispatchCommands(args), result);
71     if (!result) {
72         return;
73     }
74 
75     const std::string logMessage =
76         TEST_LOG_MESSAGE + std::to_string(rnd_()) + "_" + std::to_string(testlevel);
77     HLOGE("%s", logMessage.c_str());
78     HLOGW("%s", logMessage.c_str());
79     HLOGI("%s", logMessage.c_str());
80     HLOGD("%s", logMessage.c_str());
81     HLOGV("%s", logMessage.c_str());
82     HLOGM("%s", logMessage.c_str());
83 
84     if (fflush(DebugLogger::GetInstance()->file_) != 0) {
85         HLOGD("fflush failed.");
86     }
87     std::string log = ReadFileToString(DebugLogger::GetInstance()->logPath_);
88     ASSERT_EQ(log.empty(), false);
89     // we have 6 level log
90     // so the logout line is : (all log level - curr log level) + curr log level self
91     EXPECT_EQ(SubStringCount(log, logMessage),
92               static_cast<size_t>(LEVEL_ERROR) - static_cast<size_t>(testlevel) + 1u);
93     if (HasFailure()) {
94         HLOGD("LogLevelTest failed.");
95     }
96     // restore
97     DebugLogger::GetInstance()->SetLogLevel(oldLevel);
98 }
99 
100 /**
101  * @tc.name: TestRegisterMainCommandDebug
102  * @tc.desc:
103  * @tc.type: FUNC
104  */
HWTEST_F(OptionDebugTest, TestRegisterMainCommandDebug, TestSize.Level1)105 HWTEST_F(OptionDebugTest, TestRegisterMainCommandDebug, TestSize.Level1)
106 {
107     // see RegisterMainCommandDebug
108 #if is_ohos
109     EXPECT_EQ(Option::GetMainOptions().size(), 8u);
110 #else
111     EXPECT_EQ(Option::GetMainOptions().size(), 7u);
112 #endif
113 }
114 
115 /**
116  * @tc.name: debug
117  * @tc.desc:
118  * @tc.type: FUNC
119  */
HWTEST_F(OptionDebugTest, debug, TestSize.Level1)120 HWTEST_F(OptionDebugTest, debug, TestSize.Level1)
121 {
122     LogLevelTest({"--debug", TEST_CMD_NOTHING}, LEVEL_DEBUG);
123 }
124 
125 /**
126  * @tc.name: verbose
127  * @tc.desc:
128  * @tc.type: FUNC
129  */
HWTEST_F(OptionDebugTest, verbose, TestSize.Level1)130 HWTEST_F(OptionDebugTest, verbose, TestSize.Level1)
131 {
132     LogLevelTest({"--verbose", TEST_CMD_NOTHING}, LEVEL_VERBOSE);
133 }
134 
135 /**
136  * @tc.name: verbose
137  * @tc.desc:
138  * @tc.type: FUNC
139  */
HWTEST_F(OptionDebugTest, much, TestSize.Level1)140 HWTEST_F(OptionDebugTest, much, TestSize.Level1)
141 {
142     LogLevelTest({"--much", TEST_CMD_NOTHING}, LEVEL_MUCH);
143 }
144 
145 /**
146  * @tc.name: undebug
147  * @tc.desc:
148  * @tc.type: FUNC
149  */
HWTEST_F(OptionDebugTest, undebug, TestSize.Level1)150 HWTEST_F(OptionDebugTest, undebug, TestSize.Level1)
151 {
152     LogLevelTest({"--debug"}, LEVEL_DEBUG, false);
153 }
154 
155 /**
156  * @tc.name: unverbose
157  * @tc.desc:
158  * @tc.type: FUNC
159  */
HWTEST_F(OptionDebugTest, unverbose, TestSize.Level1)160 HWTEST_F(OptionDebugTest, unverbose, TestSize.Level1)
161 {
162     LogLevelTest({"--verbose"}, LEVEL_VERBOSE, false);
163 }
164 
165 /**
166  * @tc.name: unmuch
167  * @tc.desc:
168  * @tc.type: FUNC
169  */
HWTEST_F(OptionDebugTest, unmuch, TestSize.Level1)170 HWTEST_F(OptionDebugTest, unmuch, TestSize.Level1)
171 {
172     LogLevelTest({"--much"}, LEVEL_MUCH, false);
173 }
174 
175 /**
176  * @tc.name: mixlog
177  * @tc.desc:
178  * @tc.type: FUNC
179  */
HWTEST_F(OptionDebugTest, mixlog, TestSize.Level1)180 HWTEST_F(OptionDebugTest, mixlog, TestSize.Level1)
181 {
182     StdoutRecord stdoutRecord;
183     stdoutRecord.Start();
184     EXPECT_EQ(Command::DispatchCommands({"--mixlog", TEST_CMD_NOTHING}), true);
185 
186     const std::string logMessage = TEST_LOG_MESSAGE + std::to_string(rnd_());
187     HLOGD("%s", logMessage.c_str());
188     std::string stringOut = stdoutRecord.Stop();
189     EXPECT_NE(stringOut.find(logMessage), std::string::npos);
190 
191     // close it
192     DebugLogger::GetInstance()->SetMixLogOutput(false);
193 }
194 
195 /**
196  * @tc.name: logpath
197  * @tc.desc:
198  * @tc.type: FUNC
199  */
HWTEST_F(OptionDebugTest, logpath, TestSize.Level1)200 HWTEST_F(OptionDebugTest, logpath, TestSize.Level1)
201 {
202     EXPECT_EQ(Command::DispatchCommands({"--logpath", "./log.temp.txt", TEST_CMD_NOTHING}), true);
203     EXPECT_EQ(Command::DispatchCommands({"--logpath", DEFAULT_LOG_PATH, TEST_CMD_NOTHING}), true);
204 }
205 
206 /**
207  * @tc.name: unlogpath
208  * @tc.desc:
209  * @tc.type: FUNC
210  */
HWTEST_F(OptionDebugTest, unlogpath, TestSize.Level1)211 HWTEST_F(OptionDebugTest, unlogpath, TestSize.Level1)
212 {
213     EXPECT_EQ(Command::DispatchCommands({"--logpath"}), false);
214 }
215 
216 /**
217  * @tc.name: logtag
218  * @tc.desc:
219  * @tc.type: FUNC
220  */
HWTEST_F(OptionDebugTest, logtag, TestSize.Level1)221 HWTEST_F(OptionDebugTest, logtag, TestSize.Level1)
222 {
223     LogLevelTest({"--logtag", "OptionDebugTest", TEST_CMD_NOTHING}, LEVEL_MUCH);
224     LogLevelTest({"--logtag", "123", TEST_CMD_NOTHING}, DebugLogger::GetInstance()->GetLogLevel());
225 }
226 
227 /**
228  * @tc.name: unlogtag
229  * @tc.desc:
230  * @tc.type: FUNC
231  */
HWTEST_F(OptionDebugTest, unlogtag, TestSize.Level1)232 HWTEST_F(OptionDebugTest, unlogtag, TestSize.Level1)
233 {
234     LogLevelTest({"--logtag"}, LEVEL_MUCH, false);
235 }
236 
237 /**
238  * @tc.name: logDisabled
239  * @tc.desc:
240  * @tc.type: FUNC
241  */
HWTEST_F(OptionDebugTest, logDisabled, TestSize.Level1)242 HWTEST_F(OptionDebugTest, logDisabled, TestSize.Level1)
243 {
244     // no log will save in log file.
245     LogLevelTest({"--nodebug", TEST_CMD_NOTHING}, LEVEL_FATAL);
246     DebugLogger::GetInstance()->Disable(false);
247 }
248 
249 /**
250  * @tc.name: unlogDisabled
251  * @tc.desc:
252  * @tc.type: FUNC
253  */
HWTEST_F(OptionDebugTest, unlogDisabled, TestSize.Level1)254 HWTEST_F(OptionDebugTest, unlogDisabled, TestSize.Level1)
255 {
256     // no log will save in log file.
257     LogLevelTest({"--nodebug"}, LEVEL_FATAL, false);
258     DebugLogger::GetInstance()->Disable(false);
259 }
260 
261 /**
262  * @tc.name: hilog
263  * @tc.desc:
264  * @tc.type: FUNC
265  */
HWTEST_F(OptionDebugTest, hilog, TestSize.Level1)266 HWTEST_F(OptionDebugTest, hilog, TestSize.Level1)
267 {
268 #if is_ohos
269     // no log will save in log file.
270     LogLevelTest({"--hilog", TEST_CMD_NOTHING}, LEVEL_FATAL);
271 
272     DebugLogger::GetInstance()->EnableHiLog(false);
273 #endif
274 }
275 } // namespace HiPerf
276 } // namespace Developtools
277 } // namespace OHOS
278