Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1fff690c authored by Daniel Zheng's avatar Daniel Zheng
Browse files

Adding testing for optimized flash super

Adding test cases for correct formation of optimized flash super task.
We are adding an explicit pattern match for this task to be correctly
formed. Changing Optimized flash task to only remove the reboot to
userspace as a user might want to reboot back to bootloader after
flashing. We also need to change a couple functions to take a
IFastbootDriver to mock up the initialization path.

Test: fastboot_test
Bug: 297085098
Change-Id: Ic5c63bd4057ca6d64647134e5ce33fef12077fdb
parent 09a61fad
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
@@ -1285,7 +1285,7 @@ std::string get_current_slot() {
    return current_slot;
}

static int get_slot_count() {
static int get_slot_count(fastboot::IFastBootDriver* fb) {
    std::string var;
    int count = 0;
    if (fb->GetVar("slot-count", &var) != fastboot::SUCCESS ||
@@ -1295,8 +1295,8 @@ static int get_slot_count() {
    return count;
}

bool supports_AB() {
    return get_slot_count() >= 2;
bool supports_AB(fastboot::IFastBootDriver* fb) {
    return get_slot_count(fb) >= 2;
}

// Given a current slot, this returns what the 'other' slot is.
@@ -1308,7 +1308,7 @@ static std::string get_other_slot(const std::string& current_slot, int count) {
}

static std::string get_other_slot(const std::string& current_slot) {
    return get_other_slot(current_slot, get_slot_count());
    return get_other_slot(current_slot, get_slot_count(fb));
}

static std::string get_other_slot(int count) {
@@ -1316,7 +1316,7 @@ static std::string get_other_slot(int count) {
}

static std::string get_other_slot() {
    return get_other_slot(get_current_slot(), get_slot_count());
    return get_other_slot(get_current_slot(), get_slot_count(fb));
}

static std::string verify_slot(const std::string& slot_name, bool allow_all) {
@@ -1325,7 +1325,7 @@ static std::string verify_slot(const std::string& slot_name, bool allow_all) {
        if (allow_all) {
            return "all";
        } else {
            int count = get_slot_count();
            int count = get_slot_count(fb);
            if (count > 0) {
                return "a";
            } else {
@@ -1334,7 +1334,7 @@ static std::string verify_slot(const std::string& slot_name, bool allow_all) {
        }
    }

    int count = get_slot_count();
    int count = get_slot_count(fb);
    if (count == 0) die("Device does not support slots");

    if (slot == "other") {
@@ -1407,7 +1407,7 @@ void do_for_partitions(const std::string& part, const std::string& slot,
                slot.c_str());
        }
        if (has_slot == "yes") {
            for (int i = 0; i < get_slot_count(); i++) {
            for (int i = 0; i < get_slot_count(fb); i++) {
                do_for_partition(part, std::string(1, (char)(i + 'a')), func, force_slot);
            }
        } else {
@@ -1528,7 +1528,7 @@ void do_flash(const char* pname, const char* fname, const bool apply_vbmeta,
// Sets slot_override as the active slot. If slot_override is blank,
// set current slot as active instead. This clears slot-unbootable.
static void set_active(const std::string& slot_override) {
    if (!supports_AB()) return;
    if (!supports_AB(fb)) return;

    if (slot_override != "") {
        fb->SetActive(slot_override);
@@ -1845,7 +1845,7 @@ void FlashAllTool::DetermineSlot() {
        fp_->secondary_slot = get_other_slot();
    }
    if (fp_->secondary_slot == "") {
        if (supports_AB()) {
        if (supports_AB(fb)) {
            fprintf(stderr, "Warning: Could not determine slot for secondary images. Ignoring.\n");
        }
        fp_->skip_secondary = true;
+1 −3
Original line number Diff line number Diff line
@@ -29,10 +29,8 @@

#include <functional>
#include <string>
#include "fastboot_driver.h"
#include "fastboot_driver_interface.h"
#include "filesystem.h"
#include "super_flash_helper.h"
#include "task.h"
#include "util.h"

@@ -183,12 +181,12 @@ struct NetworkSerial {
};

Result<NetworkSerial, FastbootError> ParseNetworkSerial(const std::string& serial);
bool supports_AB();
std::string GetPartitionName(const ImageEntry& entry, const std::string& current_slot_);
void flash_partition_files(const std::string& partition, const std::vector<SparsePtr>& files);
int64_t get_sparse_limit(int64_t size, const FlashingPlan* fp);
std::vector<SparsePtr> resparse_file(sparse_file* s, int64_t max_size);

bool supports_AB(fastboot::IFastBootDriver* fb);
bool is_retrofit_device(fastboot::IFastBootDriver* fb);
bool is_logical(const std::string& partition);
void fb_perform_format(const std::string& partition, int skip_if_not_supported,
+0 −3
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@
 */
#pragma once
#include <cstdlib>
#include <deque>
#include <functional>
#include <limits>
#include <string>
@@ -37,10 +36,8 @@
#include <android-base/stringprintf.h>
#include <android-base/unique_fd.h>
#include <bootimg.h>
#include <inttypes.h>
#include <sparse/sparse.h>

#include "constants.h"
#include "fastboot_driver_interface.h"
#include "transport.h"

+20 −25
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@
#include <gtest/gtest.h>
#include <sparse/sparse.h>

#include "constants.h"
#include "fastboot_driver.h"
#include "usb.h"

@@ -929,8 +930,7 @@ TEST_F(Fuzz, BadCommandTooLarge) {

    ASSERT_TRUE(UsbStillAvailible()) << USB_PORT_GONE;
    std::string resp;
    EXPECT_EQ(fb->GetVar("product", &resp), SUCCESS)
                << "Device is unresponsive to getvar command";
    EXPECT_EQ(fb->GetVar("product", &resp), SUCCESS) << "Device is unresponsive to getvar command";
}

TEST_F(Fuzz, CommandTooLarge) {
@@ -986,11 +986,10 @@ TEST_F(Fuzz, SparseZeroLength) {
TEST_F(Fuzz, SparseZeroBlkSize) {
    // handcrafted malform sparse file with zero as block size
    const std::vector<char> buf = {
        '\x3a', '\xff', '\x26', '\xed', '\x01', '\x00', '\x00', '\x00', '\x1c', '\x00', '\x0c', '\x00',
        '\x00', '\x00', '\x00', '\x00', '\x01', '\x00', '\x00', '\x00', '\x01', '\x00', '\x00', '\x00',
        '\x00', '\x00', '\x00', '\x00', '\xc2', '\xca', '\x00', '\x00', '\x01', '\x00', '\x00', '\x00',
        '\x10', '\x00', '\x00', '\x00', '\x11', '\x22', '\x33', '\x44'
    };
            '\x3a', '\xff', '\x26', '\xed', '\x01', '\x00', '\x00', '\x00', '\x1c', '\x00', '\x0c',
            '\x00', '\x00', '\x00', '\x00', '\x00', '\x01', '\x00', '\x00', '\x00', '\x01', '\x00',
            '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\xc2', '\xca', '\x00', '\x00', '\x01',
            '\x00', '\x00', '\x00', '\x10', '\x00', '\x00', '\x00', '\x11', '\x22', '\x33', '\x44'};

    ASSERT_EQ(DownloadCommand(buf.size()), SUCCESS) << "Device rejected download command";
    ASSERT_EQ(SendBuffer(buf), SUCCESS) << "Downloading payload failed";
@@ -1005,13 +1004,10 @@ TEST_F(Fuzz, SparseZeroBlkSize) {
TEST_F(Fuzz, SparseVeryLargeBlkSize) {
    // handcrafted sparse file with block size of ~4GB and divisible 4
    const std::vector<char> buf = {
        '\x3a', '\xff', '\x26', '\xed', '\x01', '\x00', '\x00', '\x00',
        '\x1c', '\x00', '\x0c', '\x00', '\xF0', '\xFF', '\xFF', '\xFF',
        '\x01', '\x00', '\x00', '\x00', '\x01', '\x00', '\x00', '\x00',
        '\x00', '\x00', '\x00', '\x00', '\xc3', '\xca', '\x00', '\x00',
        '\x01', '\x00', '\x00', '\x00', '\x0c', '\x00', '\x00', '\x00',
        '\x11', '\x22', '\x33', '\x44'
    };
            '\x3a', '\xff', '\x26', '\xed', '\x01', '\x00', '\x00', '\x00', '\x1c', '\x00', '\x0c',
            '\x00', '\xF0', '\xFF', '\xFF', '\xFF', '\x01', '\x00', '\x00', '\x00', '\x01', '\x00',
            '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\xc3', '\xca', '\x00', '\x00', '\x01',
            '\x00', '\x00', '\x00', '\x0c', '\x00', '\x00', '\x00', '\x11', '\x22', '\x33', '\x44'};

    ASSERT_EQ(DownloadCommand(buf.size()), SUCCESS) << "Device rejected download command";
    ASSERT_EQ(SendBuffer(buf), SUCCESS) << "Downloading payload failed";
@@ -1022,11 +1018,10 @@ TEST_F(Fuzz, SparseVeryLargeBlkSize) {
TEST_F(Fuzz, SparseTrimmed) {
    // handcrafted malform sparse file which is trimmed
    const std::vector<char> buf = {
        '\x3a', '\xff', '\x26', '\xed', '\x01', '\x00', '\x00', '\x00', '\x1c', '\x00', '\x0c', '\x00',
        '\x00', '\x10', '\x00', '\x00', '\x00', '\x00', '\x08', '\x00', '\x01', '\x00', '\x00', '\x00',
        '\x00', '\x00', '\x00', '\x00', '\xc1', '\xca', '\x00', '\x00', '\x01', '\x00', '\x00', '\x00',
        '\x00', '\x00', '\x00', '\x80', '\x11', '\x22', '\x33', '\x44'
    };
            '\x3a', '\xff', '\x26', '\xed', '\x01', '\x00', '\x00', '\x00', '\x1c', '\x00', '\x0c',
            '\x00', '\x00', '\x10', '\x00', '\x00', '\x00', '\x00', '\x08', '\x00', '\x01', '\x00',
            '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\xc1', '\xca', '\x00', '\x00', '\x01',
            '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x80', '\x11', '\x22', '\x33', '\x44'};

    ASSERT_EQ(DownloadCommand(buf.size()), SUCCESS) << "Device rejected download command";
    ASSERT_EQ(SendBuffer(buf), SUCCESS) << "Downloading payload failed";
@@ -1041,11 +1036,10 @@ TEST_F(Fuzz, SparseTrimmed) {
TEST_F(Fuzz, SparseInvalidChurk) {
    // handcrafted malform sparse file with invalid churk
    const std::vector<char> buf = {
        '\x3a', '\xff', '\x26', '\xed', '\x01', '\x00', '\x00', '\x00', '\x1c', '\x00', '\x0c', '\x00',
        '\x00', '\x10', '\x00', '\x00', '\x00', '\x00', '\x08', '\x00', '\x01', '\x00', '\x00', '\x00',
        '\x00', '\x00', '\x00', '\x00', '\xc1', '\xca', '\x00', '\x00', '\x01', '\x00', '\x00', '\x00',
        '\x10', '\x00', '\x00', '\x00', '\x11', '\x22', '\x33', '\x44'
    };
            '\x3a', '\xff', '\x26', '\xed', '\x01', '\x00', '\x00', '\x00', '\x1c', '\x00', '\x0c',
            '\x00', '\x00', '\x10', '\x00', '\x00', '\x00', '\x00', '\x08', '\x00', '\x01', '\x00',
            '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\xc1', '\xca', '\x00', '\x00', '\x01',
            '\x00', '\x00', '\x00', '\x10', '\x00', '\x00', '\x00', '\x11', '\x22', '\x33', '\x44'};

    ASSERT_EQ(DownloadCommand(buf.size()), SUCCESS) << "Device rejected download command";
    ASSERT_EQ(SendBuffer(buf), SUCCESS) << "Downloading payload failed";
@@ -1895,7 +1889,8 @@ int main(int argc, char** argv) {
    if (!fastboot::FastBootTest::IsFastbootOverTcp()) {
        printf("<Waiting for Device>\n");
        const auto matcher = [](usb_ifc_info* info) -> int {
            return fastboot::FastBootTest::MatchFastboot(info, fastboot::FastBootTest::device_serial);
            return fastboot::FastBootTest::MatchFastboot(info,
                                                         fastboot::FastBootTest::device_serial);
        };
        Transport* transport = nullptr;
        while (!transport) {
+9 −5
Original line number Diff line number Diff line
@@ -15,8 +15,7 @@
//
#include "task.h"

#include <cstddef>
#include <iostream>
#include "fastboot_driver.h"

#include <android-base/logging.h>
#include <android-base/parseint.h>
@@ -130,6 +129,7 @@ void OptimizedFlashSuperTask::Run() {
    // Send the data to the device.
    flash_partition_files(super_name_, files);
}

std::string OptimizedFlashSuperTask::ToString() const {
    return "optimized-flash-super";
}
@@ -165,7 +165,7 @@ std::unique_ptr<OptimizedFlashSuperTask> OptimizedFlashSuperTask::Initialize(
        LOG(INFO) << "super optimization is disabled";
        return nullptr;
    }
    if (!supports_AB()) {
    if (!supports_AB(fp->fb)) {
        LOG(VERBOSE) << "Cannot optimize flashing super on non-AB device";
        return nullptr;
    }
@@ -218,17 +218,21 @@ std::unique_ptr<OptimizedFlashSuperTask> OptimizedFlashSuperTask::Initialize(

    auto s = helper->GetSparseLayout();
    if (!s) return nullptr;
    // Remove images that we already flashed, just in case we have non-dynamic OS images.

    // Remove tasks that are concatenated into this optimized task
    auto remove_if_callback = [&](const auto& task) -> bool {
        if (auto flash_task = task->AsFlashTask()) {
            return helper->WillFlash(flash_task->GetPartitionAndSlot());
        } else if (auto update_super_task = task->AsUpdateSuperTask()) {
            return true;
        } else if (auto reboot_task = task->AsRebootTask()) {
            if (reboot_task->GetTarget() == "fastboot") {
                return true;
            }
        }
        return false;
    };

    tasks.erase(std::remove_if(tasks.begin(), tasks.end(), remove_if_callback), tasks.end());

    return std::make_unique<OptimizedFlashSuperTask>(super_name, std::move(helper), std::move(s),
Loading