1 /* 2 * Copyright (C) 2013-2017 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 <sys/types.h> 18 #include <time.h> 19 #include <unistd.h> 20 21 #include <string> 22 23 #include <android-base/chrono_utils.h> 24 #include <android-base/stringprintf.h> 25 #include <android/log.h> // minimal logging API 26 #include <gtest/gtest.h> 27 #include <log/log_properties.h> 28 #include <log/log_read.h> 29 #include <log/log_time.h> 30 #include <log/log_transport.h> 31 32 #ifdef __ANDROID__ 33 static void read_with_wrap() { 34 android_set_log_transport(LOGGER_LOGD); 35 36 // Read the last line in the log to get a starting timestamp. We're assuming 37 // the log is not empty. 38 const int mode = ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK; 39 struct logger_list* logger_list = 40 android_logger_list_open(LOG_ID_MAIN, mode, 1000, 0); 41 42 ASSERT_NE(logger_list, nullptr); 43 44 log_msg log_msg; 45 int ret = android_logger_list_read(logger_list, &log_msg); 46 android_logger_list_close(logger_list); 47 ASSERT_GT(ret, 0); 48 49 log_time start(log_msg.entry.sec, log_msg.entry.nsec); 50 ASSERT_NE(start, log_time()); 51 52 logger_list = 53 android_logger_list_alloc_time(mode | ANDROID_LOG_WRAP, start, 0); 54 ASSERT_NE(logger_list, nullptr); 55 56 struct logger* logger = android_logger_open(logger_list, LOG_ID_MAIN); 57 EXPECT_NE(logger, nullptr); 58 if (logger) { 59 android_logger_list_read(logger_list, &log_msg); 60 } 61 62 android_logger_list_close(logger_list); 63 } 64 65 static void caught_signal(int /* signum */) { 66 } 67 #endif 68 69 // b/64143705 confirm fixed 70 TEST(liblog, wrap_mode_blocks) { 71 #ifdef __ANDROID__ 72 73 android::base::Timer timer; 74 75 // The read call is expected to take up to 2 hours in the happy case. 76 // We only want to make sure it waits for longer than 30s, but we can't 77 // use an alarm as the implementation uses it. So we run the test in 78 // a separate process. 79 pid_t pid = fork(); 80 81 if (pid == 0) { 82 // child 83 read_with_wrap(); 84 _exit(0); 85 } 86 87 struct sigaction ignore, old_sigaction; 88 memset(&ignore, 0, sizeof(ignore)); 89 ignore.sa_handler = caught_signal; 90 sigemptyset(&ignore.sa_mask); 91 sigaction(SIGALRM, &ignore, &old_sigaction); 92 alarm(45); 93 94 bool killed = false; 95 for (;;) { 96 siginfo_t info = {}; 97 // This wait will succeed if the child exits, or fail with EINTR if the 98 // alarm goes off first - a loose approximation to a timed wait. 99 int ret = waitid(P_PID, pid, &info, WEXITED); 100 if (ret >= 0 || errno != EINTR) { 101 EXPECT_EQ(ret, 0); 102 if (!killed) { 103 EXPECT_EQ(info.si_status, 0); 104 } 105 break; 106 } 107 unsigned int alarm_left = alarm(0); 108 if (alarm_left > 0) { 109 alarm(alarm_left); 110 } else { 111 kill(pid, SIGTERM); 112 killed = true; 113 } 114 } 115 116 alarm(0); 117 EXPECT_GT(timer.duration(), std::chrono::seconds(40)); 118 #else 119 GTEST_LOG_(INFO) << "This test does nothing.\n"; 120 #endif 121 } 122