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