// b/27242723 confirmed fixed TEST(logd, SNDTIMEO) { static const unsigned sndtimeo = LOGD_SNDTIMEO; // <sigh> it has to be done! static const unsigned sleep_time = sndtimeo + 3; static const unsigned alarm_time = sleep_time + 5; int fd; ASSERT_TRUE((fd = socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET)) > 0); struct sigaction ignore, old_sigaction; memset(&ignore, 0, sizeof(ignore)); ignore.sa_handler = caught_signal; sigemptyset(&ignore.sa_mask); sigaction(SIGALRM, &ignore, &old_sigaction); unsigned int old_alarm = alarm(alarm_time); static const char ask[] = "stream lids=0,1,2,3,4,5,6"; // all sources bool reader_requested = write(fd, ask, sizeof(ask)) == sizeof(ask); EXPECT_TRUE(reader_requested); log_msg msg; bool read_one = recv(fd, msg.buf, sizeof(msg), 0) > 0; EXPECT_TRUE(read_one); if (read_one) { dump_log_msg("user", &msg, 3, -1); } fprintf (stderr, "Sleep for >%d seconds logd SO_SNDTIMEO ...\n", sndtimeo); sleep(sleep_time); // flush will block if we did not trigger. if it did, last entry returns 0 int recv_ret; do { recv_ret = recv(fd, msg.buf, sizeof(msg), 0); } while (recv_ret > 0); int save_errno = (recv_ret < 0) ? errno : 0; EXPECT_NE(0U, alarm(old_alarm)); sigaction(SIGALRM, &old_sigaction, NULL); EXPECT_EQ(0, recv_ret); if (recv_ret > 0) { dump_log_msg("user", &msg, 3, -1); } EXPECT_EQ(0, save_errno); close(fd); }
TEST(logd, both) { log_msg msg; // check if we can read any logs from logd bool user_logger_available = false; bool user_logger_content = false; int fd = socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET); if (fd >= 0) { struct sigaction ignore, old_sigaction; memset(&ignore, 0, sizeof(ignore)); ignore.sa_handler = caught_signal; sigemptyset(&ignore.sa_mask); sigaction(SIGALRM, &ignore, &old_sigaction); unsigned int old_alarm = alarm(10); static const char ask[] = "dumpAndClose lids=0,1,2,3"; user_logger_available = write(fd, ask, sizeof(ask)) == sizeof(ask); user_logger_content = recv(fd, msg.buf, sizeof(msg), 0) > 0; if (user_logger_content) { dump_log_msg("user", &msg, 3, -1); } alarm(old_alarm); sigaction(SIGALRM, &old_sigaction, NULL); close(fd); } // check if we can read any logs from kernel logger bool kernel_logger_available = false; bool kernel_logger_content = false; static const char *loggers[] = { "/dev/log/main", "/dev/log_main", "/dev/log/radio", "/dev/log_radio", "/dev/log/events", "/dev/log_events", "/dev/log/system", "/dev/log_system", }; for (unsigned int i = 0; i < (sizeof(loggers) / sizeof(loggers[0])); ++i) { fd = open(loggers[i], O_RDONLY); if (fd < 0) { continue; } kernel_logger_available = true; fcntl(fd, F_SETFL, O_RDONLY | O_NONBLOCK); int result = TEMP_FAILURE_RETRY(read(fd, msg.buf, sizeof(msg))); if (result > 0) { kernel_logger_content = true; dump_log_msg("kernel", &msg, 0, i / 2); } close(fd); } static const char yes[] = "\xE2\x9C\x93"; static const char no[] = "\xE2\x9c\x98"; fprintf(stderr, "LOGGER Available Content\n" "user %-13s%s\n" "kernel %-13s%s\n" " status %-11s%s\n", (user_logger_available) ? yes : no, (user_logger_content) ? yes : no, (kernel_logger_available) ? yes : no, (kernel_logger_content) ? yes : no, (user_logger_available && kernel_logger_available) ? "WARNING" : "ok", (user_logger_content && kernel_logger_content) ? "ERROR" : "ok"); if (user_logger_available && kernel_logger_available) { printf("WARNING: kernel & user logger; both consuming resources!!!\n"); } EXPECT_EQ(0, user_logger_content && kernel_logger_content); EXPECT_EQ(0, !user_logger_content && !kernel_logger_content); }
// b/26447386 refined behavior TEST(logd, timeout) { log_msg msg_wrap, msg_timeout; bool content_wrap = false, content_timeout = false, written = false; unsigned int alarm_wrap = 0, alarm_timeout = 0; // A few tries to get it right just in case wrap kicks in due to // content providers being active during the test int i = 5; log_time now(android_log_clockid()); now.tv_sec -= 30; // reach back a moderate period of time while (--i) { int fd = socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET); ASSERT_LT(0, fd); std::string ask = android::base::StringPrintf( "dumpAndClose lids=0,1,2,3,4,5 timeout=6 start=%" PRIu32 ".%09" PRIu32, now.tv_sec, now.tv_nsec); struct sigaction ignore, old_sigaction; memset(&ignore, 0, sizeof(ignore)); ignore.sa_handler = caught_signal; sigemptyset(&ignore.sa_mask); sigaction(SIGALRM, &ignore, &old_sigaction); unsigned int old_alarm = alarm(3); size_t len = ask.length() + 1; written = write(fd, ask.c_str(), len) == (ssize_t)len; if (!written) { alarm(old_alarm); sigaction(SIGALRM, &old_sigaction, NULL); close(fd); continue; } content_wrap = recv(fd, msg_wrap.buf, sizeof(msg_wrap), 0) > 0; alarm_wrap = alarm(5); content_timeout = recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0; if (!content_timeout) { // make sure we hit dumpAndClose content_timeout = recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0; } alarm_timeout = alarm((old_alarm <= 0) ? old_alarm : (old_alarm > (1 + 3 - alarm_wrap)) ? old_alarm - 3 + alarm_wrap : 2); sigaction(SIGALRM, &old_sigaction, NULL); close(fd); if (!content_wrap && !alarm_wrap && content_timeout && alarm_timeout) { break; } // modify start time in case content providers are relatively // active _or_ inactive during the test. if (content_timeout) { log_time msg(msg_timeout.entry.sec, msg_timeout.entry.nsec); EXPECT_FALSE(msg < now); if (msg > now) { now = msg; now.tv_sec += 30; msg = log_time(android_log_clockid()); if (now > msg) { now = msg; --now.tv_sec; } } } else { now.tv_sec -= 120; // inactive, reach further back! } } if (content_wrap) { dump_log_msg("wrap", &msg_wrap, 3, -1); } if (content_timeout) { dump_log_msg("timeout", &msg_timeout, 3, -1); } if (content_wrap || !content_timeout) { fprintf(stderr, "now=%" PRIu32 ".%09" PRIu32 "\n", now.tv_sec, now.tv_nsec); } EXPECT_TRUE(written); EXPECT_FALSE(content_wrap); EXPECT_EQ(0U, alarm_wrap); EXPECT_TRUE(content_timeout); EXPECT_NE(0U, alarm_timeout); }
// b/26447386 confirm fixed void timeout_negative(const char *command) { log_msg msg_wrap, msg_timeout; bool content_wrap = false, content_timeout = false, written = false; unsigned int alarm_wrap = 0, alarm_timeout = 0; // A few tries to get it right just in case wrap kicks in due to // content providers being active during the test. int i = 3; while (--i) { int fd = socket_local_client("logdr", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET); ASSERT_LT(0, fd); std::string ask(command); struct sigaction ignore, old_sigaction; memset(&ignore, 0, sizeof(ignore)); ignore.sa_handler = caught_signal; sigemptyset(&ignore.sa_mask); sigaction(SIGALRM, &ignore, &old_sigaction); unsigned int old_alarm = alarm(3); size_t len = ask.length() + 1; written = write(fd, ask.c_str(), len) == (ssize_t)len; if (!written) { alarm(old_alarm); sigaction(SIGALRM, &old_sigaction, NULL); close(fd); continue; } content_wrap = recv(fd, msg_wrap.buf, sizeof(msg_wrap), 0) > 0; alarm_wrap = alarm(5); content_timeout = recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0; if (!content_timeout) { // make sure we hit dumpAndClose content_timeout = recv(fd, msg_timeout.buf, sizeof(msg_timeout), 0) > 0; } alarm_timeout = alarm((old_alarm <= 0) ? old_alarm : (old_alarm > (1 + 3 - alarm_wrap)) ? old_alarm - 3 + alarm_wrap : 2); sigaction(SIGALRM, &old_sigaction, NULL); close(fd); if (!content_wrap && !alarm_wrap && content_timeout && alarm_timeout) { break; } } if (content_wrap) { dump_log_msg("wrap", &msg_wrap, 3, -1); } if (content_timeout) { dump_log_msg("timeout", &msg_timeout, 3, -1); } EXPECT_TRUE(written); EXPECT_TRUE(content_wrap); EXPECT_NE(0U, alarm_wrap); EXPECT_TRUE(content_timeout); EXPECT_NE(0U, alarm_timeout); }