go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/resultdb/proto/v1/test_result.proto (about)

     1  // Copyright 2019 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.resultdb.v1;
    18  
    19  import "google/api/field_behavior.proto";
    20  import "google/protobuf/duration.proto";
    21  import "google/protobuf/struct.proto";
    22  import "google/protobuf/timestamp.proto";
    23  import "go.chromium.org/luci/resultdb/proto/v1/common.proto";
    24  import "go.chromium.org/luci/resultdb/proto/v1/test_metadata.proto";
    25  import "go.chromium.org/luci/resultdb/proto/v1/failure_reason.proto";
    26  
    27  option go_package = "go.chromium.org/luci/resultdb/proto/v1;resultpb";
    28  
    29  // A result of a functional test case.
    30  // Often a single test case is executed multiple times and has multiple results,
    31  // a single test suite has multiple test cases,
    32  // and the same test suite can be executed in different variants
    33  // (OS, GPU, compile flags, etc).
    34  //
    35  // This message does not specify the test id.
    36  // It should be available in the message that embeds this message.
    37  //
    38  // Next id: 17.
    39  message TestResult {
    40    reserved 11;  // test_location
    41  
    42    // Can be used to refer to this test result, e.g. in ResultDB.GetTestResult
    43    // RPC.
    44    // Format:
    45    // "invocations/{INVOCATION_ID}/tests/{URL_ESCAPED_TEST_ID}/results/{RESULT_ID}".
    46    // where URL_ESCAPED_TEST_ID is test_id escaped with
    47    // https://golang.org/pkg/net/url/#PathEscape See also https://aip.dev/122.
    48    //
    49    // Output only.
    50    string name = 1 [
    51      (google.api.field_behavior) = OUTPUT_ONLY,
    52      (google.api.field_behavior) = IMMUTABLE
    53    ];
    54  
    55    // Test id, a unique identifier of the test in a LUCI project.
    56    // Regex: ^[[::print::]]{1,512}$
    57    //
    58    // If two tests have a common test id prefix that ends with a
    59    // non-alphanumeric character, they considered a part of a group. Examples:
    60    // - "a/b/c"
    61    // - "a/b/d"
    62    // - "a/b/e:x"
    63    // - "a/b/e:y"
    64    // - "a/f"
    65    // This defines the following groups:
    66    // - All items belong to one group because of the common prefix "a/"
    67    // - Within that group, the first 4 form a sub-group because of the common
    68    //   prefix "a/b/"
    69    // - Within that group, "a/b/e:x" and "a/b/e:y" form a sub-group because of
    70    //   the common prefix "a/b/e:".
    71    // This can be used in UI.
    72    // LUCI does not interpret test ids in any other way.
    73    string test_id = 2 [(google.api.field_behavior) = IMMUTABLE];
    74  
    75    // Identifies a test result in a given invocation and test id.
    76    // Regex: ^[a-z0-9\-_.]{1,32}$
    77    string result_id = 3 [
    78      (google.api.field_behavior) = IMMUTABLE,
    79      (google.api.field_behavior) = REQUIRED
    80    ];
    81  
    82    // Description of one specific way of running the test,
    83    // e.g. a specific bucket, builder and a test suite.
    84    Variant variant = 4 [(google.api.field_behavior) = IMMUTABLE];
    85  
    86    // Whether the result of test case execution is expected.
    87    // In a typical Chromium CL, 99%+ of test results are expected.
    88    // Users are typically interested only in the unexpected results.
    89    //
    90    // An unexpected result != test case failure. There are test cases that are
    91    // expected to fail/skip/crash. The test harness compares the actual status
    92    // with the expected one(s) and this field is the result of the comparison.
    93    bool expected = 5 [(google.api.field_behavior) = IMMUTABLE];
    94  
    95    // Machine-readable status of the test case.
    96    // MUST NOT be STATUS_UNSPECIFIED.
    97    TestStatus status = 6 [(google.api.field_behavior) = IMMUTABLE];
    98  
    99    // Human-readable explanation of the result, in HTML.
   100    // MUST be sanitized before rendering in the browser.
   101    //
   102    // The size of the summary must be equal to or smaller than 4096 bytes in
   103    // UTF-8.
   104    //
   105    // Supports artifact embedding using custom tags:
   106    // * <text-artifact> renders contents of an artifact as text.
   107    //   Usage:
   108    //   * To embed result level artifact: <text-artifact
   109    //   artifact-id="<artifact_id>">
   110    //   * To embed invocation level artifact: <text-artifact
   111    //   artifact-id="<artifact_id>" inv-level>
   112    string summary_html = 7 [(google.api.field_behavior) = IMMUTABLE];
   113  
   114    // The point in time when the test case started to execute.
   115    google.protobuf.Timestamp start_time = 8
   116        [(google.api.field_behavior) = IMMUTABLE];
   117  
   118    // Duration of the test case execution.
   119    // MUST be equal to or greater than 0.
   120    google.protobuf.Duration duration = 9
   121        [(google.api.field_behavior) = IMMUTABLE];
   122  
   123    // Metadata for this test result.
   124    // It might describe this particular execution or the test case.
   125    // A key can be repeated.
   126    repeated StringPair tags = 10 [(google.api.field_behavior) = IMMUTABLE];
   127  
   128    // Hash of the variant.
   129    // hex(sha256(sorted(''.join('%s:%s\n' for k, v in variant.items())))).
   130    //
   131    // Output only.
   132    string variant_hash = 12 [
   133      (google.api.field_behavior) = OUTPUT_ONLY,
   134      (google.api.field_behavior) = IMMUTABLE
   135    ];
   136  
   137    // Information about the test at the time of its execution.
   138    TestMetadata test_metadata = 13;
   139  
   140    // Information about the test failure. Only present if the test failed.
   141    FailureReason failure_reason = 14;
   142  
   143    // Arbitrary JSON object that contains structured, domain-specific properties
   144    // of the test result.
   145    //
   146    // The serialized size must be <= 4096 bytes.
   147    google.protobuf.Struct properties = 15;
   148  
   149    // Whether the test result has been masked so that it includes only metadata.
   150    // The metadata fields for a TestResult are:
   151    // * name
   152    // * test_id
   153    // * result_id
   154    // * expected
   155    // * status
   156    // * start_time
   157    // * duration
   158    // * variant_hash
   159    // * failure_reason.primary_error_message (truncated to 140 characters)
   160    // * skip_reason
   161    //
   162    // Output only.
   163    bool is_masked = 16 [(google.api.field_behavior) = OUTPUT_ONLY];
   164  
   165    // Reasoning behind a test skip, in machine-readable form.
   166    // Used to assist downstream analyses, such as automatic bug-filing.
   167    // MUST not be set unless status is SKIP.
   168    SkipReason skip_reason = 18;
   169  }
   170  
   171  // Machine-readable status of a test result.
   172  enum TestStatus {
   173    // Status was not specified.
   174    // Not to be used in actual test results; serves as a default value for an
   175    // unset field.
   176    STATUS_UNSPECIFIED = 0;
   177  
   178    // The test case has passed.
   179    PASS = 1;
   180  
   181    // The test case has failed.
   182    // Suggests that the code under test is incorrect, but it is also possible
   183    // that the test is incorrect or it is a flake.
   184    FAIL = 2;
   185  
   186    // The test case has crashed during execution.
   187    // The outcome is inconclusive: the code under test might or might not be
   188    // correct, but the test+code is incorrect.
   189    CRASH = 3;
   190  
   191    // The test case has started, but was aborted before finishing.
   192    // A common reason: timeout.
   193    ABORT = 4;
   194  
   195    // The test case did not execute.
   196    // Examples:
   197    // - The execution of the collection of test cases, such as a test
   198    //   binary, was aborted prematurely and execution of some test cases was
   199    //   skipped.
   200    // - The test harness configuration specified that the test case MUST be
   201    //   skipped.
   202    SKIP = 5;
   203  }
   204  
   205  // Machine-readable reason that a test execution was skipped.
   206  // Only reasons actually used are listed here, if you need a new reason
   207  // please add it here and send a CL to the OWNERS.
   208  enum SkipReason {
   209    // Skip reason was not specified.
   210    // This represents an unset field which should be used for non-skip test
   211    // result statuses.  It can also be used if none of the other statuses
   212    // apply.
   213    SKIP_REASON_UNSPECIFIED = 0;
   214  
   215    // Disabled automatically in response to a test skipping policy that skips
   216    // flaky tests.
   217    // Used for ChromeOS CQ test filtering.
   218    AUTOMATICALLY_DISABLED_FOR_FLAKINESS = 1;
   219  }
   220  
   221  // Indicates the test subject (e.g. a CL) is absolved from blame
   222  // for an unexpected result of a test variant.
   223  // For example, the test variant fails both with and without CL, so it is not
   224  // CL's fault.
   225  message TestExoneration {
   226    // Can be used to refer to this test exoneration, e.g. in
   227    // ResultDB.GetTestExoneration RPC.
   228    // Format:
   229    // invocations/{INVOCATION_ID}/tests/{URL_ESCAPED_TEST_ID}/exonerations/{EXONERATION_ID}.
   230    // URL_ESCAPED_TEST_ID is test_variant.test_id escaped with
   231    // https://golang.org/pkg/net/url/#PathEscape See also https://aip.dev/122.
   232    //
   233    // Output only.
   234    string name = 1 [
   235      (google.api.field_behavior) = OUTPUT_ONLY,
   236      (google.api.field_behavior) = IMMUTABLE
   237    ];
   238  
   239    // Test identifier, see TestResult.test_id.
   240    string test_id = 2;
   241  
   242    // Description of the variant of the test, see Variant type.
   243    // Unlike TestResult.extra_variant_pairs, this one must be a full definition
   244    // of the variant, i.e. it is not combined with Invocation.base_test_variant.
   245    Variant variant = 3;
   246  
   247    // Identifies an exoneration in a given invocation and test id.
   248    // It is server-generated.
   249    string exoneration_id = 4 [
   250      (google.api.field_behavior) = OUTPUT_ONLY,
   251      (google.api.field_behavior) = IMMUTABLE
   252    ];
   253  
   254    // Reasoning behind the exoneration, in HTML.
   255    // MUST be sanitized before rendering in the browser.
   256    string explanation_html = 5 [(google.api.field_behavior) = IMMUTABLE];
   257  
   258    // Hash of the variant.
   259    // hex(sha256(sorted(''.join('%s:%s\n' for k, v in variant.items())))).
   260    string variant_hash = 6 [(google.api.field_behavior) = IMMUTABLE];
   261  
   262    // Reasoning behind the exoneration, in machine-readable form.
   263    // Used to assist downstream analyses, such as automatic bug-filing.
   264    // This allow detection of e.g. critical tests failing in presubmit,
   265    // even if they are being exonerated because they fail on other CLs.
   266    ExonerationReason reason = 7 [(google.api.field_behavior) = IMMUTABLE];
   267  
   268    // Whether the test exoneration has been masked so that it includes only
   269    // metadata. The metadata fields for a TestExoneration are:
   270    // * name
   271    // * test_id
   272    // * exoneration_id
   273    // * variant_hash
   274    // * explanation_html
   275    // * reason
   276    //
   277    // Output only.
   278    bool is_masked = 8 [(google.api.field_behavior) = OUTPUT_ONLY];
   279  }
   280  
   281  // Reason why a test variant was exonerated.
   282  enum ExonerationReason {
   283    // Reason was not specified.
   284    // Not to be used in actual test exonerations; serves as a default value for
   285    // an unset field.
   286    EXONERATION_REASON_UNSPECIFIED = 0;
   287  
   288    // Similar unexpected results were observed on a mainline branch
   289    // (i.e. against a build without unsubmitted changes applied).
   290    // (For avoidance of doubt, this includes both flakily and
   291    // deterministically occurring unexpected results.)
   292    // Applies to unexpected results in presubmit/CQ runs only.
   293    OCCURS_ON_MAINLINE = 1;
   294  
   295    // Similar unexpected results were observed in presubmit run(s) for other,
   296    // unrelated CL(s). (This is suggestive of the issue being present
   297    // on mainline but is not confirmed as there are possible confounding
   298    // factors, like how tests are run on CLs vs how tests are run on
   299    // mainline branches.)
   300    // Applies to unexpected results in presubmit/CQ runs only.
   301    OCCURS_ON_OTHER_CLS = 2;
   302  
   303    // The tests are not critical to the test subject (e.g. CL) passing.
   304    // This could be because more data is being collected to determine if
   305    // the tests are stable enough to be made critical (as is often the
   306    // case for experimental test suites).
   307    // If information exists indicating the tests are producing unexpected
   308    // results, and the tests are not critical for that reason,
   309    // prefer more specific reasons OCCURS_ON_MAINLINE or OCCURS_ON_OTHER_CLS.
   310    NOT_CRITICAL = 3;
   311  
   312    // The test result was an unexpected pass. (Note that such an exoneration is
   313    // not automatically created for unexpected passes, unless the option is
   314    // specified to ResultSink or the project manually creates one).
   315    UNEXPECTED_PASS = 4;
   316  }