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