[email protected] | e93620d | 2010-08-10 08:49:34 | [diff] [blame] | 1 | #!/bin/bash |
[email protected] | 29ddcba | 2010-08-03 12:12:39 | [diff] [blame] | 2 | |
[email protected] | dbde5e8 | 2011-05-05 13:35:11 | [diff] [blame] | 3 | # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
[email protected] | 29ddcba | 2010-08-03 12:12:39 | [diff] [blame] | 4 | # Use of this source code is governed by a BSD-style license that can be |
5 | # found in the LICENSE file. | ||||
6 | |||||
7 | # This script can be used by waterfall sheriffs to fetch the status | ||||
8 | # of Valgrind bots on the memory waterfall and test if their local | ||||
9 | # suppressions match the reports on the waterfall. | ||||
10 | |||||
11 | set -e | ||||
12 | |||||
13 | THISDIR=$(dirname "${0}") | ||||
14 | LOGS_DIR=$THISDIR/waterfall.tmp | ||||
glider | 061f914 | 2016-01-12 09:37:22 | [diff] [blame] | 15 | WATERFALL_PAGE="https://build.chromium.org/p/chromium.memory/builders" |
16 | WATERFALL_FYI_PAGE="https://build.chromium.org/p/chromium.memory.fyi/builders" | ||||
[email protected] | 29ddcba | 2010-08-03 12:12:39 | [diff] [blame] | 17 | |
[email protected] | e93620d | 2010-08-10 08:49:34 | [diff] [blame] | 18 | download() { |
19 | # Download a file. | ||||
20 | # $1 = URL to download | ||||
21 | # $2 = Path to the output file | ||||
22 | # {{{1 | ||||
[email protected] | 8e1f425 | 2010-08-11 12:42:40 | [diff] [blame] | 23 | if [ "$(which curl)" != "" ] |
24 | then | ||||
25 | if ! curl -s -o "$2" "$1" | ||||
26 | then | ||||
[email protected] | e93620d | 2010-08-10 08:49:34 | [diff] [blame] | 27 | echo |
28 | echo "Failed to download '$1'... aborting" | ||||
29 | exit 1 | ||||
30 | fi | ||||
[email protected] | 8e1f425 | 2010-08-11 12:42:40 | [diff] [blame] | 31 | elif [ "$(which wget)" != "" ] |
32 | then | ||||
33 | if ! wget "$1" -O "$2" -q | ||||
34 | then | ||||
[email protected] | e93620d | 2010-08-10 08:49:34 | [diff] [blame] | 35 | echo |
36 | echo "Failed to download '$1'... aborting" | ||||
37 | exit 1 | ||||
38 | fi | ||||
39 | else | ||||
40 | echo "Need either curl or wget to download stuff... aborting" | ||||
41 | exit 1 | ||||
42 | fi | ||||
43 | # }}} | ||||
44 | } | ||||
45 | |||||
[email protected] | 29ddcba | 2010-08-03 12:12:39 | [diff] [blame] | 46 | fetch_logs() { |
47 | # Fetch Valgrind logs from the waterfall {{{1 | ||||
48 | |||||
[email protected] | b4b92a0c | 2011-01-18 11:51:52 | [diff] [blame] | 49 | # TODO(timurrrr,maruel): use JSON, see |
50 | # http://build.chromium.org/p/chromium.memory/json/help | ||||
51 | |||||
[email protected] | 7e7525a5 | 2010-08-05 07:38:24 | [diff] [blame] | 52 | rm -rf "$LOGS_DIR" # Delete old logs |
53 | mkdir "$LOGS_DIR" | ||||
[email protected] | 29ddcba | 2010-08-03 12:12:39 | [diff] [blame] | 54 | |
thestig | cc07670 | 2015-10-13 22:28:44 | [diff] [blame] | 55 | URL=$1 |
56 | LAYOUT_ONLY=0 | ||||
57 | if [ $# != 0 ]; then | ||||
58 | shift | ||||
59 | if [ "$1" = "layout_only" ]; then | ||||
60 | LAYOUT_ONLY=1 | ||||
61 | fi | ||||
62 | fi | ||||
63 | |||||
[email protected] | 29ddcba | 2010-08-03 12:12:39 | [diff] [blame] | 64 | echo "Fetching the list of builders..." |
thestig | cc07670 | 2015-10-13 22:28:44 | [diff] [blame] | 65 | download "$URL" "$LOGS_DIR/builders" |
[email protected] | 7e7525a5 | 2010-08-05 07:38:24 | [diff] [blame] | 66 | SLAVES=$(grep "<a href=\"builders\/" "$LOGS_DIR/builders" | \ |
[email protected] | 5b02012 | 2011-10-05 16:11:56 | [diff] [blame] | 67 | grep 'td class="box"' | \ |
[email protected] | 29ddcba | 2010-08-03 12:12:39 | [diff] [blame] | 68 | sed "s/.*<a href=\"builders\///" | sed "s/\".*//" | \ |
69 | sort | uniq) | ||||
70 | |||||
71 | for S in $SLAVES | ||||
72 | do | ||||
thestig | cc07670 | 2015-10-13 22:28:44 | [diff] [blame] | 73 | if [ "$LAYOUT_ONLY" = "1" ]; then |
74 | if [ "$S" != "Webkit%20Linux%20%28valgrind%20layout%29" ]; then | ||||
75 | continue; | ||||
76 | fi | ||||
77 | fi | ||||
78 | |||||
79 | SLAVE_URL="$URL/$S" | ||||
[email protected] | 8e1f425 | 2010-08-11 12:42:40 | [diff] [blame] | 80 | SLAVE_NAME=$(echo $S | sed -e "s/%20/ /g" -e "s/%28/(/g" -e "s/%29/)/g") |
[email protected] | a06f7c0 | 2010-08-04 08:48:47 | [diff] [blame] | 81 | echo -n "Fetching builds by slave '${SLAVE_NAME}'" |
[email protected] | 74c6fe74 | 2013-05-15 10:09:33 | [diff] [blame] | 82 | download $SLAVE_URL?numbuilds=${NUMBUILDS} "$LOGS_DIR/slave_${S}" |
[email protected] | 29ddcba | 2010-08-03 12:12:39 | [diff] [blame] | 83 | |
[email protected] | a06f7c0 | 2010-08-04 08:48:47 | [diff] [blame] | 84 | # We speed up the 'fetch' step by skipping the builds/tests which succeeded. |
85 | # TODO(timurrrr): OTOH, we won't be able to check | ||||
86 | # if some suppression is not used anymore. | ||||
[email protected] | 5b02012 | 2011-10-05 16:11:56 | [diff] [blame] | 87 | # |
88 | # The awk script here joins the lines ending with </td> to make it possible | ||||
89 | # to find the failed builds. | ||||
90 | LIST_OF_BUILDS=$(cat "$LOGS_DIR/slave_$S" | \ | ||||
91 | awk 'BEGIN { buf = "" } | ||||
92 | { | ||||
93 | if ($0 ~ /<\/td>/) { buf = (buf $0); } | ||||
94 | else { | ||||
95 | if (buf) { print buf; buf="" } | ||||
96 | print $0 | ||||
97 | } | ||||
98 | } | ||||
99 | END {if (buf) print buf}' | \ | ||||
[email protected] | 3a85da4 | 2013-01-30 11:37:08 | [diff] [blame] | 100 | grep "success\|failure" | \ |
[email protected] | 74c6fe74 | 2013-05-15 10:09:33 | [diff] [blame] | 101 | head -n $NUMBUILDS | \ |
[email protected] | 3a85da4 | 2013-01-30 11:37:08 | [diff] [blame] | 102 | grep "failure" | \ |
[email protected] | 5b02012 | 2011-10-05 16:11:56 | [diff] [blame] | 103 | grep -v "failed compile" | \ |
[email protected] | b4b92a0c | 2011-01-18 11:51:52 | [diff] [blame] | 104 | sed "s/.*\/builds\///" | sed "s/\".*//") |
[email protected] | a06f7c0 | 2010-08-04 08:48:47 | [diff] [blame] | 105 | |
[email protected] | 29ddcba | 2010-08-03 12:12:39 | [diff] [blame] | 106 | for BUILD in $LIST_OF_BUILDS |
107 | do | ||||
[email protected] | b4b92a0c | 2011-01-18 11:51:52 | [diff] [blame] | 108 | # We'll fetch a few tiny URLs now, let's use a temp file. |
[email protected] | 60616fc | 2011-01-27 15:52:45 | [diff] [blame] | 109 | TMPFILE=$(mktemp -t memory_waterfall.XXXXXX) |
[email protected] | b4b92a0c | 2011-01-18 11:51:52 | [diff] [blame] | 110 | download $SLAVE_URL/builds/$BUILD "$TMPFILE" |
111 | |||||
112 | REPORT_FILE="$LOGS_DIR/report_${S}_${BUILD}" | ||||
113 | rm -f $REPORT_FILE 2>/dev/null || true # make sure it doesn't exist | ||||
114 | |||||
[email protected] | 0a3a466a | 2014-01-17 21:47:17 | [diff] [blame] | 115 | REPORT_URLS=$(grep -o "[0-9]\+/steps/memory.*/logs/[0-9A-F]\{16\}" \ |
[email protected] | dbde5e8 | 2011-05-05 13:35:11 | [diff] [blame] | 116 | "$TMPFILE" \ |
117 | || true) # `true` is to succeed on empty output | ||||
[email protected] | 0a3a466a | 2014-01-17 21:47:17 | [diff] [blame] | 118 | FAILED_TESTS=$(grep -o "[0-9]\+/steps/memory.*/logs/[A-Za-z0-9_.]\+" \ |
[email protected] | dbde5e8 | 2011-05-05 13:35:11 | [diff] [blame] | 119 | "$TMPFILE" | grep -v "[0-9A-F]\{16\}" \ |
120 | | grep -v "stdio" || true) | ||||
[email protected] | b4b92a0c | 2011-01-18 11:51:52 | [diff] [blame] | 121 | |
122 | for REPORT in $REPORT_URLS | ||||
[email protected] | 29ddcba | 2010-08-03 12:12:39 | [diff] [blame] | 123 | do |
[email protected] | b4b92a0c | 2011-01-18 11:51:52 | [diff] [blame] | 124 | download "$SLAVE_URL/builds/$REPORT/text" "$TMPFILE" |
125 | echo "" >> "$TMPFILE" # Add a newline at the end | ||||
126 | cat "$TMPFILE" | tr -d '\r' >> "$REPORT_FILE" | ||||
[email protected] | 29ddcba | 2010-08-03 12:12:39 | [diff] [blame] | 127 | done |
[email protected] | b4b92a0c | 2011-01-18 11:51:52 | [diff] [blame] | 128 | |
129 | for FAILURE in $FAILED_TESTS | ||||
130 | do | ||||
131 | echo -n "FAILED:" >> "$REPORT_FILE" | ||||
132 | echo "$FAILURE" | sed -e "s/.*\/logs\///" -e "s/\/.*//" \ | ||||
133 | >> "$REPORT_FILE" | ||||
134 | done | ||||
135 | |||||
136 | rm "$TMPFILE" | ||||
137 | echo $SLAVE_URL/builds/$BUILD >> "$REPORT_FILE" | ||||
[email protected] | 29ddcba | 2010-08-03 12:12:39 | [diff] [blame] | 138 | done |
139 | echo " DONE" | ||||
140 | done | ||||
141 | # }}} | ||||
142 | } | ||||
143 | |||||
144 | match_suppressions() { | ||||
145 | PYTHONPATH=$THISDIR/../python/google \ | ||||
[email protected] | c131963 | 2013-05-07 22:14:50 | [diff] [blame] | 146 | python "$THISDIR/test_suppressions.py" $@ "$LOGS_DIR/report_"* |
[email protected] | 29ddcba | 2010-08-03 12:12:39 | [diff] [blame] | 147 | } |
148 | |||||
[email protected] | 484893f | 2010-11-24 10:47:55 | [diff] [blame] | 149 | match_gtest_excludes() { |
timurrrr | 0475a46f | 2014-10-02 12:30:19 | [diff] [blame] | 150 | for PLATFORM in "Linux" "Chromium%20Mac" "Chromium%20OS" "Windows" |
[email protected] | 484893f | 2010-11-24 10:47:55 | [diff] [blame] | 151 | do |
152 | echo | ||||
153 | echo "Test failures on ${PLATFORM}:" | sed "s/%20/ /" | ||||
[email protected] | b4b92a0c | 2011-01-18 11:51:52 | [diff] [blame] | 154 | grep -h -o "^FAILED:.*" -R "$LOGS_DIR"/*${PLATFORM}* | \ |
155 | grep -v "FAILS\|FLAKY" | sort | uniq | \ | ||||
156 | sed -e "s/^FAILED://" -e "s/^/ /" | ||||
[email protected] | 484893f | 2010-11-24 10:47:55 | [diff] [blame] | 157 | # Don't put any operators between "grep | sed" and "RESULT=$PIPESTATUS" |
158 | RESULT=$PIPESTATUS | ||||
159 | |||||
160 | if [ "$RESULT" == 1 ] | ||||
161 | then | ||||
162 | echo " None!" | ||||
163 | else | ||||
164 | echo | ||||
165 | echo " Note: we don't check for failures already excluded locally yet" | ||||
166 | echo " TODO(timurrrr): don't list tests we've already excluded locally" | ||||
167 | fi | ||||
168 | done | ||||
169 | echo | ||||
170 | echo "Note: we don't print FAILS/FLAKY tests and 1200s-timeout failures" | ||||
171 | } | ||||
172 | |||||
[email protected] | 74c6fe74 | 2013-05-15 10:09:33 | [diff] [blame] | 173 | usage() { |
174 | cat <<EOF | ||||
175 | usage: $0 fetch|match options | ||||
176 | |||||
177 | This script can be used by waterfall sheriffs to fetch the status | ||||
178 | of Valgrind bots on the memory waterfall and test if their local | ||||
179 | suppressions match the reports on the waterfall. | ||||
180 | |||||
181 | OPTIONS: | ||||
182 | -h Show this message | ||||
183 | -n N Fetch N builds from each slave. | ||||
184 | |||||
185 | COMMANDS: | ||||
thestig | cc07670 | 2015-10-13 22:28:44 | [diff] [blame] | 186 | fetch Fetch Valgrind logs from the memory waterfall |
187 | fetch_layout Fetch many Valgrind logs from the layout test bot only | ||||
188 | match Test the local suppression files against the downloaded logs | ||||
[email protected] | 74c6fe74 | 2013-05-15 10:09:33 | [diff] [blame] | 189 | |
190 | EOF | ||||
191 | } | ||||
192 | |||||
[email protected] | 74c6fe74 | 2013-05-15 10:09:33 | [diff] [blame] | 193 | CMD=$1 |
[email protected] | 74c6fe74 | 2013-05-15 10:09:33 | [diff] [blame] | 194 | if [ $# != 0 ]; then |
[email protected] | 0cecd447 | 2013-06-18 13:52:57 | [diff] [blame] | 195 | shift |
196 | fi | ||||
197 | |||||
thestig | cc07670 | 2015-10-13 22:28:44 | [diff] [blame] | 198 | NUMBUILDS=3 |
199 | if [ "$CMD" = "fetch_layout" ]; then | ||||
200 | NUMBUILDS=30 | ||||
201 | fi | ||||
202 | |||||
[email protected] | 0cecd447 | 2013-06-18 13:52:57 | [diff] [blame] | 203 | # Arguments for "match" are handled in match_suppressions |
204 | if [ "$CMD" != "match" ]; then | ||||
205 | while getopts “hn:” OPTION | ||||
206 | do | ||||
207 | case $OPTION in | ||||
208 | h) | ||||
209 | usage | ||||
210 | exit | ||||
211 | ;; | ||||
212 | n) | ||||
213 | NUMBUILDS=$OPTARG | ||||
214 | ;; | ||||
215 | ?) | ||||
216 | usage | ||||
217 | exit | ||||
218 | ;; | ||||
219 | esac | ||||
220 | done | ||||
221 | shift $((OPTIND-1)) | ||||
222 | if [ $# != 0 ]; then | ||||
223 | usage | ||||
224 | exit 1 | ||||
225 | fi | ||||
[email protected] | 74c6fe74 | 2013-05-15 10:09:33 | [diff] [blame] | 226 | fi |
227 | |||||
228 | if [ "$CMD" = "fetch" ]; then | ||||
229 | echo "Fetching $NUMBUILDS builds" | ||||
thestig | cc07670 | 2015-10-13 22:28:44 | [diff] [blame] | 230 | fetch_logs "$WATERFALL_PAGE" |
231 | fetch_logs "$WATERFALL_FYI_PAGE" | ||||
232 | elif [ "$CMD" = "fetch_layout" ]; then | ||||
233 | echo "Fetching $NUMBUILDS builds" | ||||
234 | fetch_logs "$WATERFALL_FYI_PAGE" layout_only | ||||
[email protected] | 74c6fe74 | 2013-05-15 10:09:33 | [diff] [blame] | 235 | elif [ "$CMD" = "match" ]; then |
[email protected] | 0cecd447 | 2013-06-18 13:52:57 | [diff] [blame] | 236 | match_suppressions $@ |
[email protected] | 484893f | 2010-11-24 10:47:55 | [diff] [blame] | 237 | match_gtest_excludes |
[email protected] | 74c6fe74 | 2013-05-15 10:09:33 | [diff] [blame] | 238 | elif [ "$CMD" = "blame" ]; then |
[email protected] | 62745ce | 2011-05-16 14:48:57 | [diff] [blame] | 239 | echo The blame command died of bitrot. If you need it, please reimplement it. |
240 | echo Reimplementation is blocked on http://crbug.com/82688 | ||||
[email protected] | 29ddcba | 2010-08-03 12:12:39 | [diff] [blame] | 241 | else |
[email protected] | 74c6fe74 | 2013-05-15 10:09:33 | [diff] [blame] | 242 | usage |
243 | exit 1 | ||||
[email protected] | 29ddcba | 2010-08-03 12:12:39 | [diff] [blame] | 244 | fi |