// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use {
    anyhow::{Context, Error},
    blobfs_ramdisk::BlobfsRamdisk,
    fidl::endpoints::{ClientEnd, RequestStream, ServerEnd},
    fidl_fuchsia_io::{
        self as fio, DirectoryAdminRequest, DirectoryAdminRequestStream, DirectoryMarker,
        DirectoryObject, NodeAttributes, NodeInfo, NodeMarker,
    },
    fidl_fuchsia_paver::{Asset, Configuration, PaverRequestStream},
    fidl_fuchsia_pkg_ext::{MirrorConfigBuilder, RepositoryConfigBuilder, RepositoryConfigs},
    fuchsia_async as fasync,
    fuchsia_component::server::ServiceFs,
    fuchsia_merkle::Hash,
    fuchsia_pkg_testing::{serve::ServedRepository, Package, PackageBuilder, RepositoryBuilder},
    fuchsia_url::pkg_url::RepoUrl,
    fuchsia_zircon as zx,
    futures::prelude::*,
    http::uri::Uri,
    isolated_ota::{download_and_apply_update, OmahaConfig, UpdateError},
    matches::assert_matches,
    mock_omaha_server::{OmahaResponse, OmahaServer},
    mock_paver::{hooks as mphooks, MockPaverService, MockPaverServiceBuilder, PaverEvent},
    serde_json::json,
    std::{
        collections::{BTreeSet, HashMap},
        str::FromStr,
        sync::Arc,
    },
    tempfile::TempDir,
};

const EMPTY_REPO_PATH: &str = "/pkg/empty-repo";
const TEST_CERTS_PATH: &str = "/pkg/data/ssl";
const TEST_REPO_URL: &str = "fuchsia-pkg://integration.test.fuchsia.com";

enum OmahaState {
    /// Don't use Omaha for this update.
    Disabled,
    /// Set up an Omaha server automatically.
    Auto(OmahaResponse),
    /// Pass the given OmahaConfig to Omaha.
    Manual(OmahaConfig),
}

struct TestEnvBuilder {
    blobfs: Option<ClientEnd<DirectoryMarker>>,
    board: String,
    channel: String,
    images: HashMap<String, Vec<u8>>,
    omaha: OmahaState,
    packages: Vec<Package>,
    paver: MockPaverServiceBuilder,
    repo_config: Option<RepositoryConfigs>,
    version: String,
}

impl TestEnvBuilder {
    pub fn new() -> Self {
        TestEnvBuilder {
            blobfs: None,
            board: "test-board".to_owned(),
            channel: "test".to_owned(),
            images: HashMap::new(),
            omaha: OmahaState::Disabled,
            packages: vec![],
            paver: MockPaverServiceBuilder::new(),
            repo_config: None,
            version: "0.1.2.3".to_owned(),
        }
    }

    /// Add an image to the update package that will be generated by this TestEnvBuilder
    pub fn add_image(mut self, name: &str, data: &[u8]) -> Self {
        self.images.insert(name.to_owned(), data.to_vec());
        self
    }

    /// Add a package to the repository generated by this TestEnvBuilder.
    /// The package will also be listed in the generated update package
    /// so that it will be downloaded as part of the OTA.
    pub fn add_package(mut self, pkg: Package) -> Self {
        self.packages.push(pkg);
        self
    }

    pub fn blobfs(mut self, client: ClientEnd<DirectoryMarker>) -> Self {
        self.blobfs = Some(client);
        self
    }

    /// Provide a TUF repository configuration to the package resolver.
    /// This will override the repository that the builder would otherwise generate.
    pub fn repo_config(mut self, repo: RepositoryConfigs) -> Self {
        self.repo_config = Some(repo);
        self
    }

    /// Enable/disable Omaha. OmahaState::Auto will automatically set up an Omaha server and tell
    /// the updater to use it.
    pub fn omaha_state(mut self, state: OmahaState) -> Self {
        self.omaha = state;
        self
    }

