fastboot: Add a test for super_flash_helper.
This test checks that the sparsing logic matches a canonical sample
output.
Bug: N/A
Test: fastboot_test
Change-Id: Ic7bad08a79e4223f8352db2397b741c2179e76bb
diff --git a/fastboot/Android.bp b/fastboot/Android.bp
index 6d50fa4..76aaf7b 100644
--- a/fastboot/Android.bp
+++ b/fastboot/Android.bp
@@ -378,6 +378,7 @@
"fastboot_test.cpp",
"socket_mock.cpp",
"socket_test.cpp",
+ "super_flash_helper_test.cpp",
"tcp_test.cpp",
"udp_test.cpp",
],
@@ -395,6 +396,12 @@
},
test_suites: ["general-tests"],
+
+ data: [
+ "testdata/super.img",
+ "testdata/super_empty.img",
+ "testdata/system.img",
+ ],
}
cc_test_host {
diff --git a/fastboot/fastboot_test.cpp b/fastboot/fastboot_test.cpp
index 9c3ab6e..79f37fd 100644
--- a/fastboot/fastboot_test.cpp
+++ b/fastboot/fastboot_test.cpp
@@ -16,6 +16,7 @@
#include "fastboot.h"
+#include <android-base/logging.h>
#include <gtest/gtest.h>
TEST(FastBoot, ParseOsPatchLevel) {
@@ -201,3 +202,11 @@
// No spaces allowed before between require-for-product and :.
ParseRequirementLineTestMalformed("require-for-product :");
}
+
+int main(int argc, char* argv[]) {
+ ::testing::InitGoogleTest(&argc, argv);
+ android::base::InitLogging(argv);
+ android::base::SetMinimumLogSeverity(android::base::VERBOSE);
+
+ return RUN_ALL_TESTS();
+}
diff --git a/fastboot/super_flash_helper_test.cpp b/fastboot/super_flash_helper_test.cpp
new file mode 100644
index 0000000..82b8aa5
--- /dev/null
+++ b/fastboot/super_flash_helper_test.cpp
@@ -0,0 +1,88 @@
+//
+// Copyright (C) 2023 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "super_flash_helper.h"
+
+#include <unistd.h>
+
+#include <android-base/file.h>
+#include <android-base/unique_fd.h>
+#include <gtest/gtest.h>
+#include <sparse/sparse.h>
+
+using android::base::unique_fd;
+
+unique_fd OpenTestFile(const std::string& file, int flags) {
+ std::string path = "testdata/" + file;
+
+ unique_fd fd(open(path.c_str(), flags));
+ if (fd >= 0) {
+ return fd;
+ }
+
+ path = android::base::GetExecutableDirectory() + "/" + path;
+ return unique_fd{open(path.c_str(), flags)};
+}
+
+class TestImageSource final : public ImageSource {
+ public:
+ bool ReadFile(const std::string&, std::vector<char>*) const override {
+ // Not used here.
+ return false;
+ }
+ unique_fd OpenFile(const std::string& name) const override {
+ return OpenTestFile(name, O_RDONLY | O_CLOEXEC);
+ }
+};
+
+TEST(SuperFlashHelper, ImageEquality) {
+ auto super_empty_fd = OpenTestFile("super_empty.img", O_RDONLY);
+ ASSERT_GE(super_empty_fd, 0);
+
+ TestImageSource source;
+ SuperFlashHelper helper(source);
+ ASSERT_TRUE(helper.Open(super_empty_fd));
+ ASSERT_TRUE(helper.AddPartition("system_a", "system.img", false));
+
+ auto sparse_file = helper.GetSparseLayout();
+ ASSERT_NE(sparse_file, nullptr);
+
+ TemporaryFile fb_super;
+ ASSERT_GE(fb_super.fd, 0);
+ ASSERT_EQ(sparse_file_write(sparse_file.get(), fb_super.fd, false, false, false), 0);
+
+ auto real_super_fd = OpenTestFile("super.img", O_RDONLY);
+ ASSERT_GE(real_super_fd, 0);
+
+ std::string expected(get_file_size(real_super_fd), '\0');
+ ASSERT_FALSE(expected.empty());
+ ASSERT_TRUE(android::base::ReadFully(real_super_fd, expected.data(), expected.size()));
+
+ std::string actual(get_file_size(fb_super.fd), '\0');
+ ASSERT_FALSE(actual.empty());
+ ASSERT_EQ(lseek(fb_super.fd, 0, SEEK_SET), 0);
+ ASSERT_TRUE(android::base::ReadFully(fb_super.fd, actual.data(), actual.size()));
+
+ // The helper doesn't add any extra zeroes to the image, whereas lpmake does, to
+ // pad to the entire super size.
+ ASSERT_LE(actual.size(), expected.size());
+ for (size_t i = 0; i < actual.size(); i++) {
+ ASSERT_EQ(actual[i], expected[i]) << "byte mismatch at position " << i;
+ }
+ for (size_t i = actual.size(); i < expected.size(); i++) {
+ ASSERT_EQ(expected[i], 0) << "byte mismatch at position " << i;
+ }
+}
diff --git a/fastboot/testdata/make_super_images.sh b/fastboot/testdata/make_super_images.sh
new file mode 100644
index 0000000..71c54ee
--- /dev/null
+++ b/fastboot/testdata/make_super_images.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+set -e
+set -x
+
+lpmake \
+ --device-size=auto \
+ --metadata-size=4096 \
+ --metadata-slots=3 \
+ --partition=system_a:readonly:0 \
+ --alignment=16384 \
+ --output=super_empty.img
+
+lpmake \
+ --device-size=auto \
+ --metadata-size=4096 \
+ --metadata-slots=3 \
+ --partition=system_a:readonly:0 \
+ --alignment=16384 \
+ --output=super.img \
+ --image=system_a=system.img
diff --git a/fastboot/testdata/super.img b/fastboot/testdata/super.img
new file mode 100644
index 0000000..be13d36
--- /dev/null
+++ b/fastboot/testdata/super.img
Binary files differ
diff --git a/fastboot/testdata/super_empty.img b/fastboot/testdata/super_empty.img
new file mode 100644
index 0000000..4b25869
--- /dev/null
+++ b/fastboot/testdata/super_empty.img
Binary files differ
diff --git a/fastboot/testdata/system.img b/fastboot/testdata/system.img
new file mode 100644
index 0000000..b360610
--- /dev/null
+++ b/fastboot/testdata/system.img
Binary files differ