165772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn/*
265772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn * Copyright (C) 2013-2014 The Android Open Source Project
365772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn *
465772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn * Licensed under the Apache License, Version 2.0 (the "License");
565772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn * you may not use this file except in compliance with the License.
665772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn * You may obtain a copy of the License at
765772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn *
865772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn *      http://www.apache.org/licenses/LICENSE-2.0
965772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn *
1065772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn * Unless required by applicable law or agreed to in writing, software
1165772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn * distributed under the License is distributed on an "AS IS" BASIS,
1265772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1365772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn * See the License for the specific language governing permissions and
1465772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn * limitations under the License.
1565772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn */
1665772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
17ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn#include <ctype.h>
189812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn#include <dirent.h>
1965772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn#include <signal.h>
2065772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn#include <stdio.h>
219879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn#include <stdlib.h>
22ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn#include <string.h>
239812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn#include <sys/types.h>
241ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn#include <sys/wait.h>
25ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn
2665772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn#include <gtest/gtest.h>
2765772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn#include <log/log.h>
2865772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn#include <log/logger.h>
2965772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn#include <log/log_read.h>
3065772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
317545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn#define BIG_BUFFER (5 * 1024)
327545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn
3365772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn// enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and
3465772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn// non-syscall libs. Since we are only using this in the emergency of
3565772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn// a signal to stuff a terminating code into the logs, we will spin rather
3665772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn// than try a usleep.
3765772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn#define LOG_FAILURE_RETRY(exp) ({  \
3865772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    typeof (exp) _rc;              \
3965772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    do {                           \
4065772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn        _rc = (exp);               \
4165772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    } while (((_rc == -1)          \
4265772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn           && ((errno == EINTR)    \
4365772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn            || (errno == EAGAIN))) \
4465772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn          || (_rc == -EINTR)       \
4565772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn          || (_rc == -EAGAIN));    \
4665772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    _rc; })
4765772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
4865772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzynstatic const char begin[] = "--------- beginning of ";
4965772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
5065772ca7d7b61b111e75fb0f66f43966f0794bbdMark SalyzynTEST(logcat, buckets) {
5165772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    FILE *fp;
5265772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
53ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    ASSERT_TRUE(NULL != (fp = popen(
5465772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn      "logcat -b radio -b events -b system -b main -d 2>/dev/null",
5565772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn      "r")));
5665772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
577545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn    char buffer[BIG_BUFFER];
5865772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
5965772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    int ids = 0;
6065772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    int count = 0;
6165772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
6265772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    while (fgets(buffer, sizeof(buffer), fp)) {
6365772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn        if (!strncmp(begin, buffer, sizeof(begin) - 1)) {
6465772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn            while (char *cp = strrchr(buffer, '\n')) {
6565772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn                *cp = '\0';
6665772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn            }
6765772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn            log_id_t id = android_name_to_log_id(buffer + sizeof(begin) - 1);
6865772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn            ids |= 1 << id;
6965772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn            ++count;
7065772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn        }
7165772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    }
7265772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
7365772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    pclose(fp);
7465772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
75ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    EXPECT_EQ(15, ids);
7665772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
77ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    EXPECT_EQ(4, count);
7865772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn}
7965772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
80f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark SalyzynTEST(logcat, year) {
81b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn
82ba7a9a016bf011fdf45b6736d4c6d6795faba9d3Mark Salyzyn    if (android_log_clockid() == CLOCK_MONOTONIC) {
83b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        fprintf(stderr, "Skipping test, logd is monotonic time\n");
84b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        return;
85b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn    }
86b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn
87f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn    FILE *fp;
88f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn
89f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn    char needle[32];
90f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn    time_t now;
91f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn    time(&now);
92f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn    struct tm *ptm;
93f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn#if !defined(_WIN32)
94f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn    struct tm tmBuf;
95f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn    ptm = localtime_r(&now, &tmBuf);
96f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn#else
97f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn    ptm = localtime(&&now);
98f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn#endif
99f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn    strftime(needle, sizeof(needle), "[ %Y-", ptm);
100f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn
101f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn    ASSERT_TRUE(NULL != (fp = popen(
102f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn      "logcat -v long -v year -b all -t 3 2>/dev/null",
103f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn      "r")));
104f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn
1057545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn    char buffer[BIG_BUFFER];
106f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn
107f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn    int count = 0;
108f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn
109f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn    while (fgets(buffer, sizeof(buffer), fp)) {
110f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn        if (!strncmp(buffer, needle, strlen(needle))) {
111f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn            ++count;
112f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn        }
113f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn    }
114f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn
115f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn    pclose(fp);
116f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn
117f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn    ASSERT_EQ(3, count);
118f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn}
119f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn
120b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn// Return a pointer to each null terminated -v long time field.
121b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzynchar *fgetLongTime(char *buffer, size_t buflen, FILE *fp) {
122b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn    while (fgets(buffer, buflen, fp)) {
123b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        char *cp = buffer;
124b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        if (*cp != '[') {
125b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn            continue;
126b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        }
127b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        while (*++cp == ' ') {
128b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn            ;
129b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        }
130b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        char *ep = cp;
131b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        while (isdigit(*ep)) {
132b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn            ++ep;
133b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        }
134b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        if ((*ep != '-') && (*ep != '.')) {
135b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn           continue;
136b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        }
137b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        // Find PID field
138b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        while (((ep = strchr(ep, ':'))) && (*++ep != ' ')) {
139b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn            ;
140b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        }
141b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        if (!ep) {
142b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn            continue;
143b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        }
144b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        ep -= 7;
145b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        *ep = '\0';
146b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        return cp;
147b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn    }
148b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn    return NULL;
149b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn}
150b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn
151f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark SalyzynTEST(logcat, tz) {
152b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn
153ba7a9a016bf011fdf45b6736d4c6d6795faba9d3Mark Salyzyn    if (android_log_clockid() == CLOCK_MONOTONIC) {
154b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        fprintf(stderr, "Skipping test, logd is monotonic time\n");
155b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        return;
156b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn    }
157b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn
1583c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn    int tries = 3; // in case run too soon after system start or buffer clear
1593c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn    int count;
160f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn
1613c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn    do {
1623c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn        FILE *fp;
163f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn
1643c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn        ASSERT_TRUE(NULL != (fp = popen(
1653c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn          "logcat -v long -v America/Los_Angeles -b all -t 3 2>/dev/null",
1663c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn          "r")));
167f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn
1687545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn        char buffer[BIG_BUFFER];
169f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn
1703c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn        count = 0;
1713c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn
1723c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn        while (fgetLongTime(buffer, sizeof(buffer), fp)) {
1733c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn            if (strstr(buffer, " -0700") || strstr(buffer, " -0800")) {
1743c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn                ++count;
1753c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn            }
176f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn        }
177f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn
1783c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn        pclose(fp);
1793c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn
1803c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn    } while ((count < 3) && --tries && (sleep(1), true));
181f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn
182f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn    ASSERT_EQ(3, count);
183f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn}
184f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn
185f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark SalyzynTEST(logcat, ntz) {
186f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn    FILE *fp;
187f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn
188f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn    ASSERT_TRUE(NULL != (fp = popen(
189f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn      "logcat -v long -v America/Los_Angeles -v zone -b all -t 3 2>/dev/null",
190f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn      "r")));
191f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn
1927545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn    char buffer[BIG_BUFFER];
193f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn
194f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn    int count = 0;
195f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn
196b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn    while (fgetLongTime(buffer, sizeof(buffer), fp)) {
197b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        if (strstr(buffer, " -0700") || strstr(buffer, " -0800")) {
198f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn            ++count;
199f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn        }
200f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn    }
201f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn
202f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn    pclose(fp);
203f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn
204f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn    ASSERT_EQ(0, count);
205f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn}
206f28f6a9ba228803b402ebaccb59f1b2f2fd4af92Mark Salyzyn
2073c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzynvoid do_tail(int num) {
2083c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn    int tries = 3; // in case run too soon after system start or buffer clear
2093c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn    int count;
21065772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
2113c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn    do {
2127545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn        char buffer[BIG_BUFFER];
21365772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
2143c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn        snprintf(buffer, sizeof(buffer),
2153c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn          "logcat -v long -b radio -b events -b system -b main -t %d 2>/dev/null",
2163c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn          num);
21765772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
2183c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn        FILE *fp;
2193c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn        ASSERT_TRUE(NULL != (fp = popen(buffer, "r")));
22065772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
2213c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn        count = 0;
22265772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
2233c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn        while (fgetLongTime(buffer, sizeof(buffer), fp)) {
2243c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn            ++count;
2253c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn        }
22665772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
2273c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn        pclose(fp);
22865772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
2293c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn    } while ((count < num) && --tries && (sleep(1), true));
23065772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
2313c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn    ASSERT_EQ(num, count);
2323c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn}
23365772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
2343c535de75e3da05e32e69dfcdd6a864dbdc451fdMark SalyzynTEST(logcat, tail_3) {
2353c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn    do_tail(3);
2363c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn}
23765772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
2383c535de75e3da05e32e69dfcdd6a864dbdc451fdMark SalyzynTEST(logcat, tail_10) {
2393c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn    do_tail(10);
24065772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn}
24165772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
24265772ca7d7b61b111e75fb0f66f43966f0794bbdMark SalyzynTEST(logcat, tail_100) {
2433c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn    do_tail(100);
24465772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn}
24565772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
24665772ca7d7b61b111e75fb0f66f43966f0794bbdMark SalyzynTEST(logcat, tail_1000) {
2473c535de75e3da05e32e69dfcdd6a864dbdc451fdMark Salyzyn    do_tail(1000);
24865772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn}
24965772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
250ef7c411ac384665fba6209f6b26d83932f9de576Mark SalyzynTEST(logcat, tail_time) {
251ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    FILE *fp;
252ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn
253ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    ASSERT_TRUE(NULL != (fp = popen("logcat -v long -b all -t 10 2>&1", "r")));
254ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn
2557545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn    char buffer[BIG_BUFFER];
256ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    char *last_timestamp = NULL;
257ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    char *first_timestamp = NULL;
258ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    int count = 0;
259ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn
260b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn    char *cp;
261b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn    while ((cp = fgetLongTime(buffer, sizeof(buffer), fp))) {
262b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        ++count;
263b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        if (!first_timestamp) {
264b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn            first_timestamp = strdup(cp);
265ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn        }
266b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        free(last_timestamp);
267b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        last_timestamp = strdup(cp);
268ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    }
269ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    pclose(fp);
270ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn
271ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    EXPECT_EQ(10, count);
272ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    EXPECT_TRUE(last_timestamp != NULL);
273ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    EXPECT_TRUE(first_timestamp != NULL);
274ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn
275ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    snprintf(buffer, sizeof(buffer), "logcat -v long -b all -t '%s' 2>&1",
276ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn             first_timestamp);
277ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    ASSERT_TRUE(NULL != (fp = popen(buffer, "r")));
278ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn
279ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    int second_count = 0;
280ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    int last_timestamp_count = -1;
281ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn
282b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn    while ((cp = fgetLongTime(buffer, sizeof(buffer), fp))) {
283b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        ++second_count;
284b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        if (first_timestamp) {
285b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn            // we can get a transitory *extremely* rare failure if hidden
286b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn            // underneath the time is *exactly* XX-XX XX:XX:XX.XXX000000
287b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn            EXPECT_STREQ(cp, first_timestamp);
288b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn            free(first_timestamp);
289b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn            first_timestamp = NULL;
290b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        }
291b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn        if (!strcmp(cp, last_timestamp)) {
292b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn            last_timestamp_count = second_count;
293ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn        }
294ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    }
295ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    pclose(fp);
296ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn
297ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    free(last_timestamp);
298ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    last_timestamp = NULL;
299b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn    free(first_timestamp);
300ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn
301ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    EXPECT_TRUE(first_timestamp == NULL);
302ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    EXPECT_LE(count, second_count);
303ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    EXPECT_LE(count, last_timestamp_count);
304ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn}
305ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn
30665772ca7d7b61b111e75fb0f66f43966f0794bbdMark SalyzynTEST(logcat, End_to_End) {
30765772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    pid_t pid = getpid();
30865772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
30965772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    log_time ts(CLOCK_MONOTONIC);
31065772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
31165772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
31265772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
31365772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    FILE *fp;
314ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    ASSERT_TRUE(NULL != (fp = popen(
315a5e2429f09295dd94b0ae2125e380cfb3b02ab04Mark Salyzyn      "logcat -v brief -b events -t 100 2>/dev/null",
31665772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn      "r")));
31765772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
3187545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn    char buffer[BIG_BUFFER];
31965772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
32065772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    int count = 0;
32165772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
32265772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    while (fgets(buffer, sizeof(buffer), fp)) {
32365772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn        int p;
32465772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn        unsigned long long t;
32565772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
32665772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn        if ((2 != sscanf(buffer, "I/[0]     ( %d): %llu", &p, &t))
32765772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn         || (p != pid)) {
32865772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn            continue;
32965772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn        }
33065772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
33165772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn        log_time tx((const char *) &t);
33265772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn        if (ts == tx) {
33365772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn            ++count;
33465772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn        }
33565772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    }
33665772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
33765772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    pclose(fp);
33865772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
33965772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    ASSERT_EQ(1, count);
34065772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn}
34165772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
3427545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzynint get_groups(const char *cmd) {
34365772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    FILE *fp;
34465772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
3459879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn    // NB: crash log only available in user space
3467545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn    EXPECT_TRUE(NULL != (fp = popen(cmd, "r")));
3477545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn
3487545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn    if (fp == NULL) {
3497545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn        return 0;
3507545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn    }
35165772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
3527545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn    char buffer[BIG_BUFFER];
35365772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
35465772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    int count = 0;
35565772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
35665772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    while (fgets(buffer, sizeof(buffer), fp)) {
35765772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn        int size, consumed, max, payload;
3589812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        char size_mult[3], consumed_mult[3];
3599879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn        long full_size, full_consumed;
36065772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
36165772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn        size = consumed = max = payload = 0;
3629879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn        // NB: crash log can be very small, not hit a Kb of consumed space
3639879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn        //     doubly lucky we are not including it.
364d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn        if (6 != sscanf(buffer, "%*s ring buffer is %d%2s (%d%2s consumed),"
3659879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn                                " max entry is %db, max payload is %db",
366d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn                                &size, size_mult, &consumed, consumed_mult,
3679879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn                                &max, &payload)) {
3689879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn            fprintf(stderr, "WARNING: Parse error: %s", buffer);
3699879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn            continue;
3709879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn        }
3719879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn        full_size = size;
372d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn        switch(size_mult[0]) {
3739879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn        case 'G':
3749879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn            full_size *= 1024;
3759879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn            /* FALLTHRU */
3769879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn        case 'M':
3779879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn            full_size *= 1024;
3789879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn            /* FALLTHRU */
3799879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn        case 'K':
3809879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn            full_size *= 1024;
381d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn            /* FALLTHRU */
382d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn        case 'b':
3839879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn            break;
3849879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn        }
3859879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn        full_consumed = consumed;
386d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn        switch(consumed_mult[0]) {
3879879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn        case 'G':
3889879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn            full_consumed *= 1024;
3899879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn            /* FALLTHRU */
3909879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn        case 'M':
3919879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn            full_consumed *= 1024;
3929879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn            /* FALLTHRU */
3939879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn        case 'K':
3949879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn            full_consumed *= 1024;
395d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn            /* FALLTHRU */
396d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn        case 'b':
3979879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn            break;
3989879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn        }
3999879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn        EXPECT_GT((full_size * 9) / 4, full_consumed);
4009879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn        EXPECT_GT(full_size, max);
4019879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn        EXPECT_GT(max, payload);
4029879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn
4039879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn        if ((((full_size * 9) / 4) >= full_consumed)
4049879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn         && (full_size > max)
40565772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn         && (max > payload)) {
40665772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn            ++count;
40765772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn        }
40865772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    }
40965772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
41065772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    pclose(fp);
41165772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
4127545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn    return count;
4137545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn}
4147545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn
4157545b471a223a4a222a24b8b1693cc4a69ee3833Mark SalyzynTEST(logcat, get_size) {
4167545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn    ASSERT_EQ(4, get_groups(
4177545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn      "logcat -v brief -b radio -b events -b system -b main -g 2>/dev/null"));
4187545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn}
4197545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn
4207545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn// duplicate test for get_size, but use comma-separated list of buffers
4217545b471a223a4a222a24b8b1693cc4a69ee3833Mark SalyzynTEST(logcat, multiple_buffer) {
4227545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn    ASSERT_EQ(4, get_groups(
4237545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn      "logcat -v brief -b radio,events,system,main -g 2>/dev/null"));
4247545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn}
4257545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn
4267545b471a223a4a222a24b8b1693cc4a69ee3833Mark SalyzynTEST(logcat, bad_buffer) {
4277545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn    ASSERT_EQ(0, get_groups(
4287545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn      "logcat -v brief -b radio,events,bogo,system,main -g 2>/dev/null"));
42965772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn}
43065772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
431b149e245c8ccd90b52227f3d07ab572080afac53Mark Salyzynstatic void caught_blocking(int /*signum*/)
43265772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn{
43365772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    unsigned long long v = 0xDEADBEEFA55A0000ULL;
43465772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
43565772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    v += getpid() & 0xFFFF;
43665772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
43765772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
43865772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn}
43965772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
44065772ca7d7b61b111e75fb0f66f43966f0794bbdMark SalyzynTEST(logcat, blocking) {
44165772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    FILE *fp;
4429b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    unsigned long long v = 0xDEADBEEFA55F0000ULL;
44365772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
44465772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    pid_t pid = getpid();
44565772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
44665772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    v += pid & 0xFFFF;
44765772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
4489b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
4499b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
4509b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    v &= 0xFFFFFFFFFFFAFFFFULL;
4519b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
452ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    ASSERT_TRUE(NULL != (fp = popen(
45365772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn      "( trap exit HUP QUIT INT PIPE KILL ; sleep 6; echo DONE )&"
454a5e2429f09295dd94b0ae2125e380cfb3b02ab04Mark Salyzyn      " logcat -v brief -b events 2>&1",
45565772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn      "r")));
45665772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
4577545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn    char buffer[BIG_BUFFER];
45865772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
45965772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    int count = 0;
46065772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
46165772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    int signals = 0;
46265772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
46365772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    signal(SIGALRM, caught_blocking);
46465772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    alarm(2);
46565772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    while (fgets(buffer, sizeof(buffer), fp)) {
46665772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
46765772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn        if (!strncmp(buffer, "DONE", 4)) {
46865772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn            break;
46965772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn        }
47065772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
4719b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn        ++count;
4729b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
47365772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn        int p;
47465772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn        unsigned long long l;
47565772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
47665772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn        if ((2 != sscanf(buffer, "I/[0] ( %u): %lld", &p, &l))
47765772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn         || (p != pid)) {
47865772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn            continue;
47965772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn        }
48065772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
48165772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn        if (l == v) {
48265772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn            ++signals;
48365772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn            break;
48465772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn        }
48565772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    }
48665772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    alarm(0);
48765772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    signal(SIGALRM, SIG_DFL);
48865772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
48965772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    // Generate SIGPIPE
49065772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    fclose(fp);
49165772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    caught_blocking(0);
49265772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
49365772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn    pclose(fp);
49465772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
495ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    EXPECT_LE(2, count);
49665772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn
497ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    EXPECT_EQ(1, signals);
49865772ca7d7b61b111e75fb0f66f43966f0794bbdMark Salyzyn}
4995d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn
500b149e245c8ccd90b52227f3d07ab572080afac53Mark Salyzynstatic void caught_blocking_tail(int /*signum*/)
5015d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn{
5025d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn    unsigned long long v = 0xA55ADEADBEEF0000ULL;
5035d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn
5045d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn    v += getpid() & 0xFFFF;
5055d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn
5065d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn    LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
5075d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn}
5085d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn
5095d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark SalyzynTEST(logcat, blocking_tail) {
5105d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn    FILE *fp;
5119b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    unsigned long long v = 0xA55FDEADBEEF0000ULL;
5125d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn
5135d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn    pid_t pid = getpid();
5145d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn
5155d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn    v += pid & 0xFFFF;
5165d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn
5179b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
5189b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
5199b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    v &= 0xFFFAFFFFFFFFFFFFULL;
5209b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
521ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    ASSERT_TRUE(NULL != (fp = popen(
5225d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn      "( trap exit HUP QUIT INT PIPE KILL ; sleep 6; echo DONE )&"
523a5e2429f09295dd94b0ae2125e380cfb3b02ab04Mark Salyzyn      " logcat -v brief -b events -T 5 2>&1",
5245d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn      "r")));
5255d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn
5267545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn    char buffer[BIG_BUFFER];
5275d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn
5285d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn    int count = 0;
5295d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn
5305d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn    int signals = 0;
5315d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn
5325d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn    signal(SIGALRM, caught_blocking_tail);
5335d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn    alarm(2);
5345d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn    while (fgets(buffer, sizeof(buffer), fp)) {
5355d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn
5365d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn        if (!strncmp(buffer, "DONE", 4)) {
5375d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn            break;
5385d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn        }
5395d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn
5409b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn        ++count;
5419b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
5425d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn        int p;
5435d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn        unsigned long long l;
5445d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn
5455d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn        if ((2 != sscanf(buffer, "I/[0] ( %u): %lld", &p, &l))
5465d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn         || (p != pid)) {
5475d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn            continue;
5485d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn        }
5495d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn
5505d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn        if (l == v) {
5515d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn            if (count >= 5) {
5525d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn                ++signals;
5535d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn            }
5545d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn            break;
5555d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn        }
5565d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn    }
5575d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn    alarm(0);
5585d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn    signal(SIGALRM, SIG_DFL);
5595d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn
5609b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    // Generate SIGPIPE
5615d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn    fclose(fp);
5625d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn    caught_blocking_tail(0);
5635d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn
5645d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn    pclose(fp);
5655d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn
566ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    EXPECT_LE(2, count);
5679b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
568ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    EXPECT_EQ(1, signals);
5699b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn}
5709b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
571d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark SalyzynTEST(logcat, logrotate) {
572d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn    static const char form[] = "/data/local/tmp/logcat.logrotate.XXXXXX";
573d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn    char buf[sizeof(form)];
574d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn    ASSERT_TRUE(NULL != mkdtemp(strcpy(buf, form)));
575d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn
576d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn    static const char comm[] = "logcat -b radio -b events -b system -b main"
577d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn                                     " -d -f %s/log.txt -n 7 -r 1";
578d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn    char command[sizeof(buf) + sizeof(comm)];
5799812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    snprintf(command, sizeof(command), comm, buf);
580d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn
581d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn    int ret;
582d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn    EXPECT_FALSE((ret = system(command)));
583d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn    if (!ret) {
5849812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        snprintf(command, sizeof(command), "ls -s %s 2>/dev/null", buf);
585d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn
586d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn        FILE *fp;
587d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn        EXPECT_TRUE(NULL != (fp = popen(command, "r")));
588d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn        if (fp) {
5897545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn            char buffer[BIG_BUFFER];
590d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn            int count = 0;
591d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn
592d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn            while (fgets(buffer, sizeof(buffer), fp)) {
593d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn                static const char total[] = "total ";
5949812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn                int num;
5959812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn                char c;
596d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn
5979812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn                if ((2 == sscanf(buffer, "%d log.tx%c", &num, &c)) &&
5988beb0d3ad7b00f47e655f126d619bfaa59334b30Mark Salyzyn                        (num <= 40)) {
599d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn                    ++count;
600d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn                } else if (strncmp(buffer, total, sizeof(total) - 1)) {
601d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn                    fprintf(stderr, "WARNING: Parse error: %s", buffer);
602d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn                }
603d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn            }
604d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn            pclose(fp);
605b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn            if ((count != 7) && (count != 8)) {
606b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn                fprintf(stderr, "count=%d\n", count);
607b6bee33182cedea49199eb2252b3f3b442899c6dMark Salyzyn            }
608d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn            EXPECT_TRUE(count == 7 || count == 8);
609d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn        }
610d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn    }
6119812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    snprintf(command, sizeof(command), "rm -rf %s", buf);
612d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn    EXPECT_FALSE(system(command));
613d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn}
614d03caa23ddd8670ccd83eaf4ef4fc0c78e065c1bMark Salyzyn
615eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis PapaioannouTEST(logcat, logrotate_suffix) {
616eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou    static const char tmp_out_dir_form[] = "/data/local/tmp/logcat.logrotate.XXXXXX";
617eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou    char tmp_out_dir[sizeof(tmp_out_dir_form)];
618eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou    ASSERT_TRUE(NULL != mkdtemp(strcpy(tmp_out_dir, tmp_out_dir_form)));
619eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou
620eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou    static const char logcat_cmd[] = "logcat -b radio -b events -b system -b main"
621eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou                                     " -d -f %s/log.txt -n 10 -r 1";
622eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou    char command[sizeof(tmp_out_dir) + sizeof(logcat_cmd)];
6239812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    snprintf(command, sizeof(command), logcat_cmd, tmp_out_dir);
624eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou
625eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou    int ret;
626eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou    EXPECT_FALSE((ret = system(command)));
627eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou    if (!ret) {
6289812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        snprintf(command, sizeof(command), "ls %s 2>/dev/null", tmp_out_dir);
629eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou
630eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou        FILE *fp;
631eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou        EXPECT_TRUE(NULL != (fp = popen(command, "r")));
6327545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn        char buffer[BIG_BUFFER];
633eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou        int log_file_count = 0;
634eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou
635eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou        while (fgets(buffer, sizeof(buffer), fp)) {
636eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou            static const char rotated_log_filename_prefix[] = "log.txt.";
637eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou            static const size_t rotated_log_filename_prefix_len =
638eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou                strlen(rotated_log_filename_prefix);
639eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou            static const char log_filename[] = "log.txt";
640eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou
641eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou            if (!strncmp(buffer, rotated_log_filename_prefix, rotated_log_filename_prefix_len)) {
642eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou              // Rotated file should have form log.txt.##
643eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou              char* rotated_log_filename_suffix = buffer + rotated_log_filename_prefix_len;
644eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou              char* endptr;
645eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou              const long int suffix_value = strtol(rotated_log_filename_suffix, &endptr, 10);
646eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou              EXPECT_EQ(rotated_log_filename_suffix + 2, endptr);
647eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou              EXPECT_LE(suffix_value, 10);
648eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou              EXPECT_GT(suffix_value, 0);
649eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou              ++log_file_count;
650eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou              continue;
651eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou            }
652eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou
653eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou            if (!strncmp(buffer, log_filename, strlen(log_filename))) {
654eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou              ++log_file_count;
655eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou              continue;
656eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou            }
657eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou
658eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou            fprintf(stderr, "ERROR: Unexpected file: %s", buffer);
659eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou            ADD_FAILURE();
660eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou        }
661eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou        pclose(fp);
662eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou        EXPECT_EQ(11, log_file_count);
663eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou    }
6649812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    snprintf(command, sizeof(command), "rm -rf %s", tmp_out_dir);
6659812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    EXPECT_FALSE(system(command));
6669812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn}
6679812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn
6689812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark SalyzynTEST(logcat, logrotate_continue) {
6699812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    static const char tmp_out_dir_form[] = "/data/local/tmp/logcat.logrotate.XXXXXX";
6709812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    char tmp_out_dir[sizeof(tmp_out_dir_form)];
6719812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    ASSERT_TRUE(NULL != mkdtemp(strcpy(tmp_out_dir, tmp_out_dir_form)));
6729812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn
6739812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    static const char log_filename[] = "log.txt";
6749812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    static const char logcat_cmd[] = "logcat -b all -d -f %s/%s -n 256 -r 1024";
6759812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    static const char cleanup_cmd[] = "rm -rf %s";
6769812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    char command[sizeof(tmp_out_dir) + sizeof(logcat_cmd) + sizeof(log_filename)];
6779812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    snprintf(command, sizeof(command), logcat_cmd, tmp_out_dir, log_filename);
6789812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn
6799812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    int ret;
6809812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    EXPECT_FALSE((ret = system(command)));
6819812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    if (ret) {
6829812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
6839812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        EXPECT_FALSE(system(command));
6849812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        return;
6859812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    }
6869812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    FILE *fp;
6879812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    snprintf(command, sizeof(command), "%s/%s", tmp_out_dir, log_filename);
6889812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    EXPECT_TRUE(NULL != ((fp = fopen(command, "r"))));
6899812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    if (!fp) {
6909812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
6919812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        EXPECT_FALSE(system(command));
6929812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        return;
6939812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    }
6949812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    char *line = NULL;
6959812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    char *last_line = NULL; // this line is allowed to stutter, one-line overlap
6969812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    char *second_last_line = NULL;
6979812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    size_t len = 0;
6989812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    while (getline(&line, &len, fp) != -1) {
6999812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        free(second_last_line);
7009812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        second_last_line = last_line;
7019812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        last_line = line;
7029812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        line = NULL;
7039812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    }
7049812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    fclose(fp);
7059812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    free(line);
7069812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    if (second_last_line == NULL) {
7079812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        fprintf(stderr, "No second to last line, using last, test may fail\n");
7089812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        second_last_line = last_line;
7099812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        last_line = NULL;
7109812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    }
7119812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    free(last_line);
7129812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    EXPECT_TRUE(NULL != second_last_line);
7139812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    if (!second_last_line) {
7149812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
7159812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        EXPECT_FALSE(system(command));
7169812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        return;
7179812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    }
7189812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    // re-run the command, it should only add a few lines more content if it
7199812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    // continues where it left off.
7209812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    snprintf(command, sizeof(command), logcat_cmd, tmp_out_dir, log_filename);
7219812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    EXPECT_FALSE((ret = system(command)));
7229812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    if (ret) {
7239812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
7249812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        EXPECT_FALSE(system(command));
7259812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        return;
7269812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    }
7279812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    DIR *dir;
7289812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    EXPECT_TRUE(NULL != (dir = opendir(tmp_out_dir)));
7299812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    if (!dir) {
7309812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
7319812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        EXPECT_FALSE(system(command));
7329812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        return;
7339812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    }
7349812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    struct dirent *entry;
7359812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    unsigned count = 0;
7369812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    while ((entry = readdir(dir))) {
7379812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        if (strncmp(entry->d_name, log_filename, sizeof(log_filename) - 1)) {
7389812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn            continue;
7399812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        }
7409812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        snprintf(command, sizeof(command), "%s/%s", tmp_out_dir, entry->d_name);
7419812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        EXPECT_TRUE(NULL != ((fp = fopen(command, "r"))));
7429812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        if (!fp) {
7439812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn            fprintf(stderr, "%s ?\n", command);
7449812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn            continue;
7459812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        }
7469812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        line = NULL;
7479812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        size_t number = 0;
7489812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        while (getline(&line, &len, fp) != -1) {
7499812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn            ++number;
7509812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn            if (!strcmp(line, second_last_line)) {
7519812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn                EXPECT_TRUE(++count <= 1);
7529812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn                fprintf(stderr, "%s(%zu):\n", entry->d_name, number);
7539812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn            }
7549812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        }
7559812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        fclose(fp);
7569812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        free(line);
7579812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        unlink(command);
7589812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    }
7599812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    closedir(dir);
7609812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    if (count > 1) {
7619812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        char *brk = strpbrk(second_last_line, "\r\n");
7629812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        if (!brk) {
7639812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn            brk = second_last_line + strlen(second_last_line);
7649812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        }
7659812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn        fprintf(stderr, "\"%.*s\" occured %u times\n",
7669812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn            (int)(brk - second_last_line), second_last_line, count);
7679812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    }
7689812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    free(second_last_line);
7699812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn
7709812fc4bd0b92baeb8f1cad6abdc440512e3cf40Mark Salyzyn    snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
771c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn    EXPECT_FALSE(system(command));
772c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn}
773c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn
774c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark SalyzynTEST(logcat, logrotate_clear) {
775c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn    static const char tmp_out_dir_form[] = "/data/local/tmp/logcat.logrotate.XXXXXX";
776c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn    char tmp_out_dir[sizeof(tmp_out_dir_form)];
777c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn    ASSERT_TRUE(NULL != mkdtemp(strcpy(tmp_out_dir, tmp_out_dir_form)));
778c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn
779c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn    static const char log_filename[] = "log.txt";
780c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn    static const unsigned num_val = 32;
781c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn    static const char logcat_cmd[] = "logcat -b all -d -f %s/%s -n %d -r 1";
782c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn    static const char clear_cmd[] = " -c";
783c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn    static const char cleanup_cmd[] = "rm -rf %s";
784c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn    char command[sizeof(tmp_out_dir) + sizeof(logcat_cmd) + sizeof(log_filename) + sizeof(clear_cmd) + 32];
785c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn
786c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn    // Run command with all data
787c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn    {
788c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        snprintf(command, sizeof(command) - sizeof(clear_cmd),
789c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn                 logcat_cmd, tmp_out_dir, log_filename, num_val);
790c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn
791c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        int ret;
792c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        EXPECT_FALSE((ret = system(command)));
793c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        if (ret) {
794c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn            snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
795c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn            EXPECT_FALSE(system(command));
796c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn            return;
797c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        }
798c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(tmp_out_dir), closedir);
799c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        EXPECT_NE(nullptr, dir);
800c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        if (!dir) {
801c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn            snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
802c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn            EXPECT_FALSE(system(command));
803c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn            return;
804c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        }
805c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        struct dirent *entry;
806c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        unsigned count = 0;
807c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        while ((entry = readdir(dir.get()))) {
808c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn            if (strncmp(entry->d_name, log_filename, sizeof(log_filename) - 1)) {
809c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn                continue;
810c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn            }
811c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn            ++count;
812c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        }
813c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        EXPECT_EQ(count, num_val + 1);
814c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn    }
815c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn
816c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn    {
817c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        // Now with -c option tacked onto the end
818c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        strcat(command, clear_cmd);
819c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn
820c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        int ret;
821c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        EXPECT_FALSE((ret = system(command)));
822c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        if (ret) {
823c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn            snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
824c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn            EXPECT_FALSE(system(command));
825c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn            return;
826c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        }
827c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(tmp_out_dir), closedir);
828c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        EXPECT_NE(nullptr, dir);
829c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        if (!dir) {
830c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn            snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
831c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn            EXPECT_FALSE(system(command));
832c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn            return;
833c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        }
834c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        struct dirent *entry;
835c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        unsigned count = 0;
836c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        while ((entry = readdir(dir.get()))) {
837c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn            if (strncmp(entry->d_name, log_filename, sizeof(log_filename) - 1)) {
838c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn                continue;
839c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn            }
840c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn            fprintf(stderr, "Found %s/%s!!!\n", tmp_out_dir, entry->d_name);
841c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn            ++count;
842c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        }
843c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn        EXPECT_EQ(count, 0U);
844c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn    }
845c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn
846c869959d6266a07591653b6c9e8ea0c173c3b0c8Mark Salyzyn    snprintf(command, sizeof(command), cleanup_cmd, tmp_out_dir);
847eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou    EXPECT_FALSE(system(command));
848eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou}
849eba7344fc1aca4ae232b881fdf6c5b16e6f59bc9Aristidis Papaioannou
8501ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark SalyzynTEST(logcat, logrotate_nodir) {
8511ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn    // expect logcat to error out on writing content and exit(1) for nodir
8521ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn    EXPECT_EQ(W_EXITCODE(1, 0),
8531ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn              system("logcat -b all -d"
8541ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn                     " -f /das/nein/gerfingerpoken/logcat/log.txt"
8551ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn                     " -n 256 -r 1024"));
8561ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn}
8571ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzyn
8581ab87e7712cea615ecdf70e65d74d14d3fd8fa85Mark Salyzynstatic void caught_blocking_clear(int /*signum*/) {
8599b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    unsigned long long v = 0xDEADBEEFA55C0000ULL;
8609b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
8619b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    v += getpid() & 0xFFFF;
8629b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
8639b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
8649b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn}
8659b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
8669b986497e7f19a7fde9e35eb73d765f4a09dee07Mark SalyzynTEST(logcat, blocking_clear) {
8679b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    FILE *fp;
8689b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    unsigned long long v = 0xDEADBEEFA55C0000ULL;
8699b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
8709b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    pid_t pid = getpid();
8719b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
8729b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    v += pid & 0xFFFF;
8739b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
8749b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    // This test is racey; an event occurs between clear and dump.
8759b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    // We accept that we will get a false positive, but never a false negative.
876ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    ASSERT_TRUE(NULL != (fp = popen(
8779b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn      "( trap exit HUP QUIT INT PIPE KILL ; sleep 6; echo DONE )&"
8789b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn      " logcat -b events -c 2>&1 ;"
879a5e2429f09295dd94b0ae2125e380cfb3b02ab04Mark Salyzyn      " logcat -v brief -b events 2>&1",
8809b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn      "r")));
8819b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
8827545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn    char buffer[BIG_BUFFER];
8839b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
8849b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    int count = 0;
8859b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
8869b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    int signals = 0;
8879b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
8889b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    signal(SIGALRM, caught_blocking_clear);
8899b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    alarm(2);
8909b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    while (fgets(buffer, sizeof(buffer), fp)) {
8919b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
8929b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn        if (!strncmp(buffer, "clearLog: ", 10)) {
8939b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn            fprintf(stderr, "WARNING: Test lacks permission to run :-(\n");
8949b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn            count = signals = 1;
8959b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn            break;
8969b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn        }
8979b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
8989b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn        if (!strncmp(buffer, "DONE", 4)) {
8999b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn            break;
9009b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn        }
9019b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
9029b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn        ++count;
9039b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
9049b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn        int p;
9059b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn        unsigned long long l;
9069b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
9079b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn        if ((2 != sscanf(buffer, "I/[0] ( %u): %lld", &p, &l))
9089b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn         || (p != pid)) {
9099b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn            continue;
9109b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn        }
9119b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
9129b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn        if (l == v) {
9139b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn            if (count > 1) {
9149b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn                fprintf(stderr, "WARNING: Possible false positive\n");
9159b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn            }
9169b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn            ++signals;
9179b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn            break;
9189b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn        }
9199b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    }
9209b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    alarm(0);
9219b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    signal(SIGALRM, SIG_DFL);
9229b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
9239b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    // Generate SIGPIPE
9249b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    fclose(fp);
9259b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    caught_blocking_clear(0);
9269b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
9279b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn    pclose(fp);
9289b986497e7f19a7fde9e35eb73d765f4a09dee07Mark Salyzyn
929ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    EXPECT_LE(1, count);
9305d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn
931ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    EXPECT_EQ(1, signals);
9325d3d1f17dbcb01aedd510b5435ebdaf1d6afc138Mark Salyzyn}
93395cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn
93495cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzynstatic bool get_white_black(char **list) {
93595cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    FILE *fp;
93695cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn
93795cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    fp = popen("logcat -p 2>/dev/null", "r");
93895cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    if (fp == NULL) {
93995cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        fprintf(stderr, "ERROR: logcat -p 2>/dev/null\n");
94095cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        return false;
94195cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    }
94295cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn
9437545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn    char buffer[BIG_BUFFER];
94495cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn
94595cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    while (fgets(buffer, sizeof(buffer), fp)) {
94695cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        char *hold = *list;
94795cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        char *buf = buffer;
94895cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn	while (isspace(*buf)) {
94995cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn            ++buf;
95095cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        }
95195cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        char *end = buf + strlen(buf);
95295cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        while (isspace(*--end) && (end >= buf)) {
95395cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn            *end = '\0';
95495cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        }
95595cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        if (end < buf) {
95695cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn            continue;
95795cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        }
95895cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        if (hold) {
95995cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn            asprintf(list, "%s %s", hold, buf);
96095cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn            free(hold);
96195cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        } else {
96295cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn            asprintf(list, "%s", buf);
96395cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        }
96495cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    }
96595cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    pclose(fp);
96695cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    return *list != NULL;
96795cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn}
96895cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn
96995cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzynstatic bool set_white_black(const char *list) {
97095cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    FILE *fp;
97195cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn
9727545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn    char buffer[BIG_BUFFER];
97395cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn
9749879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn    snprintf(buffer, sizeof(buffer), "logcat -P '%s' 2>&1", list ? list : "");
97595cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    fp = popen(buffer, "r");
97695cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    if (fp == NULL) {
97795cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        fprintf(stderr, "ERROR: %s\n", buffer);
97895cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        return false;
97995cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    }
98095cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn
98195cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    while (fgets(buffer, sizeof(buffer), fp)) {
98295cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        char *buf = buffer;
98395cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn	while (isspace(*buf)) {
98495cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn            ++buf;
98595cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        }
98695cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        char *end = buf + strlen(buf);
9879879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn        while ((end > buf) && isspace(*--end)) {
98895cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn            *end = '\0';
98995cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        }
9909879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn        if (end <= buf) {
99195cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn            continue;
99295cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        }
99395cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        fprintf(stderr, "%s\n", buf);
99495cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        pclose(fp);
99595cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn        return false;
99695cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    }
99795cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    return pclose(fp) == 0;
99895cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn}
99995cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn
100095cfc7b8e2e6e5c6cdc97989563e49208915a583Mark SalyzynTEST(logcat, white_black_adjust) {
100195cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    char *list = NULL;
100295cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    char *adjust = NULL;
100395cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn
10049879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn    get_white_black(&list);
100595cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn
100622e287df0dfbc6e10c02f570d2fc0c42a2a6b7aaMark Salyzyn    static const char adjustment[] = "~! 300/20 300/25 2000 ~1000/5 ~1000/30";
100795cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    ASSERT_EQ(true, set_white_black(adjustment));
100895cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    ASSERT_EQ(true, get_white_black(&adjust));
1009ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    EXPECT_STREQ(adjustment, adjust);
101095cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    free(adjust);
101195cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    adjust = NULL;
101295cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn
101322e287df0dfbc6e10c02f570d2fc0c42a2a6b7aaMark Salyzyn    static const char adjustment2[] = "300/20 300/21 2000 ~1000";
101422e287df0dfbc6e10c02f570d2fc0c42a2a6b7aaMark Salyzyn    ASSERT_EQ(true, set_white_black(adjustment2));
101522e287df0dfbc6e10c02f570d2fc0c42a2a6b7aaMark Salyzyn    ASSERT_EQ(true, get_white_black(&adjust));
1016ef7c411ac384665fba6209f6b26d83932f9de576Mark Salyzyn    EXPECT_STREQ(adjustment2, adjust);
101722e287df0dfbc6e10c02f570d2fc0c42a2a6b7aaMark Salyzyn    free(adjust);
101822e287df0dfbc6e10c02f570d2fc0c42a2a6b7aaMark Salyzyn    adjust = NULL;
101922e287df0dfbc6e10c02f570d2fc0c42a2a6b7aaMark Salyzyn
102095cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    ASSERT_EQ(true, set_white_black(list));
10219879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn    get_white_black(&adjust);
10229879ac8e1290d744fc4363e6a976516053d5f64dMark Salyzyn    EXPECT_STREQ(list ? list : "", adjust ? adjust : "");
102395cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    free(adjust);
102495cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    adjust = NULL;
102595cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn
102695cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    free(list);
102795cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn    list = NULL;
102895cfc7b8e2e6e5c6cdc97989563e49208915a583Mark Salyzyn}
10290f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin
10300f7732d70810cd66cd2c69a40311785d67044c2cCasey DahlinTEST(logcat, regex) {
10310f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin    FILE *fp;
10320f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin    int count = 0;
10330f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin
10347545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn    char buffer[BIG_BUFFER];
10350f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin
10360f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin    snprintf(buffer, sizeof(buffer), "logcat --pid %d -d -e logcat_test_a+b", getpid());
10370f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin
10380f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin    LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_WARN, "logcat_test", "logcat_test_ab"));
10390f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin    LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_WARN, "logcat_test", "logcat_test_b"));
10400f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin    LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_WARN, "logcat_test", "logcat_test_aaaab"));
10410f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin    LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_WARN, "logcat_test", "logcat_test_aaaa"));
10420f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin
10430f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin    // Let the logs settle
10440f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin    sleep(1);
10450f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin
10460f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin    ASSERT_TRUE(NULL != (fp = popen(buffer, "r")));
10470f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin
10480f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin    while (fgets(buffer, sizeof(buffer), fp)) {
10490f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin        if (!strncmp(begin, buffer, sizeof(begin) - 1)) {
10500f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin            continue;
10510f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin        }
10520f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin
10530f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin        EXPECT_TRUE(strstr(buffer, "logcat_test_") != NULL);
10540f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin
10550f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin        count++;
10560f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin    }
10570f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin
10580f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin    pclose(fp);
10590f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin
10600f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin    ASSERT_EQ(2, count);
10610f7732d70810cd66cd2c69a40311785d67044c2cCasey Dahlin}
10621164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin
10631164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey DahlinTEST(logcat, maxcount) {
10641164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin    FILE *fp;
10651164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin    int count = 0;
10661164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin
10677545b471a223a4a222a24b8b1693cc4a69ee3833Mark Salyzyn    char buffer[BIG_BUFFER];
10681164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin
10691164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin    snprintf(buffer, sizeof(buffer), "logcat --pid %d -d --max-count 3", getpid());
10701164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin
10711164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin    LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_WARN, "logcat_test", "logcat_test"));
10721164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin    LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_WARN, "logcat_test", "logcat_test"));
10731164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin    LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_WARN, "logcat_test", "logcat_test"));
10741164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin    LOG_FAILURE_RETRY(__android_log_print(ANDROID_LOG_WARN, "logcat_test", "logcat_test"));
10751164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin
10761164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin    // Let the logs settle
10771164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin    sleep(1);
10781164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin
10791164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin    ASSERT_TRUE(NULL != (fp = popen(buffer, "r")));
10801164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin
10811164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin    while (fgets(buffer, sizeof(buffer), fp)) {
10821164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin        if (!strncmp(begin, buffer, sizeof(begin) - 1)) {
10831164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin            continue;
10841164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin        }
10851164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin
10861164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin        count++;
10871164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin    }
10881164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin
10891164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin    pclose(fp);
10901164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin
10911164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin    ASSERT_EQ(3, count);
10921164ef6a73b6ec4a1057027a3cb60e2b0b9c2c34Casey Dahlin}
1093