| // 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. |
| @available(added=7) |
| library fuchsia.io.test; |
| |
| using fuchsia.mem; |
| using fuchsia.io; |
| using zx; |
| |
| // TODO(fxbug.dev/33880): Implement full testing framework. For now, we are |
| // hard-coding the desired directory layout manually in separate "Get" |
| // functions. In the next step, we would want to have a protocol to describe |
| // the intended directory layout setup, and integrate io2 connections. |
| |
| /// Conformance test harnesses will implement this protocol to setup its |
| /// associated filesystem servers with the described directory layout, |
| /// allowing their implementation of `fuchsia.io` and `fuchsia.io2` protocols |
| /// to be verified by a common test suite. |
| /// |
| /// Different test cases will not interact with one another during the |
| /// conformance test, and only one test case will be active at a time per |
| /// tested filesystem. So it is possible to host all cases as different |
| /// sub-directories under a common filesystem instance, to simplify the |
| /// lifecycle and implementation. |
| /// |
| /// If a test case has mutable bits, each method call should be implemented |
| /// to obtain the directory in its original state. In other words, repeated |
| /// test case set up should "as-if" yield new directories. |
| /// |
| /// See `src/storage/conformance/README.md` for an overview of io conformance |
| /// testing. |
| /// |
| /// `Io1Config` lets the test harness modulate the set of expected outcomes and |
| /// behaviors validated by the test suite, by declaring specific properties |
| /// about the filesystem implementation. For example, setting [`ImmutableFile`] |
| /// to true informs the test suites that files hosted by this harness do not |
| /// support mutation. |
| type Io1Config = table { |
| /// Files are mutable (i.e. support RIGHT_WRITABLE). |
| 1: mutable_file bool; |
| |
| /// Directories support the CREATE flag for creating new files. |
| 2: supports_create bool; |
| |
| /// ExecutableFile objects are supported. |
| 3: supports_executable_file bool; |
| |
| /// VmoFile objects are supported. |
| 4: supports_vmo_file bool; |
| |
| /// Remote directories are supported. |
| 5: supports_remote_dir bool; |
| |
| /// GetBuffer is supported by VmoFile objects. |
| 6: supports_get_buffer bool; |
| |
| /// Rename is supported. |
| 7: supports_rename bool; |
| |
| /// Link is supported. |
| 8: supports_link bool; |
| |
| /// SetAttr is supported. |
| 9: supports_set_attr bool; |
| |
| /// GetToken is supported. |
| 10: supports_get_token bool; |
| |
| /// Path handling conforms to in-tree behavior. |
| /// TODO(fxbug.dev/82672): Ensure all libraries are conformant and remove this option. |
| /// Currently the only non-conformant implementation being tested is the SDK VFS. |
| 11: conformant_path_handling bool; |
| |
| /// Unlink is supported. |
| 12: supports_unlink bool; |
| }; |
| |
| /// Directory entries should support opening with any combination of read/write/execute rights. |
| type Directory = resource table { |
| /// Name not required for root directory. |
| 1: name string; |
| |
| /// Nullable to sidestep recursion rules. Don't actually supply nulls. |
| 2: entries vector<DirectoryEntry:optional>; |
| }; |
| |
| /// Remote directory which forwards FIDL requests from the server to the specified directory. |
| type RemoteDirectory = resource table { |
| /// Name not required for root directory. |
| 1: name string; |
| |
| /// Remote client to forward Directory requests to. |
| 2: remote_client client_end:fuchsia.io.Directory; |
| }; |
| |
| /// File object which supports reading, and if `mutable_file` is true, also supports writing. |
| /// |
| /// As the conformance tests verify W^X enforcement, attempting to open a File with RIGHT_EXECUTABLE |
| /// should fail with ACCESS_DENIED if `mutable_file` is true. |
| /// |
| /// If executable files are required, use ExecutableFile instead. |
| type File = table { |
| 1: name string; |
| 2: contents bytes; |
| }; |
| |
| /// Vmo-backed file object which supports opening as readable + writable. |
| /// |
| /// Enabled via the `supports_vmo_file` configuration option. |
| /// |
| /// As the conformance tests verify W^X enforcement, attempting to open a VmoFile as executable |
| /// should fail with ACCESS_DENIED. If executable files are required, use ExecutableFile. |
| type VmoFile = resource table { |
| 1: name string; |
| 2: buffer fuchsia.mem.Range; |
| }; |
| |
| /// Adds an executable file that supports opening as readable + executable. The file has a non-zero |
| /// size, but the contents are otherwise unspecified. |
| /// |
| /// Enabled by setting `supports_executable_file` to false. If enabled, `supports_get_buffer` should |
| /// be enabled to validate the permissions of the VMO backing the ExecutableFile. |
| /// |
| /// As the conformance tests verify W^X enforcement, opening an ExecutableFile with RIGHT_WRITABLE |
| /// should fail with ACCESS_DENIED. If writable files are required, use File/VmoFile instead. |
| type ExecutableFile = table { |
| 1: name string; |
| }; |
| |
| type DirectoryEntry = strict resource union { |
| 1: directory Directory; |
| 2: remote_directory RemoteDirectory; |
| 3: file File; |
| 4: vmo_file VmoFile; |
| 5: executable_file ExecutableFile; |
| }; |
| |
| @discoverable |
| protocol Io1Harness { |
| /// Returns the list of properties of the filesystem. |
| GetConfig() -> (struct { |
| config Io1Config; |
| }); |
| |
| /// Serves a directory with the given contents. |
| /// |
| /// `root` describes the initial layout of the filesystem that will be |
| /// used for the test case. The root directory that is served (returned via |
| /// `directory_request`) will have the equivalent contents, served with the |
| /// given `flags`. |
| GetDirectory(resource struct { |
| root Directory; |
| flags fuchsia.io.OpenFlags; |
| directory_request server_end:fuchsia.io.Directory; |
| }); |
| }; |
| |
| /// Stub harness api for the io2.fidl protocol. |
| /// TODO(fxbug.dev/46082): Add separate io2 test harness api once we come up with a |
| /// good enough set of functions that we have enough flexibility to create |
| /// variable directory structures to with explicit permission settings for tests. |
| @discoverable |
| protocol Io2Harness { |
| /// Prepares a test case with an empty directory. The directory metadata |
| /// and directory entires should be read-only. |
| /// |
| /// + `directory_request` the server end of the root directory connection. |
| /// |
| /// This connection should have the following rights: |
| /// |
| /// * [`fuchsia.io/Rights.CONNECT`]. |
| /// * [`fuchsia.io/Rights.ENUMERATE`]. |
| /// * [`fuchsia.io/Rights.TRAVERSE`]. |
| /// * [`fuchsia.io/Rights.READ_BYTES`]. |
| /// * [`fuchsia.io/Rights.WRITE_BYTES`]. |
| /// * [`fuchsia.io/Rights.GET_ATTRIBUTES`]. |
| /// * [`fuchsia.io/Rights.UPDATE_ATTRIBUTES`]. |
| /// |
| GetEmptyDirectory(resource struct { |
| directory_request zx.handle:CHANNEL; |
| }); |
| }; |