1 // Copyright 2020 The Android Open Source Project
2 //
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 #include <gmock/gmock.h>
16
17 #include "host-common/logging.h"
18
19 #include <thread>
20
21 #include "aemu/base/testing/TestUtils.h"
22
23 namespace {
24
25 using ::testing::EndsWith;
26 using ::testing::HasSubstr;
27 using ::testing::Not;
28 using ::testing::StartsWith;
29 using ::testing::internal::CaptureStderr;
30 using ::testing::internal::CaptureStdout;
31 using ::testing::internal::GetCapturedStderr;
32 using ::testing::internal::GetCapturedStdout;
33
34 // Returns the microseconds since the Unix epoch for Sep 13, 2020 12:26:40.123456 in the machine's
35 // local timezone.
defaultTimestamp()36 int64_t defaultTimestamp() {
37 std::tm time = {};
38 time.tm_year = 2020 - 1900;
39 time.tm_mon = 9 - 1; // month starts at 0
40 time.tm_mday = 13;
41 time.tm_hour = 12;
42 time.tm_min = 26;
43 time.tm_sec = 40;
44 time.tm_isdst = -1; // let mktime determine whether DST is in effect
45 int64_t timestamp_s = mktime(&time);
46 EXPECT_GT(timestamp_s, 0) << "mktime() failed";
47 return timestamp_s * 1000000 + 123456;
48 }
49
TEST(Logging,ERRMacroNoArguments)50 TEST(Logging, ERRMacroNoArguments) {
51 CaptureStderr();
52 ERR("Hello world.");
53 std::string log = GetCapturedStderr();
54 EXPECT_THAT(log, StartsWith("E"));
55 EXPECT_THAT(log, EndsWith("] Hello world.\n"));
56 }
57
TEST(Logging,ERRMacroWithArguments)58 TEST(Logging, ERRMacroWithArguments) {
59 CaptureStderr();
60 ERR("hello %s %d", "world", 1);
61 std::string log = GetCapturedStderr();
62 EXPECT_THAT(log, StartsWith("E"));
63 EXPECT_THAT(log, EndsWith("] hello world 1\n"));
64 }
65
TEST(Logging,INFOMacroNoArguments)66 TEST(Logging, INFOMacroNoArguments) {
67 CaptureStderr();
68 INFO("Hello world.");
69 std::string log = GetCapturedStderr();
70 EXPECT_THAT(log, StartsWith("I"));
71 EXPECT_THAT(log, EndsWith("] Hello world.\n"));
72 }
73
TEST(Logging,INFOMacroWithArguments)74 TEST(Logging, INFOMacroWithArguments) {
75 CaptureStderr();
76 INFO("hello %s %d", "world", 1);
77 std::string log = GetCapturedStderr();
78 EXPECT_THAT(log, StartsWith("I"));
79 EXPECT_THAT(log, EndsWith("] hello world 1\n"));
80 }
81
TEST(Logging,FormatsPrefixCorrectly)82 TEST(Logging, FormatsPrefixCorrectly) {
83 CaptureStderr();
84 INFO("foo");
85 std::string log = GetCapturedStderr();
86 EXPECT_THAT(
87 log, MatchesStdRegex(
88 R"re(I\d{4} \d{2}:\d{2}:\d{2}\.\d{6} +\w+ logging_unittest.cpp:\d+\] foo\n)re"));
89 }
90
TEST(Logging,OutputsTimestamp)91 TEST(Logging, OutputsTimestamp) {
92 CaptureStdout();
93 OutputLog(stdout, 'I', "", 0, defaultTimestamp(), "");
94 std::string log = GetCapturedStdout();
95 EXPECT_THAT(log, StartsWith("I0913 12:26:40.123456"));
96 }
97
98 #if defined(_WIN32)
TEST(Logging,FileHasBasenameOnlyWithBackwardsSlashes)99 TEST(Logging, FileHasBasenameOnlyWithBackwardsSlashes) {
100 CaptureStdout();
101 OutputLog(stdout, ' ', R"(c:\foo\bar\file_name)", 123, 0, "");
102 std::string log = GetCapturedStdout();
103 EXPECT_THAT(log, HasSubstr(" file_name:123"));
104 EXPECT_THAT(log, Not(HasSubstr("bar")));
105 }
106 #endif
107
TEST(Logging,FileHasBasenameOnlyWithForwardSlashes)108 TEST(Logging, FileHasBasenameOnlyWithForwardSlashes) {
109 CaptureStdout();
110 OutputLog(stdout, ' ', "/foo/bar/file_name", 123, 0, "");
111 std::string log = GetCapturedStdout();
112 EXPECT_THAT(log, HasSubstr(" file_name:123"));
113 EXPECT_THAT(log, Not(HasSubstr("bar")));
114 }
115
TEST(Logging,OutputsDifferentThreadIdsOnDifferentThreads)116 TEST(Logging, OutputsDifferentThreadIdsOnDifferentThreads) {
117 CaptureStderr();
118 INFO("hello");
119 std::string log1 = GetCapturedStderr();
120
121 CaptureStderr();
122 std::thread([]() { INFO("from thread"); }).join();
123 std::string log2 = GetCapturedStderr();
124
125 std::string tid1 = log1.substr(21, 9);
126 std::string tid2 = log2.substr(21, 9);
127 EXPECT_THAT(tid1, MatchesStdRegex(R"( +\w+ )"));
128 EXPECT_THAT(tid2, MatchesStdRegex(R"( +\w+ )"));
129 EXPECT_NE(tid1, tid2);
130 }
131
132 } // namespace
133