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