| // Copyright 2019 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.test.manager; |
| |
| using fuchsia.developer.remotecontrol; |
| using fuchsia.diagnostics; |
| using fuchsia.url; |
| using zx; |
| |
| /// Holds the server end of an iterator over the isolated logs of a test. |
| resource flexible union LogsIterator { |
| /// Server end of the iterator, when this protocol is used by host-side clients. |
| 1: request<fuchsia.developer.remotecontrol.ArchiveIterator> archive; |
| /// Server end of the iterator, when this protocol is used by Fuchsia clients. |
| 2: request<fuchsia.diagnostics.BatchIterator> batch; |
| }; |
| |
| /// Error for `LaunchSuite` call. |
| enum LaunchError { |
| /// There were insufficient resources to perform the operation. |
| RESOURCE_UNAVAILABLE = 1; |
| |
| /// Cannot resolve `test_url`. |
| INSTANCE_CANNOT_RESOLVE = 2; |
| |
| /// Invalid argument(s) passed. |
| INVALID_ARGS = 3; |
| |
| /// Failed to connect to the `fuchsia.test.TestSuite` that the test should |
| /// expose. |
| FAILED_TO_CONNECT_TO_TEST_SUITE = 4; |
| |
| /// Failed to enumerate tests. |
| CASE_ENUMERATION = 5; |
| |
| /// Some internal error occured. Something wrong with test manager setup. |
| /// Check logs and report bug. |
| INTERNAL_ERROR = 6; |
| }; |
| /// Human-readable name for a test case. |
| alias CaseName = string:512; |
| |
| /// Information about the enumerated test case. |
| table Case { |
| /// Name of the test case. |
| 1: CaseName name; |
| }; |
| |
| /// Iterator for listing available test cases. |
| protocol CaseIterator { |
| /// Returns the next batch of test cases. |
| /// Empty vector if no more test cases. |
| GetNext() -> (vector<Case>:MAX cases); |
| }; |
| |
| // Query server for tests which implement `fuchsia.test.Suite` protocol. |
| [Discoverable] |
| protocol Query { |
| /// Enumerates test cases. |
| Enumerate(fuchsia.url.Url test_url, request<CaseIterator> iterator) -> () error LaunchError; |
| }; |
| |
| /// This is the entry point of running test suites. A test "run" consists of |
| /// multiple test "suites" which consists of running multiple "test cases". |
| [Discoverable] |
| protocol RunBuilder { |
| /// Add a suite to this run. A suite is a component that implements |
| /// `fuchsia.test.Suite`. Implementors of this API will talk to test suites |
| /// using "Suite" protocol and return results using `controller`. The |
| /// controller is also used to control the execution of the test suite. |
| AddSuite(fuchsia.url.Url test_url, RunOptions options, request<SuiteController> controller); |
| |
| /// Build and schedule the run. |
| /// |
| /// This runs all suites added with their respective filters and closes the |
| /// channel once it is done. |
| Build(request<RunController> controller); |
| }; |
| |
| /// Optional additional instructions for executing a test suite. |
| table RunOptions { |
| /// If set to true, test cases that have been disabled by the test author |
| /// will nonetheless be executed. Defaults to false. |
| 1: bool run_disabled_tests; |
| |
| /// Defines maximum number of test cases to run simultaneously. |
| /// If unspecified, the default behavior is chosen by the `Suite` |
| /// implementation. |
| 2: uint16 parallel; |
| |
| /// Optional arguments to pass to the test. |
| /// Test runners will decide how to pass these arguments to tests. |
| 3: vector<string:MAX>:MAX arguments; |
| |
| /// Timeout in seconds for the entire suite. |
| 4: zx.duration timeout; |
| |
| /// glob case filter. This filter will match based on glob pattern |
| /// [https://en.wikipedia.org/wiki/Glob_(programming)]. |
| /// All the filters are ORed. If passed in, only tests matching these |
| /// filters would be executed. If not specified then all test cases will |
| /// be admitted which is equivalent to specifying [ "*" ] |
| 5: vector<string:MAX>:MAX case_filters_to_run; |
| |
| /// Defines what kind of log iterator the client supports. Default value is |
| /// Batch iterator. |
| 6: LogsIteratorOption log_iterator; |
| }; |
| |
| /// Option which specifies which kind of iterator the client supports |
| flexible enum LogsIteratorOption { |
| BATCH_ITERATOR = 0; |
| ARCHIVE_ITERATOR = 1; |
| }; |
| |
| /// The server end will disconnect after all the suite runs have finished and |
| /// the events are drained. |
| /// If the client disconnects, the tests will be terminated immediately and all |
| /// results discarded. |
| [Discoverable] |
| protocol RunController { |
| /// Stop the run gracefully. RunController will disconnect after all |
| /// resources are released and all the events in this controller are drained. |
| /// This method is used to allow the run to complete tests that are in progress, |
| /// but will prevent starting new tests. |
| Stop(); |
| |
| /// Immediately terminate the run. RunController will disconnect after all |
| /// resources are released. This method will terminate tests even if they |
| /// are in progress. |
| Kill(); |
| |
| // Iterator over events for the run. |
| GetEvents() -> (vector<RunEvent>:MAX events); |
| }; |
| |
| // Placeholder for future events. |
| resource table RunEvent { |
| }; |
| |
| /// The server end will disconnect after all the suite run has finished and |
| /// all events are drained. If the client disconnects, the suite will be |
| /// terminated immediately and all results discarded. |
| [Discoverable] |
| protocol SuiteController { |
| /// Stop the suite run gracefully. SuiteController will disconnect after |
| /// all resources are released and all the events in this controller are drained. |
| Stop(); |
| |
| /// Immediately terminate the run. SuiteController will disconnect after |
| /// all resources are released. This method will terminate tests even if |
| /// they are in progress. |
| Kill(); |
| |
| /// Iterator over events for the run. This method is a hanging get; it |
| /// returns an empty vector only when there will be no further events |
| /// (the run completed). |
| GetEvents() -> (vector<SuiteEvent>:MAX events) error LaunchError; |
| }; |
| |
| resource table SuiteEvent { |
| // The monotonic timestamp for the event. |
| 1: zx.time timestamp; |
| 2: SuiteEventPayload payload; |
| }; |
| |
| /// Various events for test execution. |
| /// |
| /// First event for a test case will always be `case_found` and last will be |
| /// `case_finished`. Events `case_started` and `case_artifact` can come in any |
| /// order. There can be some `case_artifact` between `case_stopped` and |
| /// `case_finished`. `suite_finished` event will always fire when the whole |
| /// suite has finished executing and `suite_artifact` may be fired anytime |
| /// before `suite_finished`. |
| resource union SuiteEventPayload { |
| /// A case was found. |
| 1: CaseFound case_found; |
| |
| /// A case started execution |
| 2: CaseStarted case_started; |
| |
| /// A case stopped executing, includes the pass/fail/skipped result of |
| /// the case. The client might still get artifacts pertaining to this test |
| /// after this event. |
| 3: CaseStopped case_stopped; |
| |
| /// A case has finished and all artifact events have been dispatched to the |
| /// client. |
| 4: CaseFinished case_finished; |
| |
| /// Artifact from a case |
| 5: CaseArtifact case_artifact; |
| |
| /// Artifact from a suite. |
| 6: SuiteArtifact suite_artifact; |
| |
| /// Suite run finished executing |
| 7: SuiteFinished suite_finished; |
| }; |
| |
| /// Test case identifier. Unique in a suite run. |
| alias TestCaseId = uint32; |
| |
| struct CaseFound { |
| /// Name of this test case. |
| CaseName test_case_name; |
| |
| /// Used to identify this test case in subsequent payloads |
| TestCaseId identifier; |
| }; |
| |
| struct CaseStarted { |
| TestCaseId identifier; |
| }; |
| |
| /// Represent status of a test case run execution. |
| flexible enum CaseStatus { |
| /// The test case passed. |
| PASSED = 0; |
| |
| /// Test case failed. |
| FAILED = 1; |
| |
| /// Test case timed out. |
| TIMED_OUT = 2; |
| |
| /// Test case was skipped. |
| SKIPPED = 3; |
| |
| /// Suite implementation did not return status. |
| ERROR = 4; |
| }; |
| |
| /// Represents status of a suite run. This ordering is the explicit ordering of |
| /// preference, from lowest priority to highest priority. |
| /// for example, if all Cases PASSED except one that FAILED, the status for the |
| /// whole suite will be FAILED. |
| flexible enum SuiteStatus { |
| /// All tests cases passed/skipped. |
| PASSED = 0; |
| |
| /// At least one test case in the suite failed. |
| FAILED = 1; |
| |
| /// Suite implementation crashed or did not send `Finish` event. |
| DID_NOT_FINISH = 3; |
| |
| /// At least one test case in the suite timed out. |
| TIMED_OUT = 4; |
| |
| /// The test suite was stopped. |
| STOPPED = 5; |
| |
| // Some internal error occurred, please file bug. |
| INTERNAL_ERROR = 6; |
| }; |
| |
| struct CaseStopped { |
| TestCaseId identifier; |
| CaseStatus status; |
| }; |
| |
| struct CaseFinished { |
| TestCaseId identifier; |
| }; |
| |
| struct SuiteFinished { |
| SuiteStatus status; |
| }; |
| |
| resource flexible union Artifact { |
| 1: zx.handle:SOCKET stdout; |
| 2: zx.handle:SOCKET stderr; |
| 3: Syslog log; |
| }; |
| |
| resource struct Stdout { |
| zx.handle:SOCKET socket; |
| }; |
| |
| resource struct Stderr { |
| zx.handle:SOCKET socket; |
| }; |
| |
| resource flexible union Syslog { |
| /// Client end of the iterator, when this protocol is used by host-side clients. |
| 1: fuchsia.developer.remotecontrol.ArchiveIterator archive; |
| /// Client end of the iterator, when this protocol is used by Fuchsia clients. |
| 2: fuchsia.diagnostics.BatchIterator batch; |
| }; |
| |
| resource struct CaseArtifact { |
| TestCaseId identifier; |
| Artifact artifact; |
| }; |
| |
| resource struct SuiteArtifact { |
| Artifact artifact; |
| }; |