Home | History | Annotate | Download | only in tools
      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 
     19 Suppressed tests that are nonetheless passing are output as warnings
     20 by vogar.  Any tests that generate warnings in every builder are good
     21 candidates for no longer being suppressed, since they're passing on
     22 a regular basis."""
     23 
     24 import collections
     25 import json
     26 import requests
     27 
     28 # The number of recent builds to check for each builder
     29 NUM_BUILDS = 5
     30 # The buildbot step to check for warnings
     31 BUILDBOT_STEP = 'test libcore'
     32 
     33 
     34 def 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 
     95 if __name__ == '__main__':
     96     main()
     97