blob: abe023974a67b32c3f760174c2766d7f6955b920 [file] [log] [blame]
Mark Salyzyn819c58a2013-11-22 12:39:43 -08001/*
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>
Elliott Hughes5d9fe772014-02-05 17:50:35 -080018#include <inttypes.h>
Mark Salyzyncef098e2014-01-09 09:02:55 -080019#include <signal.h>
Mark Salyzync1584562015-03-12 15:46:29 -070020
21#include <cutils/properties.h>
Mark Salyzyn819c58a2013-11-22 12:39:43 -080022#include <gtest/gtest.h>
23#include <log/log.h>
24#include <log/logger.h>
25#include <log/log_read.h>
Mark Salyzyn5045f572014-04-30 08:50:53 -070026#include <log/logprint.h>
Mark Salyzyn819c58a2013-11-22 12:39:43 -080027
Mark Salyzyncef098e2014-01-09 09:02:55 -080028// enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and
29// non-syscall libs. Since we are only using this in the emergency of
30// a signal to stuff a terminating code into the logs, we will spin rather
31// than try a usleep.
32#define LOG_FAILURE_RETRY(exp) ({ \
33 typeof (exp) _rc; \
34 do { \
35 _rc = (exp); \
36 } while (((_rc == -1) \
37 && ((errno == EINTR) \
38 || (errno == EAGAIN))) \
39 || (_rc == -EINTR) \
40 || (_rc == -EAGAIN)); \
41 _rc; })
42
Mark Salyzyn819c58a2013-11-22 12:39:43 -080043TEST(liblog, __android_log_buf_print) {
Mark Salyzyn8196be32014-03-18 17:10:47 -070044 EXPECT_LT(0, __android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO,
Mark Salyzyn819c58a2013-11-22 12:39:43 -080045 "TEST__android_log_buf_print",
46 "radio"));
47 usleep(1000);
Mark Salyzyn8196be32014-03-18 17:10:47 -070048 EXPECT_LT(0, __android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
Mark Salyzyn819c58a2013-11-22 12:39:43 -080049 "TEST__android_log_buf_print",
50 "system"));
51 usleep(1000);
Mark Salyzyn8196be32014-03-18 17:10:47 -070052 EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
Mark Salyzyn819c58a2013-11-22 12:39:43 -080053 "TEST__android_log_buf_print",
54 "main"));
55 usleep(1000);
56}
57
58TEST(liblog, __android_log_buf_write) {
Mark Salyzyn8196be32014-03-18 17:10:47 -070059 EXPECT_LT(0, __android_log_buf_write(LOG_ID_RADIO, ANDROID_LOG_INFO,
Mark Salyzyn819c58a2013-11-22 12:39:43 -080060 "TEST__android_log_buf_write",
61 "radio"));
62 usleep(1000);
Mark Salyzyn8196be32014-03-18 17:10:47 -070063 EXPECT_LT(0, __android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
Mark Salyzyn819c58a2013-11-22 12:39:43 -080064 "TEST__android_log_buf_write",
65 "system"));
66 usleep(1000);
Mark Salyzyn8196be32014-03-18 17:10:47 -070067 EXPECT_LT(0, __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO,
Mark Salyzyn819c58a2013-11-22 12:39:43 -080068 "TEST__android_log_buf_write",
69 "main"));
70 usleep(1000);
71}
72
73TEST(liblog, __android_log_btwrite) {
74 int intBuf = 0xDEADBEEF;
Mark Salyzyn8196be32014-03-18 17:10:47 -070075 EXPECT_LT(0, __android_log_btwrite(0,
Mark Salyzyn819c58a2013-11-22 12:39:43 -080076 EVENT_TYPE_INT,
77 &intBuf, sizeof(intBuf)));
78 long long longBuf = 0xDEADBEEFA55A5AA5;
Mark Salyzyn8196be32014-03-18 17:10:47 -070079 EXPECT_LT(0, __android_log_btwrite(0,
Mark Salyzyn819c58a2013-11-22 12:39:43 -080080 EVENT_TYPE_LONG,
81 &longBuf, sizeof(longBuf)));
82 usleep(1000);
83 char Buf[] = "\20\0\0\0DeAdBeEfA55a5aA5";
Mark Salyzyn8196be32014-03-18 17:10:47 -070084 EXPECT_LT(0, __android_log_btwrite(0,
Mark Salyzyn819c58a2013-11-22 12:39:43 -080085 EVENT_TYPE_STRING,
86 Buf, sizeof(Buf) - 1));
87 usleep(1000);
88}
89
90static void* ConcurrentPrintFn(void *arg) {
91 int ret = __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
Elliott Hughes5d9fe772014-02-05 17:50:35 -080092 "TEST__android_log_print", "Concurrent %" PRIuPTR,
93 reinterpret_cast<uintptr_t>(arg));
Mark Salyzyn819c58a2013-11-22 12:39:43 -080094 return reinterpret_cast<void*>(ret);
95}
96
97#define NUM_CONCURRENT 64
98#define _concurrent_name(a,n) a##__concurrent##n
99#define concurrent_name(a,n) _concurrent_name(a,n)
100
101TEST(liblog, concurrent_name(__android_log_buf_print, NUM_CONCURRENT)) {
102 pthread_t t[NUM_CONCURRENT];
103 int i;
104 for (i=0; i < NUM_CONCURRENT; i++) {
105 ASSERT_EQ(0, pthread_create(&t[i], NULL,
106 ConcurrentPrintFn,
107 reinterpret_cast<void *>(i)));
108 }
109 int ret = 0;
110 for (i=0; i < NUM_CONCURRENT; i++) {
111 void* result;
112 ASSERT_EQ(0, pthread_join(t[i], &result));
Elliott Hughes5d9fe772014-02-05 17:50:35 -0800113 int this_result = reinterpret_cast<uintptr_t>(result);
114 if ((0 == ret) && (0 != this_result)) {
115 ret = this_result;
Mark Salyzyn819c58a2013-11-22 12:39:43 -0800116 }
117 }
118 ASSERT_LT(0, ret);
119}
120
121TEST(liblog, __android_log_btwrite__android_logger_list_read) {
122 struct logger_list *logger_list;
123
124 pid_t pid = getpid();
125
Mark Salyzyn8196be32014-03-18 17:10:47 -0700126 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
Mark Salyzyn2d3f38a2015-01-26 10:46:44 -0800127 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
Mark Salyzyn819c58a2013-11-22 12:39:43 -0800128
129 log_time ts(CLOCK_MONOTONIC);
130
131 ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
132 usleep(1000000);
133
134 int count = 0;
135
136 for (;;) {
137 log_msg log_msg;
138 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
139 break;
140 }
141
142 ASSERT_EQ(log_msg.entry.pid, pid);
143
144 if ((log_msg.entry.len != (4 + 1 + 8))
145 || (log_msg.id() != LOG_ID_EVENTS)) {
146 continue;
147 }
148
149 char *eventData = log_msg.msg();
150
151 if (eventData[4] != EVENT_TYPE_LONG) {
152 continue;
153 }
154
155 log_time tx(eventData + 4 + 1);
156 if (ts == tx) {
157 ++count;
158 }
159 }
160
Mark Salyzyn8196be32014-03-18 17:10:47 -0700161 EXPECT_EQ(1, count);
Mark Salyzyn819c58a2013-11-22 12:39:43 -0800162
163 android_logger_list_close(logger_list);
164}
165
Mark Salyzyncef098e2014-01-09 09:02:55 -0800166static unsigned signaled;
167log_time signal_time;
168
Mark Salyzyna04464a2014-04-30 08:50:53 -0700169static void caught_blocking(int /*signum*/)
Mark Salyzyncef098e2014-01-09 09:02:55 -0800170{
171 unsigned long long v = 0xDEADBEEFA55A0000ULL;
172
173 v += getpid() & 0xFFFF;
174
175 ++signaled;
176 if ((signal_time.tv_sec == 0) && (signal_time.tv_nsec == 0)) {
Mark Salyzyn7e2f83c2014-03-05 07:41:49 -0800177 signal_time = log_time(CLOCK_MONOTONIC);
Mark Salyzyncef098e2014-01-09 09:02:55 -0800178 signal_time.tv_sec += 2;
179 }
180
181 LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
182}
183
184// Fill in current process user and system time in 10ms increments
185static void get_ticks(unsigned long long *uticks, unsigned long long *sticks)
186{
187 *uticks = *sticks = 0;
188
189 pid_t pid = getpid();
190
191 char buffer[512];
192 snprintf(buffer, sizeof(buffer), "/proc/%u/stat", pid);
193
194 FILE *fp = fopen(buffer, "r");
195 if (!fp) {
196 return;
197 }
198
199 char *cp = fgets(buffer, sizeof(buffer), fp);
200 fclose(fp);
201 if (!cp) {
202 return;
203 }
204
205 pid_t d;
206 char s[sizeof(buffer)];
207 char c;
208 long long ll;
209 unsigned long long ull;
210
211 if (15 != sscanf(buffer,
212 "%d %s %c %lld %lld %lld %lld %lld %llu %llu %llu %llu %llu %llu %llu ",
213 &d, s, &c, &ll, &ll, &ll, &ll, &ll, &ull, &ull, &ull, &ull, &ull,
214 uticks, sticks)) {
215 *uticks = *sticks = 0;
216 }
217}
218
219TEST(liblog, android_logger_list_read__cpu) {
220 struct logger_list *logger_list;
221 unsigned long long v = 0xDEADBEEFA55A0000ULL;
222
223 pid_t pid = getpid();
224
225 v += pid & 0xFFFF;
226
Mark Salyzyn8196be32014-03-18 17:10:47 -0700227 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
Mark Salyzyn2d3f38a2015-01-26 10:46:44 -0800228 LOG_ID_EVENTS, ANDROID_LOG_RDONLY, 1000, pid)));
Mark Salyzyncef098e2014-01-09 09:02:55 -0800229
230 int count = 0;
231
232 int signals = 0;
233
234 unsigned long long uticks_start;
235 unsigned long long sticks_start;
236 get_ticks(&uticks_start, &sticks_start);
237
238 const unsigned alarm_time = 10;
239
240 memset(&signal_time, 0, sizeof(signal_time));
241
242 signal(SIGALRM, caught_blocking);
243 alarm(alarm_time);
244
245 signaled = 0;
246
247 do {
248 log_msg log_msg;
249 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
250 break;
251 }
252
253 alarm(alarm_time);
254
255 ++count;
256
257 ASSERT_EQ(log_msg.entry.pid, pid);
258
259 if ((log_msg.entry.len != (4 + 1 + 8))
260 || (log_msg.id() != LOG_ID_EVENTS)) {
261 continue;
262 }
263
264 char *eventData = log_msg.msg();
265
266 if (eventData[4] != EVENT_TYPE_LONG) {
267 continue;
268 }
269
270 unsigned long long l = eventData[4 + 1 + 0] & 0xFF;
271 l |= (unsigned long long) (eventData[4 + 1 + 1] & 0xFF) << 8;
272 l |= (unsigned long long) (eventData[4 + 1 + 2] & 0xFF) << 16;
273 l |= (unsigned long long) (eventData[4 + 1 + 3] & 0xFF) << 24;
274 l |= (unsigned long long) (eventData[4 + 1 + 4] & 0xFF) << 32;
275 l |= (unsigned long long) (eventData[4 + 1 + 5] & 0xFF) << 40;
276 l |= (unsigned long long) (eventData[4 + 1 + 6] & 0xFF) << 48;
277 l |= (unsigned long long) (eventData[4 + 1 + 7] & 0xFF) << 56;
278
279 if (l == v) {
280 ++signals;
281 break;
282 }
Mark Salyzyn8196be32014-03-18 17:10:47 -0700283 } while (!signaled || (log_time(CLOCK_MONOTONIC) < signal_time));
Mark Salyzyncef098e2014-01-09 09:02:55 -0800284 alarm(0);
285 signal(SIGALRM, SIG_DFL);
286
Mark Salyzyn8196be32014-03-18 17:10:47 -0700287 EXPECT_LT(1, count);
Mark Salyzyncef098e2014-01-09 09:02:55 -0800288
Mark Salyzyn8196be32014-03-18 17:10:47 -0700289 EXPECT_EQ(1, signals);
Mark Salyzyncef098e2014-01-09 09:02:55 -0800290
291 android_logger_list_close(logger_list);
292
293 unsigned long long uticks_end;
294 unsigned long long sticks_end;
295 get_ticks(&uticks_end, &sticks_end);
296
297 // Less than 1% in either user or system time, or both
298 const unsigned long long one_percent_ticks = alarm_time;
299 unsigned long long user_ticks = uticks_end - uticks_start;
300 unsigned long long system_ticks = sticks_end - sticks_start;
Mark Salyzyn8196be32014-03-18 17:10:47 -0700301 EXPECT_GT(one_percent_ticks, user_ticks);
302 EXPECT_GT(one_percent_ticks, system_ticks);
303 EXPECT_GT(one_percent_ticks, user_ticks + system_ticks);
304}
305
306static const char max_payload_tag[] = "TEST_max_payload_XXXX";
307static const char max_payload_buf[LOGGER_ENTRY_MAX_PAYLOAD
308 - sizeof(max_payload_tag) - 1] = "LEONATO\n\
309I learn in this letter that Don Peter of Arragon\n\
310comes this night to Messina\n\
311MESSENGER\n\
312He is very near by this: he was not three leagues off\n\
313when I left him\n\
314LEONATO\n\
315How many gentlemen have you lost in this action?\n\
316MESSENGER\n\
317But few of any sort, and none of name\n\
318LEONATO\n\
319A victory is twice itself when the achiever brings\n\
320home full numbers. I find here that Don Peter hath\n\
321bestowed much honour on a young Florentine called Claudio\n\
322MESSENGER\n\
323Much deserved on his part and equally remembered by\n\
324Don Pedro: he hath borne himself beyond the\n\
325promise of his age, doing, in the figure of a lamb,\n\
326the feats of a lion: he hath indeed better\n\
327bettered expectation than you must expect of me to\n\
328tell you how\n\
329LEONATO\n\
330He hath an uncle here in Messina will be very much\n\
331glad of it.\n\
332MESSENGER\n\
333I have already delivered him letters, and there\n\
334appears much joy in him; even so much that joy could\n\
335not show itself modest enough without a badge of\n\
336bitterness.\n\
337LEONATO\n\
338Did he break out into tears?\n\
339MESSENGER\n\
340In great measure.\n\
341LEONATO\n\
342A kind overflow of kindness: there are no faces\n\
343truer than those that are so washed. How much\n\
344better is it to weep at joy than to joy at weeping!\n\
345BEATRICE\n\
346I pray you, is Signior Mountanto returned from the\n\
347wars or no?\n\
348MESSENGER\n\
349I know none of that name, lady: there was none such\n\
350in the army of any sort.\n\
351LEONATO\n\
352What is he that you ask for, niece?\n\
353HERO\n\
354My cousin means Signior Benedick of Padua.\n\
355MESSENGER\n\
356O, he's returned; and as pleasant as ever he was.\n\
357BEATRICE\n\
358He set up his bills here in Messina and challenged\n\
359Cupid at the flight; and my uncle's fool, reading\n\
360the challenge, subscribed for Cupid, and challenged\n\
361him at the bird-bolt. I pray you, how many hath he\n\
362killed and eaten in these wars? But how many hath\n\
363he killed? for indeed I promised to eat all of his killing.\n\
364LEONATO\n\
365Faith, niece, you tax Signior Benedick too much;\n\
366but he'll be meet with you, I doubt it not.\n\
367MESSENGER\n\
368He hath done good service, lady, in these wars.\n\
369BEATRICE\n\
370You had musty victual, and he hath holp to eat it:\n\
371he is a very valiant trencherman; he hath an\n\
372excellent stomach.\n\
373MESSENGER\n\
374And a good soldier too, lady.\n\
375BEATRICE\n\
376And a good soldier to a lady: but what is he to a lord?\n\
377MESSENGER\n\
378A lord to a lord, a man to a man; stuffed with all\n\
379honourable virtues.\n\
380BEATRICE\n\
381It is so, indeed; he is no less than a stuffed man:\n\
382but for the stuffing,--well, we are all mortal.\n\
383LEONATO\n\
384You must not, sir, mistake my niece. There is a\n\
385kind of merry war betwixt Signior Benedick and her:\n\
386they never meet but there's a skirmish of wit\n\
387between them.\n\
388BEATRICE\n\
389Alas! he gets nothing by that. In our last\n\
390conflict four of his five wits went halting off, and\n\
391now is the whole man governed with one: so that if\n\
392he have wit enough to keep himself warm, let him\n\
393bear it for a difference between himself and his\n\
394horse; for it is all the wealth that he hath left,\n\
395to be known a reasonable creature. Who is his\n\
396companion now? He hath every month a new sworn brother.\n\
397MESSENGER\n\
398Is't possible?\n\
399BEATRICE\n\
400Very easily possible: he wears his faith but as\n\
401the fashion of his hat; it ever changes with the\n\
402next block.\n\
403MESSENGER\n\
404I see, lady, the gentleman is not in your books.\n\
405BEATRICE\n\
406No; an he were, I would burn my study. But, I pray\n\
407you, who is his companion? Is there no young\n\
408squarer now that will make a voyage with him to the devil?\n\
409MESSENGER\n\
410He is most in the company of the right noble Claudio.\n\
411BEATRICE\n\
412O Lord, he will hang upon him like a disease: he\n\
413is sooner caught than the pestilence, and the taker\n\
414runs presently mad. God help the noble Claudio! if\n\
415he have caught the Benedick, it will cost him a\n\
416thousand pound ere a' be cured.\n\
417MESSENGER\n\
418I will hold friends with you, lady.\n\
419BEATRICE\n\
420Do, good friend.\n\
421LEONATO\n\
422You will never run mad, niece.\n\
423BEATRICE\n\
424No, not till a hot January.\n\
425MESSENGER\n\
426Don Pedro is approached.\n\
427Enter DON PEDRO, DON JOHN, CLAUDIO, BENEDICK, and BALTHASAR\n\
428\n\
429DON PEDRO\n\
430Good Signior Leonato, you are come to meet your\n\
431trouble: the fashion of the world is to avoid\n\
432cost, and you encounter it\n\
433LEONATO\n\
434Never came trouble to my house in the likeness";
435
436TEST(liblog, max_payload) {
437 pid_t pid = getpid();
438 char tag[sizeof(max_payload_tag)];
439 memcpy(tag, max_payload_tag, sizeof(tag));
440 snprintf(tag + sizeof(tag) - 5, 5, "%04X", pid & 0xFFFF);
441
442 LOG_FAILURE_RETRY(__android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
443 tag, max_payload_buf));
Mark Salyzync1584562015-03-12 15:46:29 -0700444 sleep(2);
Mark Salyzyn8196be32014-03-18 17:10:47 -0700445
446 struct logger_list *logger_list;
447
448 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
Mark Salyzyn2d3f38a2015-01-26 10:46:44 -0800449 LOG_ID_SYSTEM, ANDROID_LOG_RDONLY, 100, 0)));
Mark Salyzyn8196be32014-03-18 17:10:47 -0700450
451 bool matches = false;
452 ssize_t max_len = 0;
453
454 for(;;) {
455 log_msg log_msg;
456 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
457 break;
458 }
459
460 if ((log_msg.entry.pid != pid) || (log_msg.id() != LOG_ID_SYSTEM)) {
461 continue;
462 }
463
464 char *data = log_msg.msg() + 1;
465
466 if (strcmp(data, tag)) {
467 continue;
468 }
469
470 data += strlen(data) + 1;
471
472 const char *left = data;
473 const char *right = max_payload_buf;
474 while (*left && *right && (*left == *right)) {
475 ++left;
476 ++right;
477 }
478
479 if (max_len <= (left - data)) {
480 max_len = left - data + 1;
481 }
482
483 if (max_len > 512) {
484 matches = true;
485 break;
486 }
487 }
488
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700489 android_logger_list_close(logger_list);
490
Mark Salyzyn8196be32014-03-18 17:10:47 -0700491 EXPECT_EQ(true, matches);
492
Ben Cheng1bafa522014-04-11 16:19:30 -0700493 EXPECT_LE(sizeof(max_payload_buf), static_cast<size_t>(max_len));
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700494}
495
496TEST(liblog, too_big_payload) {
497 pid_t pid = getpid();
498 static const char big_payload_tag[] = "TEST_big_payload_XXXX";
499 char tag[sizeof(big_payload_tag)];
500 memcpy(tag, big_payload_tag, sizeof(tag));
501 snprintf(tag + sizeof(tag) - 5, 5, "%04X", pid & 0xFFFF);
502
503 std::string longString(3266519, 'x');
504
505 ssize_t ret = LOG_FAILURE_RETRY(__android_log_buf_write(LOG_ID_SYSTEM,
506 ANDROID_LOG_INFO, tag, longString.c_str()));
507
508 struct logger_list *logger_list;
509
510 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
Mark Salyzyn2d3f38a2015-01-26 10:46:44 -0800511 LOG_ID_SYSTEM, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 100, 0)));
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700512
513 ssize_t max_len = 0;
514
515 for(;;) {
516 log_msg log_msg;
517 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
518 break;
519 }
520
521 if ((log_msg.entry.pid != pid) || (log_msg.id() != LOG_ID_SYSTEM)) {
522 continue;
523 }
524
525 char *data = log_msg.msg() + 1;
526
527 if (strcmp(data, tag)) {
528 continue;
529 }
530
531 data += strlen(data) + 1;
532
533 const char *left = data;
534 const char *right = longString.c_str();
535 while (*left && *right && (*left == *right)) {
536 ++left;
537 ++right;
538 }
539
540 if (max_len <= (left - data)) {
541 max_len = left - data + 1;
542 }
543 }
Mark Salyzyn8196be32014-03-18 17:10:47 -0700544
545 android_logger_list_close(logger_list);
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700546
547 EXPECT_LE(LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag),
548 static_cast<size_t>(max_len));
549
Ben Cheng43232922014-05-20 10:38:24 -0700550 EXPECT_EQ(ret, max_len + static_cast<ssize_t>(sizeof(big_payload_tag)));
Mark Salyzyn8196be32014-03-18 17:10:47 -0700551}
552
553TEST(liblog, dual_reader) {
554 struct logger_list *logger_list1;
555
556 // >25 messages due to liblog.__android_log_buf_print__concurrentXX above.
557 ASSERT_TRUE(NULL != (logger_list1 = android_logger_list_open(
Mark Salyzyn2d3f38a2015-01-26 10:46:44 -0800558 LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 25, 0)));
Mark Salyzyn8196be32014-03-18 17:10:47 -0700559
560 struct logger_list *logger_list2;
561
562 if (NULL == (logger_list2 = android_logger_list_open(
Mark Salyzyn2d3f38a2015-01-26 10:46:44 -0800563 LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 15, 0))) {
Mark Salyzyn8196be32014-03-18 17:10:47 -0700564 android_logger_list_close(logger_list1);
565 ASSERT_TRUE(NULL != logger_list2);
566 }
567
568 int count1 = 0;
569 bool done1 = false;
570 int count2 = 0;
571 bool done2 = false;
572
573 do {
574 log_msg log_msg;
575
576 if (!done1) {
577 if (android_logger_list_read(logger_list1, &log_msg) <= 0) {
578 done1 = true;
579 } else {
580 ++count1;
581 }
582 }
583
584 if (!done2) {
585 if (android_logger_list_read(logger_list2, &log_msg) <= 0) {
586 done2 = true;
587 } else {
588 ++count2;
589 }
590 }
591 } while ((!done1) || (!done2));
592
593 android_logger_list_close(logger_list1);
594 android_logger_list_close(logger_list2);
595
596 EXPECT_EQ(25, count1);
597 EXPECT_EQ(15, count2);
Mark Salyzyncef098e2014-01-09 09:02:55 -0800598}
599
Mark Salyzyn819c58a2013-11-22 12:39:43 -0800600TEST(liblog, android_logger_get_) {
Mark Salyzyn2d3f38a2015-01-26 10:46:44 -0800601 struct logger_list * logger_list = android_logger_list_alloc(ANDROID_LOG_WRONLY, 0, 0);
Mark Salyzyn819c58a2013-11-22 12:39:43 -0800602
603 for(int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
604 log_id_t id = static_cast<log_id_t>(i);
605 const char *name = android_log_id_to_name(id);
606 if (id != android_name_to_log_id(name)) {
607 continue;
608 }
Mark Salyzync1584562015-03-12 15:46:29 -0700609 fprintf(stderr, "log buffer %s\r", name);
Mark Salyzyn819c58a2013-11-22 12:39:43 -0800610 struct logger * logger;
Mark Salyzyn8196be32014-03-18 17:10:47 -0700611 EXPECT_TRUE(NULL != (logger = android_logger_open(logger_list, id)));
612 EXPECT_EQ(id, android_logger_get_id(logger));
Mark Salyzync1584562015-03-12 15:46:29 -0700613 /* crash buffer is allowed to be empty, that is actually healthy! */
614 if (android_logger_get_log_size(logger) || strcmp("crash", name)) {
615 EXPECT_LT(0, android_logger_get_log_size(logger));
616 }
Mark Salyzyn8196be32014-03-18 17:10:47 -0700617 EXPECT_LT(0, android_logger_get_log_readable_size(logger));
618 EXPECT_LT(0, android_logger_get_log_version(logger));
Mark Salyzyn819c58a2013-11-22 12:39:43 -0800619 }
620
621 android_logger_list_close(logger_list);
622}
Mark Salyzyn5045f572014-04-30 08:50:53 -0700623
624static bool checkPriForTag(AndroidLogFormat *p_format, const char *tag, android_LogPriority pri) {
625 return android_log_shouldPrintLine(p_format, tag, pri)
626 && !android_log_shouldPrintLine(p_format, tag, (android_LogPriority)(pri - 1));
627}
628
629TEST(liblog, filterRule) {
630 static const char tag[] = "random";
631
632 AndroidLogFormat *p_format = android_log_format_new();
633
634 android_log_addFilterRule(p_format,"*:i");
635
636 EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_INFO));
637 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
638 android_log_addFilterRule(p_format, "*");
639 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
640 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
641 android_log_addFilterRule(p_format, "*:v");
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, "*:i");
645 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_INFO));
646 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
647
648 android_log_addFilterRule(p_format, tag);
649 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
650 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
651 android_log_addFilterRule(p_format, "random:v");
652 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
653 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
654 android_log_addFilterRule(p_format, "random:d");
655 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
656 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
657 android_log_addFilterRule(p_format, "random:w");
658 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
659 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
660
661 android_log_addFilterRule(p_format, "crap:*");
662 EXPECT_TRUE (checkPriForTag(p_format, "crap", ANDROID_LOG_VERBOSE));
663 EXPECT_TRUE(android_log_shouldPrintLine(p_format, "crap", ANDROID_LOG_VERBOSE) > 0);
664
665 // invalid expression
666 EXPECT_TRUE (android_log_addFilterRule(p_format, "random:z") < 0);
667 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
668 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
669
670 // Issue #550946
671 EXPECT_TRUE(android_log_addFilterString(p_format, " ") == 0);
672 EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
673
674 // note trailing space
675 EXPECT_TRUE(android_log_addFilterString(p_format, "*:s random:d ") == 0);
676 EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
677
678 EXPECT_TRUE(android_log_addFilterString(p_format, "*:s random:z") < 0);
679
680#if 0 // bitrot, seek update
681 char defaultBuffer[512];
682
683 android_log_formatLogLine(p_format,
684 defaultBuffer, sizeof(defaultBuffer), 0, ANDROID_LOG_ERROR, 123,
685 123, 123, tag, "nofile", strlen("Hello"), "Hello", NULL);
686
687 fprintf(stderr, "%s\n", defaultBuffer);
688#endif
689
690 android_log_format_free(p_format);
691}
Mark Salyzync1584562015-03-12 15:46:29 -0700692
693TEST(liblog, is_loggable) {
694 static const char tag[] = "is_loggable";
695 static const char log_namespace[] = "persist.log.tag.";
696 static const size_t base_offset = 8; /* skip "persist." */
697 // sizeof("string") = strlen("string") + 1
698 char key[sizeof(log_namespace) + sizeof(tag) - 1];
699 char hold[4][PROP_VALUE_MAX];
700 static const struct {
701 int level;
702 char type;
703 } levels[] = {
704 { ANDROID_LOG_VERBOSE, 'v' },
705 { ANDROID_LOG_DEBUG , 'd' },
706 { ANDROID_LOG_INFO , 'i' },
707 { ANDROID_LOG_WARN , 'w' },
708 { ANDROID_LOG_ERROR , 'e' },
709 { ANDROID_LOG_FATAL , 'a' },
710 { -1 , 's' },
711 { -2 , 'g' }, // Illegal value, resort to default
712 };
713
714 // Set up initial test condition
715 memset(hold, 0, sizeof(hold));
716 snprintf(key, sizeof(key), "%s%s", log_namespace, tag);
717 property_get(key, hold[0], "");
718 property_set(key, "");
719 property_get(key + base_offset, hold[1], "");
720 property_set(key + base_offset, "");
721 strcpy(key, log_namespace);
722 key[sizeof(log_namespace) - 2] = '\0';
723 property_get(key, hold[2], "");
724 property_set(key, "");
725 property_get(key, hold[3], "");
726 property_set(key + base_offset, "");
727
728 // All combinations of level and defaults
729 for(size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) {
730 if (levels[i].level == -2) {
731 continue;
732 }
733 for(size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) {
734 if (levels[j].level == -2) {
735 continue;
736 }
737 fprintf(stderr, "i=%zu j=%zu\r", i, j);
738 if ((levels[i].level < levels[j].level)
739 || (levels[j].level == -1)) {
740 EXPECT_FALSE(__android_log_is_loggable(levels[i].level, tag,
741 levels[j].level));
742 } else {
743 EXPECT_TRUE(__android_log_is_loggable(levels[i].level, tag,
744 levels[j].level));
745 }
746 }
747 }
748
749 // All combinations of level and tag and global properties
750 for(size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) {
751 if (levels[i].level == -2) {
752 continue;
753 }
754 for(size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) {
755 char buf[2];
756 buf[0] = levels[j].type;
757 buf[1] = '\0';
758
759 snprintf(key, sizeof(key), "%s%s", log_namespace, tag);
760 fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
761 i, j, key, buf);
762 property_set(key, buf);
763 if ((levels[i].level < levels[j].level)
764 || (levels[j].level == -1)
765 || ((levels[i].level < ANDROID_LOG_DEBUG)
766 && (levels[j].level == -2))) {
767 EXPECT_FALSE(__android_log_is_loggable(levels[i].level, tag,
768 ANDROID_LOG_DEBUG));
769 } else {
770 EXPECT_TRUE(__android_log_is_loggable(levels[i].level, tag,
771 ANDROID_LOG_DEBUG));
772 }
773 property_set(key, "");
774
775 fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
776 i, j, key + base_offset, buf);
777 property_set(key + base_offset, buf);
778 if ((levels[i].level < levels[j].level)
779 || (levels[j].level == -1)
780 || ((levels[i].level < ANDROID_LOG_DEBUG)
781 && (levels[j].level == -2))) {
782 EXPECT_FALSE(__android_log_is_loggable(levels[i].level, tag,
783 ANDROID_LOG_DEBUG));
784 } else {
785 EXPECT_TRUE(__android_log_is_loggable(levels[i].level, tag,
786 ANDROID_LOG_DEBUG));
787 }
788 property_set(key + base_offset, "");
789
790 strcpy(key, log_namespace);
791 key[sizeof(log_namespace) - 2] = '\0';
792 fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
793 i, j, key, buf);
794 property_set(key, buf);
795 if ((levels[i].level < levels[j].level)
796 || (levels[j].level == -1)
797 || ((levels[i].level < ANDROID_LOG_DEBUG)
798 && (levels[j].level == -2))) {
799 EXPECT_FALSE(__android_log_is_loggable(levels[i].level, tag,
800 ANDROID_LOG_DEBUG));
801 } else {
802 EXPECT_TRUE(__android_log_is_loggable(levels[i].level, tag,
803 ANDROID_LOG_DEBUG));
804 }
805 property_set(key, "");
806
807 fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
808 i, j, key + base_offset, buf);
809 property_set(key + base_offset, buf);
810 if ((levels[i].level < levels[j].level)
811 || (levels[j].level == -1)
812 || ((levels[i].level < ANDROID_LOG_DEBUG)
813 && (levels[j].level == -2))) {
814 EXPECT_FALSE(__android_log_is_loggable(levels[i].level, tag,
815 ANDROID_LOG_DEBUG));
816 } else {
817 EXPECT_TRUE(__android_log_is_loggable(levels[i].level, tag,
818 ANDROID_LOG_DEBUG));
819 }
820 property_set(key + base_offset, "");
821 }
822 }
823
824 // All combinations of level and tag properties, but with global set to INFO
825 strcpy(key, log_namespace);
826 key[sizeof(log_namespace) - 2] = '\0';
827 property_set(key, "I");
828 snprintf(key, sizeof(key), "%s%s", log_namespace, tag);
829 for(size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) {
830 if (levels[i].level == -2) {
831 continue;
832 }
833 for(size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) {
834 char buf[2];
835 buf[0] = levels[j].type;
836 buf[1] = '\0';
837
838 fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
839 i, j, key, buf);
840 property_set(key, buf);
841 if ((levels[i].level < levels[j].level)
842 || (levels[j].level == -1)
843 || ((levels[i].level < ANDROID_LOG_INFO) // Yes INFO
844 && (levels[j].level == -2))) {
845 EXPECT_FALSE(__android_log_is_loggable(levels[i].level, tag,
846 ANDROID_LOG_DEBUG));
847 } else {
848 EXPECT_TRUE(__android_log_is_loggable(levels[i].level, tag,
849 ANDROID_LOG_DEBUG));
850 }
851 property_set(key, "");
852
853 fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
854 i, j, key + base_offset, buf);
855 property_set(key + base_offset, buf);
856 if ((levels[i].level < levels[j].level)
857 || (levels[j].level == -1)
858 || ((levels[i].level < ANDROID_LOG_INFO) // Yes INFO
859 && (levels[j].level == -2))) {
860 EXPECT_FALSE(__android_log_is_loggable(levels[i].level, tag,
861 ANDROID_LOG_DEBUG));
862 } else {
863 EXPECT_TRUE(__android_log_is_loggable(levels[i].level, tag,
864 ANDROID_LOG_DEBUG));
865 }
866 property_set(key + base_offset, "");
867 }
868 }
869
870 // reset parms
871 snprintf(key, sizeof(key), "%s%s", log_namespace, tag);
872 property_set(key, hold[0]);
873 property_set(key + base_offset, hold[1]);
874 strcpy(key, log_namespace);
875 key[sizeof(log_namespace) - 2] = '\0';
876 property_set(key, hold[2]);
877 property_set(key + base_offset, hold[3]);
878}