blob: ff4e56cb8378770b32df850d317cf7fe06ba8a86 [file] [log] [blame]
// Copyright 2020 The Chromium 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 pinpoint;
option go_package = "infra/chromeperf/pinpoint/proto";
import "google/api/annotations.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/struct.proto";
// Service definition for Pinpoint's API.
service Pinpoint {
// Schedules a Pinpoint Job for execution.
rpc ScheduleJob(ScheduleJobRequest) returns (Job) {
option (google.api.http) = {
post: "/v1/jobs"
body: "job"
};
}
// Retrieves details about a Pinpoint Job.
rpc GetJob(GetJobRequest) returns (Job) {
option (google.api.http) = {
get: "/v1/{name=jobs/*}"
};
}
// Lists jobs with filters.
rpc ListJobs(ListJobsRequest) returns (ListJobsResponse) {
option (google.api.http) = {
get: "/v1/jobs"
};
}
// Cancels an ongoing job.
rpc CancelJob(CancelJobRequest) returns (Job) {
option (google.api.http) = {
post: "/v1/{name=jobs/*}:cancel"
body: "*"
};
}
}
// Specifies the details for data generated by a Telemetry benchmark.
message TelemetryBenchmark {
// The name of the benchmark.
string benchmark = 1;
message StoryTagList {
// A list of story tags which specify stories that will be run. All stories
// that match any of the specified tags will be collected (unioned) in the
// run.
repeated string story_tags = 1;
}
oneof story_selection {
// A story to run.
string story = 2;
// NOTE: We use a nested message in this proto oneof because it cannot
// include repeated fields.
StoryTagList story_tags = 3;
}
// The name of the measurement to extract. This refers to the name of the
// histogram in a HistogramSet which we'll be making statistical analysis
// decisions on.
//
// See
// https://chromium.googlesource.com/catapult.git/+/HEAD/docs/how-to-write-metrics.md#histograms
// and
// https://chromium.googlesource.com/catapult/+/HEAD/docs/histogram-set-json-format.md
// for details on what metric names can be and how to select those from
// histograms produced by Telemetry benchmarks.
string measurement = 4;
// The optional grouping label, as described in
// https://chromium.googlesource.com/catapult.git/+/HEAD/docs/how-to-write-metrics.md#reserved-names
// (as `labels`, passed as a flag to Telemetry via the --results-label flag).
string grouping_label = 5;
// Supported statistics for when performing statistical analysis/comparisons.
enum Statistic {
// If unspecified, lets Pinpoint determine the default statistic to use
// depending on the mode.
STATISTIC_UNSPECIFIED = 0;
// Use all the sample values when performing statistical
// analysis/comparisons.
NONE = 1;
// All the following values select the appropriate statistic across
// multiple attempts, and performs statistical analysis on these values,
// instead of the raw sample values.
MIN = 2;
MAX = 3;
MEAN = 4;
STD_DEV = 5;
MEDIAN = 6;
PCT90 = 7;
PCT99 = 8;
}
// The statistic to extract. If unspecified defaults to "NONE", i.e. use all
// the sample values instead of computing a statistic.
Statistic statistic = 6;
// List of extra arguments passed to the Telemetry runner.
repeated string extra_args = 7;
}
// Specify the details for data generated by a GTest benchmark.
message GTestBenchmark {
// Name of the benchmark. This is provided to the GTest benchmark through the
// '--gtest-benchmark-name' flag, to identify which benchmark in the `target`
// (provided in the JobSpec) will be run.
string benchmark = 1;
// Name of the measurement that shows up as a chart in the Dashboard.
string measurement = 2;
// Name of the testcase in the benchmark, supplied as a filter to the GTest.
string test = 3;
}
// A commit in a Gitiles repostory.
message GitilesCommit {
// The gitiles host to query for commits.
string host = 1 [(google.api.field_behavior) = REQUIRED];
// The gitiles project to query for commits.
string project = 2 [(google.api.field_behavior) = REQUIRED];
// The hash for the specific Git commit.
string git_hash = 3 [(google.api.field_behavior) = REQUIRED];
}
// A Gerrit change review, to refer to patches to apply in builds.
message GerritChange {
// Gerrit hostname.
string host = 1 [(google.api.field_behavior) = REQUIRED];
// Gerrit project in the host.
string project = 2 [(google.api.field_behavior) = REQUIRED];
// A change ID against the project in the host.
int64 change = 3 [(google.api.field_behavior) = REQUIRED];
// A reference to the patch set. If unspecified this will always be the
// latest.
int64 patchset = 4 [(google.api.field_behavior) = REQUIRED];
}
// A CommitRange consists of two git commit hashes from the same project that
// the end commit must be reachable from the start commit.
message GitilesCommitRange {
// The gitiles host to query for commits.
string host = 1 [(google.api.field_behavior) = REQUIRED];
// The gitiles project to query for commits.
string project = 2 [(google.api.field_behavior) = REQUIRED];
// The start of the commit range.
string start_git_hash = 3 [(google.api.field_behavior) = REQUIRED];
// The end of the commit range.
string end_git_hash = 4 [(google.api.field_behavior) = REQUIRED];
}
// A Bisection specifies a range through which Pinpoint will perform
// builds/runs against to find potential culprits.
message Bisection {
// A commit range through which the bisection will be performed.
GitilesCommitRange commit_range = 1 [(google.api.field_behavior) = REQUIRED];
// A patch to apply to all commits in the range before building. This is
// useful if you want to apply a patch that fixes the build in a range where
// the bisection might encounter broken builds.
GerritChange patch = 3;
}
// An Experiment defines an A/B test between a base build (with an optional
// patch) and an experimental build. This is also referred to as a "tryjob" in
// Pinpoint.
message Experiment {
// The commit and optional patch from which we'd perform the A/B Test.
GitilesCommit base_commit = 1 [(google.api.field_behavior) = REQUIRED];
GerritChange base_patch = 2;
// The commit and required patch which we'll compare against the base and
// optional patch. If the experiment_commit is empty, we use the base_commit
// instead.
GitilesCommit experiment_commit = 3;
GerritChange experiment_patch = 4 [(google.api.field_behavior) = REQUIRED];
// The alpha and histogram_filter are used for deciding whether the
// experiment is statistic significante enough as a difference. We check the
// alpah_value on filtered histograms
// https://en.wikipedia.org/wiki/Statistical_significance
double alpha = 5;
string measurement_regex = 6;
}
message MonorailIssue {
// Name of the Monorail project.
string project = 1 [(google.api.field_behavior) = REQUIRED];
// The Issue ID in the provided project.
int64 issue_id = 2 [(google.api.field_behavior) = REQUIRED];
}
// A JobSpec defines inputs for Pinpoint to configure a job being created and
// managed by the service.
message JobSpec {
// The comparison mode used by Pinpoint in this job.
enum ComparisonMode {
// If unspecified, it's as if 'PERFORMANCE' was specified.
COMPARISON_MODE_UNSPECIFIED = 0;
// Performs statistical tests appropriate for performance measurements.
PERFORMANCE = 1;
// Performs statistical tests appropriate for functional success/failure
// measurements. This is used in determining whether a benchmark has failed
// or started to become flaky in a bisection or to try out whether a patch
// will cause failures for specific benchmarks/stories in experiments.
FUNCTIONAL = 2;
}
// The comparison mode to perform. Defaults to 'PERFORMANCE' if unspecified.
ComparisonMode comparison_mode = 1;
// A threshold value which determines how sensitive the comparison algorithm
// should be. This is typically a multiple of the inter-quartile range for
// the measurements, indicating how "tight" the bounds for differences must
// be when considering statistical significance.
//
// If unspecified, the service will determine a default comparison magnitude
// based on the empirically measured inter-quartile range.
double comparison_magnitude = 2;
// A named configuration, representing a "bot pool" in Pinpoint.
//
// These are managed through the administration console on the Chromeperf UI.
//
// TODO(dberris): Add a reference to the luci-config files when these have
// been migrated.
string config = 3 [(google.api.field_behavior) = REQUIRED];
// The target representing a build target that will be built/run by Pinpoint.
string target = 4 [(google.api.field_behavior) = REQUIRED];
oneof job_kind {
Bisection bisection = 5;
Experiment experiment = 6;
}
oneof arguments {
TelemetryBenchmark telemetry_benchmark = 7;
GTestBenchmark gtest_benchmark = 8;
// Support more benchmark-running options here.
}
// The associated Monorail issue.
MonorailIssue monorail_issue = 9;
// A client can associate an agent identifier (similar to an HTTP User Agent).
// This is purely metadata.
string user_agent = 10;
// A batch identifier links multiple jobs together.
string batch_id = 11;
// Determines when this job will be run (lower numbers run first).
int32 priority = 12;
// How many attempts a try job should do for A and B
int32 initial_attempt_count = 13;
// TODO(crbug/1059667): Fill this out with more details like priority, other
// constraints, when relevant.
}
// Contains the required information for creating a Job represented in
// the datastore.
message ScheduleJobRequest {
JobSpec job = 1 [(google.api.field_behavior) = REQUIRED];
}
// ==== LEGACY RESULTS PROTOS
// Everything within this section is a translation of the schema used by the
// legacy API to represent results for a given job.
//
message Change {
GitilesCommit commit = 1;
GerritChange patch = 2;
}
message ExecutionDetails {
string key= 1;
string value = 2;
string url = 3;
}
message Execution {
bool completed = 1;
string label = 4;
repeated ExecutionDetails details = 2;
google.protobuf.Struct exception = 3;
}
message Attempt {
repeated Execution executions = 1;
}
// Results associated with a Change.
message ChangeResult {
repeated Attempt attempts = 1;
Change change = 2 [(google.api.field_behavior) = REQUIRED];
repeated double result_values = 3;
}
message BisectionResults {
repeated ChangeResult results = 1;
}
message ABExperimentResults {
ChangeResult a_change_result = 1;
ChangeResult b_change_result = 2;
}
// === LEGACY RESULTS PROTOS
// A representation of a Pinpoint Job.
message Job {
option (google.api.resource) = {
type: "api.pinpoint.cr.dev/Job"
pattern: "jobs/{job}"
};
// The resource name of the job.
// Format: jobs/{job}
//
// Name must follow either of the following formats:
// - 'legacy-<hex>' where <hex> is a non-prefixed hexadecimal string
// - a canonical textual representation of a UUID
string name = 1;
enum State {
STATE_UNSPECIFIED = 0;
PENDING = 1;
RUNNING = 2;
SUCCEEDED = 3;
FAILED = 4;
CANCELLED = 5;
}
State state = 2;
// The user that created this Job, referred to by email address.
string created_by = 3;
google.protobuf.Timestamp create_time = 4;
google.protobuf.Timestamp last_update_time = 5;
// Specification provided when the Job was created.
JobSpec job_spec = 6;
// If present, the reason provided for when a job is cancelled.
string cancellation_reason = 7;
oneof results {
BisectionResults bisection_results = 8;
ABExperimentResults ab_experiment_results = 9;
}
// A list of files representing results for the associated Job, for example
// an HTML summary page. This field will only be set if state==SUCCEEDED.
repeated ResultFile result_files = 10;
}
// ResultFile represents a result for a Pinpoint Job; the file is stored in
// Google Cloud Storage (GCS).
message ResultFile {
string gcs_bucket = 1;
string path = 2;
}
message GetJobRequest {
string name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = { type: "api.pinpoint.cr.dev/Job" }
];
}
message ListJobsRequest {
// If unspecified, at most 100 Jobs will be returned.
// Max is 1000, any values above will be capped to 1000.
int32 page_size = 1;
// A page token, received from a previous `ListJobs` call.
// Provide this to retrieve the subsequent page.
// When paginating, all other parameters provided must match previous
// requests.
string page_token = 2;
// A structured string specifying a filter on Job properties.
// TODO(dberris): Document this, see https://aip.dev/160 for details.
string filter = 3;
}
message ListJobsResponse {
repeated Job jobs = 1;
string next_page_token = 2;
}
message CancelJobRequest {
string name = 1 [
(google.api.field_behavior) = REQUIRED,
(google.api.resource_reference) = { type: "api.pinpoint.cr.dev/Job" }
];
string reason = 2 [(google.api.field_behavior) = REQUIRED];
}