blob: 920d50447f262fe7233f24d4ea63cec4a202e526 [file] [log] [blame]
Mark Salyzyn65772ca2013-12-13 11:10:11 -08001/*
2 * Copyright (C) 2013-2014 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
Mark Salyzynef7c4112014-03-11 10:35:58 -070017#include <ctype.h>
Mark Salyzyn9812fc42015-10-06 08:59:02 -070018#include <dirent.h>
Mark Salyzyn65772ca2013-12-13 11:10:11 -080019#include <signal.h>
20#include <stdio.h>
Mark Salyzyn9879ac82014-06-03 11:24:34 -070021#include <stdlib.h>
Mark Salyzynef7c4112014-03-11 10:35:58 -070022#include <string.h>
Mark Salyzyn9812fc42015-10-06 08:59:02 -070023#include <sys/types.h>
Mark Salyzync18c2132016-04-01 07:52:20 -070024#include <sys/wait.h>
25
James Hawkins588a2ca2016-02-18 14:52:46 -080026#include <memory>
Mark Salyzynef7c4112014-03-11 10:35:58 -070027
Mark Salyzyn33c26252016-04-12 09:11:46 -070028#include <cutils/properties.h>
Mark Salyzyn65772ca2013-12-13 11:10:11 -080029#include <gtest/gtest.h>
30#include <log/log.h>
31#include <log/logger.h>
32#include <log/log_read.h>
33
Mark Salyzyn45177732016-04-11 14:03:48 -070034#define BIG_BUFFER (5 * 1024)
35
Mark Salyzyn65772ca2013-12-13 11:10:11 -080036// enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and
37// non-syscall libs. Since we are only using this in the emergency of
38// a signal to stuff a terminating code into the logs, we will spin rather
39// than try a usleep.
40#define LOG_FAILURE_RETRY(exp) ({ \
41 typeof (exp) _rc; \
42 do { \
43 _rc = (exp); \
44 } while (((_rc == -1) \
45 && ((errno == EINTR) \
46 || (errno == EAGAIN))) \
47 || (_rc == -EINTR) \
48 || (_rc == -EAGAIN)); \
49 _rc; })
50
51static const char begin[] = "--------- beginning of ";
52
Mark Salyzyn65772ca2013-12-13 11:10:11 -080053TEST(logcat, buckets) {
54 FILE *fp;
55
Mark Salyzynef7c4112014-03-11 10:35:58 -070056 ASSERT_TRUE(NULL != (fp = popen(
Mark Salyzyn65772ca2013-12-13 11:10:11 -080057 "logcat -b radio -b events -b system -b main -d 2>/dev/null",
58 "r")));
59
Mark Salyzyn45177732016-04-11 14:03:48 -070060 char buffer[BIG_BUFFER];
Mark Salyzyn65772ca2013-12-13 11:10:11 -080061
62 int ids = 0;
63 int count = 0;
64
65 while (fgets(buffer, sizeof(buffer), fp)) {
66 if (!strncmp(begin, buffer, sizeof(begin) - 1)) {
67 while (char *cp = strrchr(buffer, '\n')) {
68 *cp = '\0';
69 }
70 log_id_t id = android_name_to_log_id(buffer + sizeof(begin) - 1);
71 ids |= 1 << id;
72 ++count;
73 }
74 }
75
76 pclose(fp);
77
Mark Salyzynef7c4112014-03-11 10:35:58 -070078 EXPECT_EQ(15, ids);
Mark Salyzyn65772ca2013-12-13 11:10:11 -080079
Mark Salyzynef7c4112014-03-11 10:35:58 -070080 EXPECT_EQ(4, count);
Mark Salyzyn65772ca2013-12-13 11:10:11 -080081}
82
Mark Salyzynf28f6a92015-08-31 08:01:33 -070083TEST(logcat, year) {
Mark Salyzynb6bee332015-09-08 08:56:32 -070084
Mark Salyzynba7a9a02015-12-01 15:57:25 -080085 if (android_log_clockid() == CLOCK_MONOTONIC) {
Mark Salyzynb6bee332015-09-08 08:56:32 -070086 fprintf(stderr, "Skipping test, logd is monotonic time\n");
87 return;
88 }
89
Mark Salyzynf28f6a92015-08-31 08:01:33 -070090 FILE *fp;
91
92 char needle[32];
93 time_t now;
94 time(&now);
95 struct tm *ptm;
96#if !defined(_WIN32)
97 struct tm tmBuf;
98 ptm = localtime_r(&now, &tmBuf);
99#else
100 ptm = localtime(&&now);
101#endif
102 strftime(needle, sizeof(needle), "[ %Y-", ptm);
103
104 ASSERT_TRUE(NULL != (fp = popen(
105 "logcat -v long -v year -b all -t 3 2>/dev/null",
106 "r")));
107
Mark Salyzyn45177732016-04-11 14:03:48 -0700108 char buffer[BIG_BUFFER];
Mark Salyzynf28f6a92015-08-31 08:01:33 -0700109
110 int count = 0;
111
112 while (fgets(buffer, sizeof(buffer), fp)) {
113 if (!strncmp(buffer, needle, strlen(needle))) {
114 ++count;
115 }
116 }
117
118 pclose(fp);
119
120 ASSERT_EQ(3, count);
121}
122
Mark Salyzynb6bee332015-09-08 08:56:32 -0700123// Return a pointer to each null terminated -v long time field.
124char *fgetLongTime(char *buffer, size_t buflen, FILE *fp) {
125 while (fgets(buffer, buflen, fp)) {
126 char *cp = buffer;
127 if (*cp != '[') {
128 continue;
129 }
130 while (*++cp == ' ') {
131 ;
132 }
133 char *ep = cp;
134 while (isdigit(*ep)) {
135 ++ep;
136 }
137 if ((*ep != '-') && (*ep != '.')) {
138 continue;
139 }
140 // Find PID field
141 while (((ep = strchr(ep, ':'))) && (*++ep != ' ')) {
142 ;
143 }
144 if (!ep) {
145 continue;
146 }
147 ep -= 7;
148 *ep = '\0';
149 return cp;
150 }
151 return NULL;
152}
153
Mark Salyzynf28f6a92015-08-31 08:01:33 -0700154TEST(logcat, tz) {
Mark Salyzynb6bee332015-09-08 08:56:32 -0700155
Mark Salyzynba7a9a02015-12-01 15:57:25 -0800156 if (android_log_clockid() == CLOCK_MONOTONIC) {
Mark Salyzynb6bee332015-09-08 08:56:32 -0700157 fprintf(stderr, "Skipping test, logd is monotonic time\n");
158 return;
159 }
160
Mark Salyzyn3842b1a2016-04-12 11:07:26 -0700161 int tries = 3; // in case run too soon after system start or buffer clear
162 int count;
Mark Salyzynf28f6a92015-08-31 08:01:33 -0700163
Mark Salyzyn3842b1a2016-04-12 11:07:26 -0700164 do {
165 FILE *fp;
Mark Salyzynf28f6a92015-08-31 08:01:33 -0700166
Mark Salyzyn3842b1a2016-04-12 11:07:26 -0700167 ASSERT_TRUE(NULL != (fp = popen(
168 "logcat -v long -v America/Los_Angeles -b all -t 3 2>/dev/null",
169 "r")));
Mark Salyzynf28f6a92015-08-31 08:01:33 -0700170
Mark Salyzyn45177732016-04-11 14:03:48 -0700171 char buffer[BIG_BUFFER];
Mark Salyzynf28f6a92015-08-31 08:01:33 -0700172
Mark Salyzyn3842b1a2016-04-12 11:07:26 -0700173 count = 0;
174
175 while (fgetLongTime(buffer, sizeof(buffer), fp)) {
176 if (strstr(buffer, " -0700") || strstr(buffer, " -0800")) {
177 ++count;
178 }
Mark Salyzynf28f6a92015-08-31 08:01:33 -0700179 }
Mark Salyzynf28f6a92015-08-31 08:01:33 -0700180
Mark Salyzyn3842b1a2016-04-12 11:07:26 -0700181 pclose(fp);
182
183 } while ((count < 3) && --tries && (sleep(1), true));
Mark Salyzynf28f6a92015-08-31 08:01:33 -0700184
185 ASSERT_EQ(3, count);
186}
187
188TEST(logcat, ntz) {
189 FILE *fp;
190
191 ASSERT_TRUE(NULL != (fp = popen(
192 "logcat -v long -v America/Los_Angeles -v zone -b all -t 3 2>/dev/null",
193 "r")));
194
Mark Salyzyn45177732016-04-11 14:03:48 -0700195 char buffer[BIG_BUFFER];
Mark Salyzynf28f6a92015-08-31 08:01:33 -0700196
197 int count = 0;
198
Mark Salyzynb6bee332015-09-08 08:56:32 -0700199 while (fgetLongTime(buffer, sizeof(buffer), fp)) {
200 if (strstr(buffer, " -0700") || strstr(buffer, " -0800")) {
Mark Salyzynf28f6a92015-08-31 08:01:33 -0700201 ++count;
202 }
203 }
204
205 pclose(fp);
206
207 ASSERT_EQ(0, count);
208}
209
Mark Salyzyn3842b1a2016-04-12 11:07:26 -0700210void do_tail(int num) {
211 int tries = 3; // in case run too soon after system start or buffer clear
212 int count;
213
214 do {
Mark Salyzyn45177732016-04-11 14:03:48 -0700215 char buffer[BIG_BUFFER];
Mark Salyzyn3842b1a2016-04-12 11:07:26 -0700216
217 snprintf(buffer, sizeof(buffer),
218 "logcat -v long -b radio -b events -b system -b main -t %d 2>/dev/null",
219 num);
220
221 FILE *fp;
222 ASSERT_TRUE(NULL != (fp = popen(buffer, "r")));
223
224 count = 0;
225
226 while (fgetLongTime(buffer, sizeof(buffer), fp)) {
227 ++count;
228 }
229
230 pclose(fp);
231
232 } while ((count < num) && --tries && (sleep(1), true));
233
234 ASSERT_EQ(num, count);
235}
236
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800237TEST(logcat, tail_3) {
Mark Salyzyn3842b1a2016-04-12 11:07:26 -0700238 do_tail(3);
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800239}
240
241TEST(logcat, tail_10) {
Mark Salyzyn3842b1a2016-04-12 11:07:26 -0700242 do_tail(10);
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800243}
244
245TEST(logcat, tail_100) {
Mark Salyzyn3842b1a2016-04-12 11:07:26 -0700246 do_tail(100);
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800247}
248
249TEST(logcat, tail_1000) {
Mark Salyzyn3842b1a2016-04-12 11:07:26 -0700250 do_tail(1000);
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800251}
252
Mark Salyzynef7c4112014-03-11 10:35:58 -0700253TEST(logcat, tail_time) {
254 FILE *fp;
255
256 ASSERT_TRUE(NULL != (fp = popen("logcat -v long -b all -t 10 2>&1", "r")));
257
Mark Salyzyn45177732016-04-11 14:03:48 -0700258 char buffer[BIG_BUFFER];
Mark Salyzynef7c4112014-03-11 10:35:58 -0700259 char *last_timestamp = NULL;
260 char *first_timestamp = NULL;
261 int count = 0;
Mark Salyzynef7c4112014-03-11 10:35:58 -0700262
Mark Salyzynb6bee332015-09-08 08:56:32 -0700263 char *cp;
264 while ((cp = fgetLongTime(buffer, sizeof(buffer), fp))) {
265 ++count;
266 if (!first_timestamp) {
267 first_timestamp = strdup(cp);
Mark Salyzynef7c4112014-03-11 10:35:58 -0700268 }
Mark Salyzynb6bee332015-09-08 08:56:32 -0700269 free(last_timestamp);
270 last_timestamp = strdup(cp);
Mark Salyzynef7c4112014-03-11 10:35:58 -0700271 }
272 pclose(fp);
273
274 EXPECT_EQ(10, count);
275 EXPECT_TRUE(last_timestamp != NULL);
276 EXPECT_TRUE(first_timestamp != NULL);
277
278 snprintf(buffer, sizeof(buffer), "logcat -v long -b all -t '%s' 2>&1",
279 first_timestamp);
280 ASSERT_TRUE(NULL != (fp = popen(buffer, "r")));
281
282 int second_count = 0;
283 int last_timestamp_count = -1;
284
Mark Salyzynb6bee332015-09-08 08:56:32 -0700285 while ((cp = fgetLongTime(buffer, sizeof(buffer), fp))) {
286 ++second_count;
287 if (first_timestamp) {
288 // we can get a transitory *extremely* rare failure if hidden
289 // underneath the time is *exactly* XX-XX XX:XX:XX.XXX000000
290 EXPECT_STREQ(cp, first_timestamp);
291 free(first_timestamp);
292 first_timestamp = NULL;
293 }
294 if (!strcmp(cp, last_timestamp)) {
295 last_timestamp_count = second_count;
Mark Salyzynef7c4112014-03-11 10:35:58 -0700296 }
297 }
298 pclose(fp);
299
300 free(last_timestamp);
301 last_timestamp = NULL;
Mark Salyzynb6bee332015-09-08 08:56:32 -0700302 free(first_timestamp);
Mark Salyzynef7c4112014-03-11 10:35:58 -0700303
304 EXPECT_TRUE(first_timestamp == NULL);
305 EXPECT_LE(count, second_count);
306 EXPECT_LE(count, last_timestamp_count);
307}
308
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800309TEST(logcat, End_to_End) {
310 pid_t pid = getpid();
311
312 log_time ts(CLOCK_MONOTONIC);
313
314 ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
315
316 FILE *fp;
Mark Salyzynef7c4112014-03-11 10:35:58 -0700317 ASSERT_TRUE(NULL != (fp = popen(
Mark Salyzyna5e24292014-09-18 10:25:38 -0700318 "logcat -v brief -b events -t 100 2>/dev/null",
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800319 "r")));
320
Mark Salyzyn45177732016-04-11 14:03:48 -0700321 char buffer[BIG_BUFFER];
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800322
323 int count = 0;
324
325 while (fgets(buffer, sizeof(buffer), fp)) {
326 int p;
327 unsigned long long t;
328
329 if ((2 != sscanf(buffer, "I/[0] ( %d): %llu", &p, &t))
330 || (p != pid)) {
331 continue;
332 }
333
334 log_time tx((const char *) &t);
335 if (ts == tx) {
336 ++count;
337 }
338 }
339
340 pclose(fp);
341
342 ASSERT_EQ(1, count);
343}
344
Mark Salyzyn45177732016-04-11 14:03:48 -0700345int get_groups(const char *cmd) {
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800346 FILE *fp;
347
Mark Salyzyn9879ac82014-06-03 11:24:34 -0700348 // NB: crash log only available in user space
Mark Salyzyn45177732016-04-11 14:03:48 -0700349 EXPECT_TRUE(NULL != (fp = popen(cmd, "r")));
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800350
Mark Salyzyn45177732016-04-11 14:03:48 -0700351 if (fp == NULL) {
352 return 0;
353 }
354
355 char buffer[BIG_BUFFER];
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800356
357 int count = 0;
358
359 while (fgets(buffer, sizeof(buffer), fp)) {
360 int size, consumed, max, payload;
Mark Salyzyn9812fc42015-10-06 08:59:02 -0700361 char size_mult[3], consumed_mult[3];
Mark Salyzyn9879ac82014-06-03 11:24:34 -0700362 long full_size, full_consumed;
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800363
364 size = consumed = max = payload = 0;
Mark Salyzyn9879ac82014-06-03 11:24:34 -0700365 // NB: crash log can be very small, not hit a Kb of consumed space
366 // doubly lucky we are not including it.
Mark Salyzynd03caa22014-07-10 14:07:39 -0700367 if (6 != sscanf(buffer, "%*s ring buffer is %d%2s (%d%2s consumed),"
Mark Salyzyn9879ac82014-06-03 11:24:34 -0700368 " max entry is %db, max payload is %db",
Mark Salyzynd03caa22014-07-10 14:07:39 -0700369 &size, size_mult, &consumed, consumed_mult,
Mark Salyzyn9879ac82014-06-03 11:24:34 -0700370 &max, &payload)) {
371 fprintf(stderr, "WARNING: Parse error: %s", buffer);
372 continue;
373 }
374 full_size = size;
Mark Salyzynd03caa22014-07-10 14:07:39 -0700375 switch(size_mult[0]) {
Mark Salyzyn9879ac82014-06-03 11:24:34 -0700376 case 'G':
377 full_size *= 1024;
378 /* FALLTHRU */
379 case 'M':
380 full_size *= 1024;
381 /* FALLTHRU */
382 case 'K':
383 full_size *= 1024;
Mark Salyzynd03caa22014-07-10 14:07:39 -0700384 /* FALLTHRU */
385 case 'b':
Mark Salyzyn9879ac82014-06-03 11:24:34 -0700386 break;
387 }
388 full_consumed = consumed;
Mark Salyzynd03caa22014-07-10 14:07:39 -0700389 switch(consumed_mult[0]) {
Mark Salyzyn9879ac82014-06-03 11:24:34 -0700390 case 'G':
391 full_consumed *= 1024;
392 /* FALLTHRU */
393 case 'M':
394 full_consumed *= 1024;
395 /* FALLTHRU */
396 case 'K':
397 full_consumed *= 1024;
Mark Salyzynd03caa22014-07-10 14:07:39 -0700398 /* FALLTHRU */
399 case 'b':
Mark Salyzyn9879ac82014-06-03 11:24:34 -0700400 break;
401 }
402 EXPECT_GT((full_size * 9) / 4, full_consumed);
403 EXPECT_GT(full_size, max);
404 EXPECT_GT(max, payload);
405
406 if ((((full_size * 9) / 4) >= full_consumed)
407 && (full_size > max)
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800408 && (max > payload)) {
409 ++count;
410 }
411 }
412
413 pclose(fp);
414
Mark Salyzyn45177732016-04-11 14:03:48 -0700415 return count;
416}
417
418TEST(logcat, get_size) {
419 ASSERT_EQ(4, get_groups(
420 "logcat -v brief -b radio -b events -b system -b main -g 2>/dev/null"));
421}
422
423// duplicate test for get_size, but use comma-separated list of buffers
424TEST(logcat, multiple_buffer) {
425 ASSERT_EQ(4, get_groups(
426 "logcat -v brief -b radio,events,system,main -g 2>/dev/null"));
427}
428
Mark Salyzyn33c26252016-04-12 09:11:46 -0700429// duplicate test for get_size, but use test.logcat.buffer property
430TEST(logcat, property_expand) {
431 property_set("test.logcat.buffer", "radio,events");
432 EXPECT_EQ(4, get_groups(
433 "logcat -v brief -b 'system,${test.logcat.buffer:-bogo},main' -g 2>/dev/null"));
434 property_set("test.logcat.buffer", "");
435}
436
Mark Salyzyn45177732016-04-11 14:03:48 -0700437TEST(logcat, bad_buffer) {
438 ASSERT_EQ(0, get_groups(
439 "logcat -v brief -b radio,events,bogo,system,main -g 2>/dev/null"));
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800440}
441
Mark Salyzynb149e242014-04-30 09:39:09 -0700442static void caught_blocking(int /*signum*/)
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800443{
444 unsigned long long v = 0xDEADBEEFA55A0000ULL;
445
446 v += getpid() & 0xFFFF;
447
448 LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
449}
450
451TEST(logcat, blocking) {
452 FILE *fp;
Mark Salyzyn9b986492014-01-22 10:30:09 -0800453 unsigned long long v = 0xDEADBEEFA55F0000ULL;
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800454
455 pid_t pid = getpid();
456
457 v += pid & 0xFFFF;
458
Mark Salyzyn9b986492014-01-22 10:30:09 -0800459 LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
460
461 v &= 0xFFFFFFFFFFFAFFFFULL;
462
Mark Salyzynef7c4112014-03-11 10:35:58 -0700463 ASSERT_TRUE(NULL != (fp = popen(
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800464 "( trap exit HUP QUIT INT PIPE KILL ; sleep 6; echo DONE )&"
Mark Salyzyna5e24292014-09-18 10:25:38 -0700465 " logcat -v brief -b events 2>&1",
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800466 "r")));
467
Mark Salyzyn45177732016-04-11 14:03:48 -0700468 char buffer[BIG_BUFFER];
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800469
470 int count = 0;
471
472 int signals = 0;
473
474 signal(SIGALRM, caught_blocking);
475 alarm(2);
476 while (fgets(buffer, sizeof(buffer), fp)) {
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800477
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800478 if (!strncmp(buffer, "DONE", 4)) {
479 break;
480 }
481
Mark Salyzyn9b986492014-01-22 10:30:09 -0800482 ++count;
483
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800484 int p;
485 unsigned long long l;
486
487 if ((2 != sscanf(buffer, "I/[0] ( %u): %lld", &p, &l))
488 || (p != pid)) {
489 continue;
490 }
491
492 if (l == v) {
493 ++signals;
494 break;
495 }
496 }
497 alarm(0);
498 signal(SIGALRM, SIG_DFL);
499
500 // Generate SIGPIPE
501 fclose(fp);
502 caught_blocking(0);
503
504 pclose(fp);
505
Mark Salyzynef7c4112014-03-11 10:35:58 -0700506 EXPECT_LE(2, count);
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800507
Mark Salyzynef7c4112014-03-11 10:35:58 -0700508 EXPECT_EQ(1, signals);
Mark Salyzyn65772ca2013-12-13 11:10:11 -0800509}
Mark Salyzyn5d3d1f12013-12-09 13:47:00 -0800510
Mark Salyzynb149e242014-04-30 09:39:09 -0700511static void caught_blocking_tail(int /*signum*/)
Mark Salyzyn5d3d1f12013-12-09 13:47:00 -0800512{
513 unsigned long long v = 0xA55ADEADBEEF0000ULL;
514
515 v += getpid() & 0xFFFF;
516
517 LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
518}
519
520TEST(logcat, blocking_tail) {
521 FILE *fp;
Mark Salyzyn9b986492014-01-22 10:30:09 -0800522 unsigned long long v = 0xA55FDEADBEEF0000ULL;
Mark Salyzyn5d3d1f12013-12-09 13:47:00 -0800523
524 pid_t pid = getpid();
525
526 v += pid & 0xFFFF;
527
Mark Salyzyn9b986492014-01-22 10:30:09 -0800528 LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
529
530 v &= 0xFFFAFFFFFFFFFFFFULL;
531
Mark Salyzynef7c4112014-03-11 10:35:58 -0700532 ASSERT_TRUE(NULL != (fp = popen(
Mark Salyzyn5d3d1f12013-12-09 13:47:00 -0800533 "( trap exit HUP QUIT INT PIPE KILL ; sleep 6; echo DONE )&"
Mark Salyzyna5e24292014-09-18 10:25:38 -0700534 " logcat -v brief -b events -T 5 2>&1",
Mark Salyzyn5d3d1f12013-12-09 13:47:00 -0800535 "r")));
536
Mark Salyzyn45177732016-04-11 14:03:48 -0700537 char buffer[BIG_BUFFER];
Mark Salyzyn5d3d1f12013-12-09 13:47:00 -0800538
539 int count = 0;
540
541 int signals = 0;
542
543 signal(SIGALRM, caught_blocking_tail);
544 alarm(2);
545 while (fgets(buffer, sizeof(buffer), fp)) {
Mark Salyzyn5d3d1f12013-12-09 13:47:00 -0800546
Mark Salyzyn5d3d1f12013-12-09 13:47:00 -0800547 if (!strncmp(buffer, "DONE", 4)) {
548 break;
549 }
550
Mark Salyzyn9b986492014-01-22 10:30:09 -0800551 ++count;
552
Mark Salyzyn5d3d1f12013-12-09 13:47:00 -0800553 int p;
554 unsigned long long l;
555
556 if ((2 != sscanf(buffer, "I/[0] ( %u): %lld", &p, &l))
557 || (p != pid)) {
558 continue;
559 }
560
561 if (l == v) {
562 if (count >= 5) {
563 ++signals;
564 }
565 break;
566 }
567 }
568 alarm(0);
569 signal(SIGALRM, SIG_DFL);
570
Mark Salyzyn9b986492014-01-22 10:30:09 -0800571 // Generate SIGPIPE
Mark Salyzyn5d3d1f12013-12-09 13:47:00 -0800572 fclose(fp);
573 caught_blocking_tail(0);
574
575 pclose(fp);
576
Mark Salyzynef7c4112014-03-11 10:35:58 -0700577 EXPECT_LE(2, count);
Mark Salyzyn9b986492014-01-22 10:30:09 -0800578
Mark Salyzynef7c4112014-03-11 10:35:58 -0700579 EXPECT_EQ(1, signals);
Mark Salyzyn9b986492014-01-22 10:30:09 -0800580}
581
Mark Salyzynd03caa22014-07-10 14:07:39 -0700582TEST(logcat, logrotate) {
583 static const char form[] = "/data/local/tmp/logcat.logrotate.XXXXXX";
584 char buf[sizeof(form)];
585 ASSERT_TRUE(NULL != mkdtemp(strcpy(buf, form)));
586
587 static const char comm[] = "logcat -b radio -b events -b system -b main"
588 " -d -f %s/log.txt -n 7 -r 1";
589 char command[sizeof(buf) + sizeof(comm)];
Mark Salyzyn9812fc42015-10-06 08:59:02 -0700590 snprintf(command, sizeof(command), comm, buf);
Mark Salyzynd03caa22014-07-10 14:07:39 -0700591
592 int ret;
593 EXPECT_FALSE((ret = system(command)));
594 if (!ret) {
Mark Salyzyn9812fc42015-10-06 08:59:02 -0700595 snprintf(command, sizeof(command), "ls -s %s 2>/dev/null", buf);
Mark Salyzynd03caa22014-07-10 14:07:39 -0700596
597 FILE *fp;
598 EXPECT_TRUE(NULL != (fp = popen(command, "r")));
599 if (fp) {
Mark Salyzyn45177732016-04-11 14:03:48 -0700600 char buffer[BIG_BUFFER];
Mark Salyzynd03caa22014-07-10 14:07:39 -0700601 int count = 0;
602
603 while (fgets(buffer, sizeof(buffer), fp)) {
Mark Salyzynd03caa22014-07-10 14:07:39 -0700604 static const char total[] = "total ";
Mark Salyzyn9812fc42015-10-06 08:59:02 -0700605 int num;
606 char c;
Mark Salyzynd03caa22014-07-10 14:07:39 -0700607
Mark Salyzyn9812fc42015-10-06 08:59:02 -0700608 if ((2 == sscanf(buffer, "%d log.tx%c", &num, &c)) &&
Mark Salyzyn8beb0d32015-12-15 10:39:07 -0800609 (num <= 40)) {
Mark Salyzynd03caa22014-07-10 14:07:39 -0700610 ++count;
611 } else if (strncmp(buffer, total, sizeof(total) - 1)) {
612 fprintf(stderr, "WARNING: Parse error: %s", buffer);
613 }
614 }
615 pclose(fp);
Mark Salyzynb6bee332015-09-08 08:56:32 -0700616 if ((count != 7) && (count != 8)) {
617 fprintf(stderr, "count=%d\n", count);
618 }
Mark Salyzynd03caa22014-07-10 14:07:39 -0700619 EXPECT_TRUE(count == 7 || count == 8);
620 }
621 }
Mark Salyzyn9812fc42015-10-06 08:59:02 -0700622 snprintf(command, sizeof(command), "rm -rf %s", buf);
Mark Salyzynd03caa22014-07-10 14:07:39 -0700623 EXPECT_FALSE(system(command));
624}
625
Aristidis Papaioannoueba73442014-10-16 22:19:55 -0700626TEST(logcat, logrotate_suffix) {
627 static const char tmp_out_dir_form[] = "/data/local/tmp/logcat.logrotate.XXXXXX";
628 char tmp_out_dir[sizeof(tmp_out_dir_form)];
629 ASSERT_TRUE(NULL != mkdtemp(strcpy(tmp_out_dir, tmp_out_dir_form)));
630
631 static const char logcat_cmd[] = "logcat -b radio -b events -b system -b main"
632 " -d -f %s/log.txt -n 10 -r 1";
633 char command[sizeof(tmp_out_dir) + sizeof(logcat_cmd)];
Mark Salyzyn9812fc42015-10-06 08:59:02 -0700634 snprintf(command, sizeof(command), logcat_cmd, tmp_out_dir);
Aristidis Papaioannoueba73442014-10-16 22:19:55 -0700635
636 int ret;
637 EXPECT_FALSE((ret = system(command)));
638 if (!ret) {
Mark Salyzyn9812fc42015-10-06 08:59:02 -0700639 snprintf(command, sizeof(command), "ls %s 2>/dev/null", tmp_out_dir);
Aristidis Papaioannoueba73442014-10-16 22:19:55 -0700640
641 FILE *fp;
642 EXPECT_TRUE(NULL != (fp = popen(command, "r")));
Mark Salyzyn45177732016-04-11 14:03:48 -0700643 char buffer[BIG_BUFFER];
Aristidis Papaioannoueba73442014-10-16 22:19:55 -0700644 int log_file_count = 0;
645
646 while (fgets(buffer, sizeof(buffer), fp)) {
647 static const char rotated_log_filename_prefix[] = "log.txt.";
648 static const size_t rotated_log_filename_prefix_len =
649 strlen(rotated_log_filename_prefix);
Aristidis Papaioannoueba73442014-10-16 22:19:55 -0700650 static const char log_filename[] = "log.txt";
651
652 if (!strncmp(buffer, rotated_log_filename_prefix, rotated_log_filename_prefix_len)) {
653 // Rotated file should have form log.txt.##
654 char* rotated_log_filename_suffix = buffer + rotated_log_filename_prefix_len;
655 char* endptr;
656 const long int suffix_value = strtol(rotated_log_filename_suffix, &endptr, 10);
657 EXPECT_EQ(rotated_log_filename_suffix + 2, endptr);
658 EXPECT_LE(suffix_value, 10);
659 EXPECT_GT(suffix_value, 0);
660 ++log_file_count;
661 continue;
662 }
663
664 if (!strncmp(buffer, log_filename, strlen(log_filename))) {
665 ++log_file_count;
666 continue;
667 }
668
669 fprintf(stderr, "ERROR: Unexpected file: %s", buffer);
670 ADD_FAILURE();
671 }
672 pclose(fp);
673 EXPECT_EQ(11, log_file_count);
674 }
Mark Salyzyn9812fc42015-10-06 08:59:02 -0700675 snprintf(command, sizeof(command), "rm -rf %s", tmp_out_dir);
676 EXPECT_FALSE(system(command));
677}
678
679TEST(logcat, logrotate_continue) {
680 static const char tmp_out_dir_form[] = "/data/local/tmp/logcat.logrotate.XXXXXX";
681 char tmp_out_dir[sizeof(tmp_out_dir_form)];
682 ASSERT_TRUE(NULL != mkdtemp(strcpy(tmp_out_dir, tmp_out_dir_form)));
683
684 static const char log_filename[] = "log.txt";
685 static const char logcat_cmd[] = "logcat -b all -d -f %s/%s -n 256 -r 1024";
686 static const char cleanup_cmd[] = "rm -rf %s";
687 char command[sizeof(tmp_out_dir) + sizeof(logcat_cmd) + sizeof(log_filename)];
688 snprintf(command, sizeof(command), logcat_cmd, tmp_out_dir, log_filename);
689
690 int ret;
691 EXPECT_FALSE((ret = system(command)));
692 if (ret) {
693 snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
694 EXPECT_FALSE(system(command));
695 return;
696 }
697 FILE *fp;
698 snprintf(command, sizeof(command), "%s/%s", tmp_out_dir, log_filename);
699 EXPECT_TRUE(NULL != ((fp = fopen(command, "r"))));
700 if (!fp) {
701 snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
702 EXPECT_FALSE(system(command));
703 return;
704 }
705 char *line = NULL;
706 char *last_line = NULL; // this line is allowed to stutter, one-line overlap
707 char *second_last_line = NULL;
708 size_t len = 0;
709 while (getline(&line, &len, fp) != -1) {
710 free(second_last_line);
711 second_last_line = last_line;
712 last_line = line;
713 line = NULL;
714 }
715 fclose(fp);
716 free(line);
717 if (second_last_line == NULL) {
718 fprintf(stderr, "No second to last line, using last, test may fail\n");
719 second_last_line = last_line;
720 last_line = NULL;
721 }
722 free(last_line);
723 EXPECT_TRUE(NULL != second_last_line);
724 if (!second_last_line) {
725 snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
726 EXPECT_FALSE(system(command));
727 return;
728 }
729 // re-run the command, it should only add a few lines more content if it
730 // continues where it left off.
731 snprintf(command, sizeof(command), logcat_cmd, tmp_out_dir, log_filename);
732 EXPECT_FALSE((ret = system(command)));
733 if (ret) {
734 snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
735 EXPECT_FALSE(system(command));
736 return;
737 }
James Hawkins588a2ca2016-02-18 14:52:46 -0800738 std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(tmp_out_dir), closedir);
739 EXPECT_NE(nullptr, dir);
Mark Salyzyn9812fc42015-10-06 08:59:02 -0700740 if (!dir) {
741 snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
742 EXPECT_FALSE(system(command));
743 return;
744 }
745 struct dirent *entry;
746 unsigned count = 0;
James Hawkins588a2ca2016-02-18 14:52:46 -0800747 while ((entry = readdir(dir.get()))) {
Mark Salyzyn9812fc42015-10-06 08:59:02 -0700748 if (strncmp(entry->d_name, log_filename, sizeof(log_filename) - 1)) {
749 continue;
750 }
751 snprintf(command, sizeof(command), "%s/%s", tmp_out_dir, entry->d_name);
752 EXPECT_TRUE(NULL != ((fp = fopen(command, "r"))));
753 if (!fp) {
754 fprintf(stderr, "%s ?\n", command);
755 continue;
756 }
757 line = NULL;
758 size_t number = 0;
759 while (getline(&line, &len, fp) != -1) {
760 ++number;
761 if (!strcmp(line, second_last_line)) {
762 EXPECT_TRUE(++count <= 1);
763 fprintf(stderr, "%s(%zu):\n", entry->d_name, number);
764 }
765 }
766 fclose(fp);
767 free(line);
768 unlink(command);
769 }
Mark Salyzyn9812fc42015-10-06 08:59:02 -0700770 if (count > 1) {
771 char *brk = strpbrk(second_last_line, "\r\n");
772 if (!brk) {
773 brk = second_last_line + strlen(second_last_line);
774 }
775 fprintf(stderr, "\"%.*s\" occured %u times\n",
776 (int)(brk - second_last_line), second_last_line, count);
777 }
778 free(second_last_line);
779
780 snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
Aristidis Papaioannoueba73442014-10-16 22:19:55 -0700781 EXPECT_FALSE(system(command));
782}
783
Mark Salyzync18c2132016-04-01 07:52:20 -0700784TEST(logcat, logrotate_nodir) {
785 // expect logcat to error out on writing content and exit(1) for nodir
786 EXPECT_EQ(W_EXITCODE(1, 0),
787 system("logcat -b all -d"
788 " -f /das/nein/gerfingerpoken/logcat/log.txt"
789 " -n 256 -r 1024"));
790}
791
792static void caught_blocking_clear(int /*signum*/) {
Mark Salyzyn9b986492014-01-22 10:30:09 -0800793 unsigned long long v = 0xDEADBEEFA55C0000ULL;
794
795 v += getpid() & 0xFFFF;
796
797 LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
798}
799
800TEST(logcat, blocking_clear) {
801 FILE *fp;
802 unsigned long long v = 0xDEADBEEFA55C0000ULL;
803
804 pid_t pid = getpid();
805
806 v += pid & 0xFFFF;
807
808 // This test is racey; an event occurs between clear and dump.
809 // We accept that we will get a false positive, but never a false negative.
Mark Salyzynef7c4112014-03-11 10:35:58 -0700810 ASSERT_TRUE(NULL != (fp = popen(
Mark Salyzyn9b986492014-01-22 10:30:09 -0800811 "( trap exit HUP QUIT INT PIPE KILL ; sleep 6; echo DONE )&"
812 " logcat -b events -c 2>&1 ;"
Mark Salyzyne7e5f1b2016-04-29 11:28:03 -0700813 " logcat -b events -g 2>&1 ;"
Mark Salyzyna5e24292014-09-18 10:25:38 -0700814 " logcat -v brief -b events 2>&1",
Mark Salyzyn9b986492014-01-22 10:30:09 -0800815 "r")));
816
Mark Salyzyn45177732016-04-11 14:03:48 -0700817 char buffer[BIG_BUFFER];
Mark Salyzyn9b986492014-01-22 10:30:09 -0800818
819 int count = 0;
Mark Salyzyne7e5f1b2016-04-29 11:28:03 -0700820 int minus_g = 0;
Mark Salyzyn9b986492014-01-22 10:30:09 -0800821
822 int signals = 0;
823
824 signal(SIGALRM, caught_blocking_clear);
825 alarm(2);
826 while (fgets(buffer, sizeof(buffer), fp)) {
Mark Salyzyn9b986492014-01-22 10:30:09 -0800827
828 if (!strncmp(buffer, "clearLog: ", 10)) {
829 fprintf(stderr, "WARNING: Test lacks permission to run :-(\n");
830 count = signals = 1;
831 break;
832 }
833
834 if (!strncmp(buffer, "DONE", 4)) {
835 break;
836 }
837
Mark Salyzyne7e5f1b2016-04-29 11:28:03 -0700838 int size, consumed, max, payload;
839 char size_mult[3], consumed_mult[3];
840 size = consumed = max = payload = 0;
841 if (6 == sscanf(buffer, "events: ring buffer is %d%2s (%d%2s consumed),"
842 " max entry is %db, max payload is %db",
843 &size, size_mult, &consumed, consumed_mult,
844 &max, &payload)) {
845 long full_size = size, full_consumed = consumed;
846
847 switch(size_mult[0]) {
848 case 'G':
849 full_size *= 1024;
850 /* FALLTHRU */
851 case 'M':
852 full_size *= 1024;
853 /* FALLTHRU */
854 case 'K':
855 full_size *= 1024;
856 /* FALLTHRU */
857 case 'b':
858 break;
859 }
860 switch(consumed_mult[0]) {
861 case 'G':
862 full_consumed *= 1024;
863 /* FALLTHRU */
864 case 'M':
865 full_consumed *= 1024;
866 /* FALLTHRU */
867 case 'K':
868 full_consumed *= 1024;
869 /* FALLTHRU */
870 case 'b':
871 break;
872 }
873 EXPECT_GT(full_size, full_consumed);
874 EXPECT_GT(full_size, max);
875 EXPECT_GT(max, payload);
876 EXPECT_GT(max, full_consumed);
877
878 ++minus_g;
879 continue;
880 }
881
Mark Salyzyn9b986492014-01-22 10:30:09 -0800882 ++count;
883
884 int p;
885 unsigned long long l;
886
887 if ((2 != sscanf(buffer, "I/[0] ( %u): %lld", &p, &l))
888 || (p != pid)) {
889 continue;
890 }
891
892 if (l == v) {
893 if (count > 1) {
894 fprintf(stderr, "WARNING: Possible false positive\n");
895 }
896 ++signals;
897 break;
898 }
899 }
900 alarm(0);
901 signal(SIGALRM, SIG_DFL);
902
903 // Generate SIGPIPE
904 fclose(fp);
905 caught_blocking_clear(0);
906
907 pclose(fp);
908
Mark Salyzynef7c4112014-03-11 10:35:58 -0700909 EXPECT_LE(1, count);
Mark Salyzyne7e5f1b2016-04-29 11:28:03 -0700910 EXPECT_EQ(1, minus_g);
Mark Salyzyn5d3d1f12013-12-09 13:47:00 -0800911
Mark Salyzynef7c4112014-03-11 10:35:58 -0700912 EXPECT_EQ(1, signals);
Mark Salyzyn5d3d1f12013-12-09 13:47:00 -0800913}
Mark Salyzyn95cfc7b2014-03-11 11:20:56 -0700914
Mark Salyzyn95cfc7b2014-03-11 11:20:56 -0700915static bool get_white_black(char **list) {
916 FILE *fp;
917
918 fp = popen("logcat -p 2>/dev/null", "r");
919 if (fp == NULL) {
920 fprintf(stderr, "ERROR: logcat -p 2>/dev/null\n");
921 return false;
922 }
923
Mark Salyzyn45177732016-04-11 14:03:48 -0700924 char buffer[BIG_BUFFER];
Mark Salyzyn95cfc7b2014-03-11 11:20:56 -0700925
926 while (fgets(buffer, sizeof(buffer), fp)) {
927 char *hold = *list;
928 char *buf = buffer;
929 while (isspace(*buf)) {
930 ++buf;
931 }
932 char *end = buf + strlen(buf);
933 while (isspace(*--end) && (end >= buf)) {
934 *end = '\0';
935 }
936 if (end < buf) {
937 continue;
938 }
939 if (hold) {
940 asprintf(list, "%s %s", hold, buf);
941 free(hold);
942 } else {
943 asprintf(list, "%s", buf);
944 }
945 }
946 pclose(fp);
947 return *list != NULL;
948}
949
950static bool set_white_black(const char *list) {
951 FILE *fp;
952
Mark Salyzyn45177732016-04-11 14:03:48 -0700953 char buffer[BIG_BUFFER];
Mark Salyzyn95cfc7b2014-03-11 11:20:56 -0700954
Mark Salyzyn9879ac82014-06-03 11:24:34 -0700955 snprintf(buffer, sizeof(buffer), "logcat -P '%s' 2>&1", list ? list : "");
Mark Salyzyn95cfc7b2014-03-11 11:20:56 -0700956 fp = popen(buffer, "r");
957 if (fp == NULL) {
958 fprintf(stderr, "ERROR: %s\n", buffer);
959 return false;
960 }
961
962 while (fgets(buffer, sizeof(buffer), fp)) {
963 char *buf = buffer;
964 while (isspace(*buf)) {
965 ++buf;
966 }
967 char *end = buf + strlen(buf);
Mark Salyzyn9879ac82014-06-03 11:24:34 -0700968 while ((end > buf) && isspace(*--end)) {
Mark Salyzyn95cfc7b2014-03-11 11:20:56 -0700969 *end = '\0';
970 }
Mark Salyzyn9879ac82014-06-03 11:24:34 -0700971 if (end <= buf) {
Mark Salyzyn95cfc7b2014-03-11 11:20:56 -0700972 continue;
973 }
974 fprintf(stderr, "%s\n", buf);
975 pclose(fp);
976 return false;
977 }
978 return pclose(fp) == 0;
979}
980
981TEST(logcat, white_black_adjust) {
982 char *list = NULL;
983 char *adjust = NULL;
984
Mark Salyzyn9879ac82014-06-03 11:24:34 -0700985 get_white_black(&list);
Mark Salyzyn95cfc7b2014-03-11 11:20:56 -0700986
Mark Salyzyn22e287d2014-03-21 13:12:16 -0700987 static const char adjustment[] = "~! 300/20 300/25 2000 ~1000/5 ~1000/30";
Mark Salyzyn95cfc7b2014-03-11 11:20:56 -0700988 ASSERT_EQ(true, set_white_black(adjustment));
989 ASSERT_EQ(true, get_white_black(&adjust));
Mark Salyzynef7c4112014-03-11 10:35:58 -0700990 EXPECT_STREQ(adjustment, adjust);
Mark Salyzyn95cfc7b2014-03-11 11:20:56 -0700991 free(adjust);
992 adjust = NULL;
993
Mark Salyzyn22e287d2014-03-21 13:12:16 -0700994 static const char adjustment2[] = "300/20 300/21 2000 ~1000";
995 ASSERT_EQ(true, set_white_black(adjustment2));
996 ASSERT_EQ(true, get_white_black(&adjust));
Mark Salyzynef7c4112014-03-11 10:35:58 -0700997 EXPECT_STREQ(adjustment2, adjust);
Mark Salyzyn22e287d2014-03-21 13:12:16 -0700998 free(adjust);
999 adjust = NULL;
1000
Mark Salyzyn95cfc7b2014-03-11 11:20:56 -07001001 ASSERT_EQ(true, set_white_black(list));
Mark Salyzyn9879ac82014-06-03 11:24:34 -07001002 get_white_black(&adjust);
1003 EXPECT_STREQ(list ? list : "", adjust ? adjust : "");
Mark Salyzyn95cfc7b2014-03-11 11:20:56 -07001004 free(adjust);
1005 adjust = NULL;
1006
1007 free(list);
1008 list = NULL;
1009}
Casey Dahlindc42a872016-03-17 16:18:55 -07001010
1011TEST(logcat, regex) {
1012 FILE *fp;
1013 int count = 0;
1014
Mark Salyzyn45177732016-04-11 14:03:48 -07001015 char buffer[BIG_BUFFER];
Casey Dahlindc42a872016-03-17 16:18:55 -07001016
1017 snprintf(buffer, sizeof(buffer), "logcat --pid %d -d -e logcat_test_a+b", getpid());
1018
1019 LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_WARN, "logcat_test", "logcat_test_ab"));
1020 LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_WARN, "logcat_test", "logcat_test_b"));
1021 LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_WARN, "logcat_test", "logcat_test_aaaab"));
1022 LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_WARN, "logcat_test", "logcat_test_aaaa"));
1023
1024 // Let the logs settle
1025 sleep(1);
1026
1027 ASSERT_TRUE(NULL != (fp = popen(buffer, "r")));
1028
1029 while (fgets(buffer, sizeof(buffer), fp)) {
1030 if (!strncmp(begin, buffer, sizeof(begin) - 1)) {
1031 continue;
1032 }
1033
1034 EXPECT_TRUE(strstr(buffer, "logcat_test_") != NULL);
1035
1036 count++;
1037 }
1038
1039 pclose(fp);
1040
1041 ASSERT_EQ(2, count);
1042}
Casey Dahlin6ac498d2016-03-17 14:04:52 -07001043
1044TEST(logcat, maxcount) {
1045 FILE *fp;
1046 int count = 0;
1047
Mark Salyzyn45177732016-04-11 14:03:48 -07001048 char buffer[BIG_BUFFER];
Casey Dahlin6ac498d2016-03-17 14:04:52 -07001049
1050 snprintf(buffer, sizeof(buffer), "logcat --pid %d -d --max-count 3", getpid());
1051
1052 LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_WARN, "logcat_test", "logcat_test"));
1053 LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_WARN, "logcat_test", "logcat_test"));
1054 LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_WARN, "logcat_test", "logcat_test"));
1055 LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_WARN, "logcat_test", "logcat_test"));
1056
1057 // Let the logs settle
1058 sleep(1);
1059
1060 ASSERT_TRUE(NULL != (fp = popen(buffer, "r")));
1061
1062 while (fgets(buffer, sizeof(buffer), fp)) {
1063 if (!strncmp(begin, buffer, sizeof(begin) - 1)) {
1064 continue;
1065 }
1066
1067 count++;
1068 }
1069
1070 pclose(fp);
1071
1072 ASSERT_EQ(3, count);
1073}