io_conformance_util/
test_harness.rsuse crate::flags::Rights;
use fidl::endpoints::create_proxy;
use {
fidl_fuchsia_component as fcomponent, fidl_fuchsia_component_decl as fdecl,
fidl_fuchsia_io as fio, fidl_fuchsia_io_test as io_test,
};
pub struct TestHarness {
pub proxy: io_test::TestHarnessProxy,
pub config: io_test::HarnessConfig,
pub dir_rights: Rights,
pub file_rights: Rights,
pub executable_file_rights: Rights,
}
impl TestHarness {
pub async fn new() -> TestHarness {
let proxy = connect_to_harness().await;
let config = proxy.get_config().await.expect("Could not get config from proxy");
if config.supports_modify_directory {
assert!(
config.supports_get_token,
"GetToken must be supported for testing Rename/Link!"
);
}
if config.supports_append {
assert!(config.supports_mutable_file, "Files supporting append must also be mutable.");
}
if config.supports_truncate {
assert!(
config.supports_mutable_file,
"Files supporting truncate must also be mutable."
);
}
let dir_rights = Rights::new(get_supported_dir_rights(&config));
let file_rights = Rights::new(get_supported_file_rights(&config));
let executable_file_rights = Rights::new(fio::Rights::READ_BYTES | fio::Rights::EXECUTE);
TestHarness { proxy, config, dir_rights, file_rights, executable_file_rights }
}
pub fn get_directory(
&self,
entries: Vec<io_test::DirectoryEntry>,
flags: fio::Flags,
) -> fio::DirectoryProxy {
let contents: Vec<Option<Box<io_test::DirectoryEntry>>> =
entries.into_iter().map(|e| Some(Box::new(e))).collect();
let (client, server) = create_proxy::<fio::DirectoryMarker>();
self.proxy
.create_directory(contents, flags, server)
.expect("Cannot get directory from test harness");
client
}
pub async fn open_service_directory(&self) -> fio::DirectoryProxy {
assert!(self.config.supports_services);
let client_end = self.proxy.open_service_directory().await.unwrap();
client_end.into_proxy()
}
pub fn supported_file_abilities(&self) -> fio::Abilities {
let mut abilities = fio::Abilities::READ_BYTES | fio::Abilities::GET_ATTRIBUTES;
if self.config.supports_mutable_file {
abilities |= fio::Abilities::WRITE_BYTES;
}
if self.supports_mutable_attrs() {
abilities |= fio::Abilities::UPDATE_ATTRIBUTES;
}
abilities
}
pub fn supported_dir_abilities(&self) -> fio::Abilities {
if self.config.supports_modify_directory {
fio::Abilities::GET_ATTRIBUTES
| fio::Abilities::UPDATE_ATTRIBUTES
| fio::Abilities::ENUMERATE
| fio::Abilities::TRAVERSE
| fio::Abilities::MODIFY_DIRECTORY
} else {
fio::Abilities::GET_ATTRIBUTES | fio::Abilities::ENUMERATE | fio::Abilities::TRAVERSE
}
}
pub fn supports_mutable_attrs(&self) -> bool {
supports_mutable_attrs(&self.config)
}
}
async fn connect_to_harness() -> io_test::TestHarnessProxy {
let (client, server) = zx::Channel::create();
fuchsia_component::client::connect_channel_to_protocol::<fcomponent::RealmMarker>(server)
.expect("Cannot connect to Realm service");
let realm = fcomponent::RealmSynchronousProxy::new(client);
let child_ref = fdecl::ChildRef { name: "fs_test".to_string(), collection: None };
let (client, server) = zx::Channel::create();
realm
.open_exposed_dir(
&child_ref,
fidl::endpoints::ServerEnd::<fio::DirectoryMarker>::new(server),
zx::MonotonicInstant::INFINITE,
)
.expect("FIDL error when binding to child in Realm")
.expect("Cannot bind to test harness child in Realm");
let exposed_dir = fio::DirectoryProxy::new(fidl::AsyncChannel::from_channel(client));
fuchsia_component::client::connect_to_protocol_at_dir_root::<io_test::TestHarnessMarker>(
&exposed_dir,
)
.expect("Cannot connect to test harness protocol")
}
fn get_supported_dir_rights(config: &io_test::HarnessConfig) -> fio::Rights {
fio::R_STAR_DIR
| fio::W_STAR_DIR
| if config.supports_executable_file { fio::X_STAR_DIR } else { fio::Rights::empty() }
}
fn get_supported_file_rights(config: &io_test::HarnessConfig) -> fio::Rights {
let mut rights = fio::Rights::READ_BYTES | fio::Rights::GET_ATTRIBUTES;
if config.supports_mutable_file {
rights |= fio::Rights::WRITE_BYTES;
}
if supports_mutable_attrs(&config) {
rights |= fio::Rights::WRITE_BYTES;
}
rights
}
fn supports_mutable_attrs(config: &io_test::HarnessConfig) -> bool {
let all_mutable_attrs: fio::NodeAttributesQuery = fio::NodeAttributesQuery::ACCESS_TIME
| fio::NodeAttributesQuery::MODIFICATION_TIME
| fio::NodeAttributesQuery::CREATION_TIME
| fio::NodeAttributesQuery::MODE
| fio::NodeAttributesQuery::GID
| fio::NodeAttributesQuery::UID
| fio::NodeAttributesQuery::RDEV;
if config.supported_attributes.intersects(all_mutable_attrs) {
assert!(
config.supported_attributes.contains(
fio::NodeAttributesQuery::CREATION_TIME
| fio::NodeAttributesQuery::MODIFICATION_TIME
),
"Harnesses must support at least CREATION_TIME if attributes are mutable."
);
return true;
}
false
}