Gentle introduction of log backend

The goal is to be able to write short logs to the pre-allocated
memory. To do that, we want to decouple file operations from logs
behind light abstraction.

There are a couple of TODO added. I hope to fix them with next iteration
where actual memory log backend will be implemented.

Change-Id: I65e80825b1e080375efc54f35b270df1ceb17a0d
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
diff --git a/aos/events/logging/log_backend_test.cc b/aos/events/logging/log_backend_test.cc
new file mode 100644
index 0000000..452592f
--- /dev/null
+++ b/aos/events/logging/log_backend_test.cc
@@ -0,0 +1,87 @@
+#include "aos/events/logging/log_backend.h"
+
+#include <filesystem>
+
+#include "aos/testing/tmpdir.h"
+#include "gtest/gtest.h"
+
+namespace aos::logger::testing {
+TEST(LogBackendTest, CreateSimpleFile) {
+  const std::string logevent = aos::testing::TestTmpDir() + "/logevent/";
+  FileBackend backend(logevent);
+  auto file = backend.RequestFile("test.log");
+  ASSERT_EQ(file->OpenForWrite(), WriteCode::kOk);
+  auto result = write(file->fd(), "test", 4);
+  EXPECT_GT(result, 0);
+  EXPECT_EQ(file->Close(), WriteCode::kOk);
+  EXPECT_TRUE(std::filesystem::exists(logevent + "test.log"));
+}
+
+TEST(LogBackendTest, CreateRenamableFile) {
+  const std::string logevent = aos::testing::TestTmpDir() + "/logevent/";
+  RenamableFileBackend backend(logevent);
+  auto file = backend.RequestFile("test.log");
+  ASSERT_EQ(file->OpenForWrite(), WriteCode::kOk);
+  auto result = write(file->fd(), "testtest", 8);
+  EXPECT_GT(result, 0);
+  EXPECT_EQ(file->Close(), WriteCode::kOk);
+  EXPECT_TRUE(std::filesystem::exists(logevent + "test.log"));
+}
+
+TEST(LogBackendTest, UseTempRenamableFile) {
+  const std::string logevent = aos::testing::TestTmpDir() + "/logevent/";
+  RenamableFileBackend backend(logevent);
+  backend.EnableTempFiles();
+  auto file = backend.RequestFile("test.log");
+  ASSERT_EQ(file->OpenForWrite(), WriteCode::kOk);
+  auto result = write(file->fd(), "testtest", 8);
+  EXPECT_GT(result, 0);
+  EXPECT_TRUE(std::filesystem::exists(logevent + "test.log.tmp"));
+
+  EXPECT_EQ(file->Close(), WriteCode::kOk);
+  // Check that file is renamed.
+  EXPECT_TRUE(std::filesystem::exists(logevent + "test.log"));
+}
+
+TEST(LogBackendTest, RenameBaseAfterWrite) {
+  const std::string logevent = aos::testing::TestTmpDir() + "/logevent/";
+  RenamableFileBackend backend(logevent);
+  auto file = backend.RequestFile("test.log");
+  ASSERT_EQ(file->OpenForWrite(), WriteCode::kOk);
+  auto result = write(file->fd(), "testtest", 8);
+  EXPECT_GT(result, 0);
+  EXPECT_TRUE(std::filesystem::exists(logevent + "test.log"));
+
+  std::string renamed = aos::testing::TestTmpDir() + "/renamed/";
+  backend.RenameLogBase(renamed);
+
+  EXPECT_FALSE(std::filesystem::exists(logevent + "test.log"));
+  EXPECT_TRUE(std::filesystem::exists(renamed + "test.log"));
+
+  EXPECT_EQ(file->Close(), WriteCode::kOk);
+  // Check that file is renamed.
+  EXPECT_TRUE(std::filesystem::exists(renamed + "test.log"));
+}
+
+TEST(LogBackendTest, UseTestAndRenameBaseAfterWrite) {
+  const std::string logevent = aos::testing::TestTmpDir() + "/logevent/";
+  RenamableFileBackend backend(logevent);
+  backend.EnableTempFiles();
+  auto file = backend.RequestFile("test.log");
+  ASSERT_EQ(file->OpenForWrite(), WriteCode::kOk);
+  auto result = write(file->fd(), "testtest", 8);
+  EXPECT_GT(result, 0);
+  EXPECT_TRUE(std::filesystem::exists(logevent + "test.log.tmp"));
+
+  std::string renamed = aos::testing::TestTmpDir() + "/renamed/";
+  backend.RenameLogBase(renamed);
+
+  EXPECT_FALSE(std::filesystem::exists(logevent + "test.log.tmp"));
+  EXPECT_TRUE(std::filesystem::exists(renamed + "test.log.tmp"));
+
+  EXPECT_EQ(file->Close(), WriteCode::kOk);
+  // Check that file is renamed.
+  EXPECT_TRUE(std::filesystem::exists(renamed + "test.log"));
+}
+
+}  // namespace aos::logger::testing
\ No newline at end of file