Home | History | Annotate | Download | only in builder_name_schema
      1 # Copyright 2014 The Chromium Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 
      6 """ Utilities for dealing with builder names. This module obtains its attributes
      7 dynamically from builder_name_schema.json. """
      8 
      9 
     10 import json
     11 import os
     12 
     13 
     14 # All of these global variables are filled in by _LoadSchema().
     15 
     16 # The full schema.
     17 BUILDER_NAME_SCHEMA = None
     18 
     19 # Character which separates parts of a builder name.
     20 BUILDER_NAME_SEP = None
     21 
     22 # Builder roles.
     23 BUILDER_ROLE_CANARY = 'Canary'
     24 BUILDER_ROLE_BUILD = 'Build'
     25 BUILDER_ROLE_HOUSEKEEPER = 'Housekeeper'
     26 BUILDER_ROLE_INFRA = 'Infra'
     27 BUILDER_ROLE_PERF = 'Perf'
     28 BUILDER_ROLE_TEST = 'Test'
     29 BUILDER_ROLE_UPLOAD = 'Upload'
     30 BUILDER_ROLE_CALMBENCH = "Calmbench"
     31 BUILDER_ROLES = (BUILDER_ROLE_CANARY,
     32                  BUILDER_ROLE_BUILD,
     33                  BUILDER_ROLE_HOUSEKEEPER,
     34                  BUILDER_ROLE_INFRA,
     35                  BUILDER_ROLE_PERF,
     36                  BUILDER_ROLE_TEST,
     37                  BUILDER_ROLE_UPLOAD,
     38                  BUILDER_ROLE_CALMBENCH)
     39 
     40 
     41 def _LoadSchema():
     42   """ Load the builder naming schema from the JSON file. """
     43 
     44   def _UnicodeToStr(obj):
     45     """ Convert all unicode strings in obj to Python strings. """
     46     if isinstance(obj, unicode):
     47       return str(obj)
     48     elif isinstance(obj, dict):
     49       return dict(map(_UnicodeToStr, obj.iteritems()))
     50     elif isinstance(obj, list):
     51       return list(map(_UnicodeToStr, obj))
     52     elif isinstance(obj, tuple):
     53       return tuple(map(_UnicodeToStr, obj))
     54 
     55   builder_name_json_filename = os.path.join(
     56       os.path.dirname(__file__), 'builder_name_schema.json')
     57   builder_name_schema_json = json.load(open(builder_name_json_filename))
     58 
     59   global BUILDER_NAME_SCHEMA
     60   BUILDER_NAME_SCHEMA = _UnicodeToStr(
     61       builder_name_schema_json['builder_name_schema'])
     62 
     63   global BUILDER_NAME_SEP
     64   BUILDER_NAME_SEP = _UnicodeToStr(
     65       builder_name_schema_json['builder_name_sep'])
     66 
     67   # Since the builder roles are dictionary keys, just assert that the global
     68   # variables above account for all of them.
     69   assert len(BUILDER_ROLES) == len(BUILDER_NAME_SCHEMA)
     70   for role in BUILDER_ROLES:
     71     assert role in BUILDER_NAME_SCHEMA
     72 
     73 
     74 _LoadSchema()
     75 
     76 
     77 def MakeBuilderName(role, extra_config=None, **kwargs):
     78   schema = BUILDER_NAME_SCHEMA.get(role)
     79   if not schema:
     80     raise ValueError('%s is not a recognized role.' % role)
     81   for k, v in kwargs.iteritems():
     82     if BUILDER_NAME_SEP in v:
     83       raise ValueError('%s not allowed in %s.' % (BUILDER_NAME_SEP, v))
     84     if not k in schema:
     85       raise ValueError('Schema does not contain "%s": %s' %(k, schema))
     86   if extra_config and BUILDER_NAME_SEP in extra_config:
     87     raise ValueError('%s not allowed in %s.' % (BUILDER_NAME_SEP,
     88                                                 extra_config))
     89   name_parts = [role]
     90   name_parts.extend([kwargs[attribute] for attribute in schema])
     91   if extra_config:
     92     name_parts.append(extra_config)
     93   return BUILDER_NAME_SEP.join(name_parts)
     94 
     95 
     96 def DictForBuilderName(builder_name):
     97   """Makes a dictionary containing details about the builder from its name."""
     98   split_name = builder_name.split(BUILDER_NAME_SEP)
     99 
    100   def pop_front():
    101     try:
    102       return split_name.pop(0)
    103     except:
    104       raise ValueError('Invalid builder name: %s' % builder_name)
    105 
    106   result = {}
    107   if split_name[0] in BUILDER_NAME_SCHEMA.keys():
    108     key_list = BUILDER_NAME_SCHEMA[split_name[0]]
    109     result['role'] = pop_front()
    110     for key in key_list:
    111       result[key] = pop_front()
    112     if split_name:
    113       result['extra_config'] = pop_front()
    114     if split_name:
    115       raise ValueError('Invalid builder name: %s' % builder_name)
    116   else:
    117     raise ValueError('Invalid builder name: %s' % builder_name)
    118   return result
    119 
    120 
    121