blob: ffc86ee43ff6ca796ad4fe4aed8518b62cc600d5 [file] [log] [blame]
// Copyright 2022 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 assert_matches::assert_matches;
use fidl_fuchsia_io as fio;
use fuchsia_async as fasync;
use fuchsia_fs::node::OpenError;
use fuchsia_zircon_status as zx_status;
use futures::StreamExt;
#[fasync::run_singlethreaded(test)]
async fn component_manager_namespace() {
let nodes = [
"/svc/fuchsia.component.Binder",
"/svc/fuchsia.component.Namespace",
"/svc/fuchsia.component.Realm",
"/svc/fuchsia.component.sandbox.Factory",
"/svc/fuchsia.sys2.LifecycleController",
"/svc/fuchsia.sys2.RouteValidator",
"/svc/fuchsia.sys2.StorageAdmin",
"/svc/fuchsia.sys2.RealmQuery",
"/svc/fuchsia.boot.Arguments",
"/svc/fuchsia.boot.FactoryItems",
"/svc/fuchsia.boot.Items",
"/svc/fuchsia.boot.ReadOnlyLog",
"/svc/fuchsia.boot.RootResource",
"/svc/fuchsia.boot.WriteOnlyLog",
"/svc/fuchsia.inspect.InspectSink",
"/svc/fuchsia.kernel.CpuResource",
"/svc/fuchsia.kernel.DebugResource",
"/svc/fuchsia.kernel.EnergyInfoResource",
"/svc/fuchsia.kernel.FramebufferResource",
"/svc/fuchsia.kernel.HypervisorResource",
"/svc/fuchsia.kernel.InfoResource",
"/svc/fuchsia.kernel.IommuResource",
"/svc/fuchsia.kernel.IrqResource",
"/svc/fuchsia.kernel.MexecResource",
"/svc/fuchsia.kernel.MmioResource",
"/svc/fuchsia.kernel.MsiResource",
"/svc/fuchsia.kernel.PowerResource",
"/svc/fuchsia.kernel.ProfileResource",
"/svc/fuchsia.kernel.RootJob",
"/svc/fuchsia.kernel.RootJobForInspect",
"/svc/fuchsia.kernel.Stats",
"/svc/fuchsia.kernel.VmexResource",
"/svc/fuchsia.logger.LogSink",
"/svc/fuchsia.process.Launcher",
"/svc/fuchsia.sys2.CrashIntrospect",
];
let opens = nodes.iter().map(|node_path| async move {
assert_matches!(
validate_open_with_node_reference_and_describe(node_path).await,
Ok(()),
"Opening capability: {} with DESCRIBE|NODE_REFERENCE did not produce open stream.",
node_path
);
validate_open_with_extra_path_should_fail(node_path).await;
});
let () = futures::future::join_all(opens).await.into_iter().collect();
}
async fn validate_open_with_node_reference_and_describe(path: &str) -> Result<(), OpenError> {
// The Rust VFS defines the only valid call for DESCRIBE on a service node to be one
// that includes the NODE_REFERENCE flag. Component framework aims to adhere to the rust
// VFS implementation of the io protocol.
// TODO(https://fxbug.dev/42055559): If the rust VFS interpretation of the DESCRIBE
// flag behavior on service nodes is incorrect, update this call.
let node = fuchsia_fs::node::open_in_namespace(
path,
fio::OpenFlags::DESCRIBE | fio::OpenFlags::NODE_REFERENCE,
)?;
let mut events = node.take_event_stream();
match events
.next()
.await
.ok_or(OpenError::OnOpenEventStreamClosed)?
.map_err(OpenError::OnOpenDecode)?
{
fio::NodeEvent::OnOpen_ { s: status, info } => {
let () = zx_status::Status::ok(status).map_err(OpenError::OpenError)?;
info.ok_or(OpenError::MissingOnOpenInfo)?;
}
event @ fio::NodeEvent::OnRepresentation { payload: _ } => {
panic!("Compliance test got unexpected event: {:?}", event)
}
}
Ok(())
}
async fn validate_open_with_extra_path_should_fail(path: &str) {
let node =
fuchsia_fs::node::open_in_namespace(&format!("{}/extra", path), fio::OpenFlags::empty())
.unwrap();
let mut events = node.take_event_stream();
let event = events.next().await.unwrap();
event.expect_err("Opening a protocol with a non-empty relative path should fail.");
}