blob: b8b800720c2b2783e4a85b25ec5727d1757c3591 [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,
fidl::endpoints::create_proxy,
fidl_fuchsia_io as fio, fuchsia_zircon as zx,
futures::TryStreamExt as _,
io_conformance_util::{flags::Rights, test_harness::TestHarness, *},
};
#[fuchsia::test]
async fn clone_file_with_same_or_fewer_rights() {
let harness = TestHarness::new().await;
for file_flags in harness.file_rights.valid_combos() {
let root = root_directory(vec![file(TEST_FILE, vec![])]);
let test_dir = harness.get_directory(root, harness.dir_rights.all());
let file = open_file_with_flags(&test_dir, file_flags, TEST_FILE).await;
// Clone using every subset of flags.
for clone_flags in Rights::new(file_flags).valid_combos() {
let (proxy, server) = create_proxy::<fio::NodeMarker>().expect("create_proxy failed");
file.clone(clone_flags | fio::OpenFlags::DESCRIBE, server).expect("clone failed");
let status = get_open_status(&proxy).await;
assert_eq!(status, zx::Status::OK);
// Check flags of cloned connection are correct.
let proxy = convert_node_proxy::<fio::FileProxy>(proxy);
let (status, flags) = proxy.get_flags().await.expect("get_flags failed");
assert_eq!(zx::Status::from_raw(status), zx::Status::OK);
assert_eq!(flags, clone_flags);
}
}
}
#[fuchsia::test]
async fn clone_file_with_same_rights_flag() {
let harness = TestHarness::new().await;
for file_flags in harness.file_rights.valid_combos() {
let root = root_directory(vec![file(TEST_FILE, vec![])]);
let test_dir = harness.get_directory(root, harness.dir_rights.all());
let file = open_file_with_flags(&test_dir, file_flags, TEST_FILE).await;
// Clone using CLONE_FLAG_SAME_RIGHTS.
let (proxy, server) = create_proxy::<fio::NodeMarker>().expect("create_proxy failed");
file.clone(fio::OpenFlags::CLONE_SAME_RIGHTS | fio::OpenFlags::DESCRIBE, server)
.expect("clone failed");
let status = get_open_status(&proxy).await;
assert_eq!(status, zx::Status::OK);
// Check flags of cloned connection are correct.
let proxy = convert_node_proxy::<fio::FileProxy>(proxy);
let (status, flags) = proxy.get_flags().await.expect("get_flags failed");
assert_eq!(zx::Status::from_raw(status), zx::Status::OK);
assert_eq!(flags, file_flags);
}
}
#[fuchsia::test]
async fn clone_file_with_additional_rights() {
let harness = TestHarness::new().await;
for file_flags in harness.file_rights.valid_combos() {
let root = root_directory(vec![file(TEST_FILE, vec![])]);
let test_dir = harness.get_directory(root, harness.dir_rights.all());
let file = open_file_with_flags(&test_dir, file_flags, TEST_FILE).await;
// Clone using every superset of flags, should fail.
for clone_flags in harness.file_rights.valid_combos_with(file_flags) {
if clone_flags == file_flags {
continue;
}
let (proxy, server) = create_proxy::<fio::NodeMarker>().expect("create_proxy failed");
file.clone(clone_flags | fio::OpenFlags::DESCRIBE, server).expect("clone failed");
let status = get_open_status(&proxy).await;
assert_eq!(status, zx::Status::ACCESS_DENIED);
}
}
}
#[fuchsia::test]
async fn clone_directory_with_same_or_fewer_rights() {
let harness = TestHarness::new().await;
for dir_flags in harness.dir_rights.valid_combos() {
let root = root_directory(vec![directory("dir", vec![])]);
let test_dir = harness.get_directory(root, harness.dir_rights.all());
let dir = open_dir_with_flags(&test_dir, dir_flags, "dir").await;
// Clone using every subset of flags.
for clone_flags in Rights::new(dir_flags).valid_combos() {
let (proxy, server) = create_proxy::<fio::NodeMarker>().expect("create_proxy failed");
dir.clone(clone_flags | fio::OpenFlags::DESCRIBE, server).expect("clone failed");
let status = get_open_status(&proxy).await;
assert_eq!(status, zx::Status::OK);
// Check flags of cloned connection are correct.
let (status, flags) = proxy.get_flags().await.expect("get_flags failed");
assert_eq!(zx::Status::from_raw(status), zx::Status::OK);
assert_eq!(flags, clone_flags);
}
}
}
#[fuchsia::test]
async fn clone_directory_with_same_rights_flag() {
let harness = TestHarness::new().await;
for dir_flags in harness.dir_rights.valid_combos() {
let root = root_directory(vec![directory("dir", vec![])]);
let test_dir = harness.get_directory(root, harness.dir_rights.all());
let dir = open_dir_with_flags(&test_dir, dir_flags, "dir").await;
// Clone using CLONE_FLAG_SAME_RIGHTS.
let (proxy, server) = create_proxy::<fio::NodeMarker>().expect("create_proxy failed");
dir.clone(fio::OpenFlags::CLONE_SAME_RIGHTS | fio::OpenFlags::DESCRIBE, server)
.expect("clone failed");
let status = get_open_status(&proxy).await;
assert_eq!(status, zx::Status::OK);
// Check flags of cloned connection are correct.
let proxy = convert_node_proxy::<fio::DirectoryProxy>(proxy);
let (status, flags) = proxy.get_flags().await.expect("get_flags failed");
assert_eq!(zx::Status::from_raw(status), zx::Status::OK);
assert_eq!(flags, dir_flags);
}
}
#[fuchsia::test]
async fn clone_directory_with_additional_rights() {
let harness = TestHarness::new().await;
for dir_flags in harness.dir_rights.valid_combos() {
let root = root_directory(vec![directory("dir", vec![])]);
let test_dir = harness.get_directory(root, harness.dir_rights.all());
let dir = open_dir_with_flags(&test_dir, dir_flags, "dir").await;
// Clone using every superset of flags, should fail.
for clone_flags in harness.dir_rights.valid_combos_with(dir_flags) {
if clone_flags == dir_flags {
continue;
}
let (proxy, server) = create_proxy::<fio::NodeMarker>().expect("create_proxy failed");
dir.clone(clone_flags | fio::OpenFlags::DESCRIBE, server).expect("clone failed");
let status = get_open_status(&proxy).await;
assert_eq!(status, zx::Status::ACCESS_DENIED);
}
}
}
#[fuchsia::test]
async fn reopen_file_unsupported() {
let harness = TestHarness::new().await;
let root = root_directory(vec![file(TEST_FILE, vec![])]);
let test_dir = harness.get_directory(root, harness.dir_rights.all());
let file_proxy =
open_file_with_flags(&test_dir, fio::OpenFlags::RIGHT_READABLE, TEST_FILE).await;
// fuchsia.io/Node.Reopen
let (reopen_proxy, reopen_server) = fidl::endpoints::create_proxy::<fio::NodeMarker>().unwrap();
file_proxy.reopen(&fio::RightsRequest::default(), reopen_server).unwrap();
assert_matches!(
reopen_proxy.take_event_stream().try_next().await,
Err(fidl::Error::ClientChannelClosed { status: zx::Status::NOT_SUPPORTED, .. })
);
}
#[fuchsia::test]
async fn reopen_file_node_reference_unsupported() {
let harness = TestHarness::new().await;
let root = root_directory(vec![file(TEST_FILE, vec![])]);
let test_dir = harness.get_directory(root, harness.dir_rights.all());
let file_proxy =
open_file_with_flags(&test_dir, fio::OpenFlags::NODE_REFERENCE, TEST_FILE).await;
// fuchsia.io/Node.Reopen
let (reopen_proxy, reopen_server) = fidl::endpoints::create_proxy::<fio::NodeMarker>().unwrap();
file_proxy.reopen(&fio::RightsRequest::default(), reopen_server).unwrap();
assert_matches!(
reopen_proxy.take_event_stream().try_next().await,
Err(fidl::Error::ClientChannelClosed { status: zx::Status::NOT_SUPPORTED, .. })
);
}
#[fuchsia::test]
async fn reopen_directory_unsupported() {
let harness = TestHarness::new().await;
let root = root_directory(vec![directory("dir", vec![])]);
let test_dir = harness.get_directory(root, harness.dir_rights.all());
let dir_proxy = open_dir_with_flags(&test_dir, fio::OpenFlags::RIGHT_READABLE, "dir").await;
// fuchsia.io/Node.Reopen
let (reopen_proxy, reopen_server) = fidl::endpoints::create_proxy::<fio::NodeMarker>().unwrap();
dir_proxy.reopen(&fio::RightsRequest::default(), reopen_server).unwrap();
assert_matches!(
reopen_proxy.take_event_stream().try_next().await,
Err(fidl::Error::ClientChannelClosed { status: zx::Status::NOT_SUPPORTED, .. })
);
}
#[fuchsia::test]
async fn reopen_directory_node_reference_unsupported() {
let harness = TestHarness::new().await;
let root = root_directory(vec![directory("dir", vec![])]);
let test_dir = harness.get_directory(root, harness.dir_rights.all());
let dir_proxy = open_dir_with_flags(&test_dir, fio::OpenFlags::NODE_REFERENCE, "dir").await;
// fuchsia.io/Node.Reopen
let (reopen_proxy, reopen_server) = fidl::endpoints::create_proxy::<fio::NodeMarker>().unwrap();
dir_proxy.reopen(&fio::RightsRequest::default(), reopen_server).unwrap();
assert_matches!(
reopen_proxy.take_event_stream().try_next().await,
Err(fidl::Error::ClientChannelClosed { status: zx::Status::NOT_SUPPORTED, .. })
);
}