// 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::{self, Context},
    argh::FromArgs,
    fidl::endpoints::{create_proxy, ClientEnd, Proxy},
    fidl_fuchsia_io::{self as fio, DirectoryMarker, DirectoryProxy},
    fidl_fuchsia_mem as fmem,
    fidl_fuchsia_pkg::{PackageResolverMarker, PackageResolverProxy},
    fidl_fuchsia_sys2::{
        self as fsys, ComponentResolverMarker, ComponentResolverRequest,
        ComponentResolverRequestStream,
    },
    fuchsia_component::{client::connect_to_service, server::ServiceFs},
    fuchsia_url::{errors::ParseError as PkgUrlParseError, pkg_url::PkgUrl},
    fuchsia_zircon::Status,
    futures::prelude::*,
    log::*,
    thiserror::Error,
};

#[derive(FromArgs, Debug)]
#[argh(description = "Controls for universe resolver")]
struct Args {
    #[argh(
        switch,
        description = "if true the fuchsia.pkg.PkgResolver protocol provided to \
        this component is used, otherwise the fuchsia.sys2.ComponentResolver \
        protocol (assumed to come from base-resolver) is used"
    )]
    enable_ephemeral_components: bool,
}

#[fuchsia::component]
async fn main() -> anyhow::Result<()> {
    info!("started");
    let args: Args = argh::from_env();
    let mut service_fs = ServiceFs::new_local();
    service_fs.dir("svc").add_fidl_service(|stream: ComponentResolverRequestStream| stream);
    service_fs.take_and_serve_directory_handle().context("failed to serve outgoing namespace")?;
    service_fs
        .for_each_concurrent(None, |stream| {
            let all = args.enable_ephemeral_components;
            async move {
                let r = if all { serve(stream).await } else { forward_to_base(stream).await };

                match r {
                    Ok(()) => {}
                    Err(err) => error!("failed to serve resolve request: {:?}", err),
                }
            }
        })
        .await;

    Ok(())
}

async fn forward_to_base(mut stream: ComponentResolverRequestStream) -> anyhow::Result<()> {
    let base_resolver = connect_to_service::<ComponentResolverMarker>()
        .context("failed to connect to base package resolver")?;

    while let Some(ComponentResolverRequest::Resolve { component_url, responder }) =
        stream.try_next().await.context("failed to read request from FIDL stream")?
    {
        match base_resolver.resolve(&component_url).await {
            Ok(Ok(r)) => responder.send(&mut Ok(r)),
            Ok(Err(e)) => responder.send(&mut Err(e)),
            Err(err) => {
                info!("universe resolver got FIDL error forward request to base resolver for component URL {}: {}", &component_url, &err);
                responder.send(&mut Err(fsys::ResolverError::Internal))
            }
        }
        .context("failed to send response")?;
    }
    Ok(())
}

async fn serve(mut stream: ComponentResolverRequestStream) -> anyhow::Result<()> {
    let package_resolver = connect_to_service::<PackageResolverMarker>()
        .context("failed to connect to PackageResolver service")?;
    while let Some(ComponentResolverRequest::Resolve { component_url, responder }) =
        stream.try_next().await.context("failed to read request from FIDL stream")?
    {
        match resolve_component(&component_url, &package_resolver).await {
            Ok(result) => responder.send(&mut Ok(result)),
            Err(err) => {
                info!("failed to resolve component URL {}: {}", &component_url, &err);
                responder.send(&mut Err(err.into()))
            }
        }
        .context("failed sending response")?;
    }
    Ok(())
}

async fn resolve_component(
    component_url: &str,
    package_resolver: &PackageResolverProxy,
) -> Result<fsys::Component, ResolverError> {
    let package_url = PkgUrl::parse(component_url)?;
    let cm_path = package_url
        .resource()
        .ok_or_else(|| ResolverError::InvalidUrl(PkgUrlParseError::InvalidResourcePath))?;
    let package_dir = resolve_package(&package_url, package_resolver).await?;

    // Read the component manifest (.cm file) from the package directory.
    let cm_file = io_util::directory::open_file(&package_dir, cm_path, fio::OPEN_RIGHT_READABLE)
        .await
        .map_err(ResolverError::ComponentNotFound)?;

    let (status, buffer) =
        cm_file.get_buffer(fio::VMO_FLAG_READ).await.map_err(ResolverError::IoError)?;
    Status::ok(status).map_err(ResolverError::VmoFailure)?;
    let data = match buffer {
        Some(buffer) => fmem::Data::Buffer(*buffer),
        None => fmem::Data::Bytes(
            io_util::file::read(&cm_file).await.map_err(ResolverError::ReadManifest)?,
        ),
    };

    let package_dir = ClientEnd::new(
        package_dir.into_channel().expect("could not convert proxy to channel").into_zx_channel(),
    );
    Ok(fsys::Component {
        resolved_url: Some(component_url.into()),
        decl: Some(data),
        package: Some(fsys::Package {
            package_url: Some(package_url.root_url().to_string()),
            package_dir: Some(package_dir),
            ..fsys::Package::EMPTY
        }),
        ..fsys::Component::EMPTY
    })
}

