1*598139dcSAndroid Build Coastguard Worker /*
2*598139dcSAndroid Build Coastguard Worker * Copyright (C) 2014 The Android Open Source Project
3*598139dcSAndroid Build Coastguard Worker *
4*598139dcSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*598139dcSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*598139dcSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*598139dcSAndroid Build Coastguard Worker *
8*598139dcSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*598139dcSAndroid Build Coastguard Worker *
10*598139dcSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*598139dcSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*598139dcSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*598139dcSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*598139dcSAndroid Build Coastguard Worker * limitations under the License.
15*598139dcSAndroid Build Coastguard Worker */
16*598139dcSAndroid Build Coastguard Worker
17*598139dcSAndroid Build Coastguard Worker #include <ctype.h>
18*598139dcSAndroid Build Coastguard Worker #include <errno.h>
19*598139dcSAndroid Build Coastguard Worker #include <fcntl.h>
20*598139dcSAndroid Build Coastguard Worker #include <inttypes.h>
21*598139dcSAndroid Build Coastguard Worker #include <poll.h>
22*598139dcSAndroid Build Coastguard Worker #include <signal.h>
23*598139dcSAndroid Build Coastguard Worker #include <stdio.h>
24*598139dcSAndroid Build Coastguard Worker #include <string.h>
25*598139dcSAndroid Build Coastguard Worker #include <sys/stat.h>
26*598139dcSAndroid Build Coastguard Worker #include <sys/types.h>
27*598139dcSAndroid Build Coastguard Worker #include <unistd.h>
28*598139dcSAndroid Build Coastguard Worker
29*598139dcSAndroid Build Coastguard Worker #include <string>
30*598139dcSAndroid Build Coastguard Worker
31*598139dcSAndroid Build Coastguard Worker #include <android-base/file.h>
32*598139dcSAndroid Build Coastguard Worker #include <android-base/macros.h>
33*598139dcSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
34*598139dcSAndroid Build Coastguard Worker #include <android-base/unique_fd.h>
35*598139dcSAndroid Build Coastguard Worker #include <cutils/sockets.h>
36*598139dcSAndroid Build Coastguard Worker #include <gtest/gtest-death-test.h>
37*598139dcSAndroid Build Coastguard Worker #include <gtest/gtest.h>
38*598139dcSAndroid Build Coastguard Worker #include <log/log_read.h>
39*598139dcSAndroid Build Coastguard Worker #include <private/android_filesystem_config.h>
40*598139dcSAndroid Build Coastguard Worker #include <private/android_logger.h>
41*598139dcSAndroid Build Coastguard Worker #ifdef __ANDROID__
42*598139dcSAndroid Build Coastguard Worker #include <selinux/selinux.h>
43*598139dcSAndroid Build Coastguard Worker #endif
44*598139dcSAndroid Build Coastguard Worker
45*598139dcSAndroid Build Coastguard Worker #include "LogUtils.h" // For LOGD_SNDTIMEO.
46*598139dcSAndroid Build Coastguard Worker
47*598139dcSAndroid Build Coastguard Worker using android::base::unique_fd;
48*598139dcSAndroid Build Coastguard Worker
49*598139dcSAndroid Build Coastguard Worker #ifdef __ANDROID__
write_command(int sock,const char * command)50*598139dcSAndroid Build Coastguard Worker static bool write_command(int sock, const char* command) {
51*598139dcSAndroid Build Coastguard Worker // The command sent to logd must include the '\0' character at the end.
52*598139dcSAndroid Build Coastguard Worker size_t command_length = strlen(command) + 1;
53*598139dcSAndroid Build Coastguard Worker ssize_t bytes_written = TEMP_FAILURE_RETRY(write(sock, command, command_length));
54*598139dcSAndroid Build Coastguard Worker if (bytes_written != static_cast<ssize_t>(command_length)) {
55*598139dcSAndroid Build Coastguard Worker if (bytes_written == -1) {
56*598139dcSAndroid Build Coastguard Worker printf("Failed to send '%s' command: %s\n", command, strerror(errno));
57*598139dcSAndroid Build Coastguard Worker } else {
58*598139dcSAndroid Build Coastguard Worker printf("Failed to send '%s' command: bytes written %zd, expected written %zu\n",
59*598139dcSAndroid Build Coastguard Worker command, bytes_written, command_length);
60*598139dcSAndroid Build Coastguard Worker }
61*598139dcSAndroid Build Coastguard Worker return false;
62*598139dcSAndroid Build Coastguard Worker }
63*598139dcSAndroid Build Coastguard Worker return true;
64*598139dcSAndroid Build Coastguard Worker }
65*598139dcSAndroid Build Coastguard Worker
write_command(int sock,const std::string & command)66*598139dcSAndroid Build Coastguard Worker static bool write_command(int sock, const std::string& command) {
67*598139dcSAndroid Build Coastguard Worker return write_command(sock, command.c_str());
68*598139dcSAndroid Build Coastguard Worker }
69*598139dcSAndroid Build Coastguard Worker
send_to_control(const char * command,std::string & result)70*598139dcSAndroid Build Coastguard Worker static void send_to_control(const char* command, std::string& result) {
71*598139dcSAndroid Build Coastguard Worker unique_fd sock(socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM));
72*598139dcSAndroid Build Coastguard Worker ASSERT_LT(0, sock) << "Failed to open logd: " << strerror(errno);
73*598139dcSAndroid Build Coastguard Worker ASSERT_TRUE(write_command(sock, command));
74*598139dcSAndroid Build Coastguard Worker result.clear();
75*598139dcSAndroid Build Coastguard Worker while (true) {
76*598139dcSAndroid Build Coastguard Worker struct pollfd p = {.fd = sock, .events = POLLIN, .revents = 0};
77*598139dcSAndroid Build Coastguard Worker // Timeout after 20 seconds.
78*598139dcSAndroid Build Coastguard Worker int ret = TEMP_FAILURE_RETRY(poll(&p, 1, 20000));
79*598139dcSAndroid Build Coastguard Worker ASSERT_TRUE(ret != -1) << "Poll call failed for command '" << command
80*598139dcSAndroid Build Coastguard Worker << "': " << strerror(errno);
81*598139dcSAndroid Build Coastguard Worker ASSERT_NE(0, ret) << "Timeout sending command '" << command << "'";
82*598139dcSAndroid Build Coastguard Worker ASSERT_TRUE(p.revents & POLLIN)
83*598139dcSAndroid Build Coastguard Worker << "Command socket not readable for command '" << command << "'";
84*598139dcSAndroid Build Coastguard Worker
85*598139dcSAndroid Build Coastguard Worker char buffer[256];
86*598139dcSAndroid Build Coastguard Worker ssize_t bytes_read = TEMP_FAILURE_RETRY(read(sock, buffer, sizeof(buffer)));
87*598139dcSAndroid Build Coastguard Worker ASSERT_GE(bytes_read, 0) << "Read failed for command '" << command
88*598139dcSAndroid Build Coastguard Worker << "': " << strerror(errno);
89*598139dcSAndroid Build Coastguard Worker result += std::string(buffer, bytes_read);
90*598139dcSAndroid Build Coastguard Worker if (bytes_read == 0 || static_cast<size_t>(bytes_read) < sizeof(buffer)) {
91*598139dcSAndroid Build Coastguard Worker return;
92*598139dcSAndroid Build Coastguard Worker }
93*598139dcSAndroid Build Coastguard Worker }
94*598139dcSAndroid Build Coastguard Worker }
95*598139dcSAndroid Build Coastguard Worker #endif
96*598139dcSAndroid Build Coastguard Worker
97*598139dcSAndroid Build Coastguard Worker #ifdef LOGD_ENABLE_FLAKY_TESTS
TEST(logd,statistics)98*598139dcSAndroid Build Coastguard Worker TEST(logd, statistics) {
99*598139dcSAndroid Build Coastguard Worker #ifdef __ANDROID__
100*598139dcSAndroid Build Coastguard Worker // Drop cache so that any access problems can be discovered.
101*598139dcSAndroid Build Coastguard Worker if (!android::base::WriteStringToFile("3\n", "/proc/sys/vm/drop_caches")) {
102*598139dcSAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "Could not open trigger dropping inode cache";
103*598139dcSAndroid Build Coastguard Worker }
104*598139dcSAndroid Build Coastguard Worker
105*598139dcSAndroid Build Coastguard Worker std::string result;
106*598139dcSAndroid Build Coastguard Worker send_to_control("getStatistics 0 1 2 3 4", result);
107*598139dcSAndroid Build Coastguard Worker ASSERT_FALSE(result.empty());
108*598139dcSAndroid Build Coastguard Worker
109*598139dcSAndroid Build Coastguard Worker EXPECT_NE(std::string::npos, result.find("\nChattiest UIDs in main "));
110*598139dcSAndroid Build Coastguard Worker
111*598139dcSAndroid Build Coastguard Worker EXPECT_NE(std::string::npos, result.find("\nChattiest UIDs in radio "));
112*598139dcSAndroid Build Coastguard Worker
113*598139dcSAndroid Build Coastguard Worker EXPECT_NE(std::string::npos, result.find("\nChattiest UIDs in system "));
114*598139dcSAndroid Build Coastguard Worker
115*598139dcSAndroid Build Coastguard Worker EXPECT_NE(std::string::npos, result.find("\nChattiest UIDs in events "));
116*598139dcSAndroid Build Coastguard Worker
117*598139dcSAndroid Build Coastguard Worker // Look for any u0_a or u0_a[0-9]+ values. If found, it indicates the
118*598139dcSAndroid Build Coastguard Worker // libpackagelistparser failed.
119*598139dcSAndroid Build Coastguard Worker static const char getpwuid_prefix[] = " u0_a";
120*598139dcSAndroid Build Coastguard Worker size_t pos = 0;
121*598139dcSAndroid Build Coastguard Worker while ((pos = result.find(getpwuid_prefix, pos)) != std::string::npos) {
122*598139dcSAndroid Build Coastguard Worker // Check to see if the value following u0_a is all digits, or empty.
123*598139dcSAndroid Build Coastguard Worker size_t uid_name_pos = pos + strlen(getpwuid_prefix);
124*598139dcSAndroid Build Coastguard Worker size_t i = 0;
125*598139dcSAndroid Build Coastguard Worker while (isdigit(result[uid_name_pos + i])) {
126*598139dcSAndroid Build Coastguard Worker i++;
127*598139dcSAndroid Build Coastguard Worker }
128*598139dcSAndroid Build Coastguard Worker ASSERT_FALSE(isspace(result[uid_name_pos + i]))
129*598139dcSAndroid Build Coastguard Worker << "libpackagelistparser failed to pick up " << result.substr(uid_name_pos, i);
130*598139dcSAndroid Build Coastguard Worker
131*598139dcSAndroid Build Coastguard Worker pos = uid_name_pos + i;
132*598139dcSAndroid Build Coastguard Worker }
133*598139dcSAndroid Build Coastguard Worker #else
134*598139dcSAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "This test does nothing.\n";
135*598139dcSAndroid Build Coastguard Worker #endif
136*598139dcSAndroid Build Coastguard Worker }
137*598139dcSAndroid Build Coastguard Worker #endif
138*598139dcSAndroid Build Coastguard Worker
139*598139dcSAndroid Build Coastguard Worker #ifdef __ANDROID__
caught_signal(int)140*598139dcSAndroid Build Coastguard Worker static void caught_signal(int /* signum */) {
141*598139dcSAndroid Build Coastguard Worker }
142*598139dcSAndroid Build Coastguard Worker
dump_log_msg(const char * prefix,log_msg * msg,int lid)143*598139dcSAndroid Build Coastguard Worker static void dump_log_msg(const char* prefix, log_msg* msg, int lid) {
144*598139dcSAndroid Build Coastguard Worker std::cout << std::flush;
145*598139dcSAndroid Build Coastguard Worker std::cerr << std::flush;
146*598139dcSAndroid Build Coastguard Worker fflush(stdout);
147*598139dcSAndroid Build Coastguard Worker fflush(stderr);
148*598139dcSAndroid Build Coastguard Worker EXPECT_GE(msg->entry.hdr_size, sizeof(logger_entry));
149*598139dcSAndroid Build Coastguard Worker
150*598139dcSAndroid Build Coastguard Worker fprintf(stderr, "%s: [%u] ", prefix, msg->len());
151*598139dcSAndroid Build Coastguard Worker fprintf(stderr, "hdr_size=%u ", msg->entry.hdr_size);
152*598139dcSAndroid Build Coastguard Worker fprintf(stderr, "pid=%u tid=%u %u.%09u ", msg->entry.pid, msg->entry.tid, msg->entry.sec,
153*598139dcSAndroid Build Coastguard Worker msg->entry.nsec);
154*598139dcSAndroid Build Coastguard Worker lid = msg->entry.lid;
155*598139dcSAndroid Build Coastguard Worker
156*598139dcSAndroid Build Coastguard Worker switch (lid) {
157*598139dcSAndroid Build Coastguard Worker case 0:
158*598139dcSAndroid Build Coastguard Worker fprintf(stderr, "lid=main ");
159*598139dcSAndroid Build Coastguard Worker break;
160*598139dcSAndroid Build Coastguard Worker case 1:
161*598139dcSAndroid Build Coastguard Worker fprintf(stderr, "lid=radio ");
162*598139dcSAndroid Build Coastguard Worker break;
163*598139dcSAndroid Build Coastguard Worker case 2:
164*598139dcSAndroid Build Coastguard Worker fprintf(stderr, "lid=events ");
165*598139dcSAndroid Build Coastguard Worker break;
166*598139dcSAndroid Build Coastguard Worker case 3:
167*598139dcSAndroid Build Coastguard Worker fprintf(stderr, "lid=system ");
168*598139dcSAndroid Build Coastguard Worker break;
169*598139dcSAndroid Build Coastguard Worker case 4:
170*598139dcSAndroid Build Coastguard Worker fprintf(stderr, "lid=crash ");
171*598139dcSAndroid Build Coastguard Worker break;
172*598139dcSAndroid Build Coastguard Worker case 5:
173*598139dcSAndroid Build Coastguard Worker fprintf(stderr, "lid=security ");
174*598139dcSAndroid Build Coastguard Worker break;
175*598139dcSAndroid Build Coastguard Worker case 6:
176*598139dcSAndroid Build Coastguard Worker fprintf(stderr, "lid=kernel ");
177*598139dcSAndroid Build Coastguard Worker break;
178*598139dcSAndroid Build Coastguard Worker default:
179*598139dcSAndroid Build Coastguard Worker if (lid >= 0) {
180*598139dcSAndroid Build Coastguard Worker fprintf(stderr, "lid=%d ", lid);
181*598139dcSAndroid Build Coastguard Worker }
182*598139dcSAndroid Build Coastguard Worker }
183*598139dcSAndroid Build Coastguard Worker
184*598139dcSAndroid Build Coastguard Worker unsigned int len = msg->entry.len;
185*598139dcSAndroid Build Coastguard Worker fprintf(stderr, "msg[%u]={", len);
186*598139dcSAndroid Build Coastguard Worker unsigned char* cp = reinterpret_cast<unsigned char*>(msg->msg());
187*598139dcSAndroid Build Coastguard Worker if (!cp) {
188*598139dcSAndroid Build Coastguard Worker static const unsigned char garbage[] = "<INVALID>";
189*598139dcSAndroid Build Coastguard Worker cp = const_cast<unsigned char*>(garbage);
190*598139dcSAndroid Build Coastguard Worker len = strlen(reinterpret_cast<const char*>(garbage));
191*598139dcSAndroid Build Coastguard Worker }
192*598139dcSAndroid Build Coastguard Worker while (len) {
193*598139dcSAndroid Build Coastguard Worker unsigned char* p = cp;
194*598139dcSAndroid Build Coastguard Worker while (*p && (((' ' <= *p) && (*p < 0x7F)) || (*p == '\n'))) {
195*598139dcSAndroid Build Coastguard Worker ++p;
196*598139dcSAndroid Build Coastguard Worker }
197*598139dcSAndroid Build Coastguard Worker if (((p - cp) > 3) && !*p && ((unsigned int)(p - cp) < len)) {
198*598139dcSAndroid Build Coastguard Worker fprintf(stderr, "\"");
199*598139dcSAndroid Build Coastguard Worker while (*cp) {
200*598139dcSAndroid Build Coastguard Worker if (*cp != '\n') {
201*598139dcSAndroid Build Coastguard Worker fprintf(stderr, "%c", *cp);
202*598139dcSAndroid Build Coastguard Worker } else {
203*598139dcSAndroid Build Coastguard Worker fprintf(stderr, "\\n");
204*598139dcSAndroid Build Coastguard Worker }
205*598139dcSAndroid Build Coastguard Worker ++cp;
206*598139dcSAndroid Build Coastguard Worker --len;
207*598139dcSAndroid Build Coastguard Worker }
208*598139dcSAndroid Build Coastguard Worker fprintf(stderr, "\"");
209*598139dcSAndroid Build Coastguard Worker } else {
210*598139dcSAndroid Build Coastguard Worker fprintf(stderr, "%02x", *cp);
211*598139dcSAndroid Build Coastguard Worker }
212*598139dcSAndroid Build Coastguard Worker ++cp;
213*598139dcSAndroid Build Coastguard Worker if (--len) {
214*598139dcSAndroid Build Coastguard Worker fprintf(stderr, ", ");
215*598139dcSAndroid Build Coastguard Worker }
216*598139dcSAndroid Build Coastguard Worker }
217*598139dcSAndroid Build Coastguard Worker fprintf(stderr, "}\n");
218*598139dcSAndroid Build Coastguard Worker fflush(stderr);
219*598139dcSAndroid Build Coastguard Worker }
220*598139dcSAndroid Build Coastguard Worker #endif
221*598139dcSAndroid Build Coastguard Worker
222*598139dcSAndroid Build Coastguard Worker // b/26447386 confirm fixed
timeout_negative(const char * command)223*598139dcSAndroid Build Coastguard Worker void timeout_negative([[maybe_unused]] const char* command) {
224*598139dcSAndroid Build Coastguard Worker #ifdef __ANDROID__
225*598139dcSAndroid Build Coastguard Worker log_msg msg_wrap, msg_timeout;
226*598139dcSAndroid Build Coastguard Worker bool content_wrap = false, content_timeout = false, written = false;
227*598139dcSAndroid Build Coastguard Worker unsigned int alarm_wrap = 0, alarm_timeout = 0;
228*598139dcSAndroid Build Coastguard Worker // A few tries to get it right just in case wrap kicks in due to
229*598139dcSAndroid Build Coastguard Worker // content providers being active during the test.
230*598139dcSAndroid Build Coastguard Worker int i = 3;
231*598139dcSAndroid Build Coastguard Worker
232*598139dcSAndroid Build Coastguard Worker while (--i) {
233*598139dcSAndroid Build Coastguard Worker unique_fd fd(
234*598139dcSAndroid Build Coastguard Worker socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET));
235*598139dcSAndroid Build Coastguard Worker ASSERT_LT(0, fd) << "Failed to open logdr: " << strerror(errno);
236*598139dcSAndroid Build Coastguard Worker
237*598139dcSAndroid Build Coastguard Worker struct sigaction ignore = {.sa_handler = caught_signal};
238*598139dcSAndroid Build Coastguard Worker sigemptyset(&ignore.sa_mask);
239*598139dcSAndroid Build Coastguard Worker struct sigaction old_sigaction;
240*598139dcSAndroid Build Coastguard Worker sigaction(SIGALRM, &ignore, &old_sigaction);
241*598139dcSAndroid Build Coastguard Worker unsigned int old_alarm = alarm(3);
242*598139dcSAndroid Build Coastguard Worker
243*598139dcSAndroid Build Coastguard Worker written = write_command(fd, command);
244*598139dcSAndroid Build Coastguard Worker if (!written) {
245*598139dcSAndroid Build Coastguard Worker alarm(old_alarm);
246*598139dcSAndroid Build Coastguard Worker sigaction(SIGALRM, &old_sigaction, nullptr);
247*598139dcSAndroid Build Coastguard Worker continue;
248*598139dcSAndroid Build Coastguard Worker }
249*598139dcSAndroid Build Coastguard Worker
250*598139dcSAndroid Build Coastguard Worker // alarm triggers at 50% of the --wrap time out
251*598139dcSAndroid Build Coastguard Worker content_wrap = TEMP_FAILURE_RETRY(recv(fd, msg_wrap.buf, sizeof(msg_wrap), 0)) > 0;
252*598139dcSAndroid Build Coastguard Worker
253*598139dcSAndroid Build Coastguard Worker alarm_wrap = alarm(5);
254*598139dcSAndroid Build Coastguard Worker
255*598139dcSAndroid Build Coastguard Worker // alarm triggers at 133% of the --wrap time out
256*598139dcSAndroid Build Coastguard Worker content_timeout = TEMP_FAILURE_RETRY(recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0)) > 0;
257*598139dcSAndroid Build Coastguard Worker if (!content_timeout) { // make sure we hit dumpAndClose
258*598139dcSAndroid Build Coastguard Worker content_timeout =
259*598139dcSAndroid Build Coastguard Worker TEMP_FAILURE_RETRY(recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0)) > 0;
260*598139dcSAndroid Build Coastguard Worker }
261*598139dcSAndroid Build Coastguard Worker
262*598139dcSAndroid Build Coastguard Worker if (old_alarm > 0) {
263*598139dcSAndroid Build Coastguard Worker unsigned int time_spent = 3 - alarm_wrap;
264*598139dcSAndroid Build Coastguard Worker if (old_alarm > time_spent + 1) {
265*598139dcSAndroid Build Coastguard Worker old_alarm -= time_spent;
266*598139dcSAndroid Build Coastguard Worker } else {
267*598139dcSAndroid Build Coastguard Worker old_alarm = 2;
268*598139dcSAndroid Build Coastguard Worker }
269*598139dcSAndroid Build Coastguard Worker }
270*598139dcSAndroid Build Coastguard Worker alarm_timeout = alarm(old_alarm);
271*598139dcSAndroid Build Coastguard Worker sigaction(SIGALRM, &old_sigaction, nullptr);
272*598139dcSAndroid Build Coastguard Worker
273*598139dcSAndroid Build Coastguard Worker if (content_wrap && alarm_wrap && content_timeout && alarm_timeout) {
274*598139dcSAndroid Build Coastguard Worker break;
275*598139dcSAndroid Build Coastguard Worker }
276*598139dcSAndroid Build Coastguard Worker }
277*598139dcSAndroid Build Coastguard Worker
278*598139dcSAndroid Build Coastguard Worker if (content_wrap) {
279*598139dcSAndroid Build Coastguard Worker dump_log_msg("wrap", &msg_wrap, -1);
280*598139dcSAndroid Build Coastguard Worker }
281*598139dcSAndroid Build Coastguard Worker
282*598139dcSAndroid Build Coastguard Worker if (content_timeout) {
283*598139dcSAndroid Build Coastguard Worker dump_log_msg("timeout", &msg_timeout, -1);
284*598139dcSAndroid Build Coastguard Worker }
285*598139dcSAndroid Build Coastguard Worker
286*598139dcSAndroid Build Coastguard Worker EXPECT_TRUE(written);
287*598139dcSAndroid Build Coastguard Worker EXPECT_TRUE(content_wrap);
288*598139dcSAndroid Build Coastguard Worker EXPECT_NE(0U, alarm_wrap);
289*598139dcSAndroid Build Coastguard Worker EXPECT_TRUE(content_timeout);
290*598139dcSAndroid Build Coastguard Worker EXPECT_NE(0U, alarm_timeout);
291*598139dcSAndroid Build Coastguard Worker #else
292*598139dcSAndroid Build Coastguard Worker command = nullptr;
293*598139dcSAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "This test does nothing.\n";
294*598139dcSAndroid Build Coastguard Worker #endif
295*598139dcSAndroid Build Coastguard Worker }
296*598139dcSAndroid Build Coastguard Worker
TEST(logd,timeout_no_start)297*598139dcSAndroid Build Coastguard Worker TEST(logd, timeout_no_start) {
298*598139dcSAndroid Build Coastguard Worker timeout_negative("dumpAndClose lids=0,1,2,3,4,5 timeout=6");
299*598139dcSAndroid Build Coastguard Worker }
300*598139dcSAndroid Build Coastguard Worker
TEST(logd,timeout_start_epoch)301*598139dcSAndroid Build Coastguard Worker TEST(logd, timeout_start_epoch) {
302*598139dcSAndroid Build Coastguard Worker timeout_negative(
303*598139dcSAndroid Build Coastguard Worker "dumpAndClose lids=0,1,2,3,4,5 timeout=6 start=0.000000000");
304*598139dcSAndroid Build Coastguard Worker }
305*598139dcSAndroid Build Coastguard Worker
306*598139dcSAndroid Build Coastguard Worker #ifdef LOGD_ENABLE_FLAKY_TESTS
307*598139dcSAndroid Build Coastguard Worker // b/26447386 refined behavior
TEST(logd,timeout)308*598139dcSAndroid Build Coastguard Worker TEST(logd, timeout) {
309*598139dcSAndroid Build Coastguard Worker #ifdef __ANDROID__
310*598139dcSAndroid Build Coastguard Worker // b/33962045 This test interferes with other log reader tests that
311*598139dcSAndroid Build Coastguard Worker // follow because of file descriptor socket persistence in the same
312*598139dcSAndroid Build Coastguard Worker // process. So let's fork it to isolate it from giving us pain.
313*598139dcSAndroid Build Coastguard Worker
314*598139dcSAndroid Build Coastguard Worker pid_t pid = fork();
315*598139dcSAndroid Build Coastguard Worker
316*598139dcSAndroid Build Coastguard Worker if (pid) {
317*598139dcSAndroid Build Coastguard Worker siginfo_t info = {};
318*598139dcSAndroid Build Coastguard Worker ASSERT_EQ(0, TEMP_FAILURE_RETRY(waitid(P_PID, pid, &info, WEXITED)));
319*598139dcSAndroid Build Coastguard Worker ASSERT_EQ(0, info.si_status);
320*598139dcSAndroid Build Coastguard Worker return;
321*598139dcSAndroid Build Coastguard Worker }
322*598139dcSAndroid Build Coastguard Worker
323*598139dcSAndroid Build Coastguard Worker log_msg msg_wrap, msg_timeout;
324*598139dcSAndroid Build Coastguard Worker bool content_wrap = false, content_timeout = false, written = false;
325*598139dcSAndroid Build Coastguard Worker unsigned int alarm_wrap = 0, alarm_timeout = 0;
326*598139dcSAndroid Build Coastguard Worker // A few tries to get it right just in case wrap kicks in due to
327*598139dcSAndroid Build Coastguard Worker // content providers being active during the test.
328*598139dcSAndroid Build Coastguard Worker int i = 5;
329*598139dcSAndroid Build Coastguard Worker log_time start(CLOCK_REALTIME);
330*598139dcSAndroid Build Coastguard Worker start.tv_sec -= 30; // reach back a moderate period of time
331*598139dcSAndroid Build Coastguard Worker
332*598139dcSAndroid Build Coastguard Worker while (--i) {
333*598139dcSAndroid Build Coastguard Worker unique_fd fd(
334*598139dcSAndroid Build Coastguard Worker socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET));
335*598139dcSAndroid Build Coastguard Worker ASSERT_LT(0, fd) << "Failed to open logdr: " << strerror(errno);
336*598139dcSAndroid Build Coastguard Worker
337*598139dcSAndroid Build Coastguard Worker std::string ask = android::base::StringPrintf(
338*598139dcSAndroid Build Coastguard Worker "dumpAndClose lids=0,1,2,3,4,5 timeout=6 start=%" PRIu32
339*598139dcSAndroid Build Coastguard Worker ".%09" PRIu32,
340*598139dcSAndroid Build Coastguard Worker start.tv_sec, start.tv_nsec);
341*598139dcSAndroid Build Coastguard Worker
342*598139dcSAndroid Build Coastguard Worker struct sigaction ignore = {.sa_handler = caught_signal};
343*598139dcSAndroid Build Coastguard Worker sigemptyset(&ignore.sa_mask);
344*598139dcSAndroid Build Coastguard Worker struct sigaction old_sigaction;
345*598139dcSAndroid Build Coastguard Worker sigaction(SIGALRM, &ignore, &old_sigaction);
346*598139dcSAndroid Build Coastguard Worker unsigned int old_alarm = alarm(3);
347*598139dcSAndroid Build Coastguard Worker
348*598139dcSAndroid Build Coastguard Worker written = write_command(fd, ask);
349*598139dcSAndroid Build Coastguard Worker if (!written) {
350*598139dcSAndroid Build Coastguard Worker alarm(old_alarm);
351*598139dcSAndroid Build Coastguard Worker sigaction(SIGALRM, &old_sigaction, nullptr);
352*598139dcSAndroid Build Coastguard Worker continue;
353*598139dcSAndroid Build Coastguard Worker }
354*598139dcSAndroid Build Coastguard Worker
355*598139dcSAndroid Build Coastguard Worker // alarm triggers at 50% of the --wrap time out
356*598139dcSAndroid Build Coastguard Worker content_wrap = TEMP_FAILURE_RETRY(recv(fd, msg_wrap.buf, sizeof(msg_wrap), 0)) > 0;
357*598139dcSAndroid Build Coastguard Worker
358*598139dcSAndroid Build Coastguard Worker alarm_wrap = alarm(5);
359*598139dcSAndroid Build Coastguard Worker
360*598139dcSAndroid Build Coastguard Worker // alarm triggers at 133% of the --wrap time out
361*598139dcSAndroid Build Coastguard Worker content_timeout = TEMP_FAILURE_RETRY(recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0)) > 0;
362*598139dcSAndroid Build Coastguard Worker if (!content_timeout) { // make sure we hit dumpAndClose
363*598139dcSAndroid Build Coastguard Worker content_timeout =
364*598139dcSAndroid Build Coastguard Worker TEMP_FAILURE_RETRY(recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0)) > 0;
365*598139dcSAndroid Build Coastguard Worker }
366*598139dcSAndroid Build Coastguard Worker
367*598139dcSAndroid Build Coastguard Worker if (old_alarm > 0) {
368*598139dcSAndroid Build Coastguard Worker unsigned int time_spent = 3 - alarm_wrap;
369*598139dcSAndroid Build Coastguard Worker if (old_alarm > time_spent + 1) {
370*598139dcSAndroid Build Coastguard Worker old_alarm -= time_spent;
371*598139dcSAndroid Build Coastguard Worker } else {
372*598139dcSAndroid Build Coastguard Worker old_alarm = 2;
373*598139dcSAndroid Build Coastguard Worker }
374*598139dcSAndroid Build Coastguard Worker }
375*598139dcSAndroid Build Coastguard Worker alarm_timeout = alarm(old_alarm);
376*598139dcSAndroid Build Coastguard Worker sigaction(SIGALRM, &old_sigaction, nullptr);
377*598139dcSAndroid Build Coastguard Worker
378*598139dcSAndroid Build Coastguard Worker if (!content_wrap && !alarm_wrap && content_timeout && alarm_timeout) {
379*598139dcSAndroid Build Coastguard Worker break;
380*598139dcSAndroid Build Coastguard Worker }
381*598139dcSAndroid Build Coastguard Worker
382*598139dcSAndroid Build Coastguard Worker // modify start time in case content providers are relatively
383*598139dcSAndroid Build Coastguard Worker // active _or_ inactive during the test.
384*598139dcSAndroid Build Coastguard Worker if (content_timeout) {
385*598139dcSAndroid Build Coastguard Worker log_time msg(msg_timeout.entry.sec, msg_timeout.entry.nsec);
386*598139dcSAndroid Build Coastguard Worker if (msg < start) {
387*598139dcSAndroid Build Coastguard Worker fprintf(stderr, "%u.%09u < %u.%09u\n", msg_timeout.entry.sec,
388*598139dcSAndroid Build Coastguard Worker msg_timeout.entry.nsec, (unsigned)start.tv_sec,
389*598139dcSAndroid Build Coastguard Worker (unsigned)start.tv_nsec);
390*598139dcSAndroid Build Coastguard Worker _exit(-1);
391*598139dcSAndroid Build Coastguard Worker }
392*598139dcSAndroid Build Coastguard Worker if (msg > start) {
393*598139dcSAndroid Build Coastguard Worker start = msg;
394*598139dcSAndroid Build Coastguard Worker start.tv_sec += 30;
395*598139dcSAndroid Build Coastguard Worker log_time now = log_time(CLOCK_REALTIME);
396*598139dcSAndroid Build Coastguard Worker if (start > now) {
397*598139dcSAndroid Build Coastguard Worker start = now;
398*598139dcSAndroid Build Coastguard Worker --start.tv_sec;
399*598139dcSAndroid Build Coastguard Worker }
400*598139dcSAndroid Build Coastguard Worker }
401*598139dcSAndroid Build Coastguard Worker } else {
402*598139dcSAndroid Build Coastguard Worker start.tv_sec -= 120; // inactive, reach further back!
403*598139dcSAndroid Build Coastguard Worker }
404*598139dcSAndroid Build Coastguard Worker }
405*598139dcSAndroid Build Coastguard Worker
406*598139dcSAndroid Build Coastguard Worker if (content_wrap) {
407*598139dcSAndroid Build Coastguard Worker dump_log_msg("wrap", &msg_wrap, -1);
408*598139dcSAndroid Build Coastguard Worker }
409*598139dcSAndroid Build Coastguard Worker
410*598139dcSAndroid Build Coastguard Worker if (content_timeout) {
411*598139dcSAndroid Build Coastguard Worker dump_log_msg("timeout", &msg_timeout, -1);
412*598139dcSAndroid Build Coastguard Worker }
413*598139dcSAndroid Build Coastguard Worker
414*598139dcSAndroid Build Coastguard Worker if (content_wrap || !content_timeout) {
415*598139dcSAndroid Build Coastguard Worker fprintf(stderr, "start=%" PRIu32 ".%09" PRIu32 "\n", start.tv_sec,
416*598139dcSAndroid Build Coastguard Worker start.tv_nsec);
417*598139dcSAndroid Build Coastguard Worker }
418*598139dcSAndroid Build Coastguard Worker
419*598139dcSAndroid Build Coastguard Worker EXPECT_TRUE(written);
420*598139dcSAndroid Build Coastguard Worker EXPECT_FALSE(content_wrap);
421*598139dcSAndroid Build Coastguard Worker EXPECT_EQ(0U, alarm_wrap);
422*598139dcSAndroid Build Coastguard Worker EXPECT_TRUE(content_timeout);
423*598139dcSAndroid Build Coastguard Worker EXPECT_NE(0U, alarm_timeout);
424*598139dcSAndroid Build Coastguard Worker
425*598139dcSAndroid Build Coastguard Worker _exit(!written + content_wrap + alarm_wrap + !content_timeout +
426*598139dcSAndroid Build Coastguard Worker !alarm_timeout);
427*598139dcSAndroid Build Coastguard Worker #else
428*598139dcSAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "This test does nothing.\n";
429*598139dcSAndroid Build Coastguard Worker #endif
430*598139dcSAndroid Build Coastguard Worker }
431*598139dcSAndroid Build Coastguard Worker #endif
432*598139dcSAndroid Build Coastguard Worker
433*598139dcSAndroid Build Coastguard Worker #ifdef LOGD_ENABLE_FLAKY_TESTS
434*598139dcSAndroid Build Coastguard Worker // b/27242723 confirmed fixed
TEST(logd,SNDTIMEO)435*598139dcSAndroid Build Coastguard Worker TEST(logd, SNDTIMEO) {
436*598139dcSAndroid Build Coastguard Worker #ifdef __ANDROID__
437*598139dcSAndroid Build Coastguard Worker static const unsigned sndtimeo =
438*598139dcSAndroid Build Coastguard Worker LOGD_SNDTIMEO; // <sigh> it has to be done!
439*598139dcSAndroid Build Coastguard Worker static const unsigned sleep_time = sndtimeo + 3;
440*598139dcSAndroid Build Coastguard Worker static const unsigned alarm_time = sleep_time + 5;
441*598139dcSAndroid Build Coastguard Worker
442*598139dcSAndroid Build Coastguard Worker unique_fd fd(socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET));
443*598139dcSAndroid Build Coastguard Worker ASSERT_LT(0, fd) << "Failed to open logdr: " << strerror(errno);
444*598139dcSAndroid Build Coastguard Worker
445*598139dcSAndroid Build Coastguard Worker struct sigaction ignore = {.sa_handler = caught_signal};
446*598139dcSAndroid Build Coastguard Worker sigemptyset(&ignore.sa_mask);
447*598139dcSAndroid Build Coastguard Worker struct sigaction old_sigaction;
448*598139dcSAndroid Build Coastguard Worker sigaction(SIGALRM, &ignore, &old_sigaction);
449*598139dcSAndroid Build Coastguard Worker unsigned int old_alarm = alarm(alarm_time);
450*598139dcSAndroid Build Coastguard Worker
451*598139dcSAndroid Build Coastguard Worker // Stream all sources.
452*598139dcSAndroid Build Coastguard Worker ASSERT_TRUE(write_command(fd, "stream lids=0,1,2,3,4,5,6"));
453*598139dcSAndroid Build Coastguard Worker
454*598139dcSAndroid Build Coastguard Worker log_msg msg;
455*598139dcSAndroid Build Coastguard Worker bool read_one = TEMP_FAILURE_RETRY(recv(fd, msg.buf, sizeof(msg), 0)) > 0;
456*598139dcSAndroid Build Coastguard Worker EXPECT_TRUE(read_one);
457*598139dcSAndroid Build Coastguard Worker if (read_one) {
458*598139dcSAndroid Build Coastguard Worker dump_log_msg("user", &msg, -1);
459*598139dcSAndroid Build Coastguard Worker }
460*598139dcSAndroid Build Coastguard Worker
461*598139dcSAndroid Build Coastguard Worker fprintf(stderr, "Sleep for >%d seconds logd SO_SNDTIMEO ...\n", sndtimeo);
462*598139dcSAndroid Build Coastguard Worker sleep(sleep_time);
463*598139dcSAndroid Build Coastguard Worker
464*598139dcSAndroid Build Coastguard Worker // flush will block if we did not trigger. if it did, last entry returns 0
465*598139dcSAndroid Build Coastguard Worker int recv_ret;
466*598139dcSAndroid Build Coastguard Worker do {
467*598139dcSAndroid Build Coastguard Worker recv_ret = TEMP_FAILURE_RETRY(recv(fd, msg.buf, sizeof(msg), 0));
468*598139dcSAndroid Build Coastguard Worker } while (recv_ret > 0);
469*598139dcSAndroid Build Coastguard Worker int save_errno = (recv_ret < 0) ? errno : 0;
470*598139dcSAndroid Build Coastguard Worker
471*598139dcSAndroid Build Coastguard Worker EXPECT_NE(0U, alarm(old_alarm));
472*598139dcSAndroid Build Coastguard Worker sigaction(SIGALRM, &old_sigaction, nullptr);
473*598139dcSAndroid Build Coastguard Worker
474*598139dcSAndroid Build Coastguard Worker EXPECT_EQ(0, recv_ret);
475*598139dcSAndroid Build Coastguard Worker if (recv_ret > 0) {
476*598139dcSAndroid Build Coastguard Worker dump_log_msg("user", &msg, -1);
477*598139dcSAndroid Build Coastguard Worker }
478*598139dcSAndroid Build Coastguard Worker EXPECT_EQ(0, save_errno);
479*598139dcSAndroid Build Coastguard Worker #else
480*598139dcSAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "This test does nothing.\n";
481*598139dcSAndroid Build Coastguard Worker #endif
482*598139dcSAndroid Build Coastguard Worker }
483*598139dcSAndroid Build Coastguard Worker #endif
484*598139dcSAndroid Build Coastguard Worker
TEST(logd,getEventTag_list)485*598139dcSAndroid Build Coastguard Worker TEST(logd, getEventTag_list) {
486*598139dcSAndroid Build Coastguard Worker #ifdef __ANDROID__
487*598139dcSAndroid Build Coastguard Worker std::string result;
488*598139dcSAndroid Build Coastguard Worker send_to_control("getEventTag name=*", result);
489*598139dcSAndroid Build Coastguard Worker ASSERT_FALSE(result.empty());
490*598139dcSAndroid Build Coastguard Worker
491*598139dcSAndroid Build Coastguard Worker char* cp;
492*598139dcSAndroid Build Coastguard Worker long ret = strtol(result.c_str(), &cp, 10);
493*598139dcSAndroid Build Coastguard Worker EXPECT_GT(ret, 4096) << "Command result: " << result;
494*598139dcSAndroid Build Coastguard Worker #else
495*598139dcSAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "This test does nothing.\n";
496*598139dcSAndroid Build Coastguard Worker #endif
497*598139dcSAndroid Build Coastguard Worker }
498*598139dcSAndroid Build Coastguard Worker
TEST(logd,getEventTag_42)499*598139dcSAndroid Build Coastguard Worker TEST(logd, getEventTag_42) {
500*598139dcSAndroid Build Coastguard Worker #ifdef __ANDROID__
501*598139dcSAndroid Build Coastguard Worker std::string result;
502*598139dcSAndroid Build Coastguard Worker send_to_control("getEventTag id=42", result);
503*598139dcSAndroid Build Coastguard Worker ASSERT_FALSE(result.empty());
504*598139dcSAndroid Build Coastguard Worker
505*598139dcSAndroid Build Coastguard Worker char* cp;
506*598139dcSAndroid Build Coastguard Worker long ret = strtol(result.c_str(), &cp, 10);
507*598139dcSAndroid Build Coastguard Worker EXPECT_GT(ret, 16) << "Command result: " << result;
508*598139dcSAndroid Build Coastguard Worker EXPECT_NE(std::string::npos, result.find("\t(to life the universe etc|3)"))
509*598139dcSAndroid Build Coastguard Worker << "Command result: " << result;
510*598139dcSAndroid Build Coastguard Worker EXPECT_NE(std::string::npos, result.find("answer")) << "Command result: " << result;
511*598139dcSAndroid Build Coastguard Worker #else
512*598139dcSAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "This test does nothing.\n";
513*598139dcSAndroid Build Coastguard Worker #endif
514*598139dcSAndroid Build Coastguard Worker }
515*598139dcSAndroid Build Coastguard Worker
TEST(logd,getEventTag_newentry)516*598139dcSAndroid Build Coastguard Worker TEST(logd, getEventTag_newentry) {
517*598139dcSAndroid Build Coastguard Worker #ifdef __ANDROID__
518*598139dcSAndroid Build Coastguard Worker log_time now(CLOCK_MONOTONIC);
519*598139dcSAndroid Build Coastguard Worker std::string name;
520*598139dcSAndroid Build Coastguard Worker name = android::base::StringPrintf("a%" PRIu64, now.nsec());
521*598139dcSAndroid Build Coastguard Worker
522*598139dcSAndroid Build Coastguard Worker std::string command;
523*598139dcSAndroid Build Coastguard Worker command = android::base::StringPrintf("getEventTag name=%s format=\"(new|1)\"", name.c_str());
524*598139dcSAndroid Build Coastguard Worker
525*598139dcSAndroid Build Coastguard Worker std::string result;
526*598139dcSAndroid Build Coastguard Worker send_to_control(command.c_str(), result);
527*598139dcSAndroid Build Coastguard Worker ASSERT_FALSE(result.empty());
528*598139dcSAndroid Build Coastguard Worker
529*598139dcSAndroid Build Coastguard Worker char* cp;
530*598139dcSAndroid Build Coastguard Worker long ret = strtol(result.c_str(), &cp, 10);
531*598139dcSAndroid Build Coastguard Worker EXPECT_GT(ret, 16) << "Command result: " << result;
532*598139dcSAndroid Build Coastguard Worker EXPECT_NE(std::string::npos, result.find("\t(new|1)")) << "Command result: " << result;
533*598139dcSAndroid Build Coastguard Worker EXPECT_NE(std::string::npos, result.find(name)) << "Command result: " << result;
534*598139dcSAndroid Build Coastguard Worker // ToDo: also look for this in /data/misc/logd/event-log-tags and
535*598139dcSAndroid Build Coastguard Worker // /dev/event-log-tags.
536*598139dcSAndroid Build Coastguard Worker #else
537*598139dcSAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "This test does nothing.\n";
538*598139dcSAndroid Build Coastguard Worker #endif
539*598139dcSAndroid Build Coastguard Worker }
540*598139dcSAndroid Build Coastguard Worker
TEST(logd,no_epipe)541*598139dcSAndroid Build Coastguard Worker TEST(logd, no_epipe) {
542*598139dcSAndroid Build Coastguard Worker #ifdef __ANDROID__
543*598139dcSAndroid Build Coastguard Worker // Actually generating SIGPIPE in logd is racy, since we need to close the socket quicker than
544*598139dcSAndroid Build Coastguard Worker // logd finishes writing the data to it, so we try 5 times, which should be enough to trigger
545*598139dcSAndroid Build Coastguard Worker // SIGPIPE if logd isn't ignoring SIGPIPE
546*598139dcSAndroid Build Coastguard Worker for (int i = 0; i < 5; ++i) {
547*598139dcSAndroid Build Coastguard Worker unique_fd sock1(
548*598139dcSAndroid Build Coastguard Worker socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM));
549*598139dcSAndroid Build Coastguard Worker ASSERT_LT(0, sock1) << "Failed to open logd: " << strerror(errno);
550*598139dcSAndroid Build Coastguard Worker unique_fd sock2(
551*598139dcSAndroid Build Coastguard Worker socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM));
552*598139dcSAndroid Build Coastguard Worker ASSERT_LT(0, sock2) << "Failed to open logd: " << strerror(errno);
553*598139dcSAndroid Build Coastguard Worker
554*598139dcSAndroid Build Coastguard Worker std::string message = "getStatistics 0 1 2 3 4 5 6 7";
555*598139dcSAndroid Build Coastguard Worker ASSERT_TRUE(write_command(sock1, message));
556*598139dcSAndroid Build Coastguard Worker sock1.reset();
557*598139dcSAndroid Build Coastguard Worker ASSERT_TRUE(write_command(sock2, message));
558*598139dcSAndroid Build Coastguard Worker
559*598139dcSAndroid Build Coastguard Worker struct pollfd p = {.fd = sock2, .events = POLLIN, .revents = 0};
560*598139dcSAndroid Build Coastguard Worker
561*598139dcSAndroid Build Coastguard Worker int ret = TEMP_FAILURE_RETRY(poll(&p, 1, 1000));
562*598139dcSAndroid Build Coastguard Worker EXPECT_EQ(ret, 1);
563*598139dcSAndroid Build Coastguard Worker EXPECT_TRUE(p.revents & POLLIN);
564*598139dcSAndroid Build Coastguard Worker EXPECT_FALSE(p.revents & POLL_ERR);
565*598139dcSAndroid Build Coastguard Worker }
566*598139dcSAndroid Build Coastguard Worker #else
567*598139dcSAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "This test does nothing.\n";
568*598139dcSAndroid Build Coastguard Worker #endif
569*598139dcSAndroid Build Coastguard Worker }
570*598139dcSAndroid Build Coastguard Worker
571*598139dcSAndroid Build Coastguard Worker // Only AID_ROOT, AID_SYSTEM, and AID_LOG can set log sizes. Ensure that a different user, AID_BIN,
572*598139dcSAndroid Build Coastguard Worker // cannot set the log size.
TEST(logd,logging_permissions)573*598139dcSAndroid Build Coastguard Worker TEST(logd, logging_permissions) {
574*598139dcSAndroid Build Coastguard Worker #ifdef __ANDROID__
575*598139dcSAndroid Build Coastguard Worker if (getuid() != 0) {
576*598139dcSAndroid Build Coastguard Worker GTEST_SKIP() << "This test requires root";
577*598139dcSAndroid Build Coastguard Worker }
578*598139dcSAndroid Build Coastguard Worker
579*598139dcSAndroid Build Coastguard Worker auto child_main = [] {
580*598139dcSAndroid Build Coastguard Worker setgroups(0, nullptr);
581*598139dcSAndroid Build Coastguard Worker setgid(AID_BIN);
582*598139dcSAndroid Build Coastguard Worker setuid(AID_BIN);
583*598139dcSAndroid Build Coastguard Worker
584*598139dcSAndroid Build Coastguard Worker std::unique_ptr<logger_list, decltype(&android_logger_list_free)> logger_list{
585*598139dcSAndroid Build Coastguard Worker android_logger_list_alloc(0, 0, 0), &android_logger_list_free};
586*598139dcSAndroid Build Coastguard Worker if (!logger_list) {
587*598139dcSAndroid Build Coastguard Worker _exit(1);
588*598139dcSAndroid Build Coastguard Worker }
589*598139dcSAndroid Build Coastguard Worker auto logger = android_logger_open(logger_list.get(), LOG_ID_MAIN);
590*598139dcSAndroid Build Coastguard Worker if (!logger) {
591*598139dcSAndroid Build Coastguard Worker _exit(2);
592*598139dcSAndroid Build Coastguard Worker }
593*598139dcSAndroid Build Coastguard Worker // This line should fail, so if it returns 0, we exit with an error.
594*598139dcSAndroid Build Coastguard Worker if (android_logger_set_log_size(logger, 2 * 1024 * 1024) == 0) {
595*598139dcSAndroid Build Coastguard Worker _exit(3);
596*598139dcSAndroid Build Coastguard Worker }
597*598139dcSAndroid Build Coastguard Worker _exit(EXIT_SUCCESS);
598*598139dcSAndroid Build Coastguard Worker };
599*598139dcSAndroid Build Coastguard Worker
600*598139dcSAndroid Build Coastguard Worker ASSERT_EXIT(child_main(), testing::ExitedWithCode(0), "");
601*598139dcSAndroid Build Coastguard Worker #else
602*598139dcSAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "This test does nothing.\n";
603*598139dcSAndroid Build Coastguard Worker #endif
604*598139dcSAndroid Build Coastguard Worker }
605