diff options
author | borenet <borenet@chromium.org> | 2016-08-04 11:07:10 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-08-04 11:07:10 -0700 |
commit | 538d5b68e8b6a8745ac8947f15abf1c7c6de8f18 (patch) | |
tree | 7fe5f965dde6785a2c3b89a4415f36b78adce561 /infra/bots/recipe_modules/builder_name_schema/builder_name_schema.py | |
parent | 4e44efe50474d4eebcb30b762e784b3ef2126750 (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.py | 167 |
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 + + |