1*795d594fSAndroid Build Coastguard Worker#!/usr/bin/env python 2*795d594fSAndroid Build Coastguard Worker# 3*795d594fSAndroid Build Coastguard Worker# Copyright (C) 2017 The Android Open Source Project 4*795d594fSAndroid Build Coastguard Worker# 5*795d594fSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 6*795d594fSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 7*795d594fSAndroid Build Coastguard Worker# You may obtain a copy of the License at 8*795d594fSAndroid Build Coastguard Worker# 9*795d594fSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 10*795d594fSAndroid Build Coastguard Worker# 11*795d594fSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*795d594fSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 13*795d594fSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*795d594fSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 15*795d594fSAndroid Build Coastguard Worker# limitations under the License. 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker"""Outputs the warnings that are common to all builders. 18*795d594fSAndroid Build Coastguard Worker 19*795d594fSAndroid Build Coastguard WorkerSuppressed tests that are nonetheless passing are output as warnings 20*795d594fSAndroid Build Coastguard Workerby vogar. Any tests that generate warnings in every builder are good 21*795d594fSAndroid Build Coastguard Workercandidates for no longer being suppressed, since they're passing on 22*795d594fSAndroid Build Coastguard Workera regular basis.""" 23*795d594fSAndroid Build Coastguard Worker 24*795d594fSAndroid Build Coastguard Workerimport collections 25*795d594fSAndroid Build Coastguard Workerimport json 26*795d594fSAndroid Build Coastguard Workerimport requests 27*795d594fSAndroid Build Coastguard Worker 28*795d594fSAndroid Build Coastguard Worker# The number of recent builds to check for each builder 29*795d594fSAndroid Build Coastguard WorkerNUM_BUILDS = 5 30*795d594fSAndroid Build Coastguard Worker# The buildbot step to check for warnings 31*795d594fSAndroid Build Coastguard WorkerBUILDBOT_STEP = 'test libcore' 32*795d594fSAndroid Build Coastguard Worker 33*795d594fSAndroid Build Coastguard Worker 34*795d594fSAndroid Build Coastguard Workerdef main(): 35*795d594fSAndroid Build Coastguard Worker # Dict from builder+build_num combination to the list of warnings 36*795d594fSAndroid Build Coastguard Worker # in that build 37*795d594fSAndroid Build Coastguard Worker warnings = collections.defaultdict(list) 38*795d594fSAndroid Build Coastguard Worker r = requests.get('https://build.chromium.org/p/client.art/json/builders') 39*795d594fSAndroid Build Coastguard Worker if r.status_code != 200: 40*795d594fSAndroid Build Coastguard Worker print r.text 41*795d594fSAndroid Build Coastguard Worker return 42*795d594fSAndroid Build Coastguard Worker builders = json.loads(r.text) 43*795d594fSAndroid Build Coastguard Worker for builder_name in sorted(builders): 44*795d594fSAndroid Build Coastguard Worker # Build -1 is the currently-running build (if there is one), so we 45*795d594fSAndroid Build Coastguard Worker # start with -2, which should be the most or second-most 46*795d594fSAndroid Build Coastguard Worker # recently-completed build. 47*795d594fSAndroid Build Coastguard Worker for build_num in range(-2, -2 - NUM_BUILDS, -1): 48*795d594fSAndroid Build Coastguard Worker print ('Loading data for %s, build %d...' 49*795d594fSAndroid Build Coastguard Worker % (builder_name, build_num)) 50*795d594fSAndroid Build Coastguard Worker r = requests.get( 51*795d594fSAndroid Build Coastguard Worker 'https://build.chromium.org/p/client.art' 52*795d594fSAndroid Build Coastguard Worker '/json/builders/%s/builds/%d' % ( 53*795d594fSAndroid Build Coastguard Worker builder_name, build_num)) 54*795d594fSAndroid Build Coastguard Worker if r.status_code != 200: 55*795d594fSAndroid Build Coastguard Worker print r.text 56*795d594fSAndroid Build Coastguard Worker return 57*795d594fSAndroid Build Coastguard Worker builder = json.loads(r.text) 58*795d594fSAndroid Build Coastguard Worker libcore_steps = [x for x in builder['steps'] 59*795d594fSAndroid Build Coastguard Worker if x['name'] == BUILDBOT_STEP] 60*795d594fSAndroid Build Coastguard Worker for ls in libcore_steps: 61*795d594fSAndroid Build Coastguard Worker stdio_logs = [x for x in ls['logs'] if x[0] == 'stdio'] 62*795d594fSAndroid Build Coastguard Worker for sl in stdio_logs: 63*795d594fSAndroid Build Coastguard Worker # The default link is HTML, so append /text to get the 64*795d594fSAndroid Build Coastguard Worker # text version 65*795d594fSAndroid Build Coastguard Worker r = requests.get(sl[1] + '/text') 66*795d594fSAndroid Build Coastguard Worker if r.status_code != 200: 67*795d594fSAndroid Build Coastguard Worker print r.text 68*795d594fSAndroid Build Coastguard Worker return 69*795d594fSAndroid Build Coastguard Worker stdio = r.text.splitlines() 70*795d594fSAndroid Build Coastguard Worker 71*795d594fSAndroid Build Coastguard Worker # Walk from the back of the list to find the start of the 72*795d594fSAndroid Build Coastguard Worker # warnings summary 73*795d594fSAndroid Build Coastguard Worker i = -1 74*795d594fSAndroid Build Coastguard Worker try: 75*795d594fSAndroid Build Coastguard Worker while not stdio[i].startswith('Warnings summary:'): 76*795d594fSAndroid Build Coastguard Worker i -= 1 77*795d594fSAndroid Build Coastguard Worker i += 1 # Ignore the "Warnings summary:" line 78*795d594fSAndroid Build Coastguard Worker while i < -1: 79*795d594fSAndroid Build Coastguard Worker warnings['%s:%d' % (builder_name, build_num)].append(stdio[i]) 80*795d594fSAndroid Build Coastguard Worker i += 1 81*795d594fSAndroid Build Coastguard Worker except IndexError: 82*795d594fSAndroid Build Coastguard Worker # Some builds don't have any 83*795d594fSAndroid Build Coastguard Worker print ' No warnings section found.' 84*795d594fSAndroid Build Coastguard Worker # sharedwarnings will build up the intersection of all the lists of 85*795d594fSAndroid Build Coastguard Worker # warnings. We seed it with an arbitrary starting point (which is fine 86*795d594fSAndroid Build Coastguard Worker # since intersection is commutative). 87*795d594fSAndroid Build Coastguard Worker sharedwarnings = set(warnings.popitem()[1]) 88*795d594fSAndroid Build Coastguard Worker for warning_list in warnings.itervalues(): 89*795d594fSAndroid Build Coastguard Worker sharedwarnings = sharedwarnings & set(warning_list) 90*795d594fSAndroid Build Coastguard Worker print 'Warnings shared across all builders:' 91*795d594fSAndroid Build Coastguard Worker for warning in sorted(list(sharedwarnings)): 92*795d594fSAndroid Build Coastguard Worker print warning 93*795d594fSAndroid Build Coastguard Worker 94*795d594fSAndroid Build Coastguard Worker 95*795d594fSAndroid Build Coastguard Workerif __name__ == '__main__': 96*795d594fSAndroid Build Coastguard Worker main() 97