blob: 481b47607eb1df139c50ec397f6d789a007253cd [file] [log] [blame]
#!/usr/bin/env python
# Copyright (c) 2011 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Lists slaves with hung build steps."""
import logging
import os
import optparse
import re
import sys
import time
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.join(BASE_DIR, '..'))
sys.path.append(os.path.join(BASE_DIR, '..', '..', '..', 'commit-queue'))
import buildbot_json # pylint: disable=F0401
from tools import slaves
def format_time(value):
"""Convert a value in seconds into a human readable string."""
out = ''
value = int(value)
for divider, unit_name in ((60, 's'), (60, 'm'), (24, 'h'), (0, 'd')):
value, unit = divmod(value, divider) if divider else (0, value)
out = '%02d%s%s' % (unit, unit_name, out)
if not value:
break
return re.sub(r'^0(\d)', r'\1', out)
def from_time(value):
"""Convert a human readable string representing a duration into a int as
seconds.
This function considers 2m1h4d a valid string for simplicity.
"""
units = {'d': 24*60*60, 'h': 60*60, 'm': 60, 's': 1, '': 1}
return sum(
int(x) * units[unit]
for x, unit in re.findall(r'(\d+)(d|h|m|s|)', value))
def main():
usage = """%prog [options] <master>
Sample usage:
%prog t.c -d 3h
Note: t is replaced with 'tryserver', 'c' with chromium' and
co with 'chromiumos'.
Only the slave names are printed on stdout, making it bash-friendly.
"""
parser = optparse.OptionParser(usage=usage)
parser.add_option(
'-b', '--builder',
action='append',
default=[],
help='Specify builders (use multiple times), otherwise selects all')
parser.add_option(
'-d', '--duration',
help='Only builds of specific duration or more, formated')
parser.add_option('-v', '--verbose', action='count', default=0)
options, args = parser.parse_args()
if len(args) != 1:
parser.error('Unsupported args %s' % ' '.join(args))
levels = [logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG]
logging.basicConfig(level=levels[min(len(levels)-1, options.verbose)])
url = 'http://build.chromium.org/p/%s' % slaves.ProcessShortName(args[0])
buildbot = buildbot_json.Buildbot(url)
if options.builder:
builders = [buildbot.builders[b] for b in options.builder]
else:
builders = buildbot.builders
if options.duration:
options.duration = from_time(options.duration)
now = time.time()
for builder in builders:
for build in builder.current_builds:
start, end = build.data['times']
if end:
continue
duration = now - start
if not options.duration or duration > options.duration:
print build.slave.name
logging.warn('%s(%d) elapsed:%s' % (
builder.name, build.number,
format_time(duration)))
if __name__ == '__main__':
sys.exit(main())