1 /*
2  * Copyright (C) 2020 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 #define LOG_TAG "global_state_test_tag"
18 
19 #include <android-base/file.h>
20 #include <android-base/logging.h>
21 #include <android-base/properties.h>
22 #include <android/log.h>
23 
24 #include <gtest/gtest.h>
25 
TEST(liblog_global_state,libbase_logs_with_libbase_SetLogger)26 TEST(liblog_global_state, libbase_logs_with_libbase_SetLogger) {
27   using namespace android::base;
28   bool message_seen = false;
29   LogSeverity expected_severity = WARNING;
30   std::string expected_file = Basename(__FILE__);
31   unsigned int expected_line;
32   std::string expected_message = "libbase test message";
33 
34   auto LoggerFunction = [&](LogId log_id, LogSeverity severity, const char* tag, const char* file,
35                             unsigned int line, const char* message) {
36     message_seen = true;
37     EXPECT_EQ(DEFAULT, log_id);
38     EXPECT_EQ(expected_severity, severity);
39     EXPECT_STREQ(LOG_TAG, tag);
40     EXPECT_EQ(expected_file, file);
41     EXPECT_EQ(expected_line, line);
42     EXPECT_EQ(expected_message, message);
43   };
44 
45   SetLogger(LoggerFunction);
46 
47   expected_line = __LINE__ + 1;
48   LOG(expected_severity) << expected_message;
49   EXPECT_TRUE(message_seen);
50 }
51 
TEST(liblog_global_state,libbase_logs_with_liblog_set_logger)52 TEST(liblog_global_state, libbase_logs_with_liblog_set_logger) {
53   using namespace android::base;
54   // These must be static since they're used by the liblog logger function, which only accepts
55   // lambdas without captures.  The items used by the libbase logger are explicitly not static, to
56   // ensure that lambdas with captures do work there.
57   static bool message_seen = false;
58   static std::string expected_file = Basename(__FILE__);
59   static unsigned int expected_line;
60   static std::string expected_message = "libbase test message";
61 
62   auto liblog_logger_function = [](const struct __android_log_message* log_message) {
63     message_seen = true;
64     EXPECT_EQ(sizeof(__android_log_message), log_message->struct_size);
65     EXPECT_EQ(LOG_ID_DEFAULT, log_message->buffer_id);
66     EXPECT_EQ(ANDROID_LOG_WARN, log_message->priority);
67     EXPECT_STREQ(LOG_TAG, log_message->tag);
68     EXPECT_EQ(expected_file, log_message->file);
69     EXPECT_EQ(expected_line, log_message->line);
70     EXPECT_EQ(expected_message, log_message->message);
71   };
72 
73   __android_log_set_logger(liblog_logger_function);
74 
75   expected_line = __LINE__ + 1;
76   LOG(WARNING) << expected_message;
77   EXPECT_TRUE(message_seen);
78 }
79 
TEST(liblog_global_state,liblog_logs_with_libbase_SetLogger)80 TEST(liblog_global_state, liblog_logs_with_libbase_SetLogger) {
81   using namespace android::base;
82   bool message_seen = false;
83   std::string expected_message = "libbase test message";
84 
85   auto LoggerFunction = [&](LogId log_id, LogSeverity severity, const char* tag, const char* file,
86                             unsigned int line, const char* message) {
87     message_seen = true;
88     EXPECT_EQ(MAIN, log_id);
89     EXPECT_EQ(WARNING, severity);
90     EXPECT_STREQ(LOG_TAG, tag);
91     EXPECT_EQ(nullptr, file);
92     EXPECT_EQ(0U, line);
93     EXPECT_EQ(expected_message, message);
94   };
95 
96   SetLogger(LoggerFunction);
97 
98   __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_WARN, LOG_TAG, expected_message.c_str());
99   EXPECT_TRUE(message_seen);
100   message_seen = false;
101 }
102 
TEST(liblog_global_state,liblog_logs_with_liblog_set_logger)103 TEST(liblog_global_state, liblog_logs_with_liblog_set_logger) {
104   using namespace android::base;
105   // These must be static since they're used by the liblog logger function, which only accepts
106   // lambdas without captures.  The items used by the libbase logger are explicitly not static, to
107   // ensure that lambdas with captures do work there.
108   static bool message_seen = false;
109   static int expected_buffer_id = LOG_ID_MAIN;
110   static int expected_priority = ANDROID_LOG_WARN;
111   static std::string expected_message = "libbase test message";
112 
113   auto liblog_logger_function = [](const struct __android_log_message* log_message) {
114     message_seen = true;
115     EXPECT_EQ(sizeof(__android_log_message), log_message->struct_size);
116     EXPECT_EQ(expected_buffer_id, log_message->buffer_id);
117     EXPECT_EQ(expected_priority, log_message->priority);
118     EXPECT_STREQ(LOG_TAG, log_message->tag);
119     EXPECT_STREQ(nullptr, log_message->file);
120     EXPECT_EQ(0U, log_message->line);
121     EXPECT_EQ(expected_message, log_message->message);
122   };
123 
124   __android_log_set_logger(liblog_logger_function);
125 
126   __android_log_buf_write(expected_buffer_id, expected_priority, LOG_TAG, expected_message.c_str());
127   EXPECT_TRUE(message_seen);
128 }
129 
TEST(liblog_global_state,SetAborter_with_liblog)130 TEST(liblog_global_state, SetAborter_with_liblog) {
131   using namespace android::base;
132 
133   std::string expected_message = "libbase test message";
134   static bool message_seen = false;
135   auto aborter_function = [&](const char* message) {
136     message_seen = true;
137     EXPECT_EQ(expected_message, message);
138   };
139 
140   SetAborter(aborter_function);
141   LOG(FATAL) << expected_message;
142   EXPECT_TRUE(message_seen);
143   message_seen = false;
144 
145   static std::string expected_message_static = "libbase test message";
146   auto liblog_aborter_function = [](const char* message) {
147     message_seen = true;
148     EXPECT_EQ(expected_message_static, message);
149   };
150   __android_log_set_aborter(liblog_aborter_function);
151   LOG(FATAL) << expected_message_static;
152   EXPECT_TRUE(message_seen);
153   message_seen = false;
154 }
155 
UniqueLogTag()156 static std::string UniqueLogTag() {
157   std::string tag = LOG_TAG;
158   tag += "-" + std::to_string(getpid());
159   return tag;
160 }
161 
TEST(liblog_global_state,is_loggable_both_default)162 TEST(liblog_global_state, is_loggable_both_default) {
163   auto tag = UniqueLogTag();
164   EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
165   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
166   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
167 }
168 
TEST(liblog_global_state,is_loggable_minimum_log_priority_only)169 TEST(liblog_global_state, is_loggable_minimum_log_priority_only) {
170   auto tag = UniqueLogTag();
171   EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
172   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
173   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
174 
175   EXPECT_EQ(ANDROID_LOG_DEFAULT, __android_log_set_minimum_priority(ANDROID_LOG_DEBUG));
176   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
177   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
178   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
179 
180   EXPECT_EQ(ANDROID_LOG_DEBUG, __android_log_set_minimum_priority(ANDROID_LOG_WARN));
181   EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
182   EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
183   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
184 
185   EXPECT_EQ(android::base::WARNING, android::base::SetMinimumLogSeverity(android::base::DEBUG));
186   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
187   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
188   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
189 
190   EXPECT_EQ(android::base::DEBUG, android::base::SetMinimumLogSeverity(android::base::WARNING));
191   EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
192   EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
193   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
194 }
195 
TEST(liblog_global_state,is_loggable_tag_log_priority_only)196 TEST(liblog_global_state, is_loggable_tag_log_priority_only) {
197 #ifdef __ANDROID__
198   auto tag = UniqueLogTag();
199   EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
200   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
201   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
202 
203   auto log_tag_property = std::string("log.tag.") + tag;
204   ASSERT_TRUE(android::base::SetProperty(log_tag_property, "d"));
205   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
206   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
207   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
208 
209   ASSERT_TRUE(android::base::SetProperty(log_tag_property, "w"));
210   EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
211   EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
212   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
213 
214   ASSERT_TRUE(android::base::SetProperty(log_tag_property, ""));
215 #else
216   GTEST_SKIP() << "No log tag properties on host";
217 #endif
218 }
219 
TEST(liblog_global_state,is_loggable_both_set)220 TEST(liblog_global_state, is_loggable_both_set) {
221 #ifdef __ANDROID__
222   auto tag = UniqueLogTag();
223   EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
224   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
225   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
226 
227   // When both a tag and a minimum priority are set, we use the lower value of the two.
228 
229   // tag = warning, minimum_priority = debug, expect 'debug'
230   auto log_tag_property = std::string("log.tag.") + tag;
231   ASSERT_TRUE(android::base::SetProperty(log_tag_property, "w"));
232   EXPECT_EQ(ANDROID_LOG_DEFAULT, __android_log_set_minimum_priority(ANDROID_LOG_DEBUG));
233   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
234   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
235   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
236 
237   // tag = warning, minimum_priority = warning, expect 'warning'
238   EXPECT_EQ(ANDROID_LOG_DEBUG, __android_log_set_minimum_priority(ANDROID_LOG_WARN));
239   EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
240   EXPECT_EQ(0, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
241   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
242 
243   // tag = debug, minimum_priority = warning, expect 'debug'
244   ASSERT_TRUE(android::base::SetProperty(log_tag_property, "d"));
245   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
246   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
247   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
248 
249   // tag = debug, minimum_priority = debug, expect 'debug'
250   EXPECT_EQ(ANDROID_LOG_WARN, __android_log_set_minimum_priority(ANDROID_LOG_DEBUG));
251   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_DEBUG, tag.c_str(), ANDROID_LOG_INFO));
252   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_INFO, tag.c_str(), ANDROID_LOG_INFO));
253   EXPECT_EQ(1, __android_log_is_loggable(ANDROID_LOG_WARN, tag.c_str(), ANDROID_LOG_INFO));
254 
255   ASSERT_TRUE(android::base::SetProperty(log_tag_property, ""));
256 #else
257   GTEST_SKIP() << "No log tag properties on host";
258 #endif
259 }
260