blob: 1ed838fe59346af2cae9b2c2f0743a08a686faf3 [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 anyhow::{format_err, Context as _, Error};
use fasync::Time;
use fidl::endpoints::create_endpoints;
use fidl_fuchsia_lowpan::DeviceWatcherMarker;
use fidl_fuchsia_lowpan_device::{
DeviceConnectorMarker, DeviceExtraConnectorMarker, DeviceExtraMarker, DeviceMarker,
};
use fidl_fuchsia_lowpan_test::{DeviceTestConnectorMarker, DeviceTestMarker};
use fuchsia_async as fasync;
use fuchsia_async::TimeoutExt;
use fuchsia_component::client::connect_to_protocol;
use fuchsia_component_test::ScopedInstanceFactory;
use futures::prelude::*;
const DEFAULT_TIMEOUT: fuchsia_zircon::Duration = fuchsia_zircon::Duration::from_seconds(50);
#[fasync::run_singlethreaded(test)]
async fn test_service_driver_interaction() -> Result<(), Error> {
const IFACE_NAME: &str = "lowpan0";
// Step 1: Get an instance of the DeviceWatcher API and make sure there are no devices registered.
let lookup = connect_to_protocol::<DeviceWatcherMarker>()
.context("Failed to connect to Lowpan DeviceWatcher service")?;
let (added, removed) = lookup
.watch_devices()
.err_into::<Error>()
.on_timeout(Time::after(DEFAULT_TIMEOUT), || {
Err(format_err!("Timeout waiting for lookup.watch_devices()"))
})
.await
.context("Initial call to lookup.watch_devices() failed")?;
assert!(added.is_empty() && removed.is_empty(), "Initial device list not empty");
// Step 2: Start the LoWPAN Dummy Driver
let dummy_driver = ScopedInstanceFactory::new("drivers")
.new_instance("#meta/lowpan-dummy-driver.cm")
.await
.context("creating lowpan dummy driver")?;
dummy_driver.connect_to_binder()?;
// Step 3: Wait to receive an event that the driver has registered.
let (added, removed) = lookup
.watch_devices()
.err_into::<Error>()
.on_timeout(Time::after(DEFAULT_TIMEOUT), || {
Err(format_err!("Timeout waiting for lookup.watch_devices()"))
})
.await
.context("Second call to lookup.watch_devices() failed")?;
assert_eq!(added, vec![IFACE_NAME.to_string()]);
assert_eq!(removed, Vec::<String>::new());
// Step 4: Try to lookup the dummy device via the Lookup API
let (client, server) = create_endpoints::<DeviceMarker>();
let (client_extra, server_extra) = create_endpoints::<DeviceExtraMarker>();
let (client_test, server_test) = create_endpoints::<DeviceTestMarker>();
connect_to_protocol::<DeviceConnectorMarker>()
.context("Failed to connect to DeviceConnector")?
.connect(IFACE_NAME, server)?;
connect_to_protocol::<DeviceExtraConnectorMarker>()
.context("Failed to connect to DeviceExtraConnector")?
.connect(IFACE_NAME, server_extra)?;
connect_to_protocol::<DeviceTestConnectorMarker>()
.context("Failed to connect to DeviceTestConnector")?
.connect(IFACE_NAME, server_test)?;
let device = client.into_proxy()?;
let device_extra = client_extra.into_proxy()?;
let device_test = client_test.into_proxy()?;
// Step 5: Interact with the device to make sure it is responsive.
let ncp_version = device_test
.get_ncp_version()
.map_err(|e| format_err!("Err: {:?}", e))
.on_timeout(Time::after(DEFAULT_TIMEOUT), || Err(format_err!("Timeout")))
.await
.context("Call to get_ncp_version failed")?;
println!("Got NCP Version: {:?}", ncp_version);
// Step 5b: Check a method from each protocol to make sure they are all working.
assert!(device.leave_network().await.is_ok());
assert!(device_extra.watch_identity().await.is_ok());
assert!(device_test.get_ncp_version().await.is_ok());
// Step 6: Kill the driver.
drop(dummy_driver);
// Step 7: Make sure that the service doesn't have the device anymore.
let (added, removed) = lookup
.watch_devices()
.err_into::<Error>()
.on_timeout(Time::after(DEFAULT_TIMEOUT), || {
Err(format_err!("Timeout waiting for lookup.get_devices()"))
})
.await
.context("Second call to lookup.watch_devices() failed")?;
assert_eq!(added, Vec::<String>::new());
assert_eq!(removed, vec![IFACE_NAME.to_string()]);
// Step 8: Make sure that the endpoints are dead.
assert!(
device.leave_network().await.is_err(),
"Driver killed, but leave_network() still worked!?"
);
assert!(
device_test.get_ncp_version().await.is_err(),
"Driver killed, but get_ncp_version() still worked!?"
);
Ok(())
}