aboutsummaryrefslogtreecommitdiffhomepage
path: root/infra/bots/recipe_modules/builder_name_schema/builder_name_schema.py
diff options
context:
space:
mode:
authorGravatar borenet <borenet@chromium.org>2016-08-04 11:07:10 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-08-04 11:07:10 -0700
commit538d5b68e8b6a8745ac8947f15abf1c7c6de8f18 (patch)
tree7fe5f965dde6785a2c3b89a4415f36b78adce561 /infra/bots/recipe_modules/builder_name_schema/builder_name_schema.py
parent4e44efe50474d4eebcb30b762e784b3ef2126750 (diff)
Move builder_spec, [dm|nanobench]_flags, builder_name_schema to recipes
- builder_name_schema becomes its own recipe module. - builder_spec, dm, and nanobench flags move into vars module. - recipe expectation diffs include: - no more buildbot_spec.py step - "real" dm and nanobench flags, instead of --dummy-flags - some inconsequential stuff in visualbench, which is removed anyway. BUG=skia:5578 GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2215803002 Review-Url: https://codereview.chromium.org/2215803002
Diffstat (limited to 'infra/bots/recipe_modules/builder_name_schema/builder_name_schema.py')
-rw-r--r--infra/bots/recipe_modules/builder_name_schema/builder_name_schema.py167
1 files changed, 167 insertions, 0 deletions
diff --git a/infra/bots/recipe_modules/builder_name_schema/builder_name_schema.py b/infra/bots/recipe_modules/builder_name_schema/builder_name_schema.py
new file mode 100644
index 0000000000..125a51061e
--- /dev/null
+++ b/infra/bots/recipe_modules/builder_name_schema/builder_name_schema.py
@@ -0,0 +1,167 @@
+# Copyright 2014 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.
+
+
+""" Utilities for dealing with builder names. This module obtains its attributes
+dynamically from builder_name_schema.json. """
+
+
+import json
+import os
+
+
+# All of these global variables are filled in by _LoadSchema().
+
+# The full schema.
+BUILDER_NAME_SCHEMA = None
+
+# Character which separates parts of a builder name.
+BUILDER_NAME_SEP = None
+
+# Builder roles.
+BUILDER_ROLE_CANARY = 'Canary'
+BUILDER_ROLE_BUILD = 'Build'
+BUILDER_ROLE_HOUSEKEEPER = 'Housekeeper'
+BUILDER_ROLE_INFRA = 'Infra'
+BUILDER_ROLE_PERF = 'Perf'
+BUILDER_ROLE_TEST = 'Test'
+BUILDER_ROLES = (BUILDER_ROLE_CANARY,
+ BUILDER_ROLE_BUILD,
+ BUILDER_ROLE_HOUSEKEEPER,
+ BUILDER_ROLE_INFRA,
+ BUILDER_ROLE_PERF,
+ BUILDER_ROLE_TEST)
+
+# Suffix which distinguishes trybots from normal bots.
+TRYBOT_NAME_SUFFIX = None
+
+
+def _LoadSchema():
+ """ Load the builder naming schema from the JSON file. """
+
+ def _UnicodeToStr(obj):
+ """ Convert all unicode strings in obj to Python strings. """
+ if isinstance(obj, unicode):
+ return str(obj)
+ elif isinstance(obj, dict):
+ return dict(map(_UnicodeToStr, obj.iteritems()))
+ elif isinstance(obj, list):
+ return list(map(_UnicodeToStr, obj))
+ elif isinstance(obj, tuple):
+ return tuple(map(_UnicodeToStr, obj))
+ else:
+ return obj # pragma: no cover
+
+ builder_name_json_filename = os.path.join(
+ os.path.dirname(__file__), 'builder_name_schema.json')
+ builder_name_schema_json = json.load(open(builder_name_json_filename))
+
+ global BUILDER_NAME_SCHEMA
+ BUILDER_NAME_SCHEMA = _UnicodeToStr(
+ builder_name_schema_json['builder_name_schema'])
+
+ global BUILDER_NAME_SEP
+ BUILDER_NAME_SEP = _UnicodeToStr(
+ builder_name_schema_json['builder_name_sep'])
+
+ global TRYBOT_NAME_SUFFIX
+ TRYBOT_NAME_SUFFIX = _UnicodeToStr(
+ builder_name_schema_json['trybot_name_suffix'])
+
+ # Since the builder roles are dictionary keys, just assert that the global
+ # variables above account for all of them.
+ assert len(BUILDER_ROLES) == len(BUILDER_NAME_SCHEMA)
+ for role in BUILDER_ROLES:
+ assert role in BUILDER_NAME_SCHEMA
+
+
+_LoadSchema()
+
+
+def MakeBuilderName(role, extra_config=None, is_trybot=False, **kwargs):
+ schema = BUILDER_NAME_SCHEMA.get(role)
+ if not schema: # pragma: no cover
+ raise ValueError('%s is not a recognized role.' % role)
+ for k, v in kwargs.iteritems():
+ if BUILDER_NAME_SEP in v: # pragma: no cover
+ raise ValueError('%s not allowed in %s.' % (BUILDER_NAME_SEP, v))
+ if not k in schema: # pragma: no cover
+ raise ValueError('Schema does not contain "%s": %s' %(k, schema))
+ if extra_config and BUILDER_NAME_SEP in extra_config: # pragma: no cover
+ raise ValueError('%s not allowed in %s.' % (BUILDER_NAME_SEP,
+ extra_config))
+ name_parts = [role]
+ name_parts.extend([kwargs[attribute] for attribute in schema])
+ if extra_config:
+ name_parts.append(extra_config)
+ if is_trybot:
+ name_parts.append(TRYBOT_NAME_SUFFIX)
+ return BUILDER_NAME_SEP.join(name_parts)
+
+
+def IsTrybot(builder_name):
+ """ Returns true if builder_name refers to a trybot (as opposed to a
+ waterfall bot). """
+ return builder_name.endswith(TRYBOT_NAME_SUFFIX)
+
+
+def GetWaterfallBot(builder_name): # pragma: no cover
+ """Returns the name of the waterfall bot for this builder. If it is not a
+ trybot, builder_name is returned unchanged. If it is a trybot the name is
+ returned without the trybot suffix."""
+ if not IsTrybot(builder_name):
+ return builder_name
+ return _WithoutSuffix(builder_name, BUILDER_NAME_SEP + TRYBOT_NAME_SUFFIX)
+
+
+def TrybotName(builder_name): # pragma: no cover
+ """Returns the name of the trybot clone of this builder.
+
+ If the given builder is a trybot, the name is returned unchanged. If not, the
+ TRYBOT_NAME_SUFFIX is appended.
+ """
+ if builder_name.endswith(TRYBOT_NAME_SUFFIX):
+ return builder_name
+ return builder_name + BUILDER_NAME_SEP + TRYBOT_NAME_SUFFIX
+
+
+def _WithoutSuffix(string, suffix): # pragma: no cover
+ """ Returns a copy of string 'string', but with suffix 'suffix' removed.
+ Raises ValueError if string does not end with suffix. """
+ if not string.endswith(suffix):
+ raise ValueError('_WithoutSuffix: string %s does not end with suffix %s' % (
+ string, suffix))
+ return string[:-len(suffix)]
+
+
+def DictForBuilderName(builder_name):
+ """Makes a dictionary containing details about the builder from its name."""
+ split_name = builder_name.split(BUILDER_NAME_SEP)
+
+ def pop_front():
+ try:
+ return split_name.pop(0)
+ except: # pragma: no cover
+ raise ValueError('Invalid builder name: %s' % builder_name)
+
+ result = {'is_trybot': False}
+
+ if split_name[-1] == TRYBOT_NAME_SUFFIX:
+ result['is_trybot'] = True
+ split_name.pop()
+
+ if split_name[0] in BUILDER_NAME_SCHEMA.keys():
+ key_list = BUILDER_NAME_SCHEMA[split_name[0]]
+ result['role'] = pop_front()
+ for key in key_list:
+ result[key] = pop_front()
+ if split_name:
+ result['extra_config'] = pop_front()
+ if split_name: # pragma: no cover
+ raise ValueError('Invalid builder name: %s' % builder_name)
+ else: # pragma: no cover
+ raise ValueError('Invalid builder name: %s' % builder_name)
+ return result
+
+