Added basic span reader test.

Might as well right better tests when writing sorting v2.  Backfilling
is needed here before we can build up further.

Change-Id: Ibe805cb031eba3eac4bb3d65dfa318c52e6487e2
diff --git a/aos/events/logging/BUILD b/aos/events/logging/BUILD
index 6a85728..b7f3b5a 100644
--- a/aos/events/logging/BUILD
+++ b/aos/events/logging/BUILD
@@ -303,6 +303,7 @@
         "//aos/events:pong_lib",
         "//aos/events:simulated_event_loop",
         "//aos/testing:googletest",
+        "//aos/testing:tmpdir",
     ],
 )
 
@@ -320,3 +321,20 @@
         "//aos/testing:googletest",
     ],
 )
+
+cc_test(
+    name = "logfile_utils_test",
+    srcs = ["logfile_utils_test.cc"],
+    deps = [
+        ":logfile_utils",
+        ":test_message_fbs",
+        "//aos/testing:googletest",
+        "//aos/testing:tmpdir",
+    ],
+)
+
+flatbuffer_cc_library(
+    name = "test_message_fbs",
+    srcs = ["test_message.fbs"],
+    gen_reflections = 1,
+)
diff --git a/aos/events/logging/logfile_utils.cc b/aos/events/logging/logfile_utils.cc
index 8eec23e..58e7c30 100644
--- a/aos/events/logging/logfile_utils.cc
+++ b/aos/events/logging/logfile_utils.cc
@@ -320,23 +320,6 @@
   return absl::Span<const uint8_t>(data_ptr, data_size);
 }
 
