blob: 3a969d47e8a2a5bf9dabd656a31072e5360152da [file] [log] [blame]
James Kuszmaul38735e82019-12-07 16:42:06 -08001#include "aos/events/logging/logger.h"
Austin Schuhe309d2a2019-11-29 13:25:21 -08002
3#include "aos/events/event_loop.h"
4#include "aos/events/ping_lib.h"
5#include "aos/events/pong_lib.h"
6#include "aos/events/simulated_event_loop.h"
7#include "glog/logging.h"
Austin Schuh6f3babe2020-01-26 20:34:50 -08008#include "gmock/gmock.h"
Austin Schuhe309d2a2019-11-29 13:25:21 -08009#include "gtest/gtest.h"
10
11namespace aos {
12namespace logger {
13namespace testing {
14
15namespace chrono = std::chrono;
16
17class LoggerTest : public ::testing::Test {
18 public:
19 LoggerTest()
20 : config_(
21 aos::configuration::ReadConfig("aos/events/pingpong_config.json")),
22 event_loop_factory_(&config_.message()),
Austin Schuh5f1cc5c2019-12-01 18:01:11 -080023 ping_event_loop_(event_loop_factory_.MakeEventLoop("ping")),
Austin Schuhe309d2a2019-11-29 13:25:21 -080024 ping_(ping_event_loop_.get()),
Austin Schuh5f1cc5c2019-12-01 18:01:11 -080025 pong_event_loop_(event_loop_factory_.MakeEventLoop("pong")),
Austin Schuhe309d2a2019-11-29 13:25:21 -080026 pong_(pong_event_loop_.get()) {}
27
28 // Config and factory.
29 aos::FlatbufferDetachedBuffer<aos::Configuration> config_;
30 SimulatedEventLoopFactory event_loop_factory_;
31
32 // Event loop and app for Ping
33 std::unique_ptr<EventLoop> ping_event_loop_;
34 Ping ping_;
35
36 // Event loop and app for Pong
37 std::unique_ptr<EventLoop> pong_event_loop_;
38 Pong pong_;
39};
40
41// Tests that we can startup at all. This confirms that the channels are all in
42// the config.
43TEST_F(LoggerTest, Starts) {
44 const ::std::string tmpdir(getenv("TEST_TMPDIR"));
45 const ::std::string logfile = tmpdir + "/logfile.bfbs";
46 // Remove it.
47 unlink(logfile.c_str());
48
49 LOG(INFO) << "Logging data to " << logfile;
50
51 {
52 DetachedBufferWriter writer(logfile);
53 std::unique_ptr<EventLoop> logger_event_loop =
Austin Schuh5f1cc5c2019-12-01 18:01:11 -080054 event_loop_factory_.MakeEventLoop("logger");
Austin Schuhe309d2a2019-11-29 13:25:21 -080055
56 event_loop_factory_.RunFor(chrono::milliseconds(95));
57
58 Logger logger(&writer, logger_event_loop.get(),
59 std::chrono::milliseconds(100));
60 event_loop_factory_.RunFor(chrono::milliseconds(20000));
61 }
62
James Kuszmaulc7bbb3e2020-01-03 20:01:00 -080063 // Even though it doesn't make any difference here, exercise the logic for
64 // passing in a separate config.
65 LogReader reader(logfile, &config_.message());
Austin Schuhe309d2a2019-11-29 13:25:21 -080066
James Kuszmaulc7bbb3e2020-01-03 20:01:00 -080067 // Confirm that we can remap logged channels to point to new buses.
68 reader.RemapLoggedChannel<aos::examples::Ping>("/test", "/original");
Austin Schuhe309d2a2019-11-29 13:25:21 -080069
Austin Schuh15649d62019-12-28 16:36:38 -080070 // This sends out the fetched messages and advances time to the start of the
71 // log file.
James Kuszmaul84ff3e52020-01-03 19:48:53 -080072 reader.Register();
Austin Schuhe309d2a2019-11-29 13:25:21 -080073
Austin Schuh6f3babe2020-01-26 20:34:50 -080074 EXPECT_THAT(reader.Nodes(), ::testing::ElementsAre(nullptr));
James Kuszmaul84ff3e52020-01-03 19:48:53 -080075
Austin Schuhe309d2a2019-11-29 13:25:21 -080076 std::unique_ptr<EventLoop> test_event_loop =
James Kuszmaul84ff3e52020-01-03 19:48:53 -080077 reader.event_loop_factory()->MakeEventLoop("log_reader");
Austin Schuhe309d2a2019-11-29 13:25:21 -080078
79 int ping_count = 10;
80 int pong_count = 10;
81
James Kuszmaulc7bbb3e2020-01-03 20:01:00 -080082 // Confirm that the ping value matches in the remapped channel location.
83 test_event_loop->MakeWatcher("/original/test",
Austin Schuhe309d2a2019-11-29 13:25:21 -080084 [&ping_count](const examples::Ping &ping) {
85 EXPECT_EQ(ping.value(), ping_count + 1);
86 ++ping_count;
87 });
88 // Confirm that the ping and pong counts both match, and the value also
89 // matches.
90 test_event_loop->MakeWatcher(
91 "/test", [&pong_count, &ping_count](const examples::Pong &pong) {
92 EXPECT_EQ(pong.value(), pong_count + 1);
93 ++pong_count;
94 EXPECT_EQ(ping_count, pong_count);
95 });
96
James Kuszmaul84ff3e52020-01-03 19:48:53 -080097 reader.event_loop_factory()->RunFor(std::chrono::seconds(100));
Austin Schuhe309d2a2019-11-29 13:25:21 -080098 EXPECT_EQ(ping_count, 2010);
Austin Schuhe309d2a2019-11-29 13:25:21 -080099}
100
Austin Schuhfa895892020-01-07 20:07:41 -0800101// Tests that we can read and write rotated log files.
102TEST_F(LoggerTest, RotatedLogFile) {
103 const ::std::string tmpdir(getenv("TEST_TMPDIR"));
104 const ::std::string logfile0 = tmpdir + "/logfile0.bfbs";
105 const ::std::string logfile1 = tmpdir + "/logfile1.bfbs";
106 // Remove it.
107 unlink(logfile0.c_str());
108 unlink(logfile1.c_str());
109
110 LOG(INFO) << "Logging data to " << logfile0 << " and " << logfile1;
111
112 {
113 DetachedBufferWriter writer0(logfile0);
114 DetachedBufferWriter writer1(logfile1);
115 std::unique_ptr<EventLoop> logger_event_loop =
116 event_loop_factory_.MakeEventLoop("logger");
117
118 event_loop_factory_.RunFor(chrono::milliseconds(95));
119
120 Logger logger(&writer0, logger_event_loop.get(),
121 std::chrono::milliseconds(100));
122 event_loop_factory_.RunFor(chrono::milliseconds(10000));
123 logger.Rotate(&writer1);
124 event_loop_factory_.RunFor(chrono::milliseconds(10000));
125 }
126
127 // Even though it doesn't make any difference here, exercise the logic for
128 // passing in a separate config.
129 LogReader reader(std::vector<std::string>{logfile0, logfile1},
130 &config_.message());
131
132 // Confirm that we can remap logged channels to point to new buses.
133 reader.RemapLoggedChannel<aos::examples::Ping>("/test", "/original");
134
135 // This sends out the fetched messages and advances time to the start of the
136 // log file.
137 reader.Register();
138
Austin Schuh6f3babe2020-01-26 20:34:50 -0800139 EXPECT_THAT(reader.Nodes(), ::testing::ElementsAre(nullptr));
Austin Schuhfa895892020-01-07 20:07:41 -0800140
141 std::unique_ptr<EventLoop> test_event_loop =
142 reader.event_loop_factory()->MakeEventLoop("log_reader");
143
144 int ping_count = 10;
145 int pong_count = 10;
146
147 // Confirm that the ping value matches in the remapped channel location.
148 test_event_loop->MakeWatcher("/original/test",
149 [&ping_count](const examples::Ping &ping) {
150 EXPECT_EQ(ping.value(), ping_count + 1);
151 ++ping_count;
152 });
153 // Confirm that the ping and pong counts both match, and the value also
154 // matches.
155 test_event_loop->MakeWatcher(
156 "/test", [&pong_count, &ping_count](const examples::Pong &pong) {
157 EXPECT_EQ(pong.value(), pong_count + 1);
158 ++pong_count;
159 EXPECT_EQ(ping_count, pong_count);
160 });
161
162 reader.event_loop_factory()->RunFor(std::chrono::seconds(100));
163 EXPECT_EQ(ping_count, 2010);
164}
165
Austin Schuh4c4e0092019-12-22 16:18:03 -0800166// Tests that a large number of messages per second doesn't overwhelm writev.
167TEST_F(LoggerTest, ManyMessages) {
168 const ::std::string tmpdir(getenv("TEST_TMPDIR"));
169 const ::std::string logfile = tmpdir + "/logfile.bfbs";
170 // Remove the log file.
171 unlink(logfile.c_str());
172
173 LOG(INFO) << "Logging data to " << logfile;
174
175 {
176 DetachedBufferWriter writer(logfile);
177 std::unique_ptr<EventLoop> logger_event_loop =
178 event_loop_factory_.MakeEventLoop("logger");
179
180 std::unique_ptr<EventLoop> ping_spammer_event_loop =
181 event_loop_factory_.MakeEventLoop("ping_spammer");
182 aos::Sender<examples::Ping> ping_sender =
183 ping_spammer_event_loop->MakeSender<examples::Ping>("/test");
184
185 aos::TimerHandler *timer_handler =
186 ping_spammer_event_loop->AddTimer([&ping_sender]() {
187 aos::Sender<examples::Ping>::Builder builder =
188 ping_sender.MakeBuilder();
189 examples::Ping::Builder ping_builder =
190 builder.MakeBuilder<examples::Ping>();
191 CHECK(builder.Send(ping_builder.Finish()));
192 });
193
194 // 100 ms / 0.05 ms -> 2000 messages. Should be enough to crash it.
195 ping_spammer_event_loop->OnRun([&ping_spammer_event_loop, timer_handler]() {
196 timer_handler->Setup(ping_spammer_event_loop->monotonic_now(),
197 chrono::microseconds(50));
198 });
199
200 Logger logger(&writer, logger_event_loop.get(),
201 std::chrono::milliseconds(100));
202
203 event_loop_factory_.RunFor(chrono::milliseconds(1000));
204 }
205}
206
Austin Schuh15649d62019-12-28 16:36:38 -0800207class MultinodeLoggerTest : public ::testing::Test {
208 public:
209 MultinodeLoggerTest()
210 : config_(aos::configuration::ReadConfig(
Austin Schuhe84c3ed2019-12-14 15:29:48 -0800211 "aos/events/logging/multinode_pingpong_config.json")),
Austin Schuhac0771c2020-01-07 18:36:30 -0800212 event_loop_factory_(&config_.message()),
213 ping_event_loop_(event_loop_factory_.MakeEventLoop(
214 "ping", configuration::GetNode(event_loop_factory_.configuration(),
215 "pi1"))),
Austin Schuh6f3babe2020-01-26 20:34:50 -0800216 ping_(ping_event_loop_.get()),
217 pong_event_loop_(event_loop_factory_.MakeEventLoop(
218 "pong", configuration::GetNode(event_loop_factory_.configuration(),
219 "pi2"))),
220 pong_(pong_event_loop_.get()) {}
Austin Schuh15649d62019-12-28 16:36:38 -0800221
222 // Config and factory.
223 aos::FlatbufferDetachedBuffer<aos::Configuration> config_;
224 SimulatedEventLoopFactory event_loop_factory_;
225
226 // Event loop and app for Ping
227 std::unique_ptr<EventLoop> ping_event_loop_;
228 Ping ping_;
Austin Schuh6f3babe2020-01-26 20:34:50 -0800229
230 // Event loop and app for Pong
231 std::unique_ptr<EventLoop> pong_event_loop_;
232 Pong pong_;
Austin Schuh15649d62019-12-28 16:36:38 -0800233};
234
Austin Schuh6f3babe2020-01-26 20:34:50 -0800235// Counts the number of messages on a channel (returns channel, count) for every
236// message matching matcher()
237std::vector<std::pair<int, int>> CountChannelsMatching(
238 std::string_view filename,
239 std::function<bool(const MessageHeader *)> matcher) {
240 MessageReader message_reader(filename);
241 std::vector<int> counts(
242 message_reader.log_file_header()->configuration()->channels()->size(), 0);
Austin Schuh15649d62019-12-28 16:36:38 -0800243
Austin Schuh6f3babe2020-01-26 20:34:50 -0800244 while (true) {
245 std::optional<FlatbufferVector<MessageHeader>> msg =
246 message_reader.ReadMessage();
247 if (!msg) {
248 break;
249 }
250
251 if (matcher(&msg.value().message())) {
252 counts[msg.value().message().channel_index()]++;
253 }
254 }
255
256 std::vector<std::pair<int, int>> result;
257 int channel = 0;
258 for (size_t i = 0; i < counts.size(); ++i) {
259 if (counts[i] != 0) {
260 result.push_back(std::make_pair(channel, counts[i]));
261 }
262 ++channel;
263 }
264
265 return result;
266}
267
268// Counts the number of messages (channel, count) for all data messages.
269std::vector<std::pair<int, int>> CountChannelsData(std::string_view filename) {
270 return CountChannelsMatching(filename, [](const MessageHeader *msg) {
271 if (msg->has_data()) {
272 CHECK(!msg->has_monotonic_remote_time());
273 CHECK(!msg->has_realtime_remote_time());
274 CHECK(!msg->has_remote_queue_index());
275 return true;
276 }
277 return false;
278 });
279}
280
281// Counts the number of messages (channel, count) for all timestamp messages.
282std::vector<std::pair<int, int>> CountChannelsTimestamp(
283 std::string_view filename) {
284 return CountChannelsMatching(filename, [](const MessageHeader *msg) {
285 if (!msg->has_data()) {
286 CHECK(msg->has_monotonic_remote_time());
287 CHECK(msg->has_realtime_remote_time());
288 CHECK(msg->has_remote_queue_index());
289 return true;
290 }
291 return false;
292 });
293}
294
295// Tests that we can write and read multi-node log files correctly.
296TEST_F(MultinodeLoggerTest, MultiNode) {
297 const ::std::string tmpdir(getenv("TEST_TMPDIR"));
298 const ::std::string logfile_base = tmpdir + "/multi_logfile";
299 const ::std::string logfile1 = logfile_base + "_pi1_data.bfbs";
300 const ::std::string logfile2 =
301 logfile_base + "_pi2_data/test/aos.examples.Pong.bfbs";
302 const ::std::string logfile3 = logfile_base + "_pi2_data.bfbs";
303
304 // Remove them.
305 unlink(logfile1.c_str());
306 unlink(logfile2.c_str());
307 unlink(logfile3.c_str());
308
309 LOG(INFO) << "Logging data to " << logfile1 << ", " << logfile2 << " and "
310 << logfile3;
Austin Schuh15649d62019-12-28 16:36:38 -0800311
312 {
Austin Schuhac0771c2020-01-07 18:36:30 -0800313 const Node *pi1 =
314 configuration::GetNode(event_loop_factory_.configuration(), "pi1");
Austin Schuh6f3babe2020-01-26 20:34:50 -0800315 const Node *pi2 =
316 configuration::GetNode(event_loop_factory_.configuration(), "pi2");
Austin Schuh15649d62019-12-28 16:36:38 -0800317
Austin Schuh6f3babe2020-01-26 20:34:50 -0800318 std::unique_ptr<EventLoop> pi1_logger_event_loop =
Austin Schuhac0771c2020-01-07 18:36:30 -0800319 event_loop_factory_.MakeEventLoop("logger", pi1);
Austin Schuh6f3babe2020-01-26 20:34:50 -0800320 std::unique_ptr<LogNamer> pi1_log_namer =
321 std::make_unique<MultiNodeLogNamer>(
322 logfile_base, pi1_logger_event_loop->configuration(),
323 pi1_logger_event_loop->node());
324
325 std::unique_ptr<EventLoop> pi2_logger_event_loop =
326 event_loop_factory_.MakeEventLoop("logger", pi2);
327 std::unique_ptr<LogNamer> pi2_log_namer =
328 std::make_unique<MultiNodeLogNamer>(
329 logfile_base, pi2_logger_event_loop->configuration(),
330 pi2_logger_event_loop->node());
Austin Schuh15649d62019-12-28 16:36:38 -0800331
332 event_loop_factory_.RunFor(chrono::milliseconds(95));
333
Austin Schuh6f3babe2020-01-26 20:34:50 -0800334 Logger pi1_logger(std::move(pi1_log_namer), pi1_logger_event_loop.get(),
335 std::chrono::milliseconds(100));
336 Logger pi2_logger(std::move(pi2_log_namer), pi2_logger_event_loop.get(),
337 std::chrono::milliseconds(100));
Austin Schuh15649d62019-12-28 16:36:38 -0800338 event_loop_factory_.RunFor(chrono::milliseconds(20000));
339 }
340
Austin Schuh6f3babe2020-01-26 20:34:50 -0800341 {
342 // Confirm that the headers are all for the correct nodes.
343 FlatbufferVector<LogFileHeader> logheader1 = ReadHeader(logfile1);
344 EXPECT_EQ(logheader1.message().node()->name()->string_view(), "pi1");
345 FlatbufferVector<LogFileHeader> logheader2 = ReadHeader(logfile2);
346 EXPECT_EQ(logheader2.message().node()->name()->string_view(), "pi2");
347 FlatbufferVector<LogFileHeader> logheader3 = ReadHeader(logfile3);
348 EXPECT_EQ(logheader3.message().node()->name()->string_view(), "pi2");
Austin Schuh15649d62019-12-28 16:36:38 -0800349
Austin Schuh6f3babe2020-01-26 20:34:50 -0800350 // Timing reports, pings
351 EXPECT_THAT(CountChannelsData(logfile1),
352 ::testing::ElementsAre(::testing::Pair(1, 60),
353 ::testing::Pair(4, 2001)));
354 // Timestamps for pong
355 EXPECT_THAT(CountChannelsTimestamp(logfile1),
356 ::testing::ElementsAre(::testing::Pair(5, 2001)));
357
358 // Pong data.
359 EXPECT_THAT(CountChannelsData(logfile2),
360 ::testing::ElementsAre(::testing::Pair(5, 2001)));
361 // No timestamps
362 EXPECT_THAT(CountChannelsTimestamp(logfile2), ::testing::ElementsAre());
363
364 // Timing reports and pongs.
365 EXPECT_THAT(CountChannelsData(logfile3),
366 ::testing::ElementsAre(::testing::Pair(3, 60),
367 ::testing::Pair(5, 2001)));
368 // And ping timestamps.
369 EXPECT_THAT(CountChannelsTimestamp(logfile3),
370 ::testing::ElementsAre(::testing::Pair(4, 2001)));
371 }
372
373 LogReader reader({std::vector<std::string>{logfile1},
374 std::vector<std::string>{logfile2},
375 std::vector<std::string>{logfile3}});
376
Austin Schuhac0771c2020-01-07 18:36:30 -0800377 SimulatedEventLoopFactory log_reader_factory(reader.logged_configuration());
Austin Schuh6331ef92020-01-07 18:28:09 -0800378 log_reader_factory.set_send_delay(chrono::microseconds(0));
Austin Schuh15649d62019-12-28 16:36:38 -0800379
380 // This sends out the fetched messages and advances time to the start of the
381 // log file.
Austin Schuh6331ef92020-01-07 18:28:09 -0800382 reader.Register(&log_reader_factory);
James Kuszmaul84ff3e52020-01-03 19:48:53 -0800383
Austin Schuhac0771c2020-01-07 18:36:30 -0800384 const Node *pi1 =
385 configuration::GetNode(log_reader_factory.configuration(), "pi1");
Austin Schuh6f3babe2020-01-26 20:34:50 -0800386 const Node *pi2 =
387 configuration::GetNode(log_reader_factory.configuration(), "pi2");
Austin Schuhac0771c2020-01-07 18:36:30 -0800388
Austin Schuh6f3babe2020-01-26 20:34:50 -0800389 EXPECT_THAT(reader.Nodes(), ::testing::ElementsAre(pi1, pi2));
James Kuszmaul84ff3e52020-01-03 19:48:53 -0800390
391 reader.event_loop_factory()->set_send_delay(chrono::microseconds(0));
Austin Schuh15649d62019-12-28 16:36:38 -0800392
Austin Schuh6f3babe2020-01-26 20:34:50 -0800393 std::unique_ptr<EventLoop> pi1_event_loop =
Austin Schuhac0771c2020-01-07 18:36:30 -0800394 log_reader_factory.MakeEventLoop("test", pi1);
Austin Schuh6f3babe2020-01-26 20:34:50 -0800395 std::unique_ptr<EventLoop> pi2_event_loop =
396 log_reader_factory.MakeEventLoop("test", pi2);
Austin Schuh15649d62019-12-28 16:36:38 -0800397
Austin Schuh6f3babe2020-01-26 20:34:50 -0800398 int pi1_ping_count = 10;
399 int pi2_ping_count = 10;
400 int pi1_pong_count = 10;
401 int pi2_pong_count = 10;
Austin Schuh15649d62019-12-28 16:36:38 -0800402
403 // Confirm that the ping value matches.
Austin Schuh6f3babe2020-01-26 20:34:50 -0800404 pi1_event_loop->MakeWatcher(
405 "/test", [&pi1_ping_count, &pi1_event_loop](const examples::Ping &ping) {
406 VLOG(1) << "Pi1 ping " << FlatbufferToJson(&ping)
407 << pi1_event_loop->context().monotonic_remote_time << " -> "
408 << pi1_event_loop->context().monotonic_event_time;
409 EXPECT_EQ(ping.value(), pi1_ping_count + 1);
410 EXPECT_EQ(pi1_event_loop->context().monotonic_remote_time,
411 pi1_ping_count * chrono::milliseconds(10) +
412 monotonic_clock::epoch());
413 EXPECT_EQ(pi1_event_loop->context().realtime_remote_time,
414 pi1_ping_count * chrono::milliseconds(10) +
415 realtime_clock::epoch());
416 EXPECT_EQ(pi1_event_loop->context().monotonic_remote_time,
417 pi1_event_loop->context().monotonic_event_time);
418 EXPECT_EQ(pi1_event_loop->context().realtime_remote_time,
419 pi1_event_loop->context().realtime_event_time);
Austin Schuh15649d62019-12-28 16:36:38 -0800420
Austin Schuh6f3babe2020-01-26 20:34:50 -0800421 ++pi1_ping_count;
422 });
423 pi2_event_loop->MakeWatcher(
424 "/test", [&pi2_ping_count, &pi2_event_loop](const examples::Ping &ping) {
425 VLOG(1) << "Pi2 ping " << FlatbufferToJson(&ping)
426 << pi2_event_loop->context().monotonic_remote_time << " -> "
427 << pi2_event_loop->context().monotonic_event_time;
428 EXPECT_EQ(ping.value(), pi2_ping_count + 1);
429
430 EXPECT_EQ(pi2_event_loop->context().monotonic_remote_time,
431 pi2_ping_count * chrono::milliseconds(10) +
432 monotonic_clock::epoch());
433 EXPECT_EQ(pi2_event_loop->context().realtime_remote_time,
434 pi2_ping_count * chrono::milliseconds(10) +
435 realtime_clock::epoch());
436 EXPECT_EQ(pi2_event_loop->context().monotonic_remote_time +
437 chrono::microseconds(150),
438 pi2_event_loop->context().monotonic_event_time);
439 EXPECT_EQ(pi2_event_loop->context().realtime_remote_time +
440 chrono::microseconds(150),
441 pi2_event_loop->context().realtime_event_time);
442 ++pi2_ping_count;
Austin Schuh15649d62019-12-28 16:36:38 -0800443 });
444
Austin Schuh6f3babe2020-01-26 20:34:50 -0800445 constexpr ssize_t kQueueIndexOffset = 0;
446 // Confirm that the ping and pong counts both match, and the value also
447 // matches.
448 pi1_event_loop->MakeWatcher(
449 "/test", [&pi1_event_loop, &pi1_ping_count,
450 &pi1_pong_count](const examples::Pong &pong) {
451 VLOG(1) << "Pi1 pong " << FlatbufferToJson(&pong) << " at "
452 << pi1_event_loop->context().monotonic_remote_time << " -> "
453 << pi1_event_loop->context().monotonic_event_time;
454
455 EXPECT_EQ(pi1_event_loop->context().remote_queue_index,
456 pi1_pong_count + kQueueIndexOffset);
457 EXPECT_EQ(pi1_event_loop->context().monotonic_remote_time,
458 chrono::microseconds(200) +
459 pi1_pong_count * chrono::milliseconds(10) +
460 monotonic_clock::epoch());
461 EXPECT_EQ(pi1_event_loop->context().realtime_remote_time,
462 chrono::microseconds(200) +
463 pi1_pong_count * chrono::milliseconds(10) +
464 realtime_clock::epoch());
465
466 EXPECT_EQ(pi1_event_loop->context().monotonic_remote_time +
467 chrono::microseconds(150),
468 pi1_event_loop->context().monotonic_event_time);
469 EXPECT_EQ(pi1_event_loop->context().realtime_remote_time +
470 chrono::microseconds(150),
471 pi1_event_loop->context().realtime_event_time);
472
473 EXPECT_EQ(pong.value(), pi1_pong_count + 1);
474 ++pi1_pong_count;
475 EXPECT_EQ(pi1_ping_count, pi1_pong_count);
476 });
477 pi2_event_loop->MakeWatcher(
478 "/test", [&pi2_event_loop, &pi2_ping_count,
479 &pi2_pong_count](const examples::Pong &pong) {
480 VLOG(1) << "Pi2 pong " << FlatbufferToJson(&pong) << " at "
481 << pi2_event_loop->context().monotonic_remote_time << " -> "
482 << pi2_event_loop->context().monotonic_event_time;
483
484 EXPECT_EQ(pi2_event_loop->context().remote_queue_index,
485 pi2_pong_count + kQueueIndexOffset - 9);
486
487 EXPECT_EQ(pi2_event_loop->context().monotonic_remote_time,
488 chrono::microseconds(200) +
489 pi2_pong_count * chrono::milliseconds(10) +
490 monotonic_clock::epoch());
491 EXPECT_EQ(pi2_event_loop->context().realtime_remote_time,
492 chrono::microseconds(200) +
493 pi2_pong_count * chrono::milliseconds(10) +
494 realtime_clock::epoch());
495
496 EXPECT_EQ(pi2_event_loop->context().monotonic_remote_time,
497 pi2_event_loop->context().monotonic_event_time);
498 EXPECT_EQ(pi2_event_loop->context().realtime_remote_time,
499 pi2_event_loop->context().realtime_event_time);
500
501 EXPECT_EQ(pong.value(), pi2_pong_count + 1);
502 ++pi2_pong_count;
503 EXPECT_EQ(pi2_ping_count, pi2_pong_count);
504 });
505
506 log_reader_factory.Run();
507 EXPECT_EQ(pi1_ping_count, 2010);
508 EXPECT_EQ(pi2_ping_count, 2010);
509 EXPECT_EQ(pi1_pong_count, 2010);
510 EXPECT_EQ(pi2_pong_count, 2010);
Austin Schuh6331ef92020-01-07 18:28:09 -0800511
512 reader.Deregister();
Austin Schuh15649d62019-12-28 16:36:38 -0800513}
514
Austin Schuh6f3babe2020-01-26 20:34:50 -0800515// TODO(austin): We can write a test which recreates a logfile and confirms that
516// we get it back. That is the ultimate test.
517
Austin Schuhe309d2a2019-11-29 13:25:21 -0800518} // namespace testing
519} // namespace logger
520} // namespace aos