• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013-2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <fcntl.h>
18 #include <inttypes.h>
19 #include <signal.h>
20 #include <gtest/gtest.h>
21 #include <log/log.h>
22 #include <log/logger.h>
23 #include <log/log_read.h>
24 #include <log/logprint.h>
25 
26 // enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and
27 // non-syscall libs. Since we are only using this in the emergency of
28 // a signal to stuff a terminating code into the logs, we will spin rather
29 // than try a usleep.
30 #define LOG_FAILURE_RETRY(exp) ({  \
31     typeof (exp) _rc;              \
32     do {                           \
33         _rc = (exp);               \
34     } while (((_rc == -1)          \
35            && ((errno == EINTR)    \
36             || (errno == EAGAIN))) \
37           || (_rc == -EINTR)       \
38           || (_rc == -EAGAIN));    \
39     _rc; })
40 
TEST(liblog,__android_log_buf_print)41 TEST(liblog, __android_log_buf_print) {
42     EXPECT_LT(0, __android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO,
43                                          "TEST__android_log_buf_print",
44                                          "radio"));
45     usleep(1000);
46     EXPECT_LT(0, __android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
47                                          "TEST__android_log_buf_print",
48                                          "system"));
49     usleep(1000);
50     EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
51                                          "TEST__android_log_buf_print",
52                                          "main"));
53     usleep(1000);
54 }
55 
TEST(liblog,__android_log_buf_write)56 TEST(liblog, __android_log_buf_write) {
57     EXPECT_LT(0, __android_log_buf_write(LOG_ID_RADIO, ANDROID_LOG_INFO,
58                                          "TEST__android_log_buf_write",
59                                          "radio"));
60     usleep(1000);
61     EXPECT_LT(0, __android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
62                                          "TEST__android_log_buf_write",
63                                          "system"));
64     usleep(1000);
65     EXPECT_LT(0, __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO,
66                                          "TEST__android_log_buf_write",
67                                          "main"));
68     usleep(1000);
69 }
70 
TEST(liblog,__android_log_btwrite)71 TEST(liblog, __android_log_btwrite) {
72     int intBuf = 0xDEADBEEF;
73     EXPECT_LT(0, __android_log_btwrite(0,
74                                       EVENT_TYPE_INT,
75                                       &intBuf, sizeof(intBuf)));
76     long long longBuf = 0xDEADBEEFA55A5AA5;
77     EXPECT_LT(0, __android_log_btwrite(0,
78                                       EVENT_TYPE_LONG,
79                                       &longBuf, sizeof(longBuf)));
80     usleep(1000);
81     char Buf[] = "\20\0\0\0DeAdBeEfA55a5aA5";
82     EXPECT_LT(0, __android_log_btwrite(0,
83                                       EVENT_TYPE_STRING,
84                                       Buf, sizeof(Buf) - 1));
85     usleep(1000);
86 }
87 
ConcurrentPrintFn(void * arg)88 static void* ConcurrentPrintFn(void *arg) {
89     int ret = __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
90                                   "TEST__android_log_print", "Concurrent %" PRIuPTR,
91                                   reinterpret_cast<uintptr_t>(arg));
92     return reinterpret_cast<void*>(ret);
93 }
94 
95 #define NUM_CONCURRENT 64
96 #define _concurrent_name(a,n) a##__concurrent##n
97 #define concurrent_name(a,n) _concurrent_name(a,n)
98 
TEST(liblog,concurrent_name (__android_log_buf_print,NUM_CONCURRENT))99 TEST(liblog, concurrent_name(__android_log_buf_print, NUM_CONCURRENT)) {
100     pthread_t t[NUM_CONCURRENT];
101     int i;
102     for (i=0; i < NUM_CONCURRENT; i++) {
103         ASSERT_EQ(0, pthread_create(&t[i], NULL,
104                                     ConcurrentPrintFn,
105                                     reinterpret_cast<void *>(i)));
106     }
107     int ret = 0;
108     for (i=0; i < NUM_CONCURRENT; i++) {
109         void* result;
110         ASSERT_EQ(0, pthread_join(t[i], &result));
111         int this_result = reinterpret_cast<uintptr_t>(result);
112         if ((0 == ret) && (0 != this_result)) {
113             ret = this_result;
114         }
115     }
116     ASSERT_LT(0, ret);
117 }
118 
TEST(liblog,__android_log_btwrite__android_logger_list_read)119 TEST(liblog, __android_log_btwrite__android_logger_list_read) {
120     struct logger_list *logger_list;
121 
122     pid_t pid = getpid();
123 
124     ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
125         LOG_ID_EVENTS, O_RDONLY | O_NDELAY, 1000, pid)));
126 
127     log_time ts(CLOCK_MONOTONIC);
128 
129     ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
130     usleep(1000000);
131 
132     int count = 0;
133 
134     for (;;) {
135         log_msg log_msg;
136         if (android_logger_list_read(logger_list, &log_msg) <= 0) {
137             break;
138         }
139 
140         ASSERT_EQ(log_msg.entry.pid, pid);
141 
142         if ((log_msg.entry.len != (4 + 1 + 8))
143          || (log_msg.id() != LOG_ID_EVENTS)) {
144             continue;
145         }
146 
147         char *eventData = log_msg.msg();
148 
149         if (eventData[4] != EVENT_TYPE_LONG) {
150             continue;
151         }
152 
153         log_time tx(eventData + 4 + 1);
154         if (ts == tx) {
155             ++count;
156         }
157     }
158 
159     EXPECT_EQ(1, count);
160 
161     android_logger_list_close(logger_list);
162 }
163 
164 static unsigned signaled;
165 log_time signal_time;
166 
caught_blocking(int)167 static void caught_blocking(int /*signum*/)
168 {
169     unsigned long long v = 0xDEADBEEFA55A0000ULL;
170 
171     v += getpid() & 0xFFFF;
172 
173     ++signaled;
174     if ((signal_time.tv_sec == 0) && (signal_time.tv_nsec == 0)) {
175         signal_time = log_time(CLOCK_MONOTONIC);
176         signal_time.tv_sec += 2;
177     }
178 
179     LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
180 }
181 
182 // Fill in current process user and system time in 10ms increments
get_ticks(unsigned long long * uticks,unsigned long long * sticks)183 static void get_ticks(unsigned long long *uticks, unsigned long long *sticks)
184 {
185     *uticks = *sticks = 0;
186 
187     pid_t pid = getpid();
188 
189     char buffer[512];
190     snprintf(buffer, sizeof(buffer), "/proc/%u/stat", pid);
191 
192     FILE *fp = fopen(buffer, "r");
193     if (!fp) {
194         return;
195     }
196 
197     char *cp = fgets(buffer, sizeof(buffer), fp);
198     fclose(fp);
199     if (!cp) {
200         return;
201     }
202 
203     pid_t d;
204     char s[sizeof(buffer)];
205     char c;
206     long long ll;
207     unsigned long long ull;
208 
209     if (15 != sscanf(buffer,
210       "%d %s %c %lld %lld %lld %lld %lld %llu %llu %llu %llu %llu %llu %llu ",
211       &d, s, &c, &ll, &ll, &ll, &ll, &ll, &ull, &ull, &ull, &ull, &ull,
212       uticks, sticks)) {
213         *uticks = *sticks = 0;
214     }
215 }
216 
TEST(liblog,android_logger_list_read__cpu)217 TEST(liblog, android_logger_list_read__cpu) {
218     struct logger_list *logger_list;
219     unsigned long long v = 0xDEADBEEFA55A0000ULL;
220 
221     pid_t pid = getpid();
222 
223     v += pid & 0xFFFF;
224 
225     ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
226         LOG_ID_EVENTS, O_RDONLY, 1000, pid)));
227 
228     int count = 0;
229 
230     int signals = 0;
231 
232     unsigned long long uticks_start;
233     unsigned long long sticks_start;
234     get_ticks(&uticks_start, &sticks_start);
235 
236     const unsigned alarm_time = 10;
237 
238     memset(&signal_time, 0, sizeof(signal_time));
239 
240     signal(SIGALRM, caught_blocking);
241     alarm(alarm_time);
242 
243     signaled = 0;
244 
245     do {
246         log_msg log_msg;
247         if (android_logger_list_read(logger_list, &log_msg) <= 0) {
248             break;
249         }
250 
251         alarm(alarm_time);
252 
253         ++count;
254 
255         ASSERT_EQ(log_msg.entry.pid, pid);
256 
257         if ((log_msg.entry.len != (4 + 1 + 8))
258          || (log_msg.id() != LOG_ID_EVENTS)) {
259             continue;
260         }
261 
262         char *eventData = log_msg.msg();
263 
264         if (eventData[4] != EVENT_TYPE_LONG) {
265             continue;
266         }
267 
268         unsigned long long l = eventData[4 + 1 + 0] & 0xFF;
269         l |= (unsigned long long) (eventData[4 + 1 + 1] & 0xFF) << 8;
270         l |= (unsigned long long) (eventData[4 + 1 + 2] & 0xFF) << 16;
271         l |= (unsigned long long) (eventData[4 + 1 + 3] & 0xFF) << 24;
272         l |= (unsigned long long) (eventData[4 + 1 + 4] & 0xFF) << 32;
273         l |= (unsigned long long) (eventData[4 + 1 + 5] & 0xFF) << 40;
274         l |= (unsigned long long) (eventData[4 + 1 + 6] & 0xFF) << 48;
275         l |= (unsigned long long) (eventData[4 + 1 + 7] & 0xFF) << 56;
276 
277         if (l == v) {
278             ++signals;
279             break;
280         }
281     } while (!signaled || (log_time(CLOCK_MONOTONIC) < signal_time));
282     alarm(0);
283     signal(SIGALRM, SIG_DFL);
284 
285     EXPECT_LT(1, count);
286 
287     EXPECT_EQ(1, signals);
288 
289     android_logger_list_close(logger_list);
290 
291     unsigned long long uticks_end;
292     unsigned long long sticks_end;
293     get_ticks(&uticks_end, &sticks_end);
294 
295     // Less than 1% in either user or system time, or both
296     const unsigned long long one_percent_ticks = alarm_time;
297     unsigned long long user_ticks = uticks_end - uticks_start;
298     unsigned long long system_ticks = sticks_end - sticks_start;
299     EXPECT_GT(one_percent_ticks, user_ticks);
300     EXPECT_GT(one_percent_ticks, system_ticks);
301     EXPECT_GT(one_percent_ticks, user_ticks + system_ticks);
302 }
303 
304 static const char max_payload_tag[] = "TEST_max_payload_XXXX";
305 static const char max_payload_buf[LOGGER_ENTRY_MAX_PAYLOAD
306     - sizeof(max_payload_tag) - 1] = "LEONATO\n\
307 I learn in this letter that Don Peter of Arragon\n\
308 comes this night to Messina\n\
309 MESSENGER\n\
310 He is very near by this: he was not three leagues off\n\
311 when I left him\n\
312 LEONATO\n\
313 How many gentlemen have you lost in this action?\n\
314 MESSENGER\n\
315 But few of any sort, and none of name\n\
316 LEONATO\n\
317 A victory is twice itself when the achiever brings\n\
318 home full numbers. I find here that Don Peter hath\n\
319 bestowed much honour on a young Florentine called Claudio\n\
320 MESSENGER\n\
321 Much deserved on his part and equally remembered by\n\
322 Don Pedro: he hath borne himself beyond the\n\
323 promise of his age, doing, in the figure of a lamb,\n\
324 the feats of a lion: he hath indeed better\n\
325 bettered expectation than you must expect of me to\n\
326 tell you how\n\
327 LEONATO\n\
328 He hath an uncle here in Messina will be very much\n\
329 glad of it.\n\
330 MESSENGER\n\
331 I have already delivered him letters, and there\n\
332 appears much joy in him; even so much that joy could\n\
333 not show itself modest enough without a badge of\n\
334 bitterness.\n\
335 LEONATO\n\
336 Did he break out into tears?\n\
337 MESSENGER\n\
338 In great measure.\n\
339 LEONATO\n\
340 A kind overflow of kindness: there are no faces\n\
341 truer than those that are so washed. How much\n\
342 better is it to weep at joy than to joy at weeping!\n\
343 BEATRICE\n\
344 I pray you, is Signior Mountanto returned from the\n\
345 wars or no?\n\
346 MESSENGER\n\
347 I know none of that name, lady: there was none such\n\
348 in the army of any sort.\n\
349 LEONATO\n\
350 What is he that you ask for, niece?\n\
351 HERO\n\
352 My cousin means Signior Benedick of Padua.\n\
353 MESSENGER\n\
354 O, he's returned; and as pleasant as ever he was.\n\
355 BEATRICE\n\
356 He set up his bills here in Messina and challenged\n\
357 Cupid at the flight; and my uncle's fool, reading\n\
358 the challenge, subscribed for Cupid, and challenged\n\
359 him at the bird-bolt. I pray you, how many hath he\n\
360 killed and eaten in these wars? But how many hath\n\
361 he killed? for indeed I promised to eat all of his killing.\n\
362 LEONATO\n\
363 Faith, niece, you tax Signior Benedick too much;\n\
364 but he'll be meet with you, I doubt it not.\n\
365 MESSENGER\n\
366 He hath done good service, lady, in these wars.\n\
367 BEATRICE\n\
368 You had musty victual, and he hath holp to eat it:\n\
369 he is a very valiant trencherman; he hath an\n\
370 excellent stomach.\n\
371 MESSENGER\n\
372 And a good soldier too, lady.\n\
373 BEATRICE\n\
374 And a good soldier to a lady: but what is he to a lord?\n\
375 MESSENGER\n\
376 A lord to a lord, a man to a man; stuffed with all\n\
377 honourable virtues.\n\
378 BEATRICE\n\
379 It is so, indeed; he is no less than a stuffed man:\n\
380 but for the stuffing,--well, we are all mortal.\n\
381 LEONATO\n\
382 You must not, sir, mistake my niece. There is a\n\
383 kind of merry war betwixt Signior Benedick and her:\n\
384 they never meet but there's a skirmish of wit\n\
385 between them.\n\
386 BEATRICE\n\
387 Alas! he gets nothing by that. In our last\n\
388 conflict four of his five wits went halting off, and\n\
389 now is the whole man governed with one: so that if\n\
390 he have wit enough to keep himself warm, let him\n\
391 bear it for a difference between himself and his\n\
392 horse; for it is all the wealth that he hath left,\n\
393 to be known a reasonable creature. Who is his\n\
394 companion now? He hath every month a new sworn brother.\n\
395 MESSENGER\n\
396 Is't possible?\n\
397 BEATRICE\n\
398 Very easily possible: he wears his faith but as\n\
399 the fashion of his hat; it ever changes with the\n\
400 next block.\n\
401 MESSENGER\n\
402 I see, lady, the gentleman is not in your books.\n\
403 BEATRICE\n\
404 No; an he were, I would burn my study. But, I pray\n\
405 you, who is his companion? Is there no young\n\
406 squarer now that will make a voyage with him to the devil?\n\
407 MESSENGER\n\
408 He is most in the company of the right noble Claudio.\n\
409 BEATRICE\n\
410 O Lord, he will hang upon him like a disease: he\n\
411 is sooner caught than the pestilence, and the taker\n\
412 runs presently mad. God help the noble Claudio! if\n\
413 he have caught the Benedick, it will cost him a\n\
414 thousand pound ere a' be cured.\n\
415 MESSENGER\n\
416 I will hold friends with you, lady.\n\
417 BEATRICE\n\
418 Do, good friend.\n\
419 LEONATO\n\
420 You will never run mad, niece.\n\
421 BEATRICE\n\
422 No, not till a hot January.\n\
423 MESSENGER\n\
424 Don Pedro is approached.\n\
425 Enter DON PEDRO, DON JOHN, CLAUDIO, BENEDICK, and BALTHASAR\n\
426 \n\
427 DON PEDRO\n\
428 Good Signior Leonato, you are come to meet your\n\
429 trouble: the fashion of the world is to avoid\n\
430 cost, and you encounter it\n\
431 LEONATO\n\
432 Never came trouble to my house in the likeness";
433 
TEST(liblog,max_payload)434 TEST(liblog, max_payload) {
435     pid_t pid = getpid();
436     char tag[sizeof(max_payload_tag)];
437     memcpy(tag, max_payload_tag, sizeof(tag));
438     snprintf(tag + sizeof(tag) - 5, 5, "%04X", pid & 0xFFFF);
439 
440     LOG_FAILURE_RETRY(__android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
441                                               tag, max_payload_buf));
442 
443     struct logger_list *logger_list;
444 
445     ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
446         LOG_ID_SYSTEM, O_RDONLY, 100, 0)));
447 
448     bool matches = false;
449     ssize_t max_len = 0;
450 
451     for(;;) {
452         log_msg log_msg;
453         if (android_logger_list_read(logger_list, &log_msg) <= 0) {
454             break;
455         }
456 
457         if ((log_msg.entry.pid != pid) || (log_msg.id() != LOG_ID_SYSTEM)) {
458             continue;
459         }
460 
461         char *data = log_msg.msg() + 1;
462 
463         if (strcmp(data, tag)) {
464             continue;
465         }
466 
467         data += strlen(data) + 1;
468 
469         const char *left = data;
470         const char *right = max_payload_buf;
471         while (*left && *right && (*left == *right)) {
472             ++left;
473             ++right;
474         }
475 
476         if (max_len <= (left - data)) {
477             max_len = left - data + 1;
478         }
479 
480         if (max_len > 512) {
481             matches = true;
482             break;
483         }
484     }
485 
486     android_logger_list_close(logger_list);
487 
488     EXPECT_EQ(true, matches);
489 
490     EXPECT_LE(sizeof(max_payload_buf), static_cast<size_t>(max_len));
491 }
492 
TEST(liblog,too_big_payload)493 TEST(liblog, too_big_payload) {
494     pid_t pid = getpid();
495     static const char big_payload_tag[] = "TEST_big_payload_XXXX";
496     char tag[sizeof(big_payload_tag)];
497     memcpy(tag, big_payload_tag, sizeof(tag));
498     snprintf(tag + sizeof(tag) - 5, 5, "%04X", pid & 0xFFFF);
499 
500     std::string longString(3266519, 'x');
501 
502     ssize_t ret = LOG_FAILURE_RETRY(__android_log_buf_write(LOG_ID_SYSTEM,
503                                     ANDROID_LOG_INFO, tag, longString.c_str()));
504 
505     struct logger_list *logger_list;
506 
507     ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
508         LOG_ID_SYSTEM, O_RDONLY | O_NDELAY, 100, 0)));
509 
510     ssize_t max_len = 0;
511 
512     for(;;) {
513         log_msg log_msg;
514         if (android_logger_list_read(logger_list, &log_msg) <= 0) {
515             break;
516         }
517 
518         if ((log_msg.entry.pid != pid) || (log_msg.id() != LOG_ID_SYSTEM)) {
519             continue;
520         }
521 
522         char *data = log_msg.msg() + 1;
523 
524         if (strcmp(data, tag)) {
525             continue;
526         }
527 
528         data += strlen(data) + 1;
529 
530         const char *left = data;
531         const char *right = longString.c_str();
532         while (*left && *right && (*left == *right)) {
533             ++left;
534             ++right;
535         }
536 
537         if (max_len <= (left - data)) {
538             max_len = left - data + 1;
539         }
540     }
541 
542     android_logger_list_close(logger_list);
543 
544     EXPECT_LE(LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag),
545               static_cast<size_t>(max_len));
546 
547     EXPECT_EQ(ret, max_len + static_cast<ssize_t>(sizeof(big_payload_tag)));
548 }
549 
TEST(liblog,dual_reader)550 TEST(liblog, dual_reader) {
551     struct logger_list *logger_list1;
552 
553     // >25 messages due to liblog.__android_log_buf_print__concurrentXX above.
554     ASSERT_TRUE(NULL != (logger_list1 = android_logger_list_open(
555         LOG_ID_MAIN, O_RDONLY | O_NDELAY, 25, 0)));
556 
557     struct logger_list *logger_list2;
558 
559     if (NULL == (logger_list2 = android_logger_list_open(
560             LOG_ID_MAIN, O_RDONLY | O_NDELAY, 15, 0))) {
561         android_logger_list_close(logger_list1);
562         ASSERT_TRUE(NULL != logger_list2);
563     }
564 
565     int count1 = 0;
566     bool done1 = false;
567     int count2 = 0;
568     bool done2 = false;
569 
570     do {
571         log_msg log_msg;
572 
573         if (!done1) {
574             if (android_logger_list_read(logger_list1, &log_msg) <= 0) {
575                 done1 = true;
576             } else {
577                 ++count1;
578             }
579         }
580 
581         if (!done2) {
582             if (android_logger_list_read(logger_list2, &log_msg) <= 0) {
583                 done2 = true;
584             } else {
585                 ++count2;
586             }
587         }
588     } while ((!done1) || (!done2));
589 
590     android_logger_list_close(logger_list1);
591     android_logger_list_close(logger_list2);
592 
593     EXPECT_EQ(25, count1);
594     EXPECT_EQ(15, count2);
595 }
596 
TEST(liblog,android_logger_get_)597 TEST(liblog, android_logger_get_) {
598     struct logger_list * logger_list = android_logger_list_alloc(O_WRONLY, 0, 0);
599 
600     for(int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
601         log_id_t id = static_cast<log_id_t>(i);
602         const char *name = android_log_id_to_name(id);
603         if (id != android_name_to_log_id(name)) {
604             continue;
605         }
606         struct logger * logger;
607         EXPECT_TRUE(NULL != (logger = android_logger_open(logger_list, id)));
608         EXPECT_EQ(id, android_logger_get_id(logger));
609         EXPECT_LT(0, android_logger_get_log_size(logger));
610         EXPECT_LT(0, android_logger_get_log_readable_size(logger));
611         EXPECT_LT(0, android_logger_get_log_version(logger));
612     }
613 
614     android_logger_list_close(logger_list);
615 }
616 
checkPriForTag(AndroidLogFormat * p_format,const char * tag,android_LogPriority pri)617 static bool checkPriForTag(AndroidLogFormat *p_format, const char *tag, android_LogPriority pri) {
618     return android_log_shouldPrintLine(p_format, tag, pri)
619         && !android_log_shouldPrintLine(p_format, tag, (android_LogPriority)(pri - 1));
620 }
621 
TEST(liblog,filterRule)622 TEST(liblog, filterRule) {
623     static const char tag[] = "random";
624 
625     AndroidLogFormat *p_format = android_log_format_new();
626 
627     android_log_addFilterRule(p_format,"*:i");
628 
629     EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_INFO));
630     EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
631     android_log_addFilterRule(p_format, "*");
632     EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
633     EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
634     android_log_addFilterRule(p_format, "*:v");
635     EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
636     EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
637     android_log_addFilterRule(p_format, "*:i");
638     EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_INFO));
639     EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
640 
641     android_log_addFilterRule(p_format, tag);
642     EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
643     EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
644     android_log_addFilterRule(p_format, "random:v");
645     EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
646     EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
647     android_log_addFilterRule(p_format, "random:d");
648     EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
649     EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
650     android_log_addFilterRule(p_format, "random:w");
651     EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
652     EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
653 
654     android_log_addFilterRule(p_format, "crap:*");
655     EXPECT_TRUE (checkPriForTag(p_format, "crap", ANDROID_LOG_VERBOSE));
656     EXPECT_TRUE(android_log_shouldPrintLine(p_format, "crap", ANDROID_LOG_VERBOSE) > 0);
657 
658     // invalid expression
659     EXPECT_TRUE (android_log_addFilterRule(p_format, "random:z") < 0);
660     EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
661     EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
662 
663     // Issue #550946
664     EXPECT_TRUE(android_log_addFilterString(p_format, " ") == 0);
665     EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
666 
667     // note trailing space
668     EXPECT_TRUE(android_log_addFilterString(p_format, "*:s random:d ") == 0);
669     EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
670 
671     EXPECT_TRUE(android_log_addFilterString(p_format, "*:s random:z") < 0);
672 
673 #if 0 // bitrot, seek update
674     char defaultBuffer[512];
675 
676     android_log_formatLogLine(p_format,
677         defaultBuffer, sizeof(defaultBuffer), 0, ANDROID_LOG_ERROR, 123,
678         123, 123, tag, "nofile", strlen("Hello"), "Hello", NULL);
679 
680     fprintf(stderr, "%s\n", defaultBuffer);
681 #endif
682 
683     android_log_format_free(p_format);
684 }
685