    /// Mutate the MockPaverServiecBuilder used by this TestEnvBuilder.
    pub fn paver<F>(mut self, func: F) -> Self
    where
        F: FnOnce(MockPaverServiceBuilder) -> MockPaverServiceBuilder,
    {
        self.paver = func(self.paver);
        self
    }

    fn generate_packages(&self) -> String {
        json!({
            "version": "1",
            "content": self.packages
                .iter()
                .map(|p| format!("{}/{}/0?hash={}",
                                 TEST_REPO_URL,
                                 p.name(),
                                 p.meta_far_merkle_root()))
                .collect::<Vec<String>>(),
        })
        .to_string()
    }

    /// Turn this |TestEnvBuilder| into a |TestEnv|
    pub async fn build(mut self) -> Result<TestEnv, Error> {
        let mut update = PackageBuilder::new("update")
            .add_resource_at("packages.json", self.generate_packages().as_bytes());

        let (repo_config, served_repo, cert_dir, packages, merkle) = if self.repo_config.is_none() {
            // If no repo config was specified, host a repo containing the provided packages,
            // and an update package containing given images + all packages in the repo.
            for (name, data) in self.images.iter() {
                update = update.add_resource_at(name, data.as_slice());
            }

            let update = update.build().await.context("Building update package")?;
            let repo = Arc::new(
                self.packages
                    .iter()
                    .fold(
                        RepositoryBuilder::from_template_dir(EMPTY_REPO_PATH).add_package(&update),
                        |repo, package| repo.add_package(package),
                    )
                    .build()
                    .await
                    .context("Building repo")?,
            );

            let served_repo = Arc::clone(&repo).server().start().context("serving repo")?;
            let config = RepositoryConfigs::Version1(vec![
                served_repo.make_repo_config(TEST_REPO_URL.parse()?)
            ]);

            let update_merkle = update.meta_far_merkle_root().clone();
            // Add the update package to the list of packages, so that TestResult::check_packages
            // will expect to see the update package's blobs in blobfs.
            let mut packages = vec![update];
            packages.append(&mut self.packages);
            (
                config,
                Some(served_repo),
                std::fs::File::open(TEST_CERTS_PATH).context("opening test certificates")?,
                packages,
                update_merkle,
            )
        } else {
            // Use the provided repo config. Assume that this means we'll actually want to use
            // real SSL certificates, and that we don't need to host our own repository.
            (
                self.repo_config.unwrap(),
                None,
                std::fs::File::open("/config/ssl").context("opening system ssl certificates")?,
                vec![],
                Hash::from_str("deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef")
                    .context("Making merkle")?,
            )
        };

        let dir = tempfile::tempdir()?;
        let mut path = dir.path().to_owned();
        path.push("repo_config.json");
        let path = path.as_path();
        serde_json::to_writer(
            std::io::BufWriter::new(std::fs::File::create(path).context("creating file")?),
            &repo_config,
        )
        .unwrap();

        Ok(TestEnv {
            blobfs: self.blobfs,
            board: self.board,
            channel: self.channel,
            omaha: self.omaha,
            packages,
            paver: Arc::new(self.paver.build()),
            _repo: served_repo,
            repo_config_dir: dir,
            ssl_certs: cert_dir,
            update_merkle: merkle,
            version: self.version,
        })
    }
}

struct TestEnv {
    blobfs: Option<ClientEnd<DirectoryMarker>>,
    board: String,
    channel: String,
    omaha: OmahaState,
    packages: Vec<Package>,
    paver: Arc<MockPaverService>,
    _repo: Option<ServedRepository>,
    repo_config_dir: TempDir,
    ssl_certs: std::fs::File,
    update_merkle: Hash,
    version: String,
}

