1 /*
2 * Copyright (C) 2013-2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <fcntl.h>
18 #include <inttypes.h>
19 #include <semaphore.h>
20 #include <signal.h>
21 #include <string.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24
25 #include <cutils/properties.h>
26 #include <gtest/gtest.h>
27 #include <log/log.h>
28 #include <log/logger.h>
29 #include <log/log_read.h>
30 #include <log/logprint.h>
31 #include <private/android_filesystem_config.h>
32 #include <private/android_logger.h>
33
34 // enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and
35 // non-syscall libs. Since we are only using this in the emergency of
36 // a signal to stuff a terminating code into the logs, we will spin rather
37 // than try a usleep.
38 #define LOG_FAILURE_RETRY(exp) ({ \
39 typeof (exp) _rc; \
40 do { \
41 _rc = (exp); \
42 } while (((_rc == -1) \
43 && ((errno == EINTR) \
44 || (errno == EAGAIN))) \
45 || (_rc == -EINTR) \
46 || (_rc == -EAGAIN)); \
47 _rc; })
48
TEST(liblog,__android_log_buf_print)49 TEST(liblog, __android_log_buf_print) {
50 EXPECT_LT(0, __android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO,
51 "TEST__android_log_buf_print",
52 "radio"));
53 usleep(1000);
54 EXPECT_LT(0, __android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
55 "TEST__android_log_buf_print",
56 "system"));
57 usleep(1000);
58 EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
59 "TEST__android_log_buf_print",
60 "main"));
61 usleep(1000);
62 }
63
TEST(liblog,__android_log_buf_write)64 TEST(liblog, __android_log_buf_write) {
65 EXPECT_LT(0, __android_log_buf_write(LOG_ID_RADIO, ANDROID_LOG_INFO,
66 "TEST__android_log_buf_write",
67 "radio"));
68 usleep(1000);
69 EXPECT_LT(0, __android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
70 "TEST__android_log_buf_write",
71 "system"));
72 usleep(1000);
73 EXPECT_LT(0, __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO,
74 "TEST__android_log_buf_write",
75 "main"));
76 usleep(1000);
77 }
78
TEST(liblog,__android_log_btwrite)79 TEST(liblog, __android_log_btwrite) {
80 int intBuf = 0xDEADBEEF;
81 EXPECT_LT(0, __android_log_btwrite(0,
82 EVENT_TYPE_INT,
83 &intBuf, sizeof(intBuf)));
84 long long longBuf = 0xDEADBEEFA55A5AA5;
85 EXPECT_LT(0, __android_log_btwrite(0,
86 EVENT_TYPE_LONG,
87 &longBuf, sizeof(longBuf)));
88 usleep(1000);
89 char Buf[] = "\20\0\0\0DeAdBeEfA55a5aA5";
90 EXPECT_LT(0, __android_log_btwrite(0,
91 EVENT_TYPE_STRING,
92 Buf, sizeof(Buf) - 1));
93 usleep(1000);
94 }
95
ConcurrentPrintFn(void * arg)96 static void* ConcurrentPrintFn(void *arg) {
97 int ret = __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
98 "TEST__android_log_print", "Concurrent %" PRIuPTR,
99 reinterpret_cast<uintptr_t>(arg));
100 return reinterpret_cast<void*>(ret);
101 }
102
103 #define NUM_CONCURRENT 64
104 #define _concurrent_name(a,n) a##__concurrent##n
105 #define concurrent_name(a,n) _concurrent_name(a,n)
106
TEST(liblog,concurrent_name (__android_log_buf_print,NUM_CONCURRENT))107 TEST(liblog, concurrent_name(__android_log_buf_print, NUM_CONCURRENT)) {
108 pthread_t t[NUM_CONCURRENT];
109 int i;
110 for (i=0; i < NUM_CONCURRENT; i++) {
111 ASSERT_EQ(0, pthread_create(&t[i], NULL,
112 ConcurrentPrintFn,
113 reinterpret_cast<void *>(i)));
114 }
115 int ret = 0;
116 for (i=0; i < NUM_CONCURRENT; i++) {
117 void* result;
118 ASSERT_EQ(0, pthread_join(t[i], &result));
119 int this_result = reinterpret_cast<uintptr_t>(result);
120 if ((0 == ret) && (0 != this_result)) {
121 ret = this_result;
122 }
123 }
124 ASSERT_LT(0, ret);
125 }
126
TEST(liblog,__android_log_btwrite__android_logger_list_read)127 TEST(liblog, __android_log_btwrite__android_logger_list_read) {
128 struct logger_list *logger_list;
129
130 pid_t pid = getpid();
131
132 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
133 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
134
135 log_time ts(CLOCK_MONOTONIC);
136
137 ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
138 usleep(1000000);
139
140 int count = 0;
141
142 for (;;) {
143 log_msg log_msg;
144 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
145 break;
146 }
147
148 ASSERT_EQ(log_msg.entry.pid, pid);
149
150 if ((log_msg.entry.len != (4 + 1 + 8))
151 || (log_msg.id() != LOG_ID_EVENTS)) {
152 continue;
153 }
154
155 char *eventData = log_msg.msg();
156
157 if (eventData[4] != EVENT_TYPE_LONG) {
158 continue;
159 }
160
161 log_time tx(eventData + 4 + 1);
162 if (ts == tx) {
163 ++count;
164 }
165 }
166
167 EXPECT_EQ(1, count);
168
169 android_logger_list_close(logger_list);
170 }
171
get4LE(const char * src)172 static inline int32_t get4LE(const char* src)
173 {
174 return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
175 }
176
TEST(liblog,__android_log_bswrite)177 TEST(liblog, __android_log_bswrite) {
178 struct logger_list *logger_list;
179
180 pid_t pid = getpid();
181
182 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
183 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
184
185 static const char buffer[] = "Hello World";
186 log_time ts(android_log_clockid());
187
188 ASSERT_LT(0, __android_log_bswrite(0, buffer));
189 usleep(1000000);
190
191 int count = 0;
192
193 for (;;) {
194 log_msg log_msg;
195 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
196 break;
197 }
198
199 ASSERT_EQ(log_msg.entry.pid, pid);
200
201 if ((log_msg.entry.sec < (ts.tv_sec - 1))
202 || ((ts.tv_sec + 1) < log_msg.entry.sec)
203 || (log_msg.entry.len != (4 + 1 + 4 + sizeof(buffer) - 1))
204 || (log_msg.id() != LOG_ID_EVENTS)) {
205 continue;
206 }
207
208 char *eventData = log_msg.msg();
209
210 if (eventData[4] != EVENT_TYPE_STRING) {
211 continue;
212 }
213
214 int len = get4LE(eventData + 4 + 1);
215 if (len == (sizeof(buffer) - 1)) {
216 ++count;
217
218 AndroidLogFormat *logformat = android_log_format_new();
219 EXPECT_TRUE(NULL != logformat);
220 AndroidLogEntry entry;
221 char msgBuf[1024];
222 EXPECT_EQ(0, android_log_processBinaryLogBuffer(&log_msg.entry_v1,
223 &entry,
224 NULL,
225 msgBuf,
226 sizeof(msgBuf)));
227 fflush(stderr);
228 EXPECT_EQ(31, android_log_printLogLine(logformat, fileno(stderr), &entry));
229 android_log_format_free(logformat);
230 }
231 }
232
233 EXPECT_EQ(1, count);
234
235 android_logger_list_close(logger_list);
236 }
237
TEST(liblog,__android_log_bswrite__empty_string)238 TEST(liblog, __android_log_bswrite__empty_string) {
239 struct logger_list *logger_list;
240
241 pid_t pid = getpid();
242
243 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
244 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
245
246 static const char buffer[] = "";
247 log_time ts(android_log_clockid());
248
249 ASSERT_LT(0, __android_log_bswrite(0, buffer));
250 usleep(1000000);
251
252 int count = 0;
253
254 for (;;) {
255 log_msg log_msg;
256 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
257 break;
258 }
259
260 ASSERT_EQ(log_msg.entry.pid, pid);
261
262 if ((log_msg.entry.sec < (ts.tv_sec - 1))
263 || ((ts.tv_sec + 1) < log_msg.entry.sec)
264 || (log_msg.entry.len != (4 + 1 + 4))
265 || (log_msg.id() != LOG_ID_EVENTS)) {
266 continue;
267 }
268
269 char *eventData = log_msg.msg();
270
271 if (eventData[4] != EVENT_TYPE_STRING) {
272 continue;
273 }
274
275 int len = get4LE(eventData + 4 + 1);
276 if (len == 0) {
277 ++count;
278
279 AndroidLogFormat *logformat = android_log_format_new();
280 EXPECT_TRUE(NULL != logformat);
281 AndroidLogEntry entry;
282 char msgBuf[1024];
283 EXPECT_EQ(0, android_log_processBinaryLogBuffer(&log_msg.entry_v1,
284 &entry,
285 NULL,
286 msgBuf,
287 sizeof(msgBuf)));
288 fflush(stderr);
289 EXPECT_EQ(20, android_log_printLogLine(logformat, fileno(stderr), &entry));
290 android_log_format_free(logformat);
291 }
292 }
293
294 EXPECT_EQ(1, count);
295
296 android_logger_list_close(logger_list);
297 }
298
TEST(liblog,__security)299 TEST(liblog, __security) {
300 static const char persist_key[] = "persist.logd.security";
301 static const char readonly_key[] = "ro.device_owner";
302 static const char nothing_val[] = "_NOTHING_TO_SEE_HERE_";
303 char persist[PROP_VALUE_MAX];
304 char readonly[PROP_VALUE_MAX];
305
306 property_get(persist_key, persist, "");
307 property_get(readonly_key, readonly, nothing_val);
308
309 if (!strcmp(readonly, nothing_val)) {
310 EXPECT_FALSE(__android_log_security());
311 fprintf(stderr, "Warning, setting ro.device_owner to a domain\n");
312 property_set(readonly_key, "com.google.android.SecOps.DeviceOwner");
313 } else if (!strcasecmp(readonly, "false") || !readonly[0]) {
314 EXPECT_FALSE(__android_log_security());
315 return;
316 }
317
318 if (!strcasecmp(persist, "true")) {
319 EXPECT_TRUE(__android_log_security());
320 } else {
321 EXPECT_FALSE(__android_log_security());
322 }
323 property_set(persist_key, "TRUE");
324 EXPECT_TRUE(__android_log_security());
325 property_set(persist_key, "FALSE");
326 EXPECT_FALSE(__android_log_security());
327 property_set(persist_key, "true");
328 EXPECT_TRUE(__android_log_security());
329 property_set(persist_key, "false");
330 EXPECT_FALSE(__android_log_security());
331 property_set(persist_key, "");
332 EXPECT_FALSE(__android_log_security());
333 property_set(persist_key, persist);
334 }
335
TEST(liblog,__security_buffer)336 TEST(liblog, __security_buffer) {
337 struct logger_list *logger_list;
338 android_event_long_t buffer;
339
340 static const char persist_key[] = "persist.logd.security";
341 char persist[PROP_VALUE_MAX];
342 bool set_persist = false;
343 bool allow_security = false;
344
345 if (__android_log_security()) {
346 allow_security = true;
347 } else {
348 property_get(persist_key, persist, "");
349 if (strcasecmp(persist, "true")) {
350 property_set(persist_key, "TRUE");
351 if (__android_log_security()) {
352 allow_security = true;
353 set_persist = true;
354 } else {
355 property_set(persist_key, persist);
356 }
357 }
358 }
359
360 if (!allow_security) {
361 fprintf(stderr, "WARNING: "
362 "security buffer disabled, bypassing end-to-end test\n");
363
364 log_time ts(CLOCK_MONOTONIC);
365
366 buffer.type = EVENT_TYPE_LONG;
367 buffer.data = *(static_cast<uint64_t *>((void *)&ts));
368
369 // expect failure!
370 ASSERT_GE(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer)));
371
372 return;
373 }
374
375 /* Matches clientHasLogCredentials() in logd */
376 uid_t uid = getuid();
377 gid_t gid = getgid();
378 bool clientHasLogCredentials = true;
379 if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)
380 && (gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
381 uid_t euid = geteuid();
382 if ((euid != AID_SYSTEM) && (euid != AID_ROOT) && (euid != AID_LOG)) {
383 gid_t egid = getegid();
384 if ((egid != AID_SYSTEM) && (egid != AID_ROOT) && (egid != AID_LOG)) {
385 int num_groups = getgroups(0, NULL);
386 if (num_groups > 0) {
387 gid_t groups[num_groups];
388 num_groups = getgroups(num_groups, groups);
389 while (num_groups > 0) {
390 if (groups[num_groups - 1] == AID_LOG) {
391 break;
392 }
393 --num_groups;
394 }
395 }
396 if (num_groups <= 0) {
397 clientHasLogCredentials = false;
398 }
399 }
400 }
401 }
402 if (!clientHasLogCredentials) {
403 fprintf(stderr, "WARNING: "
404 "not in system context, bypassing end-to-end test\n");
405
406 log_time ts(CLOCK_MONOTONIC);
407
408 buffer.type = EVENT_TYPE_LONG;
409 buffer.data = *(static_cast<uint64_t *>((void *)&ts));
410
411 // expect failure!
412 ASSERT_GE(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer)));
413
414 return;
415 }
416
417 pid_t pid = getpid();
418
419 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
420 LOG_ID_SECURITY, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK,
421 1000, pid)));
422
423 log_time ts(CLOCK_MONOTONIC);
424
425 buffer.type = EVENT_TYPE_LONG;
426 buffer.data = *(static_cast<uint64_t *>((void *)&ts));
427
428 ASSERT_LT(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer)));
429 usleep(1000000);
430
431 int count = 0;
432
433 for (;;) {
434 log_msg log_msg;
435 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
436 break;
437 }
438
439 ASSERT_EQ(log_msg.entry.pid, pid);
440
441 if ((log_msg.entry.len != (4 + 1 + 8))
442 || (log_msg.id() != LOG_ID_SECURITY)) {
443 continue;
444 }
445
446 char *eventData = log_msg.msg();
447
448 if (eventData[4] != EVENT_TYPE_LONG) {
449 continue;
450 }
451
452 log_time tx(eventData + 4 + 1);
453 if (ts == tx) {
454 ++count;
455 }
456 }
457
458 if (set_persist) {
459 property_set(persist_key, persist);
460 }
461
462 android_logger_list_close(logger_list);
463
464 bool clientHasSecurityCredentials = (uid == AID_SYSTEM) || (gid == AID_SYSTEM);
465 if (!clientHasSecurityCredentials) {
466 fprintf(stderr, "WARNING: "
467 "not system, content submitted but can not check end-to-end\n");
468 }
469 EXPECT_EQ(clientHasSecurityCredentials ? 1 : 0, count);
470
471 }
472
473 static unsigned signaled;
474 static log_time signal_time;
475
476 /*
477 * Strictly, we are not allowed to log messages in a signal context, but we
478 * do make an effort to keep the failure surface minimized, and this in-effect
479 * should catch any regressions in that effort. The odds of a logged message
480 * in a signal handler causing a lockup problem should be _very_ small.
481 */
caught_blocking_signal(int)482 static void caught_blocking_signal(int /*signum*/)
483 {
484 unsigned long long v = 0xDEADBEEFA55A0000ULL;
485
486 v += getpid() & 0xFFFF;
487
488 ++signaled;
489 if ((signal_time.tv_sec == 0) && (signal_time.tv_nsec == 0)) {
490 signal_time = log_time(CLOCK_MONOTONIC);
491 signal_time.tv_sec += 2;
492 }
493
494 LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
495 }
496
497 // Fill in current process user and system time in 10ms increments
get_ticks(unsigned long long * uticks,unsigned long long * sticks)498 static void get_ticks(unsigned long long *uticks, unsigned long long *sticks)
499 {
500 *uticks = *sticks = 0;
501
502 pid_t pid = getpid();
503
504 char buffer[512];
505 snprintf(buffer, sizeof(buffer), "/proc/%u/stat", pid);
506
507 FILE *fp = fopen(buffer, "r");
508 if (!fp) {
509 return;
510 }
511
512 char *cp = fgets(buffer, sizeof(buffer), fp);
513 fclose(fp);
514 if (!cp) {
515 return;
516 }
517
518 pid_t d;
519 char s[sizeof(buffer)];
520 char c;
521 long long ll;
522 unsigned long long ull;
523
524 if (15 != sscanf(buffer,
525 "%d %s %c %lld %lld %lld %lld %lld %llu %llu %llu %llu %llu %llu %llu ",
526 &d, s, &c, &ll, &ll, &ll, &ll, &ll, &ull, &ull, &ull, &ull, &ull,
527 uticks, sticks)) {
528 *uticks = *sticks = 0;
529 }
530 }
531
TEST(liblog,android_logger_list_read__cpu_signal)532 TEST(liblog, android_logger_list_read__cpu_signal) {
533 struct logger_list *logger_list;
534 unsigned long long v = 0xDEADBEEFA55A0000ULL;
535
536 pid_t pid = getpid();
537
538 v += pid & 0xFFFF;
539
540 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
541 LOG_ID_EVENTS, ANDROID_LOG_RDONLY, 1000, pid)));
542
543 int count = 0;
544
545 int signals = 0;
546
547 unsigned long long uticks_start;
548 unsigned long long sticks_start;
549 get_ticks(&uticks_start, &sticks_start);
550
551 const unsigned alarm_time = 10;
552
553 memset(&signal_time, 0, sizeof(signal_time));
554
555 signal(SIGALRM, caught_blocking_signal);
556 alarm(alarm_time);
557
558 signaled = 0;
559
560 do {
561 log_msg log_msg;
562 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
563 break;
564 }
565
566 alarm(alarm_time);
567
568 ++count;
569
570 ASSERT_EQ(log_msg.entry.pid, pid);
571
572 if ((log_msg.entry.len != (4 + 1 + 8))
573 || (log_msg.id() != LOG_ID_EVENTS)) {
574 continue;
575 }
576
577 char *eventData = log_msg.msg();
578
579 if (eventData[4] != EVENT_TYPE_LONG) {
580 continue;
581 }
582
583 unsigned long long l = eventData[4 + 1 + 0] & 0xFF;
584 l |= (unsigned long long) (eventData[4 + 1 + 1] & 0xFF) << 8;
585 l |= (unsigned long long) (eventData[4 + 1 + 2] & 0xFF) << 16;
586 l |= (unsigned long long) (eventData[4 + 1 + 3] & 0xFF) << 24;
587 l |= (unsigned long long) (eventData[4 + 1 + 4] & 0xFF) << 32;
588 l |= (unsigned long long) (eventData[4 + 1 + 5] & 0xFF) << 40;
589 l |= (unsigned long long) (eventData[4 + 1 + 6] & 0xFF) << 48;
590 l |= (unsigned long long) (eventData[4 + 1 + 7] & 0xFF) << 56;
591
592 if (l == v) {
593 ++signals;
594 break;
595 }
596 } while (!signaled || (log_time(CLOCK_MONOTONIC) < signal_time));
597 alarm(0);
598 signal(SIGALRM, SIG_DFL);
599
600 EXPECT_LE(1, count);
601
602 EXPECT_EQ(1, signals);
603
604 android_logger_list_close(logger_list);
605
606 unsigned long long uticks_end;
607 unsigned long long sticks_end;
608 get_ticks(&uticks_end, &sticks_end);
609
610 // Less than 1% in either user or system time, or both
611 const unsigned long long one_percent_ticks = alarm_time;
612 unsigned long long user_ticks = uticks_end - uticks_start;
613 unsigned long long system_ticks = sticks_end - sticks_start;
614 EXPECT_GT(one_percent_ticks, user_ticks);
615 EXPECT_GT(one_percent_ticks, system_ticks);
616 EXPECT_GT(one_percent_ticks, user_ticks + system_ticks);
617 }
618
619 /*
620 * Strictly, we are not allowed to log messages in a signal context, the
621 * correct way to handle this is to ensure the messages are constructed in
622 * a thread; the signal handler should only unblock the thread.
623 */
624 static sem_t thread_trigger;
625
caught_blocking_thread(int)626 static void caught_blocking_thread(int /*signum*/)
627 {
628 sem_post(&thread_trigger);
629 }
630
running_thread(void *)631 static void *running_thread(void *) {
632 unsigned long long v = 0xDEADBEAFA55A0000ULL;
633
634 v += getpid() & 0xFFFF;
635
636 struct timespec timeout;
637 clock_gettime(CLOCK_REALTIME, &timeout);
638 timeout.tv_sec += 55;
639 sem_timedwait(&thread_trigger, &timeout);
640
641 ++signaled;
642 if ((signal_time.tv_sec == 0) && (signal_time.tv_nsec == 0)) {
643 signal_time = log_time(CLOCK_MONOTONIC);
644 signal_time.tv_sec += 2;
645 }
646
647 LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
648
649 return NULL;
650 }
651
start_thread()652 int start_thread()
653 {
654 sem_init(&thread_trigger, 0, 0);
655
656 pthread_attr_t attr;
657 if (pthread_attr_init(&attr)) {
658 return -1;
659 }
660
661 struct sched_param param;
662
663 memset(¶m, 0, sizeof(param));
664 pthread_attr_setschedparam(&attr, ¶m);
665 pthread_attr_setschedpolicy(&attr, SCHED_BATCH);
666
667 if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) {
668 pthread_attr_destroy(&attr);
669 return -1;
670 }
671
672 pthread_t thread;
673 if (pthread_create(&thread, &attr, running_thread, NULL)) {
674 pthread_attr_destroy(&attr);
675 return -1;
676 }
677
678 pthread_attr_destroy(&attr);
679 return 0;
680 }
681
TEST(liblog,android_logger_list_read__cpu_thread)682 TEST(liblog, android_logger_list_read__cpu_thread) {
683 struct logger_list *logger_list;
684 unsigned long long v = 0xDEADBEAFA55A0000ULL;
685
686 pid_t pid = getpid();
687
688 v += pid & 0xFFFF;
689
690 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
691 LOG_ID_EVENTS, ANDROID_LOG_RDONLY, 1000, pid)));
692
693 int count = 0;
694
695 int signals = 0;
696
697 unsigned long long uticks_start;
698 unsigned long long sticks_start;
699 get_ticks(&uticks_start, &sticks_start);
700
701 const unsigned alarm_time = 10;
702
703 memset(&signal_time, 0, sizeof(signal_time));
704
705 signaled = 0;
706 EXPECT_EQ(0, start_thread());
707
708 signal(SIGALRM, caught_blocking_thread);
709 alarm(alarm_time);
710
711 do {
712 log_msg log_msg;
713 if (LOG_FAILURE_RETRY(android_logger_list_read(logger_list, &log_msg)) <= 0) {
714 break;
715 }
716
717 alarm(alarm_time);
718
719 ++count;
720
721 ASSERT_EQ(log_msg.entry.pid, pid);
722
723 if ((log_msg.entry.len != (4 + 1 + 8))
724 || (log_msg.id() != LOG_ID_EVENTS)) {
725 continue;
726 }
727
728 char *eventData = log_msg.msg();
729
730 if (eventData[4] != EVENT_TYPE_LONG) {
731 continue;
732 }
733
734 unsigned long long l = eventData[4 + 1 + 0] & 0xFF;
735 l |= (unsigned long long) (eventData[4 + 1 + 1] & 0xFF) << 8;
736 l |= (unsigned long long) (eventData[4 + 1 + 2] & 0xFF) << 16;
737 l |= (unsigned long long) (eventData[4 + 1 + 3] & 0xFF) << 24;
738 l |= (unsigned long long) (eventData[4 + 1 + 4] & 0xFF) << 32;
739 l |= (unsigned long long) (eventData[4 + 1 + 5] & 0xFF) << 40;
740 l |= (unsigned long long) (eventData[4 + 1 + 6] & 0xFF) << 48;
741 l |= (unsigned long long) (eventData[4 + 1 + 7] & 0xFF) << 56;
742
743 if (l == v) {
744 ++signals;
745 break;
746 }
747 } while (!signaled || (log_time(CLOCK_MONOTONIC) < signal_time));
748 alarm(0);
749 signal(SIGALRM, SIG_DFL);
750
751 EXPECT_LE(1, count);
752
753 EXPECT_EQ(1, signals);
754
755 android_logger_list_close(logger_list);
756
757 unsigned long long uticks_end;
758 unsigned long long sticks_end;
759 get_ticks(&uticks_end, &sticks_end);
760
761 // Less than 1% in either user or system time, or both
762 const unsigned long long one_percent_ticks = alarm_time;
763 unsigned long long user_ticks = uticks_end - uticks_start;
764 unsigned long long system_ticks = sticks_end - sticks_start;
765 EXPECT_GT(one_percent_ticks, user_ticks);
766 EXPECT_GT(one_percent_ticks, system_ticks);
767 EXPECT_GT(one_percent_ticks, user_ticks + system_ticks);
768 }
769
770 static const char max_payload_tag[] = "TEST_max_payload_XXXX";
771 #define SIZEOF_MAX_PAYLOAD_BUF (LOGGER_ENTRY_MAX_PAYLOAD - \
772 sizeof(max_payload_tag) - 1)
773 static const char max_payload_buf[] = "LEONATO\n\
774 I learn in this letter that Don Peter of Arragon\n\
775 comes this night to Messina\n\
776 MESSENGER\n\
777 He is very near by this: he was not three leagues off\n\
778 when I left him\n\
779 LEONATO\n\
780 How many gentlemen have you lost in this action?\n\
781 MESSENGER\n\
782 But few of any sort, and none of name\n\
783 LEONATO\n\
784 A victory is twice itself when the achiever brings\n\
785 home full numbers. I find here that Don Peter hath\n\
786 bestowed much honour on a young Florentine called Claudio\n\
787 MESSENGER\n\
788 Much deserved on his part and equally remembered by\n\
789 Don Pedro: he hath borne himself beyond the\n\
790 promise of his age, doing, in the figure of a lamb,\n\
791 the feats of a lion: he hath indeed better\n\
792 bettered expectation than you must expect of me to\n\
793 tell you how\n\
794 LEONATO\n\
795 He hath an uncle here in Messina will be very much\n\
796 glad of it.\n\
797 MESSENGER\n\
798 I have already delivered him letters, and there\n\
799 appears much joy in him; even so much that joy could\n\
800 not show itself modest enough without a badge of\n\
801 bitterness.\n\
802 LEONATO\n\
803 Did he break out into tears?\n\
804 MESSENGER\n\
805 In great measure.\n\
806 LEONATO\n\
807 A kind overflow of kindness: there are no faces\n\
808 truer than those that are so washed. How much\n\
809 better is it to weep at joy than to joy at weeping!\n\
810 BEATRICE\n\
811 I pray you, is Signior Mountanto returned from the\n\
812 wars or no?\n\
813 MESSENGER\n\
814 I know none of that name, lady: there was none such\n\
815 in the army of any sort.\n\
816 LEONATO\n\
817 What is he that you ask for, niece?\n\
818 HERO\n\
819 My cousin means Signior Benedick of Padua.\n\
820 MESSENGER\n\
821 O, he's returned; and as pleasant as ever he was.\n\
822 BEATRICE\n\
823 He set up his bills here in Messina and challenged\n\
824 Cupid at the flight; and my uncle's fool, reading\n\
825 the challenge, subscribed for Cupid, and challenged\n\
826 him at the bird-bolt. I pray you, how many hath he\n\
827 killed and eaten in these wars? But how many hath\n\
828 he killed? for indeed I promised to eat all of his killing.\n\
829 LEONATO\n\
830 Faith, niece, you tax Signior Benedick too much;\n\
831 but he'll be meet with you, I doubt it not.\n\
832 MESSENGER\n\
833 He hath done good service, lady, in these wars.\n\
834 BEATRICE\n\
835 You had musty victual, and he hath holp to eat it:\n\
836 he is a very valiant trencherman; he hath an\n\
837 excellent stomach.\n\
838 MESSENGER\n\
839 And a good soldier too, lady.\n\
840 BEATRICE\n\
841 And a good soldier to a lady: but what is he to a lord?\n\
842 MESSENGER\n\
843 A lord to a lord, a man to a man; stuffed with all\n\
844 honourable virtues.\n\
845 BEATRICE\n\
846 It is so, indeed; he is no less than a stuffed man:\n\
847 but for the stuffing,--well, we are all mortal.\n\
848 LEONATO\n\
849 You must not, sir, mistake my niece. There is a\n\
850 kind of merry war betwixt Signior Benedick and her:\n\
851 they never meet but there's a skirmish of wit\n\
852 between them.\n\
853 BEATRICE\n\
854 Alas! he gets nothing by that. In our last\n\
855 conflict four of his five wits went halting off, and\n\
856 now is the whole man governed with one: so that if\n\
857 he have wit enough to keep himself warm, let him\n\
858 bear it for a difference between himself and his\n\
859 horse; for it is all the wealth that he hath left,\n\
860 to be known a reasonable creature. Who is his\n\
861 companion now? He hath every month a new sworn brother.\n\
862 MESSENGER\n\
863 Is't possible?\n\
864 BEATRICE\n\
865 Very easily possible: he wears his faith but as\n\
866 the fashion of his hat; it ever changes with the\n\
867 next block.\n\
868 MESSENGER\n\
869 I see, lady, the gentleman is not in your books.\n\
870 BEATRICE\n\
871 No; an he were, I would burn my study. But, I pray\n\
872 you, who is his companion? Is there no young\n\
873 squarer now that will make a voyage with him to the devil?\n\
874 MESSENGER\n\
875 He is most in the company of the right noble Claudio.\n\
876 BEATRICE\n\
877 O Lord, he will hang upon him like a disease: he\n\
878 is sooner caught than the pestilence, and the taker\n\
879 runs presently mad. God help the noble Claudio! if\n\
880 he have caught the Benedick, it will cost him a\n\
881 thousand pound ere a' be cured.\n\
882 MESSENGER\n\
883 I will hold friends with you, lady.\n\
884 BEATRICE\n\
885 Do, good friend.\n\
886 LEONATO\n\
887 You will never run mad, niece.\n\
888 BEATRICE\n\
889 No, not till a hot January.\n\
890 MESSENGER\n\
891 Don Pedro is approached.\n\
892 Enter DON PEDRO, DON JOHN, CLAUDIO, BENEDICK, and BALTHASAR\n\
893 \n\
894 DON PEDRO\n\
895 Good Signior Leonato, you are come to meet your\n\
896 trouble: the fashion of the world is to avoid\n\
897 cost, and you encounter it\n\
898 LEONATO\n\
899 Never came trouble to my house in the likeness of your grace,\n\
900 for trouble being gone, comfort should remain, but\n\
901 when you depart from me, sorrow abides and happiness\n\
902 takes his leave.";
903
TEST(liblog,max_payload)904 TEST(liblog, max_payload) {
905 pid_t pid = getpid();
906 char tag[sizeof(max_payload_tag)];
907 memcpy(tag, max_payload_tag, sizeof(tag));
908 snprintf(tag + sizeof(tag) - 5, 5, "%04X", pid & 0xFFFF);
909
910 LOG_FAILURE_RETRY(__android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
911 tag, max_payload_buf));
912 sleep(2);
913
914 struct logger_list *logger_list;
915
916 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
917 LOG_ID_SYSTEM, ANDROID_LOG_RDONLY, 100, 0)));
918
919 bool matches = false;
920 ssize_t max_len = 0;
921
922 for(;;) {
923 log_msg log_msg;
924 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
925 break;
926 }
927
928 if ((log_msg.entry.pid != pid) || (log_msg.id() != LOG_ID_SYSTEM)) {
929 continue;
930 }
931
932 char *data = log_msg.msg() + 1;
933
934 if (strcmp(data, tag)) {
935 continue;
936 }
937
938 data += strlen(data) + 1;
939
940 const char *left = data;
941 const char *right = max_payload_buf;
942 while (*left && *right && (*left == *right)) {
943 ++left;
944 ++right;
945 }
946
947 if (max_len <= (left - data)) {
948 max_len = left - data + 1;
949 }
950
951 if (max_len > 512) {
952 matches = true;
953 break;
954 }
955 }
956
957 android_logger_list_close(logger_list);
958
959 EXPECT_EQ(true, matches);
960
961 EXPECT_LE(SIZEOF_MAX_PAYLOAD_BUF, static_cast<size_t>(max_len));
962 }
963
TEST(liblog,__android_log_buf_print__maxtag)964 TEST(liblog, __android_log_buf_print__maxtag) {
965 struct logger_list *logger_list;
966
967 pid_t pid = getpid();
968
969 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
970 LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
971
972 log_time ts(android_log_clockid());
973
974 EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
975 max_payload_buf, max_payload_buf));
976 usleep(1000000);
977
978 int count = 0;
979
980 for (;;) {
981 log_msg log_msg;
982 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
983 break;
984 }
985
986 ASSERT_EQ(log_msg.entry.pid, pid);
987
988 if ((log_msg.entry.sec < (ts.tv_sec - 1))
989 || ((ts.tv_sec + 1) < log_msg.entry.sec)
990 || ((size_t)log_msg.entry.len < LOGGER_ENTRY_MAX_PAYLOAD)
991 || (log_msg.id() != LOG_ID_MAIN)) {
992 continue;
993 }
994
995 ++count;
996
997 AndroidLogFormat *logformat = android_log_format_new();
998 EXPECT_TRUE(NULL != logformat);
999 AndroidLogEntry entry;
1000 int processLogBuffer = android_log_processLogBuffer(&log_msg.entry_v1,
1001 &entry);
1002 EXPECT_EQ(0, processLogBuffer);
1003 if (processLogBuffer == 0) {
1004 fflush(stderr);
1005 int printLogLine =
1006 android_log_printLogLine(logformat, fileno(stderr), &entry);
1007 // Legacy tag truncation
1008 EXPECT_LE(128, printLogLine);
1009 // Measured maximum if we try to print part of the tag as message
1010 EXPECT_GT(LOGGER_ENTRY_MAX_PAYLOAD * 13 / 8, printLogLine);
1011 }
1012 android_log_format_free(logformat);
1013 }
1014
1015 EXPECT_EQ(1, count);
1016
1017 android_logger_list_close(logger_list);
1018 }
1019
TEST(liblog,too_big_payload)1020 TEST(liblog, too_big_payload) {
1021 pid_t pid = getpid();
1022 static const char big_payload_tag[] = "TEST_big_payload_XXXX";
1023 char tag[sizeof(big_payload_tag)];
1024 memcpy(tag, big_payload_tag, sizeof(tag));
1025 snprintf(tag + sizeof(tag) - 5, 5, "%04X", pid & 0xFFFF);
1026
1027 std::string longString(3266519, 'x');
1028
1029 ssize_t ret = LOG_FAILURE_RETRY(__android_log_buf_write(LOG_ID_SYSTEM,
1030 ANDROID_LOG_INFO, tag, longString.c_str()));
1031
1032 struct logger_list *logger_list;
1033
1034 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
1035 LOG_ID_SYSTEM, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 100, 0)));
1036
1037 ssize_t max_len = 0;
1038
1039 for(;;) {
1040 log_msg log_msg;
1041 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
1042 break;
1043 }
1044
1045 if ((log_msg.entry.pid != pid) || (log_msg.id() != LOG_ID_SYSTEM)) {
1046 continue;
1047 }
1048
1049 char *data = log_msg.msg() + 1;
1050
1051 if (strcmp(data, tag)) {
1052 continue;
1053 }
1054
1055 data += strlen(data) + 1;
1056
1057 const char *left = data;
1058 const char *right = longString.c_str();
1059 while (*left && *right && (*left == *right)) {
1060 ++left;
1061 ++right;
1062 }
1063
1064 if (max_len <= (left - data)) {
1065 max_len = left - data + 1;
1066 }
1067 }
1068
1069 android_logger_list_close(logger_list);
1070
1071 EXPECT_LE(LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag),
1072 static_cast<size_t>(max_len));
1073
1074 EXPECT_EQ(ret, max_len + static_cast<ssize_t>(sizeof(big_payload_tag)));
1075 }
1076
TEST(liblog,dual_reader)1077 TEST(liblog, dual_reader) {
1078 struct logger_list *logger_list1;
1079
1080 // >25 messages due to liblog.__android_log_buf_print__concurrentXX above.
1081 ASSERT_TRUE(NULL != (logger_list1 = android_logger_list_open(
1082 LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 25, 0)));
1083
1084 struct logger_list *logger_list2;
1085
1086 if (NULL == (logger_list2 = android_logger_list_open(
1087 LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 15, 0))) {
1088 android_logger_list_close(logger_list1);
1089 ASSERT_TRUE(NULL != logger_list2);
1090 }
1091
1092 int count1 = 0;
1093 bool done1 = false;
1094 int count2 = 0;
1095 bool done2 = false;
1096
1097 do {
1098 log_msg log_msg;
1099
1100 if (!done1) {
1101 if (android_logger_list_read(logger_list1, &log_msg) <= 0) {
1102 done1 = true;
1103 } else {
1104 ++count1;
1105 }
1106 }
1107
1108 if (!done2) {
1109 if (android_logger_list_read(logger_list2, &log_msg) <= 0) {
1110 done2 = true;
1111 } else {
1112 ++count2;
1113 }
1114 }
1115 } while ((!done1) || (!done2));
1116
1117 android_logger_list_close(logger_list1);
1118 android_logger_list_close(logger_list2);
1119
1120 EXPECT_EQ(25, count1);
1121 EXPECT_EQ(15, count2);
1122 }
1123
TEST(liblog,android_logger_get_)1124 TEST(liblog, android_logger_get_) {
1125 struct logger_list * logger_list = android_logger_list_alloc(ANDROID_LOG_WRONLY, 0, 0);
1126
1127 for(int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
1128 log_id_t id = static_cast<log_id_t>(i);
1129 const char *name = android_log_id_to_name(id);
1130 if (id != android_name_to_log_id(name)) {
1131 continue;
1132 }
1133 fprintf(stderr, "log buffer %s\r", name);
1134 struct logger * logger;
1135 EXPECT_TRUE(NULL != (logger = android_logger_open(logger_list, id)));
1136 EXPECT_EQ(id, android_logger_get_id(logger));
1137 ssize_t get_log_size = android_logger_get_log_size(logger);
1138 /* security buffer is allowed to be denied */
1139 if (strcmp("security", name)) {
1140 EXPECT_LT(0, get_log_size);
1141 /* crash buffer is allowed to be empty, that is actually healthy! */
1142 EXPECT_LE((strcmp("crash", name)) != 0,
1143 android_logger_get_log_readable_size(logger));
1144 } else {
1145 EXPECT_NE(0, get_log_size);
1146 if (get_log_size < 0) {
1147 EXPECT_GT(0, android_logger_get_log_readable_size(logger));
1148 } else {
1149 EXPECT_LE(0, android_logger_get_log_readable_size(logger));
1150 }
1151 }
1152 EXPECT_LT(0, android_logger_get_log_version(logger));
1153 }
1154
1155 android_logger_list_close(logger_list);
1156 }
1157
checkPriForTag(AndroidLogFormat * p_format,const char * tag,android_LogPriority pri)1158 static bool checkPriForTag(AndroidLogFormat *p_format, const char *tag, android_LogPriority pri) {
1159 return android_log_shouldPrintLine(p_format, tag, pri)
1160 && !android_log_shouldPrintLine(p_format, tag, (android_LogPriority)(pri - 1));
1161 }
1162
TEST(liblog,filterRule)1163 TEST(liblog, filterRule) {
1164 static const char tag[] = "random";
1165
1166 AndroidLogFormat *p_format = android_log_format_new();
1167
1168 android_log_addFilterRule(p_format,"*:i");
1169
1170 EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_INFO));
1171 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
1172 android_log_addFilterRule(p_format, "*");
1173 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
1174 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
1175 android_log_addFilterRule(p_format, "*:v");
1176 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
1177 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
1178 android_log_addFilterRule(p_format, "*:i");
1179 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_INFO));
1180 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
1181
1182 android_log_addFilterRule(p_format, tag);
1183 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
1184 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
1185 android_log_addFilterRule(p_format, "random:v");
1186 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
1187 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
1188 android_log_addFilterRule(p_format, "random:d");
1189 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
1190 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
1191 android_log_addFilterRule(p_format, "random:w");
1192 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
1193 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
1194
1195 android_log_addFilterRule(p_format, "crap:*");
1196 EXPECT_TRUE (checkPriForTag(p_format, "crap", ANDROID_LOG_VERBOSE));
1197 EXPECT_TRUE(android_log_shouldPrintLine(p_format, "crap", ANDROID_LOG_VERBOSE) > 0);
1198
1199 // invalid expression
1200 EXPECT_TRUE (android_log_addFilterRule(p_format, "random:z") < 0);
1201 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
1202 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
1203
1204 // Issue #550946
1205 EXPECT_TRUE(android_log_addFilterString(p_format, " ") == 0);
1206 EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
1207
1208 // note trailing space
1209 EXPECT_TRUE(android_log_addFilterString(p_format, "*:s random:d ") == 0);
1210 EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
1211
1212 EXPECT_TRUE(android_log_addFilterString(p_format, "*:s random:z") < 0);
1213
1214 #if 0 // bitrot, seek update
1215 char defaultBuffer[512];
1216
1217 android_log_formatLogLine(p_format,
1218 defaultBuffer, sizeof(defaultBuffer), 0, ANDROID_LOG_ERROR, 123,
1219 123, 123, tag, "nofile", strlen("Hello"), "Hello", NULL);
1220
1221 fprintf(stderr, "%s\n", defaultBuffer);
1222 #endif
1223
1224 android_log_format_free(p_format);
1225 }
1226
TEST(liblog,is_loggable)1227 TEST(liblog, is_loggable) {
1228 static const char tag[] = "is_loggable";
1229 static const char log_namespace[] = "persist.log.tag.";
1230 static const size_t base_offset = 8; /* skip "persist." */
1231 // sizeof("string") = strlen("string") + 1
1232 char key[sizeof(log_namespace) + sizeof(tag) - 1];
1233 char hold[4][PROP_VALUE_MAX];
1234 static const struct {
1235 int level;
1236 char type;
1237 } levels[] = {
1238 { ANDROID_LOG_VERBOSE, 'v' },
1239 { ANDROID_LOG_DEBUG , 'd' },
1240 { ANDROID_LOG_INFO , 'i' },
1241 { ANDROID_LOG_WARN , 'w' },
1242 { ANDROID_LOG_ERROR , 'e' },
1243 { ANDROID_LOG_FATAL , 'a' },
1244 { -1 , 's' },
1245 { -2 , 'g' }, // Illegal value, resort to default
1246 };
1247
1248 // Set up initial test condition
1249 memset(hold, 0, sizeof(hold));
1250 snprintf(key, sizeof(key), "%s%s", log_namespace, tag);
1251 property_get(key, hold[0], "");
1252 property_set(key, "");
1253 property_get(key + base_offset, hold[1], "");
1254 property_set(key + base_offset, "");
1255 strcpy(key, log_namespace);
1256 key[sizeof(log_namespace) - 2] = '\0';
1257 property_get(key, hold[2], "");
1258 property_set(key, "");
1259 property_get(key, hold[3], "");
1260 property_set(key + base_offset, "");
1261
1262 // All combinations of level and defaults
1263 for(size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) {
1264 if (levels[i].level == -2) {
1265 continue;
1266 }
1267 for(size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) {
1268 if (levels[j].level == -2) {
1269 continue;
1270 }
1271 fprintf(stderr, "i=%zu j=%zu\r", i, j);
1272 bool android_log_is_loggable = __android_log_is_loggable(
1273 levels[i].level, tag, levels[j].level);
1274 if ((levels[i].level < levels[j].level)
1275 || (levels[j].level == -1)) {
1276 if (android_log_is_loggable) {
1277 fprintf(stderr, "\n");
1278 }
1279 EXPECT_FALSE(android_log_is_loggable);
1280 for(size_t k = 10; k; --k) {
1281 EXPECT_FALSE(__android_log_is_loggable(
1282 levels[i].level, tag, levels[j].level));
1283 }
1284 } else {
1285 if (!android_log_is_loggable) {
1286 fprintf(stderr, "\n");
1287 }
1288 EXPECT_TRUE(android_log_is_loggable);
1289 for(size_t k = 10; k; --k) {
1290 EXPECT_TRUE(__android_log_is_loggable(
1291 levels[i].level, tag, levels[j].level));
1292 }
1293 }
1294 }
1295 }
1296
1297 // All combinations of level and tag and global properties
1298 for(size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) {
1299 if (levels[i].level == -2) {
1300 continue;
1301 }
1302 for(size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) {
1303 char buf[2];
1304 buf[0] = levels[j].type;
1305 buf[1] = '\0';
1306
1307 snprintf(key, sizeof(key), "%s%s", log_namespace, tag);
1308 fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
1309 i, j, key, buf);
1310 property_set(key, buf);
1311 bool android_log_is_loggable = __android_log_is_loggable(
1312 levels[i].level, tag, ANDROID_LOG_DEBUG);
1313 if ((levels[i].level < levels[j].level)
1314 || (levels[j].level == -1)
1315 || ((levels[i].level < ANDROID_LOG_DEBUG)
1316 && (levels[j].level == -2))) {
1317 if (android_log_is_loggable) {
1318 fprintf(stderr, "\n");
1319 }
1320 EXPECT_FALSE(android_log_is_loggable);
1321 for(size_t k = 10; k; --k) {
1322 EXPECT_FALSE(__android_log_is_loggable(
1323 levels[i].level, tag, ANDROID_LOG_DEBUG));
1324 }
1325 } else {
1326 if (!android_log_is_loggable) {
1327 fprintf(stderr, "\n");
1328 }
1329 EXPECT_TRUE(android_log_is_loggable);
1330 for(size_t k = 10; k; --k) {
1331 EXPECT_TRUE(__android_log_is_loggable(
1332 levels[i].level, tag, ANDROID_LOG_DEBUG));
1333 }
1334 }
1335 property_set(key, "");
1336
1337 fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
1338 i, j, key + base_offset, buf);
1339 property_set(key + base_offset, buf);
1340 android_log_is_loggable = __android_log_is_loggable(
1341 levels[i].level, tag, ANDROID_LOG_DEBUG);
1342 if ((levels[i].level < levels[j].level)
1343 || (levels[j].level == -1)
1344 || ((levels[i].level < ANDROID_LOG_DEBUG)
1345 && (levels[j].level == -2))) {
1346 if (android_log_is_loggable) {
1347 fprintf(stderr, "\n");
1348 }
1349 EXPECT_FALSE(android_log_is_loggable);
1350 for(size_t k = 10; k; --k) {
1351 EXPECT_FALSE(__android_log_is_loggable(
1352 levels[i].level, tag, ANDROID_LOG_DEBUG));
1353 }
1354 } else {
1355 if (!android_log_is_loggable) {
1356 fprintf(stderr, "\n");
1357 }
1358 EXPECT_TRUE(android_log_is_loggable);
1359 for(size_t k = 10; k; --k) {
1360 EXPECT_TRUE(__android_log_is_loggable(
1361 levels[i].level, tag, ANDROID_LOG_DEBUG));
1362 }
1363 }
1364 property_set(key + base_offset, "");
1365
1366 strcpy(key, log_namespace);
1367 key[sizeof(log_namespace) - 2] = '\0';
1368 fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
1369 i, j, key, buf);
1370 property_set(key, buf);
1371 android_log_is_loggable = __android_log_is_loggable(
1372 levels[i].level, tag, ANDROID_LOG_DEBUG);
1373 if ((levels[i].level < levels[j].level)
1374 || (levels[j].level == -1)
1375 || ((levels[i].level < ANDROID_LOG_DEBUG)
1376 && (levels[j].level == -2))) {
1377 if (android_log_is_loggable) {
1378 fprintf(stderr, "\n");
1379 }
1380 EXPECT_FALSE(android_log_is_loggable);
1381 for(size_t k = 10; k; --k) {
1382 EXPECT_FALSE(__android_log_is_loggable(
1383 levels[i].level, tag, ANDROID_LOG_DEBUG));
1384 }
1385 } else {
1386 if (!android_log_is_loggable) {
1387 fprintf(stderr, "\n");
1388 }
1389 EXPECT_TRUE(android_log_is_loggable);
1390 for(size_t k = 10; k; --k) {
1391 EXPECT_TRUE(__android_log_is_loggable(
1392 levels[i].level, tag, ANDROID_LOG_DEBUG));
1393 }
1394 }
1395 property_set(key, "");
1396
1397 fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
1398 i, j, key + base_offset, buf);
1399 property_set(key + base_offset, buf);
1400 android_log_is_loggable = __android_log_is_loggable(
1401 levels[i].level, tag, ANDROID_LOG_DEBUG);
1402 if ((levels[i].level < levels[j].level)
1403 || (levels[j].level == -1)
1404 || ((levels[i].level < ANDROID_LOG_DEBUG)
1405 && (levels[j].level == -2))) {
1406 if (android_log_is_loggable) {
1407 fprintf(stderr, "\n");
1408 }
1409 EXPECT_FALSE(android_log_is_loggable);
1410 for(size_t k = 10; k; --k) {
1411 EXPECT_FALSE(__android_log_is_loggable(
1412 levels[i].level, tag, ANDROID_LOG_DEBUG));
1413 }
1414 } else {
1415 if (!android_log_is_loggable) {
1416 fprintf(stderr, "\n");
1417 }
1418 EXPECT_TRUE(android_log_is_loggable);
1419 for(size_t k = 10; k; --k) {
1420 EXPECT_TRUE(__android_log_is_loggable(
1421 levels[i].level, tag, ANDROID_LOG_DEBUG));
1422 }
1423 }
1424 property_set(key + base_offset, "");
1425 }
1426 }
1427
1428 // All combinations of level and tag properties, but with global set to INFO
1429 strcpy(key, log_namespace);
1430 key[sizeof(log_namespace) - 2] = '\0';
1431 property_set(key, "I");
1432 snprintf(key, sizeof(key), "%s%s", log_namespace, tag);
1433 for(size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) {
1434 if (levels[i].level == -2) {
1435 continue;
1436 }
1437 for(size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) {
1438 char buf[2];
1439 buf[0] = levels[j].type;
1440 buf[1] = '\0';
1441
1442 fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
1443 i, j, key, buf);
1444 property_set(key, buf);
1445 bool android_log_is_loggable = __android_log_is_loggable(
1446 levels[i].level, tag, ANDROID_LOG_DEBUG);
1447 if ((levels[i].level < levels[j].level)
1448 || (levels[j].level == -1)
1449 || ((levels[i].level < ANDROID_LOG_INFO) // Yes INFO
1450 && (levels[j].level == -2))) {
1451 if (android_log_is_loggable) {
1452 fprintf(stderr, "\n");
1453 }
1454 EXPECT_FALSE(android_log_is_loggable);
1455 for(size_t k = 10; k; --k) {
1456 EXPECT_FALSE(__android_log_is_loggable(
1457 levels[i].level, tag, ANDROID_LOG_DEBUG));
1458 }
1459 } else {
1460 if (!android_log_is_loggable) {
1461 fprintf(stderr, "\n");
1462 }
1463 EXPECT_TRUE(android_log_is_loggable);
1464 for(size_t k = 10; k; --k) {
1465 EXPECT_TRUE(__android_log_is_loggable(
1466 levels[i].level, tag, ANDROID_LOG_DEBUG));
1467 }
1468 }
1469 property_set(key, "");
1470
1471 fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
1472 i, j, key + base_offset, buf);
1473 property_set(key + base_offset, buf);
1474 android_log_is_loggable = __android_log_is_loggable(
1475 levels[i].level, tag, ANDROID_LOG_DEBUG);
1476 if ((levels[i].level < levels[j].level)
1477 || (levels[j].level == -1)
1478 || ((levels[i].level < ANDROID_LOG_INFO) // Yes INFO
1479 && (levels[j].level == -2))) {
1480 if (android_log_is_loggable) {
1481 fprintf(stderr, "\n");
1482 }
1483 EXPECT_FALSE(android_log_is_loggable);
1484 for(size_t k = 10; k; --k) {
1485 EXPECT_FALSE(__android_log_is_loggable(
1486 levels[i].level, tag, ANDROID_LOG_DEBUG));
1487 }
1488 } else {
1489 if (!android_log_is_loggable) {
1490 fprintf(stderr, "\n");
1491 }
1492 EXPECT_TRUE(android_log_is_loggable);
1493 for(size_t k = 10; k; --k) {
1494 EXPECT_TRUE(__android_log_is_loggable(
1495 levels[i].level, tag, ANDROID_LOG_DEBUG));
1496 }
1497 }
1498 property_set(key + base_offset, "");
1499 }
1500 }
1501
1502 // reset parms
1503 snprintf(key, sizeof(key), "%s%s", log_namespace, tag);
1504 property_set(key, hold[0]);
1505 property_set(key + base_offset, hold[1]);
1506 strcpy(key, log_namespace);
1507 key[sizeof(log_namespace) - 2] = '\0';
1508 property_set(key, hold[2]);
1509 property_set(key + base_offset, hold[3]);
1510 }
1511
TEST(liblog,android_errorWriteWithInfoLog__android_logger_list_read__typical)1512 TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__typical) {
1513 const int TAG = 123456781;
1514 const char SUBTAG[] = "test-subtag";
1515 const int UID = -1;
1516 const int DATA_LEN = 200;
1517 struct logger_list *logger_list;
1518
1519 pid_t pid = getpid();
1520
1521 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
1522 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
1523
1524 ASSERT_LT(0, android_errorWriteWithInfoLog(
1525 TAG, SUBTAG, UID, max_payload_buf, DATA_LEN));
1526
1527 sleep(2);
1528
1529 int count = 0;
1530
1531 for (;;) {
1532 log_msg log_msg;
1533 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
1534 break;
1535 }
1536
1537 char *eventData = log_msg.msg();
1538
1539 // Tag
1540 int tag = get4LE(eventData);
1541 eventData += 4;
1542
1543 if (tag != TAG) {
1544 continue;
1545 }
1546
1547 // List type
1548 ASSERT_EQ(EVENT_TYPE_LIST, eventData[0]);
1549 eventData++;
1550
1551 // Number of elements in list
1552 ASSERT_EQ(3, eventData[0]);
1553 eventData++;
1554
1555 // Element #1: string type for subtag
1556 ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);
1557 eventData++;
1558
1559 ASSERT_EQ((int) strlen(SUBTAG), get4LE(eventData));
1560 eventData +=4;
1561
1562 if (memcmp(SUBTAG, eventData, strlen(SUBTAG))) {
1563 continue;
1564 }
1565 eventData += strlen(SUBTAG);
1566
1567 // Element #2: int type for uid
1568 ASSERT_EQ(EVENT_TYPE_INT, eventData[0]);
1569 eventData++;
1570
1571 ASSERT_EQ(UID, get4LE(eventData));
1572 eventData += 4;
1573
1574 // Element #3: string type for data
1575 ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);
1576 eventData++;
1577
1578 ASSERT_EQ(DATA_LEN, get4LE(eventData));
1579 eventData += 4;
1580
1581 if (memcmp(max_payload_buf, eventData, DATA_LEN)) {
1582 continue;
1583 }
1584
1585 ++count;
1586 }
1587
1588 EXPECT_EQ(1, count);
1589
1590 android_logger_list_close(logger_list);
1591 }
1592
TEST(liblog,android_errorWriteWithInfoLog__android_logger_list_read__data_too_large)1593 TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__data_too_large) {
1594 const int TAG = 123456782;
1595 const char SUBTAG[] = "test-subtag";
1596 const int UID = -1;
1597 const int DATA_LEN = sizeof(max_payload_buf);
1598 struct logger_list *logger_list;
1599
1600 pid_t pid = getpid();
1601
1602 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
1603 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
1604
1605 ASSERT_LT(0, android_errorWriteWithInfoLog(
1606 TAG, SUBTAG, UID, max_payload_buf, DATA_LEN));
1607
1608 sleep(2);
1609
1610 int count = 0;
1611
1612 for (;;) {
1613 log_msg log_msg;
1614 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
1615 break;
1616 }
1617
1618 char *eventData = log_msg.msg();
1619 char *original = eventData;
1620
1621 // Tag
1622 int tag = get4LE(eventData);
1623 eventData += 4;
1624
1625 if (tag != TAG) {
1626 continue;
1627 }
1628
1629 // List type
1630 ASSERT_EQ(EVENT_TYPE_LIST, eventData[0]);
1631 eventData++;
1632
1633 // Number of elements in list
1634 ASSERT_EQ(3, eventData[0]);
1635 eventData++;
1636
1637 // Element #1: string type for subtag
1638 ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);
1639 eventData++;
1640
1641 ASSERT_EQ((int) strlen(SUBTAG), get4LE(eventData));
1642 eventData +=4;
1643
1644 if (memcmp(SUBTAG, eventData, strlen(SUBTAG))) {
1645 continue;
1646 }
1647 eventData += strlen(SUBTAG);
1648
1649 // Element #2: int type for uid
1650 ASSERT_EQ(EVENT_TYPE_INT, eventData[0]);
1651 eventData++;
1652
1653 ASSERT_EQ(UID, get4LE(eventData));
1654 eventData += 4;
1655
1656 // Element #3: string type for data
1657 ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);
1658 eventData++;
1659
1660 size_t dataLen = get4LE(eventData);
1661 eventData += 4;
1662
1663 if (memcmp(max_payload_buf, eventData, dataLen)) {
1664 continue;
1665 }
1666 eventData += dataLen;
1667
1668 // 4 bytes for the tag, and max_payload_buf should be truncated.
1669 ASSERT_LE(4 + 512, eventData - original); // worst expectations
1670 ASSERT_GT(4 + DATA_LEN, eventData - original); // must be truncated
1671
1672 ++count;
1673 }
1674
1675 EXPECT_EQ(1, count);
1676
1677 android_logger_list_close(logger_list);
1678 }
1679
TEST(liblog,android_errorWriteWithInfoLog__android_logger_list_read__null_data)1680 TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__null_data) {
1681 const int TAG = 123456783;
1682 const char SUBTAG[] = "test-subtag";
1683 const int UID = -1;
1684 const int DATA_LEN = 200;
1685 struct logger_list *logger_list;
1686
1687 pid_t pid = getpid();
1688
1689 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
1690 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
1691
1692 ASSERT_GT(0, android_errorWriteWithInfoLog(
1693 TAG, SUBTAG, UID, NULL, DATA_LEN));
1694
1695 sleep(2);
1696
1697 int count = 0;
1698
1699 for (;;) {
1700 log_msg log_msg;
1701 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
1702 break;
1703 }
1704
1705 char *eventData = log_msg.msg();
1706
1707 // Tag
1708 int tag = get4LE(eventData);
1709 eventData += 4;
1710
1711 if (tag == TAG) {
1712 // This tag should not have been written because the data was null
1713 count++;
1714 break;
1715 }
1716 }
1717
1718 EXPECT_EQ(0, count);
1719
1720 android_logger_list_close(logger_list);
1721 }
1722
TEST(liblog,android_errorWriteWithInfoLog__android_logger_list_read__subtag_too_long)1723 TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__subtag_too_long) {
1724 const int TAG = 123456784;
1725 const char SUBTAG[] = "abcdefghijklmnopqrstuvwxyz now i know my abc";
1726 const int UID = -1;
1727 const int DATA_LEN = 200;
1728 struct logger_list *logger_list;
1729
1730 pid_t pid = getpid();
1731
1732 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
1733 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
1734
1735 ASSERT_LT(0, android_errorWriteWithInfoLog(
1736 TAG, SUBTAG, UID, max_payload_buf, DATA_LEN));
1737
1738 sleep(2);
1739
1740 int count = 0;
1741
1742 for (;;) {
1743 log_msg log_msg;
1744 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
1745 break;
1746 }
1747
1748 char *eventData = log_msg.msg();
1749
1750 // Tag
1751 int tag = get4LE(eventData);
1752 eventData += 4;
1753
1754 if (tag != TAG) {
1755 continue;
1756 }
1757
1758 // List type
1759 ASSERT_EQ(EVENT_TYPE_LIST, eventData[0]);
1760 eventData++;
1761
1762 // Number of elements in list
1763 ASSERT_EQ(3, eventData[0]);
1764 eventData++;
1765
1766 // Element #1: string type for subtag
1767 ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);
1768 eventData++;
1769
1770 // The subtag is longer than 32 and should be truncated to that.
1771 ASSERT_EQ(32, get4LE(eventData));
1772 eventData +=4;
1773
1774 if (memcmp(SUBTAG, eventData, 32)) {
1775 continue;
1776 }
1777 eventData += 32;
1778
1779 // Element #2: int type for uid
1780 ASSERT_EQ(EVENT_TYPE_INT, eventData[0]);
1781 eventData++;
1782
1783 ASSERT_EQ(UID, get4LE(eventData));
1784 eventData += 4;
1785
1786 // Element #3: string type for data
1787 ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);
1788 eventData++;
1789
1790 ASSERT_EQ(DATA_LEN, get4LE(eventData));
1791 eventData += 4;
1792
1793 if (memcmp(max_payload_buf, eventData, DATA_LEN)) {
1794 continue;
1795 }
1796
1797 ++count;
1798 }
1799
1800 EXPECT_EQ(1, count);
1801
1802 android_logger_list_close(logger_list);
1803 }
1804
TEST(liblog,android_errorWriteLog__android_logger_list_read__success)1805 TEST(liblog, android_errorWriteLog__android_logger_list_read__success) {
1806 const int TAG = 123456785;
1807 const char SUBTAG[] = "test-subtag";
1808 struct logger_list *logger_list;
1809
1810 pid_t pid = getpid();
1811
1812 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
1813 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
1814
1815 ASSERT_LT(0, android_errorWriteLog(TAG, SUBTAG));
1816
1817 sleep(2);
1818
1819 int count = 0;
1820
1821 for (;;) {
1822 log_msg log_msg;
1823 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
1824 break;
1825 }
1826
1827 char *eventData = log_msg.msg();
1828
1829 // Tag
1830 int tag = get4LE(eventData);
1831 eventData += 4;
1832
1833 if (tag != TAG) {
1834 continue;
1835 }
1836
1837 // List type
1838 ASSERT_EQ(EVENT_TYPE_LIST, eventData[0]);
1839 eventData++;
1840
1841 // Number of elements in list
1842 ASSERT_EQ(3, eventData[0]);
1843 eventData++;
1844
1845 // Element #1: string type for subtag
1846 ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);
1847 eventData++;
1848
1849 ASSERT_EQ((int) strlen(SUBTAG), get4LE(eventData));
1850 eventData +=4;
1851
1852 if (memcmp(SUBTAG, eventData, strlen(SUBTAG))) {
1853 continue;
1854 }
1855 ++count;
1856 }
1857
1858 EXPECT_EQ(1, count);
1859
1860 android_logger_list_close(logger_list);
1861 }
1862
TEST(liblog,android_errorWriteLog__android_logger_list_read__null_subtag)1863 TEST(liblog, android_errorWriteLog__android_logger_list_read__null_subtag) {
1864 const int TAG = 123456786;
1865 struct logger_list *logger_list;
1866
1867 pid_t pid = getpid();
1868
1869 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
1870 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
1871
1872 ASSERT_GT(0, android_errorWriteLog(TAG, NULL));
1873
1874 sleep(2);
1875
1876 int count = 0;
1877
1878 for (;;) {
1879 log_msg log_msg;
1880 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
1881 break;
1882 }
1883
1884 char *eventData = log_msg.msg();
1885
1886 // Tag
1887 int tag = get4LE(eventData);
1888 eventData += 4;
1889
1890 if (tag == TAG) {
1891 // This tag should not have been written because the data was null
1892 count++;
1893 break;
1894 }
1895 }
1896
1897 EXPECT_EQ(0, count);
1898
1899 android_logger_list_close(logger_list);
1900 }
1901
is_real_element(int type)1902 static int is_real_element(int type) {
1903 return ((type == EVENT_TYPE_INT) ||
1904 (type == EVENT_TYPE_LONG) ||
1905 (type == EVENT_TYPE_STRING) ||
1906 (type == EVENT_TYPE_FLOAT));
1907 }
1908
android_log_buffer_to_string(const char * msg,size_t len,char * strOut,size_t strOutLen)1909 int android_log_buffer_to_string(const char *msg, size_t len,
1910 char *strOut, size_t strOutLen) {
1911 android_log_context context = create_android_log_parser(msg, len);
1912 android_log_list_element elem;
1913 bool overflow = false;
1914 /* Reserve 1 byte for null terminator. */
1915 size_t origStrOutLen = strOutLen--;
1916
1917 if (!context) {
1918 return -EBADF;
1919 }
1920
1921 memset(&elem, 0, sizeof(elem));
1922
1923 size_t outCount;
1924
1925 do {
1926 elem = android_log_read_next(context);
1927 switch ((int)elem.type) {
1928 case EVENT_TYPE_LIST:
1929 if (strOutLen == 0) {
1930 overflow = true;
1931 } else {
1932 *strOut++ = '[';
1933 strOutLen--;
1934 }
1935 break;
1936
1937 case EVENT_TYPE_LIST_STOP:
1938 if (strOutLen == 0) {
1939 overflow = true;
1940 } else {
1941 *strOut++ = ']';
1942 strOutLen--;
1943 }
1944 break;
1945
1946 case EVENT_TYPE_INT:
1947 /*
1948 * snprintf also requires room for the null terminator, which
1949 * we don't care about but we have allocated enough room for
1950 * that
1951 */
1952 outCount = snprintf(strOut, strOutLen + 1,
1953 "%" PRId32, elem.data.int32);
1954 if (outCount <= strOutLen) {
1955 strOut += outCount;
1956 strOutLen -= outCount;
1957 } else {
1958 overflow = true;
1959 }
1960 break;
1961
1962 case EVENT_TYPE_LONG:
1963 /*
1964 * snprintf also requires room for the null terminator, which
1965 * we don't care about but we have allocated enough room for
1966 * that
1967 */
1968 outCount = snprintf(strOut, strOutLen + 1,
1969 "%" PRId64, elem.data.int64);
1970 if (outCount <= strOutLen) {
1971 strOut += outCount;
1972 strOutLen -= outCount;
1973 } else {
1974 overflow = true;
1975 }
1976 break;
1977
1978 case EVENT_TYPE_FLOAT:
1979 /*
1980 * snprintf also requires room for the null terminator, which
1981 * we don't care about but we have allocated enough room for
1982 * that
1983 */
1984 outCount = snprintf(strOut, strOutLen + 1, "%f", elem.data.float32);
1985 if (outCount <= strOutLen) {
1986 strOut += outCount;
1987 strOutLen -= outCount;
1988 } else {
1989 overflow = true;
1990 }
1991 break;
1992
1993 default:
1994 elem.complete = true;
1995 break;
1996
1997 case EVENT_TYPE_UNKNOWN:
1998 #if 0 // Ideal purity in the test, we want to complain about UNKNOWN showing up
1999 if (elem.complete) {
2000 break;
2001 }
2002 #endif
2003 elem.data.string = const_cast<char *>("<unknown>");
2004 elem.len = strlen(elem.data.string);
2005 /* FALLTHRU */
2006 case EVENT_TYPE_STRING:
2007 if (elem.len <= strOutLen) {
2008 memcpy(strOut, elem.data.string, elem.len);
2009 strOut += elem.len;
2010 strOutLen -= elem.len;
2011 } else if (strOutLen > 0) {
2012 /* copy what we can */
2013 memcpy(strOut, elem.data.string, strOutLen);
2014 strOut += strOutLen;
2015 strOutLen = 0;
2016 overflow = true;
2017 }
2018 break;
2019 }
2020
2021 if (elem.complete) {
2022 break;
2023 }
2024 /* Determine whether to put a comma or not. */
2025 if (!overflow && (is_real_element(elem.type) ||
2026 (elem.type == EVENT_TYPE_LIST_STOP))) {
2027 android_log_list_element next = android_log_peek_next(context);
2028 if (!next.complete && (is_real_element(next.type) ||
2029 (next.type == EVENT_TYPE_LIST))) {
2030 if (strOutLen == 0) {
2031 overflow = true;
2032 } else {
2033 *strOut++ = ',';
2034 strOutLen--;
2035 }
2036 }
2037 }
2038 } while ((elem.type != EVENT_TYPE_UNKNOWN) && !overflow && !elem.complete);
2039
2040 android_log_destroy(&context);
2041
2042 if (overflow) {
2043 if (strOutLen < origStrOutLen) {
2044 /* leave an indicator */
2045 *(strOut-1) = '!';
2046 } else {
2047 /* nothing was written at all */
2048 *strOut++ = '!';
2049 }
2050 }
2051 *strOut++ = '\0';
2052
2053 if ((elem.type == EVENT_TYPE_UNKNOWN) && !elem.complete) {
2054 fprintf(stderr, "Binary log entry conversion failed\n");
2055 return -EINVAL;
2056 }
2057
2058 return 0;
2059 }
2060
event_test_int32(uint32_t tag,size_t & expected_len)2061 static const char *event_test_int32(uint32_t tag, size_t &expected_len) {
2062 android_log_context ctx;
2063
2064 EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2065 if (!ctx) {
2066 return NULL;
2067 }
2068 EXPECT_LE(0, android_log_write_int32(ctx, 0x40302010));
2069 EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2070 EXPECT_LE(0, android_log_destroy(&ctx));
2071 EXPECT_TRUE(NULL == ctx);
2072
2073 expected_len = sizeof(uint32_t) +
2074 sizeof(uint8_t) + sizeof(uint32_t);
2075
2076 return "1076895760";
2077 }
2078
event_test_int64(uint32_t tag,size_t & expected_len)2079 static const char *event_test_int64(uint32_t tag, size_t &expected_len) {
2080 android_log_context ctx;
2081
2082 EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2083 if (!ctx) {
2084 return NULL;
2085 }
2086 EXPECT_LE(0, android_log_write_int64(ctx, 0x8070605040302010));
2087 EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2088 EXPECT_LE(0, android_log_destroy(&ctx));
2089 EXPECT_TRUE(NULL == ctx);
2090
2091 expected_len = sizeof(uint32_t) +
2092 sizeof(uint8_t) + sizeof(uint64_t);
2093
2094 return "-9191740941672636400";
2095 }
2096
event_test_list_int64(uint32_t tag,size_t & expected_len)2097 static const char *event_test_list_int64(uint32_t tag, size_t &expected_len) {
2098 android_log_context ctx;
2099
2100 EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2101 if (!ctx) {
2102 return NULL;
2103 }
2104 EXPECT_LE(0, android_log_write_list_begin(ctx));
2105 EXPECT_LE(0, android_log_write_int64(ctx, 0x8070605040302010));
2106 EXPECT_LE(0, android_log_write_list_end(ctx));
2107 EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2108 EXPECT_LE(0, android_log_destroy(&ctx));
2109 EXPECT_TRUE(NULL == ctx);
2110
2111 expected_len = sizeof(uint32_t) +
2112 sizeof(uint8_t) + sizeof(uint8_t) +
2113 sizeof(uint8_t) + sizeof(uint64_t);
2114
2115 return "[-9191740941672636400]";
2116 }
2117
event_test_simple_automagic_list(uint32_t tag,size_t & expected_len)2118 static const char *event_test_simple_automagic_list(uint32_t tag, size_t &expected_len) {
2119 android_log_context ctx;
2120
2121 EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2122 if (!ctx) {
2123 return NULL;
2124 }
2125 // The convenience API where we allow a simple list to be
2126 // created without explicit begin or end calls.
2127 EXPECT_LE(0, android_log_write_int32(ctx, 0x40302010));
2128 EXPECT_LE(0, android_log_write_int64(ctx, 0x8070605040302010));
2129 EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2130 EXPECT_LE(0, android_log_destroy(&ctx));
2131 EXPECT_TRUE(NULL == ctx);
2132
2133 expected_len = sizeof(uint32_t) +
2134 sizeof(uint8_t) + sizeof(uint8_t) +
2135 sizeof(uint8_t) + sizeof(uint32_t) +
2136 sizeof(uint8_t) + sizeof(uint64_t);
2137
2138 return "[1076895760,-9191740941672636400]";
2139 }
2140
event_test_list_empty(uint32_t tag,size_t & expected_len)2141 static const char *event_test_list_empty(uint32_t tag, size_t &expected_len) {
2142 android_log_context ctx;
2143
2144 EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2145 if (!ctx) {
2146 return NULL;
2147 }
2148 EXPECT_LE(0, android_log_write_list_begin(ctx));
2149 EXPECT_LE(0, android_log_write_list_end(ctx));
2150 EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2151 EXPECT_LE(0, android_log_destroy(&ctx));
2152 EXPECT_TRUE(NULL == ctx);
2153
2154 expected_len = sizeof(uint32_t) +
2155 sizeof(uint8_t) + sizeof(uint8_t);
2156
2157 return "[]";
2158 }
2159
event_test_complex_nested_list(uint32_t tag,size_t & expected_len)2160 static const char *event_test_complex_nested_list(uint32_t tag, size_t &expected_len) {
2161 android_log_context ctx;
2162
2163 EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2164 if (!ctx) {
2165 return NULL;
2166 }
2167
2168 EXPECT_LE(0, android_log_write_list_begin(ctx)); // [
2169 EXPECT_LE(0, android_log_write_int32(ctx, 0x01020304));
2170 EXPECT_LE(0, android_log_write_int64(ctx, 0x0102030405060708));
2171 EXPECT_LE(0, android_log_write_string8(ctx, "Hello World"));
2172 EXPECT_LE(0, android_log_write_list_begin(ctx)); // [
2173 EXPECT_LE(0, android_log_write_int32(ctx, 1));
2174 EXPECT_LE(0, android_log_write_int32(ctx, 2));
2175 EXPECT_LE(0, android_log_write_int32(ctx, 3));
2176 EXPECT_LE(0, android_log_write_int32(ctx, 4));
2177 EXPECT_LE(0, android_log_write_list_end(ctx)); // ]
2178 EXPECT_LE(0, android_log_write_float32(ctx, 1.0102030405060708));
2179 EXPECT_LE(0, android_log_write_list_end(ctx)); // ]
2180
2181 //
2182 // This one checks for the automagic list creation because a list
2183 // begin and end was missing for it! This is actually an <oops> corner
2184 // case, and not the behavior we morally support. The automagic API is to
2185 // allow for a simple case of a series of objects in a single list. e.g.
2186 // int32,int32,int32,string -> [int32,int32,int32,string]
2187 //
2188 EXPECT_LE(0, android_log_write_string8(ctx, "dlroW olleH"));
2189
2190 EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2191 EXPECT_LE(0, android_log_destroy(&ctx));
2192 EXPECT_TRUE(NULL == ctx);
2193
2194 expected_len = sizeof(uint32_t) +
2195 sizeof(uint8_t) + sizeof(uint8_t) +
2196 sizeof(uint8_t) + sizeof(uint8_t) +
2197 sizeof(uint8_t) + sizeof(uint32_t) +
2198 sizeof(uint8_t) + sizeof(uint64_t) +
2199 sizeof(uint8_t) + sizeof(uint32_t) +
2200 sizeof("Hello World") - 1 +
2201 sizeof(uint8_t) + sizeof(uint8_t) +
2202 4 * (sizeof(uint8_t) + sizeof(uint32_t)) +
2203 sizeof(uint8_t) + sizeof(uint32_t) +
2204 sizeof(uint8_t) + sizeof(uint32_t) +
2205 sizeof("dlroW olleH") - 1;
2206
2207 return "[[16909060,72623859790382856,Hello World,[1,2,3,4],1.010203],dlroW olleH]";
2208 }
2209
event_test_7_level_prefix(uint32_t tag,size_t & expected_len)2210 static const char *event_test_7_level_prefix(uint32_t tag, size_t &expected_len) {
2211 android_log_context ctx;
2212
2213 EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2214 if (!ctx) {
2215 return NULL;
2216 }
2217 EXPECT_LE(0, android_log_write_list_begin(ctx));
2218 EXPECT_LE(0, android_log_write_list_begin(ctx));
2219 EXPECT_LE(0, android_log_write_list_begin(ctx));
2220 EXPECT_LE(0, android_log_write_list_begin(ctx));
2221 EXPECT_LE(0, android_log_write_list_begin(ctx));
2222 EXPECT_LE(0, android_log_write_list_begin(ctx));
2223 EXPECT_LE(0, android_log_write_list_begin(ctx));
2224 EXPECT_LE(0, android_log_write_int32(ctx, 1));
2225 EXPECT_LE(0, android_log_write_list_end(ctx));
2226 EXPECT_LE(0, android_log_write_int32(ctx, 2));
2227 EXPECT_LE(0, android_log_write_list_end(ctx));
2228 EXPECT_LE(0, android_log_write_int32(ctx, 3));
2229 EXPECT_LE(0, android_log_write_list_end(ctx));
2230 EXPECT_LE(0, android_log_write_int32(ctx, 4));
2231 EXPECT_LE(0, android_log_write_list_end(ctx));
2232 EXPECT_LE(0, android_log_write_int32(ctx, 5));
2233 EXPECT_LE(0, android_log_write_list_end(ctx));
2234 EXPECT_LE(0, android_log_write_int32(ctx, 6));
2235 EXPECT_LE(0, android_log_write_list_end(ctx));
2236 EXPECT_LE(0, android_log_write_int32(ctx, 7));
2237 EXPECT_LE(0, android_log_write_list_end(ctx));
2238 EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2239 EXPECT_LE(0, android_log_destroy(&ctx));
2240 EXPECT_TRUE(NULL == ctx);
2241
2242 expected_len = sizeof(uint32_t) + 7 *
2243 (sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint32_t));
2244
2245 return "[[[[[[[1],2],3],4],5],6],7]";
2246 }
2247
event_test_7_level_suffix(uint32_t tag,size_t & expected_len)2248 static const char *event_test_7_level_suffix(uint32_t tag, size_t &expected_len) {
2249 android_log_context ctx;
2250
2251 EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2252 if (!ctx) {
2253 return NULL;
2254 }
2255 EXPECT_LE(0, android_log_write_list_begin(ctx));
2256 EXPECT_LE(0, android_log_write_int32(ctx, 1));
2257 EXPECT_LE(0, android_log_write_list_begin(ctx));
2258 EXPECT_LE(0, android_log_write_int32(ctx, 2));
2259 EXPECT_LE(0, android_log_write_list_begin(ctx));
2260 EXPECT_LE(0, android_log_write_int32(ctx, 3));
2261 EXPECT_LE(0, android_log_write_list_begin(ctx));
2262 EXPECT_LE(0, android_log_write_int32(ctx, 4));
2263 EXPECT_LE(0, android_log_write_list_begin(ctx));
2264 EXPECT_LE(0, android_log_write_int32(ctx, 5));
2265 EXPECT_LE(0, android_log_write_list_begin(ctx));
2266 EXPECT_LE(0, android_log_write_int32(ctx, 6));
2267 EXPECT_LE(0, android_log_write_list_end(ctx));
2268 EXPECT_LE(0, android_log_write_list_end(ctx));
2269 EXPECT_LE(0, android_log_write_list_end(ctx));
2270 EXPECT_LE(0, android_log_write_list_end(ctx));
2271 EXPECT_LE(0, android_log_write_list_end(ctx));
2272 EXPECT_LE(0, android_log_write_list_end(ctx));
2273 EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2274 EXPECT_LE(0, android_log_destroy(&ctx));
2275 EXPECT_TRUE(NULL == ctx);
2276
2277 expected_len = sizeof(uint32_t) + 6 *
2278 (sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint32_t));
2279
2280 return "[1,[2,[3,[4,[5,[6]]]]]]";
2281 }
2282
event_test_android_log_error_write(uint32_t tag,size_t & expected_len)2283 static const char *event_test_android_log_error_write(uint32_t tag, size_t &expected_len) {
2284 EXPECT_LE(0, __android_log_error_write(tag, "Hello World", 42, "dlroW olleH", 11));
2285
2286 expected_len = sizeof(uint32_t) +
2287 sizeof(uint8_t) + sizeof(uint8_t) +
2288 sizeof(uint8_t) + sizeof(uint32_t) + sizeof("Hello World") - 1 +
2289 sizeof(uint8_t) + sizeof(uint32_t) +
2290 sizeof(uint8_t) + sizeof(uint32_t) + sizeof("dlroW olleH") - 1;
2291
2292 return "[Hello World,42,dlroW olleH]";
2293 }
2294
event_test_android_log_error_write_null(uint32_t tag,size_t & expected_len)2295 static const char *event_test_android_log_error_write_null(uint32_t tag, size_t &expected_len) {
2296 EXPECT_LE(0, __android_log_error_write(tag, "Hello World", 42, NULL, 0));
2297
2298 expected_len = sizeof(uint32_t) +
2299 sizeof(uint8_t) + sizeof(uint8_t) +
2300 sizeof(uint8_t) + sizeof(uint32_t) + sizeof("Hello World") - 1 +
2301 sizeof(uint8_t) + sizeof(uint32_t) +
2302 sizeof(uint8_t) + sizeof(uint32_t) + sizeof("") - 1;
2303
2304 return "[Hello World,42,]";
2305 }
2306
2307 // make sure all user buffers are flushed
print_barrier()2308 static void print_barrier() {
2309 std::cout.flush();
2310 fflush(stdout);
2311 std::cerr.flush();
2312 fflush(stderr); // everything else is paranoia ...
2313 }
2314
create_android_logger(const char * (* fn)(uint32_t tag,size_t & expected_len))2315 static void create_android_logger(const char *(*fn)(uint32_t tag, size_t &expected_len)) {
2316 struct logger_list *logger_list;
2317
2318 pid_t pid = getpid();
2319
2320 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
2321 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
2322
2323 log_time ts(android_log_clockid());
2324
2325 size_t expected_len;
2326 const char *expected_string = (*fn)(1005, expected_len);
2327
2328 if (!expected_string) {
2329 android_logger_list_close(logger_list);
2330 return;
2331 }
2332
2333 usleep(1000000);
2334
2335 int count = 0;
2336
2337 for (;;) {
2338 log_msg log_msg;
2339 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
2340 break;
2341 }
2342
2343 ASSERT_EQ(log_msg.entry.pid, pid);
2344
2345 if ((log_msg.entry.sec < (ts.tv_sec - 1))
2346 || ((ts.tv_sec + 1) < log_msg.entry.sec)
2347 || ((size_t)log_msg.entry.len != expected_len)
2348 || (log_msg.id() != LOG_ID_EVENTS)) {
2349 continue;
2350 }
2351
2352 char *eventData = log_msg.msg();
2353
2354 ++count;
2355
2356 AndroidLogFormat *logformat = android_log_format_new();
2357 EXPECT_TRUE(NULL != logformat);
2358 AndroidLogEntry entry;
2359 char msgBuf[1024];
2360 int processBinaryLogBuffer = android_log_processBinaryLogBuffer(
2361 &log_msg.entry_v1, &entry, NULL, msgBuf, sizeof(msgBuf));
2362 EXPECT_EQ(0, processBinaryLogBuffer);
2363 if (processBinaryLogBuffer == 0) {
2364 print_barrier();
2365 int printLogLine = android_log_printLogLine(
2366 logformat, fileno(stderr), &entry);
2367 print_barrier();
2368 EXPECT_EQ(20 + (int)strlen(expected_string), printLogLine);
2369 }
2370 android_log_format_free(logformat);
2371
2372 // test buffer reading API
2373 snprintf(msgBuf, sizeof(msgBuf), "I/[%d]", get4LE(eventData));
2374 print_barrier();
2375 fprintf(stderr, "%-10s(%5u): ", msgBuf, pid);
2376 memset(msgBuf, 0, sizeof(msgBuf));
2377 int buffer_to_string = android_log_buffer_to_string(
2378 eventData + sizeof(uint32_t),
2379 log_msg.entry.len - sizeof(uint32_t),
2380 msgBuf, sizeof(msgBuf));
2381 fprintf(stderr, "%s\n", msgBuf);
2382 print_barrier();
2383 EXPECT_EQ(0, buffer_to_string);
2384 EXPECT_EQ(strlen(expected_string), strlen(msgBuf));
2385 EXPECT_EQ(0, strcmp(expected_string, msgBuf));
2386 }
2387
2388 EXPECT_EQ(1, count);
2389
2390 android_logger_list_close(logger_list);
2391 }
2392
TEST(liblog,create_android_logger_int32)2393 TEST(liblog, create_android_logger_int32) {
2394 create_android_logger(event_test_int32);
2395 }
2396
TEST(liblog,create_android_logger_int64)2397 TEST(liblog, create_android_logger_int64) {
2398 create_android_logger(event_test_int64);
2399 }
2400
TEST(liblog,create_android_logger_list_int64)2401 TEST(liblog, create_android_logger_list_int64) {
2402 create_android_logger(event_test_list_int64);
2403 }
2404
TEST(liblog,create_android_logger_simple_automagic_list)2405 TEST(liblog, create_android_logger_simple_automagic_list) {
2406 create_android_logger(event_test_simple_automagic_list);
2407 }
2408
TEST(liblog,create_android_logger_list_empty)2409 TEST(liblog, create_android_logger_list_empty) {
2410 create_android_logger(event_test_list_empty);
2411 }
2412
TEST(liblog,create_android_logger_complex_nested_list)2413 TEST(liblog, create_android_logger_complex_nested_list) {
2414 create_android_logger(event_test_complex_nested_list);
2415 }
2416
TEST(liblog,create_android_logger_7_level_prefix)2417 TEST(liblog, create_android_logger_7_level_prefix) {
2418 create_android_logger(event_test_7_level_prefix);
2419 }
2420
TEST(liblog,create_android_logger_7_level_suffix)2421 TEST(liblog, create_android_logger_7_level_suffix) {
2422 create_android_logger(event_test_7_level_suffix);
2423 }
2424
TEST(liblog,create_android_logger_android_log_error_write)2425 TEST(liblog, create_android_logger_android_log_error_write) {
2426 create_android_logger(event_test_android_log_error_write);
2427 }
2428
TEST(liblog,create_android_logger_android_log_error_write_null)2429 TEST(liblog, create_android_logger_android_log_error_write_null) {
2430 create_android_logger(event_test_android_log_error_write_null);
2431 }
2432
TEST(liblog,create_android_logger_overflow)2433 TEST(liblog, create_android_logger_overflow) {
2434 android_log_context ctx;
2435
2436 EXPECT_TRUE(NULL != (ctx = create_android_logger(1005)));
2437 if (ctx) {
2438 for (size_t i = 0; i < ANDROID_MAX_LIST_NEST_DEPTH; ++i) {
2439 EXPECT_LE(0, android_log_write_list_begin(ctx));
2440 }
2441 EXPECT_GT(0, android_log_write_list_begin(ctx));
2442 /* One more for good measure, must be permanently unhappy */
2443 EXPECT_GT(0, android_log_write_list_begin(ctx));
2444 EXPECT_LE(0, android_log_destroy(&ctx));
2445 EXPECT_TRUE(NULL == ctx);
2446 }
2447
2448 ASSERT_TRUE(NULL != (ctx = create_android_logger(1005)));
2449 for (size_t i = 0; i < ANDROID_MAX_LIST_NEST_DEPTH; ++i) {
2450 EXPECT_LE(0, android_log_write_list_begin(ctx));
2451 EXPECT_LE(0, android_log_write_int32(ctx, i));
2452 }
2453 EXPECT_GT(0, android_log_write_list_begin(ctx));
2454 /* One more for good measure, must be permanently unhappy */
2455 EXPECT_GT(0, android_log_write_list_begin(ctx));
2456 EXPECT_LE(0, android_log_destroy(&ctx));
2457 ASSERT_TRUE(NULL == ctx);
2458 }
2459
2460 static const char __pmsg_file[] =
2461 "/data/william-shakespeare/MuchAdoAboutNothing.txt";
2462
TEST(liblog,__android_log_pmsg_file_write)2463 TEST(liblog, __android_log_pmsg_file_write) {
2464 EXPECT_LT(0, __android_log_pmsg_file_write(
2465 LOG_ID_CRASH, ANDROID_LOG_VERBOSE,
2466 __pmsg_file, max_payload_buf, sizeof(max_payload_buf)));
2467 fprintf(stderr, "Reboot, ensure file %s matches\n"
2468 "with liblog.__android_log_msg_file_read test\n",
2469 __pmsg_file);
2470 }
2471
__pmsg_fn(log_id_t logId,char prio,const char * filename,const char * buf,size_t len,void * arg)2472 ssize_t __pmsg_fn(log_id_t logId, char prio, const char *filename,
2473 const char *buf, size_t len, void *arg) {
2474 EXPECT_TRUE(NULL == arg);
2475 EXPECT_EQ(LOG_ID_CRASH, logId);
2476 EXPECT_EQ(ANDROID_LOG_VERBOSE, prio);
2477 EXPECT_FALSE(NULL == strstr(__pmsg_file, filename));
2478 EXPECT_EQ(len, sizeof(max_payload_buf));
2479 EXPECT_EQ(0, strcmp(max_payload_buf, buf));
2480
2481 ++signaled;
2482 if ((len != sizeof(max_payload_buf)) ||
2483 strcmp(max_payload_buf, buf)) {
2484 fprintf(stderr, "comparison fails on content \"%s\"\n", buf);
2485 }
2486 return !arg ||
2487 (LOG_ID_CRASH != logId) ||
2488 (ANDROID_LOG_VERBOSE != prio) ||
2489 !strstr(__pmsg_file, filename) ||
2490 (len != sizeof(max_payload_buf)) ||
2491 !!strcmp(max_payload_buf, buf) ? -ENOEXEC : 1;
2492 }
2493
TEST(liblog,__android_log_pmsg_file_read)2494 TEST(liblog, __android_log_pmsg_file_read) {
2495 signaled = 0;
2496
2497 ssize_t ret = __android_log_pmsg_file_read(
2498 LOG_ID_CRASH, ANDROID_LOG_VERBOSE,
2499 __pmsg_file, __pmsg_fn, NULL);
2500
2501 if (ret == -ENOENT) {
2502 fprintf(stderr,
2503 "No pre-boot results of liblog.__android_log_mesg_file_write to "
2504 "compare with,\n"
2505 "false positive test result.\n");
2506 return;
2507 }
2508
2509 EXPECT_LT(0, ret);
2510 EXPECT_EQ(1U, signaled);
2511 }
2512