| Index: Tools/TestResultServer/handlers/buildershandler.py
|
| diff --git a/Tools/TestResultServer/handlers/buildershandler.py b/Tools/TestResultServer/handlers/buildershandler.py
|
| index 84dfed7e44765ad041cb81a954bfbacd4656eb90..dc1e73740ab6b8f94343915d620c0299b699822c 100644
|
| --- a/Tools/TestResultServer/handlers/buildershandler.py
|
| +++ b/Tools/TestResultServer/handlers/buildershandler.py
|
| @@ -38,15 +38,15 @@ import webapp2
|
| from google.appengine.api import memcache
|
|
|
| MASTERS = [
|
| - {'name': 'ChromiumWin', 'url': 'http://build.chromium.org/p/chromium.win', 'groups': ['@ToT Chromium']},
|
| - {'name': 'ChromiumMac', 'url': 'http://build.chromium.org/p/chromium.mac', 'groups': ['@ToT Chromium']},
|
| - {'name': 'ChromiumLinux', 'url': 'http://build.chromium.org/p/chromium.linux', 'groups': ['@ToT Chromium']},
|
| - {'name': 'ChromiumChromiumOS', 'url': 'http://build.chromium.org/p/chromium.chromiumos', 'groups': ['@ToT ChromeOS']},
|
| - {'name': 'ChromiumGPU', 'url': 'http://build.chromium.org/p/chromium.gpu', 'groups': ['@ToT Chromium']},
|
| - {'name': 'ChromiumGPUFYI', 'url': 'http://build.chromium.org/p/chromium.gpu.fyi', 'groups': ['@ToT Chromium FYI']},
|
| - {'name': 'ChromiumWebkit', 'url': 'http://build.chromium.org/p/chromium.webkit', 'groups': ['@ToT Chromium', '@ToT Blink']},
|
| - {'name': 'ChromiumFYI', 'url': 'http://build.chromium.org/p/chromium.fyi', 'groups': ['@ToT Chromium FYI']},
|
| - {'name': 'V8', 'url': 'http://build.chromium.org/p/client.v8', 'groups': ['@ToT V8']},
|
| + {'name': 'ChromiumWin', 'url_name': 'chromium.win', 'groups': ['@ToT Chromium']},
|
| + {'name': 'ChromiumMac', 'url_name': 'chromium.mac', 'groups': ['@ToT Chromium']},
|
| + {'name': 'ChromiumLinux', 'url_name': 'chromium.linux', 'groups': ['@ToT Chromium']},
|
| + {'name': 'ChromiumChromiumOS', 'url_name': 'chromium.chromiumos', 'groups': ['@ToT ChromeOS']},
|
| + {'name': 'ChromiumGPU', 'url_name': 'chromium.gpu', 'groups': ['@ToT Chromium']},
|
| + {'name': 'ChromiumGPUFYI', 'url_name': 'chromium.gpu.fyi', 'groups': ['@ToT Chromium FYI']},
|
| + {'name': 'ChromiumWebkit', 'url_name': 'chromium.webkit', 'groups': ['@ToT Chromium', '@ToT Blink']},
|
| + {'name': 'ChromiumFYI', 'url_name': 'chromium.fyi', 'groups': ['@ToT Chromium FYI']},
|
| + {'name': 'V8', 'url_name': 'client.v8', 'groups': ['@ToT V8']},
|
| ]
|
|
|
| # Buildbot steps that have test in the name, but don't run tests.
|
| @@ -77,19 +77,12 @@ TEST_STEPS_THAT_DO_NOT_UPLOAD_YET = [
|
| 'webkit_unit_tests',
|
| ]
|
|
|
| -class FetchBuildersException(Exception): pass
|
| +BUILDS_URL = 'http://chrome-build-extract.appspot.com/get_builds?builder=%s&master=%s&num_builds=1'
|
| +MASTER_URL = 'http://chrome-build-extract.appspot.com/get_master/%s'
|
|
|
|
|
| -def master_json_url(master_url):
|
| - return master_url + '/json/builders'
|
| -
|
| -
|
| -def builder_json_url(master_url, builder):
|
| - return master_json_url(master_url) + '/' + urllib2.quote(builder)
|
| -
|
| -
|
| -def cached_build_json_url(master_url, builder, build_number):
|
| - return builder_json_url(master_url, builder) + '/builds/' + str(build_number)
|
| +class FetchBuildersException(Exception):
|
| + pass
|
|
|
|
|
| def fetch_json(url):
|
| @@ -111,64 +104,34 @@ def fetch_json(url):
|
| return fetched_json
|
|
|
|
|
| -def get_latest_build(build_data):
|
| - cached_builds = []
|
| - if 'cachedBuilds' in build_data:
|
| - cached_builds = build_data['cachedBuilds']
|
| -
|
| - current_builds = build_data['currentBuilds']
|
| -
|
| - latest_cached_builds = set(cached_builds) - set(current_builds)
|
| - if len(latest_cached_builds) != 0:
|
| - latest_cached_builds = sorted(list(latest_cached_builds))
|
| - latest_build = latest_cached_builds[-1]
|
| - elif len(current_builds) != 0:
|
| - latest_build = current_builds[0]
|
| - else:
|
| - basedir = build_data['basedir'] if 'basedir' in build_data else 'current builder'
|
| - logging.info('No cached or current builds for %s', basedir)
|
| - return None
|
| -
|
| - return latest_build
|
| -
|
| -
|
| def dump_json(data):
|
| return json.dumps(data, separators=(',', ':'), sort_keys=True)
|
|
|
|
|
| -def fetch_buildbot_data(masters, force_update=False):
|
| - if force_update:
|
| - logging.info('Starting a forced buildbot update. Failure to fetch a master\'s data will not abort the fetch.')
|
| -
|
| +def fetch_buildbot_data(masters):
|
| start_time = datetime.datetime.now()
|
| master_data = masters[:]
|
| for master in master_data:
|
| - master_url = master['url']
|
| - tests_object = master.setdefault('tests', {})
|
| - master['tests'] = tests_object
|
| -
|
| - builders = fetch_json(master_json_url(master_url))
|
| + master_url = MASTER_URL % master['url_name']
|
| + builders = fetch_json(master_url)
|
| if not builders:
|
| - msg = 'Could not fetch builders from master "%s": %s.' % (master['name'], master_url)
|
| + msg = 'Aborting fetch. Could not fetch builders from master "%s": %s.' % (master['name'], master_url)
|
| logging.warning(msg)
|
| - if force_update:
|
| - continue
|
| - else:
|
| - logging.warning('Aborting fetch.')
|
| - raise FetchBuildersException(msg)
|
| + raise FetchBuildersException(msg)
|
| +
|
| + tests_object = master.setdefault('tests', {})
|
|
|
| - for builder in builders:
|
| - build_data = fetch_json(builder_json_url(master_url, builder))
|
| + for builder in builders['builders'].keys():
|
| + build = fetch_json(BUILDS_URL % (urllib2.quote(builder), master['url_name']))
|
| + if not build:
|
| + logging.info('Skipping builder %s on master %s due to empty data.', builder, master['url_name'])
|
| + continue
|
|
|
| - latest_build = get_latest_build(build_data)
|
| - if not latest_build:
|
| - logging.info('Skipping builder %s because it lacked cached or current builds.', builder)
|
| + if not build['builds']:
|
| + logging.info('Skipping builder %s on master %s due to empty builds list.', builder, master['url_name'])
|
| continue
|
|
|
| - build = fetch_json(cached_build_json_url(master_url, builder, latest_build))
|
| - if not build:
|
| - logging.info('Skipping build %s on builder %s due to empty data', latest_build, builder)
|
| - for step in build['steps']:
|
| + for step in build['builds'][0]['steps']:
|
| step_name = step['name']
|
|
|
| if not 'test' in step_name:
|
| @@ -201,9 +164,8 @@ def fetch_buildbot_data(masters, force_update=False):
|
| class UpdateBuilders(webapp2.RequestHandler):
|
| """Fetch and update the cached buildbot data."""
|
| def get(self):
|
| - force_update = True if self.request.get('force') else False
|
| try:
|
| - buildbot_data = fetch_buildbot_data(MASTERS, force_update)
|
| + buildbot_data = fetch_buildbot_data(MASTERS)
|
| memcache.set('buildbot_data', buildbot_data)
|
| self.response.set_status(200)
|
| self.response.out.write("ok")
|
| @@ -213,24 +175,23 @@ class UpdateBuilders(webapp2.RequestHandler):
|
| self.response.out.write(ex.message)
|
|
|
|
|
| -
|
| class GetBuilders(webapp2.RequestHandler):
|
| """Return a list of masters mapped to their respective builders, possibly using cached data."""
|
| def get(self):
|
| - callback = self.request.get('callback')
|
| -
|
| buildbot_data = memcache.get('buildbot_data')
|
|
|
| if not buildbot_data:
|
| logging.warning('No buildbot data in memcache. If this message repeats, something is probably wrong with memcache.')
|
| -
|
| - # Since we have no cached buildbot data, we would rather have missing masters than no data at all.
|
| - buildbot_data = fetch_buildbot_data(MASTERS, True)
|
| try:
|
| + buildbot_data = fetch_buildbot_data(MASTERS)
|
| memcache.set('buildbot_data', buildbot_data)
|
| - except ValueError, err:
|
| - logging.error(str(err))
|
| + except FetchBuildersException, ex:
|
| + logging.error('Builders fetch failed: %s', str(ex))
|
| + self.response.set_status(500)
|
| + self.response.out.write(ex.message)
|
| + return
|
|
|
| + callback = self.request.get('callback')
|
| if callback:
|
| buildbot_data = callback + '(' + buildbot_data + ');'
|
|
|
|
|