impl TestEnv {
    fn start_omaha(omaha: OmahaState, merkle: Hash) -> Result<Option<OmahaConfig>, Error> {
        match omaha {
            OmahaState::Disabled => Ok(None),
            OmahaState::Manual(cfg) => Ok(Some(cfg)),
            OmahaState::Auto(response) => {
                let server = OmahaServer::new_with_hash(response, merkle);
                let addr = server.start().context("Starting omaha server")?;
                let config =
                    OmahaConfig { app_id: "integration-test-appid".to_owned(), server_url: addr };

                Ok(Some(config))
            }
        }
    }

    /// Run the update, consuming this |TestEnv| and returning a |TestResult|.
    pub async fn run(mut self) -> TestResult {
        let (blobfs, blobfs_handle) = if let Some(client) = self.blobfs.take() {
            (None, client)
        } else {
            let blobfs = BlobfsRamdisk::start().expect("launching blobfs");
            let client = blobfs.root_dir_handle().expect("getting blobfs root handle");
            (Some(blobfs), client)
        };

        let omaha_config =
            TestEnv::start_omaha(self.omaha, self.update_merkle).expect("Starting Omaha server");

        let mut service_fs = ServiceFs::new();
        let paver_clone = Arc::clone(&self.paver);
        service_fs.add_fidl_service(move |stream: PaverRequestStream| {
            fasync::Task::spawn(
                Arc::clone(&paver_clone)
                    .run_paver_service(stream)
                    .unwrap_or_else(|e| panic!("Failed to run mock paver: {:?}", e)),
            )
            .detach();
        });
        let (client, server) = zx::Channel::create().expect("creating channel for servicefs");
        service_fs.serve_connection(server).expect("Failed to serve connection");
        fasync::Task::spawn(service_fs.collect()).detach();

        let result = download_and_apply_update(
            blobfs_handle,
            ClientEnd::from(client),
            std::fs::File::open(self.repo_config_dir.into_path()).expect("Opening repo config dir"),
            self.ssl_certs,
            &self.channel,
            &self.board,
            &self.version,
            omaha_config,
        )
        .await;

        TestResult {
            blobfs,
            packages: self.packages,
            paver_events: self.paver.take_events(),
            result,
        }
    }
}

struct TestResult {
    blobfs: Option<BlobfsRamdisk>,
    packages: Vec<Package>,
    pub paver_events: Vec<PaverEvent>,
    pub result: Result<(), UpdateError>,
}

impl TestResult {
    /// Assert that all blobs in all the packages that were part of the Update
    /// have been installed into the blobfs, and that the blobfs contains no extra blobs.
    pub fn check_packages(&self) {
        let written_blobs = self
            .blobfs
            .as_ref()
            .unwrap_or_else(|| panic!("Test had no blobfs"))
            .list_blobs()
            .expect("Listing blobfs blobs");
        let mut all_package_blobs = BTreeSet::new();
        for package in self.packages.iter() {
            all_package_blobs.append(&mut package.list_blobs().expect("Listing package blobs"));
        }

        assert_eq!(written_blobs, all_package_blobs);
    }
}

async fn build_test_package() -> Result<Package, Error> {
    PackageBuilder::new("test-package")
        .add_resource_at("/data/test", "hello, world!".as_bytes())
        .build()
        .await
        .context("Building test package")
}

