go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/analysis/proto/bq/test_verdict_row.proto (about) 1 // Copyright 2023 The LUCI Authors. 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 15 syntax = "proto3"; 16 17 package luci.analysis.bq; 18 19 import "google/protobuf/timestamp.proto"; 20 21 import "go.chromium.org/luci/analysis/proto/v1/common.proto"; 22 import "go.chromium.org/luci/analysis/proto/v1/failure_reason.proto"; 23 import "go.chromium.org/luci/analysis/proto/v1/sources.proto"; 24 import "go.chromium.org/luci/analysis/proto/v1/test_metadata.proto"; 25 import "go.chromium.org/luci/analysis/proto/v1/test_verdict.proto"; 26 import "go.chromium.org/luci/common/bq/pb/options.proto"; 27 28 option go_package = "go.chromium.org/luci/analysis/proto/bq;bqpb"; 29 30 // Represents a test verdict exported to BigQuery. 31 // 32 // A test verdict summarises the results for a test variant 33 // (a way of running a test) in an invocation (a container of test 34 // results, such as a build). 35 // 36 // BigQuery tables using this schema will use the following settings: 37 // - Partition by TIMESTAMP_TRUNC(partition_time, DAY), 38 // retain data for 540 days. 39 // - Cluster by project, test_id. 40 // 41 // NextId: 17 42 message TestVerdictRow { 43 // The LUCI Project. E.g. "chromium". 44 string project = 1; 45 46 // Is a unique identifier of the test in a LUCI project. 47 // Refer to TestResult.test_id for details. 48 string test_id = 2; 49 50 // Describes one specific way of running the test, 51 // e.g. a specific bucket, builder and a test suite. 52 // 53 // This will be encoded as a JSON object like 54 // {"builder":"linux-rel","os":"Ubuntu-18.04",...} 55 // to take advantage of BigQuery's JSON support, so that 56 // the query will only be billed for the variant 57 // keys it reads. 58 // 59 // In the protocol buffer, it must be a string as per 60 // https://cloud.google.com/bigquery/docs/write-api#data_type_conversions 61 string variant = 3 [(bqschema.options).bq_type = "JSON"]; 62 63 // A hash of the variant, encoded as lowercase hexadecimal characters. 64 // The computation is an implementation detail of ResultDB. 65 string variant_hash = 4; 66 67 message InvocationRecord { 68 // The ID of the invocation. 69 string id = 1; 70 71 // Tags represents Invocation-level string key-value pairs. 72 // A key can be repeated. 73 repeated luci.analysis.v1.StringPair tags = 2; 74 75 // The LUCI Realm the invocation exists under. 76 // For example, "chromium:try". 77 string realm = 3; 78 79 // Arbitrary JSON object that contains structured, domain-specific properties 80 // of the invocation. Stored here stringified as this is the only protocol 81 // buffer type that maps to the JSON BigQuery type: 82 // https://cloud.google.com/bigquery/docs/write-api#data_type_conversions 83 string properties = 4 [(bqschema.options).bq_type = "JSON"]; 84 } 85 86 // Invocation is the ResultDB invocation. 87 // 88 // This the top-level invocation for the test results of the verdict; 89 // individual test results may not have been directly uploaded to 90 // this invocation, but rather its included invocations. For example, 91 // the top-level invocation may be a build, which includes multiple 92 // invocations for swarming tasks within that build. The test results 93 // that form part of this verdict may actually have been uploaded to 94 // the invocations of those swarming tasks. 95 InvocationRecord invocation = 5; 96 97 // Partition_time is used to partition the table. 98 // It is the time when exported invocation was created in Spanner. 99 // Note: it is NOT the time when the row is inserted into BigQuery table. 100 // https://cloud.google.com/bigquery/docs/creating-column-partitions#limitations 101 // mentions "The partitioning column must be a top-level field." 102 // So we keep this column here instead of adding the CreateTime to InvocationRecord. 103 google.protobuf.Timestamp partition_time = 6; 104 105 // Status of the test verdict. E.g. EXPECTED, UNEXPECTED, FLAKY, 106 // UNEXPECTEDLY_SKIPPED, EXONERATED. 107 luci.analysis.v1.TestVerdictStatus status = 7; 108 109 // ParentInvocationRecord for a test result is the immediate parent invocation 110 // that directly contains the test result. 111 message ParentInvocationRecord { 112 // The ID of the invocation. 113 string id = 1; 114 } 115 116 // NextId: 13 117 message TestResult { 118 // Parent contains info of the result's immediate parent invocation. 119 ParentInvocationRecord parent = 1; 120 121 // The global identifier of a test result in ResultDB. 122 // Format: 123 // "invocations/{INVOCATION_ID}/tests/{URL_ESCAPED_TEST_ID}/results/{RESULT_ID}". 124 string name = 11; 125 126 // Identifies a test result in a given invocation and test id. 127 string result_id = 2; 128 129 // Expected is a flag indicating whether the result of test case execution is 130 // expected. Refer to TestResult.Expected for details. 131 bool expected = 3; 132 133 // Status of the test result. 134 luci.analysis.v1.TestResultStatus status = 4; 135 136 // A human-readable explanation of the result, in HTML. 137 // MUST be sanitized before rendering in the browser. 138 string summary_html = 5; 139 140 // The point in time when the test case started to execute. 141 google.protobuf.Timestamp start_time = 6; 142 143 // Duration of the test case execution in seconds. 144 double duration = 7; 145 146 // Tags contains metadata for this test result. 147 // It might describe this particular execution or the test case. 148 repeated luci.analysis.v1.StringPair tags = 8; 149 150 // Information about failed tests. 151 // e.g. the assertion failure message. 152 luci.analysis.v1.FailureReason failure_reason = 9; 153 154 // Reasoning behind a test skip, in machine-readable form. 155 // Only set when status is SKIP. 156 // It's the string presentation of luci.analysis.v1.SkipReason when 157 // specified, "" when the skip reason is unspecified. 158 string skip_reason = 12; 159 160 // Arbitrary JSON object that contains structured, domain-specific properties 161 // of the test result. Stored here stringified as this is the only protocol 162 // buffer type that maps to the JSON BigQuery type: 163 // https://cloud.google.com/bigquery/docs/write-api#data_type_conversions 164 string properties = 10 [(bqschema.options).bq_type = "JSON"]; 165 } 166 167 // The test results that are part of the verdict. Usually there is 168 // only one test result per verdict, but in case of retries there 169 // may be more. 170 repeated TestResult results = 8; 171 172 message Exoneration { 173 // Reasoning behind exoneration, in HTML. 174 // MUST be sanitized before rendering in the browser. 175 string explanation_html = 1; 176 177 // Reasoning behind the exoneration, in machine-readable form. 178 luci.analysis.v1.ExonerationReason reason = 2; 179 } 180 181 // The exoneration(s) recorded against the verdict. 182 // 183 // To determine if a verdict has an exoneration at all in a query, 184 // use `ARRAY_LENGTH(exonerations) > 0`. 185 repeated Exoneration exonerations = 9; 186 187 message Counts { 188 // The total number of unexpected test results in the verdict. 189 int64 unexpected = 1; 190 191 // The total number of test results in the verdict. 192 int64 total = 2; 193 194 // The total number of unexpected test results in the verdict 195 // that are not skips. 196 int64 unexpected_non_skipped = 3; 197 198 // The total number of unexpected test results in the verdict 199 // that are not skips and not passes. 200 int64 unexpected_non_skipped_non_passed = 4; 201 202 // The total number of test results in the verdict that 203 // are not skips. 204 int64 total_non_skipped = 5; 205 } 206 207 // Statistics about the test results that are part of the verdict. 208 Counts counts = 10; 209 210 // Information about the buildbucket build which contained the test result. 211 message BuildbucketBuild { 212 // The identifier of the buildbucket build. 213 int64 id = 1; 214 215 message Builder { 216 // The LUCI Project ID. 217 string project = 1; 218 219 // The build bucket, e.g. "try". Unique within project. 220 string bucket = 2; 221 222 // The builder name, e.g. "linux-rel". Unique within bucket. 223 string builder = 3; 224 } 225 226 // The builder the build belongs to. 227 Builder builder = 2; 228 229 // The status of the build that contained this test result. Can be used 230 // to filter incomplete results (e.g. where build was cancelled or had 231 // an infra failure). Can also be used to filter builds with incomplete 232 // exonerations (e.g. build succeeded but some tests not exonerated). 233 // 234 // Notionally luci.analysis.v1.BuildStatus, but string so that we can chop 235 // off the BUILD_STATUS_ prefix that would otherwise appear on every value. 236 string status = 3; 237 238 // The gardener rotations which monitor this build. 239 repeated string gardener_rotations = 4; 240 } 241 242 // The buildbucket build the results were collected as part of, if any. 243 BuildbucketBuild buildbucket_build = 11; 244 245 // Information about the LUCI Change Verifier run which the test result 246 // was a part of, if any. 247 message ChangeVerifierRun { 248 // Identity of the change verifier run that contains this test result. 249 // This should be unique per "CQ+1"/"CQ+2" attempt on gerrit. 250 // 251 // All test results for the same presubmit run will have one 252 // partition_time. 253 // 254 // The format of this value is: 255 // "{LUCI_PROJECT}/{LUCI_CV_ID}", e.g. 256 // "infra/8988819463854-1-f94732fe20056fd1". 257 string id = 1; 258 259 // The mode of the presubmit run (if any). 260 // E.g. DRY_RUN, FULL_RUN, QUICK_DRY_RUN. 261 luci.analysis.v1.PresubmitRunMode mode = 2; 262 263 // The presubmit run's ending status. 264 // Notionally luci.analysis.v1.PresubmitRunStatus, but string so that 265 // we can chop off the "PRESUBMIT_RUN_STATUS_" prefix and have 266 // only the status, e.g. SUCCEEDED, FAILED, CANCELED. 267 string status = 3; 268 269 // Whether the build indicated by buildbucket_build was 270 // critical to the presubmit run succeeding. This is 271 // false for experimental tryjobs. 272 bool is_build_critical = 4; 273 } 274 275 // The original presubmit run the results were collected as part of, if any. 276 ChangeVerifierRun change_verifier_run = 12; 277 278 // The code sources tested. Obtained from one of the verdict's test results. 279 // If the invocation which contained the test result 280 // specified that code sources directly, this is those sources. 281 // If the code sources were marked as are inherited from the including 282 // invocation, this is the resolved code sources (if they could be resolved). 283 // Unset otherwise. 284 luci.analysis.v1.Sources sources = 13; 285 286 // The branch in source control that was tested, if known. 287 // For example, the `refs/heads/main` branch in the `chromium/src` repo 288 // hosted by `chromium.googlesource.com`. 289 // This is a subset of the information in the `sources` field. 290 luci.analysis.v1.SourceRef source_ref = 15; 291 292 // Hash of the source_ref field, as 16 lowercase hexadecimal characters. 293 // Can be used to uniquely identify a branch in a source code 294 // version control system. 295 string source_ref_hash = 16; 296 297 // Metadata of the test case, 298 // e.g. the original test name and test location. 299 luci.analysis.v1.TestMetadata test_metadata = 14; 300 }