• 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 
16 #include "os/thread.h"
17 #include "utils/logger.h"
18 #include "utils/string_helpers.h"
19 
20 #include <cstdio>
21 
22 #include <fstream>
23 #include <regex>
24 #include <streambuf>
25 
26 #include <gtest/gtest.h>
27 
28 namespace panda::test {
29 
30 class LoggerTest : public testing::Test {
31 public:
SetUpTestSuite()32     static void SetUpTestSuite()
33     {
34         system("mount -o rw,remount /");
35     }
36 };
37 
38 HWTEST_F(LoggerTest, Initialization, testing::ext::TestSize.Level0)
39 {
40     EXPECT_FALSE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::ALLOC));
41 
42     testing::FLAGS_gtest_death_test_style = "fast";
43     testing::internal::CaptureStderr();
44 
45     LOG(DEBUG, COMMON) << "1";
46     LOG(INFO, COMMON) << "2";
47     LOG(ERROR, COMMON) << "3";
48 
49     std::string err = testing::internal::GetCapturedStderr();
50     EXPECT_EQ(err, "");
51 
52     EXPECT_DEATH_IF_SUPPORTED(LOG(FATAL, COMMON) << "4", "");
53 
54     Logger::InitializeStdLogging(Logger::Level::DEBUG, panda::LoggerComponentMaskAll);
55     EXPECT_TRUE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::ALLOC));
56 
57     testing::internal::CaptureStderr();
58 
59     LOG(DEBUG, COMMON) << "a";
60     LOG(INFO, COMMON) << "b";
61     LOG(ERROR, COMMON) << "c";
62 
63     err = testing::internal::GetCapturedStderr();
64     uint32_t tid = os::thread::GetCurrentThreadId();
65     std::string res = helpers::string::Format(
66 #ifndef NDEBUG
67         "[TID %06x] D/common: a\n"
68 #endif
69         "[TID %06x] I/common: b\n"
70         "[TID %06x] E/common: c\n",
71         tid, tid, tid);
72     EXPECT_EQ(err, res);
73 
74     EXPECT_DEATH_IF_SUPPORTED(LOG(FATAL, COMMON) << "d", "\\[TID [0-9a-f]{6}\\] F/common: d");
75 
76     Logger::Destroy();
77     EXPECT_FALSE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::ALLOC));
78 
79     testing::internal::CaptureStderr();
80 
81     LOG(DEBUG, COMMON) << "1";
82     LOG(INFO, COMMON) << "2";
83     LOG(ERROR, COMMON) << "3";
84 
85     err = testing::internal::GetCapturedStderr();
86     EXPECT_EQ(err, "");
87 
88     EXPECT_DEATH_IF_SUPPORTED(LOG(FATAL, COMMON) << "4", "");
89 }
90 
91 HWTEST_F(LoggerTest, LoggingExceptionsFatal, testing::ext::TestSize.Level0)
92 {
93     testing::FLAGS_gtest_death_test_style = "fast";
94 
95     panda::Logger::ComponentMask component_mask;
96     component_mask.set(Logger::Component::COMPILER);
97 
98     Logger::InitializeStdLogging(Logger::Level::FATAL, component_mask);
99     EXPECT_TRUE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::COMPILER));
100     EXPECT_TRUE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::ASSEMBLER));
101     EXPECT_TRUE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::DISASSEMBLER));
102     EXPECT_FALSE(Logger::IsLoggingOn(Logger::Level::ERROR, Logger::Component::COMPILER));
103     EXPECT_FALSE(Logger::IsLoggingOn(Logger::Level::ERROR, Logger::Component::ASSEMBLER));
104     EXPECT_FALSE(Logger::IsLoggingOn(Logger::Level::ERROR, Logger::Component::DISASSEMBLER));
105 
106     EXPECT_DEATH_IF_SUPPORTED(LOG(FATAL, COMPILER) << "d1", "\\[TID [0-9a-f]{6}\\] F/compiler: d1");
107     EXPECT_DEATH_IF_SUPPORTED(LOG(FATAL, ASSEMBLER) << "d2", "\\[TID [0-9a-f]{6}\\] F/assembler: d2");
108     EXPECT_DEATH_IF_SUPPORTED(LOG(FATAL, DISASSEMBLER) << "d3", "\\[TID [0-9a-f]{6}\\] F/disassembler: d3");
109 
110     testing::internal::CaptureStderr();
111 
112     LOG(ERROR, COMPILER) << "c";
113     LOG(ERROR, ASSEMBLER) << "a";
114     LOG(ERROR, DISASSEMBLER) << "d";
115 
116     std::string err = testing::internal::GetCapturedStderr();
117     EXPECT_EQ(err, "");
118 
119     Logger::Destroy();
120 }
121 
122 HWTEST_F(LoggerTest, LoggingExceptionsError, testing::ext::TestSize.Level0)
123 {
124     testing::FLAGS_gtest_death_test_style = "fast";
125 
126     panda::Logger::ComponentMask component_mask;
127     component_mask.set(Logger::Component::COMPILER);
128 
129     Logger::InitializeStdLogging(Logger::Level::ERROR, component_mask);
130     EXPECT_TRUE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::COMPILER));
131     EXPECT_TRUE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::ASSEMBLER));
132     EXPECT_TRUE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::DISASSEMBLER));
133     EXPECT_TRUE(Logger::IsLoggingOn(Logger::Level::ERROR, Logger::Component::COMPILER));
134     EXPECT_FALSE(Logger::IsLoggingOn(Logger::Level::ERROR, Logger::Component::ASSEMBLER));
135     EXPECT_FALSE(Logger::IsLoggingOn(Logger::Level::ERROR, Logger::Component::DISASSEMBLER));
136 
137     EXPECT_DEATH_IF_SUPPORTED(LOG(FATAL, COMPILER) << "d1", "\\[TID [0-9a-f]{6}\\] F/compiler: d1");
138     EXPECT_DEATH_IF_SUPPORTED(LOG(FATAL, ASSEMBLER) << "d2", "\\[TID [0-9a-f]{6}\\] F/assembler: d2");
139     EXPECT_DEATH_IF_SUPPORTED(LOG(FATAL, DISASSEMBLER) << "d3", "\\[TID [0-9a-f]{6}\\] F/disassembler: d3");
140 
141     testing::internal::CaptureStderr();
142 
143     LOG(ERROR, COMPILER) << "c";
144     LOG(ERROR, ASSEMBLER) << "a";
145     LOG(ERROR, DISASSEMBLER) << "d";
146 
147     std::string err = testing::internal::GetCapturedStderr();
148     uint32_t tid = os::thread::GetCurrentThreadId();
149     std::string res = helpers::string::Format("[TID %06x] E/compiler: c\n", tid);
150     EXPECT_EQ(err, res);
151 
152     Logger::Destroy();
153 }
154 
155 HWTEST_F(LoggerTest, FilterInfo, testing::ext::TestSize.Level0)
156 {
157     Logger::InitializeStdLogging(Logger::Level::INFO, panda::LoggerComponentMaskAll);
158     EXPECT_TRUE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::ALLOC));
159 
160     testing::internal::CaptureStderr();
161 
162     LOG(DEBUG, COMMON) << "a";
163     LOG(INFO, COMMON) << "b";
164     LOG(ERROR, COMMON) << "c";
165 
166     std::string err = testing::internal::GetCapturedStderr();
167     uint32_t tid = os::thread::GetCurrentThreadId();
168     std::string res = helpers::string::Format(
169         "[TID %06x] I/common: b\n"
170         "[TID %06x] E/common: c\n",
171         tid, tid);
172     EXPECT_EQ(err, res);
173 
174     Logger::Destroy();
175     EXPECT_FALSE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::ALLOC));
176 }
177 
178 HWTEST_F(LoggerTest, FilterError, testing::ext::TestSize.Level0)
179 {
180     Logger::InitializeStdLogging(Logger::Level::ERROR, panda::LoggerComponentMaskAll);
181     EXPECT_TRUE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::ALLOC));
182 
183     testing::internal::CaptureStderr();
184 
185     LOG(DEBUG, COMMON) << "a";
186     LOG(INFO, COMMON) << "b";
187     LOG(ERROR, COMMON) << "c";
188 
189     std::string err = testing::internal::GetCapturedStderr();
190     uint32_t tid = os::thread::GetCurrentThreadId();
191     std::string res = helpers::string::Format("[TID %06x] E/common: c\n", tid);
192     EXPECT_EQ(err, res);
193 
194     Logger::Destroy();
195     EXPECT_FALSE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::ALLOC));
196 }
197 
198 HWTEST_F(LoggerTest, FilterFatal, testing::ext::TestSize.Level0)
199 {
200     Logger::InitializeStdLogging(Logger::Level::FATAL, panda::LoggerComponentMaskAll);
201     EXPECT_TRUE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::ALLOC));
202 
203     testing::internal::CaptureStderr();
204 
205     LOG(DEBUG, COMMON) << "a";
206     LOG(INFO, COMMON) << "b";
207     LOG(ERROR, COMMON) << "c";
208 
209     std::string err = testing::internal::GetCapturedStderr();
210     EXPECT_EQ(err, "");
211 
212     Logger::Destroy();
213     EXPECT_FALSE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::ALLOC));
214 }
215 
216 HWTEST_F(LoggerTest, ComponentFilter, testing::ext::TestSize.Level0)
217 {
218     panda::Logger::ComponentMask component_mask;
219     component_mask.set(Logger::Component::COMPILER);
220     component_mask.set(Logger::Component::GC);
221 
222     Logger::InitializeStdLogging(Logger::Level::INFO, component_mask);
223     EXPECT_FALSE(Logger::IsLoggingOn(Logger::Level::WARNING, Logger::Component::ALLOC));
224     EXPECT_TRUE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::COMPILER));
225     EXPECT_TRUE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::GC));
226 
227     testing::internal::CaptureStderr();
228 
229     LOG(INFO, COMMON) << "a";
230     LOG(INFO, COMPILER) << "b";
231     LOG(INFO, RUNTIME) << "c";
232     LOG(INFO, GC) << "d";
233 
234     std::string err = testing::internal::GetCapturedStderr();
235     uint32_t tid = os::thread::GetCurrentThreadId();
236     std::string res = helpers::string::Format(
237         "[TID %06x] I/compiler: b\n"
238         "[TID %06x] I/gc: d\n",
239         tid, tid);
240     EXPECT_EQ(err, res);
241 
242     Logger::Destroy();
243     EXPECT_FALSE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::ALLOC));
244 }
245 
246 HWTEST_F(LoggerTest, FileLogging, testing::ext::TestSize.Level0)
247 {
248     uint32_t tid = os::thread::GetCurrentThreadId();
249     std::string log_filename = helpers::string::Format("/tmp/gtest_panda_logger_file_%06x", tid);
250 
251     Logger::InitializeFileLogging(log_filename, Logger::Level::INFO,
252                                   panda::Logger::ComponentMask().set(Logger::Component::COMMON));
253     EXPECT_TRUE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::ALLOC));
254     EXPECT_TRUE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::COMMON));
255 
256     LOG(DEBUG, COMMON) << "a";
257     LOG(INFO, COMMON) << "b";
258     LOG(ERROR, COMPILER) << "c";
259     LOG(ERROR, COMMON) << "d";
260 
261 #if GTEST_HAS_DEATH_TEST
262     testing::FLAGS_gtest_death_test_style = "fast";
263 
264     EXPECT_DEATH(LOG(FATAL, COMMON) << "e", "");
265 
266     std::string res = helpers::string::Format(
267         "\\[TID %06x\\] I/common: b\n"
268         "\\[TID %06x\\] E/common: d\n"
269         "\\[TID [0-9a-f]{6}\\] F/common: e\n",
270         tid, tid);
271     std::regex e(res);
272     {
273         std::ifstream log_file_stream(log_filename);
274         std::string log_file_content((std::istreambuf_iterator<char>(log_file_stream)),
275                                      std::istreambuf_iterator<char>());
276         EXPECT_TRUE(std::regex_match(log_file_content, e));
277     }
278 #endif  // GTEST_HAS_DEATH_TEST
279 
280     EXPECT_EQ(std::remove(log_filename.c_str()), 0);
281 
282     Logger::Destroy();
283     EXPECT_FALSE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::ALLOC));
284 }
285 
286 HWTEST_F(LoggerTest, Multiline, testing::ext::TestSize.Level0)
287 {
288     Logger::InitializeStdLogging(Logger::Level::INFO, panda::Logger::ComponentMask().set(Logger::Component::COMMON));
289     EXPECT_TRUE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::ALLOC));
290     EXPECT_TRUE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::COMMON));
291 
292     testing::internal::CaptureStderr();
293 
294     LOG(INFO, COMMON) << "a\nb\nc\n\nd\n";
295 
296     std::string err = testing::internal::GetCapturedStderr();
297     uint32_t tid = os::thread::GetCurrentThreadId();
298     std::string res = helpers::string::Format(
299         "[TID %06x] I/common: a\n"
300         "[TID %06x] I/common: b\n"
301         "[TID %06x] I/common: c\n"
302         "[TID %06x] I/common: \n"
303         "[TID %06x] I/common: d\n"
304         "[TID %06x] I/common: \n",
305         tid, tid, tid, tid, tid, tid);
306     EXPECT_EQ(err, res);
307 
308     Logger::Destroy();
309     EXPECT_FALSE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::ALLOC));
310 }
311 
312 HWTEST_F(LoggerTest, LogIf, testing::ext::TestSize.Level0)
313 {
314     Logger::InitializeStdLogging(Logger::Level::INFO, panda::LoggerComponentMaskAll);
315     EXPECT_TRUE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::ALLOC));
316 
317     testing::internal::CaptureStderr();
318 
319     LOG_IF(true, INFO, COMMON) << "a";
320     LOG_IF(false, INFO, COMMON) << "b";
321 
322     std::string err = testing::internal::GetCapturedStderr();
323     uint32_t tid = os::thread::GetCurrentThreadId();
324     std::string res = helpers::string::Format("[TID %06x] I/common: a\n", tid);
325     EXPECT_EQ(err, res);
326 
327     Logger::Destroy();
328     EXPECT_FALSE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::ALLOC));
329 }
330 
331 HWTEST_F(LoggerTest, LogOnce, testing::ext::TestSize.Level0)
332 {
333     Logger::InitializeStdLogging(Logger::Level::INFO, panda::LoggerComponentMaskAll);
334     EXPECT_TRUE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::ALLOC));
335 
336     testing::internal::CaptureStderr();
337 
338     LOG_ONCE(INFO, COMMON) << "a";
339     for (int i = 0; i < 10; ++i) {
340         LOG_ONCE(INFO, COMMON) << "b";
341     }
342     LOG_ONCE(INFO, COMMON) << "c";
343 
344     std::string err = testing::internal::GetCapturedStderr();
345     uint32_t tid = os::thread::GetCurrentThreadId();
346     std::string res = helpers::string::Format(
347         "[TID %06x] I/common: a\n"
348         "[TID %06x] I/common: b\n"
349         "[TID %06x] I/common: c\n",
350         tid, tid, tid);
351     EXPECT_EQ(err, res);
352 
353     Logger::Destroy();
354     EXPECT_FALSE(Logger::IsLoggingOn(Logger::Level::FATAL, Logger::Component::ALLOC));
355 }
356 
357 }  // namespace panda::test
358