Make testable sandbox/mmajewski2/testing
authorMateusz Majewski <m.majewski2@samsung.com>
Tue, 26 Sep 2023 06:15:21 +0000 (08:15 +0200)
committerMateusz Majewski <m.majewski2@samsung.com>
Tue, 26 Sep 2023 06:55:33 +0000 (08:55 +0200)
CMakeLists.txt
packaging/initrd.spec
src/parse-dynparts/CMakeLists.txt
src/parse-dynparts/lib.cpp [new file with mode: 0644]
src/parse-dynparts/lib.hpp [new file with mode: 0644]
src/parse-dynparts/main.cpp
src/parse-dynparts/test.cpp [new file with mode: 0644]

index f792260142845534c2a488ac37b0239092d2c6fd..4918e47ac716a4fa7fe33ff215e32899b9b4c204 100644 (file)
@@ -5,6 +5,9 @@ CONFIGURE_FILE(data/initrd-file-dmverity.list.in
                data/initrd-file-dmverity.list
                @ONLY)
 
+find_package(GTest REQUIRED)
+enable_testing()
+
 # reboot
 SET(REBOOT_BINARY_NAME "reboot")
 SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall -fPIE")
index a109ed61bf2d2263764cd80b7ccf0cb961b35274..eea33a5f6368b2dfd04c96de5d1748b1ccb365b0 100644 (file)
@@ -13,6 +13,7 @@ Source1:        ramdisk-flush.service
 
 BuildRequires:  cmake
 BuildRequires:  pkgconfig(openssl3)
+BuildRequires:  gtest-devel
 
 Requires(posttrans): bash
 Requires(posttrans): grep
@@ -67,6 +68,9 @@ cp %{SOURCE1001} .
                -DINSTALL_DIR=%{_sbindir}
 make %{_smp_mflags}
 
+%check
+ctest -V %{?_smp_mflags}
+
 %install
 %make_install
 
index c6ffccfb81c45d35740adbac06ff7d44ed3dc5ed..bedf1e9e30012432164de51c452b9c86cf303763 100644 (file)
@@ -3,8 +3,14 @@ set(CMAKE_CXX_STANDARD_REQUIRED True)
 
 add_subdirectory(liblp)
 
-add_executable(parse-dynparts main.cpp)
+add_executable(parse-dynparts main.cpp lib.cpp)
 target_compile_options(parse-dynparts PRIVATE -Wall -Wextra -pedantic -fPIE)
-
 target_link_libraries(parse-dynparts PRIVATE lp)
-INSTALL(TARGETS parse-dynparts DESTINATION ${INSTALL_DIR})
\ No newline at end of file
+install(TARGETS parse-dynparts DESTINATION ${INSTALL_DIR})
+
+add_executable(parse-dynparts-test test.cpp lib.cpp)
+target_compile_options(parse-dynparts-test PRIVATE -Wall -Wextra -pedantic -fPIE)
+target_link_libraries(parse-dynparts-test PRIVATE GTest::gtest_main lp)
+
+include(GoogleTest)
+gtest_discover_tests(parse-dynparts-test)
diff --git a/src/parse-dynparts/lib.cpp b/src/parse-dynparts/lib.cpp
new file mode 100644 (file)
index 0000000..a5b1303
--- /dev/null
@@ -0,0 +1,67 @@
+#include "lib.hpp"
+
+#include <iostream>
+#include <sstream>
+#include <string_view>
+
+using namespace android::fs_mgr;
+using std::endl;
+
+std::optional<std::string> go(const android::fs_mgr::LpMetadata &metadata, bool list_tables, std::string_view prog_name, std::ostream &messages) {
+  std::string table;
+
+  // Code structure taken from Android's system/core/fs_mgr/fs_mgr_dm_linear.cpp
+  for (auto partition : metadata.partitions) {
+    if (!partition.num_extents) {
+      messages << "Skipping zero-length logical partition: "
+               << GetPartitionName(partition) << endl;
+      continue;
+    }
+    if (partition.attributes & LP_PARTITION_ATTR_DISABLED) {
+      messages << "Skipping disabled partition: " << GetPartitionName(partition)
+               << endl;
+      continue;
+    }
+
+    std::ostringstream line;
+
+    if(list_tables)
+      line << GetPartitionName(partition) << " ";
+    else {
+      bool read_only = partition.attributes & LP_PARTITION_ATTR_READONLY;
+      line << GetPartitionName(partition) << ",,," << (read_only ? "ro," : "rw,");
+    }
+
+    uint64_t sector = 0;
+    for (size_t i = 0; i < partition.num_extents; i++) {
+      const auto& extent = metadata.extents[partition.first_extent_index + i];
+      switch (extent.target_type) {
+        case LP_TARGET_TYPE_ZERO:
+          line << sector << " " << extent.num_sectors << " zero";
+          break;
+        case LP_TARGET_TYPE_LINEAR: {
+          if (extent.target_source != 0) {
+            messages << "This utility does not yet support multiple block devices"
+                     << endl;
+            return std::nullopt;
+          }
+
+          line << sector << " " << extent.num_sectors << " linear "
+               << prog_name << " " << extent.target_data;
+          break;
+        }
+        default:
+          messages << "Unknown target type in metadata: " << extent.target_type
+                << endl;
+          return std::nullopt;
+      }
+      sector += extent.num_sectors;
+    }
+
+    if (!table.empty() && list_tables) table += "\n";
+    if (!table.empty() && !list_tables) table += ";";
+    table += line.str();
+  }
+
+  return table;
+}
diff --git a/src/parse-dynparts/lib.hpp b/src/parse-dynparts/lib.hpp
new file mode 100644 (file)
index 0000000..50cd80b
--- /dev/null
@@ -0,0 +1,6 @@
+#pragma once
+
+#include <optional>
+#include <liblp/liblp.h>
+
+std::optional<std::string> go(const android::fs_mgr::LpMetadata &metadata, bool list_tables, std::string_view prog_name, std::ostream &messages);
index 022821a8ed712bf745074d118c8dcaaf6a481da8..def68316c598c5e248d97130a44703ad66219ae6 100644 (file)
@@ -4,6 +4,8 @@
 #include <sstream>
 #include <string_view>
 
