diff options
Diffstat (limited to 'fastboot/fuzzy_fastboot/main.cpp')
-rw-r--r-- | fastboot/fuzzy_fastboot/main.cpp | 78 |
1 files changed, 65 insertions, 13 deletions
diff --git a/fastboot/fuzzy_fastboot/main.cpp b/fastboot/fuzzy_fastboot/main.cpp index 34ab32c12..b6beaf93a 100644 --- a/fastboot/fuzzy_fastboot/main.cpp +++ b/fastboot/fuzzy_fastboot/main.cpp @@ -43,8 +43,10 @@ #include <thread> #include <vector> +#include <android-base/file.h> #include <android-base/parseint.h> #include <android-base/stringprintf.h> +#include <android-base/strings.h> #include <gtest/gtest.h> #include <sparse/sparse.h> @@ -349,22 +351,35 @@ TEST_F(Conformance, GetVarBattVoltageOk) { EXPECT_TRUE(var == "yes" || var == "no") << "getvar:battery-soc-ok must be 'yes' or 'no'"; } -TEST_F(Conformance, GetVarDownloadSize) { - std::string var; - EXPECT_EQ(fb->GetVar("max-download-size", &var), SUCCESS) << "getvar:max-download-size failed"; - EXPECT_NE(var, "") << "getvar:max-download-size responded with empty string"; +void AssertHexUint32(const std::string& name, const std::string& var) { + ASSERT_NE(var, "") << "getvar:" << name << " responded with empty string"; // This must start with 0x - EXPECT_FALSE(isspace(var.front())) - << "getvar:max-download-size responded with a string with leading whitespace"; - EXPECT_FALSE(var.compare(0, 2, "0x")) - << "getvar:max-download-size responded with a string that does not start with 0x..."; + ASSERT_FALSE(isspace(var.front())) + << "getvar:" << name << " responded with a string with leading whitespace"; + ASSERT_FALSE(var.compare(0, 2, "0x")) + << "getvar:" << name << " responded with a string that does not start with 0x..."; int64_t size = strtoll(var.c_str(), nullptr, 16); - EXPECT_GT(size, 0) << "'" + var + "' is not a valid response from getvar:max-download-size"; + ASSERT_GT(size, 0) << "'" + var + "' is not a valid response from getvar:" << name; // At most 32-bits - EXPECT_LE(size, std::numeric_limits<uint32_t>::max()) - << "getvar:max-download-size must fit in a uint32_t"; - EXPECT_LE(var.size(), FB_RESPONSE_SZ - 4) - << "getvar:max-download-size responded with too large of string: " + var; + ASSERT_LE(size, std::numeric_limits<uint32_t>::max()) + << "getvar:" << name << " must fit in a uint32_t"; + ASSERT_LE(var.size(), FB_RESPONSE_SZ - 4) + << "getvar:" << name << " responded with too large of string: " + var; +} + +TEST_F(Conformance, GetVarDownloadSize) { + std::string var; + EXPECT_EQ(fb->GetVar("max-download-size", &var), SUCCESS) << "getvar:max-download-size failed"; + AssertHexUint32("max-download-size", var); +} + +// If fetch is supported, getvar:max-fetch-size must return a hex string. +TEST_F(Conformance, GetVarFetchSize) { + std::string var; + if (SUCCESS != fb->GetVar("max-fetch-size", &var)) { + GTEST_SKIP() << "getvar:max-fetch-size failed"; + } + AssertHexUint32("max-fetch-size", var); } TEST_F(Conformance, GetVarAll) { @@ -656,6 +671,33 @@ TEST_F(UnlockPermissions, DownloadFlash) { EXPECT_EQ(fb->Partitions(&parts), SUCCESS) << "getvar:all failed in unlocked mode"; } +// If the implementation supports getvar:max-fetch-size, it must also support fetch:vendor_boot*. +TEST_F(UnlockPermissions, FetchVendorBoot) { + std::string var; + uint64_t fetch_size; + if (fb->GetVar("max-fetch-size", &var) != SUCCESS) { + GTEST_SKIP() << "This test is skipped because fetch is not supported."; + } + ASSERT_FALSE(var.empty()); + ASSERT_TRUE(android::base::ParseUint(var, &fetch_size)) << var << " is not an integer"; + std::vector<std::tuple<std::string, uint64_t>> parts; + EXPECT_EQ(fb->Partitions(&parts), SUCCESS) << "getvar:all failed"; + for (const auto& [partition, partition_size] : parts) { + if (!android::base::StartsWith(partition, "vendor_boot")) continue; + TemporaryFile fetched; + + uint64_t offset = 0; + while (offset < partition_size) { + uint64_t chunk_size = std::min(fetch_size, partition_size - offset); + auto ret = fb->FetchToFd(partition, fetched.fd, offset, chunk_size); + ASSERT_EQ(fastboot::RetCode::SUCCESS, ret) + << "Unable to fetch " << partition << " (offset=" << offset + << ", size=" << chunk_size << ")"; + offset += chunk_size; + } + } +} + TEST_F(LockPermissions, DownloadFlash) { std::vector<char> buf{'a', 'o', 's', 'p'}; EXPECT_EQ(fb->Download(buf), SUCCESS) << "Download failed in locked mode"; @@ -717,6 +759,16 @@ TEST_F(LockPermissions, Boot) { EXPECT_GT(resp.size(), 0) << "No error message was returned by device after FAIL"; } +TEST_F(LockPermissions, FetchVendorBoot) { + std::vector<std::tuple<std::string, uint64_t>> parts; + EXPECT_EQ(fb->Partitions(&parts), SUCCESS) << "getvar:all failed"; + for (const auto& [partition, _] : parts) { + TemporaryFile fetched; + ASSERT_EQ(fb->FetchToFd(partition, fetched.fd, 0, 0), DEVICE_FAIL) + << "fetch:" << partition << ":0:0 did not fail in locked mode"; + } +} + TEST_F(Fuzz, DownloadSize) { std::string var; EXPECT_EQ(fb->GetVar("max-download-size", &var), SUCCESS) << "getvar:max-download-size failed"; |