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  }