1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <log/log.h>
18 #include <private/android_logger.h>
19
20 #include <stdlib.h>
21 #include <unistd.h>
22
23 #include <regex>
24 #include <string>
25
26 #include <android-base/logging.h>
27 #include <android-base/macros.h>
28 #include <android-base/stringprintf.h>
29 #include <android-base/test_utils.h>
30 #include <gtest/gtest.h>
31
32 using android::base::InitLogging;
33 using android::base::StderrLogger;
34 using android::base::StringPrintf;
35
MakeLogPattern(int priority,const char * tag,const char * message)36 static std::string MakeLogPattern(int priority, const char* tag, const char* message) {
37 static const char log_characters[] = "XXVDIWEF";
38 static_assert(arraysize(log_characters) - 1 == ANDROID_LOG_SILENT,
39 "Mismatch in size of log_characters and values in android_LogPriority");
40 priority = priority > ANDROID_LOG_SILENT ? ANDROID_LOG_FATAL : priority;
41 char log_char = log_characters[priority];
42
43 return StringPrintf("%s %c \\d+-\\d+ \\d+:\\d+:\\d+ \\s*\\d+ \\s*\\d+ %s", tag, log_char,
44 message);
45 }
46
CheckMessage(bool expected,const std::string & output,int priority,const char * tag,const char * message)47 static void CheckMessage(bool expected, const std::string& output, int priority, const char* tag,
48 const char* message) {
49 std::regex message_regex(MakeLogPattern(priority, tag, message));
50 EXPECT_EQ(expected, std::regex_search(output, message_regex)) << message;
51 }
52
GenerateLogContent()53 static void GenerateLogContent() {
54 __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_VERBOSE, "tag", "verbose main");
55 __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO, "tag", "info main");
56 __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_ERROR, "tag", "error main");
57
58 __android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, "tag", "verbose radio");
59 __android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO, "tag", "info radio");
60 __android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_ERROR, "tag", "error radio");
61
62 __android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, "tag", "verbose system");
63 __android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, "tag", "info system");
64 __android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_ERROR, "tag", "error system");
65
66 __android_log_buf_print(LOG_ID_CRASH, ANDROID_LOG_VERBOSE, "tag", "verbose crash");
67 __android_log_buf_print(LOG_ID_CRASH, ANDROID_LOG_INFO, "tag", "info crash");
68 __android_log_buf_print(LOG_ID_CRASH, ANDROID_LOG_ERROR, "tag", "error crash");
69 }
70
GetPidString()71 std::string GetPidString() {
72 int pid = getpid();
73 return StringPrintf("%5d", pid);
74 }
75
TEST(liblog,default_write)76 TEST(liblog, default_write) {
77 CapturedStderr captured_stderr;
78 InitLogging(nullptr, StderrLogger);
79
80 GenerateLogContent();
81
82 CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose main");
83 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info main");
84 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error main");
85
86 CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose radio");
87 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info radio");
88 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error radio");
89
90 CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose system");
91 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info system");
92 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error system");
93
94 CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose crash");
95 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info crash");
96 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error crash");
97 }
98
TEST(liblog,verbose_write)99 TEST(liblog, verbose_write) {
100 setenv("ANDROID_LOG_TAGS", "*:v", true);
101 CapturedStderr captured_stderr;
102 InitLogging(nullptr, StderrLogger);
103
104 GenerateLogContent();
105
106 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose main");
107 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info main");
108 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error main");
109
110 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose radio");
111 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info radio");
112 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error radio");
113
114 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose system");
115 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info system");
116 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error system");
117
118 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose crash");
119 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info crash");
120 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error crash");
121 }
122
TEST(liblog,error_write)123 TEST(liblog, error_write) {
124 setenv("ANDROID_LOG_TAGS", "*:e", true);
125 CapturedStderr captured_stderr;
126 InitLogging(nullptr, StderrLogger);
127
128 GenerateLogContent();
129
130 CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose main");
131 CheckMessage(false, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info main");
132 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error main");
133
134 CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose radio");
135 CheckMessage(false, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info radio");
136 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error radio");
137
138 CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose system");
139 CheckMessage(false, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info system");
140 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error system");
141
142 CheckMessage(false, captured_stderr.str(), ANDROID_LOG_VERBOSE, "tag", "verbose crash");
143 CheckMessage(false, captured_stderr.str(), ANDROID_LOG_INFO, "tag", "info crash");
144 CheckMessage(true, captured_stderr.str(), ANDROID_LOG_ERROR, "tag", "error crash");
145 }
146
TEST(liblog,kernel_no_write)147 TEST(liblog, kernel_no_write) {
148 CapturedStderr captured_stderr;
149 InitLogging(nullptr, StderrLogger);
150 __android_log_buf_print(LOG_ID_KERNEL, ANDROID_LOG_ERROR, "tag", "kernel error");
151 EXPECT_EQ("", captured_stderr.str());
152 }
153
TEST(liblog,binary_no_write)154 TEST(liblog, binary_no_write) {
155 CapturedStderr captured_stderr;
156 InitLogging(nullptr, StderrLogger);
157 __android_log_buf_print(LOG_ID_EVENTS, ANDROID_LOG_ERROR, "tag", "error events");
158 __android_log_buf_print(LOG_ID_STATS, ANDROID_LOG_ERROR, "tag", "error stats");
159 __android_log_buf_print(LOG_ID_SECURITY, ANDROID_LOG_ERROR, "tag", "error security");
160
161 __android_log_bswrite(0x12, "events");
162 __android_log_stats_bwrite(0x34, "stats", strlen("stats"));
163 __android_log_security_bswrite(0x56, "security");
164
165 EXPECT_EQ("", captured_stderr.str());
166 }
167