// Copyright 2021 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;

option go_package = "go.chromium.org/luci/resultdb/proto/v1;resultpb";
option java_package = "com.android.resultdb.proto";
option java_multiple_files = true;

// Provides structured information about why a test failed. This information is helpful
// for developers debugging failures and is also used by systems like LUCI Analysis
// to cluster similar failures together.
// It typically contains one or more error messages and potentially stack traces.
// Note: The total combined size of all errors within this message (as measured
// by proto.Size()) must not exceed 16,384 bytes.
message FailureReason {
  // Kind defines the general category of the failure.
  // Open to extension.
  enum Kind {
    KIND_UNSPECIFIED = 0;
    // The test failed in an ordinary way (not captured by another status).
    // Includes:
    // - GoogleTest and JUnit assertion failures.
    // - Golang *testing.T .Fail(), .Fatal(...) calls.
    // - Web platform tests that did not produce the expected result,
    //   for example, an unexpected pass or fail.
    ORDINARY = 1;

    // The test process crashed.
    CRASH = 2;

    // The test timed out.
    TIMEOUT = 3;
  }

  // The general category of the failure. Required.
  Kind kind = 4;

  // The error message that ultimately caused the test to fail.
  // Equal to errors[0].message, or blank if errors is unset.
  //
  // Output only. (For backwards compatibility, some clients are still
  // allowed to set this, but new clients should set the errors field
  // instead.)
  string primary_error_message = 1;

  // Error represents a problem that caused a test to fail, such as a crash
  // or expectation failure.
  message Error {
    // The specific error message associated with this particular error instance
    // (e.g., the text of a specific assertion failure). This should generally
    // exclude stack traces, which belong in the `trace` field.
    // This message is often used for clustering related failures.
    //
    // Example message:
    // camera_unittest.cc(123): Value of GetPrivacyIndicatorsView()->CameraIcon()->GetVisible() Actual: false Expected: true
    //
    // The size of this message must be equal to or smaller than 1024 bytes in UTF-8.
    string message = 1;

    // The stack trace associated with this error, if one is available.
    // For very long stack traces, it's recommended to store them as separate
    // artifacts linked to the TestResult and include a truncated version inline
    // here to avoid exceeding size limits.
    // A size limit of 4096 bytes (UTF-8) applies to this field.
    string trace = 2;
  }

  // A list of all the errors that contributed to the test failure. There might
  // be multiple errors if, for example, a test harness continues after non-fatal
  // assertion failures.
  //
  // If there is more than one error (e.g. due to multiple expectation failures),
  // a stable sorting should be used. A recommended form of stable sorting is:
  // - Fatal errors (errors that cause the test to terminate immediately first),
  //   then
  // - Within fatal/non-fatal errors, sort by chronological order
  //   (earliest error first).
  //
  // The total combined size of all errors (as measured by proto.Size()) must
  // not exceed 16,384 bytes.
  repeated Error errors = 2;

  // If the list of errors was too large to fit within the size limits for the
  // FailureReason message, this count indicates how many errors were truncated
  // from the end of the `errors` list.
  int32 truncated_errors_count = 3;
}