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")
BuildRequires: cmake
BuildRequires: pkgconfig(openssl3)
+BuildRequires: gtest-devel
Requires(posttrans): bash
Requires(posttrans): grep
-DINSTALL_DIR=%{_sbindir}
make %{_smp_mflags}
+%check
+ctest -V %{?_smp_mflags}
+
%install
%make_install
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)
--- /dev/null
+#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;
+}
--- /dev/null
+#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);
#include <sstream>
#include <string_view>
+#include "lib.hpp"
+
using namespace android::fs_mgr;
using std::cerr;
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;
}
--- /dev/null
+#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(), "");
+}