def TransformConfig(config, device_filter=None):
  """Transforms the source config (YAML) to the target system format (JSON)

  Applies consistent transforms to covert a source YAML configuration into
  JSON output that will be used by the tast test program.

  Args:
    config: Config that will be transformed.
    device_filter: Only returns configs that match the filter.

  Returns:
    Resulting JSON output from the transform.
  """
  config_yaml = yaml.load(config)
  json_from_yaml = json.dumps(config_yaml, sort_keys=True, indent=2)
  json_config = json.loads(json_from_yaml)
  configs = []
  if DEVICES in json_config[CHROMEOS]:
    for device in json_config[CHROMEOS][DEVICES]:
      configs.append(device)

  if device_filter:
    configs = [
        config for config in configs if device_filter == config['device-name']
    ]

  # Drop everything except for devices since they were just used as shared
  # config in the source yaml.
  json_config = {
      CHROMEOS: {
          DEVICES: configs,
      },
  }

  return libcros_schema.FormatJson(json_config)
def Start(config, filter_name, output, schema):
  """Transforms and validates a cros config test file for use on the system

  Applies consistent transforms to covert a source YAML configuration into
  a JSON file that will be used on the system by cros_config tast tests.

  Verifies that the file complies with the schema verification rules and
  performs additional verification checks for config consistency.

  Args:
    config: Source config file that will be transformed/verified.
    filter_name: Device name to filter on.
    output: Output file that will be generated by the transform.
    schema: Schema file used to verify the config.
  """
  json_transform = MergeConfig(config, filter_name)

  if schema is None:
    schema = default_test_schema
  with open(schema, 'r') as schema_stream:
    libcros_schema.ValidateConfigSchema(
        schema_stream.read(), libcros_schema.FormatJson(json_transform))

  if output:
    with open(output, 'w') as output_stream:
      # Using print function adds proper trailing newline.
      print(json_transform, file=output_stream)
  else:
    print(json_transform)
def TransformConfig(config, model_filter_regex=None):
  """Transforms the source config (YAML) to the target system format (JSON)

  Applies consistent transforms to covert a source YAML configuration into
  JSON output that will be used on the system by cros_config.

  Args:
    config: Config that will be transformed.
    model_filter_regex: Only returns configs that match the filter

  Returns:
    Resulting JSON output from the transform.
  """
  config_yaml = yaml.load(config)
  json_from_yaml = json.dumps(config_yaml, sort_keys=True, indent=2)
  json_config = json.loads(json_from_yaml)
  configs = []
  if DEVICES in json_config[CHROMEOS]:
    for device in json_config[CHROMEOS][DEVICES]:
      template_vars = {}
      for product in device.get(PRODUCTS, [{}]):
        for sku in device[SKUS]:
          # Template variables scope is config, then device, then product
          # This allows shared configs to define defaults using anchors, which
          # can then be easily overridden by the product/device scope.
          _SetTemplateVars(sku, template_vars)
          _SetTemplateVars(device, template_vars)
          _SetTemplateVars(product, template_vars)
          while _HasTemplateVariables(template_vars):
            _ApplyTemplateVars(template_vars, template_vars)
          sku_clone = copy.deepcopy(sku)
          _ApplyTemplateVars(sku_clone, template_vars)
          config = sku_clone[CONFIG]
          _DeleteTemplateOnlyVars(config)
          configs.append(config)
  else:
    configs = json_config[CHROMEOS][CONFIGS]

  if model_filter_regex:
    matcher = re.compile(model_filter_regex)
    configs = [
        config for config in configs if matcher.match(config['name'])
    ]

  # Drop everything except for configs since they were just used as shared
  # config in the source yaml.
  json_config = {
      CHROMEOS: {
          CONFIGS: configs,
      },
  }

  return libcros_schema.FormatJson(json_config)
示例#4
0
def FilterBuildElements(config):
    """Removes build only elements from the schema.

  Removes build only elements from the schema in preparation for the platform.

  Args:
    config: Config (transformed) that will be filtered
  """
    json_config = json.loads(config)
    for config in json_config[CHROMEOS][CONFIGS]:
        _FilterBuildElements(config, '')

    return libcros_schema.FormatJson(json_config)
