xref: /aosp_15_r20/external/googleapis/google/devtools/testing/v1/test_execution.proto (revision d5c09012810ac0c9f33fe448fb6da8260d444cc9)
1// Copyright 2023 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15syntax = "proto3";
16
17package google.devtools.testing.v1;
18
19import "google/api/annotations.proto";
20import "google/api/client.proto";
21import "google/api/field_behavior.proto";
22import "google/protobuf/duration.proto";
23import "google/protobuf/timestamp.proto";
24
25option go_package = "google.golang.org/genproto/googleapis/devtools/testing/v1;testing";
26option java_multiple_files = true;
27option java_outer_classname = "TestExecutionProto";
28option java_package = "com.google.devtools.testing.v1";
29
30// A service for requesting test executions and querying their status.
31//
32// This service is part of Firebase Test Lab. To learn about how to use the
33// product, and how to integrate it with your system,
34// visit https://firebase.google.com/docs/test-lab.
35//
36// Each test execution will wait for available capacity. It will then be
37// invoked as described. The test may be invoked multiple times if an
38// infrastructure failure is detected. Results and other files generated by
39// the test will be stored in an external storage system.
40//
41// The TestExecutionService models this behavior using two resource types:
42//
43// - TestMatrix: a group of one or more TestExecutions, built by taking a
44//   product of values over a pre-defined set of axes. In the case of Android
45//   Tests, for example, device model and OS version are two axes of the matrix.
46//
47// - TestExecution: a single execution of one or more test targets on a
48//   single device. These are created automatically when a TestMatrix is
49//   created.
50//
51// This service returns any error codes from the canonical error space (i.e.
52// google.rpc.Code). The errors which may be returned are specified on each
53// method. In addition, any method may return UNAVAILABLE or INTERNAL.
54service TestExecutionService {
55  option (google.api.default_host) = "testing.googleapis.com";
56  option (google.api.oauth_scopes) =
57      "https://www.googleapis.com/auth/cloud-platform,"
58      "https://www.googleapis.com/auth/cloud-platform.read-only";
59
60  // Creates and runs a matrix of tests according to the given specifications.
61  // Unsupported environments will be returned in the state UNSUPPORTED.
62  // A test matrix is limited to use at most 2000 devices in parallel.
63  //
64  // The returned matrix will not yet contain the executions that will be
65  // created for this matrix. Execution creation happens later on and will
66  // require a call to GetTestMatrix.
67  //
68  // May return any of the following canonical error codes:
69  //
70  // - PERMISSION_DENIED - if the user is not authorized to write to project
71  // - INVALID_ARGUMENT - if the request is malformed or if the matrix tries
72  //                      to use too many simultaneous devices.
73  rpc CreateTestMatrix(CreateTestMatrixRequest) returns (TestMatrix) {
74    option (google.api.http) = {
75      post: "/v1/projects/{project_id}/testMatrices"
76      body: "test_matrix"
77    };
78  }
79
80  // Checks the status of a test matrix and the executions once they
81  // are created.
82  //
83  // The test matrix will contain the list of test executions to run if and only
84  // if the resultStorage.toolResultsExecution fields have been populated.
85  //
86  // Note: Flaky test executions may be added to the matrix at a later stage.
87  //
88  // May return any of the following canonical error codes:
89  //
90  // - PERMISSION_DENIED - if the user is not authorized to read project
91  // - INVALID_ARGUMENT - if the request is malformed
92  // - NOT_FOUND - if the Test Matrix does not exist
93  rpc GetTestMatrix(GetTestMatrixRequest) returns (TestMatrix) {
94    option (google.api.http) = {
95      get: "/v1/projects/{project_id}/testMatrices/{test_matrix_id}"
96    };
97  }
98
99  // Cancels unfinished test executions in a test matrix.
100  // This call returns immediately and cancellation proceeds asynchronously.
101  // If the matrix is already final, this operation will have no effect.
102  //
103  // May return any of the following canonical error codes:
104  //
105  // - PERMISSION_DENIED - if the user is not authorized to read project
106  // - INVALID_ARGUMENT - if the request is malformed
107  // - NOT_FOUND - if the Test Matrix does not exist
108  rpc CancelTestMatrix(CancelTestMatrixRequest)
109      returns (CancelTestMatrixResponse) {
110    option (google.api.http) = {
111      post: "/v1/projects/{project_id}/testMatrices/{test_matrix_id}:cancel"
112    };
113  }
114}
115
116// TestMatrix captures all details about a test. It contains the environment
117// configuration, test specification, test executions and overall state and
118// outcome.
119message TestMatrix {
120  // Output only. Unique id set by the service.
121  string test_matrix_id = 1;
122
123  // The cloud project that owns the test matrix.
124  string project_id = 7;
125
126  // Information about the client which invoked the test.
127  ClientInfo client_info = 10;
128
129  // Required. How to run the test.
130  TestSpecification test_specification = 3;
131
132  // Required. The devices the tests are being executed on.
133  EnvironmentMatrix environment_matrix = 4;
134
135  // Output only. The list of test executions that the service creates for
136  // this matrix.
137  repeated TestExecution test_executions = 5;
138
139  // Required. Where the results for the matrix are written.
140  ResultStorage result_storage = 6;
141
142  // Output only. Indicates the current progress of the test matrix.
143  TestState state = 8;
144
145  // Output only. The time this test matrix was initially created.
146  google.protobuf.Timestamp timestamp = 9;
147
148  // Output only. Describes why the matrix is considered invalid.
149  // Only useful for matrices in the INVALID state.
150  InvalidMatrixDetails invalid_matrix_details = 11;
151
152  // Output only. Details about why a matrix was deemed invalid.
153  // If multiple checks can be safely performed, they will be reported but no
154  // assumptions should be made about the length of this list.
155  repeated MatrixErrorDetail extended_invalid_matrix_details = 22
156      [(google.api.field_behavior) = OUTPUT_ONLY];
157
158  // The number of times a TestExecution should be re-attempted if one or more
159  // of its test cases fail for any reason.
160  // The maximum number of reruns allowed is 10.
161  //
162  // Default is 0, which implies no reruns.
163  int32 flaky_test_attempts = 13;
164
165  // Output Only. The overall outcome of the test.
166  // Only set when the test matrix state is FINISHED.
167  OutcomeSummary outcome_summary = 14;
168
169  // If true, only a single attempt at most will be made to run each
170  // execution/shard in the matrix. Flaky test attempts are not affected.
171  //
172  // Normally, 2 or more attempts are made if a potential infrastructure issue
173  // is detected.
174  //
175  // This feature is for latency sensitive workloads. The incidence of
176  // execution failures may be significantly greater for fail-fast matrices
177  // and support is more limited because of that expectation.
178  bool fail_fast = 17;
179}
180
181// Describes a single error or issue with a matrix.
182message MatrixErrorDetail {
183  // Output only. The reason for the error. This is a constant value in
184  // UPPER_SNAKE_CASE that identifies the cause of the error.
185  string reason = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
186
187  // Output only. A human-readable message about how the error in the
188  // TestMatrix. Expands on the `reason` field with additional details and
189  // possible options to fix the issue.
190  string message = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
191}
192
193// A single test executed in a single environment.
194message TestExecution {
195  // Output only. Unique id set by the service.
196  string id = 1;
197
198  // Output only. Id of the containing TestMatrix.
199  string matrix_id = 9;
200
201  // Output only. The cloud project that owns the test execution.
202  string project_id = 10;
203
204  // Output only. How to run the test.
205  TestSpecification test_specification = 3;
206
207  // Output only. Details about the shard.
208  Shard shard = 12;
209
210  // Output only. How the host machine(s) are configured.
211  Environment environment = 4;
212
213  // Output only. Indicates the current progress of the test execution
214  // (e.g., FINISHED).
215  TestState state = 5;
216
217  // Output only. Where the results for this execution are written.
218  ToolResultsStep tool_results_step = 11;
219
220  // Output only. The time this test execution was initially created.
221  google.protobuf.Timestamp timestamp = 7;
222
223  // Output only. Additional details about the running test.
224  TestDetails test_details = 8;
225}
226
227// A description of how to run the test.
228message TestSpecification {
229  // Max time a test execution is allowed to run before it is
230  // automatically cancelled.
231  // The default value is 5 min.
232  google.protobuf.Duration test_timeout = 1;
233
234  // Test setup requirements.
235  oneof setup {
236    // Test setup requirements for Android e.g. files to install, bootstrap
237    // scripts.
238    TestSetup test_setup = 6;
239
240    // Test setup requirements for iOS.
241    IosTestSetup ios_test_setup = 14;
242  }
243
244  // Required. The type of test to run.
245  oneof test {
246    // An Android instrumentation test.
247    AndroidInstrumentationTest android_instrumentation_test = 2;
248
249    // An Android robo test.
250    AndroidRoboTest android_robo_test = 3;
251
252    // An Android Application with a Test Loop.
253    AndroidTestLoop android_test_loop = 9;
254
255    // An iOS XCTest, via an .xctestrun file.
256    IosXcTest ios_xc_test = 13;
257
258    // An iOS application with a test loop.
259    IosTestLoop ios_test_loop = 15;
260
261    // An iOS Robo test.
262    IosRoboTest ios_robo_test = 17;
263  }
264
265  // Disables video recording. May reduce test latency.
266  bool disable_video_recording = 10;
267
268  // Disables performance metrics recording. May reduce test latency.
269  bool disable_performance_metrics = 11;
270}
271
272message SystraceSetup {
273  // Systrace duration in seconds.
274  // Should be between 1 and 30 seconds. 0 disables systrace.
275  int32 duration_seconds = 1 [deprecated = true];
276}
277
278// A description of how to set up the Android device prior to running the test.
279message TestSetup {
280  // List of files to push to the device before starting the test.
281  repeated DeviceFile files_to_push = 1;
282
283  // List of directories on the device to upload to GCS at the end of the test;
284  // they must be absolute paths under /sdcard, /storage or /data/local/tmp.
285  // Path names are restricted to characters a-z A-Z 0-9 _ - . + and /
286  //
287  // Note: The paths /sdcard and /data will be made available and treated as
288  // implicit path substitutions. E.g. if /sdcard on a particular device does
289  // not map to external storage, the system will replace it with the external
290  // storage path prefix for that device.
291  repeated string directories_to_pull = 2;
292
293  // Optional. Initial setup APKs to install before the app under test is
294  // installed. Currently capped at 100.
295  repeated Apk initial_setup_apks = 29 [(google.api.field_behavior) = OPTIONAL];
296
297  // APKs to install in addition to those being directly tested. These will be
298  // installed after the app under test.
299  // Currently capped at 100.
300  repeated Apk additional_apks = 3;
301
302  // The device will be logged in on this account for the duration of the test.
303  Account account = 4;
304
305  // The network traffic profile used for running the test.
306  // Available network profiles can be queried by using the
307  // NETWORK_CONFIGURATION environment type when calling
308  // TestEnvironmentDiscoveryService.GetTestEnvironmentCatalog.
309  string network_profile = 5;
310
311  // Environment variables to set for the test (only applicable for
312  // instrumentation tests).
313  repeated EnvironmentVariable environment_variables = 6;
314
315  // Systrace configuration for the run.
316  // Deprecated: Systrace used Python 2 which was sunsetted on 2020-01-01.
317  // Systrace is no longer supported in the Cloud Testing API, and no Systrace
318  // file will be provided in the results.
319  SystraceSetup systrace = 9 [deprecated = true];
320
321  // Whether to prevent all runtime permissions to be granted at app install
322  bool dont_autogrant_permissions = 23;
323}
324
325// A description of how to set up an iOS device prior to running the test.
326message IosTestSetup {
327  // The network traffic profile used for running the test.
328  // Available network profiles can be queried by using the
329  // NETWORK_CONFIGURATION environment type when calling
330  // TestEnvironmentDiscoveryService.GetTestEnvironmentCatalog.
331  string network_profile = 1;
332
333  // iOS apps to install in addition to those being directly tested.
334  repeated FileReference additional_ipas = 2;
335
336  // List of files to push to the device before starting the test.
337  repeated IosDeviceFile push_files = 3;
338
339  // List of directories on the device to upload to Cloud Storage at the end of
340  // the test.
341  //
342  // Directories should either be in a shared directory (such as
343  // /private/var/mobile/Media) or within an accessible directory inside the
344  // app's filesystem (such as /Documents) by specifying the bundle ID.
345  repeated IosDeviceFile pull_directories = 4;
346}
347
348// A key-value pair passed as an environment variable to the test.
349message EnvironmentVariable {
350  // Key for the environment variable.
351  string key = 1;
352
353  // Value for the environment variable.
354  string value = 2;
355}
356
357// Identifies an account and how to log into it.
358message Account {
359  // Required. The type of account, based what it's for (e.g. Google) and what
360  // its login mechanism is (e.g. username and password).
361  oneof account_type {
362    // An automatic google login account.
363    GoogleAuto google_auto = 1;
364  }
365}
366
367// Enables automatic Google account login.
368// If set, the service automatically generates a Google test account and adds
369// it to the device, before executing the test. Note that test accounts might be
370// reused.
371// Many applications show their full set of functionalities when an account is
372// present on the device. Logging into the device with these generated accounts
373// allows testing more functionalities.
374message GoogleAuto {}
375
376// An Android package file to install.
377message Apk {
378  // The path to an APK to be installed on the device before the test begins.
379  FileReference location = 1;
380
381  // The java package for the APK to be installed.
382  // Value is determined by examining the application's manifest.
383  string package_name = 2;
384}
385
386// An Android App Bundle file format, containing a BundleConfig.pb file,
387// a base module directory, zero or more dynamic feature module directories.
388// <p>See https://developer.android.com/guide/app-bundle/build for guidance on
389// building App Bundles.
390message AppBundle {
391  // Required. Bundle location information.
392  oneof bundle {
393    // .aab file representing the app bundle under test.
394    FileReference bundle_location = 1;
395  }
396}
397
398// A single device file description.
399message DeviceFile {
400  // Required.
401  oneof device_file {
402    // A reference to an opaque binary blob file.
403    ObbFile obb_file = 1;
404
405    // A reference to a regular file.
406    RegularFile regular_file = 2;
407  }
408}
409
410// An opaque binary blob file to install on the device before the test starts.
411message ObbFile {
412  // Required. OBB file name which must conform to the format as specified by
413  // Android
414  // e.g. [main|patch].0300110.com.example.android.obb
415  // which will be installed into
416  //   \<shared-storage\>/Android/obb/\<package-name\>/
417  // on the device.
418  string obb_file_name = 1;
419
420  // Required. Opaque Binary Blob (OBB) file(s) to install on the device.
421  FileReference obb = 2;
422}
423
424// A file or directory to install on the device before the test starts.
425message RegularFile {
426  // Required. The source file.
427  FileReference content = 1;
428
429  // Required. Where to put the content on the device. Must be an absolute,
430  // allowlisted path. If the file exists, it will be replaced.
431  // The following device-side directories and any of their subdirectories are
432  // allowlisted:
433  // <p>${EXTERNAL_STORAGE}, /sdcard, or /storage</p>
434  // <p>${ANDROID_DATA}/local/tmp, or /data/local/tmp</p>
435  // <p>Specifying a path outside of these directory trees is invalid.
436  //
437  // <p> The paths /sdcard and /data will be made available and treated as
438  // implicit path substitutions. E.g. if /sdcard on a particular device does
439  // not map to external storage, the system will replace it with the external
440  // storage path prefix for that device and copy the file there.
441  //
442  // <p> It is strongly advised to use the <a href=
443  // "http://developer.android.com/reference/android/os/Environment.html">
444  // Environment API</a> in app and test code to access files on the device in a
445  // portable way.
446  string device_path = 2;
447}
448
449// A file or directory to install on the device before the test starts.
450message IosDeviceFile {
451  // The source file
452  FileReference content = 1;
453
454  // The bundle id of the app where this file lives.
455  //
456  // iOS apps sandbox their own filesystem, so app files must specify which app
457  // installed on the device.
458  string bundle_id = 2;
459
460  // Location of the file on the device, inside the app's sandboxed filesystem
461  string device_path = 3;
462}
463
464// A test of an Android Application with a Test Loop.
465// The intent \<intent-name\> will be implicitly added, since Games is the only
466// user of this api, for the time being.
467message AndroidTestLoop {
468  // Required. The Android package to test.
469  oneof app_under_test {
470    // The APK for the application under test.
471    FileReference app_apk = 1;
472
473    // A multi-apk app bundle for the application under test.
474    AppBundle app_bundle = 5;
475  }
476
477  // The java package for the application under test.
478  // The default is determined by examining the application's manifest.
479  string app_package_id = 2;
480
481  // The list of scenarios that should be run during the test.
482  // The default is all test loops, derived from the application's
483  // manifest.
484  repeated int32 scenarios = 3;
485
486  // The list of scenario labels that should be run during the test.
487  // The scenario labels should map to labels defined in the application's
488  // manifest. For example, player_experience and
489  // com.google.test.loops.player_experience add all of the loops labeled in the
490  // manifest with the com.google.test.loops.player_experience name to the
491  // execution.
492  // Scenarios can also be specified in the scenarios field.
493  repeated string scenario_labels = 4;
494}
495
496// A test of an iOS application that uses the XCTest framework.
497// Xcode supports the option to "build for testing", which generates an
498// .xctestrun file that contains a test specification (arguments, test methods,
499// etc). This test type accepts a zip file containing the .xctestrun file and
500// the corresponding contents of the Build/Products directory that contains all
501// the binaries needed to run the tests.
502message IosXcTest {
503  // Required. The .zip containing the .xctestrun file and the contents of the
504  // DerivedData/Build/Products directory.
505  // The .xctestrun file in this zip is ignored if the xctestrun field is
506  // specified.
507  FileReference tests_zip = 1;
508
509  // An .xctestrun file that will override the .xctestrun file in the
510  // tests zip. Because the .xctestrun file contains environment variables along
511  // with test methods to run and/or ignore, this can be useful for sharding
512  // tests. Default is taken from the tests zip.
513  FileReference xctestrun = 2;
514
515  // The Xcode version that should be used for the test.
516  // Use the TestEnvironmentDiscoveryService to get supported options.
517  // Defaults to the latest Xcode version Firebase Test Lab supports.
518  string xcode_version = 3;
519
520  // Output only. The bundle id for the application under test.
521  string app_bundle_id = 4;
522
523  // The option to test special app entitlements. Setting this would re-sign the
524  // app having special entitlements with an explicit application-identifier.
525  // Currently supports testing aps-environment entitlement.
526  bool test_special_entitlements = 6;
527}
528
529// A test of an iOS application that implements one or more game loop scenarios.
530// This test type accepts an archived application (.ipa file) and a list of
531// integer scenarios that will be executed on the app sequentially.
532message IosTestLoop {
533  // Required. The .ipa of the application to test.
534  FileReference app_ipa = 1;
535
536  // The list of scenarios that should be run during the test. Defaults to the
537  // single scenario 0 if unspecified.
538  repeated int32 scenarios = 2;
539
540  // Output only. The bundle id for the application under test.
541  string app_bundle_id = 3;
542}
543
544// A test that explores an iOS application on an iOS device.
545message IosRoboTest {
546  // Required. The ipa stored at this file should be used to run the test.
547  FileReference app_ipa = 1 [(google.api.field_behavior) = REQUIRED];
548
549  // The bundle ID for the app-under-test.
550  // This is determined by examining the application's "Info.plist" file.
551  string app_bundle_id = 4;
552
553  // An optional Roboscript to customize the crawl. See
554  // https://firebase.google.com/docs/test-lab/android/robo-scripts-reference
555  // for more information about Roboscripts.
556  FileReference robo_script = 5;
557}
558
559// A test of an Android application that can control an Android component
560// independently of its normal lifecycle.
561// Android instrumentation tests run an application APK and test APK inside the
562// same process on a virtual or physical AndroidDevice.  They also specify
563// a test runner class, such as com.google.GoogleTestRunner, which can vary
564// on the specific instrumentation framework chosen.
565//
566// See <https://developer.android.com/training/testing/fundamentals> for
567// more information on types of Android tests.
568message AndroidInstrumentationTest {
569  // Required.
570  oneof app_under_test {
571    // The APK for the application under test.
572    FileReference app_apk = 1;
573
574    // A multi-apk app bundle for the application under test.
575    AppBundle app_bundle = 8;
576  }
577
578  // Required. The APK containing the test code to be executed.
579  FileReference test_apk = 2;
580
581  // The java package for the application under test.
582  // The default value is determined by examining the application's manifest.
583  string app_package_id = 3;
584
585  // The java package for the test to be executed.
586  // The default value is determined by examining the application's manifest.
587  string test_package_id = 4;
588
589  // The InstrumentationTestRunner class.
590  // The default value is determined by examining the application's manifest.
591  string test_runner_class = 5;
592
593  // Each target must be fully qualified with the package name or class name,
594  // in one of these formats:
595  //
596  //  - "package package_name"
597  //  - "class package_name.class_name"
598  //  - "class package_name.class_name#method_name"
599  //
600  // If empty, all targets in the module will be run.
601  repeated string test_targets = 6;
602
603  // The option of whether running each test within its own invocation of
604  // instrumentation with Android Test Orchestrator or not.
605  // ** Orchestrator is only compatible with AndroidJUnitRunner version 1.1 or
606  // higher! **
607  // Orchestrator offers the following benefits:
608  //
609  //  - No shared state
610  //  - Crashes are isolated
611  //  - Logs are scoped per test
612  //
613  // See
614  // <https://developer.android.com/training/testing/junit-runner.html#using-android-test-orchestrator>
615  // for more information about Android Test Orchestrator.
616  //
617  // If not set, the test will be run without the orchestrator.
618  OrchestratorOption orchestrator_option = 7;
619
620  // The option to run tests in multiple shards in parallel.
621  ShardingOption sharding_option = 9;
622}
623
624// Specifies how to execute the test.
625enum OrchestratorOption {
626  // Default value: the server will choose the mode. Currently implies that
627  // the test will run without the orchestrator. In the future,
628  // all instrumentation tests will be run with the orchestrator.
629  // Using the orchestrator is highly encouraged because of all the benefits it
630  // offers.
631  ORCHESTRATOR_OPTION_UNSPECIFIED = 0;
632
633  // Run test using orchestrator.
634  // ** Only compatible with AndroidJUnitRunner version 1.1 or higher! **
635  // Recommended.
636  USE_ORCHESTRATOR = 1;
637
638  // Run test without using orchestrator.
639  DO_NOT_USE_ORCHESTRATOR = 2;
640}
641
642// A test of an android application that explores the application on a virtual
643// or physical Android Device, finding culprits and crashes as it goes.
644message AndroidRoboTest {
645  // Required.
646  oneof app_under_test {
647    // The APK for the application under test.
648    FileReference app_apk = 1;
649
650    // A multi-apk app bundle for the application under test.
651    AppBundle app_bundle = 16;
652  }
653
654  // The java package for the application under test.
655  // The default value is determined by examining the application's manifest.
656  string app_package_id = 2;
657
658  // The initial activity that should be used to start the app.
659  string app_initial_activity = 3;
660
661  // The max depth of the traversal stack Robo can explore. Needs to be at least
662  // 2 to make Robo explore the app beyond the first activity.
663  // Default is 50.
664  int32 max_depth = 7 [deprecated = true];
665
666  // The max number of steps Robo can execute.
667  // Default is no limit.
668  int32 max_steps = 8 [deprecated = true];
669
670  // A set of directives Robo should apply during the crawl.
671  // This allows users to customize the crawl. For example, the username and
672  // password for a test account can be provided.
673  repeated RoboDirective robo_directives = 11;
674
675  // The mode in which Robo should run. Most clients should allow the server to
676  // populate this field automatically.
677  RoboMode robo_mode = 14;
678
679  // A JSON file with a sequence of actions Robo should perform as a prologue
680  // for the crawl.
681  FileReference robo_script = 13;
682
683  // The intents used to launch the app for the crawl.
684  // If none are provided, then the main launcher activity is launched.
685  // If some are provided, then only those provided are launched (the main
686  // launcher activity must be provided explicitly).
687  repeated RoboStartingIntent starting_intents = 15;
688}
689
690// The mode in which Robo should run.
691enum RoboMode {
692  // This means that the server should choose the mode.
693  // Recommended.
694  ROBO_MODE_UNSPECIFIED = 0;
695
696  // Runs Robo in UIAutomator-only mode without app resigning
697  ROBO_VERSION_1 = 1;
698
699  // Runs Robo in standard Espresso with UIAutomator fallback
700  ROBO_VERSION_2 = 2;
701}
702
703// Directs Robo to interact with a specific UI element if it is encountered
704// during the crawl. Currently, Robo can perform text entry or element click.
705message RoboDirective {
706  // Required. The android resource name of the target UI element.
707  // For example,
708  //    in Java: R.string.foo
709  //    in xml: @string/foo
710  // Only the "foo" part is needed.
711  // Reference doc:
712  // https://developer.android.com/guide/topics/resources/accessing-resources.html
713  string resource_name = 1;
714
715  // The text that Robo is directed to set. If left empty, the directive will be
716  // treated as a CLICK on the element matching the resource_name.
717  string input_text = 2;
718
719  // Required. The type of action that Robo should perform on the specified
720  // element.
721  RoboActionType action_type = 3;
722}
723
724// Actions which Robo can perform on UI elements.
725enum RoboActionType {
726  // DO NOT USE. For proto versioning only.
727  ACTION_TYPE_UNSPECIFIED = 0;
728
729  // Direct Robo to click on the specified element. No-op if specified element
730  // is not clickable.
731  SINGLE_CLICK = 1;
732
733  // Direct Robo to enter text on the specified element. No-op if specified
734  // element is not enabled or does not allow text entry.
735  ENTER_TEXT = 2;
736
737  // Direct Robo to ignore interactions with a specific element.
738  IGNORE = 3;
739}
740
741// Message for specifying the start activities to crawl.
742message RoboStartingIntent {
743  // Required. Intent details to start an activity.
744  oneof starting_intent {
745    // An intent that starts the main launcher activity.
746    LauncherActivityIntent launcher_activity = 1;
747
748    // An intent that starts an activity with specific details.
749    StartActivityIntent start_activity = 2;
750
751    // Skips the starting activity
752    NoActivityIntent no_activity = 4;
753  }
754
755  // Timeout in seconds for each intent.
756  google.protobuf.Duration timeout = 3;
757}
758
759// Specifies an intent that starts the main launcher activity.
760message LauncherActivityIntent {}
761
762// A starting intent specified by an action, uri, and categories.
763message StartActivityIntent {
764  // Action name.
765  // Required for START_ACTIVITY.
766  string action = 2;
767
768  // URI for the action.
769  string uri = 3;
770
771  // Intent categories to set on the intent.
772  repeated string categories = 4;
773}
774
775// Skips the starting activity
776message NoActivityIntent {}
777
778// The matrix of environments in which the test is to be executed.
779message EnvironmentMatrix {
780  // Required. The environment matrix.
781  oneof environment_matrix {
782    // A matrix of Android devices.
783    AndroidMatrix android_matrix = 1;
784
785    // A list of Android devices; the test will be run only on the specified
786    // devices.
787    AndroidDeviceList android_device_list = 2;
788
789    // A list of iOS devices.
790    IosDeviceList ios_device_list = 3;
791  }
792}
793
794// A list of Android device configurations in which the test is to be executed.
795message AndroidDeviceList {
796  // Required. A list of Android devices.
797  repeated AndroidDevice android_devices = 1;
798}
799
800// A list of iOS device configurations in which the test is to be executed.
801message IosDeviceList {
802  // Required. A list of iOS devices.
803  repeated IosDevice ios_devices = 1;
804}
805
806// A set of Android device configuration permutations is defined by the
807// the cross-product of the given axes. Internally, the given AndroidMatrix
808// will be expanded into a set of AndroidDevices.
809//
810// Only supported permutations will be instantiated.  Invalid permutations
811// (e.g., incompatible models/versions) are ignored.
812message AndroidMatrix {
813  // Required. The ids of the set of Android device to be used.
814  // Use the TestEnvironmentDiscoveryService to get supported options.
815  repeated string android_model_ids = 1;
816
817  // Required. The ids of the set of Android OS version to be used.
818  // Use the TestEnvironmentDiscoveryService to get supported options.
819  repeated string android_version_ids = 2;
820
821  // Required. The set of locales the test device will enable for testing.
822  // Use the TestEnvironmentDiscoveryService to get supported options.
823  repeated string locales = 3;
824
825  // Required. The set of orientations to test with.
826  // Use the TestEnvironmentDiscoveryService to get supported options.
827  repeated string orientations = 4;
828}
829
830// Information about the client which invoked the test.
831message ClientInfo {
832  // Required. Client name, such as gcloud.
833  string name = 1;
834
835  // The list of detailed information about client.
836  repeated ClientInfoDetail client_info_details = 2;
837}
838
839// Key-value pair of detailed information about the client which invoked the
840// test. Examples: {'Version', '1.0'}, {'Release Track', 'BETA'}.
841message ClientInfoDetail {
842  // Required. The key of detailed client information.
843  string key = 1;
844
845  // Required. The value of detailed client information.
846  string value = 2;
847}
848
849// Locations where the results of running the test are stored.
850message ResultStorage {
851  // Required.
852  GoogleCloudStorage google_cloud_storage = 1;
853
854  // The tool results history that contains the tool results execution that
855  // results are written to.
856  //
857  // If not provided, the service will choose an appropriate value.
858  ToolResultsHistory tool_results_history = 5;
859
860  // Output only. The tool results execution that results are written to.
861  ToolResultsExecution tool_results_execution = 6;
862
863  // Output only. URL to the results in the Firebase Web Console.
864  string results_url = 7;
865}
866
867// Represents a tool results history resource.
868message ToolResultsHistory {
869  // Required. The cloud project that owns the tool results history.
870  string project_id = 1;
871
872  // Required. A tool results history ID.
873  string history_id = 2;
874}
875
876// Represents a tool results execution resource.
877//
878// This has the results of a TestMatrix.
879message ToolResultsExecution {
880  // Output only. The cloud project that owns the tool results execution.
881  string project_id = 1;
882
883  // Output only. A tool results history ID.
884  string history_id = 2;
885
886  // Output only. A tool results execution ID.
887  string execution_id = 3;
888}
889
890// Represents a tool results step resource.
891//
892// This has the results of a TestExecution.
893message ToolResultsStep {
894  // Output only. The cloud project that owns the tool results step.
895  string project_id = 1;
896
897  // Output only. A tool results history ID.
898  string history_id = 2;
899
900  // Output only. A tool results execution ID.
901  string execution_id = 3;
902
903  // Output only. A tool results step ID.
904  string step_id = 4;
905}
906
907// A storage location within Google cloud storage (GCS).
908message GoogleCloudStorage {
909  // Required. The path to a directory in GCS that will
910  // eventually contain the results for this test.
911  // The requesting user must have write access on the bucket in the supplied
912  // path.
913  string gcs_path = 1;
914}
915
916// A reference to a file, used for user inputs.
917message FileReference {
918  // Required. The file reference.
919  oneof file {
920    // A path to a file in Google Cloud Storage.
921    // Example: gs://build-app-1414623860166/app%40debug-unaligned.apk
922    // These paths are expected to be url encoded (percent encoding)
923    string gcs_path = 1;
924  }
925}
926
927// The environment in which the test is run.
928message Environment {
929  // Required. The environment.
930  oneof environment {
931    // An Android device which must be used with an Android test.
932    AndroidDevice android_device = 1;
933
934    // An iOS device which must be used with an iOS test.
935    IosDevice ios_device = 2;
936  }
937}
938
939// A single Android device.
940message AndroidDevice {
941  // Required. The id of the Android device to be used.
942  // Use the TestEnvironmentDiscoveryService to get supported options.
943  string android_model_id = 1;
944
945  // Required. The id of the Android OS version to be used.
946  // Use the TestEnvironmentDiscoveryService to get supported options.
947  string android_version_id = 2;
948
949  // Required. The locale the test device used for testing.
950  // Use the TestEnvironmentDiscoveryService to get supported options.
951  string locale = 3;
952
953  // Required. How the device is oriented during the test.
954  // Use the TestEnvironmentDiscoveryService to get supported options.
955  string orientation = 4;
956}
957
958// A single iOS device.
959message IosDevice {
960  // Required. The id of the iOS device to be used.
961  // Use the TestEnvironmentDiscoveryService to get supported options.
962  string ios_model_id = 1;
963
964  // Required. The id of the iOS major software version to be used.
965  // Use the TestEnvironmentDiscoveryService to get supported options.
966  string ios_version_id = 2;
967
968  // Required. The locale the test device used for testing.
969  // Use the TestEnvironmentDiscoveryService to get supported options.
970  string locale = 3;
971
972  // Required. How the device is oriented during the test.
973  // Use the TestEnvironmentDiscoveryService to get supported options.
974  string orientation = 4;
975}
976
977// Additional details about the progress of the running test.
978message TestDetails {
979  // Output only. Human-readable, detailed descriptions of the test's progress.
980  // For example: "Provisioning a device", "Starting Test".
981  //
982  // During the course of execution new data may be appended
983  // to the end of progress_messages.
984  repeated string progress_messages = 3;
985
986  // Output only. If the TestState is ERROR, then this string will contain
987  // human-readable details about the error.
988  string error_message = 4;
989}
990
991// Details behind an invalid request.
992message InvalidRequestDetail {
993  // Possible invalid request reasons.
994  enum Reason {
995    // No reason has been specified - the default.
996    REASON_UNSPECIFIED = 0;
997
998    // The request is not valid.
999    REQUEST_INVALID = 1;
1000
1001    // One or more of the resources specified in the request is too large.
1002    RESOURCE_TOO_BIG = 2;
1003
1004    // One or more resources specified in the request cannot be found.
1005    RESOURCE_NOT_FOUND = 3;
1006
1007    // This request is not (currently) supported.
1008    UNSUPPORTED = 4;
1009
1010    // This request is not currently implemented.
1011    NOT_IMPLEMENTED = 5;
1012
1013    // The caller has no permission for storing the test results
1014    RESULT_STORAGE_PERMISSION_DENIED = 6;
1015  }
1016
1017  // The reason behind the error.
1018  Reason reason = 1;
1019}
1020
1021// The detailed reason that a Matrix was deemed INVALID.
1022enum InvalidMatrixDetails {
1023  // Do not use. For proto versioning only.
1024  INVALID_MATRIX_DETAILS_UNSPECIFIED = 0;
1025
1026  // The matrix is INVALID, but there are no further details available.
1027  DETAILS_UNAVAILABLE = 1;
1028
1029  // The input app APK could not be parsed.
1030  MALFORMED_APK = 2;
1031
1032  // The input test APK could not be parsed.
1033  MALFORMED_TEST_APK = 3;
1034
1035  // The AndroidManifest.xml could not be found.
1036  NO_MANIFEST = 4;
1037
1038  // The APK manifest does not declare a package name.
1039  NO_PACKAGE_NAME = 5;
1040
1041  // The APK application ID (aka package name) is invalid.
1042  // See also
1043  // https://developer.android.com/studio/build/application-id
1044  INVALID_PACKAGE_NAME = 31;
1045
1046  // The test package and app package are the same.
1047  TEST_SAME_AS_APP = 6;
1048
1049  // The test apk does not declare an instrumentation.
1050  NO_INSTRUMENTATION = 7;
1051
1052  // The input app apk does not have a signature.
1053  NO_SIGNATURE = 20;
1054
1055  // The test runner class specified by user or in the test APK's manifest file
1056  // is not compatible with Android Test Orchestrator.
1057  // Orchestrator is only compatible with AndroidJUnitRunner version 1.1 or
1058  // higher.
1059  // Orchestrator can be disabled by using DO_NOT_USE_ORCHESTRATOR
1060  // OrchestratorOption.
1061  INSTRUMENTATION_ORCHESTRATOR_INCOMPATIBLE = 18;
1062
1063  // The test APK does not contain the test runner class specified by the user
1064  // or in the manifest file. This can be caused by one of the following
1065  // reasons:
1066  //
1067  // - the user provided a runner class name that's incorrect, or
1068  // - the test runner isn't built into the test APK (might be in the app APK
1069  // instead).
1070  NO_TEST_RUNNER_CLASS = 19;
1071
1072  // A main launcher activity could not be found.
1073  NO_LAUNCHER_ACTIVITY = 8;
1074
1075  // The app declares one or more permissions that are not allowed.
1076  FORBIDDEN_PERMISSIONS = 9;
1077
1078  // There is a conflict in the provided robo_directives.
1079  INVALID_ROBO_DIRECTIVES = 10;
1080
1081  // There is at least one invalid resource name in the provided
1082  // robo directives
1083  INVALID_RESOURCE_NAME = 33;
1084
1085  // Invalid definition of action in the robo directives
1086  // (e.g. a click or ignore action includes an input text field)
1087  INVALID_DIRECTIVE_ACTION = 34;
1088
1089  // There is no test loop intent filter, or the one that is given is
1090  // not formatted correctly.
1091  TEST_LOOP_INTENT_FILTER_NOT_FOUND = 12;
1092
1093  // The request contains a scenario label that was not declared in the
1094  // manifest.
1095  SCENARIO_LABEL_NOT_DECLARED = 13;
1096
1097  // There was an error when parsing a label's value.
1098  SCENARIO_LABEL_MALFORMED = 14;
1099
1100  // The request contains a scenario number that was not declared in the
1101  // manifest.
1102  SCENARIO_NOT_DECLARED = 15;
1103
1104  // Device administrator applications are not allowed.
1105  DEVICE_ADMIN_RECEIVER = 17;
1106
1107  // The zipped XCTest was malformed. The zip did not contain a single
1108  // .xctestrun file and the contents of the DerivedData/Build/Products
1109  // directory.
1110  MALFORMED_XC_TEST_ZIP = 11;
1111
1112  // The zipped XCTest was built for the iOS simulator rather than for a
1113  // physical device.
1114  BUILT_FOR_IOS_SIMULATOR = 24;
1115
1116  // The .xctestrun file did not specify any test targets.
1117  NO_TESTS_IN_XC_TEST_ZIP = 25;
1118
1119  // One or more of the test targets defined in the .xctestrun file specifies
1120  // "UseDestinationArtifacts", which is disallowed.
1121  USE_DESTINATION_ARTIFACTS = 26;
1122
1123  // XC tests which run on physical devices must have
1124  // "IsAppHostedTestBundle" == "true" in the xctestrun file.
1125  TEST_NOT_APP_HOSTED = 28;
1126
1127  // An Info.plist file in the XCTest zip could not be parsed.
1128  PLIST_CANNOT_BE_PARSED = 30;
1129
1130  // The APK is marked as "testOnly".
1131  // Deprecated and not currently used.
1132  TEST_ONLY_APK = 21 [deprecated = true];
1133
1134  // The input IPA could not be parsed.
1135  MALFORMED_IPA = 22;
1136
1137  // The application doesn't register the game loop URL scheme.
1138  MISSING_URL_SCHEME = 35;
1139
1140  // The iOS application bundle (.app) couldn't be processed.
1141  MALFORMED_APP_BUNDLE = 36;
1142
1143  // APK contains no code.
1144  // See also
1145  // https://developer.android.com/guide/topics/manifest/application-element.html#code
1146  NO_CODE_APK = 23;
1147
1148  // Either the provided input APK path was malformed,
1149  // the APK file does not exist, or the user does not have permission to
1150  // access the APK file.
1151  INVALID_INPUT_APK = 27;
1152
1153  // APK is built for a preview SDK which is unsupported
1154  INVALID_APK_PREVIEW_SDK = 29;
1155
1156  // The matrix expanded to contain too many executions.
1157  MATRIX_TOO_LARGE = 37;
1158
1159  // Not enough test quota to run the executions in this matrix.
1160  TEST_QUOTA_EXCEEDED = 39;
1161
1162  // A required cloud service api is not activated.
1163  // See:
1164  // https://firebase.google.com/docs/test-lab/android/continuous#requirements
1165  SERVICE_NOT_ACTIVATED = 40;
1166
1167  // There was an unknown permission issue running this test.
1168  UNKNOWN_PERMISSION_ERROR = 41;
1169}
1170
1171// The state (i.e., progress) of a test execution or matrix.
1172enum TestState {
1173  // Do not use.  For proto versioning only.
1174  TEST_STATE_UNSPECIFIED = 0;
1175
1176  // The execution or matrix is being validated.
1177  VALIDATING = 8;
1178
1179  // The execution or matrix is waiting for resources to become available.
1180  PENDING = 1;
1181
1182  // The execution is currently being processed.
1183  //
1184  // Can only be set on an execution.
1185  RUNNING = 2;
1186
1187  // The execution or matrix has terminated normally.
1188  //
1189  // On a matrix this means that the matrix level processing completed normally,
1190  // but individual executions may be in an ERROR state.
1191  FINISHED = 3;
1192
1193  // The execution or matrix has stopped because it encountered an
1194  // infrastructure failure.
1195  ERROR = 4;
1196
1197  // The execution was not run because it corresponds to a unsupported
1198  // environment.
1199  //
1200  // Can only be set on an execution.
1201  UNSUPPORTED_ENVIRONMENT = 5;
1202
1203  // The execution was not run because the provided inputs are incompatible with
1204  // the requested environment.
1205  //
1206  // Example: requested AndroidVersion is lower than APK's minSdkVersion
1207  //
1208  // Can only be set on an execution.
1209  INCOMPATIBLE_ENVIRONMENT = 9;
1210
1211  // The execution was not run because the provided inputs are incompatible with
1212  // the requested architecture.
1213  //
1214  // Example: requested device does not support running the native code in
1215  // the supplied APK
1216  //
1217  // Can only be set on an execution.
1218  INCOMPATIBLE_ARCHITECTURE = 10;
1219
1220  // The user cancelled the execution.
1221  //
1222  // Can only be set on an execution.
1223  CANCELLED = 6;
1224
1225  // The execution or matrix was not run because the provided inputs are not
1226  // valid.
1227  //
1228  // Examples: input file is not of the expected type, is malformed/corrupt, or
1229  // was flagged as malware
1230  INVALID = 7;
1231}
1232
1233// Outcome summary for a finished test matrix.
1234enum OutcomeSummary {
1235  // Do not use. For proto versioning only.
1236  OUTCOME_SUMMARY_UNSPECIFIED = 0;
1237
1238  // The test matrix run was successful, for instance:
1239  //
1240  // - All the test cases passed.
1241  // - Robo did not detect a crash of the application under test.
1242  SUCCESS = 1;
1243
1244  // A run failed, for instance:
1245  //
1246  // - One or more test cases failed.
1247  // - A test timed out.
1248  // - The application under test crashed.
1249  FAILURE = 2;
1250
1251  // Something unexpected happened. The run should still be considered
1252  // unsuccessful but this is likely a transient problem and re-running the
1253  // test might be successful.
1254  INCONCLUSIVE = 3;
1255
1256  // All tests were skipped, for instance:
1257  //
1258  // - All device configurations were incompatible.
1259  SKIPPED = 4;
1260}
1261
1262// Options for enabling sharding.
1263message ShardingOption {
1264  oneof option {
1265    // Uniformly shards test cases given a total number of shards.
1266    UniformSharding uniform_sharding = 1;
1267
1268    // Shards test cases into the specified groups of packages, classes, and/or
1269    // methods.
1270    ManualSharding manual_sharding = 2;
1271
1272    // Shards test based on previous test case timing records.
1273    SmartSharding smart_sharding = 3;
1274  }
1275}
1276
1277// Uniformly shards test cases given a total number of shards.
1278//
1279// For instrumentation tests, it will be translated to "-e numShard" and "-e
1280// shardIndex" AndroidJUnitRunner arguments. With uniform sharding enabled,
1281// specifying either of these sharding arguments via `environment_variables` is
1282// invalid.
1283//
1284// Based on the sharding mechanism AndroidJUnitRunner uses, there is no
1285// guarantee that test cases will be distributed uniformly across all shards.
1286message UniformSharding {
1287  // Required. The total number of shards to create. This must always be a
1288  // positive number that is no greater than the total number of test cases.
1289  // When you select one or more physical devices, the number of shards must be
1290  // <= 50. When you select one or more ARM virtual devices, it must be <= 200.
1291  // When you select only x86 virtual devices, it must be <= 500.
1292  int32 num_shards = 1;
1293}
1294
1295// Shards test cases into the specified groups of packages, classes, and/or
1296// methods.
1297//
1298// With manual sharding enabled, specifying test targets via
1299// environment_variables or in InstrumentationTest is invalid.
1300message ManualSharding {
1301  // Required. Group of packages, classes, and/or test methods to be run for
1302  // each manually-created shard. You must specify at least one shard if this
1303  // field is present. When you select one or more physical devices, the number
1304  // of repeated test_targets_for_shard must be <= 50. When you select one or
1305  // more ARM virtual devices, it must be <= 200. When you select only x86
1306  // virtual devices, it must be <= 500.
1307  repeated TestTargetsForShard test_targets_for_shard = 1;
1308}
1309
1310// Test targets for a shard.
1311message TestTargetsForShard {
1312  // Group of packages, classes, and/or test methods to be run for each shard.
1313  // The targets need to be specified in AndroidJUnitRunner argument format. For
1314  // example, "package com.my.packages" "class com.my.package.MyClass".
1315  //
1316  // The number of test_targets must be greater than 0.
1317  repeated string test_targets = 1;
1318}
1319
1320// Shards test based on previous test case timing records.
1321message SmartSharding {
1322  // The amount of time tests within a shard should take.
1323  //
1324  // Default: 300 seconds (5 minutes).
1325  // The minimum allowed: 120 seconds (2 minutes).
1326  //
1327  // The shard count is dynamically set based on time, up to the maximum shard
1328  // limit (described below). To guarantee at least one test case for each
1329  // shard, the number of shards will not exceed the number of test cases. Shard
1330  // duration will be exceeded if:
1331  //
1332  // - The maximum shard limit is reached and there is more calculated test time
1333  // remaining to allocate into shards.
1334  // - Any individual test is estimated to be longer than the targeted shard
1335  // duration.
1336  //
1337  // Shard duration is not guaranteed because smart sharding uses test case
1338  // history and default durations which may not be accurate. The rules for
1339  // finding the test case timing records are:
1340  //
1341  // - If the service has processed a test case in the last 30 days, the record
1342  //  of the latest successful test case will be used.
1343  // - For new test cases, the average duration of other known test cases will
1344  //  be used.
1345  // - If there are no previous test case timing records available, the default
1346  //  test case duration is 15 seconds.
1347  //
1348  // Because the actual shard duration can exceed the targeted shard duration,
1349  // we recommend that you set the targeted value at least 5 minutes less than
1350  // the maximum allowed test timeout (45 minutes for physical devices and 60
1351  // minutes for virtual), or that you use the custom test timeout value that
1352  // you set. This approach avoids cancelling the shard before all tests can
1353  // finish.
1354  //
1355  // Note that there is a limit for maximum number of shards. When you select
1356  // one or more physical devices, the number of shards must be <= 50. When you
1357  // select one or more ARM virtual devices, it must be <= 200. When you select
1358  // only x86 virtual devices, it must be <= 500. To guarantee at least one test
1359  // case for per shard, the number of shards will not exceed the number of test
1360  // cases. Each shard created counts toward daily test quota.
1361  google.protobuf.Duration targeted_shard_duration = 1;
1362}
1363
1364// Output only. Details about the shard.
1365message Shard {
1366  // Output only. The index of the shard among all the shards.
1367  int32 shard_index = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
1368
1369  // Output only. The total number of shards.
1370  int32 num_shards = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
1371
1372  // Output only. Test targets for each shard. Only set for manual sharding.
1373  TestTargetsForShard test_targets_for_shard = 3
1374      [(google.api.field_behavior) = OUTPUT_ONLY];
1375
1376  // Output only. The estimated shard duration based on previous test case
1377  // timing records, if available.
1378  google.protobuf.Duration estimated_shard_duration = 4
1379      [(google.api.field_behavior) = OUTPUT_ONLY];
1380}
1381
1382// Request to submit a matrix of tests for execution.
1383message CreateTestMatrixRequest {
1384  // The GCE project under which this job will run.
1385  string project_id = 1;
1386
1387  // The matrix of tests that the user wants to run.
1388  TestMatrix test_matrix = 2;
1389
1390  // A string id used to detect duplicated requests.
1391  // Ids are automatically scoped to a project, so
1392  // users should ensure the ID is unique per-project.
1393  // A UUID is recommended.
1394  //
1395  // Optional, but strongly recommended.
1396  string request_id = 3;
1397}
1398
1399// Request to get the Test Matrix with the given id.
1400message GetTestMatrixRequest {
1401  // Cloud project that owns the test matrix.
1402  string project_id = 1;
1403
1404  // Unique test matrix id which was assigned by the service.
1405  string test_matrix_id = 2;
1406}
1407
1408// Request to stop running all of the tests in the specified matrix.
1409message CancelTestMatrixRequest {
1410  // Cloud project that owns the test.
1411  string project_id = 1;
1412
1413  // Test matrix that will be canceled.
1414  string test_matrix_id = 2;
1415}
1416
1417// Response containing the current state of the specified test matrix.
1418message CancelTestMatrixResponse {
1419  // The current rolled-up state of the test matrix.
1420  // If this state is already final, then the cancelation request will
1421  // have no effect.
1422  TestState test_state = 1;
1423}
1424