Skip to content

Commit 899b9ba

Browse files
amscannegvisor-bot
authored andcommitted
Add BuildKite annotations for failures and profiles.
This change cleans up some minor Makefile issues, and adds support for BuildKite annotations on failure and on profiles being generated. These annotations will make failures very clear and link to the artifacts. This change is a stepping stone for aggregating coverage data from all individual test jobs, as this will also happen in .buildkite/annotate.sh. PiperOrigin-RevId: 349606598
1 parent 0fb5de1 commit 899b9ba

File tree

7 files changed

+226
-88
lines changed

7 files changed

+226
-88
lines changed

.buildkite/hooks/post-command

+65-15
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,74 @@
11
# Upload test logs on failure, if there are any.
2-
if [[ "${BUILDKITE_COMMAND_EXIT_STATUS}" -ne "0" ]]; then
3-
declare log_count=0
4-
for log in $(make testlogs 2>/dev/null | sort | uniq); do
5-
buildkite-agent artifact upload "${log}"
6-
log_count=$((${log_count}+1))
7-
# N.B. If *all* tests fail due to some common cause, then we will
8-
# end up spending way too much time uploading logs. Instead, we just
9-
# upload the first 100 and stop. That is hopefully enough to debug.
10-
if [[ "${log_count}" -ge 100 ]]; then
11-
echo "Only uploaded first 100 failures; skipping the rest."
12-
break
13-
fi
14-
done
2+
if test "${BUILDKITE_COMMAND_EXIT_STATUS}" -ne "0"; then
3+
# Generate a metafile that ends with .output, and contains all the
4+
# test failures that have been uploaded. These will all be sorted and
5+
# aggregated by a failure stage in the build pipeline.
6+
declare output=$(mktemp "${BUILDKITE_JOB_ID}".XXXXXX.output)
7+
make -s testlogs 2>/dev/null | grep // | sort | uniq | (
8+
declare log_count=0
9+
while read target log; do
10+
if test -z "${target}"; then
11+
continue
12+
fi
13+
14+
# N.B. If *all* tests fail due to some common cause, then we will
15+
# end up spending way too much time uploading logs. Instead, we just
16+
# upload the first 10 and stop. That is hopefully enough to debug.
17+
#
18+
# We include this test in the metadata, but note that we cannot
19+
# upload the actual test logs. The user should rerun locally.
20+
log_count=$((${log_count}+1))
21+
if test "${log_count}" -ge 10; then
22+
echo " * ${target} (no upload)" | tee -a "${output}"
23+
else
24+
buildkite-agent artifact upload "${log}"
25+
echo " * [${target}](artifact://${log#/})" | tee -a "${output}"
26+
fi
27+
done
28+
)
29+
30+
# Upload if we had outputs.
31+
if test -s "${output}"; then
32+
buildkite-agent artifact upload "${output}"
33+
fi
34+
rm -rf "${output}"
35+
1536
# Attempt to clear the cache and shut down.
1637
make clean || echo "make clean failed with code $?"
1738
make bazel-shutdown || echo "make bazel-shutdown failed with code $?"
1839
fi
1940

41+
# Upload all profiles, and include in an annotation.
42+
if test -d /tmp/profile; then
43+
# Same as above.
44+
declare profile_output=$(mktemp "${BUILDKITE_JOB_ID}".XXXXXX.profile_output)
45+
for file in $(find /tmp/profile -name \*.pprof -print 2>/dev/null | sort); do
46+
# Generate a link to speedscope, with a URL-encoded link to the BuildKite
47+
# artifact location. Note that we use do a fixed URL encode below, since
48+
# the link can be uniquely determined. If the storage location changes,
49+
# this schema may break and these links may stop working. The artifacts
50+
# uploaded however, will still work just fine.
51+
profile_name="${file#/tmp/profile/}"
52+
public_url="https://storage.googleapis.com/gvisor-buildkite/${BUILDKITE_BUILD_ID}/${BUILDKITE_JOB_ID}/${file#/}"
53+
encoded_url=$(jq -rn --arg x "${public_url}" '$x|@uri')
54+
encoded_title=$(jq -rn --arg x "${profile_name}" '$x|@uri')
55+
profile_url="https://speedscope.app/#profileURL=${encoded_url}&title=${encoded_title}"
56+
buildkite-agent artifact upload "${file}"
57+
echo " * [${profile_name}](${profile_url}) ([pprof](artifact://${file#/}))" | tee -a "${profile_output}"
58+
done
59+
60+
# Upload if we had outputs.
61+
if test -s "${profile_output}"; then
62+
buildkite-agent artifact upload "${profile_output}"
63+
fi
64+
rm -rf "${profile_output}"
65+
66+
# Remove stale profiles, which may be owned by root.
67+
sudo rm -rf /tmp/profile
68+
fi
69+
2070
# Kill any running containers (clear state).
2171
CONTAINERS="$(docker ps -q)"
22-
if ! [[ -z "${CONTAINERS}" ]]; then
72+
if ! test -z "${CONTAINERS}"; then
2373
docker container kill ${CONTAINERS} 2>/dev/null || true
24-
fi
74+
fi

