| // Copyright 2019 The LUCI Authors. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| syntax = "proto3"; |
| |
| package luci.resultdb.v1; |
| |
| import "google/api/field_behavior.proto"; |
| import "google/protobuf/struct.proto"; |
| import "google/protobuf/timestamp.proto"; |
| import "go.chromium.org/luci/resultdb/proto/v1/common.proto"; |
| import "go.chromium.org/luci/resultdb/proto/v1/predicate.proto"; |
| |
| option go_package = "go.chromium.org/luci/resultdb/proto/v1;resultpb"; |
| |
| // A conceptual container of results. Immutable once finalized. |
| // It represents all results of some computation; examples: swarming task, |
| // buildbucket build, CQ attempt. |
| // Composable: can include other invocations, see inclusion.proto. |
| // |
| // Next id: 15. |
| message Invocation { |
| reserved 3; // bool interrupted, crbug.com/1078696. |
| |
| // Can be used to refer to this invocation, e.g. in ResultDB.GetInvocation |
| // RPC. |
| // Format: invocations/{INVOCATION_ID} |
| // See also https://aip.dev/122. |
| // |
| // Output only. |
| string name = 1 [ |
| (google.api.field_behavior) = OUTPUT_ONLY, |
| (google.api.field_behavior) = IMMUTABLE |
| ]; |
| |
| enum State { |
| // The default value. This value is used if the state is omitted. |
| STATE_UNSPECIFIED = 0; |
| |
| // The invocation was created and accepts new results. |
| ACTIVE = 1; |
| |
| // The invocation is in the process of transitioning into FINALIZED state. |
| // This will happen automatically soon after all of its directly or |
| // indirectly included invocations become inactive. |
| FINALIZING = 2; |
| |
| // The invocation is immutable and no longer accepts new results nor |
| // inclusions directly or indirectly. |
| FINALIZED = 3; |
| } |
| |
| // Current state of the invocation. |
| // |
| // At creation time this can be set to FINALIZING e.g. if this invocation is |
| // a simple wrapper of another and will itself not be modified. |
| // |
| // Otherwise this is an output only field. |
| State state = 2; |
| |
| // When the invocation was created. |
| // Output only. |
| google.protobuf.Timestamp create_time = 4 [ |
| (google.api.field_behavior) = OUTPUT_ONLY, |
| (google.api.field_behavior) = IMMUTABLE |
| ]; |
| |
| // Invocation-level string key-value pairs. |
| // A key can be repeated. |
| repeated StringPair tags = 5; |
| |
| // == Finalization =========================================================== |
| |
| // When the invocation was finalized, i.e. transitioned to FINALIZED state. |
| // If this field is set, implies that the invocation is finalized. |
| // |
| // Output only. |
| google.protobuf.Timestamp finalize_time = 6 |
| [ (google.api.field_behavior) = OUTPUT_ONLY ]; |
| |
| // Timestamp when the invocation will be forcefully finalized. |
| // Can be extended with UpdateInvocation until finalized. |
| google.protobuf.Timestamp deadline = 7; |
| |
| // Names of invocations included into this one. Overall results of this |
| // invocation is a UNION of results directly included into this invocation |
| // and results from the included invocations, recursively. |
| // For example, a Buildbucket build invocation may include invocations of its |
| // child swarming tasks and represent overall result of the build, |
| // encapsulating the internal structure of the build. |
| // |
| // The graph is directed. |
| // There can be at most one edge between a given pair of invocations. |
| // The shape of the graph does not matter. What matters is only the set of |
| // reachable invocations. Thus cycles are allowed and are noop. |
| // |
| // QueryTestResults returns test results from the transitive closure of |
| // invocations. |
| // |
| // This field can be set under Recorder.CreateInvocationsRequest to include |
| // existing invocations at the moment of invocation creation. |
| // New invocations created in the same batch (via |
| // Recorder.BatchCreateInvocationsRequest) are also allowed. |
| // Otherwise, this field is to be treated as Output only. |
| // |
| // To modify included invocations, use Recorder.UpdateIncludedInvocations in |
| // all other cases. |
| repeated string included_invocations = 8; |
| |
| // bigquery_exports indicates what BigQuery table(s) that results in this |
| // invocation should export to. |
| repeated BigQueryExport bigquery_exports = 9; |
| |
| // LUCI identity (e.g. "user:<email>") who created the invocation. |
| // Typically, a LUCI service account (e.g. |
| // "user:cr-buildbucket@appspot.gserviceaccount.com"), but can also be a user |
| // (e.g. "user:johndoe@example.com"). |
| // |
| // Output only. |
| string created_by = 10 [ (google.api.field_behavior) = OUTPUT_ONLY ]; |
| |
| // Full name of the resource that produced results in this invocation. |
| // See also https://aip.dev/122#full-resource-names |
| // Typical examples: |
| // - Swarming task: "//chromium-swarm.appspot.com/tasks/deadbeef" |
| // - Buildbucket build: "//cr-buildbucket.appspot.com/builds/1234567890". |
| string producer_resource = 11; |
| |
| // Realm that the invocation exists under. |
| // See https://chromium.googlesource.com/infra/luci/luci-py/+/refs/heads/master/appengine/auth_service/proto/realms_config.proto |
| string realm = 12; |
| |
| // Deprecated. Values specified here are ignored. |
| HistoryOptions history_options = 13; |
| |
| // Arbitrary JSON object that contains structured, domain-specific properties |
| // of the invocation. |
| // |
| // The serialized size must be <= 4096 bytes. |
| google.protobuf.Struct properties = 14; |
| |
| // The code sources which were tested by this invocation. |
| // This is used to index test results for test history, and for |
| // related analyses (e.g. culprit analysis / changepoint analyses). |
| // |
| // The sources specified here applies only to: |
| // - the test results directly contained in this invocation, and |
| // - any directly included invocations which set their source_spec.inherit to |
| // true. |
| // |
| // Clients should be careful to ensure the uploaded source spec is consistent |
| // between included invocations that upload the same test variants. |
| // Verdicts are associated with the sources of *any* of their constituent |
| // test results, so if there is inconsistency between included invocations, |
| // the position of the verdict becomes not well defined. |
| SourceSpec source_spec = 15; |
| } |
| |
| // BigQueryExport indicates that results in this invocation should be exported |
| // to BigQuery after finalization. |
| message BigQueryExport { |
| // Name of the BigQuery project. |
| string project = 1 [ (google.api.field_behavior) = REQUIRED ]; |
| |
| // Name of the BigQuery Dataset. |
| string dataset = 2 [ (google.api.field_behavior) = REQUIRED ]; |
| |
| // Name of the BigQuery Table. |
| string table = 3 [ (google.api.field_behavior) = REQUIRED ]; |
| |
| // TestResults indicates that test results should be exported. |
| message TestResults { |
| // Use predicate to query test results that should be exported to |
| // BigQuery table. |
| TestResultPredicate predicate = 1; |
| } |
| |
| // TextArtifacts indicates that text artifacts should be exported. |
| message TextArtifacts { |
| // Use predicate to query artifacts that should be exported to |
| // BigQuery table. |
| // |
| // Sub-field predicate.content_type_regexp defaults to "text/.*". |
| ArtifactPredicate predicate = 1; |
| } |
| |
| oneof result_type { |
| TestResults test_results = 4; |
| TextArtifacts text_artifacts = 6; |
| } |
| } |
| |
| // HistoryOptions indicates how the invocations should be indexed, so that their |
| // results can be queried over a range of time or of commits. |
| // Deprecated: do not use. |
| message HistoryOptions { |
| // Set this to index the results by the containing invocation's create_time. |
| bool use_invocation_timestamp = 1; |
| |
| // Set this to index by commit position. |
| // It's up to the creator of the invocation to set this consistently over |
| // time across the same test variant. |
| CommitPosition commit = 2; |
| } |
| |
| // Specifies the source code that was tested in an invocation, either directly |
| // (via the sources field) or indirectly (via inherit_sources). |
| message SourceSpec { |
| // Specifies the source position that was tested. |
| // Either this or inherit_sources may be set, but not both. |
| Sources sources = 1; |
| |
| // Specifies that the source position of the invocation is inherited |
| // from the parent invocation it is included in. |
| // |
| // # Use case |
| // This is useful in situations where the testing infrastructure deduplicates |
| // execution of tests on identical binaries (e.g. using swarming's task |
| // deduplication feature). |
| // |
| // Let A be the invocation for a swarming task that receives only a |
| // test binary as input, with task deduplication enabled. |
| // Let B be the invocation for a buildbucket build which built the |
| // binary from sources (or at the very least knew the sources) |
| // and triggered invocation A. |
| // Invocation B includes invocation A. |
| // |
| // By setting A's source_spec to inherit, and specifying the sources |
| // on invocation B, the test results in A will be associated with |
| // the sources specified on invocation B, when queried via invocation B. |
| // |
| // This allows further invocations B2, B3 ... BN to be created which also |
| // re-use the test results in A but associate them with possibly different |
| // sources when queried via B2 ... BN (this is valid so long as the sources |
| // produce a binary-identical testing input). |
| // |
| // # Multiple inclusion paths |
| // It is possible for an invocation A to be included in the reachable |
| // invocation graph for an invocation C in more than one way. |
| // |
| // For example, we may have: |
| // A -> B1 -> C |
| // A -> B2 -> C |
| // as two paths of inclusion. |
| // |
| // If A sets inherit to true, the commit position assigned to its |
| // test results will be selected via *one* of the paths of inclusion |
| // into C (i.e. from B1 or B2). |
| // |
| // However, which path is selected is not guaranteed, so if clients |
| // must include the same invocation multiple times, they should |
| // make the source position via all paths the same. |
| bool inherit = 2; |
| } |
| |
| // Specifies the source code that was tested. |
| message Sources { |
| // The base version of code sources checked out. Mandatory. |
| // If necessary, we could add support for non-gitiles sources here in |
| // future, using a oneof statement. E.g. |
| // oneof system { |
| // GitilesCommit gitiles_commit = 1; |
| // SubversionRevision svn_revision = 4; |
| // ... |
| // } |
| GitilesCommit gitiles_commit = 1; |
| |
| // The changelist(s) which were applied upon the base version of sources |
| // checked out. E.g. in commit queue tryjobs. |
| // |
| // At most 10 changelist(s) may be specified here. If there |
| // are more, only include the first 10 and set is_dirty. |
| repeated GerritChange changelists = 2; |
| |
| // Whether there were any changes made to the sources, not described above. |
| // For example, a version of a dependency was upgraded before testing (e.g. |
| // in an autoroller recipe). |
| // |
| // Cherry-picking a changelist on top of the base checkout is not considered |
| // making the sources dirty as it is reported separately above. |
| bool is_dirty = 3; |
| } |