Add another FindLogs method for finding logs
This takes a vector of strings, which is a lot easier to create.
Change-Id: I8d42496d0eb1779a6b524396791ef1278537eda9
Signed-off-by: Austin Schuh <austin.schuh@bluerivertech.com>
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/events/logging/log_reader_utils_test.cc b/aos/events/logging/log_reader_utils_test.cc
index 9cd64f2..ff2484e 100644
--- a/aos/events/logging/log_reader_utils_test.cc
+++ b/aos/events/logging/log_reader_utils_test.cc
@@ -157,4 +157,75 @@
EXPECT_EQ(logs.front().name, log_file);
}
+// Tests that FindLogs returns reasonable results.
+TEST(LogfileSorting, FindLogs) {
+ std::string log_folder = aos::testing::TestTmpDir() + "/log_folder";
+ util::UnlinkRecursive(log_folder);
+ std::filesystem::create_directories(log_folder);
+
+ std::filesystem::create_directories(log_folder + "/log1/a");
+ std::ofstream(log_folder + "/log1/a/part1.bfbs").good();
+ std::ofstream(log_folder + "/log1/a/part2.bfbs").good();
+ std::ofstream(log_folder + "/log1/a/randomfile").good();
+ std::filesystem::create_directories(log_folder + "/log1/b");
+ std::ofstream(log_folder + "/log1/b/part1.bfbs").good();
+ std::ofstream(log_folder + "/log1/b/randomfile").good();
+ std::filesystem::create_directories(log_folder + "/log1/c");
+ std::ofstream(log_folder + "/log1/c/part1.bfbs").good();
+ std::ofstream(log_folder + "/log1/c/part2.bfbs").good();
+ std::ofstream(log_folder + "/log1/c/part3.bfbs").good();
+
+ std::filesystem::create_directories(log_folder + "/log2/a");
+ std::ofstream(log_folder + "/log2/a/part1.bfbs").good();
+ std::ofstream(log_folder + "/log2/a/part2.bfbs").good();
+ std::ofstream(log_folder + "/log2/a/part3.bfbs").good();
+ std::ofstream(log_folder + "/log2/a/randomfile").good();
+
+ std::filesystem::create_directories(log_folder + "/log3/b");
+ std::ofstream(log_folder + "/log3/b/part1.bfbs").good();
+ std::filesystem::create_directories(log_folder + "/log3/c");
+ std::ofstream(log_folder + "/log3/c/part1.bfbs").good();
+ std::ofstream(log_folder + "/log3/c/part2.bfbs").good();
+ std::ofstream(log_folder + "/log3/c/part3.bfbs").good();
+
+ auto empty_file_with_name = [](std::string_view name) {
+ return ::testing::AllOf(
+ ::testing::Field(&internal::FileOperations::File::name, name),
+ ::testing::Field(&internal::FileOperations::File::size, 0u));
+ };
+
+ {
+ std::vector<internal::FileOperations::File> result = FindLogs(
+ std::vector<std::string>{log_folder + "/log1", log_folder + "/log3"});
+
+ EXPECT_EQ(result.size(), 10);
+ }
+
+ {
+ std::vector<internal::FileOperations::File> result =
+ FindLogs(std::vector<std::string>{log_folder + "/log1"});
+
+ EXPECT_THAT(result,
+ ::testing::UnorderedElementsAre(
+ empty_file_with_name(log_folder + "/log1/a/part1.bfbs"),
+ empty_file_with_name(log_folder + "/log1/a/part2.bfbs"),
+ empty_file_with_name(log_folder + "/log1/b/part1.bfbs"),
+ empty_file_with_name(log_folder + "/log1/c/part1.bfbs"),
+ empty_file_with_name(log_folder + "/log1/c/part2.bfbs"),
+ empty_file_with_name(log_folder + "/log1/c/part3.bfbs")));
+ }
+
+ {
+ std::vector<internal::FileOperations::File> result =
+ FindLogs(std::vector<std::string>{log_folder + "/log3"});
+
+ EXPECT_THAT(result,
+ ::testing::UnorderedElementsAre(
+ empty_file_with_name(log_folder + "/log3/b/part1.bfbs"),
+ empty_file_with_name(log_folder + "/log3/c/part1.bfbs"),
+ empty_file_with_name(log_folder + "/log3/c/part2.bfbs"),
+ empty_file_with_name(log_folder + "/log3/c/part3.bfbs")));
+ }
+}
+
} // namespace aos::logger::testing
diff --git a/aos/events/logging/logfile_sorting.cc b/aos/events/logging/logfile_sorting.cc
index 4c859c2..fdb4eab 100644
--- a/aos/events/logging/logfile_sorting.cc
+++ b/aos/events/logging/logfile_sorting.cc
@@ -126,17 +126,35 @@
return files;
}
+namespace {
+
+void AddLogfiles(std::string_view filename,
+ std::vector<internal::FileOperations::File> *found_logfiles) {
+ const auto file_operations = MakeFileOperations(filename);
+ if (file_operations->Exists()) {
+ file_operations->FindLogs(found_logfiles);
+ } else {
+ LOG(FATAL) << "File " << filename << " does not exist";
+ }
+}
+
+}; // namespace
+
std::vector<internal::FileOperations::File> FindLogs(int argc, char **argv) {
std::vector<internal::FileOperations::File> found_logfiles;
for (int i = 1; i < argc; i++) {
- std::string filename = argv[i];
- const auto file_operations = MakeFileOperations(filename);
- if (file_operations->Exists()) {
- file_operations->FindLogs(&found_logfiles);
- } else {
- LOG(FATAL) << "File " << filename << " does not exist";
- }
+ AddLogfiles(argv[i], &found_logfiles);
+ }
+ return found_logfiles;
+}
+
+std::vector<internal::FileOperations::File> FindLogs(
+ const std::vector<std::string> &paths) {
+ std::vector<internal::FileOperations::File> found_logfiles;
+
+ for (const std::string &filename : paths) {
+ AddLogfiles(filename, &found_logfiles);
}
return found_logfiles;
}
diff --git a/aos/events/logging/logfile_sorting.h b/aos/events/logging/logfile_sorting.h
index 4f2a2e2..52f44e5 100644
--- a/aos/events/logging/logfile_sorting.h
+++ b/aos/events/logging/logfile_sorting.h
@@ -167,6 +167,8 @@
// Recursively searches for logfiles in argv[1] and onward.
std::vector<internal::FileOperations::File> FindLogs(int argc, char **argv);
+std::vector<internal::FileOperations::File> FindLogs(
+ const std::vector<std::string> &paths);
// Proxy container to bind log parts with log source. It helps with reading logs
// from virtual media such as memory or S3.