blob: e881e76bd1250f48d5013d898af891584874d8a0 [file] [log] [blame]
Tom Cherryfbe79422020-05-14 22:28:09 -07001/*
Tom Cherry6bc6f492020-05-21 12:13:20 -07002 * Copyright (C) 2020 The Android Open Source Project
Tom Cherryfbe79422020-05-14 22:28:09 -07003 *
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
Tom Cherry6bc6f492020-05-21 12:13:20 -070017#include "LogBufferTest.h"
Tom Cherryfbe79422020-05-14 22:28:09 -070018
19#include <unistd.h>
20
Tom Cherry9f3eb612020-05-20 12:09:22 -070021#include <limits>
Tom Cherryfbe79422020-05-14 22:28:09 -070022#include <memory>
Tom Cherry9f3eb612020-05-20 12:09:22 -070023#include <regex>
Tom Cherryfbe79422020-05-14 22:28:09 -070024#include <vector>
25
26#include <android-base/stringprintf.h>
27#include <android-base/strings.h>
Tom Cherryfbe79422020-05-14 22:28:09 -070028
Tom Cherry7a557f42020-06-11 14:06:58 -070029#include "LogBuffer.h"
Tom Cherryfbe79422020-05-14 22:28:09 -070030#include "LogReaderThread.h"
Tom Cherryfbe79422020-05-14 22:28:09 -070031#include "LogWriter.h"
32
33using android::base::Join;
Tom Cherry9f3eb612020-05-20 12:09:22 -070034using android::base::Split;
Tom Cherryfbe79422020-05-14 22:28:09 -070035using android::base::StringPrintf;
36
Tom Cherryfbe79422020-05-14 22:28:09 -070037char* android::uidToName(uid_t) {
38 return nullptr;
39}
40
Tom Cherry6bc6f492020-05-21 12:13:20 -070041static std::vector<std::string> CompareLoggerEntries(const logger_entry& expected,
42 const logger_entry& result, bool ignore_len) {
Tom Cherry9f3eb612020-05-20 12:09:22 -070043 std::vector<std::string> errors;
44 if (!ignore_len && expected.len != result.len) {
45 errors.emplace_back(
46 StringPrintf("len: expected %" PRIu16 " vs %" PRIu16, expected.len, result.len));
47 }
48 if (expected.hdr_size != result.hdr_size) {
49 errors.emplace_back(StringPrintf("hdr_size: %" PRIu16 " vs %" PRIu16, expected.hdr_size,
50 result.hdr_size));
51 }
52 if (expected.pid != result.pid) {
53 errors.emplace_back(
54 StringPrintf("pid: expected %" PRIi32 " vs %" PRIi32, expected.pid, result.pid));
55 }
56 if (expected.tid != result.tid) {
57 errors.emplace_back(
58 StringPrintf("tid: expected %" PRIu32 " vs %" PRIu32, expected.tid, result.tid));
59 }
60 if (expected.sec != result.sec) {
61 errors.emplace_back(
62 StringPrintf("sec: expected %" PRIu32 " vs %" PRIu32, expected.sec, result.sec));
63 }
64 if (expected.nsec != result.nsec) {
65 errors.emplace_back(
66 StringPrintf("nsec: expected %" PRIu32 " vs %" PRIu32, expected.nsec, result.nsec));
67 }
68 if (expected.lid != result.lid) {
69 errors.emplace_back(
70 StringPrintf("lid: expected %" PRIu32 " vs %" PRIu32, expected.lid, result.lid));
71 }
72 if (expected.uid != result.uid) {
73 errors.emplace_back(
74 StringPrintf("uid: expected %" PRIu32 " vs %" PRIu32, expected.uid, result.uid));
75 }
76 return errors;
77}
78
Tom Cherry6bc6f492020-05-21 12:13:20 -070079static std::string MakePrintable(std::string in) {
Tom Cherry9f3eb612020-05-20 12:09:22 -070080 if (in.size() > 80) {
81 in = in.substr(0, 80) + "...";
82 }
83 std::string result;
84 for (const char c : in) {
85 if (isprint(c)) {
86 result.push_back(c);
87 } else {
88 result.append(StringPrintf("\\%02x", static_cast<int>(c) & 0xFF));
89 }
90 }
91 return result;
92}
93
Tom Cherry6bc6f492020-05-21 12:13:20 -070094static std::string CompareMessages(const std::string& expected, const std::string& result) {
Tom Cherry9f3eb612020-05-20 12:09:22 -070095 if (expected == result) {
96 return {};
97 }
98 size_t diff_index = 0;
99 for (; diff_index < std::min(expected.size(), result.size()); ++diff_index) {
100 if (expected[diff_index] != result[diff_index]) {
101 break;
102 }
103 }
104
Tom Cherryca4b25d2020-05-28 20:02:42 -0700105 if (diff_index < 80) {
Tom Cherry9f3eb612020-05-20 12:09:22 -0700106 auto expected_short = MakePrintable(expected);
107 auto result_short = MakePrintable(result);
108 return StringPrintf("msg: expected '%s' vs '%s'", expected_short.c_str(),
109 result_short.c_str());
110 }
111
112 auto expected_short = MakePrintable(expected.substr(diff_index));
113 auto result_short = MakePrintable(result.substr(diff_index));
114 return StringPrintf("msg: index %zu: expected '%s' vs '%s'", diff_index, expected_short.c_str(),
115 result_short.c_str());
116}
117
Tom Cherry6bc6f492020-05-21 12:13:20 -0700118static std::string CompareRegexMessages(const std::string& expected, const std::string& result) {
Tom Cherry9f3eb612020-05-20 12:09:22 -0700119 auto expected_pieces = Split(expected, std::string("\0", 1));
120 auto result_pieces = Split(result, std::string("\0", 1));
121
122 if (expected_pieces.size() != 3 || result_pieces.size() != 3) {
123 return StringPrintf(
124 "msg: should have 3 null delimited strings found %d in expected, %d in result: "
125 "'%s' vs '%s'",
126 static_cast<int>(expected_pieces.size()), static_cast<int>(result_pieces.size()),
127 MakePrintable(expected).c_str(), MakePrintable(result).c_str());
128 }
129 if (expected_pieces[0] != result_pieces[0]) {
130 return StringPrintf("msg: tag/priority mismatch expected '%s' vs '%s'",
131 MakePrintable(expected_pieces[0]).c_str(),
132 MakePrintable(result_pieces[0]).c_str());
133 }
134 std::regex expected_tag_regex(expected_pieces[1]);
135 if (!std::regex_search(result_pieces[1], expected_tag_regex)) {
136 return StringPrintf("msg: message regex mismatch expected '%s' vs '%s'",
137 MakePrintable(expected_pieces[1]).c_str(),
138 MakePrintable(result_pieces[1]).c_str());
139 }
140 if (expected_pieces[2] != result_pieces[2]) {
141 return StringPrintf("msg: nothing expected after final null character '%s' vs '%s'",
142 MakePrintable(expected_pieces[2]).c_str(),
143 MakePrintable(result_pieces[2]).c_str());
144 }
145 return {};
146}
147
148void CompareLogMessages(const std::vector<LogMessage>& expected,
149 const std::vector<LogMessage>& result) {
150 EXPECT_EQ(expected.size(), result.size());
151 size_t end = std::min(expected.size(), result.size());
152 size_t num_errors = 0;
153 for (size_t i = 0; i < end; ++i) {
154 auto errors =
155 CompareLoggerEntries(expected[i].entry, result[i].entry, expected[i].regex_compare);
156 auto msg_error = expected[i].regex_compare
157 ? CompareRegexMessages(expected[i].message, result[i].message)
158 : CompareMessages(expected[i].message, result[i].message);
159 if (!msg_error.empty()) {
160 errors.emplace_back(msg_error);
161 }
162 if (!errors.empty()) {
163 GTEST_LOG_(ERROR) << "Mismatch log message " << i << "\n" << Join(errors, "\n");
164 ++num_errors;
165 }
166 }
167 EXPECT_EQ(0U, num_errors);
168}
169
Tom Cherry6bc6f492020-05-21 12:13:20 -0700170void FixupMessages(std::vector<LogMessage>* messages) {
171 for (auto& [entry, message, _] : *messages) {
172 entry.hdr_size = sizeof(logger_entry);
173 entry.len = message.size();
Tom Cherryfbe79422020-05-14 22:28:09 -0700174 }
Tom Cherry6bc6f492020-05-21 12:13:20 -0700175}
Tom Cherryfbe79422020-05-14 22:28:09 -0700176
Tom Cherry6bc6f492020-05-21 12:13:20 -0700177TEST_P(LogBufferTest, smoke) {
Tom Cherry9f3eb612020-05-20 12:09:22 -0700178 std::vector<LogMessage> log_messages = {
Tom Cherryfbe79422020-05-14 22:28:09 -0700179 {{
180 .pid = 1,
181 .tid = 1,
182 .sec = 1234,
183 .nsec = 323001,
184 .lid = LOG_ID_MAIN,
185 .uid = 0,
186 },
187 "smoke test"},
188 };
189 FixupMessages(&log_messages);
190 LogMessages(log_messages);
191
Tom Cherry60a08d82020-11-18 14:24:07 -0800192 auto flush_result = FlushMessages();
193 EXPECT_EQ(2ULL, flush_result.next_sequence);
194 CompareLogMessages(log_messages, flush_result.messages);
Tom Cherryfbe79422020-05-14 22:28:09 -0700195}
196
Tom Cherry6bc6f492020-05-21 12:13:20 -0700197TEST_P(LogBufferTest, smoke_with_reader_thread) {
Tom Cherry9f3eb612020-05-20 12:09:22 -0700198 std::vector<LogMessage> log_messages = {
Tom Cherryfbe79422020-05-14 22:28:09 -0700199 {{.pid = 1, .tid = 2, .sec = 10000, .nsec = 20001, .lid = LOG_ID_MAIN, .uid = 0},
200 "first"},
201 {{.pid = 10, .tid = 2, .sec = 10000, .nsec = 20002, .lid = LOG_ID_MAIN, .uid = 0},
202 "second"},
203 {{.pid = 100, .tid = 2, .sec = 10000, .nsec = 20003, .lid = LOG_ID_KERNEL, .uid = 0},
204 "third"},
205 {{.pid = 10, .tid = 2, .sec = 10000, .nsec = 20004, .lid = LOG_ID_MAIN, .uid = 0},
206 "fourth"},
207 {{.pid = 1, .tid = 2, .sec = 10000, .nsec = 20005, .lid = LOG_ID_RADIO, .uid = 0},
208 "fifth"},
209 {{.pid = 2, .tid = 2, .sec = 10000, .nsec = 20006, .lid = LOG_ID_RADIO, .uid = 0},
210 "sixth"},
211 {{.pid = 3, .tid = 2, .sec = 10000, .nsec = 20007, .lid = LOG_ID_RADIO, .uid = 0},
212 "seventh"},
213 {{.pid = 4, .tid = 2, .sec = 10000, .nsec = 20008, .lid = LOG_ID_MAIN, .uid = 0},
214 "eighth"},
215 {{.pid = 5, .tid = 2, .sec = 10000, .nsec = 20009, .lid = LOG_ID_CRASH, .uid = 0},
216 "nineth"},
217 {{.pid = 6, .tid = 2, .sec = 10000, .nsec = 20011, .lid = LOG_ID_MAIN, .uid = 0},
218 "tenth"},
219 };
220 FixupMessages(&log_messages);
221 LogMessages(log_messages);
222
Tom Cherry60a08d82020-11-18 14:24:07 -0800223 auto read_log_messages = ReadLogMessagesNonBlockingThread({});
Tom Cherryfbe79422020-05-14 22:28:09 -0700224 CompareLogMessages(log_messages, read_log_messages);
225}
226
227// Generate random messages, set the 'sec' parameter explicit though, to be able to track the
228// expected order of messages.
Tom Cherry9f3eb612020-05-20 12:09:22 -0700229LogMessage GenerateRandomLogMessage(uint32_t sec) {
Tom Cherryfbe79422020-05-14 22:28:09 -0700230 auto rand_uint32 = [](int max) -> uint32_t { return rand() % max; };
231 logger_entry entry = {
232 .hdr_size = sizeof(logger_entry),
233 .pid = rand() % 5000,
234 .tid = rand_uint32(5000),
235 .sec = sec,
236 .nsec = rand_uint32(NS_PER_SEC),
237 .lid = rand_uint32(LOG_ID_STATS),
238 .uid = rand_uint32(100000),
239 };
240
241 // See comment in ChattyLogBuffer::Log() for why this is disallowed.
242 if (entry.nsec % 1000 == 0) {
243 ++entry.nsec;
244 }
245
246 if (entry.lid == LOG_ID_EVENTS) {
247 entry.lid = LOG_ID_KERNEL;
248 }
249
250 std::string message;
251 char priority = ANDROID_LOG_INFO + rand() % 2;
252 message.push_back(priority);
253
254 int tag_length = 2 + rand() % 10;
255 for (int i = 0; i < tag_length; ++i) {
256 message.push_back('a' + rand() % 26);
257 }
258 message.push_back('\0');
259
260 int msg_length = 2 + rand() % 1000;
261 for (int i = 0; i < msg_length; ++i) {
262 message.push_back('a' + rand() % 26);
263 }
264 message.push_back('\0');
265
266 entry.len = message.size();
267
268 return {entry, message};
269}
270
Tom Cherry60a08d82020-11-18 14:24:07 -0800271std::vector<LogMessage> GenerateRandomLogMessages(size_t count) {
Tom Cherryfbe79422020-05-14 22:28:09 -0700272 srand(1);
Tom Cherry9f3eb612020-05-20 12:09:22 -0700273 std::vector<LogMessage> log_messages;
Tom Cherry60a08d82020-11-18 14:24:07 -0800274 for (size_t i = 0; i < count; ++i) {
Tom Cherryfbe79422020-05-14 22:28:09 -0700275 log_messages.emplace_back(GenerateRandomLogMessage(i));
276 }
Tom Cherry60a08d82020-11-18 14:24:07 -0800277 return log_messages;
278}
279
280TEST_P(LogBufferTest, random_messages) {
281 auto log_messages = GenerateRandomLogMessages(1000);
Tom Cherryfbe79422020-05-14 22:28:09 -0700282 LogMessages(log_messages);
283
Tom Cherry60a08d82020-11-18 14:24:07 -0800284 auto read_log_messages = ReadLogMessagesNonBlockingThread({});
Tom Cherryfbe79422020-05-14 22:28:09 -0700285 CompareLogMessages(log_messages, read_log_messages);
286}
Tom Cherry9f3eb612020-05-20 12:09:22 -0700287
Tom Cherry33ce9422020-06-01 13:43:50 -0700288TEST_P(LogBufferTest, read_last_sequence) {
289 std::vector<LogMessage> log_messages = {
290 {{.pid = 1, .tid = 2, .sec = 10000, .nsec = 20001, .lid = LOG_ID_MAIN, .uid = 0},
291 "first"},
292 {{.pid = 10, .tid = 2, .sec = 10000, .nsec = 20002, .lid = LOG_ID_MAIN, .uid = 0},
293 "second"},
294 {{.pid = 100, .tid = 2, .sec = 10000, .nsec = 20003, .lid = LOG_ID_MAIN, .uid = 0},
295 "third"},
296 };
297 FixupMessages(&log_messages);
298 LogMessages(log_messages);
299
Tom Cherry33ce9422020-06-01 13:43:50 -0700300 std::vector<LogMessage> expected_log_messages = {log_messages.back()};
Tom Cherry60a08d82020-11-18 14:24:07 -0800301 auto read_log_messages = ReadLogMessagesNonBlockingThread({.sequence = 3});
Tom Cherry33ce9422020-06-01 13:43:50 -0700302 CompareLogMessages(expected_log_messages, read_log_messages);
303}
304
Tom Cherry7a557f42020-06-11 14:06:58 -0700305TEST_P(LogBufferTest, clear_logs) {
306 // Log 3 initial logs.
307 std::vector<LogMessage> log_messages = {
308 {{.pid = 1, .tid = 2, .sec = 10000, .nsec = 20001, .lid = LOG_ID_MAIN, .uid = 0},
309 "first"},
310 {{.pid = 10, .tid = 2, .sec = 10000, .nsec = 20002, .lid = LOG_ID_MAIN, .uid = 0},
311 "second"},
312 {{.pid = 100, .tid = 2, .sec = 10000, .nsec = 20003, .lid = LOG_ID_MAIN, .uid = 0},
313 "third"},
314 };
315 FixupMessages(&log_messages);
316 LogMessages(log_messages);
317
Tom Cherry7a557f42020-06-11 14:06:58 -0700318 // Connect a blocking reader.
Tom Cherry60a08d82020-11-18 14:24:07 -0800319 auto blocking_reader = TestReaderThread({.non_block = false}, *this);
Tom Cherry7a557f42020-06-11 14:06:58 -0700320
321 // Wait up to 250ms for the reader to read the first 3 logs.
322 constexpr int kMaxRetryCount = 50;
323 int count = 0;
324 for (; count < kMaxRetryCount; ++count) {
325 usleep(5000);
Tom Cherryc5c9eba2020-10-06 10:22:35 -0700326 auto lock = std::lock_guard{logd_lock};
Tom Cherry7a557f42020-06-11 14:06:58 -0700327 if (reader_list_.reader_threads().back()->start() == 4) {
328 break;
329 }
330 }
331 ASSERT_LT(count, kMaxRetryCount);
332
333 // Clear the log buffer.
334 log_buffer_->Clear(LOG_ID_MAIN, 0);
335
336 // Log 3 more logs.
337 std::vector<LogMessage> after_clear_messages = {
338 {{.pid = 1, .tid = 2, .sec = 10000, .nsec = 20001, .lid = LOG_ID_MAIN, .uid = 0},
339 "4th"},
340 {{.pid = 10, .tid = 2, .sec = 10000, .nsec = 20002, .lid = LOG_ID_MAIN, .uid = 0},
341 "5th"},
342 {{.pid = 100, .tid = 2, .sec = 10000, .nsec = 20003, .lid = LOG_ID_MAIN, .uid = 0},
343 "6th"},
344 };
345 FixupMessages(&after_clear_messages);
346 LogMessages(after_clear_messages);
347
348 // Wait up to 250ms for the reader to read the 3 additional logs.
349 for (count = 0; count < kMaxRetryCount; ++count) {
350 usleep(5000);
Tom Cherryc5c9eba2020-10-06 10:22:35 -0700351 auto lock = std::lock_guard{logd_lock};
Tom Cherry7a557f42020-06-11 14:06:58 -0700352 if (reader_list_.reader_threads().back()->start() == 7) {
353 break;
354 }
355 }
356 ASSERT_LT(count, kMaxRetryCount);
357
Tom Cherry60a08d82020-11-18 14:24:07 -0800358 ReleaseAndJoinReaders();
Tom Cherry7a557f42020-06-11 14:06:58 -0700359
360 // Check that we have read all 6 messages.
361 std::vector<LogMessage> expected_log_messages = log_messages;
362 expected_log_messages.insert(expected_log_messages.end(), after_clear_messages.begin(),
363 after_clear_messages.end());
Tom Cherry60a08d82020-11-18 14:24:07 -0800364 CompareLogMessages(expected_log_messages, blocking_reader.read_log_messages());
Tom Cherry7a557f42020-06-11 14:06:58 -0700365
Tom Cherry60a08d82020-11-18 14:24:07 -0800366 // Finally, Flush messages and ensure that only the 3 logs after the clear remain in the buffer.
367 auto flush_after_clear_result = FlushMessages();
368 EXPECT_EQ(7ULL, flush_after_clear_result.next_sequence);
369 CompareLogMessages(after_clear_messages, flush_after_clear_result.messages);
Tom Cherry7a557f42020-06-11 14:06:58 -0700370}
371
Tom Cherry0f7ec302020-11-13 10:52:35 -0800372TEST_P(LogBufferTest, tail100_nonblocking_1000total) {
Tom Cherry60a08d82020-11-18 14:24:07 -0800373 auto log_messages = GenerateRandomLogMessages(1000);
Tom Cherry0f7ec302020-11-13 10:52:35 -0800374 LogMessages(log_messages);
375
Tom Cherry0f7ec302020-11-13 10:52:35 -0800376 constexpr int kTailCount = 100;
Tom Cherry0f7ec302020-11-13 10:52:35 -0800377 std::vector<LogMessage> expected_log_messages{log_messages.end() - kTailCount,
378 log_messages.end()};
Tom Cherry60a08d82020-11-18 14:24:07 -0800379 auto read_log_messages = ReadLogMessagesNonBlockingThread({.tail = kTailCount});
Tom Cherry0f7ec302020-11-13 10:52:35 -0800380 CompareLogMessages(expected_log_messages, read_log_messages);
381}
382
383TEST_P(LogBufferTest, tail100_blocking_1000total_then1000more) {
Tom Cherry60a08d82020-11-18 14:24:07 -0800384 auto log_messages = GenerateRandomLogMessages(1000);
Tom Cherry0f7ec302020-11-13 10:52:35 -0800385 LogMessages(log_messages);
386
Tom Cherry0f7ec302020-11-13 10:52:35 -0800387 constexpr int kTailCount = 100;
Tom Cherry60a08d82020-11-18 14:24:07 -0800388 auto blocking_reader = TestReaderThread({.non_block = false, .tail = kTailCount}, *this);
Tom Cherry0f7ec302020-11-13 10:52:35 -0800389
390 std::vector<LogMessage> expected_log_messages{log_messages.end() - kTailCount,
391 log_messages.end()};
392
393 // Wait for the reader to have read the messages.
394 int retry_count = 1s / 5000us;
395 while (retry_count--) {
396 usleep(5000);
397 auto lock = std::lock_guard{logd_lock};
Tom Cherry60a08d82020-11-18 14:24:07 -0800398 if (blocking_reader.read_log_messages().size() == expected_log_messages.size()) {
399 CompareLogMessages(expected_log_messages, blocking_reader.read_log_messages());
Tom Cherry0f7ec302020-11-13 10:52:35 -0800400 break;
401 }
402 }
403 ASSERT_GT(retry_count, 0);
404
405 // Log more messages
Tom Cherry60a08d82020-11-18 14:24:07 -0800406 log_messages = GenerateRandomLogMessages(1000);
Tom Cherry0f7ec302020-11-13 10:52:35 -0800407 LogMessages(log_messages);
408 expected_log_messages.insert(expected_log_messages.end(), log_messages.begin(),
409 log_messages.end());
410
411 // Wait for the reader to have read the new messages.
412 retry_count = 1s / 5000us;
413 while (retry_count--) {
414 usleep(5000);
415 auto lock = std::lock_guard{logd_lock};
Tom Cherry60a08d82020-11-18 14:24:07 -0800416 if (blocking_reader.read_log_messages().size() == expected_log_messages.size()) {
417 CompareLogMessages(expected_log_messages, blocking_reader.read_log_messages());
Tom Cherry0f7ec302020-11-13 10:52:35 -0800418 break;
419 }
420 }
421 ASSERT_GT(retry_count, 0);
422
Tom Cherry60a08d82020-11-18 14:24:07 -0800423 ReleaseAndJoinReaders();
Tom Cherry0f7ec302020-11-13 10:52:35 -0800424
425 // Final check that no extraneous logs were logged.
Tom Cherry60a08d82020-11-18 14:24:07 -0800426 CompareLogMessages(expected_log_messages, blocking_reader.read_log_messages());
Tom Cherry0f7ec302020-11-13 10:52:35 -0800427}
428
429TEST_P(LogBufferTest, tail100_nonblocking_50total) {
Tom Cherry60a08d82020-11-18 14:24:07 -0800430 auto log_messages = GenerateRandomLogMessages(50);
Tom Cherry0f7ec302020-11-13 10:52:35 -0800431 LogMessages(log_messages);
432
Tom Cherry0f7ec302020-11-13 10:52:35 -0800433 constexpr int kTailCount = 100;
Tom Cherry60a08d82020-11-18 14:24:07 -0800434 auto read_log_messages = ReadLogMessagesNonBlockingThread({.tail = kTailCount});
Tom Cherry0f7ec302020-11-13 10:52:35 -0800435 CompareLogMessages(log_messages, read_log_messages);
436}
437
438TEST_P(LogBufferTest, tail100_blocking_50total_then1000more) {
Tom Cherry60a08d82020-11-18 14:24:07 -0800439 auto log_messages = GenerateRandomLogMessages(50);
Tom Cherry0f7ec302020-11-13 10:52:35 -0800440 LogMessages(log_messages);
441
Tom Cherry0f7ec302020-11-13 10:52:35 -0800442 constexpr int kTailCount = 100;
Tom Cherry60a08d82020-11-18 14:24:07 -0800443 auto blocking_reader = TestReaderThread({.non_block = false, .tail = kTailCount}, *this);
Tom Cherry0f7ec302020-11-13 10:52:35 -0800444
445 std::vector<LogMessage> expected_log_messages = log_messages;
446
447 // Wait for the reader to have read the messages.
448 int retry_count = 1s / 5000us;
449 while (retry_count--) {
450 usleep(5000);
451 auto lock = std::lock_guard{logd_lock};
Tom Cherry60a08d82020-11-18 14:24:07 -0800452 if (blocking_reader.read_log_messages().size() == expected_log_messages.size()) {
453 CompareLogMessages(expected_log_messages, blocking_reader.read_log_messages());
Tom Cherry0f7ec302020-11-13 10:52:35 -0800454 break;
455 }
456 }
457 ASSERT_GT(retry_count, 0);
458
459 // Log more messages
Tom Cherry60a08d82020-11-18 14:24:07 -0800460 log_messages = GenerateRandomLogMessages(1000);
Tom Cherry0f7ec302020-11-13 10:52:35 -0800461 LogMessages(log_messages);
462 expected_log_messages.insert(expected_log_messages.end(), log_messages.begin(),
463 log_messages.end());
464
465 // Wait for the reader to have read the new messages.
466 retry_count = 1s / 5000us;
467 while (retry_count--) {
468 usleep(5000);
469 auto lock = std::lock_guard{logd_lock};
Tom Cherry60a08d82020-11-18 14:24:07 -0800470 if (blocking_reader.read_log_messages().size() == expected_log_messages.size()) {
471 CompareLogMessages(expected_log_messages, blocking_reader.read_log_messages());
472
Tom Cherry0f7ec302020-11-13 10:52:35 -0800473 break;
474 }
475 }
476 ASSERT_GT(retry_count, 0);
477
Tom Cherry60a08d82020-11-18 14:24:07 -0800478 ReleaseAndJoinReaders();
Tom Cherry0f7ec302020-11-13 10:52:35 -0800479
480 // Final check that no extraneous logs were logged.
Tom Cherry60a08d82020-11-18 14:24:07 -0800481 CompareLogMessages(expected_log_messages, blocking_reader.read_log_messages());
Tom Cherry0f7ec302020-11-13 10:52:35 -0800482}
483
Tom Cherryfb150dd2020-05-13 09:28:37 -0700484INSTANTIATE_TEST_CASE_P(LogBufferTests, LogBufferTest,
485 testing::Values("chatty", "serialized", "simple"));