#[fasync::run_singlethreaded(test)]
pub async fn test_no_network() -> Result<(), Error> {
    // Test what happens when we can't reach the remote repo.
    let bad_mirror =
        MirrorConfigBuilder::new("http://does-not-exist.fuchsia.com".parse::<Uri>().unwrap())?
            .build();
    let invalid_repo = RepositoryConfigs::Version1(vec![RepositoryConfigBuilder::new(
        RepoUrl::new("fuchsia.com".to_owned())?,
    )
    .add_mirror(bad_mirror)
    .build()]);

    let env = TestEnvBuilder::new()
        .repo_config(invalid_repo)
        .build()
        .await
        .context("Building TestEnv")?;

    let update_result = env.run().await;
    assert_eq!(
        update_result.paver_events,
        vec![
            PaverEvent::QueryCurrentConfiguration,
            PaverEvent::ReadAsset {
                configuration: Configuration::A,
                asset: Asset::VerifiedBootMetadata
            },
            PaverEvent::ReadAsset { configuration: Configuration::A, asset: Asset::Kernel },
            PaverEvent::QueryCurrentConfiguration,
            PaverEvent::QueryConfigurationStatus { configuration: Configuration::A },
            PaverEvent::SetConfigurationUnbootable { configuration: Configuration::B },
            PaverEvent::BootManagerFlush,
        ]
    );
    update_result.check_packages();

    let err = update_result.result.unwrap_err();
    assert_matches!(err, UpdateError::InstallError(_));
    Ok(())
}

#[fasync::run_singlethreaded(test)]
pub async fn test_pave_fails() -> Result<(), Error> {
    // Test what happens if the paver fails while paving.
    let test_package = build_test_package().await?;
    let paver_hook = |p: &PaverEvent| {
        if let PaverEvent::WriteAsset { payload, .. } = p {
            if payload.as_slice() == "FAIL".as_bytes() {
                return zx::Status::IO;
            }
        }
        zx::Status::OK
    };

    let env = TestEnvBuilder::new()
        .paver(|p| p.insert_hook(mphooks::return_error(paver_hook)))
        .add_package(test_package)
        .add_image("zbi.signed", "FAIL".as_bytes())
        .add_image("fuchsia.vbmeta", "FAIL".as_bytes())
        .build()
        .await
        .context("Building TestEnv")?;

    let result = env.run().await;
    assert_eq!(
        result.paver_events,
        vec![
            PaverEvent::QueryCurrentConfiguration,
            PaverEvent::ReadAsset {
                configuration: Configuration::A,
                asset: Asset::VerifiedBootMetadata
            },
            PaverEvent::ReadAsset { configuration: Configuration::A, asset: Asset::Kernel },
            PaverEvent::QueryCurrentConfiguration,
            PaverEvent::QueryConfigurationStatus { configuration: Configuration::A },
            PaverEvent::SetConfigurationUnbootable { configuration: Configuration::B },
            PaverEvent::BootManagerFlush,
            PaverEvent::WriteAsset {
                asset: Asset::Kernel,
                configuration: Configuration::B,
                payload: "FAIL".as_bytes().to_vec(),
            },
        ]
    );
    println!("Paver events: {:?}", result.paver_events);
    assert_matches!(result.result.unwrap_err(), UpdateError::InstallError(_));

    Ok(())
}

