blob: ab521a41159bc8b48f6820dc4a5060e7472faed8 [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.
use {
crate::TestEnv,
blobfs_ramdisk::BlobfsRamdisk,
fidl_fuchsia_pkg::{PackageIndexIteratorMarker, PackageIndexIteratorProxy},
fidl_fuchsia_pkg_ext::BlobId,
fuchsia_async as fasync,
fuchsia_hash::Hash,
fuchsia_pkg::PackagePath,
fuchsia_pkg_testing::{Package, PackageBuilder, SystemImageBuilder},
pkgfs_ramdisk::PkgfsRamdisk,
};
/// Sets up the test environment and writes the packages out to base.
async fn setup_test_env(static_packages: &[&Package]) -> TestEnv {
let blobfs = BlobfsRamdisk::start().unwrap();
let system_image_package = SystemImageBuilder::new().static_packages(static_packages);
let system_image_package = system_image_package.build().await;
system_image_package.write_to_blobfs_dir(&blobfs.root_dir().unwrap());
for pkg in static_packages {
pkg.write_to_blobfs_dir(&blobfs.root_dir().unwrap());
}
let pkgfs = PkgfsRamdisk::builder()
.blobfs(blobfs)
.system_image_merkle(system_image_package.meta_far_merkle_root())
.start()
.unwrap();
let env = TestEnv::builder().pkgfs(pkgfs).build().await;
env.block_until_started().await;
env
}
/// Uses the test environment to retrieve the package iterator.
async fn get_pkg_iterator(env: &TestEnv) -> PackageIndexIteratorProxy {
let (pkg_iterator, server_end) =
fidl::endpoints::create_proxy::<PackageIndexIteratorMarker>().unwrap();
env.proxies.package_cache.base_package_index(server_end).unwrap();
pkg_iterator
}
/// Assert the iterator returns all the expected packages.
async fn assert_base_packages_match(
pkg_iterator: PackageIndexIteratorProxy,
static_packages: &[&Package],
) {
let expected_entries = static_packages.into_iter().map(|pkg| {
let url = format!("fuchsia-pkg://fuchsia.com/{}", pkg.name());
let merkle = pkg.meta_far_merkle_root().clone();
(url, merkle)
});
verify_base_packages_iterator(pkg_iterator, expected_entries).await;
}
async fn verify_base_packages_iterator(
pkg_iterator: PackageIndexIteratorProxy,
mut expected_entries: impl Iterator<Item = (String, Hash)>,
) {
loop {
let chunk = pkg_iterator.next().await.unwrap();
if chunk.is_empty() {
break;
}
for entry in chunk {
let (expected_url, expected_hash) = expected_entries.next().unwrap();
assert_eq!(entry.package_url.url, expected_url);
assert_eq!(BlobId::from(entry.meta_far_blob_id), BlobId::from(expected_hash));
}
}
assert_eq!(expected_entries.next(), None);
}
/// Verifies that no base packages does not start package cache.
#[fasync::run_singlethreaded(test)]
async fn no_base_package_error() {
let pkgfs = PkgfsRamdisk::builder().start().unwrap();
let env = TestEnv::builder().pkgfs(pkgfs).build().await;
let res = env.proxies.package_cache.sync().await;
assert_eq!(res.is_err(), true);
}
/// Verifies that a single base package is handled correctly.
#[fasync::run_singlethreaded(test)]
async fn base_pkg_index_with_one_package() {
let pkg = PackageBuilder::new("base-package-0")
.add_resource_at("resource", &[][..])
.build()
.await
.unwrap();
let env = setup_test_env(&[&pkg]).await;
let pkg_iterator = get_pkg_iterator(&env).await;
assert_base_packages_match(pkg_iterator, &[&pkg]).await;
}
/// Verifies that the internal cache is not re-ordering packages based on sorting.
#[fasync::run_singlethreaded(test)]
async fn base_pkg_index_verify_ordering() {
let pkg_0 = PackageBuilder::new("base-package-zzz")
.add_resource_at("resource", &[][..])
.build()
.await
.unwrap();
let pkg_1 = PackageBuilder::new("aaa-base-package")
.add_resource_at("resource", &[][..])
.build()
.await
.unwrap();
let pkg_2 = PackageBuilder::new("base-package-aaa")
.add_resource_at("resource", &[][..])
.build()
.await
.unwrap();
let env = setup_test_env(&[&pkg_0, &pkg_1, &pkg_2]).await;
let pkg_iterator = get_pkg_iterator(&env).await;
assert_base_packages_match(pkg_iterator, &[&pkg_0, &pkg_1, &pkg_2]).await;
}
/// Verifies that the package index can be split across multiple chunks.
#[fasync::run_singlethreaded(test)]
async fn base_pkg_index_verify_multiple_chunks() {
// Try to get a partial chunk by using an unaligned value, though the server may choose to
// provide fewer entries in a single chunk.
const PACKAGE_INDEX_CHUNK_SIZE_MAX: usize = 818;
let bundle_size = PACKAGE_INDEX_CHUNK_SIZE_MAX * 3 + 1;
let mut system_image = SystemImageBuilder::new();
let mut expected_entries = Vec::with_capacity(bundle_size);
let pkg_0 = PackageBuilder::new("base-package-zzz")
.add_resource_at("resource", &[][..])
.build()
.await
.unwrap();
let hash = *pkg_0.meta_far_merkle_root();
for i in 0..bundle_size {
let name = format!("base-package-{}", i);
let url = format!("fuchsia-pkg://fuchsia.com/{}", name);
let path = PackagePath::from_name_and_variant(name, "0").unwrap();
expected_entries.push((url, hash));
system_image = system_image.static_package(path, hash);
}
let blobfs = BlobfsRamdisk::start().unwrap();
let system_image = system_image.build().await;
system_image.write_to_blobfs_dir(&blobfs.root_dir().unwrap());
pkg_0.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 env = TestEnv::builder().pkgfs(pkgfs).build().await;
let pkg_iterator = get_pkg_iterator(&env).await;
verify_base_packages_iterator(pkg_iterator, expected_entries.into_iter()).await;
}