blob: ff11ee46b8276efe061a041c2e424c4dd7509250 [file] [log] [blame]
// Copyright 2023 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::{Context, Result};
use fidl::endpoints::Proxy as _;
use fuchsia_component_test::{RealmBuilder, RealmInstance};
use fuchsia_driver_test::{DriverTestRealmBuilder, DriverTestRealmInstance};
use {
fidl_fuchsia_driver_test as fdt, fidl_fuchsia_rebind_test as frt, fuchsia_async as fasync,
fuchsia_zircon as zx,
};
async fn start_driver_test_realm() -> Result<RealmInstance> {
const ROOT_DRIVER_URL: &str = "fuchsia-boot:///dtr#meta/test-parent-sys.cm";
let builder = RealmBuilder::new().await.context("Failed to create realm builder")?;
builder.driver_test_realm_setup().await.context("Failed to setup driver test realm")?;
let instance = builder.build().await.context("Failed to build realm instance")?;
let mut realm_args = fdt::RealmArgs::default();
realm_args.root_driver = Some(ROOT_DRIVER_URL.to_owned());
instance
.driver_test_realm_start(realm_args)
.await
.context("Failed to start driver test realm")?;
Ok(instance)
}
const PARENT_DEV_PATH: &str = "sys/test/rebind-parent";
const CHILD_DEV_PATH: &str = "sys/test/rebind-parent/added-child/rebind-child";
// Tests that a node will succesfully bind to a driver after the node has
// already been bound to that driver, then shutdown, then re-added.
#[fasync::run_singlethreaded(test)]
async fn test_rebind() -> Result<()> {
let instance = start_driver_test_realm().await?;
let dev = instance.driver_test_realm_connect_to_dev()?;
let parent =
device_watcher::recursive_wait_and_open::<frt::RebindParentMarker>(&dev, PARENT_DEV_PATH)
.await?;
parent.add_child().await?.map_err(|e| zx::Status::from_raw(e))?;
let child_controller =
device_watcher::recursive_wait_and_open::<fidl_fuchsia_device::ControllerMarker>(
&dev,
&format!("{}/{}", CHILD_DEV_PATH, fidl_fuchsia_device_fs::DEVICE_CONTROLLER_NAME),
)
.await?;
parent.remove_child().await?.map_err(|e| zx::Status::from_raw(e))?;
child_controller.on_closed().await?;
parent.add_child().await?.map_err(|e| zx::Status::from_raw(e))?;
device_watcher::recursive_wait(&dev, CHILD_DEV_PATH).await?;
Ok(())
}