#[fasync::run_singlethreaded(test)]
pub async fn test_updater_succeeds() -> Result<(), Error> {
    let mut builder = TestEnvBuilder::new()
        .add_image("zbi.signed", "This is a zbi".as_bytes())
        .add_image("fuchsia.vbmeta", "This is a vbmeta".as_bytes())
        .add_image("zedboot.signed", "This is zedboot".as_bytes())
        .add_image("recovery.vbmeta", "This is another vbmeta".as_bytes())
        .add_image("bootloader", "This is a bootloader upgrade".as_bytes())
        .add_image("firmware_test", "This is the test firmware".as_bytes());
    for i in 0i64..3 {
        let name = format!("test-package{}", i);
        let package = PackageBuilder::new(name)
            .add_resource_at(
                format!("/data/my-package-data-{}", i),
                format!("This is some test data for test package {}", i).as_bytes(),
            )
            .add_resource_at("/bin/binary", "#!/boot/bin/sh\necho Hello".as_bytes())
            .build()
            .await
            .context("Building test package")?;
        builder = builder.add_package(package);
    }

    let env = builder.build().await.context("Building TestEnv")?;
    let result = env.run().await;

    result.check_packages();
    assert!(result.result.is_ok());
    assert_eq!(
        result.paver_events,
        vec![
            PaverEvent::QueryCurrentConfiguration,
            PaverEvent::ReadAsset {
                configuration: Configuration::A,
                asset: Asset::VerifiedBootMetadata
            },
            PaverEvent::ReadAsset { configuration: Configuration::A, asset: Asset::Kernel },
            PaverEvent::QueryCurrentConfiguration,
            PaverEvent::QueryConfigurationStatus { configuration: Configuration::A },
            PaverEvent::SetConfigurationUnbootable { configuration: Configuration::B },
            PaverEvent::BootManagerFlush,
            PaverEvent::WriteFirmware {
                configuration: Configuration::B,
                firmware_type: "".to_owned(),
                payload: "This is a bootloader upgrade".as_bytes().to_vec(),
            },
            PaverEvent::WriteFirmware {
                configuration: Configuration::B,
                firmware_type: "test".to_owned(),
                payload: "This is the test firmware".as_bytes().to_vec(),
            },
            PaverEvent::WriteAsset {
                configuration: Configuration::B,
                asset: Asset::Kernel,
                payload: "This is a zbi".as_bytes().to_vec(),
            },
            PaverEvent::WriteAsset {
                configuration: Configuration::B,
                asset: Asset::VerifiedBootMetadata,
                payload: "This is a vbmeta".as_bytes().to_vec(),
            },
            // Note that zedboot/recovery isn't written, as isolated-ota skips them.
            PaverEvent::SetConfigurationActive { configuration: Configuration::B },
            PaverEvent::DataSinkFlush,
            PaverEvent::BootManagerFlush,
            // This is the isolated-ota library checking to see if the paver configured ABR properly.
            PaverEvent::QueryActiveConfiguration,
        ]
    );
    Ok(())
}

fn launch_cloned_blobfs(end: ServerEnd<NodeMarker>, flags: u32, parent_flags: u32) {
    let flags = if (flags & fio::CLONE_FLAG_SAME_RIGHTS) == fio::CLONE_FLAG_SAME_RIGHTS {
        parent_flags
    } else {
        flags
    };
    let chan = fidl::AsyncChannel::from_channel(end.into_channel()).expect("cloning blobfs dir");
    let stream = DirectoryAdminRequestStream::from_channel(chan);
    fasync::Task::spawn(async move {
        serve_failing_blobfs(stream, flags)
            .await
            .unwrap_or_else(|e| panic!("Failed to serve cloned blobfs handle: {:?}", e));
    })
    .detach();
}