def MergeConfigs(configs):
  """Evaluates and merges all config files into a single configuration.

  Args:
    configs: List of source config files that will be transformed/merged.

  Returns:
    Final merged JSON result.
  """
  json_files = []
  for yaml_file in configs:
    yaml_with_imports = libcros_schema.ApplyImports(yaml_file)
    json_transformed_file = TransformConfig(yaml_with_imports)
    json_files.append(json.loads(json_transformed_file))

  result_json = json_files[0]
  for overlay_json in json_files[1:]:
    for to_merge_config in overlay_json['chromeos']['configs']:
      to_merge_identity = to_merge_config.get('identity', {})
      to_merge_name = to_merge_config.get('name', '')
      matched = False
      # Find all existing configs where there is a full/partial identity
      # match or name match and merge that config into the source.
      # If there are no matches, then append the config.
      for source_config in result_json['chromeos']['configs']:
        identity_match = False
        if to_merge_identity:
          source_identity = source_config['identity']

          # If we are missing anything from the source identity, copy
          # it into to_merge_identity before doing the comparison, as
          # missing attributes in the to_merge_identity should be
          # treated as matched.
          to_merge_identity_extended = to_merge_identity.copy()
          for key, value in source_identity.items():
            if key not in to_merge_identity_extended:
              to_merge_identity_extended[key] = value

          identity_match = _IdentityEq(source_identity,
                                       to_merge_identity_extended)
        elif to_merge_name:
          identity_match = to_merge_name == source_config.get('name', '')

        if identity_match:
          MergeDictionaries(source_config, to_merge_config)
          matched = True

      if not matched:
        result_json['chromeos']['configs'].append(to_merge_config)

  return libcros_schema.FormatJson(result_json)
示例#6
0
def MergeConfigs(configs):
    """Evaluates and merges all config files into a single configuration.

  Args:
    configs: List of source config files that will be transformed/merged.

  Returns:
    Final merged JSON result.
  """
    json_files = []
    for yaml_file in configs:
        yaml_with_imports = libcros_schema.ApplyImports(yaml_file)
        json_transformed_file = TransformConfig(yaml_with_imports)
        json_files.append(json.loads(json_transformed_file))

    result_json = json_files[0]
    for overlay_json in json_files[1:]:
        for to_merge_config in overlay_json['chromeos']['configs']:
            to_merge_identity = to_merge_config.get('identity', {})
            to_merge_name = to_merge_config.get('name', '')
            matched = False
            # Find all existing configs where there is a full/partial identity
            # match or name match and merge that config into the source.
            # If there are no matches, then append the config.
            for source_config in result_json['chromeos']['configs']:
                identity_match = False
                if to_merge_identity:
                    source_identity = source_config['identity']
                    identity_match = True
                    for identity_key, identity_value in to_merge_identity.iteritems(
                    ):
                        if (identity_key not in source_identity
                                or source_identity[identity_key] !=
                                identity_value):
                            identity_match = False
                            break
                elif to_merge_name:
                    identity_match = to_merge_name == source_config.get(
                        'name', '')

                if identity_match:
                    MergeDictionaries(source_config, to_merge_config)
                    matched = True

            if not matched:
                result_json['chromeos']['configs'].append(to_merge_config)

    return libcros_schema.FormatJson(result_json)
def FilterBuildElements(config, build_only_elements):
  """Removes build only elements from the schema.

  Removes build only elements from the schema in preparation for the
  platform, and generates any runtime-only inferred elements.

  Args:
    config: Config (transformed) that will be filtered
    build_only_elements: List of strings of paths of fields to be filtered
  """
  json_config = json.loads(config)
  json_config = _GenerateInferredElements(json_config)
  for device_config in json_config[CHROMEOS][CONFIGS]:
    _FilterBuildElements(device_config, '', build_only_elements)

  return libcros_schema.FormatJson(json_config)
