|  | // 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. | 
|  |  | 
|  | 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. | 
|  | table Io1Config { | 
|  | /// Files are read-only. | 
|  | 1: bool immutable_file; | 
|  |  | 
|  | /// Directories are read-only. | 
|  | 2: bool immutable_dir; | 
|  |  | 
|  | /// The exec right is not supported. | 
|  | 3: bool no_exec; | 
|  |  | 
|  | /// Vmofiles are not supported. | 
|  | 4: bool no_vmofile; | 
|  |  | 
|  | /// Remote directories are not supported. | 
|  | 5: bool no_remote_dir; | 
|  |  | 
|  | /// The admin right is not supported. | 
|  | 6: bool no_admin; | 
|  | }; | 
|  |  | 
|  | resource table Directory { | 
|  | /// Name not required for root directory. | 
|  | 1: string name; | 
|  |  | 
|  | /// fuchsia.io OPEN_RIGHT_* flags for the directory. | 
|  | 2: uint32 flags; | 
|  |  | 
|  | /// Nullable to sidestep recursion rules. Don't actually supply nulls. | 
|  | 3: vector<DirectoryEntry?> entries; | 
|  | }; | 
|  |  | 
|  | table File { | 
|  | 1: string name; | 
|  |  | 
|  | /// fuchsia.io OPEN_RIGHT_* flags for the file. | 
|  | 2: uint32 flags; | 
|  |  | 
|  | 3: bytes contents; | 
|  | }; | 
|  |  | 
|  | resource table VmoFile { | 
|  | 1: string name; | 
|  |  | 
|  | /// fuchsia.io OPEN_RIGHT_* flags for the VMO file. | 
|  | 2: uint32 flags; | 
|  |  | 
|  | 3: fuchsia.mem.Range buffer; | 
|  | }; | 
|  |  | 
|  | resource union DirectoryEntry { | 
|  | 1: Directory directory; | 
|  | 2: File file; | 
|  | 3: VmoFile vmo_file; | 
|  | }; | 
|  |  | 
|  | [Discoverable] | 
|  | protocol Io1Harness { | 
|  | /// Returns the list of properties of the filesystem. | 
|  | GetConfig() -> (Io1Config config); | 
|  |  | 
|  | /// 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. | 
|  | GetDirectory(Directory root, | 
|  | request<fuchsia.io.Directory> directory_request); | 
|  |  | 
|  | /// Serves a directory with a single vmofile inside. | 
|  | /// | 
|  | /// + `name` the name of the vmofile in the root directory. | 
|  | /// + `flags` the flags the served directory connection has. | 
|  | /// + `directory_request` the server end of the root directory connection. | 
|  | /// | 
|  | /// TODO(fxbug.dev/33880): Add suppport for VMO files to GetDirectory and | 
|  | /// then delete this method. | 
|  | GetDirectoryWithVmoFile(fuchsia.mem.Range file, | 
|  | string name, | 
|  | uint32 flags, | 
|  | request<fuchsia.io.Directory> directory_request); | 
|  |  | 
|  | /// Serves a directory that holds a child `remote_directory` with name | 
|  | /// `dir_name`. The `directory_request` connection to the root directory | 
|  | /// has rights defined by `flags`. | 
|  | /// Note: This might not actually be needed for the defined io1 tests, but | 
|  | /// still might be useful for future testing if a fs forwards the correct | 
|  | /// request to the remote. | 
|  | /// | 
|  | /// + `remote_directory` the client end of the child remote directory. | 
|  | /// + `name` the name of the child remote directory in the root directory. | 
|  | /// + `flags` the flags the served directory connection has. | 
|  | /// + `directory_request` the server end of the root directory connection. | 
|  | /// | 
|  | /// TODO(fxbug.dev/33880): Add suppport for remote directories to | 
|  | /// GetDirectory and then delete this method. | 
|  | GetDirectoryWithRemoteDirectory(fuchsia.io.Directory remote_directory, | 
|  | string name, | 
|  | uint32 flags, | 
|  | request<fuchsia.io.Directory> directory_request); | 
|  | }; | 
|  |  | 
|  | /// 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.io2/Rights.CONNECT`]. | 
|  | ///     * [`fuchsia.io2/Rights.ENUMERATE`]. | 
|  | ///     * [`fuchsia.io2/Rights.TRAVERSE`]. | 
|  | ///     * [`fuchsia.io2/Rights.READ_BYTES`]. | 
|  | ///     * [`fuchsia.io2/Rights.WRITE_BYTES`]. | 
|  | ///     * [`fuchsia.io2/Rights.GET_ATTRIBUTES`]. | 
|  | ///     * [`fuchsia.io2/Rights.UPDATE_ATTRIBUTES`]. | 
|  | /// | 
|  | GetEmptyDirectory(zx.handle:CHANNEL directory_request); | 
|  | }; |