async fn serve_failing_blobfs(
    mut stream: DirectoryAdminRequestStream,
    open_flags: u32,
) -> Result<(), Error> {
    if (open_flags & fio::OPEN_FLAG_DESCRIBE) == fio::OPEN_FLAG_DESCRIBE {
        stream
            .control_handle()
            .send_on_open_(
                zx::Status::OK.into_raw(),
                Some(&mut NodeInfo::Directory(DirectoryObject)),
            )
            .context("sending on open")?;
    }
    while let Some(req) = stream.try_next().await? {
        match req {
            DirectoryAdminRequest::Clone { object, flags, .. } => {
                launch_cloned_blobfs(object, flags, open_flags)
            }
            DirectoryAdminRequest::Close { responder } => {
                responder.send(zx::Status::IO.into_raw()).context("failing close")?
            }
            DirectoryAdminRequest::Describe { responder } => {
                responder.send(&mut NodeInfo::Directory(DirectoryObject)).context("describing")?
            }
            DirectoryAdminRequest::Sync { responder } => {
                responder.send(zx::Status::IO.into_raw()).context("failing sync")?
            }
            DirectoryAdminRequest::GetAttr { responder } => responder
                .send(
                    zx::Status::IO.into_raw(),
                    &mut NodeAttributes {
                        mode: 0,
                        id: 0,
                        content_size: 0,
                        storage_size: 0,
                        link_count: 0,
                        creation_time: 0,
                        modification_time: 0,
                    },
                )
                .context("failing getattr")?,
            DirectoryAdminRequest::SetAttr { responder, .. } => {
                responder.send(zx::Status::IO.into_raw()).context("failing setattr")?
            }
            DirectoryAdminRequest::NodeGetFlags { responder } => {
                responder.send(zx::Status::IO.into_raw(), 0).context("failing getflags")?
            }
            DirectoryAdminRequest::NodeSetFlags { responder, .. } => {
                responder.send(zx::Status::IO.into_raw()).context("failing setflags")?
            }
            DirectoryAdminRequest::Open { object, flags, path, .. } => {
                if &path == "." {
                    launch_cloned_blobfs(object, flags, open_flags);
                } else {
                    object.close_with_epitaph(zx::Status::IO).context("failing open")?;
                }
            }
            DirectoryAdminRequest::Unlink { responder, .. } => {
                responder.send(zx::Status::IO.into_raw()).context("failing unlink")?
            }
            DirectoryAdminRequest::ReadDirents { responder, .. } => {
                responder.send(zx::Status::IO.into_raw(), &[]).context("failing readdirents")?
            }
            DirectoryAdminRequest::Rewind { responder } => {
                responder.send(zx::Status::IO.into_raw()).context("failing rewind")?
            }
            DirectoryAdminRequest::GetToken { responder } => {
                responder.send(zx::Status::IO.into_raw(), None).context("failing gettoken")?
            }
            DirectoryAdminRequest::Rename { responder, .. } => {
                responder.send(zx::Status::IO.into_raw()).context("failing rename")?
            }
            DirectoryAdminRequest::Link { responder, .. } => {
                responder.send(zx::Status::IO.into_raw()).context("failing link")?
            }
            DirectoryAdminRequest::Watch { responder, .. } => {
                responder.send(zx::Status::IO.into_raw()).context("failing watch")?
            }
            DirectoryAdminRequest::Mount { responder, .. } => {
                responder.send(zx::Status::IO.into_raw()).context("failing mount")?
            }
            DirectoryAdminRequest::MountAndCreate { responder, .. } => {
                responder.send(zx::Status::IO.into_raw()).context("failing mountandcreate")?
            }
            DirectoryAdminRequest::Unmount { responder, .. } => {
                responder.send(zx::Status::IO.into_raw()).context("failing umount")?
            }
            DirectoryAdminRequest::UnmountNode { responder, .. } => {
                responder.send(zx::Status::IO.into_raw(), None).context("failing unmountnode")?
            }
            DirectoryAdminRequest::QueryFilesystem { responder, .. } => responder
                .send(zx::Status::IO.into_raw(), None)
                .context("failing queryfilesystem")?,
            DirectoryAdminRequest::GetDevicePath { responder } => {
                responder.send(zx::Status::IO.into_raw(), None).context("failing getdevicepath")?
            }
        };
    }

    Ok(())
}

#[fasync::run_singlethreaded(test)]
pub async fn test_blobfs_broken() -> Result<(), Error> {
    let (client, server) = zx::Channel::create().context("creating blobfs channel")?;
    let package = build_test_package().await?;
    let paver_hook = |_: &PaverEvent| zx::Status::IO;
    let env = TestEnvBuilder::new()
        .add_package(package)
        .add_image("zbi.signed", "ZBI".as_bytes())
        .blobfs(ClientEnd::from(client))
        .paver(|p| p.insert_hook(mphooks::return_error(paver_hook)))
        .build()
        .await
        .context("Building TestEnv")?;

    let stream =
        DirectoryAdminRequestStream::from_channel(fidl::AsyncChannel::from_channel(server)?);

    fasync::Task::spawn(async move {
        serve_failing_blobfs(stream, 0)
            .await
            .unwrap_or_else(|e| panic!("Failed to serve blobfs: {:?}", e));
    })
    .detach();

    let result = env.run().await;

    assert_matches!(result.result, Err(UpdateError::InstallError(_)));

    Ok(())
}

