blob: 9a3154fcd6ce470bbf8fdb7f4d612a7b8458677e [file] [log] [blame]
// 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.
#![cfg(test)]
use {
blobfs_ramdisk::BlobfsRamdisk,
fuchsia_async as fasync,
fuchsia_pkg_testing::{PackageBuilder, SystemImageBuilder},
fuchsia_zircon::Status,
pkgfs_ramdisk::PkgfsRamdisk,
std::convert::{TryFrom as _, TryInto as _},
};
fn make_file_contents(size: usize) -> impl Iterator<Item = u8> {
b"ABCD".iter().copied().cycle().take(size)
}
// zero is a multiple
fn round_up_to_4096_multiple(val: usize) -> usize {
(val + 4095) & !4095
}
// meta far file VMOs are zero-padded to the smallest multiple of 4096
fn validate_vmo_contents(file_size: usize, vmo_contents: &[u8]) {
let vmo_size = round_up_to_4096_multiple(file_size);
assert!(
make_file_contents(file_size)
.chain(std::iter::repeat(b'\0'))
.take(vmo_size)
.eq(vmo_contents.iter().copied()),
"vmo content mismatch for file size {}",
file_size
);
}
#[fasync::run_singlethreaded(test)]
async fn meta_far_file() {
let file_sizes = [0, 1, 4095, 4096, 4097];
let mut base_pkg_with_meta_files = PackageBuilder::new("example");
for size in &file_sizes {
base_pkg_with_meta_files = base_pkg_with_meta_files.add_resource_at(
format!("meta/{}", size),
make_file_contents(*size).collect::<Vec<u8>>().as_slice(),
);
}
let base_pkg_with_meta_files = base_pkg_with_meta_files.build().await.expect("build package");
let system_image =
SystemImageBuilder::new().static_packages(&[&base_pkg_with_meta_files]).build().await;
let blobfs = BlobfsRamdisk::start().unwrap();
system_image.write_to_blobfs_dir(&blobfs.root_dir().unwrap());
base_pkg_with_meta_files.write_to_blobfs_dir(&blobfs.root_dir().unwrap());
let pkgfs = PkgfsRamdisk::builder()
.blobfs(blobfs)
.system_image_merkle(system_image.meta_far_merkle_root())
.start()
.unwrap();
let d = pkgfs.root_dir_proxy().expect("getting pkgfs root dir");
for size in &file_sizes {
let meta_far_file = io_util::directory::open_file(
&d,
&format!("versions/{}/meta/{}", base_pkg_with_meta_files.meta_far_merkle_root(), size),
io_util::OPEN_RIGHT_READABLE,
)
.await
.unwrap();
let (status, buffer) = meta_far_file
.get_buffer(fidl_fuchsia_io::VMO_FLAG_READ | fidl_fuchsia_io::VMO_FLAG_PRIVATE)
.await
.unwrap();
Status::ok(status).unwrap();
let buffer = buffer.unwrap();
assert_eq!(buffer.size, u64::try_from(*size).unwrap());
let vmo_size = buffer.vmo.get_size().unwrap().try_into().unwrap();
let mut actual_contents = vec![0u8; vmo_size];
let () = buffer.vmo.read(actual_contents.as_mut_slice(), 0).unwrap();
validate_vmo_contents(*size, &actual_contents);
}
// Drop the directory before we shutdown the server that's serving it.
// In practice, this probably doesn't make a difference.
drop(d);
pkgfs.stop().await.expect("stopping pkgfs");
}