blob: 33c77cdfbc1547e1333cf373ba79c7069c90c360 [file] [log] [blame] [edit]
// Copyright 2019 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.
//! library for target side of filesystem integrity host-target interaction tests
#![deny(missing_docs)]
use {
anyhow::Error,
fidl_fuchsia_device::ControllerMarker,
files_async::readdir,
fuchsia_component::client::connect_to_protocol_at_path,
fuchsia_zircon as zx, io_util,
rand::{distributions, rngs::StdRng, Rng, SeedableRng},
structopt::StructOpt,
};
pub mod static_tree;
/// Common options for the target test binary
#[derive(Debug, StructOpt)]
#[structopt(rename_all = "kebab-case")]
pub struct CommonOpts {
/// A seed to use for all random operations. Tests are deterministic relative to the provided
/// seed.
pub seed: u64,
/// The block device on the target device to use for testing. WARNING: the test can (and likely
/// will!) format this device. Don't use a main system partition!
pub block_device: String,
}
/// A set of common subcommands for the target test binary
#[derive(Debug, StructOpt)]
pub enum CommonCommand {
/// Run the setup step.
#[structopt(name = "setup")]
Setup,
/// Run the test step.
#[structopt(name = "test")]
Test,
/// Run the verification step.
#[structopt(name = "verify")]
Verify,
}
/// Generate a Vec<u8> of random bytes from a seed using a standard distribution.
pub fn generate_content(seed: u64) -> Vec<u8> {
let mut rng = StdRng::seed_from_u64(seed);
let size = rng.gen_range(1..1 << 16);
rng.sample_iter(&distributions::Standard).take(size).collect()
}
/// Find the device in /dev/class/block that represents a given topological path. Returns the full
/// path of the device in /dev/class/block.
pub async fn find_dev(dev: &str) -> Result<String, Error> {
let dev_class_block = io_util::open_directory_in_namespace(
"/dev/class/block",
io_util::OpenFlags::RIGHT_READABLE | io_util::OpenFlags::RIGHT_WRITABLE,
)?;
for entry in readdir(&dev_class_block).await? {
let path = format!("/dev/class/block/{}", entry.name);
let proxy = connect_to_protocol_at_path::<ControllerMarker>(&path)?;
let topo_path = proxy.get_topological_path().await?.map_err(|s| zx::Status::from_raw(s))?;
println!("{} => {}", path, topo_path);
if dev == topo_path {
return Ok(path);
}
}
Err(anyhow::anyhow!("Couldn't find {} in /dev/class/block", dev))
}