blob: ed34ea413ccb3d2187d94c9152b10a43efb5f4f1 [file] [log] [blame]
Mark Salyzynd3ba6652014-02-28 13:44:12 -08001/*
2 * Copyright (C) 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 Salyzynd392ac12017-04-27 14:46:31 -070017#include <ctype.h>
Mark Salyzynd3ba6652014-02-28 13:44:12 -080018#include <fcntl.h>
Mark Salyzynef4e4f32016-01-21 10:59:25 -080019#include <inttypes.h>
Mark Salyzyn696817d2014-04-18 14:49:28 -070020#include <poll.h>
Mark Salyzynd3ba6652014-02-28 13:44:12 -080021#include <signal.h>
22#include <stdio.h>
23#include <string.h>
Mark Salyzyn247d6822017-01-03 14:00:19 -080024#include <sys/stat.h>
Mark Salyzyn501c3732017-03-10 14:31:54 -080025#include <sys/types.h>
Mark Salyzyn247d6822017-01-03 14:00:19 -080026#include <unistd.h>
Mark Salyzynd3ba6652014-02-28 13:44:12 -080027
Mark Salyzynef4e4f32016-01-21 10:59:25 -080028#include <string>
29
Mark Salyzynd392ac12017-04-27 14:46:31 -070030#include <android-base/file.h>
Mark Salyzync8d31942016-11-03 10:29:23 -070031#include <android-base/macros.h>
Mark Salyzynef4e4f32016-01-21 10:59:25 -080032#include <android-base/stringprintf.h>
33#include <cutils/sockets.h>
Mark Salyzyn0dd44312016-09-28 15:54:45 -070034#include <gtest/gtest.h>
Tom Cherryc5c6d7d2020-04-17 09:38:55 -070035#include <log/log_read.h>
Mark Salyzyn247d6822017-01-03 14:00:19 -080036#include <private/android_filesystem_config.h>
Mark Salyzync51ecf92017-05-04 10:25:13 -070037#include <private/android_logger.h>
Mark Salyzyn247d6822017-01-03 14:00:19 -080038#ifdef __ANDROID__
39#include <selinux/selinux.h>
40#endif
Mark Salyzynd3ba6652014-02-28 13:44:12 -080041
Tom Cherry43f3f762020-05-14 22:28:09 -070042#include "LogReader.h" // pickup LOGD_SNDTIMEO
Mark Salyzyn5c77ad52016-02-23 08:55:43 -080043
Mark Salyzyn2bd06f22016-12-27 13:30:03 -080044#ifdef __ANDROID__
Mark Salyzyn501c3732017-03-10 14:31:54 -080045static void send_to_control(char* buf, size_t len) {
46 int sock = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED,
Mark Salyzynd3ba6652014-02-28 13:44:12 -080047 SOCK_STREAM);
48 if (sock >= 0) {
49 if (write(sock, buf, strlen(buf) + 1) > 0) {
Mark Salyzyn696817d2014-04-18 14:49:28 -070050 ssize_t ret;
51 while ((ret = read(sock, buf, len)) > 0) {
Mark Salyzync9e5f372016-09-21 09:24:13 -070052 if (((size_t)ret == len) || (len < PAGE_SIZE)) {
Mark Salyzyn696817d2014-04-18 14:49:28 -070053 break;
54 }
55 len -= ret;
56 buf += ret;
57
Mark Salyzyn501c3732017-03-10 14:31:54 -080058 struct pollfd p = {.fd = sock, .events = POLLIN, .revents = 0 };
Mark Salyzyn696817d2014-04-18 14:49:28 -070059
60 ret = poll(&p, 1, 20);
61 if ((ret <= 0) || !(p.revents & POLLIN)) {
62 break;
63 }
64 }
Mark Salyzynd3ba6652014-02-28 13:44:12 -080065 }
66 close(sock);
67 }
68}
69
Mark Salyzyn61e9ce62016-09-12 14:51:54 -070070/*
71 * returns statistics
72 */
Mark Salyzyn501c3732017-03-10 14:31:54 -080073static void my_android_logger_get_statistics(char* buf, size_t len) {
Mark Salyzyn61e9ce62016-09-12 14:51:54 -070074 snprintf(buf, len, "getStatistics 0 1 2 3 4");
75 send_to_control(buf, len);
76}
77
Mark Salyzyn501c3732017-03-10 14:31:54 -080078static void alloc_statistics(char** buffer, size_t* length) {
Mark Salyzynd3ba6652014-02-28 13:44:12 -080079 size_t len = 8192;
Mark Salyzyn501c3732017-03-10 14:31:54 -080080 char* buf;
Mark Salyzynd3ba6652014-02-28 13:44:12 -080081
Mark Salyzyn501c3732017-03-10 14:31:54 -080082 for (int retry = 32; (retry >= 0); delete[] buf, --retry) {
83 buf = new char[len];
Mark Salyzynd3ba6652014-02-28 13:44:12 -080084 my_android_logger_get_statistics(buf, len);
85
Mark Salyzyn501c3732017-03-10 14:31:54 -080086 buf[len - 1] = '\0';
Mark Salyzynd3ba6652014-02-28 13:44:12 -080087 size_t ret = atol(buf) + 1;
88 if (ret < 4) {
Mark Salyzyn501c3732017-03-10 14:31:54 -080089 delete[] buf;
Mark Salyzynd392ac12017-04-27 14:46:31 -070090 buf = nullptr;
Mark Salyzynd3ba6652014-02-28 13:44:12 -080091 break;
92 }
93 bool check = ret <= len;
94 len = ret;
95 if (check) {
96 break;
97 }
Mark Salyzyn501c3732017-03-10 14:31:54 -080098 len += len / 8; // allow for some slop
Mark Salyzynd3ba6652014-02-28 13:44:12 -080099 }
100 *buffer = buf;
101 *length = len;
102}
103
Mark Salyzyn501c3732017-03-10 14:31:54 -0800104static char* find_benchmark_spam(char* cp) {
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800105 // liblog_benchmarks has been run designed to SPAM. The signature of
Mark Salyzyn62d6a2a2015-05-26 11:00:45 -0700106 // a noisiest UID statistics is:
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800107 //
Mark Salyzyn62d6a2a2015-05-26 11:00:45 -0700108 // Chattiest UIDs in main log buffer: Size Pruned
109 // UID PACKAGE BYTES LINES
110 // 0 root 54164 147569
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800111 //
Mark Salyzynd392ac12017-04-27 14:46:31 -0700112 char* benchmark = nullptr;
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800113 do {
Mark Salyzyn62d6a2a2015-05-26 11:00:45 -0700114 static const char signature[] = "\n0 root ";
115
116 benchmark = strstr(cp, signature);
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800117 if (!benchmark) {
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800118 break;
119 }
Mark Salyzyn62d6a2a2015-05-26 11:00:45 -0700120 cp = benchmark + sizeof(signature);
121 while (isspace(*cp)) {
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800122 ++cp;
123 }
Mark Salyzyn62d6a2a2015-05-26 11:00:45 -0700124 benchmark = cp;
Mark Salyzynf33657d2015-12-01 11:13:20 -0800125#ifdef DEBUG
Mark Salyzyn501c3732017-03-10 14:31:54 -0800126 char* end = strstr(benchmark, "\n");
Mark Salyzynd392ac12017-04-27 14:46:31 -0700127 if (end == nullptr) {
Mark Salyzynf33657d2015-12-01 11:13:20 -0800128 end = benchmark + strlen(benchmark);
129 }
130 fprintf(stderr, "parse for spam counter in \"%.*s\"\n",
131 (int)(end - benchmark), benchmark);
132#endif
133 // content
Mark Salyzyn62d6a2a2015-05-26 11:00:45 -0700134 while (isdigit(*cp)) {
135 ++cp;
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800136 }
Mark Salyzyn62d6a2a2015-05-26 11:00:45 -0700137 while (isspace(*cp)) {
138 ++cp;
139 }
Mark Salyzynf33657d2015-12-01 11:13:20 -0800140 // optional +/- field?
141 if ((*cp == '-') || (*cp == '+')) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800142 while (isdigit(*++cp) || (*cp == '.') || (*cp == '%') ||
143 (*cp == 'X')) {
Mark Salyzynf33657d2015-12-01 11:13:20 -0800144 ;
145 }
146 while (isspace(*cp)) {
147 ++cp;
148 }
149 }
150 // number of entries pruned
Mark Salyzyn62d6a2a2015-05-26 11:00:45 -0700151 unsigned long value = 0;
152 while (isdigit(*cp)) {
153 value = value * 10ULL + *cp - '0';
154 ++cp;
155 }
Mark Salyzynf33657d2015-12-01 11:13:20 -0800156 if (value > 10UL) {
Mark Salyzyn62d6a2a2015-05-26 11:00:45 -0700157 break;
158 }
Mark Salyzynd392ac12017-04-27 14:46:31 -0700159 benchmark = nullptr;
Mark Salyzyn62d6a2a2015-05-26 11:00:45 -0700160 } while (*cp);
161 return benchmark;
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800162}
Mark Salyzyn2bd06f22016-12-27 13:30:03 -0800163#endif
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800164
165TEST(logd, statistics) {
Mark Salyzyn2bd06f22016-12-27 13:30:03 -0800166#ifdef __ANDROID__
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800167 size_t len;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800168 char* buf;
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800169
Mark Salyzynd392ac12017-04-27 14:46:31 -0700170 // Drop cache so that any access problems can be discovered.
171 if (!android::base::WriteStringToFile("3\n", "/proc/sys/vm/drop_caches")) {
172 GTEST_LOG_(INFO) << "Could not open trigger dropping inode cache";
173 }
174
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800175 alloc_statistics(&buf, &len);
176
Mark Salyzynd392ac12017-04-27 14:46:31 -0700177 ASSERT_TRUE(nullptr != buf);
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800178
179 // remove trailing FF
Mark Salyzyn501c3732017-03-10 14:31:54 -0800180 char* cp = buf + len - 1;
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800181 *cp = '\0';
182 bool truncated = *--cp != '\f';
183 if (!truncated) {
184 *cp = '\0';
185 }
186
187 // squash out the byte count
188 cp = buf;
189 if (!truncated) {
190 while (isdigit(*cp) || (*cp == '\n')) {
191 ++cp;
192 }
193 }
194
195 fprintf(stderr, "%s", cp);
196
197 EXPECT_LT((size_t)64, strlen(cp));
198
199 EXPECT_EQ(0, truncated);
200
Mark Salyzyn501c3732017-03-10 14:31:54 -0800201 char* main_logs = strstr(cp, "\nChattiest UIDs in main ");
Mark Salyzynd392ac12017-04-27 14:46:31 -0700202 EXPECT_TRUE(nullptr != main_logs);
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800203
Mark Salyzyn501c3732017-03-10 14:31:54 -0800204 char* radio_logs = strstr(cp, "\nChattiest UIDs in radio ");
205 if (!radio_logs)
Mark Salyzynd392ac12017-04-27 14:46:31 -0700206 GTEST_LOG_(INFO) << "Value of: nullptr != radio_logs\n"
Mark Salyzyn501c3732017-03-10 14:31:54 -0800207 "Actual: false\n"
208 "Expected: false\n";
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800209
Mark Salyzyn501c3732017-03-10 14:31:54 -0800210 char* system_logs = strstr(cp, "\nChattiest UIDs in system ");
Mark Salyzynd392ac12017-04-27 14:46:31 -0700211 EXPECT_TRUE(nullptr != system_logs);
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800212
Mark Salyzyn501c3732017-03-10 14:31:54 -0800213 char* events_logs = strstr(cp, "\nChattiest UIDs in events ");
Mark Salyzynd392ac12017-04-27 14:46:31 -0700214 EXPECT_TRUE(nullptr != events_logs);
215
216 // Check if there is any " u0_a#### " as this means packagelistparser broken
217 char* used_getpwuid = nullptr;
218 int used_getpwuid_len;
219 char* uid_name = cp;
220 static const char getpwuid_prefix[] = " u0_a";
221 while ((uid_name = strstr(uid_name, getpwuid_prefix)) != nullptr) {
222 used_getpwuid = uid_name + 1;
223 uid_name += strlen(getpwuid_prefix);
224 while (isdigit(*uid_name)) ++uid_name;
225 used_getpwuid_len = uid_name - used_getpwuid;
226 if (isspace(*uid_name)) break;
227 used_getpwuid = nullptr;
228 }
229 EXPECT_TRUE(nullptr == used_getpwuid);
230 if (used_getpwuid) {
231 fprintf(stderr, "libpackagelistparser failed to pick up %.*s\n",
232 used_getpwuid_len, used_getpwuid);
233 }
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800234
Mark Salyzyn501c3732017-03-10 14:31:54 -0800235 delete[] buf;
Mark Salyzyn2bd06f22016-12-27 13:30:03 -0800236#else
237 GTEST_LOG_(INFO) << "This test does nothing.\n";
238#endif
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800239}
240
Mark Salyzyn2bd06f22016-12-27 13:30:03 -0800241#ifdef __ANDROID__
Mark Salyzyn501c3732017-03-10 14:31:54 -0800242static void caught_signal(int /* signum */) {
243}
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800244
Tom Cherry441054a2019-10-15 16:53:11 -0700245static void dump_log_msg(const char* prefix, log_msg* msg, int lid) {
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800246 std::cout << std::flush;
247 std::cerr << std::flush;
248 fflush(stdout);
249 fflush(stderr);
Tom Cherryd3ecc662020-04-09 14:53:55 -0700250 EXPECT_GE(msg->entry.hdr_size, sizeof(logger_entry));
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800251
Tom Cherry441054a2019-10-15 16:53:11 -0700252 fprintf(stderr, "%s: [%u] ", prefix, msg->len());
253 fprintf(stderr, "hdr_size=%u ", msg->entry.hdr_size);
254 fprintf(stderr, "pid=%u tid=%u %u.%09u ", msg->entry.pid, msg->entry.tid, msg->entry.sec,
255 msg->entry.nsec);
256 lid = msg->entry.lid;
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800257
Mark Salyzyn501c3732017-03-10 14:31:54 -0800258 switch (lid) {
259 case 0:
260 fprintf(stderr, "lid=main ");
261 break;
262 case 1:
263 fprintf(stderr, "lid=radio ");
264 break;
265 case 2:
266 fprintf(stderr, "lid=events ");
267 break;
268 case 3:
269 fprintf(stderr, "lid=system ");
270 break;
271 case 4:
272 fprintf(stderr, "lid=crash ");
273 break;
274 case 5:
275 fprintf(stderr, "lid=security ");
276 break;
277 case 6:
278 fprintf(stderr, "lid=kernel ");
279 break;
280 default:
281 if (lid >= 0) {
282 fprintf(stderr, "lid=%d ", lid);
283 }
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800284 }
285
286 unsigned int len = msg->entry.len;
287 fprintf(stderr, "msg[%u]={", len);
Mark Salyzyn501c3732017-03-10 14:31:54 -0800288 unsigned char* cp = reinterpret_cast<unsigned char*>(msg->msg());
Mark Salyzyn305374c2016-08-18 14:59:41 -0700289 if (!cp) {
290 static const unsigned char garbage[] = "<INVALID>";
Mark Salyzyn501c3732017-03-10 14:31:54 -0800291 cp = const_cast<unsigned char*>(garbage);
292 len = strlen(reinterpret_cast<const char*>(garbage));
Mark Salyzyn305374c2016-08-18 14:59:41 -0700293 }
Mark Salyzyn501c3732017-03-10 14:31:54 -0800294 while (len) {
295 unsigned char* p = cp;
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800296 while (*p && (((' ' <= *p) && (*p < 0x7F)) || (*p == '\n'))) {
297 ++p;
298 }
299 if (((p - cp) > 3) && !*p && ((unsigned int)(p - cp) < len)) {
300 fprintf(stderr, "\"");
301 while (*cp) {
Chih-Hung Hsieh634118e2014-09-12 16:02:28 -0700302 if (*cp != '\n') {
303 fprintf(stderr, "%c", *cp);
304 } else {
305 fprintf(stderr, "\\n");
306 }
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800307 ++cp;
308 --len;
309 }
310 fprintf(stderr, "\"");
311 } else {
312 fprintf(stderr, "%02x", *cp);
313 }
314 ++cp;
315 if (--len) {
316 fprintf(stderr, ", ");
317 }
318 }
319 fprintf(stderr, "}\n");
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800320 fflush(stderr);
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800321}
Mark Salyzyn2bd06f22016-12-27 13:30:03 -0800322#endif
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800323
Mark Salyzyn2bd06f22016-12-27 13:30:03 -0800324#ifdef __ANDROID__
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800325// BAD ROBOT
326// Benchmark threshold are generally considered bad form unless there is
327// is some human love applied to the continued maintenance and whether the
328// thresholds are tuned on a per-target basis. Here we check if the values
329// are more than double what is expected. Doubling will not prevent failure
330// on busy or low-end systems that could have a tendency to stretch values.
331//
332// The primary goal of this test is to simulate a spammy app (benchmark
333// being the worst) and check to make sure the logger can deal with it
334// appropriately by checking all the statistics are in an expected range.
335//
336TEST(logd, benchmark) {
337 size_t len;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800338 char* buf;
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800339
340 alloc_statistics(&buf, &len);
341 bool benchmark_already_run = buf && find_benchmark_spam(buf);
Mark Salyzyn501c3732017-03-10 14:31:54 -0800342 delete[] buf;
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800343
344 if (benchmark_already_run) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800345 fprintf(stderr,
346 "WARNING: spam already present and too much history\n"
347 " false OK for prune by worst UID check\n");
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800348 }
349
Mark Salyzyn501c3732017-03-10 14:31:54 -0800350 FILE* fp;
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800351
352 // Introduce some extreme spam for the worst UID filter
Mark Salyzyn501c3732017-03-10 14:31:54 -0800353 ASSERT_TRUE(
Mark Salyzynd392ac12017-04-27 14:46:31 -0700354 nullptr !=
Mark Salyzyn501c3732017-03-10 14:31:54 -0800355 (fp = popen("/data/nativetest/liblog-benchmarks/liblog-benchmarks"
356 " BM_log_maximum_retry"
357 " BM_log_maximum"
358 " BM_clock_overhead"
Mark Salyzyn81ab11a2017-03-29 09:11:19 -0700359 " BM_log_print_overhead"
Mark Salyzyn501c3732017-03-10 14:31:54 -0800360 " BM_log_latency"
361 " BM_log_delay",
362 "r")));
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800363
364 char buffer[5120];
365
Mark Salyzyn501c3732017-03-10 14:31:54 -0800366 static const char* benchmarks[] = {
Mark Salyzyn81ab11a2017-03-29 09:11:19 -0700367 "BM_log_maximum_retry ", "BM_log_maximum ", "BM_clock_overhead ",
368 "BM_log_print_overhead ", "BM_log_latency ", "BM_log_delay "
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800369 };
370 static const unsigned int log_maximum_retry = 0;
371 static const unsigned int log_maximum = 1;
372 static const unsigned int clock_overhead = 2;
Mark Salyzyn81ab11a2017-03-29 09:11:19 -0700373 static const unsigned int log_print_overhead = 3;
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800374 static const unsigned int log_latency = 4;
375 static const unsigned int log_delay = 5;
376
Mark Salyzync8d31942016-11-03 10:29:23 -0700377 unsigned long ns[arraysize(benchmarks)];
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800378
379 memset(ns, 0, sizeof(ns));
380
381 while (fgets(buffer, sizeof(buffer), fp)) {
Mark Salyzync8d31942016-11-03 10:29:23 -0700382 for (unsigned i = 0; i < arraysize(ns); ++i) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800383 char* cp = strstr(buffer, benchmarks[i]);
Mark Salyzyn0c57bd82014-06-06 13:38:42 -0700384 if (!cp) {
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800385 continue;
386 }
Mark Salyzyn0c57bd82014-06-06 13:38:42 -0700387 sscanf(cp, "%*s %lu %lu", &ns[i], &ns[i]);
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800388 fprintf(stderr, "%-22s%8lu\n", benchmarks[i], ns[i]);
389 }
390 }
391 int ret = pclose(fp);
392
393 if (!WIFEXITED(ret) || (WEXITSTATUS(ret) == 127)) {
394 fprintf(stderr,
395 "WARNING: "
396 "/data/nativetest/liblog-benchmarks/liblog-benchmarks missing\n"
397 " can not perform test\n");
398 return;
399 }
400
Mark Salyzyn501c3732017-03-10 14:31:54 -0800401 EXPECT_GE(200000UL, ns[log_maximum_retry]); // 104734 user
Mark Salyzyn81ab11a2017-03-29 09:11:19 -0700402 EXPECT_NE(0UL, ns[log_maximum_retry]); // failure to parse
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800403
Mark Salyzyn501c3732017-03-10 14:31:54 -0800404 EXPECT_GE(90000UL, ns[log_maximum]); // 46913 user
Mark Salyzyn81ab11a2017-03-29 09:11:19 -0700405 EXPECT_NE(0UL, ns[log_maximum]); // failure to parse
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800406
Mark Salyzyn501c3732017-03-10 14:31:54 -0800407 EXPECT_GE(4096UL, ns[clock_overhead]); // 4095
Mark Salyzyn81ab11a2017-03-29 09:11:19 -0700408 EXPECT_NE(0UL, ns[clock_overhead]); // failure to parse
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800409
Mark Salyzyn81ab11a2017-03-29 09:11:19 -0700410 EXPECT_GE(250000UL, ns[log_print_overhead]); // 126886 user
411 EXPECT_NE(0UL, ns[log_print_overhead]); // failure to parse
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800412
Mark Salyzyn501c3732017-03-10 14:31:54 -0800413 EXPECT_GE(10000000UL,
414 ns[log_latency]); // 1453559 user space (background cgroup)
Mark Salyzyn81ab11a2017-03-29 09:11:19 -0700415 EXPECT_NE(0UL, ns[log_latency]); // failure to parse
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800416
Mark Salyzyn501c3732017-03-10 14:31:54 -0800417 EXPECT_GE(20000000UL, ns[log_delay]); // 10500289 user
Mark Salyzyn81ab11a2017-03-29 09:11:19 -0700418 EXPECT_NE(0UL, ns[log_delay]); // failure to parse
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800419
420 alloc_statistics(&buf, &len);
421
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800422 bool collected_statistics = !!buf;
423 EXPECT_EQ(true, collected_statistics);
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800424
Mark Salyzynd392ac12017-04-27 14:46:31 -0700425 ASSERT_TRUE(nullptr != buf);
Mark Salyzyne821dac2014-04-09 10:02:23 -0700426
Mark Salyzyn501c3732017-03-10 14:31:54 -0800427 char* benchmark_statistics_found = find_benchmark_spam(buf);
Mark Salyzynd392ac12017-04-27 14:46:31 -0700428 ASSERT_TRUE(benchmark_statistics_found != nullptr);
Mark Salyzyne821dac2014-04-09 10:02:23 -0700429
430 // Check how effective the SPAM filter is, parse out Now size.
Mark Salyzyn62d6a2a2015-05-26 11:00:45 -0700431 // 0 root 54164 147569
Mark Salyzyne821dac2014-04-09 10:02:23 -0700432 // ^-- benchmark_statistics_found
433
Mark Salyzyn0c57bd82014-06-06 13:38:42 -0700434 unsigned long nowSpamSize = atol(benchmark_statistics_found);
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800435
Mark Salyzyn501c3732017-03-10 14:31:54 -0800436 delete[] buf;
Mark Salyzyne821dac2014-04-09 10:02:23 -0700437
Mark Salyzyn0c57bd82014-06-06 13:38:42 -0700438 ASSERT_NE(0UL, nowSpamSize);
Mark Salyzyne821dac2014-04-09 10:02:23 -0700439
Mark Salyzyn6e9aaae2014-06-13 10:09:55 -0700440 // Determine if we have the spam filter enabled
Mark Salyzyn501c3732017-03-10 14:31:54 -0800441 int sock = socket_local_client("logd", ANDROID_SOCKET_NAMESPACE_RESERVED,
Mark Salyzyne821dac2014-04-09 10:02:23 -0700442 SOCK_STREAM);
Mark Salyzyn6e9aaae2014-06-13 10:09:55 -0700443
444 ASSERT_TRUE(sock >= 0);
445
446 static const char getPruneList[] = "getPruneList";
447 if (write(sock, getPruneList, sizeof(getPruneList)) > 0) {
448 char buffer[80];
449 memset(buffer, 0, sizeof(buffer));
450 read(sock, buffer, sizeof(buffer));
Mark Salyzyn501c3732017-03-10 14:31:54 -0800451 char* cp = strchr(buffer, '\n');
Mark Salyzyn6e9aaae2014-06-13 10:09:55 -0700452 if (!cp || (cp[1] != '~') || (cp[2] != '!')) {
453 close(sock);
454 fprintf(stderr,
455 "WARNING: "
Mark Salyzyn501c3732017-03-10 14:31:54 -0800456 "Logger has SPAM filtration turned off \"%s\"\n",
457 buffer);
Mark Salyzyn6e9aaae2014-06-13 10:09:55 -0700458 return;
459 }
460 } else {
461 int save_errno = errno;
462 close(sock);
Mark Salyzyn501c3732017-03-10 14:31:54 -0800463 FAIL() << "Can not send " << getPruneList << " to logger -- "
464 << strerror(save_errno);
Mark Salyzyn6e9aaae2014-06-13 10:09:55 -0700465 }
466
Mark Salyzyne821dac2014-04-09 10:02:23 -0700467 static const unsigned long expected_absolute_minimum_log_size = 65536UL;
468 unsigned long totalSize = expected_absolute_minimum_log_size;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800469 static const char getSize[] = { 'g', 'e', 't', 'L', 'o', 'g',
470 'S', 'i', 'z', 'e', ' ', LOG_ID_MAIN + '0',
471 '\0' };
Mark Salyzyn6e9aaae2014-06-13 10:09:55 -0700472 if (write(sock, getSize, sizeof(getSize)) > 0) {
473 char buffer[80];
474 memset(buffer, 0, sizeof(buffer));
475 read(sock, buffer, sizeof(buffer));
476 totalSize = atol(buffer);
477 if (totalSize < expected_absolute_minimum_log_size) {
478 fprintf(stderr,
479 "WARNING: "
Mark Salyzyn501c3732017-03-10 14:31:54 -0800480 "Logger had unexpected referenced size \"%s\"\n",
481 buffer);
Mark Salyzyn6e9aaae2014-06-13 10:09:55 -0700482 totalSize = expected_absolute_minimum_log_size;
Mark Salyzyne821dac2014-04-09 10:02:23 -0700483 }
Mark Salyzyne821dac2014-04-09 10:02:23 -0700484 }
Mark Salyzyn6e9aaae2014-06-13 10:09:55 -0700485 close(sock);
486
Mark Salyzyne821dac2014-04-09 10:02:23 -0700487 // logd allows excursions to 110% of total size
Mark Salyzyn501c3732017-03-10 14:31:54 -0800488 totalSize = (totalSize * 11) / 10;
Mark Salyzyne821dac2014-04-09 10:02:23 -0700489
490 // 50% threshold for SPAM filter (<20% typical, lots of engineering margin)
Mark Salyzyn0c57bd82014-06-06 13:38:42 -0700491 ASSERT_GT(totalSize, nowSpamSize * 2);
Mark Salyzynd3ba6652014-02-28 13:44:12 -0800492}
Mark Salyzyn2bd06f22016-12-27 13:30:03 -0800493#endif
Mark Salyzynfc9f5b82015-12-01 08:57:53 -0800494
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800495// b/26447386 confirm fixed
Mark Salyzyn501c3732017-03-10 14:31:54 -0800496void timeout_negative(const char* command) {
Mark Salyzyn2bd06f22016-12-27 13:30:03 -0800497#ifdef __ANDROID__
Mark Salyzynfc9f5b82015-12-01 08:57:53 -0800498 log_msg msg_wrap, msg_timeout;
499 bool content_wrap = false, content_timeout = false, written = false;
500 unsigned int alarm_wrap = 0, alarm_timeout = 0;
501 // A few tries to get it right just in case wrap kicks in due to
502 // content providers being active during the test.
503 int i = 3;
504
505 while (--i) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800506 int fd = socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED,
Mark Salyzynfc9f5b82015-12-01 08:57:53 -0800507 SOCK_SEQPACKET);
508 ASSERT_LT(0, fd);
509
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800510 std::string ask(command);
511
Mark Salyzynfc9f5b82015-12-01 08:57:53 -0800512 struct sigaction ignore, old_sigaction;
513 memset(&ignore, 0, sizeof(ignore));
514 ignore.sa_handler = caught_signal;
515 sigemptyset(&ignore.sa_mask);
516 sigaction(SIGALRM, &ignore, &old_sigaction);
517 unsigned int old_alarm = alarm(3);
518
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800519 size_t len = ask.length() + 1;
520 written = write(fd, ask.c_str(), len) == (ssize_t)len;
Mark Salyzynfc9f5b82015-12-01 08:57:53 -0800521 if (!written) {
522 alarm(old_alarm);
Mark Salyzynd392ac12017-04-27 14:46:31 -0700523 sigaction(SIGALRM, &old_sigaction, nullptr);
Mark Salyzynfc9f5b82015-12-01 08:57:53 -0800524 close(fd);
525 continue;
526 }
527
Mark Salyzyn1736c482016-12-27 13:30:03 -0800528 // alarm triggers at 50% of the --wrap time out
Mark Salyzynfc9f5b82015-12-01 08:57:53 -0800529 content_wrap = recv(fd, msg_wrap.buf, sizeof(msg_wrap), 0) > 0;
530
531 alarm_wrap = alarm(5);
532
Mark Salyzyn1736c482016-12-27 13:30:03 -0800533 // alarm triggers at 133% of the --wrap time out
Mark Salyzynfc9f5b82015-12-01 08:57:53 -0800534 content_timeout = recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800535 if (!content_timeout) { // make sure we hit dumpAndClose
536 content_timeout =
537 recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0;
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800538 }
Mark Salyzynfc9f5b82015-12-01 08:57:53 -0800539
Alan Stokes81e63d02017-08-25 14:13:06 +0100540 if (old_alarm > 0) {
541 unsigned int time_spent = 3 - alarm_wrap;
542 if (old_alarm > time_spent + 1) {
543 old_alarm -= time_spent;
544 } else {
545 old_alarm = 2;
546 }
547 }
548 alarm_timeout = alarm(old_alarm);
Mark Salyzynd392ac12017-04-27 14:46:31 -0700549 sigaction(SIGALRM, &old_sigaction, nullptr);
Mark Salyzynfc9f5b82015-12-01 08:57:53 -0800550
551 close(fd);
552
Alan Stokes81e63d02017-08-25 14:13:06 +0100553 if (content_wrap && alarm_wrap && content_timeout && alarm_timeout) {
Mark Salyzynfc9f5b82015-12-01 08:57:53 -0800554 break;
555 }
556 }
557
558 if (content_wrap) {
Tom Cherry441054a2019-10-15 16:53:11 -0700559 dump_log_msg("wrap", &msg_wrap, -1);
Mark Salyzynfc9f5b82015-12-01 08:57:53 -0800560 }
561
562 if (content_timeout) {
Tom Cherry441054a2019-10-15 16:53:11 -0700563 dump_log_msg("timeout", &msg_timeout, -1);
Mark Salyzynfc9f5b82015-12-01 08:57:53 -0800564 }
565
566 EXPECT_TRUE(written);
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800567 EXPECT_TRUE(content_wrap);
568 EXPECT_NE(0U, alarm_wrap);
569 EXPECT_TRUE(content_timeout);
570 EXPECT_NE(0U, alarm_timeout);
Mark Salyzyn2bd06f22016-12-27 13:30:03 -0800571#else
Mark Salyzynd392ac12017-04-27 14:46:31 -0700572 command = nullptr;
Mark Salyzyn2bd06f22016-12-27 13:30:03 -0800573 GTEST_LOG_(INFO) << "This test does nothing.\n";
574#endif
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800575}
576
577TEST(logd, timeout_no_start) {
578 timeout_negative("dumpAndClose lids=0,1,2,3,4,5 timeout=6");
579}
580
581TEST(logd, timeout_start_epoch) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800582 timeout_negative(
583 "dumpAndClose lids=0,1,2,3,4,5 timeout=6 start=0.000000000");
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800584}
585
Tom Cherry25a4d702020-04-29 10:15:15 -0700586#ifdef ENABLE_FLAKY_TESTS
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800587// b/26447386 refined behavior
588TEST(logd, timeout) {
Mark Salyzyn2bd06f22016-12-27 13:30:03 -0800589#ifdef __ANDROID__
Mark Salyzyn1736c482016-12-27 13:30:03 -0800590 // b/33962045 This test interferes with other log reader tests that
591 // follow because of file descriptor socket persistence in the same
592 // process. So let's fork it to isolate it from giving us pain.
593
594 pid_t pid = fork();
595
596 if (pid) {
597 siginfo_t info = {};
598 ASSERT_EQ(0, TEMP_FAILURE_RETRY(waitid(P_PID, pid, &info, WEXITED)));
599 ASSERT_EQ(0, info.si_status);
600 return;
601 }
602
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800603 log_msg msg_wrap, msg_timeout;
604 bool content_wrap = false, content_timeout = false, written = false;
605 unsigned int alarm_wrap = 0, alarm_timeout = 0;
606 // A few tries to get it right just in case wrap kicks in due to
Mark Salyzyn1736c482016-12-27 13:30:03 -0800607 // content providers being active during the test.
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800608 int i = 5;
Tom Cherryf2c27462020-04-08 14:36:05 -0700609 log_time start(CLOCK_REALTIME);
Alan Stokes81e63d02017-08-25 14:13:06 +0100610 start.tv_sec -= 30; // reach back a moderate period of time
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800611
612 while (--i) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800613 int fd = socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED,
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800614 SOCK_SEQPACKET);
Mark Salyzyn24aa9a42017-04-17 12:39:13 -0700615 int save_errno = errno;
616 if (fd < 0) {
617 fprintf(stderr, "failed to open /dev/socket/logdr %s\n",
618 strerror(save_errno));
619 _exit(fd);
620 }
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800621
622 std::string ask = android::base::StringPrintf(
Mark Salyzyn501c3732017-03-10 14:31:54 -0800623 "dumpAndClose lids=0,1,2,3,4,5 timeout=6 start=%" PRIu32
624 ".%09" PRIu32,
Alan Stokes81e63d02017-08-25 14:13:06 +0100625 start.tv_sec, start.tv_nsec);
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800626
627 struct sigaction ignore, old_sigaction;
628 memset(&ignore, 0, sizeof(ignore));
629 ignore.sa_handler = caught_signal;
630 sigemptyset(&ignore.sa_mask);
631 sigaction(SIGALRM, &ignore, &old_sigaction);
632 unsigned int old_alarm = alarm(3);
633
634 size_t len = ask.length() + 1;
635 written = write(fd, ask.c_str(), len) == (ssize_t)len;
636 if (!written) {
637 alarm(old_alarm);
Mark Salyzynd392ac12017-04-27 14:46:31 -0700638 sigaction(SIGALRM, &old_sigaction, nullptr);
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800639 close(fd);
640 continue;
641 }
642
Mark Salyzyn1736c482016-12-27 13:30:03 -0800643 // alarm triggers at 50% of the --wrap time out
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800644 content_wrap = recv(fd, msg_wrap.buf, sizeof(msg_wrap), 0) > 0;
645
646 alarm_wrap = alarm(5);
647
Mark Salyzyn1736c482016-12-27 13:30:03 -0800648 // alarm triggers at 133% of the --wrap time out
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800649 content_timeout = recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0;
Mark Salyzyn501c3732017-03-10 14:31:54 -0800650 if (!content_timeout) { // make sure we hit dumpAndClose
651 content_timeout =
652 recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0;
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800653 }
654
Alan Stokes81e63d02017-08-25 14:13:06 +0100655 if (old_alarm > 0) {
656 unsigned int time_spent = 3 - alarm_wrap;
657 if (old_alarm > time_spent + 1) {
658 old_alarm -= time_spent;
659 } else {
660 old_alarm = 2;
661 }
662 }
663 alarm_timeout = alarm(old_alarm);
Mark Salyzynd392ac12017-04-27 14:46:31 -0700664 sigaction(SIGALRM, &old_sigaction, nullptr);
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800665
666 close(fd);
667
668 if (!content_wrap && !alarm_wrap && content_timeout && alarm_timeout) {
669 break;
670 }
671
672 // modify start time in case content providers are relatively
673 // active _or_ inactive during the test.
674 if (content_timeout) {
675 log_time msg(msg_timeout.entry.sec, msg_timeout.entry.nsec);
Alan Stokes81e63d02017-08-25 14:13:06 +0100676 if (msg < start) {
Mark Salyzyn24aa9a42017-04-17 12:39:13 -0700677 fprintf(stderr, "%u.%09u < %u.%09u\n", msg_timeout.entry.sec,
Alan Stokes81e63d02017-08-25 14:13:06 +0100678 msg_timeout.entry.nsec, (unsigned)start.tv_sec,
679 (unsigned)start.tv_nsec);
Mark Salyzyn24aa9a42017-04-17 12:39:13 -0700680 _exit(-1);
681 }
Alan Stokes81e63d02017-08-25 14:13:06 +0100682 if (msg > start) {
683 start = msg;
684 start.tv_sec += 30;
Tom Cherryf2c27462020-04-08 14:36:05 -0700685 log_time now = log_time(CLOCK_REALTIME);
Alan Stokes81e63d02017-08-25 14:13:06 +0100686 if (start > now) {
687 start = now;
688 --start.tv_sec;
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800689 }
690 }
691 } else {
Alan Stokes81e63d02017-08-25 14:13:06 +0100692 start.tv_sec -= 120; // inactive, reach further back!
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800693 }
694 }
695
696 if (content_wrap) {
Tom Cherry441054a2019-10-15 16:53:11 -0700697 dump_log_msg("wrap", &msg_wrap, -1);
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800698 }
699
700 if (content_timeout) {
Tom Cherry441054a2019-10-15 16:53:11 -0700701 dump_log_msg("timeout", &msg_timeout, -1);
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800702 }
703
704 if (content_wrap || !content_timeout) {
Alan Stokes81e63d02017-08-25 14:13:06 +0100705 fprintf(stderr, "start=%" PRIu32 ".%09" PRIu32 "\n", start.tv_sec,
706 start.tv_nsec);
Mark Salyzynef4e4f32016-01-21 10:59:25 -0800707 }
708
709 EXPECT_TRUE(written);
Mark Salyzynfc9f5b82015-12-01 08:57:53 -0800710 EXPECT_FALSE(content_wrap);
711 EXPECT_EQ(0U, alarm_wrap);
712 EXPECT_TRUE(content_timeout);
713 EXPECT_NE(0U, alarm_timeout);
Mark Salyzyn1736c482016-12-27 13:30:03 -0800714
Mark Salyzyn501c3732017-03-10 14:31:54 -0800715 _exit(!written + content_wrap + alarm_wrap + !content_timeout +
716 !alarm_timeout);
Mark Salyzyn2bd06f22016-12-27 13:30:03 -0800717#else
718 GTEST_LOG_(INFO) << "This test does nothing.\n";
719#endif
Mark Salyzynfc9f5b82015-12-01 08:57:53 -0800720}
Tom Cherry25a4d702020-04-29 10:15:15 -0700721#endif
Mark Salyzyn5c77ad52016-02-23 08:55:43 -0800722
723// b/27242723 confirmed fixed
724TEST(logd, SNDTIMEO) {
Mark Salyzyn2bd06f22016-12-27 13:30:03 -0800725#ifdef __ANDROID__
Mark Salyzyn501c3732017-03-10 14:31:54 -0800726 static const unsigned sndtimeo =
727 LOGD_SNDTIMEO; // <sigh> it has to be done!
Mark Salyzyn5c77ad52016-02-23 08:55:43 -0800728 static const unsigned sleep_time = sndtimeo + 3;
729 static const unsigned alarm_time = sleep_time + 5;
730
731 int fd;
732
Mark Salyzyn501c3732017-03-10 14:31:54 -0800733 ASSERT_TRUE(
734 (fd = socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED,
735 SOCK_SEQPACKET)) > 0);
Mark Salyzyn5c77ad52016-02-23 08:55:43 -0800736
737 struct sigaction ignore, old_sigaction;
738 memset(&ignore, 0, sizeof(ignore));
739 ignore.sa_handler = caught_signal;
740 sigemptyset(&ignore.sa_mask);
741 sigaction(SIGALRM, &ignore, &old_sigaction);
742 unsigned int old_alarm = alarm(alarm_time);
743
Mark Salyzyn501c3732017-03-10 14:31:54 -0800744 static const char ask[] = "stream lids=0,1,2,3,4,5,6"; // all sources
Mark Salyzyn5c77ad52016-02-23 08:55:43 -0800745 bool reader_requested = write(fd, ask, sizeof(ask)) == sizeof(ask);
746 EXPECT_TRUE(reader_requested);
747
748 log_msg msg;
749 bool read_one = recv(fd, msg.buf, sizeof(msg), 0) > 0;
750
751 EXPECT_TRUE(read_one);
752 if (read_one) {
Tom Cherry441054a2019-10-15 16:53:11 -0700753 dump_log_msg("user", &msg, -1);
Mark Salyzyn5c77ad52016-02-23 08:55:43 -0800754 }
755
Mark Salyzyn501c3732017-03-10 14:31:54 -0800756 fprintf(stderr, "Sleep for >%d seconds logd SO_SNDTIMEO ...\n", sndtimeo);
Mark Salyzyn5c77ad52016-02-23 08:55:43 -0800757 sleep(sleep_time);
758
759 // flush will block if we did not trigger. if it did, last entry returns 0
760 int recv_ret;
761 do {
762 recv_ret = recv(fd, msg.buf, sizeof(msg), 0);
763 } while (recv_ret > 0);
764 int save_errno = (recv_ret < 0) ? errno : 0;
765
766 EXPECT_NE(0U, alarm(old_alarm));
Mark Salyzynd392ac12017-04-27 14:46:31 -0700767 sigaction(SIGALRM, &old_sigaction, nullptr);
Mark Salyzyn5c77ad52016-02-23 08:55:43 -0800768
769 EXPECT_EQ(0, recv_ret);
770 if (recv_ret > 0) {
Tom Cherry441054a2019-10-15 16:53:11 -0700771 dump_log_msg("user", &msg, -1);
Mark Salyzyn5c77ad52016-02-23 08:55:43 -0800772 }
773 EXPECT_EQ(0, save_errno);
774
775 close(fd);
Mark Salyzyn2bd06f22016-12-27 13:30:03 -0800776#else
777 GTEST_LOG_(INFO) << "This test does nothing.\n";
778#endif
Mark Salyzyn5c77ad52016-02-23 08:55:43 -0800779}
Mark Salyzyna2c02222016-12-13 10:31:29 -0800780
Mark Salyzyn61e9ce62016-09-12 14:51:54 -0700781TEST(logd, getEventTag_list) {
782#ifdef __ANDROID__
783 char buffer[256];
784 memset(buffer, 0, sizeof(buffer));
785 snprintf(buffer, sizeof(buffer), "getEventTag name=*");
786 send_to_control(buffer, sizeof(buffer));
787 buffer[sizeof(buffer) - 1] = '\0';
Mark Salyzyn501c3732017-03-10 14:31:54 -0800788 char* cp;
Mark Salyzyn61e9ce62016-09-12 14:51:54 -0700789 long ret = strtol(buffer, &cp, 10);
790 EXPECT_GT(ret, 4096);
791#else
792 GTEST_LOG_(INFO) << "This test does nothing.\n";
793#endif
794}
795
Mark Salyzyn407537f2017-02-21 16:19:08 -0800796TEST(logd, getEventTag_42) {
797#ifdef __ANDROID__
798 char buffer[256];
799 memset(buffer, 0, sizeof(buffer));
800 snprintf(buffer, sizeof(buffer), "getEventTag id=42");
801 send_to_control(buffer, sizeof(buffer));
802 buffer[sizeof(buffer) - 1] = '\0';
Mark Salyzyn501c3732017-03-10 14:31:54 -0800803 char* cp;
Mark Salyzyn407537f2017-02-21 16:19:08 -0800804 long ret = strtol(buffer, &cp, 10);
805 EXPECT_GT(ret, 16);
Mark Salyzynd392ac12017-04-27 14:46:31 -0700806 EXPECT_TRUE(strstr(buffer, "\t(to life the universe etc|3)") != nullptr);
807 EXPECT_TRUE(strstr(buffer, "answer") != nullptr);
Mark Salyzyn407537f2017-02-21 16:19:08 -0800808#else
809 GTEST_LOG_(INFO) << "This test does nothing.\n";
810#endif
811}
812
Mark Salyzyn61e9ce62016-09-12 14:51:54 -0700813TEST(logd, getEventTag_newentry) {
814#ifdef __ANDROID__
815 char buffer[256];
816 memset(buffer, 0, sizeof(buffer));
817 log_time now(CLOCK_MONOTONIC);
818 char name[64];
819 snprintf(name, sizeof(name), "a%" PRIu64, now.nsec());
Mark Salyzyn501c3732017-03-10 14:31:54 -0800820 snprintf(buffer, sizeof(buffer), "getEventTag name=%s format=\"(new|1)\"",
821 name);
Mark Salyzyn61e9ce62016-09-12 14:51:54 -0700822 send_to_control(buffer, sizeof(buffer));
823 buffer[sizeof(buffer) - 1] = '\0';
Mark Salyzyn501c3732017-03-10 14:31:54 -0800824 char* cp;
Mark Salyzyn61e9ce62016-09-12 14:51:54 -0700825 long ret = strtol(buffer, &cp, 10);
826 EXPECT_GT(ret, 16);
Mark Salyzynd392ac12017-04-27 14:46:31 -0700827 EXPECT_TRUE(strstr(buffer, "\t(new|1)") != nullptr);
828 EXPECT_TRUE(strstr(buffer, name) != nullptr);
Mark Salyzyn501c3732017-03-10 14:31:54 -0800829// ToDo: also look for this in /data/misc/logd/event-log-tags and
830// /dev/event-log-tags.
Mark Salyzyn61e9ce62016-09-12 14:51:54 -0700831#else
832 GTEST_LOG_(INFO) << "This test does nothing.\n";
833#endif
834}
835
Mark Salyzyn2bd06f22016-12-27 13:30:03 -0800836#ifdef __ANDROID__
Jaesung Chung23f1d092017-06-15 19:46:44 +0900837static inline uint32_t get4LE(const uint8_t* src) {
838 return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
839}
840
841static inline uint32_t get4LE(const char* src) {
842 return get4LE(reinterpret_cast<const uint8_t*>(src));
Mark Salyzyna2c02222016-12-13 10:31:29 -0800843}
Mark Salyzyn2bd06f22016-12-27 13:30:03 -0800844#endif
Mark Salyzyna2c02222016-12-13 10:31:29 -0800845
846void __android_log_btwrite_multiple__helper(int count) {
Mark Salyzyn2bd06f22016-12-27 13:30:03 -0800847#ifdef __ANDROID__
Mark Salyzyna2c02222016-12-13 10:31:29 -0800848 log_time ts(CLOCK_MONOTONIC);
Xu YiPing998fca52019-06-19 16:38:33 +0800849 usleep(100);
Mark Salyzyna2c02222016-12-13 10:31:29 -0800850 log_time ts1(CLOCK_MONOTONIC);
851
Mark Salyzyn1736c482016-12-27 13:30:03 -0800852 // We fork to create a unique pid for the submitted log messages
853 // so that we do not collide with the other _multiple_ tests.
854
Mark Salyzyna2c02222016-12-13 10:31:29 -0800855 pid_t pid = fork();
856
857 if (pid == 0) {
858 // child
859 for (int i = count; i; --i) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800860 ASSERT_LT(
861 0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
Mark Salyzyna2c02222016-12-13 10:31:29 -0800862 usleep(100);
863 }
Mark Salyzyn501c3732017-03-10 14:31:54 -0800864 ASSERT_LT(0,
865 __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1)));
Mark Salyzyna2c02222016-12-13 10:31:29 -0800866 usleep(1000000);
867
868 _exit(0);
869 }
870
Mark Salyzyn1736c482016-12-27 13:30:03 -0800871 siginfo_t info = {};
Mark Salyzyna2c02222016-12-13 10:31:29 -0800872 ASSERT_EQ(0, TEMP_FAILURE_RETRY(waitid(P_PID, pid, &info, WEXITED)));
Mark Salyzyn1736c482016-12-27 13:30:03 -0800873 ASSERT_EQ(0, info.si_status);
874
Mark Salyzyn501c3732017-03-10 14:31:54 -0800875 struct logger_list* logger_list;
Tom Cherry907b2d02020-03-23 13:40:10 -0700876 ASSERT_TRUE(nullptr != (logger_list = android_logger_list_open(LOG_ID_EVENTS,
877 ANDROID_LOG_NONBLOCK, 0, pid)));
Mark Salyzyna2c02222016-12-13 10:31:29 -0800878
879 int expected_count = (count < 2) ? count : 2;
880 int expected_chatty_count = (count <= 2) ? 0 : 1;
Mark Salyzynb5b87962017-01-23 14:20:31 -0800881 int expected_identical_count = (count < 2) ? 0 : (count - 2);
882 static const int expected_expire_count = 0;
Mark Salyzyna2c02222016-12-13 10:31:29 -0800883
884 count = 0;
885 int second_count = 0;
886 int chatty_count = 0;
Mark Salyzynb5b87962017-01-23 14:20:31 -0800887 int identical_count = 0;
Mark Salyzyna2c02222016-12-13 10:31:29 -0800888 int expire_count = 0;
889
890 for (;;) {
891 log_msg log_msg;
892 if (android_logger_list_read(logger_list, &log_msg) <= 0) break;
893
Mark Salyzyn501c3732017-03-10 14:31:54 -0800894 if ((log_msg.entry.pid != pid) || (log_msg.entry.len < (4 + 1 + 8)) ||
895 (log_msg.id() != LOG_ID_EVENTS))
896 continue;
Mark Salyzyna2c02222016-12-13 10:31:29 -0800897
Mark Salyzyn501c3732017-03-10 14:31:54 -0800898 char* eventData = log_msg.msg();
Mark Salyzyna2c02222016-12-13 10:31:29 -0800899 if (!eventData) continue;
900
901 uint32_t tag = get4LE(eventData);
902
Mark Salyzyn501c3732017-03-10 14:31:54 -0800903 if ((eventData[4] == EVENT_TYPE_LONG) &&
904 (log_msg.entry.len == (4 + 1 + 8))) {
Mark Salyzyna2c02222016-12-13 10:31:29 -0800905 if (tag != 0) continue;
906
Tom Cherrybd80e562020-05-18 08:58:50 -0700907 log_time* tx = reinterpret_cast<log_time*>(eventData + 4 + 1);
908 if (ts == *tx) {
Mark Salyzyna2c02222016-12-13 10:31:29 -0800909 ++count;
Tom Cherrybd80e562020-05-18 08:58:50 -0700910 } else if (ts1 == *tx) {
Mark Salyzyna2c02222016-12-13 10:31:29 -0800911 ++second_count;
912 }
913 } else if (eventData[4] == EVENT_TYPE_STRING) {
Mark Salyzyn247d6822017-01-03 14:00:19 -0800914 if (tag != CHATTY_LOG_TAG) continue;
Mark Salyzyna2c02222016-12-13 10:31:29 -0800915 ++chatty_count;
916 // int len = get4LE(eventData + 4 + 1);
Mark Salyzyn247d6822017-01-03 14:00:19 -0800917 log_msg.buf[LOGGER_ENTRY_MAX_LEN] = '\0';
Mark Salyzyn501c3732017-03-10 14:31:54 -0800918 const char* cp;
Mark Salyzynb5b87962017-01-23 14:20:31 -0800919 if ((cp = strstr(eventData + 4 + 1 + 4, " identical "))) {
920 unsigned val = 0;
921 sscanf(cp, " identical %u lines", &val);
922 identical_count += val;
923 } else if ((cp = strstr(eventData + 4 + 1 + 4, " expire "))) {
924 unsigned val = 0;
925 sscanf(cp, " expire %u lines", &val);
926 expire_count += val;
927 }
Mark Salyzyna2c02222016-12-13 10:31:29 -0800928 }
929 }
930
Mark Salyzyn1736c482016-12-27 13:30:03 -0800931 android_logger_list_close(logger_list);
932
Mark Salyzyna2c02222016-12-13 10:31:29 -0800933 EXPECT_EQ(expected_count, count);
934 EXPECT_EQ(1, second_count);
935 EXPECT_EQ(expected_chatty_count, chatty_count);
Mark Salyzynb5b87962017-01-23 14:20:31 -0800936 EXPECT_EQ(expected_identical_count, identical_count);
Mark Salyzyna2c02222016-12-13 10:31:29 -0800937 EXPECT_EQ(expected_expire_count, expire_count);
Mark Salyzyn2bd06f22016-12-27 13:30:03 -0800938#else
939 count = 0;
940 GTEST_LOG_(INFO) << "This test does nothing.\n";
941#endif
Mark Salyzyna2c02222016-12-13 10:31:29 -0800942}
943
944TEST(logd, multiple_test_1) {
945 __android_log_btwrite_multiple__helper(1);
946}
947
948TEST(logd, multiple_test_2) {
949 __android_log_btwrite_multiple__helper(2);
950}
951
952TEST(logd, multiple_test_3) {
953 __android_log_btwrite_multiple__helper(3);
954}
955
956TEST(logd, multiple_test_10) {
957 __android_log_btwrite_multiple__helper(10);
958}