• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17syntax = "proto3";
18
19package luci.resultdb.v1;
20
21import "google/api/field_behavior.proto";
22import "google/protobuf/empty.proto";
23import "google/protobuf/field_mask.proto";
24
25import public "tools/tradefederation/core/proto/resultdb/invocation.proto";
26import public "tools/tradefederation/core/proto/resultdb/artifact.proto";
27import public "tools/tradefederation/core/proto/resultdb/test_result.proto";
28
29option go_package = "go.chromium.org/luci/resultdb/proto/v1;resultpb";
30option java_package = "com.android.resultdb.proto";
31option java_multiple_files = true;
32option java_generic_services = true;
33
34// Service to record test results.
35//
36// CreateInvocation response includes a metadata key "update-token".
37// It MUST be passed to all other mutation RPCs, such as CreateTestResult.
38// Otherwise the request will fail with UNAUTHENTICATED error code.
39//
40// RPCs that mutate an invocation return FAILED_PRECONDITION error code if the
41// invocation is finalized.
42service Recorder {
43
44  // == Invocations ============================================================
45
46  // Creates a new invocation.
47  // The request specifies the invocation id and its contents.
48  //
49  // The response header metadata contains "update-token" required for future
50  // updates, including finalization.
51  //
52  // If invocation with the given ID already exists, returns ALREADY_EXISTS
53  // error code.
54  rpc CreateInvocation(CreateInvocationRequest) returns (Invocation) {};
55
56  // Creates multiple invocations in a single rpc.
57  //
58  // The response header metadata contains a multi-valued "update-token"
59  // required for future updates, including finalization. The tokens will be
60  // given in the same order as BatchCreateInvocationRequest.requests.
61  rpc BatchCreateInvocations(BatchCreateInvocationsRequest)
62      returns (BatchCreateInvocationsResponse) {};
63
64  // Updates an existing non-finalized invocation.
65  rpc UpdateInvocation(UpdateInvocationRequest) returns (Invocation) {};
66
67  // Transitions the given invocation to the state FINALIZED.
68  rpc FinalizeInvocation(FinalizeInvocationRequest) returns (Invocation) {};
69
70  // Updates inclusions for a non-finalized invocation.
71  rpc UpdateIncludedInvocations(UpdateIncludedInvocationsRequest)
72      returns (google.protobuf.Empty) {};
73
74  // Recursively marks all test variants associated with the invocation as
75  // submitted, merging them into the invocation's associated baseline.
76  rpc MarkInvocationSubmitted(MarkInvocationSubmittedRequest)
77      returns (google.protobuf.Empty) {};
78
79  // == Test results ===========================================================
80
81  // Appends a test result to a non-finalized invocation.
82  rpc CreateTestResult(CreateTestResultRequest) returns (TestResult) {};
83  // Atomically appends a batch of test results to a non-finalized invocation.
84  rpc BatchCreateTestResults(BatchCreateTestResultsRequest)
85      returns (BatchCreateTestResultsResponse) {};
86
87  // Appends a test exoneration to a non-finalized invocation.
88  rpc CreateTestExoneration(CreateTestExonerationRequest)
89      returns (TestExoneration) {};
90  // Atomically appends a batch of test exonerations to a non-finalized
91  // invocation.
92  rpc BatchCreateTestExonerations(BatchCreateTestExonerationsRequest)
93      returns (BatchCreateTestExonerationsResponse) {};
94
95  // == Artifacts ==============================================================
96
97  // Create multiple artifacts.
98  //
99  // An artifact can be either invocation-level or test-result-level.
100  // See Artifact.name for more info.
101  rpc BatchCreateArtifacts(BatchCreateArtifactsRequest)
102      returns (BatchCreateArtifactsResponse) {};
103}
104
105// == Invocations ==============================================================
106
107// A request message for CreateInvocation.
108message CreateInvocationRequest {
109  // Invocation identifier, becomes a part of the invocation.name.
110  // LUCI systems MAY create invocations with nicely formatted IDs, such as
111  // "build-1234567890". All other clients MUST use GUIDs.
112  //
113  // Regex: ^[a-z][a-z0-9_\-]*$.
114  string invocation_id = 1 [ (google.api.field_behavior) = REQUIRED ];
115
116  // Invocation data to insert.
117  Invocation invocation = 2;
118
119  // A unique identifier for this request. Restricted to 36 ASCII characters.
120  // A random UUID is recommended.
121  // This request is only idempotent if a `request_id` is provided.
122  string request_id = 3;
123}
124
125// A request message for BatchCreateInvocations
126message BatchCreateInvocationsRequest {
127  // requests[i].request_id MUST be either empty or equal to request_id in
128  // this message.
129  //
130  // Up to 500 requests.
131  repeated CreateInvocationRequest requests = 1;
132
133  // A unique identifier for this request. Restricted to 36 ASCII characters.
134  // A random UUID is recommended.
135  // This request is only idempotent if a `request_id` is provided, so it is
136  // strongly recommended to populate this field.
137  string request_id = 2;
138}
139
140
141// A response message for BatchCreateInvocations RPC.
142message BatchCreateInvocationsResponse {
143  // Invocations created.
144  repeated Invocation invocations = 1;
145
146  // One token per each created invocation.
147  // These are passed in the response instead of as metadata, because large
148  // batches increase the size of the response headers beyond allowed limits and
149  // cause failures like crbug.com/1064496
150  // update_tokens[i] corresponds to invocations[i].
151  // *Do not log these values*.
152  repeated string update_tokens = 2;
153}
154
155
156// A request message for UpdateInvocation RPC.
157message UpdateInvocationRequest {
158  // Invocation to update.
159  Invocation invocation = 1 [ (google.api.field_behavior) = REQUIRED ];
160
161  // The list of fields to be updated.
162  google.protobuf.FieldMask update_mask = 2;
163}
164
165// A request message for FinalizeInvocation RPC.
166message FinalizeInvocationRequest {
167  // Name of the invocation to finalize.
168  string name = 1 [ (google.api.field_behavior) = REQUIRED ];
169}
170
171// A request message for UpdateIncludedInvocations RPC.
172message UpdateIncludedInvocationsRequest {
173  // Name of the invocation to add/remove inclusions to/from,
174  // see Invocation.name.
175  // For example, name of the buildbucket build invocation that should include
176  // a swarming task invocation.
177  string including_invocation = 1 [ (google.api.field_behavior) = REQUIRED ];
178
179  // Names of the invocations to include, see Invocation.name.
180  // If any of these invocations are already included, they will be silently
181  // ignored for idempotency.
182  repeated string add_invocations = 2;
183
184  // Deprecated: Removing invocations is no longer supported. Do not use.
185  repeated string remove_invocations = 3;
186}
187
188// A request message for MarkInvocationSubmitted RPC.
189// To use this RPC, callers need:
190// - resultdb.invocations.setSubmitted in the realm the <project>:@project, where
191//   project is the project of the nominated invocation.
192message MarkInvocationSubmittedRequest {
193  // Name of the invocation, e.g. "invocations/{id}".
194  string invocation = 1 [ (google.api.field_behavior) = REQUIRED ];
195}
196
197
198// A request message for CreateTestResult RPC.
199message CreateTestResultRequest {
200  // Name of the parent invocation, see Invocation.name.
201  string invocation = 1 [ (google.api.field_behavior) = REQUIRED ];
202
203  // The test result to create.
204  // Test id and result id are used to dedupe requests, i.e.
205  // if a test result with the same test id and result id already exists in
206  // the invocation, then the requests succeeds as opposed to returns with
207  // ALREADY_EXISTS error.
208  TestResult test_result = 2 [ (google.api.field_behavior) = REQUIRED ];
209
210  // A unique identifier for this request. Restricted to 36 ASCII characters.
211  // A random UUID is recommended.
212  // This request is only idempotent if a `request_id` is provided, so it is
213  // strongly recommended to populate this field.
214  //
215  // Impl note: this field is used to compute the spanner-level result id, which
216  // will encode tuple (request_id, index_of_request)", where
217  // - request_id is a random GUID if not provided by the user
218  // - index_of_request is 0 in CreateTestResult RPC, or index of the request
219  //   in BatchCreateTestResultsRequest in the batch RPC.
220  // TODO(jchinlee): remove this impl note when it is converted into code.
221  string request_id = 3;
222}
223
224// == Test results =============================================================
225
226// A request message for BatchCreateTestResults RPC.
227message BatchCreateTestResultsRequest {
228  // Name of the parent invocation, see Invocation.name.
229  string invocation = 1 [ (google.api.field_behavior) = REQUIRED ];
230
231  // Requests to create test results.
232  // requests[i].invocation MUST be either empty or equal to invocation in this
233  // message.
234  // requests[i].request_id MUST be either empty or equal to request_id in
235  // this message.
236  //
237  // Up to 500 requests.
238  repeated CreateTestResultRequest requests = 2;
239
240  // A unique identifier for this request. Restricted to 36 ASCII characters.
241  // A random UUID is recommended.
242  // This request is only idempotent if a `request_id` is provided, so it is
243  // strongly recommended to populate this field.
244  //
245  string request_id = 3;
246}
247
248// A response message for BatchCreateTestResults RPC.
249message BatchCreateTestResultsResponse {
250  // Test results created.
251  repeated TestResult test_results = 1;
252}
253
254// A request message for CreateTestExoneration RPC.
255message CreateTestExonerationRequest {
256  // Name of the parent invocation, see Invocation.name.
257  string invocation = 1 [ (google.api.field_behavior) = REQUIRED ];
258
259  // The TestExoneration to create.
260  TestExoneration test_exoneration = 2
261      [ (google.api.field_behavior) = REQUIRED ];
262
263  // A unique identifier for this request. Restricted to 36 ASCII characters.
264  // A random UUID is recommended.
265  // This request is only idempotent if a `request_id` is provided.
266  string request_id = 3;
267}
268
269// A request message for BatchCreateTestExonerations RPC.
270message BatchCreateTestExonerationsRequest {
271  // Name of the parent invocation, see Invocation.name.
272  string invocation = 1 [ (google.api.field_behavior) = REQUIRED ];
273
274  // Requests to create TestExonerations.
275  // requests[i].invocation MUST be either empty or equal to invocation in this
276  // message.
277  // requests[i].request_id MUST be either empty or equal to request_id in
278  // this message.
279  //
280  // Up to 500 requests.
281  repeated CreateTestExonerationRequest requests = 2;
282
283  // A unique identifier for this request. Restricted to 36 ASCII characters.
284  // A random UUID is recommended.
285  // This request is only idempotent if a `request_id` is provided, so it is
286  // strongly recommended to populate this field.
287  string request_id = 3;
288}
289
290// A response message for BatchCreateTestExonerations RPC.
291message BatchCreateTestExonerationsResponse {
292  // Test exonerations created.
293  repeated TestExoneration test_exonerations = 1;
294}
295
296// == Artifacts ================================================================
297
298// A request message for CreateArtifactRequest.
299message CreateArtifactRequest {
300  // Name of the parent resource where the artifact will be created.
301  //
302  // For invocation-level artifacts, it is the invocation name.
303  // For test-result-level artifacts, it is the TestResult name.
304  string parent = 1 [ (google.api.field_behavior) = REQUIRED ];
305
306  // Artifact to upload.
307  // The length of the artifact contents MUST be <= 512KiB.
308  // artifact.artifact_id MUST be set.
309  // artifact.name will be ignored.
310  Artifact artifact = 2 [ (google.api.field_behavior) = REQUIRED ];
311}
312
313// A request message for BatchCreateArtifactsRequest.
314message BatchCreateArtifactsRequest {
315  // Requests to create Artifacts.
316  // The sum of the content lengths MUST be <= 10MiB.
317  // The parents of all the requests must be derived from the same invocation.
318  //
319  // Up to 500 requests.
320  repeated CreateArtifactRequest requests = 2;
321}
322
323message BatchCreateArtifactsResponse {
324  // Artifacts created.
325  repeated Artifact artifacts = 1;
326}
327