-bool SpanReader::MessageAvailable() {
-  // Are we big enough to read the size?
-  if (data_.size() - consumed_data_ < sizeof(flatbuffers::uoffset_t)) {
-    return false;
-  }
-
-  // Then, are we big enough to read the full message?
-  const size_t data_size =
-      flatbuffers::GetPrefixedSize(data_.data() + consumed_data_) +
-      sizeof(flatbuffers::uoffset_t);
-  if (data_.size() < consumed_data_ + data_size) {
-    return false;
-  }
-
-  return true;
-}
-
 bool SpanReader::ReadBlock() {
   // This is the amount of data we grab at a time. Doing larger chunks minimizes
   // syscalls and helps decompressors batch things more efficiently.
diff --git a/aos/events/logging/logfile_utils.h b/aos/events/logging/logfile_utils.h
index fddda72..60bd39c 100644
--- a/aos/events/logging/logfile_utils.h
+++ b/aos/events/logging/logfile_utils.h
@@ -195,10 +195,6 @@
   // the size.
   absl::Span<const uint8_t> ReadMessage();
 
-  // Returns true if there is a full message available in the buffer, or if we
-  // will have to read more data from disk.
-  bool MessageAvailable();
-
  private:
   // TODO(austin): Optimization:
   //   Allocate the 256k blocks like we do today.  But, refcount them with
diff --git a/aos/events/logging/logfile_utils_test.cc b/aos/events/logging/logfile_utils_test.cc
new file mode 100644
index 0000000..fec3186
--- /dev/null
+++ b/aos/events/logging/logfile_utils_test.cc
@@ -0,0 +1,49 @@
+#include "aos/events/logging/logfile_utils.h"
+
+#include "gtest/gtest.h"
+
+#include "aos/events/logging/test_message_generated.h"
+#include "aos/json_to_flatbuffer.h"
+#include "aos/testing/tmpdir.h"
+
+namespace aos {
+namespace logger {
+namespace testing {
+
+template <typename T>
+SizePrefixedFlatbufferDetachedBuffer<T> JsonToSizedFlatbuffer(
+    const std::string_view data) {
+  flatbuffers::FlatBufferBuilder fbb;
+  fbb.ForceDefaults(true);
+  fbb.FinishSizePrefixed(JsonToFlatbuffer<T>(data, &fbb));
+  return fbb.Release();
+}
+
+TEST(SpanReaderTest, ReadWrite) {
+  const std::string logfile = aos::testing::TestTmpDir() + "/log.bfbs";
+  unlink(logfile.c_str());
+
+  const aos::SizePrefixedFlatbufferDetachedBuffer<TestMessage> m1 =
+      JsonToSizedFlatbuffer<TestMessage>(
+          R"({ "value": 1 })");
+  const aos::SizePrefixedFlatbufferDetachedBuffer<TestMessage> m2 =
+      JsonToSizedFlatbuffer<TestMessage>(
+          R"({ "value": 2 })");
+
+  {
+    DetachedBufferWriter writer(logfile, std::make_unique<DummyEncoder>());
+    writer.QueueSpan(m1.full_span());
+    writer.QueueSpan(m2.full_span());
+  }
+
+  SpanReader reader(logfile);
+
+  EXPECT_EQ(reader.filename(), logfile);
+  EXPECT_EQ(reader.ReadMessage(), m1.full_span());
+  EXPECT_EQ(reader.ReadMessage(), m2.full_span());
+  EXPECT_EQ(reader.ReadMessage(), absl::Span<const uint8_t>());
+}
+
+}  // namespace testing
+}  // namespace logger
+}  // namespace aos
diff --git a/aos/events/logging/logger_test.cc b/aos/events/logging/logger_test.cc
index 51994e3..1affce9 100644
--- a/aos/events/logging/logger_test.cc
+++ b/aos/events/logging/logger_test.cc
@@ -6,6 +6,7 @@
 #include "aos/events/pong_lib.h"
 #include "aos/events/simulated_event_loop.h"
 #include "aos/network/timestamp_generated.h"
+#include "aos/testing/tmpdir.h"
 #include "aos/util/file.h"
 #include "glog/logging.h"
 #include "gmock/gmock.h"
@@ -47,7 +48,7 @@
 // Tests that we can startup at all.  This confirms that the channels are all in
 // the config.
 TEST_F(LoggerTest, Starts) {
-  const ::std::string tmpdir(getenv("TEST_TMPDIR"));
+  const ::std::string tmpdir = aos::testing::TestTmpDir();
   const ::std::string base_name = tmpdir + "/logfile";
   const ::std::string logfile = base_name + ".part0.bfbs";
   // Remove it.
diff --git a/aos/events/logging/test_message.fbs b/aos/events/logging/test_message.fbs
new file mode 100644
index 0000000..ef876aa
--- /dev/null
+++ b/aos/events/logging/test_message.fbs
@@ -0,0 +1,7 @@
+namespace aos.logger.testing;
+
+table TestMessage {
+  value:int;
+}
+
+root_type TestMessage;
diff --git a/aos/testing/BUILD b/aos/testing/BUILD
index ce67b84..e70b5a4 100644
--- a/aos/testing/BUILD
+++ b/aos/testing/BUILD
@@ -86,3 +86,11 @@
     ],
     visibility = ["//visibility:public"],
 )
+
+cc_library(
+    name = "tmpdir",
+    testonly = True,
+    srcs = ["tmpdir.cc"],
+    hdrs = ["tmpdir.h"],
+    visibility = ["//visibility:public"],
+)
diff --git a/aos/testing/tmpdir.cc b/aos/testing/tmpdir.cc
new file mode 100644
index 0000000..15e3c13
--- /dev/null
+++ b/aos/testing/tmpdir.cc
@@ -0,0 +1,18 @@
+#include "aos/testing/tmpdir.h"
+
+#include <cstdlib>
+#include <string>
+
+namespace aos {
+namespace testing {
+
+std::string TestTmpDir() {
+  const char *tmp_dir = std::getenv("TEST_TMPDIR");
+  if (tmp_dir != nullptr) {
+    return tmp_dir;
+  }
+  return "/tmp";
+}
+
+}  // namespace testing
+}  // namespace aos
diff --git a/aos/testing/tmpdir.h b/aos/testing/tmpdir.h
new file mode 100644
index 0000000..7e64342
--- /dev/null
+++ b/aos/testing/tmpdir.h
@@ -0,0 +1,15 @@
+#ifndef AOS_TESTING_TMPDIR_H_
+#define AOS_TESTING_TMPDIR_H_
+
+#include <string>
+
+namespace aos {
+namespace testing {
+
+// Returns a usable temporary directory.
+std::string TestTmpDir();
+
+}  // namespace testing
+}  // namespace aos
+
+#endif  // AOS_TESTING_TMPDIR_H_