blob: c9a1574c31aae859f37c29694b05cfa5314787b4 [file] [edit]
CREATE OR REPLACE VIEW `APP_ID.PROJECT_NAME.sheriffable_failures`
AS
/*
Sheriffable failures table.
This view represents a set of steps that are currently failing,
and for each includes information about when (commit position, build number)
the step began failing in the latest run of failures.
This is the view that the bigquery analyzer will poll to collect alertable failures.
A simplified diagram of the values we care about for a particular failing step:
Commit Pos +---------------------------------+
|-----| Culprit CP Range
Build ID +--+ + - - - -- -- -+
^ ^ ^
| | |
| | |
Last Pass + + First Fail + Latest Fail
|----------------------| Failing Build Range
Things to note:
- Culprit CP range should bound the range of commits that contains
the culprit causing the current range of build failures.
- Failing Build Range should end with the latest build (otherwise if
the latest build is passing, we shouldn't have an alert to generate),
and begin with the earliest failing build of the same build step in
the latest run of failures for that step.
- Commit Positions usually increment more frequently than Build IDs.
- Builds can contain multiple commits. So a build that fails after a passing
build may contain multiple commits, any one or a subset of which could be
the culprit.
- Identifying a culprit range requires us to look at the build immediately
preceeding the earliest failure to find its set of commits.
Complications and breaks with reality from the above:
Build Numbers:
Many chromium project builders still use Build *numbers*, which are a hold-over
from buildbot times. References to these still appear in various places in
the sheriff-o-matic code and the Milo UI. Importantly, build numbers are
monotonically *increasing*, while the newer buildbucket IDs are *decreasing*.
This may lead to some confusion when trying to grok any bits of code
that try to sort failures.
Commit Positions:
"Commit Pos" is the gold standard for ordering builds. It is guaranteed by
gnumd to be monotonically increasing for a given repo. However, some projects
do not have commit positions implemented, so we must rely instead on the
order of Build IDs and the assumption that Build IDs form at least a partial
ordering on commits: So Build ID N contains commits that landed prior to
commits contained in Build ID N-1 (Build IDs descend with age). If this
assumption does not hold (e.g. official builders who build from multiple
branches on the same builder) the results may be meaningless or at least
inconsistent.
TODO: Deal with commit ranges in the absence of commit position data.
If commit positions are not implemented, we should probalby look at
the build preceeding the the earliest failure *by two* (not just the
immediately preceednig build). This is so we can be sure we cover the
entire range of possible culprit commits. Since we don't know the order
of commits within the latest passing build, we have to start with
any of the commits in the build right *before* it.
Builds may refer to at least two types of commit positions, contained in
either input properties or output properties. We generally prefer
to assume the output properties contain the commit positions we want,
but in some cases may fall back to using build input properties to
find it. This varies from project to project.
*/
WITH
latest_failure_transitions AS (
SELECT
s.project,
s.bucket,
s.builder,
s.buildergroup,
s.step_name,
s.critical,
# Latest, meaning sort by commit position if it exists, then by build ID (ascending), otherwise by the build number.
ARRAY_AGG(s
ORDER BY
s.output_commit.position DESC, id, number DESC
LIMIT
1)[
OFFSET
(0)] latest
FROM
`APP_ID.PROJECT_NAME.step_status_transitions` s
WHERE
(s.step_status = 'FAILURE'
OR (s.step_status = 'CANCELED' AND s.status = 'INFRA_FAILURE')
OR s.step_status = 'INFRA_FAILURE'
) AND s.previous_step_status = 'SUCCESS'
GROUP BY
project,
bucket,
builder,
buildergroup,
step_name,
critical)
SELECT
s.project AS Project,
s.bucket AS Bucket,
s.builder AS Builder,
s.buildergroup AS BuilderGroup,
s.sheriff_rotations AS SheriffRotations,
s.critical AS Critical,
s.step AS StepName,
s.test_names_fp as TestNamesFingerprint,
s.test_names_trunc as TestNamesTrunc,
s.tests_trunc as TestsTrunc,
s.num_tests as NumTests,
t.latest.id AS BuildIdBegin,
s.build_id AS BuildIdEnd,
t.latest.number AS BuildNumberBegin,
s.number AS BuildNumberEnd,
t.latest.previous_output_commit AS CPRangeOutputBegin,
t.latest.previous_input_commit AS CPRangeInputBegin,
t.latest.output_commit AS CPRangeOutputEnd,
t.latest.input_commit AS CPRangeInputEnd,
t.latest.previous_id as CulpritIdRangeBegin,
t.latest.id as CulpritIdRangeEnd,
t.latest.end_time AS StartTime,
s.status AS BuildStatus
FROM
`APP_ID.PROJECT_NAME.failing_steps` s
# Deal with steps who have *never* been green by using a left outer join.
# Include all of the latest failing steps, and for the ones whose beginnings
# we can identify, include git pos etc. Otherwise just include the current
# failing step's end git position. Still need to show these to sheriffs.
LEFT OUTER JOIN
latest_failure_transitions t
ON
s.project = t.project
AND s.bucket = t.bucket
AND s.builder = t.builder
AND s.step = t.step_name