async fn resolve_package(
    package_url: &PkgUrl,
    package_resolver: &PackageResolverProxy,
) -> Result<DirectoryProxy, ResolverError> {
    let package_url = package_url.root_url();
    let selectors = Vec::new();
    let (proxy, server_end) =
        create_proxy::<DirectoryMarker>().expect("failed to create channel pair");
    package_resolver
        .resolve(&package_url.to_string(), &mut selectors.into_iter(), server_end)
        .await
        .map_err(ResolverError::IoError)?
        .map_err(Status::from_raw)
        .map_err(|err| match err {
            Status::NOT_FOUND => ResolverError::PackageNotFound,
            Status::ADDRESS_UNREACHABLE | Status::UNAVAILABLE => ResolverError::Unavailable,
            Status::NO_SPACE => ResolverError::NoSpace,
            _ => ResolverError::Internal,
        })?;
    Ok(proxy)
}

#[derive(Error, Debug)]
enum ResolverError {
    #[error("an unexpected error ocurred")]
    Internal,
    #[error("invalid component URL: {}", .0)]
    InvalidUrl(#[from] PkgUrlParseError),
    #[error("component not found: {}", .0)]
    ComponentNotFound(#[source] io_util::node::OpenError),
    #[error("package not found")]
    PackageNotFound,
    #[error("read manifest error: {}", .0)]
    ReadManifest(#[source] io_util::file::ReadError),
    #[error("IO error: {}", .0)]
    IoError(#[source] fidl::Error),
    #[error("failed to get manifest VMO: {}", .0)]
    VmoFailure(#[source] Status),
    #[error("insufficient space to store package")]
    NoSpace,
    #[error("the component's package is temporarily unavailable")]
    Unavailable,
}

impl From<ResolverError> for fsys::ResolverError {
    fn from(err: ResolverError) -> fsys::ResolverError {
        match err {
            ResolverError::Internal => fsys::ResolverError::Internal,
            ResolverError::InvalidUrl(_) => fsys::ResolverError::InvalidArgs,
            ResolverError::ComponentNotFound(_) => fsys::ResolverError::ManifestNotFound,
            ResolverError::PackageNotFound => fsys::ResolverError::PackageNotFound,
            ResolverError::ReadManifest(_)
            | ResolverError::VmoFailure(_)
            | ResolverError::IoError(_) => fsys::ResolverError::Io,
            ResolverError::NoSpace => fsys::ResolverError::NoSpace,
            ResolverError::Unavailable => fsys::ResolverError::ResourceUnavailable,
        }
    }
}

#[cfg(test)]
mod tests {
    use {
        super::*,
        anyhow::Error,
        fidl::{encoding::encode_persistent, endpoints::ServerEnd},
        fidl_fuchsia_mem,
        fidl_fuchsia_pkg::{self as fpkg, PackageResolverRequest},
        fidl_fuchsia_sys2::{self as fsys, ComponentResolverMarker},
        fuchsia_async as fasync,
        fuchsia_component::server as fserver,
        fuchsia_component_test::{
            builder::{Capability, CapabilityRoute, ComponentSource, RealmBuilder, RouteEndpoint},
            mock::{Mock, MockHandles},
        },
        fuchsia_zircon as zx,
        fuchsia_zircon::Vmo,
        futures::{channel::mpsc, join, lock::Mutex},
        matches::assert_matches,
        std::{boxed::Box, sync::Arc},
        vfs::{
            directory::entry::DirectoryEntry,
            execution_scope::ExecutionScope,
            file::{vmo::asynchronous::read_only_static, vmo::asynchronous::NewVmo},
            path::Path,
            pseudo_directory,
        },
    };

    async fn mock_pkg_resolver(
        trigger: Arc<Mutex<Option<mpsc::Sender<Result<(), Error>>>>>,
        handles: MockHandles,
    ) -> Result<(), Error> {
        let mut fs = fserver::ServiceFs::new();
        fs.dir("svc").add_fidl_service(
            move |mut req_stream: fpkg::PackageResolverRequestStream| {
                let tx = trigger.clone();
                fasync::Task::local(async move {
                    while let Some(fpkg::PackageResolverRequest::Resolve { responder, .. }) =
                        req_stream.try_next().await.expect("Serving package resolver stream failed")
                    {
                        responder
                            .send(&mut Err(zx::Status::NOT_FOUND.into_raw()))
                            .expect("failed sending package resolver response to client");

                        {
                            let mut lock = tx.lock().await;
                            let mut c = lock.take().unwrap();
                            c.send(Ok(())).await.expect("failed sending oneshot to test");
                            lock.replace(c);
                        }
                    }
                })
                .detach();
            },
        );

        fs.serve_connection(handles.outgoing_dir.into_channel())?;
        fs.collect::<()>().await;
        Ok(())
    }

    async fn package_requester(
        trigger: Arc<Mutex<Option<mpsc::Sender<Result<(), Error>>>>>,
        url: String,
        handles: MockHandles,
    ) -> Result<(), Error> {
        let resolver_proxy = handles.connect_to_service::<ComponentResolverMarker>()?;
        let _ = resolver_proxy.resolve(&url).await?;
        fasync::Task::local(async move {
            let mut lock = trigger.lock().await;
            let mut c = lock.take().unwrap();
            c.send(Ok(())).await.expect("sending oneshot from package requester failed");
            lock.replace(c);
        })
        .detach();
        Ok(())
    }

    #[fasync::run_singlethreaded(test)]
    // Test that the default configuration which forwards requests to
    // PackageResolver works properly.
    async fn test_using_pkg_resolver() {
        let (sender, mut receiver) = mpsc::channel(2);
        let tx = Arc::new(Mutex::new(Some(sender)));
        let resolver_url =
            "fuchsia-pkg://fuchsia.com/universe-resolver-unittests#meta/universe-resolver-for-test.cm"
                .to_string();
        let requested_url =
            "fuchsia-pkg://fuchsia.com/test-pkg-request#meta/test-component.cm".to_string();
        let mut builder = RealmBuilder::new().await.expect("Failed to create test realm builder");
        builder
            .add_component("universe-resolver", ComponentSource::url(resolver_url))
            .await
            .expect("Failed add universe-resolver to test topology")
            .add_component(
                "fake-pkg-resolver",
                ComponentSource::Mock(Mock::new({
                    let sender = tx.clone();
                    move |mock_handles: MockHandles| {
                        Box::pin(mock_pkg_resolver(sender.clone(), mock_handles))
                    }
                })),
            )
            .await
            .expect("Failed adding base resolver mock")
            .add_eager_component(
                "requesting-component",
                ComponentSource::Mock(Mock::new({
                    let sender = tx.clone();
                    move |mock_handles: MockHandles| {
                        Box::pin(package_requester(
                            sender.clone(),
                            requested_url.clone(),
                            mock_handles,
                        ))
                    }
                })),
            )
            .await
            .expect("Failed adding mock request component")
            .add_route(CapabilityRoute {
                capability: Capability::protocol("fuchsia.pkg.PackageResolver"),
                source: RouteEndpoint::component("fake-pkg-resolver"),
                targets: vec![RouteEndpoint::component("universe-resolver")],
            })
            .expect("Failed adding resolver route from fake-base-resolver to universe-resolver")
            .add_route(CapabilityRoute {
                capability: Capability::protocol("fuchsia.sys2.ComponentResolver"),
                source: RouteEndpoint::component("universe-resolver"),
                targets: vec![RouteEndpoint::component("requesting-component")],
            })
            .expect("Failed adding resolver route from universe-resolver to requesting-component")
            .add_route(CapabilityRoute {
                capability: Capability::protocol("fuchsia.logger.LogSink"),
                source: RouteEndpoint::AboveRoot,
                targets: vec![
                    RouteEndpoint::component("universe-resolver"),
                    RouteEndpoint::component("fake-pkg-resolver"),
                    RouteEndpoint::component("requesting-component"),
                ],
            })
            .expect("Failed adding LogSink route to test components");
        let _test_topo = builder.build().create().await.unwrap();

        receiver.next().await.expect("Unexpected error waiting for response").expect("error sent");
        receiver.next().await.expect("Unexpected error waiting for response").expect("error sent");
    }

    async fn mock_base_resolver(
        trigger: Arc<Mutex<Option<mpsc::Sender<Result<(), Error>>>>>,
        handles: MockHandles,
    ) -> Result<(), Error> {
        let mut fs = fserver::ServiceFs::new();
        fs.dir("svc").add_fidl_service(
            move |mut req_stream: fsys::ComponentResolverRequestStream| {
                let tx = trigger.clone();
                fasync::Task::local(async move {
                    while let Some(fsys::ComponentResolverRequest::Resolve { responder, .. }) =
                        req_stream
                            .try_next()
                            .await
                            .expect("Serving component resolver stream failed")
                    {
                        responder
                            .send(&mut Err(fsys::ResolverError::PackageNotFound))
                            .expect("failed sending resolve response to client");

                        {
                            let mut lock = tx.lock().await;
                            let mut c = lock.take().unwrap();
                            c.send(Ok(())).await.expect("failed sending oneshot to test");
                            lock.replace(c);
                        }
                    }
                })
                .detach();
            },
        );

        fs.serve_connection(handles.outgoing_dir.into_channel())?;
        fs.collect::<()>().await;
        Ok(())
    }

    #[fasync::run_singlethreaded(test)]
    // Test configuration where use of package resolver is disabled and
    // requests are forwarded to the base resolver.
    async fn test_using_base_resolver() {
        let (sender, mut receiver) = mpsc::channel(2);
        let tx = Arc::new(Mutex::new(Some(sender)));
        let resolver_url =
            "fuchsia-pkg://fuchsia.com/universe-resolver-unittests#meta/universe-resolver-base-only-for-test.cm"
                .to_string();
        let requested_url =
            "fuchsia-pkg://fuchsia.com/test-pkg-request#meta/test-component.cm".to_string();
        let mut builder = RealmBuilder::new().await.expect("Failed to create test realm builder");
        builder
            .add_component("universe-resolver", ComponentSource::url(resolver_url))
            .await
            .expect("Failed add universe-resolver to test topology")
            .add_component(
                "fake-base-resolver",
                ComponentSource::Mock(Mock::new({
                    let sender = tx.clone();
                    move |mock_handles: MockHandles| {
                        Box::pin(mock_base_resolver(sender.clone(), mock_handles))
                    }
                })),
            )
            .await
            .expect("Failed adding base resolver mock")
            .add_eager_component(
                "requesting-component",
                ComponentSource::Mock(Mock::new({
                    let sender = tx.clone();
                    move |mock_handles: MockHandles| {
                        Box::pin(package_requester(
                            sender.clone(),
                            requested_url.clone(),
                            mock_handles,
                        ))
                    }
                })),
            )
            .await
            .expect("Failed adding mock request component")
            .add_route(CapabilityRoute {
                capability: Capability::protocol("fuchsia.sys2.ComponentResolver"),
                source: RouteEndpoint::component("fake-base-resolver"),
                targets: vec![RouteEndpoint::component("universe-resolver")],
            })
            .expect("Failed adding resolver route from fake-base-resolver to universe-resolver")
            .add_route(CapabilityRoute {
                capability: Capability::protocol("fuchsia.sys2.ComponentResolver"),
                source: RouteEndpoint::component("universe-resolver"),
                targets: vec![RouteEndpoint::component("requesting-component")],
            })
            .expect("Failed adding resolver route from universe-resolver to requesting-component")
            .add_route(CapabilityRoute {
                capability: Capability::protocol("fuchsia.logger.LogSink"),
                source: RouteEndpoint::AboveRoot,
                targets: vec![
                    RouteEndpoint::component("universe-resolver"),
                    RouteEndpoint::component("fake-base-resolver"),
                    RouteEndpoint::component("requesting-component"),
                ],
            })
            .expect("Failed adding LogSink route to test components");
        let _test_topo = builder.build().create().await.unwrap();

        receiver.next().await.expect("Unexpected error waiting for response").expect("error sent");
        receiver.next().await.expect("Unexpected error waiting for response").expect("error sent");
    }

    #[fuchsia::test]
    async fn resolve_package_succeeds() {
        let (proxy, mut server) =
            fidl::endpoints::create_proxy_and_stream::<PackageResolverMarker>().unwrap();
        let server = async move {
            let fs = pseudo_directory! {
                "test_file" => read_only_static(b"foo"),
            };
            while let Some(request) = server.try_next().await.unwrap() {
                match request {
                    PackageResolverRequest::Resolve { package_url, selectors, dir, responder } => {
                        assert_eq!(
                            package_url, "fuchsia-pkg://fuchsia.com/test",
                            "unexpected package URL"
                        );
                        assert!(
                            selectors.is_empty(),
                            "Call to Resolve should not contain any selectors"
                        );
                        fs.clone().open(
                            ExecutionScope::new(),
                            fio::OPEN_RIGHT_READABLE,
                            fio::MODE_TYPE_DIRECTORY,
                            Path::empty(),
                            ServerEnd::new(dir.into_channel()),
                        );
                        responder.send(&mut Ok(())).unwrap();
                    }
                    _ => panic!("unexpected API call"),
                }
            }
        };
        let client = async move {
            let result = resolve_package(
                &PkgUrl::new_package("fuchsia.com".into(), "/test".into(), None).unwrap(),
                &proxy,
            )
            .await;
            let directory = result.expect("package resolver failed unexpectedly");
            let file =
                io_util::directory::open_file(&directory, "test_file", fio::OPEN_RIGHT_READABLE)
                    .await
                    .expect("failed to open 'test_file' from package resolver directory");
            let contents = io_util::file::read(&file)
                .await
                .expect("failed to read 'test_file' contents from package resolver directory");
            assert_eq!(&contents, b"foo");
        };
        join!(server, client);
    }

    #[fuchsia::test]
    async fn resolve_component_succeeds() {
        let (proxy, mut server) =
            fidl::endpoints::create_proxy_and_stream::<PackageResolverMarker>().unwrap();
        let server = async move {
            let cm_bytes = encode_persistent(&mut fsys::ComponentDecl::EMPTY.clone())
                .expect("failed to encode ComponentDecl FIDL");
            let fs = pseudo_directory! {
                "meta" => pseudo_directory!{
                    "test.cm" => read_only_static(cm_bytes),
                },
            };
            while let Some(request) = server.try_next().await.unwrap() {
                match request {
                    PackageResolverRequest::Resolve { package_url, selectors, dir, responder } => {
                        assert_eq!(
                            package_url, "fuchsia-pkg://fuchsia.com/test",
                            "unexpected package URL"
                        );
                        assert!(
                            selectors.is_empty(),
                            "Call to Resolve should not contain any selectors"
                        );
                        fs.clone().open(
                            ExecutionScope::new(),
                            fio::OPEN_RIGHT_READABLE,
                            fio::MODE_TYPE_DIRECTORY,
                            Path::empty(),
                            ServerEnd::new(dir.into_channel()),
                        );
                        responder.send(&mut Ok(())).unwrap();
                    }
                    _ => panic!("unexpected API call"),
                }
            }
        };
        let client = async move {
            assert_matches!(
                resolve_component("fuchsia-pkg://fuchsia.com/test#meta/test.cm", &proxy).await,
                Ok(fsys::Component {
                    decl: Some(fidl_fuchsia_mem::Data::Buffer(fidl_fuchsia_mem::Buffer { .. })),
                    ..
                })
            );
        };
        join!(server, client);
    }

    #[fuchsia::test]
    async fn resolve_component_succeeds_with_hash() {
        let (proxy, mut server) =
            fidl::endpoints::create_proxy_and_stream::<PackageResolverMarker>().unwrap();
        let server = async move {
            let cm_bytes = encode_persistent(&mut fsys::ComponentDecl::EMPTY.clone())
                .expect("failed to encode ComponentDecl FIDL");
            let fs = pseudo_directory! {
                "meta" => pseudo_directory!{
                    "test.cm" => read_only_static(cm_bytes),
                },
            };
            while let Some(request) = server.try_next().await.unwrap() {
                match request {
                    PackageResolverRequest::Resolve { package_url, selectors, dir, responder } => {
                        assert_eq!(package_url, "fuchsia-pkg://fuchsia.com/test?hash=9e3a3f63c018e2a4db0ef93903a87714f036e3e8ff982a7a2020eca86cc4677c", "unexpected package URL");
                        assert!(
                            selectors.is_empty(),
                            "Call to Resolve should not contain any selectors"
                        );
                        fs.clone().open(
                            ExecutionScope::new(),
                            fio::OPEN_RIGHT_READABLE,
                            fio::MODE_TYPE_DIRECTORY,
                            Path::empty(),
                            ServerEnd::new(dir.into_channel()),
                        );
                        responder.send(&mut Ok(())).unwrap();
                    }
                    _ => panic!("unexpected API call"),
                }
            }
        };
        let client = async move {
            assert_matches!(resolve_component("fuchsia-pkg://fuchsia.com/test?hash=9e3a3f63c018e2a4db0ef93903a87714f036e3e8ff982a7a2020eca86cc4677c#meta/test.cm", &proxy).await, Ok(_));
        };
        join!(server, client);
    }

    #[fuchsia::test]
    async fn resolve_component_succeeds_with_vmo_manifest() {
        let (proxy, mut server) =
            fidl::endpoints::create_proxy_and_stream::<PackageResolverMarker>().unwrap();
        let server = async move {
            let fs = pseudo_directory! {
                "meta" => pseudo_directory!{
                    "test.cm" => vfs::file::vmo::read_only(|| async move {
                        let cm_bytes = encode_persistent(&mut fsys::ComponentDecl::EMPTY.clone())
                            .expect("failed to encode ComponentDecl FIDL");
                        let capacity = cm_bytes.len() as u64;
                        let vmo = Vmo::create(capacity)?;
                        Ok(NewVmo { vmo, size: capacity, capacity })
                    }),
                },
            };
            while let Some(request) = server.try_next().await.unwrap() {
                match request {
                    PackageResolverRequest::Resolve { dir, responder, .. } => {
                        fs.clone().open(
                            ExecutionScope::new(),
                            fio::OPEN_RIGHT_READABLE,
                            fio::MODE_TYPE_DIRECTORY,
                            Path::empty(),
                            ServerEnd::new(dir.into_channel()),
                        );
                        responder.send(&mut Ok(())).unwrap();
                    }
                    _ => panic!("unexpected API call"),
                }
            }
        };
        let client = async move {
            assert_matches!(
                resolve_component("fuchsia-pkg://fuchsia.com/test#meta/test.cm", &proxy).await,
                Ok(fsys::Component { decl: Some(fmem::Data::Buffer(_)), .. })
            );
        };
        join!(server, client);
    }

    #[fuchsia::test]
    async fn resolve_component_fails_bad_connection() {
        let (proxy, server) =
            fidl::endpoints::create_proxy_and_stream::<PackageResolverMarker>().unwrap();
        drop(server);
        assert_matches!(
            resolve_component("fuchsia-pkg://fuchsia.com/test#meta/test.cm", &proxy).await,
            Err(ResolverError::IoError(_))
        );
    }

    #[fuchsia::test]
    async fn resolve_component_fails_with_package_resolver_failure() {
        let (proxy, mut server) =
            fidl::endpoints::create_proxy_and_stream::<PackageResolverMarker>().unwrap();
        let server = async move {
            while let Some(request) = server.try_next().await.unwrap() {
                match request {
                    PackageResolverRequest::Resolve { responder, .. } => {
                        responder.send(&mut Err(Status::NO_SPACE.into_raw())).unwrap();
                    }
                    _ => panic!("unexpected API call"),
                }
            }
        };
        let client = async move {
            assert_matches!(
                resolve_component("fuchsia-pkg://fuchsia.com/test#meta/test.cm", &proxy).await,
                Err(ResolverError::NoSpace)
            );
        };
        join!(server, client);
    }

    #[fuchsia::test]
    async fn resolve_component_fails_with_component_not_found() {
        let (proxy, mut server) =
            fidl::endpoints::create_proxy_and_stream::<PackageResolverMarker>().unwrap();
        let server = async move {
            let fs = pseudo_directory! {};
            while let Some(request) = server.try_next().await.unwrap() {
                match request {
                    PackageResolverRequest::Resolve { dir, responder, .. } => {
                        fs.clone().open(
                            ExecutionScope::new(),
                            fio::OPEN_RIGHT_READABLE,
                            fio::MODE_TYPE_DIRECTORY,
                            Path::empty(),
                            ServerEnd::new(dir.into_channel()),
                        );
                        responder.send(&mut Ok(())).unwrap();
                    }
                    _ => panic!("unexpected API call"),
                }
            }
        };
        let client = async move {
            assert_matches!(
                resolve_component("fuchsia-pkg://fuchsia.com/test#meta/test.cm", &proxy).await,
                Err(ResolverError::ComponentNotFound(_))
            );
        };
        join!(server, client);
    }
}
