diff options
author | Tom Cherry <tomcherry@google.com> | 2020-06-11 14:06:58 -0700 |
---|---|---|
committer | Tom Cherry <tomcherry@google.com> | 2020-06-11 14:13:39 -0700 |
commit | 8319bb40d095db553cbcfa93455a84138bf4564e (patch) | |
tree | 14e31251860424bde87a45a3bd47fa0625ed1a09 /logd/LogBufferTest.cpp | |
parent | 7a372d168ad9728282acee4b033bace1cc97201d (diff) |
logd: add a test for clearing logs with a reader present
Test that:
1) Logs are cleared
2) More logs can be added after clear
3) Well behaving blocking readers stay connected and can read new logs
after clear.
Test: this unit test
Change-Id: I8497896f5fb068b1e50ff0dcaab1cf79aebae2bb
Diffstat (limited to 'logd/LogBufferTest.cpp')
-rw-r--r-- | logd/LogBufferTest.cpp | 98 |
1 files changed, 95 insertions, 3 deletions
diff --git a/logd/LogBufferTest.cpp b/logd/LogBufferTest.cpp index e651b4fec..412b6f1d7 100644 --- a/logd/LogBufferTest.cpp +++ b/logd/LogBufferTest.cpp @@ -26,6 +26,7 @@ #include <android-base/stringprintf.h> #include <android-base/strings.h> +#include "LogBuffer.h" #include "LogReaderThread.h" #include "LogWriter.h" @@ -240,7 +241,7 @@ TEST_P(LogBufferTest, smoke_with_reader_thread) { std::unique_ptr<LogWriter> test_writer(new TestWriter(&read_log_messages, &released)); std::unique_ptr<LogReaderThread> log_reader( new LogReaderThread(log_buffer_.get(), &reader_list_, std::move(test_writer), true, - 0, ~0, 0, {}, 1, {})); + 0, kLogMaskAll, 0, {}, 1, {})); reader_list_.reader_threads().emplace_back(std::move(log_reader)); } @@ -314,7 +315,7 @@ TEST_P(LogBufferTest, random_messages) { std::unique_ptr<LogWriter> test_writer(new TestWriter(&read_log_messages, &released)); std::unique_ptr<LogReaderThread> log_reader( new LogReaderThread(log_buffer_.get(), &reader_list_, std::move(test_writer), true, - 0, ~0, 0, {}, 1, {})); + 0, kLogMaskAll, 0, {}, 1, {})); reader_list_.reader_threads().emplace_back(std::move(log_reader)); } @@ -348,7 +349,7 @@ TEST_P(LogBufferTest, read_last_sequence) { std::unique_ptr<LogWriter> test_writer(new TestWriter(&read_log_messages, &released)); std::unique_ptr<LogReaderThread> log_reader( new LogReaderThread(log_buffer_.get(), &reader_list_, std::move(test_writer), true, - 0, ~0, 0, {}, 3, {})); + 0, kLogMaskAll, 0, {}, 3, {})); reader_list_.reader_threads().emplace_back(std::move(log_reader)); } @@ -363,4 +364,95 @@ TEST_P(LogBufferTest, read_last_sequence) { CompareLogMessages(expected_log_messages, read_log_messages); } +TEST_P(LogBufferTest, clear_logs) { + // Log 3 initial logs. + std::vector<LogMessage> log_messages = { + {{.pid = 1, .tid = 2, .sec = 10000, .nsec = 20001, .lid = LOG_ID_MAIN, .uid = 0}, + "first"}, + {{.pid = 10, .tid = 2, .sec = 10000, .nsec = 20002, .lid = LOG_ID_MAIN, .uid = 0}, + "second"}, + {{.pid = 100, .tid = 2, .sec = 10000, .nsec = 20003, .lid = LOG_ID_MAIN, .uid = 0}, + "third"}, + }; + FixupMessages(&log_messages); + LogMessages(log_messages); + + std::vector<LogMessage> read_log_messages; + bool released = false; + + // Connect a blocking reader. + { + auto lock = std::unique_lock{reader_list_.reader_threads_lock()}; + std::unique_ptr<LogWriter> test_writer(new TestWriter(&read_log_messages, &released)); + std::unique_ptr<LogReaderThread> log_reader( + new LogReaderThread(log_buffer_.get(), &reader_list_, std::move(test_writer), false, + 0, kLogMaskAll, 0, {}, 1, {})); + reader_list_.reader_threads().emplace_back(std::move(log_reader)); + } + + // Wait up to 250ms for the reader to read the first 3 logs. + constexpr int kMaxRetryCount = 50; + int count = 0; + for (; count < kMaxRetryCount; ++count) { + usleep(5000); + auto lock = std::unique_lock{reader_list_.reader_threads_lock()}; + if (reader_list_.reader_threads().back()->start() == 4) { + break; + } + } + ASSERT_LT(count, kMaxRetryCount); + + // Clear the log buffer. + log_buffer_->Clear(LOG_ID_MAIN, 0); + + // Log 3 more logs. + std::vector<LogMessage> after_clear_messages = { + {{.pid = 1, .tid = 2, .sec = 10000, .nsec = 20001, .lid = LOG_ID_MAIN, .uid = 0}, + "4th"}, + {{.pid = 10, .tid = 2, .sec = 10000, .nsec = 20002, .lid = LOG_ID_MAIN, .uid = 0}, + "5th"}, + {{.pid = 100, .tid = 2, .sec = 10000, .nsec = 20003, .lid = LOG_ID_MAIN, .uid = 0}, + "6th"}, + }; + FixupMessages(&after_clear_messages); + LogMessages(after_clear_messages); + + // Wait up to 250ms for the reader to read the 3 additional logs. + for (count = 0; count < kMaxRetryCount; ++count) { + usleep(5000); + auto lock = std::unique_lock{reader_list_.reader_threads_lock()}; + if (reader_list_.reader_threads().back()->start() == 7) { + break; + } + } + ASSERT_LT(count, kMaxRetryCount); + + // Release the reader, wait for it to get the signal then check that it has been deleted. + { + auto lock = std::unique_lock{reader_list_.reader_threads_lock()}; + reader_list_.reader_threads().back()->release_Locked(); + } + while (!released) { + usleep(5000); + } + { + auto lock = std::unique_lock{reader_list_.reader_threads_lock()}; + EXPECT_EQ(0U, reader_list_.reader_threads().size()); + } + + // Check that we have read all 6 messages. + std::vector<LogMessage> expected_log_messages = log_messages; + expected_log_messages.insert(expected_log_messages.end(), after_clear_messages.begin(), + after_clear_messages.end()); + CompareLogMessages(expected_log_messages, read_log_messages); + + // Finally, call FlushTo and ensure that only the 3 logs after the clear remain in the buffer. + std::vector<LogMessage> read_log_messages_after_clear; + std::unique_ptr<LogWriter> test_writer(new TestWriter(&read_log_messages_after_clear, nullptr)); + std::unique_ptr<FlushToState> flush_to_state = log_buffer_->CreateFlushToState(1, kLogMaskAll); + EXPECT_TRUE(log_buffer_->FlushTo(test_writer.get(), *flush_to_state, nullptr)); + EXPECT_EQ(7ULL, flush_to_state->start()); + CompareLogMessages(after_clear_messages, read_log_messages_after_clear); +} + INSTANTIATE_TEST_CASE_P(LogBufferTests, LogBufferTest, testing::Values("chatty", "simple")); |