#[fasync::run_singlethreaded(test)]
pub async fn test_omaha_broken() -> Result<(), Error> {
    let bad_omaha_config = OmahaConfig {
        app_id: "broken-omaha-test".to_owned(),
        server_url: "http://does-not-exist.fuchsia.com".to_owned(),
    };
    let package = build_test_package().await?;
    let env = TestEnvBuilder::new()
        .add_package(package)
        .add_image("zbi.signed", "ZBI".as_bytes())
        .omaha_state(OmahaState::Manual(bad_omaha_config))
        .build()
        .await
        .context("Building TestEnv")?;

    let result = env.run().await;
    assert_matches!(result.result, Err(UpdateError::InstallError(_)));

    Ok(())
}

#[fasync::run_singlethreaded(test)]
pub async fn test_omaha_works() -> Result<(), Error> {
    let mut builder = TestEnvBuilder::new()
        .add_image("zbi.signed", "This is a zbi".as_bytes())
        .add_image("fuchsia.vbmeta", "This is a vbmeta".as_bytes())
        .add_image("zedboot.signed", "This is zedboot".as_bytes())
        .add_image("recovery.vbmeta", "This is another vbmeta".as_bytes())
        .add_image("bootloader", "This is a bootloader upgrade".as_bytes())
        .add_image("firmware_test", "This is the test firmware".as_bytes());
    for i in 0i64..3 {
        let name = format!("test-package{}", i);
        let package = PackageBuilder::new(name)
            .add_resource_at(
                format!("/data/my-package-data-{}", i),
                format!("This is some test data for test package {}", i).as_bytes(),
            )
            .add_resource_at("/bin/binary", "#!/boot/bin/sh\necho Hello".as_bytes())
            .build()
            .await
            .context("Building test package")?;
        builder = builder.add_package(package);
    }

    let env = builder
        .omaha_state(OmahaState::Auto(OmahaResponse::Update))
        .build()
        .await
        .context("Building TestEnv")?;

    let result = env.run().await;
    result.check_packages();
    assert!(result.result.is_ok());
    assert_eq!(
        result.paver_events,
        vec![
            PaverEvent::QueryCurrentConfiguration,
            PaverEvent::ReadAsset {
                configuration: Configuration::A,
                asset: Asset::VerifiedBootMetadata
            },
            PaverEvent::ReadAsset { configuration: Configuration::A, asset: Asset::Kernel },
            PaverEvent::QueryCurrentConfiguration,
            PaverEvent::QueryConfigurationStatus { configuration: Configuration::A },
            PaverEvent::SetConfigurationUnbootable { configuration: Configuration::B },
            PaverEvent::BootManagerFlush,
            PaverEvent::WriteFirmware {
                configuration: Configuration::B,
                firmware_type: "".to_owned(),
                payload: "This is a bootloader upgrade".as_bytes().to_vec(),
            },
            PaverEvent::WriteFirmware {
                configuration: Configuration::B,
                firmware_type: "test".to_owned(),
                payload: "This is the test firmware".as_bytes().to_vec(),
            },
            PaverEvent::WriteAsset {
                configuration: Configuration::B,
                asset: Asset::Kernel,
                payload: "This is a zbi".as_bytes().to_vec(),
            },
            PaverEvent::WriteAsset {
                configuration: Configuration::B,
                asset: Asset::VerifiedBootMetadata,
                payload: "This is a vbmeta".as_bytes().to_vec(),
            },
            // Note that zedboot/recovery isn't written, as isolated-ota skips them.
            PaverEvent::SetConfigurationActive { configuration: Configuration::B },
            PaverEvent::DataSinkFlush,
            PaverEvent::BootManagerFlush,
            // This is the isolated-ota library checking to see if the paver configured ABR properly.
            PaverEvent::QueryActiveConfiguration,
        ]
    );

    Ok(())
}
