xref: /aosp_15_r20/system/logging/logd/LogBufferTest.cpp (revision 598139dc91b21518d67c408eaea2644226490971)
1*598139dcSAndroid Build Coastguard Worker /*
2*598139dcSAndroid Build Coastguard Worker  * Copyright (C) 2020 The Android Open Source Project
3*598139dcSAndroid Build Coastguard Worker  *
4*598139dcSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*598139dcSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*598139dcSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*598139dcSAndroid Build Coastguard Worker  *
8*598139dcSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*598139dcSAndroid Build Coastguard Worker  *
10*598139dcSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*598139dcSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*598139dcSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*598139dcSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*598139dcSAndroid Build Coastguard Worker  * limitations under the License.
15*598139dcSAndroid Build Coastguard Worker  */
16*598139dcSAndroid Build Coastguard Worker 
17*598139dcSAndroid Build Coastguard Worker #include "LogBufferTest.h"
18*598139dcSAndroid Build Coastguard Worker 
19*598139dcSAndroid Build Coastguard Worker #include <unistd.h>
20*598139dcSAndroid Build Coastguard Worker 
21*598139dcSAndroid Build Coastguard Worker #include <limits>
22*598139dcSAndroid Build Coastguard Worker #include <memory>
23*598139dcSAndroid Build Coastguard Worker #include <regex>
24*598139dcSAndroid Build Coastguard Worker #include <vector>
25*598139dcSAndroid Build Coastguard Worker 
26*598139dcSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
27*598139dcSAndroid Build Coastguard Worker #include <android-base/strings.h>
28*598139dcSAndroid Build Coastguard Worker 
29*598139dcSAndroid Build Coastguard Worker #include "LogBuffer.h"
30*598139dcSAndroid Build Coastguard Worker #include "LogReaderThread.h"
31*598139dcSAndroid Build Coastguard Worker #include "LogWriter.h"
32*598139dcSAndroid Build Coastguard Worker 
33*598139dcSAndroid Build Coastguard Worker using android::base::Join;
34*598139dcSAndroid Build Coastguard Worker using android::base::Split;
35*598139dcSAndroid Build Coastguard Worker using android::base::StringPrintf;
36*598139dcSAndroid Build Coastguard Worker 
uidToName(uid_t)37*598139dcSAndroid Build Coastguard Worker char* android::uidToName(uid_t) {
38*598139dcSAndroid Build Coastguard Worker     return nullptr;
39*598139dcSAndroid Build Coastguard Worker }
40*598139dcSAndroid Build Coastguard Worker 
CompareLoggerEntries(const logger_entry & expected,const logger_entry & result,bool ignore_len)41*598139dcSAndroid Build Coastguard Worker static std::vector<std::string> CompareLoggerEntries(const logger_entry& expected,
42*598139dcSAndroid Build Coastguard Worker                                                      const logger_entry& result, bool ignore_len) {
43*598139dcSAndroid Build Coastguard Worker     std::vector<std::string> errors;
44*598139dcSAndroid Build Coastguard Worker     if (!ignore_len && expected.len != result.len) {
45*598139dcSAndroid Build Coastguard Worker         errors.emplace_back(
46*598139dcSAndroid Build Coastguard Worker                 StringPrintf("len: expected %" PRIu16 " vs %" PRIu16, expected.len, result.len));
47*598139dcSAndroid Build Coastguard Worker     }
48*598139dcSAndroid Build Coastguard Worker     if (expected.hdr_size != result.hdr_size) {
49*598139dcSAndroid Build Coastguard Worker         errors.emplace_back(StringPrintf("hdr_size: %" PRIu16 " vs %" PRIu16, expected.hdr_size,
50*598139dcSAndroid Build Coastguard Worker                                          result.hdr_size));
51*598139dcSAndroid Build Coastguard Worker     }
52*598139dcSAndroid Build Coastguard Worker     if (expected.pid != result.pid) {
53*598139dcSAndroid Build Coastguard Worker         errors.emplace_back(
54*598139dcSAndroid Build Coastguard Worker                 StringPrintf("pid: expected %" PRIi32 " vs %" PRIi32, expected.pid, result.pid));
55*598139dcSAndroid Build Coastguard Worker     }
56*598139dcSAndroid Build Coastguard Worker     if (expected.tid != result.tid) {
57*598139dcSAndroid Build Coastguard Worker         errors.emplace_back(
58*598139dcSAndroid Build Coastguard Worker                 StringPrintf("tid: expected %" PRIu32 " vs %" PRIu32, expected.tid, result.tid));
59*598139dcSAndroid Build Coastguard Worker     }
60*598139dcSAndroid Build Coastguard Worker     if (expected.sec != result.sec) {
61*598139dcSAndroid Build Coastguard Worker         errors.emplace_back(
62*598139dcSAndroid Build Coastguard Worker                 StringPrintf("sec: expected %" PRIu32 " vs %" PRIu32, expected.sec, result.sec));
63*598139dcSAndroid Build Coastguard Worker     }
64*598139dcSAndroid Build Coastguard Worker     if (expected.nsec != result.nsec) {
65*598139dcSAndroid Build Coastguard Worker         errors.emplace_back(
66*598139dcSAndroid Build Coastguard Worker                 StringPrintf("nsec: expected %" PRIu32 " vs %" PRIu32, expected.nsec, result.nsec));
67*598139dcSAndroid Build Coastguard Worker     }
68*598139dcSAndroid Build Coastguard Worker     if (expected.lid != result.lid) {
69*598139dcSAndroid Build Coastguard Worker         errors.emplace_back(
70*598139dcSAndroid Build Coastguard Worker                 StringPrintf("lid: expected %" PRIu32 " vs %" PRIu32, expected.lid, result.lid));
71*598139dcSAndroid Build Coastguard Worker     }
72*598139dcSAndroid Build Coastguard Worker     if (expected.uid != result.uid) {
73*598139dcSAndroid Build Coastguard Worker         errors.emplace_back(
74*598139dcSAndroid Build Coastguard Worker                 StringPrintf("uid: expected %" PRIu32 " vs %" PRIu32, expected.uid, result.uid));
75*598139dcSAndroid Build Coastguard Worker     }
76*598139dcSAndroid Build Coastguard Worker     return errors;
77*598139dcSAndroid Build Coastguard Worker }
78*598139dcSAndroid Build Coastguard Worker 
MakePrintable(std::string in)79*598139dcSAndroid Build Coastguard Worker static std::string MakePrintable(std::string in) {
80*598139dcSAndroid Build Coastguard Worker     if (in.size() > 80) {
81*598139dcSAndroid Build Coastguard Worker         in = in.substr(0, 80) + "...";
82*598139dcSAndroid Build Coastguard Worker     }
83*598139dcSAndroid Build Coastguard Worker     std::string result;
84*598139dcSAndroid Build Coastguard Worker     for (const char c : in) {
85*598139dcSAndroid Build Coastguard Worker         if (isprint(c)) {
86*598139dcSAndroid Build Coastguard Worker             result.push_back(c);
87*598139dcSAndroid Build Coastguard Worker         } else {
88*598139dcSAndroid Build Coastguard Worker             result.append(StringPrintf("\\%02x", static_cast<int>(c) & 0xFF));
89*598139dcSAndroid Build Coastguard Worker         }
90*598139dcSAndroid Build Coastguard Worker     }
91*598139dcSAndroid Build Coastguard Worker     return result;
92*598139dcSAndroid Build Coastguard Worker }
93*598139dcSAndroid Build Coastguard Worker 
CompareMessages(const std::string & expected,const std::string & result)94*598139dcSAndroid Build Coastguard Worker static std::string CompareMessages(const std::string& expected, const std::string& result) {
95*598139dcSAndroid Build Coastguard Worker     if (expected == result) {
96*598139dcSAndroid Build Coastguard Worker         return {};
97*598139dcSAndroid Build Coastguard Worker     }
98*598139dcSAndroid Build Coastguard Worker     size_t diff_index = 0;
99*598139dcSAndroid Build Coastguard Worker     for (; diff_index < std::min(expected.size(), result.size()); ++diff_index) {
100*598139dcSAndroid Build Coastguard Worker         if (expected[diff_index] != result[diff_index]) {
101*598139dcSAndroid Build Coastguard Worker             break;
102*598139dcSAndroid Build Coastguard Worker         }
103*598139dcSAndroid Build Coastguard Worker     }
104*598139dcSAndroid Build Coastguard Worker 
105*598139dcSAndroid Build Coastguard Worker     if (diff_index < 80) {
106*598139dcSAndroid Build Coastguard Worker         auto expected_short = MakePrintable(expected);
107*598139dcSAndroid Build Coastguard Worker         auto result_short = MakePrintable(result);
108*598139dcSAndroid Build Coastguard Worker         return StringPrintf("msg: expected '%s' vs '%s'", expected_short.c_str(),
109*598139dcSAndroid Build Coastguard Worker                             result_short.c_str());
110*598139dcSAndroid Build Coastguard Worker     }
111*598139dcSAndroid Build Coastguard Worker 
112*598139dcSAndroid Build Coastguard Worker     auto expected_short = MakePrintable(expected.substr(diff_index));
113*598139dcSAndroid Build Coastguard Worker     auto result_short = MakePrintable(result.substr(diff_index));
114*598139dcSAndroid Build Coastguard Worker     return StringPrintf("msg: index %zu: expected '%s' vs '%s'", diff_index, expected_short.c_str(),
115*598139dcSAndroid Build Coastguard Worker                         result_short.c_str());
116*598139dcSAndroid Build Coastguard Worker }
117*598139dcSAndroid Build Coastguard Worker 
CompareRegexMessages(const std::string & expected,const std::string & result)118*598139dcSAndroid Build Coastguard Worker static std::string CompareRegexMessages(const std::string& expected, const std::string& result) {
119*598139dcSAndroid Build Coastguard Worker     auto expected_pieces = Split(expected, std::string("\0", 1));
120*598139dcSAndroid Build Coastguard Worker     auto result_pieces = Split(result, std::string("\0", 1));
121*598139dcSAndroid Build Coastguard Worker 
122*598139dcSAndroid Build Coastguard Worker     if (expected_pieces.size() != 3 || result_pieces.size() != 3) {
123*598139dcSAndroid Build Coastguard Worker         return StringPrintf(
124*598139dcSAndroid Build Coastguard Worker                 "msg: should have 3 null delimited strings found %d in expected, %d in result: "
125*598139dcSAndroid Build Coastguard Worker                 "'%s' vs '%s'",
126*598139dcSAndroid Build Coastguard Worker                 static_cast<int>(expected_pieces.size()), static_cast<int>(result_pieces.size()),
127*598139dcSAndroid Build Coastguard Worker                 MakePrintable(expected).c_str(), MakePrintable(result).c_str());
128*598139dcSAndroid Build Coastguard Worker     }
129*598139dcSAndroid Build Coastguard Worker     if (expected_pieces[0] != result_pieces[0]) {
130*598139dcSAndroid Build Coastguard Worker         return StringPrintf("msg: tag/priority mismatch expected '%s' vs '%s'",
131*598139dcSAndroid Build Coastguard Worker                             MakePrintable(expected_pieces[0]).c_str(),
132*598139dcSAndroid Build Coastguard Worker                             MakePrintable(result_pieces[0]).c_str());
133*598139dcSAndroid Build Coastguard Worker     }
134*598139dcSAndroid Build Coastguard Worker     std::regex expected_tag_regex(expected_pieces[1]);
135*598139dcSAndroid Build Coastguard Worker     if (!std::regex_search(result_pieces[1], expected_tag_regex)) {
136*598139dcSAndroid Build Coastguard Worker         return StringPrintf("msg: message regex mismatch expected '%s' vs '%s'",
137*598139dcSAndroid Build Coastguard Worker                             MakePrintable(expected_pieces[1]).c_str(),
138*598139dcSAndroid Build Coastguard Worker                             MakePrintable(result_pieces[1]).c_str());
139*598139dcSAndroid Build Coastguard Worker     }
140*598139dcSAndroid Build Coastguard Worker     if (expected_pieces[2] != result_pieces[2]) {
141*598139dcSAndroid Build Coastguard Worker         return StringPrintf("msg: nothing expected after final null character '%s' vs '%s'",
142*598139dcSAndroid Build Coastguard Worker                             MakePrintable(expected_pieces[2]).c_str(),
143*598139dcSAndroid Build Coastguard Worker                             MakePrintable(result_pieces[2]).c_str());
144*598139dcSAndroid Build Coastguard Worker     }
145*598139dcSAndroid Build Coastguard Worker     return {};
146*598139dcSAndroid Build Coastguard Worker }
147*598139dcSAndroid Build Coastguard Worker 
CompareLogMessages(const std::vector<LogMessage> & expected,const std::vector<LogMessage> & result)148*598139dcSAndroid Build Coastguard Worker void CompareLogMessages(const std::vector<LogMessage>& expected,
149*598139dcSAndroid Build Coastguard Worker                         const std::vector<LogMessage>& result) {
150*598139dcSAndroid Build Coastguard Worker     EXPECT_EQ(expected.size(), result.size());
151*598139dcSAndroid Build Coastguard Worker     size_t end = std::min(expected.size(), result.size());
152*598139dcSAndroid Build Coastguard Worker     size_t num_errors = 0;
153*598139dcSAndroid Build Coastguard Worker     for (size_t i = 0; i < end; ++i) {
154*598139dcSAndroid Build Coastguard Worker         auto errors =
155*598139dcSAndroid Build Coastguard Worker                 CompareLoggerEntries(expected[i].entry, result[i].entry, expected[i].regex_compare);
156*598139dcSAndroid Build Coastguard Worker         auto msg_error = expected[i].regex_compare
157*598139dcSAndroid Build Coastguard Worker                                  ? CompareRegexMessages(expected[i].message, result[i].message)
158*598139dcSAndroid Build Coastguard Worker                                  : CompareMessages(expected[i].message, result[i].message);
159*598139dcSAndroid Build Coastguard Worker         if (!msg_error.empty()) {
160*598139dcSAndroid Build Coastguard Worker             errors.emplace_back(msg_error);
161*598139dcSAndroid Build Coastguard Worker         }
162*598139dcSAndroid Build Coastguard Worker         if (!errors.empty()) {
163*598139dcSAndroid Build Coastguard Worker             GTEST_LOG_(ERROR) << "Mismatch log message " << i << "\n" << Join(errors, "\n");
164*598139dcSAndroid Build Coastguard Worker             ++num_errors;
165*598139dcSAndroid Build Coastguard Worker         }
166*598139dcSAndroid Build Coastguard Worker     }
167*598139dcSAndroid Build Coastguard Worker     EXPECT_EQ(0U, num_errors);
168*598139dcSAndroid Build Coastguard Worker }
169*598139dcSAndroid Build Coastguard Worker 
FixupMessages(std::vector<LogMessage> * messages)170*598139dcSAndroid Build Coastguard Worker void FixupMessages(std::vector<LogMessage>* messages) {
171*598139dcSAndroid Build Coastguard Worker     for (auto& [entry, message, _] : *messages) {
172*598139dcSAndroid Build Coastguard Worker         entry.hdr_size = sizeof(logger_entry);
173*598139dcSAndroid Build Coastguard Worker         entry.len = message.size();
174*598139dcSAndroid Build Coastguard Worker     }
175*598139dcSAndroid Build Coastguard Worker }
176*598139dcSAndroid Build Coastguard Worker 
TEST_P(LogBufferTest,smoke)177*598139dcSAndroid Build Coastguard Worker TEST_P(LogBufferTest, smoke) {
178*598139dcSAndroid Build Coastguard Worker     std::vector<LogMessage> log_messages = {
179*598139dcSAndroid Build Coastguard Worker             {{
180*598139dcSAndroid Build Coastguard Worker                      .pid = 1,
181*598139dcSAndroid Build Coastguard Worker                      .tid = 1,
182*598139dcSAndroid Build Coastguard Worker                      .sec = 1234,
183*598139dcSAndroid Build Coastguard Worker                      .nsec = 323001,
184*598139dcSAndroid Build Coastguard Worker                      .lid = LOG_ID_MAIN,
185*598139dcSAndroid Build Coastguard Worker                      .uid = 0,
186*598139dcSAndroid Build Coastguard Worker              },
187*598139dcSAndroid Build Coastguard Worker              "smoke test"},
188*598139dcSAndroid Build Coastguard Worker     };
189*598139dcSAndroid Build Coastguard Worker     FixupMessages(&log_messages);
190*598139dcSAndroid Build Coastguard Worker     LogMessages(log_messages);
191*598139dcSAndroid Build Coastguard Worker 
192*598139dcSAndroid Build Coastguard Worker     auto flush_result = FlushMessages();
193*598139dcSAndroid Build Coastguard Worker     EXPECT_EQ(2ULL, flush_result.next_sequence);
194*598139dcSAndroid Build Coastguard Worker     CompareLogMessages(log_messages, flush_result.messages);
195*598139dcSAndroid Build Coastguard Worker }
196*598139dcSAndroid Build Coastguard Worker 
TEST_P(LogBufferTest,smoke_with_reader_thread)197*598139dcSAndroid Build Coastguard Worker TEST_P(LogBufferTest, smoke_with_reader_thread) {
198*598139dcSAndroid Build Coastguard Worker     std::vector<LogMessage> log_messages = {
199*598139dcSAndroid Build Coastguard Worker             {{.pid = 1, .tid = 2, .sec = 10000, .nsec = 20001, .lid = LOG_ID_MAIN, .uid = 0},
200*598139dcSAndroid Build Coastguard Worker              "first"},
201*598139dcSAndroid Build Coastguard Worker             {{.pid = 10, .tid = 2, .sec = 10000, .nsec = 20002, .lid = LOG_ID_MAIN, .uid = 0},
202*598139dcSAndroid Build Coastguard Worker              "second"},
203*598139dcSAndroid Build Coastguard Worker             {{.pid = 100, .tid = 2, .sec = 10000, .nsec = 20003, .lid = LOG_ID_KERNEL, .uid = 0},
204*598139dcSAndroid Build Coastguard Worker              "third"},
205*598139dcSAndroid Build Coastguard Worker             {{.pid = 10, .tid = 2, .sec = 10000, .nsec = 20004, .lid = LOG_ID_MAIN, .uid = 0},
206*598139dcSAndroid Build Coastguard Worker              "fourth"},
207*598139dcSAndroid Build Coastguard Worker             {{.pid = 1, .tid = 2, .sec = 10000, .nsec = 20005, .lid = LOG_ID_RADIO, .uid = 0},
208*598139dcSAndroid Build Coastguard Worker              "fifth"},
209*598139dcSAndroid Build Coastguard Worker             {{.pid = 2, .tid = 2, .sec = 10000, .nsec = 20006, .lid = LOG_ID_RADIO, .uid = 0},
210*598139dcSAndroid Build Coastguard Worker              "sixth"},
211*598139dcSAndroid Build Coastguard Worker             {{.pid = 3, .tid = 2, .sec = 10000, .nsec = 20007, .lid = LOG_ID_RADIO, .uid = 0},
212*598139dcSAndroid Build Coastguard Worker              "seventh"},
213*598139dcSAndroid Build Coastguard Worker             {{.pid = 4, .tid = 2, .sec = 10000, .nsec = 20008, .lid = LOG_ID_MAIN, .uid = 0},
214*598139dcSAndroid Build Coastguard Worker              "eighth"},
215*598139dcSAndroid Build Coastguard Worker             {{.pid = 5, .tid = 2, .sec = 10000, .nsec = 20009, .lid = LOG_ID_CRASH, .uid = 0},
216*598139dcSAndroid Build Coastguard Worker              "nineth"},
217*598139dcSAndroid Build Coastguard Worker             {{.pid = 6, .tid = 2, .sec = 10000, .nsec = 20011, .lid = LOG_ID_MAIN, .uid = 0},
218*598139dcSAndroid Build Coastguard Worker              "tenth"},
219*598139dcSAndroid Build Coastguard Worker     };
220*598139dcSAndroid Build Coastguard Worker     FixupMessages(&log_messages);
221*598139dcSAndroid Build Coastguard Worker     LogMessages(log_messages);
222*598139dcSAndroid Build Coastguard Worker 
223*598139dcSAndroid Build Coastguard Worker     auto read_log_messages = ReadLogMessagesNonBlockingThread({});
224*598139dcSAndroid Build Coastguard Worker     CompareLogMessages(log_messages, read_log_messages);
225*598139dcSAndroid Build Coastguard Worker }
226*598139dcSAndroid Build Coastguard Worker 
227*598139dcSAndroid Build Coastguard Worker // Generate random messages, set the 'sec' parameter explicit though, to be able to track the
228*598139dcSAndroid Build Coastguard Worker // expected order of messages.
GenerateRandomLogMessage(uint32_t sec)229*598139dcSAndroid Build Coastguard Worker LogMessage GenerateRandomLogMessage(uint32_t sec) {
230*598139dcSAndroid Build Coastguard Worker     auto rand_uint32 = [](int max) -> uint32_t { return rand() % max; };
231*598139dcSAndroid Build Coastguard Worker     logger_entry entry = {
232*598139dcSAndroid Build Coastguard Worker             .hdr_size = sizeof(logger_entry),
233*598139dcSAndroid Build Coastguard Worker             .pid = rand() % 5000,
234*598139dcSAndroid Build Coastguard Worker             .tid = rand_uint32(5000),
235*598139dcSAndroid Build Coastguard Worker             .sec = sec,
236*598139dcSAndroid Build Coastguard Worker             .nsec = rand_uint32(NS_PER_SEC),
237*598139dcSAndroid Build Coastguard Worker             .lid = rand_uint32(LOG_ID_STATS),
238*598139dcSAndroid Build Coastguard Worker             .uid = rand_uint32(100000),
239*598139dcSAndroid Build Coastguard Worker     };
240*598139dcSAndroid Build Coastguard Worker 
241*598139dcSAndroid Build Coastguard Worker     // See comment in ChattyLogBuffer::Log() for why this is disallowed.
242*598139dcSAndroid Build Coastguard Worker     if (entry.nsec % 1000 == 0) {
243*598139dcSAndroid Build Coastguard Worker         ++entry.nsec;
244*598139dcSAndroid Build Coastguard Worker     }
245*598139dcSAndroid Build Coastguard Worker 
246*598139dcSAndroid Build Coastguard Worker     if (entry.lid == LOG_ID_EVENTS) {
247*598139dcSAndroid Build Coastguard Worker         entry.lid = LOG_ID_KERNEL;
248*598139dcSAndroid Build Coastguard Worker     }
249*598139dcSAndroid Build Coastguard Worker 
250*598139dcSAndroid Build Coastguard Worker     std::string message;
251*598139dcSAndroid Build Coastguard Worker     char priority = ANDROID_LOG_INFO + rand() % 2;
252*598139dcSAndroid Build Coastguard Worker     message.push_back(priority);
253*598139dcSAndroid Build Coastguard Worker 
254*598139dcSAndroid Build Coastguard Worker     int tag_length = 2 + rand() % 10;
255*598139dcSAndroid Build Coastguard Worker     for (int i = 0; i < tag_length; ++i) {
256*598139dcSAndroid Build Coastguard Worker         message.push_back('a' + rand() % 26);
257*598139dcSAndroid Build Coastguard Worker     }
258*598139dcSAndroid Build Coastguard Worker     message.push_back('\0');
259*598139dcSAndroid Build Coastguard Worker 
260*598139dcSAndroid Build Coastguard Worker     int msg_length = 2 + rand() % 1000;
261*598139dcSAndroid Build Coastguard Worker     for (int i = 0; i < msg_length; ++i) {
262*598139dcSAndroid Build Coastguard Worker         message.push_back('a' + rand() % 26);
263*598139dcSAndroid Build Coastguard Worker     }
264*598139dcSAndroid Build Coastguard Worker     message.push_back('\0');
265*598139dcSAndroid Build Coastguard Worker 
266*598139dcSAndroid Build Coastguard Worker     entry.len = message.size();
267*598139dcSAndroid Build Coastguard Worker 
268*598139dcSAndroid Build Coastguard Worker     return {entry, message};
269*598139dcSAndroid Build Coastguard Worker }
270*598139dcSAndroid Build Coastguard Worker 
GenerateRandomLogMessages(size_t count)271*598139dcSAndroid Build Coastguard Worker std::vector<LogMessage> GenerateRandomLogMessages(size_t count) {
272*598139dcSAndroid Build Coastguard Worker     srand(1);
273*598139dcSAndroid Build Coastguard Worker     std::vector<LogMessage> log_messages;
274*598139dcSAndroid Build Coastguard Worker     for (size_t i = 0; i < count; ++i) {
275*598139dcSAndroid Build Coastguard Worker         log_messages.emplace_back(GenerateRandomLogMessage(i));
276*598139dcSAndroid Build Coastguard Worker     }
277*598139dcSAndroid Build Coastguard Worker     return log_messages;
278*598139dcSAndroid Build Coastguard Worker }
279*598139dcSAndroid Build Coastguard Worker 
TEST_P(LogBufferTest,random_messages)280*598139dcSAndroid Build Coastguard Worker TEST_P(LogBufferTest, random_messages) {
281*598139dcSAndroid Build Coastguard Worker     auto log_messages = GenerateRandomLogMessages(1000);
282*598139dcSAndroid Build Coastguard Worker     LogMessages(log_messages);
283*598139dcSAndroid Build Coastguard Worker 
284*598139dcSAndroid Build Coastguard Worker     auto read_log_messages = ReadLogMessagesNonBlockingThread({});
285*598139dcSAndroid Build Coastguard Worker     CompareLogMessages(log_messages, read_log_messages);
286*598139dcSAndroid Build Coastguard Worker }
287*598139dcSAndroid Build Coastguard Worker 
TEST_P(LogBufferTest,read_last_sequence)288*598139dcSAndroid Build Coastguard Worker TEST_P(LogBufferTest, read_last_sequence) {
289*598139dcSAndroid Build Coastguard Worker     std::vector<LogMessage> log_messages = {
290*598139dcSAndroid Build Coastguard Worker             {{.pid = 1, .tid = 2, .sec = 10000, .nsec = 20001, .lid = LOG_ID_MAIN, .uid = 0},
291*598139dcSAndroid Build Coastguard Worker              "first"},
292*598139dcSAndroid Build Coastguard Worker             {{.pid = 10, .tid = 2, .sec = 10000, .nsec = 20002, .lid = LOG_ID_MAIN, .uid = 0},
293*598139dcSAndroid Build Coastguard Worker              "second"},
294*598139dcSAndroid Build Coastguard Worker             {{.pid = 100, .tid = 2, .sec = 10000, .nsec = 20003, .lid = LOG_ID_MAIN, .uid = 0},
295*598139dcSAndroid Build Coastguard Worker              "third"},
296*598139dcSAndroid Build Coastguard Worker     };
297*598139dcSAndroid Build Coastguard Worker     FixupMessages(&log_messages);
298*598139dcSAndroid Build Coastguard Worker     LogMessages(log_messages);
299*598139dcSAndroid Build Coastguard Worker 
300*598139dcSAndroid Build Coastguard Worker     std::vector<LogMessage> expected_log_messages = {log_messages.back()};
301*598139dcSAndroid Build Coastguard Worker     auto read_log_messages = ReadLogMessagesNonBlockingThread({.sequence = 3});
302*598139dcSAndroid Build Coastguard Worker     CompareLogMessages(expected_log_messages, read_log_messages);
303*598139dcSAndroid Build Coastguard Worker }
304*598139dcSAndroid Build Coastguard Worker 
TEST_P(LogBufferTest,clear_logs)305*598139dcSAndroid Build Coastguard Worker TEST_P(LogBufferTest, clear_logs) {
306*598139dcSAndroid Build Coastguard Worker     // Log 3 initial logs.
307*598139dcSAndroid Build Coastguard Worker     std::vector<LogMessage> log_messages = {
308*598139dcSAndroid Build Coastguard Worker             {{.pid = 1, .tid = 2, .sec = 10000, .nsec = 20001, .lid = LOG_ID_MAIN, .uid = 0},
309*598139dcSAndroid Build Coastguard Worker              "first"},
310*598139dcSAndroid Build Coastguard Worker             {{.pid = 10, .tid = 2, .sec = 10000, .nsec = 20002, .lid = LOG_ID_MAIN, .uid = 0},
311*598139dcSAndroid Build Coastguard Worker              "second"},
312*598139dcSAndroid Build Coastguard Worker             {{.pid = 100, .tid = 2, .sec = 10000, .nsec = 20003, .lid = LOG_ID_MAIN, .uid = 0},
313*598139dcSAndroid Build Coastguard Worker              "third"},
314*598139dcSAndroid Build Coastguard Worker     };
315*598139dcSAndroid Build Coastguard Worker     FixupMessages(&log_messages);
316*598139dcSAndroid Build Coastguard Worker     LogMessages(log_messages);
317*598139dcSAndroid Build Coastguard Worker 
318*598139dcSAndroid Build Coastguard Worker     // Connect a blocking reader.
319*598139dcSAndroid Build Coastguard Worker     auto blocking_reader = TestReaderThread({.non_block = false}, *this);
320*598139dcSAndroid Build Coastguard Worker 
321*598139dcSAndroid Build Coastguard Worker     // Wait up to 250ms for the reader to read the first 3 logs.
322*598139dcSAndroid Build Coastguard Worker     constexpr int kMaxRetryCount = 50;
323*598139dcSAndroid Build Coastguard Worker     int count = 0;
324*598139dcSAndroid Build Coastguard Worker     for (; count < kMaxRetryCount; ++count) {
325*598139dcSAndroid Build Coastguard Worker         usleep(5000);
326*598139dcSAndroid Build Coastguard Worker         auto lock = std::lock_guard{logd_lock};
327*598139dcSAndroid Build Coastguard Worker         if (reader_list_.running_reader_threads().back()->start() == 4) {
328*598139dcSAndroid Build Coastguard Worker             break;
329*598139dcSAndroid Build Coastguard Worker         }
330*598139dcSAndroid Build Coastguard Worker     }
331*598139dcSAndroid Build Coastguard Worker     ASSERT_LT(count, kMaxRetryCount);
332*598139dcSAndroid Build Coastguard Worker 
333*598139dcSAndroid Build Coastguard Worker     // Clear the log buffer.
334*598139dcSAndroid Build Coastguard Worker     log_buffer_->Clear(LOG_ID_MAIN, 0);
335*598139dcSAndroid Build Coastguard Worker 
336*598139dcSAndroid Build Coastguard Worker     // Log 3 more logs.
337*598139dcSAndroid Build Coastguard Worker     std::vector<LogMessage> after_clear_messages = {
338*598139dcSAndroid Build Coastguard Worker             {{.pid = 1, .tid = 2, .sec = 10000, .nsec = 20001, .lid = LOG_ID_MAIN, .uid = 0},
339*598139dcSAndroid Build Coastguard Worker              "4th"},
340*598139dcSAndroid Build Coastguard Worker             {{.pid = 10, .tid = 2, .sec = 10000, .nsec = 20002, .lid = LOG_ID_MAIN, .uid = 0},
341*598139dcSAndroid Build Coastguard Worker              "5th"},
342*598139dcSAndroid Build Coastguard Worker             {{.pid = 100, .tid = 2, .sec = 10000, .nsec = 20003, .lid = LOG_ID_MAIN, .uid = 0},
343*598139dcSAndroid Build Coastguard Worker              "6th"},
344*598139dcSAndroid Build Coastguard Worker     };
345*598139dcSAndroid Build Coastguard Worker     FixupMessages(&after_clear_messages);
346*598139dcSAndroid Build Coastguard Worker     LogMessages(after_clear_messages);
347*598139dcSAndroid Build Coastguard Worker 
348*598139dcSAndroid Build Coastguard Worker     // Wait up to 250ms for the reader to read the 3 additional logs.
349*598139dcSAndroid Build Coastguard Worker     for (count = 0; count < kMaxRetryCount; ++count) {
350*598139dcSAndroid Build Coastguard Worker         usleep(5000);
351*598139dcSAndroid Build Coastguard Worker         auto lock = std::lock_guard{logd_lock};
352*598139dcSAndroid Build Coastguard Worker         if (reader_list_.running_reader_threads().back()->start() == 7) {
353*598139dcSAndroid Build Coastguard Worker             break;
354*598139dcSAndroid Build Coastguard Worker         }
355*598139dcSAndroid Build Coastguard Worker     }
356*598139dcSAndroid Build Coastguard Worker     ASSERT_LT(count, kMaxRetryCount);
357*598139dcSAndroid Build Coastguard Worker 
358*598139dcSAndroid Build Coastguard Worker     ReleaseAndJoinReaders();
359*598139dcSAndroid Build Coastguard Worker 
360*598139dcSAndroid Build Coastguard Worker     // Check that we have read all 6 messages.
361*598139dcSAndroid Build Coastguard Worker     std::vector<LogMessage> expected_log_messages = log_messages;
362*598139dcSAndroid Build Coastguard Worker     expected_log_messages.insert(expected_log_messages.end(), after_clear_messages.begin(),
363*598139dcSAndroid Build Coastguard Worker                                  after_clear_messages.end());
364*598139dcSAndroid Build Coastguard Worker     CompareLogMessages(expected_log_messages, blocking_reader.read_log_messages());
365*598139dcSAndroid Build Coastguard Worker 
366*598139dcSAndroid Build Coastguard Worker     // Finally, Flush messages and ensure that only the 3 logs after the clear remain in the buffer.
367*598139dcSAndroid Build Coastguard Worker     auto flush_after_clear_result = FlushMessages();
368*598139dcSAndroid Build Coastguard Worker     EXPECT_EQ(7ULL, flush_after_clear_result.next_sequence);
369*598139dcSAndroid Build Coastguard Worker     CompareLogMessages(after_clear_messages, flush_after_clear_result.messages);
370*598139dcSAndroid Build Coastguard Worker }
371*598139dcSAndroid Build Coastguard Worker 
TEST_P(LogBufferTest,tail100_nonblocking_1000total)372*598139dcSAndroid Build Coastguard Worker TEST_P(LogBufferTest, tail100_nonblocking_1000total) {
373*598139dcSAndroid Build Coastguard Worker     auto log_messages = GenerateRandomLogMessages(1000);
374*598139dcSAndroid Build Coastguard Worker     LogMessages(log_messages);
375*598139dcSAndroid Build Coastguard Worker 
376*598139dcSAndroid Build Coastguard Worker     constexpr int kTailCount = 100;
377*598139dcSAndroid Build Coastguard Worker     std::vector<LogMessage> expected_log_messages{log_messages.end() - kTailCount,
378*598139dcSAndroid Build Coastguard Worker                                                   log_messages.end()};
379*598139dcSAndroid Build Coastguard Worker     auto read_log_messages = ReadLogMessagesNonBlockingThread({.tail = kTailCount});
380*598139dcSAndroid Build Coastguard Worker     CompareLogMessages(expected_log_messages, read_log_messages);
381*598139dcSAndroid Build Coastguard Worker }
382*598139dcSAndroid Build Coastguard Worker 
TEST_P(LogBufferTest,tail100_blocking_1000total_then1000more)383*598139dcSAndroid Build Coastguard Worker TEST_P(LogBufferTest, tail100_blocking_1000total_then1000more) {
384*598139dcSAndroid Build Coastguard Worker     auto log_messages = GenerateRandomLogMessages(1000);
385*598139dcSAndroid Build Coastguard Worker     LogMessages(log_messages);
386*598139dcSAndroid Build Coastguard Worker 
387*598139dcSAndroid Build Coastguard Worker     constexpr int kTailCount = 100;
388*598139dcSAndroid Build Coastguard Worker     auto blocking_reader = TestReaderThread({.non_block = false, .tail = kTailCount}, *this);
389*598139dcSAndroid Build Coastguard Worker 
390*598139dcSAndroid Build Coastguard Worker     std::vector<LogMessage> expected_log_messages{log_messages.end() - kTailCount,
391*598139dcSAndroid Build Coastguard Worker                                                   log_messages.end()};
392*598139dcSAndroid Build Coastguard Worker 
393*598139dcSAndroid Build Coastguard Worker     std::vector<LogMessage> actual = blocking_reader.WaitForMessages(expected_log_messages.size());
394*598139dcSAndroid Build Coastguard Worker     CompareLogMessages(expected_log_messages, actual);
395*598139dcSAndroid Build Coastguard Worker 
396*598139dcSAndroid Build Coastguard Worker     // Log more messages
397*598139dcSAndroid Build Coastguard Worker     log_messages = GenerateRandomLogMessages(1000);
398*598139dcSAndroid Build Coastguard Worker     LogMessages(log_messages);
399*598139dcSAndroid Build Coastguard Worker     expected_log_messages.insert(expected_log_messages.end(), log_messages.begin(),
400*598139dcSAndroid Build Coastguard Worker                                  log_messages.end());
401*598139dcSAndroid Build Coastguard Worker 
402*598139dcSAndroid Build Coastguard Worker     // Wait for the reader to have read the new messages.
403*598139dcSAndroid Build Coastguard Worker     actual = blocking_reader.WaitForMessages(expected_log_messages.size());
404*598139dcSAndroid Build Coastguard Worker     CompareLogMessages(expected_log_messages, actual);
405*598139dcSAndroid Build Coastguard Worker 
406*598139dcSAndroid Build Coastguard Worker     ReleaseAndJoinReaders();
407*598139dcSAndroid Build Coastguard Worker 
408*598139dcSAndroid Build Coastguard Worker     // Final check that no extraneous logs were logged.
409*598139dcSAndroid Build Coastguard Worker     CompareLogMessages(expected_log_messages, blocking_reader.read_log_messages());
410*598139dcSAndroid Build Coastguard Worker }
411*598139dcSAndroid Build Coastguard Worker 
TEST_P(LogBufferTest,tail100_nonblocking_50total)412*598139dcSAndroid Build Coastguard Worker TEST_P(LogBufferTest, tail100_nonblocking_50total) {
413*598139dcSAndroid Build Coastguard Worker     auto log_messages = GenerateRandomLogMessages(50);
414*598139dcSAndroid Build Coastguard Worker     LogMessages(log_messages);
415*598139dcSAndroid Build Coastguard Worker 
416*598139dcSAndroid Build Coastguard Worker     constexpr int kTailCount = 100;
417*598139dcSAndroid Build Coastguard Worker     auto read_log_messages = ReadLogMessagesNonBlockingThread({.tail = kTailCount});
418*598139dcSAndroid Build Coastguard Worker     CompareLogMessages(log_messages, read_log_messages);
419*598139dcSAndroid Build Coastguard Worker }
420*598139dcSAndroid Build Coastguard Worker 
TEST_P(LogBufferTest,tail100_blocking_50total_then1000more)421*598139dcSAndroid Build Coastguard Worker TEST_P(LogBufferTest, tail100_blocking_50total_then1000more) {
422*598139dcSAndroid Build Coastguard Worker     auto log_messages = GenerateRandomLogMessages(50);
423*598139dcSAndroid Build Coastguard Worker     LogMessages(log_messages);
424*598139dcSAndroid Build Coastguard Worker 
425*598139dcSAndroid Build Coastguard Worker     constexpr int kTailCount = 100;
426*598139dcSAndroid Build Coastguard Worker     auto blocking_reader = TestReaderThread({.non_block = false, .tail = kTailCount}, *this);
427*598139dcSAndroid Build Coastguard Worker 
428*598139dcSAndroid Build Coastguard Worker     std::vector<LogMessage> expected_log_messages = log_messages;
429*598139dcSAndroid Build Coastguard Worker 
430*598139dcSAndroid Build Coastguard Worker     // Wait for the reader to have read the messages.
431*598139dcSAndroid Build Coastguard Worker     std::vector<LogMessage> actual = blocking_reader.WaitForMessages(expected_log_messages.size());
432*598139dcSAndroid Build Coastguard Worker     CompareLogMessages(expected_log_messages, actual);
433*598139dcSAndroid Build Coastguard Worker 
434*598139dcSAndroid Build Coastguard Worker     // Log more messages
435*598139dcSAndroid Build Coastguard Worker     log_messages = GenerateRandomLogMessages(1000);
436*598139dcSAndroid Build Coastguard Worker     LogMessages(log_messages);
437*598139dcSAndroid Build Coastguard Worker     expected_log_messages.insert(expected_log_messages.end(), log_messages.begin(),
438*598139dcSAndroid Build Coastguard Worker                                  log_messages.end());
439*598139dcSAndroid Build Coastguard Worker 
440*598139dcSAndroid Build Coastguard Worker     // Wait for the reader to have read the new messages.
441*598139dcSAndroid Build Coastguard Worker     actual = blocking_reader.WaitForMessages(expected_log_messages.size());
442*598139dcSAndroid Build Coastguard Worker     CompareLogMessages(expected_log_messages, actual);
443*598139dcSAndroid Build Coastguard Worker 
444*598139dcSAndroid Build Coastguard Worker     ReleaseAndJoinReaders();
445*598139dcSAndroid Build Coastguard Worker 
446*598139dcSAndroid Build Coastguard Worker     // Final check that no extraneous logs were logged.
447*598139dcSAndroid Build Coastguard Worker     CompareLogMessages(expected_log_messages, blocking_reader.read_log_messages());
448*598139dcSAndroid Build Coastguard Worker }
449*598139dcSAndroid Build Coastguard Worker 
450*598139dcSAndroid Build Coastguard Worker INSTANTIATE_TEST_CASE_P(LogBufferTests, LogBufferTest, testing::Values("serialized", "simple"));
451