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