1#!/usr/bin/env python 2# 3# Copyright (C) 2017 The Android Open Source Project 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"""Outputs the warnings that are common to all builders. 18 19Suppressed tests that are nonetheless passing are output as warnings 20by vogar. Any tests that generate warnings in every builder are good 21candidates for no longer being suppressed, since they're passing on 22a regular basis.""" 23 24import collections 25import json 26import requests 27 28# The number of recent builds to check for each builder 29NUM_BUILDS = 5 30# The buildbot step to check for warnings 31BUILDBOT_STEP = 'test libcore' 32 33 34def main(): 35 # Dict from builder+build_num combination to the list of warnings 36 # in that build 37 warnings = collections.defaultdict(list) 38 r = requests.get('https://build.chromium.org/p/client.art/json/builders') 39 if r.status_code != 200: 40 print r.text 41 return 42 builders = json.loads(r.text) 43 for builder_name in sorted(builders): 44 # Build -1 is the currently-running build (if there is one), so we 45 # start with -2, which should be the most or second-most 46 # recently-completed build. 47 for build_num in range(-2, -2 - NUM_BUILDS, -1): 48 print ('Loading data for %s, build %d...' 49 % (builder_name, build_num)) 50 r = requests.get( 51 'https://build.chromium.org/p/client.art' 52 '/json/builders/%s/builds/%d' % ( 53 builder_name, build_num)) 54 if r.status_code != 200: 55 print r.text 56 return 57 builder = json.loads(r.text) 58 libcore_steps = [x for x in builder['steps'] 59 if x['name'] == BUILDBOT_STEP] 60 for ls in libcore_steps: 61 stdio_logs = [x for x in ls['logs'] if x[0] == 'stdio'] 62 for sl in stdio_logs: 63 # The default link is HTML, so append /text to get the 64 # text version 65 r = requests.get(sl[1] + '/text') 66 if r.status_code != 200: 67 print r.text 68 return 69 stdio = r.text.splitlines() 70 71 # Walk from the back of the list to find the start of the 72 # warnings summary 73 i = -1 74 try: 75 while not stdio[i].startswith('Warnings summary:'): 76 i -= 1 77 i += 1 # Ignore the "Warnings summary:" line 78 while i < -1: 79 warnings['%s:%d' % (builder_name, build_num)].append(stdio[i]) 80 i += 1 81 except IndexError: 82 # Some builds don't have any 83 print ' No warnings section found.' 84 # sharedwarnings will build up the intersection of all the lists of 85 # warnings. We seed it with an arbitrary starting point (which is fine 86 # since intersection is commutative). 87 sharedwarnings = set(warnings.popitem()[1]) 88 for warning_list in warnings.itervalues(): 89 sharedwarnings = sharedwarnings & set(warning_list) 90 print 'Warnings shared across all builders:' 91 for warning in sorted(list(sharedwarnings)): 92 print warning 93 94 95if __name__ == '__main__': 96 main() 97