Home | History | Annotate | Download | only in tests
      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 
     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 
     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 
     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 
     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 
     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 
    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 
    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
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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