.buildkite/hooks/pre-command

+19
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
# Install packages we need. Docker must be installed and configured,
2+
# as should Go itself. We just install some extra bits and pieces.
3+
function install_pkgs() {
4+
while true; do
5+
if sudo apt-get update && sudo apt-get install -y "$@"; then
6+
break
7+
fi
8+
done
9+
}
10+
install_pkgs graphviz jq curl binutils gnupg gnupg-agent linux-libc-dev \
11+
apt-transport-https ca-certificates software-properties-common
12+
113
# Setup for parallelization with PARTITION and TOTAL_PARTITIONS.
214
export PARTITION=${BUILDKITE_PARALLEL_JOB:-0}
315
PARTITION=$((${PARTITION}+1)) # 1-indexed, but PARALLEL_JOB is 0-indexed.
@@ -9,3 +21,10 @@ if test "${EXPERIMENTAL}" != "true"; then
921
make sudo TARGETS=//runsc:runsc ARGS="install --experimental=true"
1022
sudo systemctl restart docker
1123
fi
24+
25+
# Helper for benchmarks, based on the branch.
26+
if test "${BUILDKITE_BRANCH}" = "master"; then
27+
export BENCHMARKS_OFFICIAL=true
28+
else
29+
export BENCHMARKS_OFFICIAL=false
30+
fi

.buildkite/pipeline.yaml

+15
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,18 @@ steps:
132132
command: make python3.7.3-runtime-tests
133133
parallelism: 10
134134
if: build.message =~ /VFS1/ || build.branch == "master"
135+
136+
# The final step here will aggregate data uploaded by all other steps into an
137+
# annotation that will appear at the top of the build, with useful information.
138+
#
139+
# See .buildkite/summarize.sh and .buildkite/hooks/post-command for more.
140+
- wait
141+
- <<: *common
142+
label: ":yawning_face: Wait"
143+
command: "true"
144+
key: "wait"
145+
- <<: *common
146+
label: ":thisisfine: Summarize"
147+
command: .buildkite/summarize.sh
148+
allow_dependency_failure: true
149+
depends_on: "wait"

.buildkite/summarize.sh

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/bin/bash
2+
3+
# Copyright 2020 The gVisor Authors.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
set -xeou pipefail
18+
19+
# This script collects metadata fragments produced by individual test shards in
20+
# .buildkite/hooks/postcommand, and aggregates these into a single annotation
21+
# that is posted to the build. In the future, this will include coverage.
22+
23+
# Start the summary.
24+
declare summary
25+
declare status
26+
summary=$(mktemp --tmpdir summary.XXXXXX)
27+
status="info"
28+
29+
# Download all outputs.
30+
declare outputs
31+
outputs=$(mktemp -d --tmpdir outputs.XXXXXX)
32+
if buildkite-agent artifact download '**/*.output' "${outputs}"; then
33+
status="error"
34+
echo "## Failures" >> "${summary}"
35+
find "${outputs}" -type f -print | xargs -r -n 1 cat | sort >> "${summary}"
36+
fi
37+
rm -rf "${outputs}"
38+
39+
# Attempt to find profiles, if there are any.
40+
declare profiles
41+
profiles=$(mktemp -d --tmpdir profiles.XXXXXX)
42+
if buildkite-agent artifact download '**/*.profile_output' "${profiles}"; then
43+
echo "## Profiles" >> "${summary}"
44+
find "${profiles}" -type f -print | xargs -r -n 1 cat | sort >> "${summary}"
45+
fi
46+
rm -rf "${profiles}"
47+
48+
# Upload the final annotation.
49+
if [[ -s "${summary}" ]]; then
50+
cat "${summary}" | buildkite-agent annotate --style "${status}"
51+
fi
52+
rm -rf "${summary}"

0 commit comments

Comments
 (0)