def _GetElementToIntMap(schema_yaml, hwprop):
  """Returns a mapping of an enum's elements to a distinct integer.

  Used in the c_template to assign an integer to
  the stylus category type.

  Args:
    schema_yaml: Cros_config_schema in yaml format.
    hwprop: String representing the hardware property
    of the enum (ex. stylus-category)
  """
  schema_json_from_yaml = libcros_schema.FormatJson(schema_yaml)
  schema_json = json.loads(schema_json_from_yaml)
  if hwprop not in schema_json['typeDefs']:
    raise ValidationError('Hardware property not found: %s' % str(hwprop))
  if 'enum' not in schema_json['typeDefs'][hwprop]:
    raise ValidationError('Hardware property is not an enum: %s' % str(hwprop))
  return dict((element, i) for (i, element) in enumerate(
      schema_json['typeDefs'][hwprop]['enum']))
 def testROVersion(self):
     config = {
         'chromeos': {
             'configs': [
                 {
                     'identity': {
                         'platform-name': 'foo',
                         'sku-id': 1
                     },
                     'name': 'foo',
                     'fingerprint': {
                         'board': 'dartmonkey',
                         'ro-version': '123'
                     }
                 },
             ],
         },
     }
     libcros_schema.ValidateConfigSchema(self._schema,
                                         libcros_schema.FormatJson(config))
 def testDevices(self):
     config = {
         'chromeos': {
             'configs': [
                 {
                     'identity': {
                         'platform-name': 'foo',
                         'sku-id': 1
                     },
                     'name': 'foo',
                     'camera': {
                         'count':
                         2,
                         'devices': [
                             {
                                 'interface': 'usb',
                                 'facing': 'front',
                                 'orientation': 180,
                                 'flags': {
                                     'support-1080p': False,
                                     'support-autofocus': False,
                                 },
                                 'ids': ['0123:abcd', '4567:efef'],
                             },
                             {
                                 'interface': 'mipi',
                                 'facing': 'back',
                                 'orientation': 0,
                                 'flags': {
                                     'support-1080p': True,
                                     'support-autofocus': True,
                                 },
                             },
                         ],
                     }
                 },
             ],
         },
     }
     libcros_schema.ValidateConfigSchema(self._schema,
                                         libcros_schema.FormatJson(config))
    def testInvalidUsbId(self):
        if version.parse(jsonschema.__version__) < version.Version('3.0.0'):
            self.skipTest('jsonschema needs upgrade to support conditionals')

        for invalid_usb_id in ('0123-abcd', '0123:Abcd', '123:abcd'):
            config = {
                'chromeos': {
                    'configs': [
                        {
                            'identity': {
                                'platform-name': 'foo',
                                'sku-id': 1
                            },
                            'name': 'foo',
                            'camera': {
                                'count':
                                1,
                                'devices': [
                                    {
                                        'interface': 'usb',
                                        'facing': 'front',
                                        'orientation': 0,
                                        'flags': {
                                            'support-1080p': False,
                                            'support-autofocus': True,
                                        },
                                        'ids': [invalid_usb_id],
                                    },
                                ],
                            }
                        },
                    ],
                },
            }
            with self.assertRaises(jsonschema.ValidationError) as ctx:
                libcros_schema.ValidateConfigSchema(
                    self._schema, libcros_schema.FormatJson(config))
            self.assertIn('%r does not match' % invalid_usb_id,
                          str(ctx.exception))
    def testROVersionMissingBoardName(self):
        config = {
            'chromeos': {
                'configs': [
                    {
                        'identity': {
                            'platform-name': 'foo',
                            'sku-id': 1
                        },
                        'name': 'foo',
                        'fingerprint': {
                            # "ro-version" only allowed if "board" is also specified.
                            'ro-version': '123'
                        }
                    },
                ],
            },
        }
        with self.assertRaises(jsonschema.exceptions.ValidationError) as ctx:
            libcros_schema.ValidateConfigSchema(
                self._schema, libcros_schema.FormatJson(config))

        self.assertEqual(ctx.exception.message,
                         "'board' is a dependency of 'ro-version'")