1 /**
2 * Copyright (c) 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 "test_logger.h"
17
18 #include "macros.h"
19 #include "utils/logger.h"
20
21 #include "gtest/gtest.h"
22 #include "gmock/gmock.h"
23
24 #include <iomanip>
25 #include <iostream>
26 #include <sstream>
27
28 using testing::AnyNumber;
29 using testing::UnitTest;
30
31 namespace panda::tooling::inspector::test {
TestLogger(unsigned flags)32 TestLogger::TestLogger(unsigned flags) : Logger(Level::DEBUG, ComponentMask().set(Component::DEBUGGER)), flags_(flags)
33 {
34 if ((flags_ & OUTPUT_UNBUFFERED) != 0) {
35 flags_ &= ~OUTPUT_ON_FAIL;
36 }
37
38 oldLogger_ = Logger::logger;
39 Logger::logger = this;
40
41 EXPECT_CALL(*this, LogLineInternal).Times(AnyNumber());
42
43 ON_CALL(*this, LogLineInternal).WillByDefault([this](auto level, auto component, auto &message) {
44 if ((flags_ & OUTPUT_UNBUFFERED) != 0) {
45 std::cout << " " << FormatLogLine(level, component, message) << '\n' << std::flush;
46 }
47
48 if ((flags_ & OUTPUT_ON_FAIL) != 0) {
49 log_ << " " << FormatLogLine(level, component, message) << '\n';
50 }
51
52 if ((flags_ & FAIL_ON_ERROR) != 0) {
53 ASSERT_NE(level, Level::ERROR) << "Log line: " << FormatLogLine(level, component, message);
54 }
55 });
56 }
57
~TestLogger()58 TestLogger::~TestLogger()
59 {
60 Logger::logger = oldLogger_;
61
62 if ((flags_ & OUTPUT_ON_FAIL) != 0) {
63 if (auto *testInfo = UnitTest::GetInstance()->current_test_info()) {
64 if (testInfo->result()->Failed()) {
65 std::cout << "Full log:\n" << log_.rdbuf() << std::flush;
66 }
67 }
68 }
69 }
70
FormatLogLine(Level level,Component,const std::string & message) const71 std::string TestLogger::FormatLogLine(Level level, Component /* component */, const std::string &message) const
72 {
73 std::stringstream logLine;
74
75 switch (level) {
76 case Logger::Level::FATAL:
77 logLine << "F";
78 break;
79 case Logger::Level::ERROR:
80 logLine << "E";
81 break;
82 case Logger::Level::WARNING:
83 logLine << "W";
84 break;
85 case Logger::Level::INFO:
86 logLine << "I";
87 break;
88 case Logger::Level::DEBUG:
89 logLine << "D";
90 break;
91 default:
92 UNREACHABLE();
93 }
94
95 if (!prefix_.empty()) {
96 logLine << "[" << prefix_ << "]";
97 }
98
99 logLine << ": " << message;
100 return logLine.str();
101 }
102 } // namespace panda::tooling::inspector::test
103