Teach PartsMessageReader to verify out of order

We want to know when a log file doesn't meet our requirements.
PartsMessageReader is a reasonable spot since it knows a lot about log
files.

Add a test while we are here, and also make it so we get max_time back
for the newest timestamp when the log file finishes to make it easy to
read until X happens.

Change-Id: I934f0dffedf023e10596de558dedc79bdc289ff2
diff --git a/aos/events/logging/logfile_utils_test.cc b/aos/events/logging/logfile_utils_test.cc
index 57d1d9d..3644419 100644
--- a/aos/events/logging/logfile_utils_test.cc
+++ b/aos/events/logging/logfile_utils_test.cc
@@ -91,6 +91,47 @@
   EXPECT_FALSE(reader.ReadMessage());
 }
 
+// Tests that we explode when messages are too far out of order.
+TEST(PartsMessageReaderDeathTest, TooFarOutOfOrder) {
+  const std::string logfile0 = aos::testing::TestTmpDir() + "/log0.bfbs";
+  unlink(logfile0.c_str());
+
+  const aos::SizePrefixedFlatbufferDetachedBuffer<LogFileHeader> config0 =
+      JsonToSizedFlatbuffer<LogFileHeader>(
+          R"({
+  "max_out_of_order_duration": 100000000,
+  "log_event_uuid": "30ef1283-81d7-4004-8c36-1c162dbcb2b2",
+  "parts_uuid": "2a05d725-5d5c-4c0b-af42-88de2f3c3876",
+  "parts_index": 0
+})");
+
+  const aos::SizePrefixedFlatbufferDetachedBuffer<MessageHeader> m1 =
+      JsonToSizedFlatbuffer<MessageHeader>(
+          R"({ "channel_index": 0, "monotonic_sent_time": 100000000 })");
+  const aos::SizePrefixedFlatbufferDetachedBuffer<MessageHeader> m2 =
+      JsonToSizedFlatbuffer<MessageHeader>(
+          R"({ "channel_index": 0, "monotonic_sent_time": 0 })");
+  const aos::SizePrefixedFlatbufferDetachedBuffer<MessageHeader> m3 =
+      JsonToSizedFlatbuffer<MessageHeader>(
+          R"({ "channel_index": 0, "monotonic_sent_time": -1 })");
+
+  {
+    DetachedBufferWriter writer(logfile0, std::make_unique<DummyEncoder>());
+    writer.QueueSpan(config0.full_span());
+    writer.QueueSpan(m1.full_span());
+    writer.QueueSpan(m2.full_span());
+    writer.QueueSpan(m3.full_span());
+  }
+
+  const std::vector<LogFile> parts = SortParts({logfile0});
+
+  PartsMessageReader reader(parts[0].parts[0]);
+
+  EXPECT_TRUE(reader.ReadMessage());
+  EXPECT_TRUE(reader.ReadMessage());
+  EXPECT_DEATH({ reader.ReadMessage(); }, "-0.000000001sec vs. 0.000000000sec");
+}
+
 // Tests that we can transparently re-assemble part files with a
 // PartsMessageReader.
 TEST(PartsMessageReaderTest, ReadWrite) {
@@ -171,7 +212,9 @@
   EXPECT_EQ(
       reader.max_out_of_order_duration(),
       std::chrono::nanoseconds(config1.message().max_out_of_order_duration()));
+  EXPECT_EQ(reader.newest_timestamp(), monotonic_clock::max_time);
 }
+
 }  // namespace testing
 }  // namespace logger
 }  // namespace aos