aboutsummaryrefslogtreecommitdiffhomepage
path: root/infra/bots/gen_buildbot_specs.py
diff options
context:
space:
mode:
Diffstat (limited to 'infra/bots/gen_buildbot_specs.py')
-rwxr-xr-xinfra/bots/gen_buildbot_specs.py172
1 files changed, 172 insertions, 0 deletions
diff --git a/infra/bots/gen_buildbot_specs.py b/infra/bots/gen_buildbot_specs.py
new file mode 100755
index 0000000000..d960ab217b
--- /dev/null
+++ b/infra/bots/gen_buildbot_specs.py
@@ -0,0 +1,172 @@
+#!/usr/bin/env python
+#
+# Copyright 2015 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.
+
+
+'''Generate buildbot specs for all buildbots.'''
+
+
+import datetime
+import imp
+import json
+import os
+import re
+import subprocess
+import sys
+import tempfile
+
+
+SKIA_DIR = os.path.abspath(os.path.join(
+ os.path.dirname(os.path.realpath(__file__)),
+ os.pardir, os.pardir))
+
+BUILDBOT_SPEC_FILE = os.path.join(SKIA_DIR, 'tools', 'buildbot_spec.py')
+
+SKIA_RECIPES = [
+ 'swarm_compile.py',
+ 'swarm_housekeeper.py',
+ 'swarm_perf.py',
+ 'swarm_RecreateSKPs.py',
+ 'swarm_test.py',
+ 'swarm_trigger.py'
+]
+
+
+def prettier_print(obj, indent, stream=sys.stdout, max_line_length=80):
+ """Pretty-print the object, in a nicer format than pprint."""
+
+ def _breakline(line):
+ """Break the line to fit under N characters."""
+ # If we're under the limit, just return.
+ if len(line) <= max_line_length:
+ return [line]
+
+ # Dict entries.
+ m = re.match(r'^(\s+)(.+): (.+)$', line)
+ if m:
+ return (_breakline(m.groups()[0] + m.groups()[1] + ':') +
+ _breakline(m.groups()[0] + ' ' + m.groups()[2]))
+
+ # List entries and dict keys.
+ m = re.match(r"^(\s+)'(.+)'([:,])$", line)
+ if m:
+ prefix = m.groups()[0]
+ content = m.groups()[1]
+ max_len = max_line_length - len(prefix) - len("(''):")
+ parts = []
+ while len(content) > max_len:
+ parts.append(content[:max_len])
+ content = content[max_len:]
+ parts.append(content)
+ lines = _breakline(prefix + "('" + parts[0] + "'")
+ for p in parts[1:-1]:
+ lines.extend(_breakline(prefix + " '" + p + "'"))
+ lines.extend(_breakline(prefix + " '" + parts[-1] + "')" + m.groups()[2]))
+ return lines
+
+ class LineBreakingStream(object):
+ """Stream wrapper which writes line-by-line, breaking them as needed."""
+ def __init__(self, backing_stream):
+ self._backing_stream = backing_stream
+ self._current_line = ''
+
+ def _writeline(self, line):
+ for l in _breakline(line):
+ self._backing_stream.write(l + '\n')
+
+ def write(self, s):
+ self._current_line += s
+ split = self._current_line.split('\n')
+ for w in split[:-1]:
+ self._writeline(w)
+ self._current_line = split[len(split)-1]
+
+ def flush(self):
+ self._writeline(self._current_line)
+
+ def _pprint(obj, indent, stream):
+ indent_str = ' ' * indent
+ if isinstance(obj, dict):
+ stream.write('{\n')
+ for k in sorted(obj.iterkeys()):
+ stream.write(indent_str + '\'%s\': ' % k)
+ _pprint(obj[k], indent + 2, stream=stream)
+ stream.write(',\n')
+ stream.write(' ' * (indent-2) + '}')
+ elif isinstance(obj, list):
+ stream.write('[\n')
+ for v in obj:
+ stream.write(indent_str)
+ _pprint(v, indent + 2, stream=stream)
+ stream.write(',\n')
+ stream.write(' ' * (indent-2) + ']')
+ elif isinstance(obj, basestring):
+ stream.write('\'%s\'' % obj)
+ elif isinstance(obj, bool):
+ if obj:
+ stream.write('True')
+ else:
+ stream.write('False')
+ else:
+ stream.write(obj)
+
+ s = LineBreakingStream(stream)
+ _pprint(obj, indent, stream=s)
+ s.flush()
+
+
+def get_bots():
+ """Find all of the bots referenced in Skia recipes."""
+ recipes = os.path.join(SKIA_DIR, 'infra', 'bots', 'recipes')
+ bots = []
+ for skia_recipe in SKIA_RECIPES:
+ skia_recipe = os.path.join(recipes, skia_recipe)
+ skia = imp.load_source('skia', skia_recipe)
+ for _, slaves in skia.TEST_BUILDERS.iteritems():
+ for _, builders in slaves.iteritems():
+ bots.extend(builders)
+ bots.sort()
+ return bots
+
+
+def main():
+ """Generate a spec for each of the above bots. Dump them all to a file."""
+ # Get the list of bots.
+ bots = get_bots()
+
+ # Create the fake specs.
+ specs = {}
+ tmp_spec_file = tempfile.NamedTemporaryFile(delete=False)
+ tmp_spec_file.close()
+ try:
+ for bot in bots:
+ subprocess.check_call(['python', BUILDBOT_SPEC_FILE,
+ tmp_spec_file.name, bot])
+ with open(tmp_spec_file.name) as f:
+ spec = json.load(f)
+ spec['dm_flags'] = ['--dummy-flags']
+ spec['nanobench_flags'] = ['--dummy-flags']
+ specs[bot] = spec
+ finally:
+ os.remove(tmp_spec_file.name)
+
+ out = os.path.join(
+ SKIA_DIR, 'infra', 'bots', 'recipe_modules', 'skia', 'fake_specs.py')
+
+ with open(out, 'w') as f:
+ f.write('''# Copyright 2016 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.
+
+# This file is generated by the %s script.
+
+FAKE_SPECS = ''' % sys.argv[0])
+ prettier_print(specs, indent=2, stream=f)
+
+ print 'Wrote output to %s' % out
+
+
+if __name__ == '__main__':
+ main()