From ada871875ecfc4b953a6e5d9a843aee8cfb4bf7f Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 8 Feb 2023 22:06:56 -0800 Subject: [PATCH] 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 --- fastboot/Android.bp | 7 ++ fastboot/fastboot_test.cpp | 9 +++ fastboot/super_flash_helper_test.cpp | 88 +++++++++++++++++++++++++ fastboot/testdata/make_super_images.sh | 21 ++++++ fastboot/testdata/super.img | Bin 0 -> 65536 bytes fastboot/testdata/super_empty.img | Bin 0 -> 4388 bytes fastboot/testdata/system.img | Bin 0 -> 8192 bytes 7 files changed, 125 insertions(+) create mode 100644 fastboot/super_flash_helper_test.cpp create mode 100644 fastboot/testdata/make_super_images.sh create mode 100644 fastboot/testdata/super.img create mode 100644 fastboot/testdata/super_empty.img create mode 100644 fastboot/testdata/system.img diff --git a/fastboot/Android.bp b/fastboot/Android.bp index 6d50fa472..76aaf7bcd 100644 --- a/fastboot/Android.bp +++ b/fastboot/Android.bp @@ -378,6 +378,7 @@ cc_test_host { "fastboot_test.cpp", "socket_mock.cpp", "socket_test.cpp", + "super_flash_helper_test.cpp", "tcp_test.cpp", "udp_test.cpp", ], @@ -395,6 +396,12 @@ cc_test_host { }, 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 9c3ab6e66..79f37fd47 100644 --- a/fastboot/fastboot_test.cpp +++ b/fastboot/fastboot_test.cpp @@ -16,6 +16,7 @@ #include "fastboot.h" +#include #include TEST(FastBoot, ParseOsPatchLevel) { @@ -201,3 +202,11 @@ TEST(FastBoot, ParseRequirementLineMalformed) { // 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 000000000..82b8aa59c --- /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 + +#include +#include +#include +#include + +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*) 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 000000000..71c54ee49 --- /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 0000000000000000000000000000000000000000..be13d36973bcf3e01476803a229e51e2a4a16ea9 GIT binary patch literal 65536 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 a00KY&2mk>f00e*l5C8%|00{j55cpq^MNuvQ literal 0 HcmV?d00001 diff --git a/fastboot/testdata/super_empty.img b/fastboot/testdata/super_empty.img new file mode 100644 index 0000000000000000000000000000000000000000..4b258698348459bd1070cee75bdccd6690d4dbdc GIT binary patch literal 4388 zcmYdy$w@R}U|?un@PE2*m~ZlhBQuU1of7!-ymG>}zvkkTBi86$(KfKz%OJqOzzkFe zqDR4K2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQQDY0fPV^M=qd~8-Une zhk?^4f`6){&VQ>f*1z3u|NCX&a^9Z9?!^*~Pe%J!F9E7)-EPJ15_;$U-2Q_XB#P=q zPL>|#{xeIbpfA5?S4I6Z@aO;|P#tJY0fa$70*FCukhlR5r$E^bK)SfHxFj_o l2|)UgK}u>`VrfnZvJhT&0!-Ec#(pc*s@d(Ai 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