+#include "lib.hpp"
+
 using namespace android::fs_mgr;
 
 using std::cerr;
@@ -27,62 +29,11 @@ int main(int argc, char* argv[]) {
     return 1;
   }
 
-  std::string table;
-
-  // Code structure taken from Android's system/core/fs_mgr/fs_mgr_dm_linear.cpp
-  for (auto partition : metadata->partitions) {
-    if (!partition.num_extents) {
-      cerr << "Skipping zero-length logical partition: "
-           << GetPartitionName(partition) << endl;
-      continue;
-    }
-    if (partition.attributes & LP_PARTITION_ATTR_DISABLED) {
-      cerr << "Skipping disabled partition: " << GetPartitionName(partition)
-           << endl;
-      continue;
-    }
-
-    std::ostringstream line;
-
-    if(list_tables)
-      line << GetPartitionName(partition) << " ";
-    else {
-      bool read_only = partition.attributes & LP_PARTITION_ATTR_READONLY;
-      line << GetPartitionName(partition) << ",,," << (read_only ? "ro," : "rw,");
-    }
-
-    uint64_t sector = 0;
-    for (size_t i = 0; i < partition.num_extents; i++) {
-      const auto& extent = metadata->extents[partition.first_extent_index + i];
-      switch (extent.target_type) {
-        case LP_TARGET_TYPE_ZERO:
-          line << sector << " " << extent.num_sectors << " zero";
-          break;
-        case LP_TARGET_TYPE_LINEAR: {
-          if (extent.target_source != 0) {
-            cerr << "This utility does not yet support multiple block devices"
-                 << endl;
-            return 1;
-          }
-
-          line << sector << " " << extent.num_sectors << " linear "
-               << argv[1] << " " << extent.target_data;
-          break;
-        }
-        default:
-          cerr << "Unknown target type in metadata: " << extent.target_type
-               << endl;
-          return false;
-      }
-      sector += extent.num_sectors;
-    }
-
-    if (!table.empty() && list_tables) table += "\n";
-    if (!table.empty() && !list_tables) table += ";";
-    table += line.str();
-  }
-
-  cout << table << endl;
+  auto out = go(*metadata, list_tables, argv[1], cerr);
+  if (out)
+    cout << *out << "\n";
+  else
+    return 1;
 
   return 0;
 }
diff --git a/src/parse-dynparts/test.cpp b/src/parse-dynparts/test.cpp
new file mode 100644 (file)
index 0000000..26526b7
--- /dev/null
@@ -0,0 +1,12 @@
+#include <gtest/gtest.h>
+
+#include "lib.hpp"
+
+using namespace android::fs_mgr;
+
+TEST(ParseDynpartsTest, Example) {
+    LpMetadata metadata {};
+    std::ostringstream messages;
+    EXPECT_EQ(go(metadata, true, "test", messages), "");
+    EXPECT_EQ(messages.str(), "");
+}