blob: 163f0762a703a20b5be11fba052a463a5d54645b [file] [log] [blame]
#!/usr/bin/env python2
# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# pylint: disable=module-missing-docstring,class-missing-docstring
from __future__ import print_function
import cros_config_schema
import json
import jsonschema
import os
import unittest
import tempfile
BASIC_CONFIG = """
name: 'coral'
componentConfig:
bluetoothConfigPath: '/etc/bluetooth/coral.conf'
models:
- name: 'astronaut'
componentConfig:
bluetoothConfigPath: '/etc/bluetooth/astronaut.conf'
- name: 'lava'
componentConfig:
bluetoothConfigPath: '/etc/bluetooth/lava.conf'
"""
INHERITED_CONFIG = """
name: 'coral'
componentConfig:
bluetoothConfigPath: '/etc/bluetooth/coral.conf'
models:
- name: 'astronaut'
componentConfig:
- name: 'lava'
componentConfig:
bluetoothConfigPath: '/etc/bluetooth/lava.conf'
"""
class GetNamedTupleTests(unittest.TestCase):
def testRecursiveDicts(self):
val = {'a': {'b': 1, 'c': 2}}
val_tuple = cros_config_schema.GetNamedTuple(val)
self.assertEqual(val['a']['b'], val_tuple.a.b)
self.assertEqual(val['a']['c'], val_tuple.a.c)
def testListInRecursiveDicts(self):
val = {'a': {'b': [{'c': 2}]}}
val_tuple = cros_config_schema.GetNamedTuple(val)
self.assertEqual(val['a']['b'][0]['c'], val_tuple.a.b[0].c)
class ParseArgsTests(unittest.TestCase):
def testParseArgs(self):
argv = ['-s', 'schema', '-c', 'config', '-o', 'output']
args = cros_config_schema.ParseArgs(argv)
self.assertEqual(args.schema, 'schema')
self.assertEqual(args.config, 'config')
self.assertEqual(args.output, 'output')
class TransformConfigTests(unittest.TestCase):
def testBasicTransform(self):
result = cros_config_schema.TransformConfig(BASIC_CONFIG)
json_obj = cros_config_schema.GetNamedTuple(json.loads(result))
self.assertEqual(2, len(json_obj.models))
self.assertEqual(
'astronaut',
json_obj.models[0].name)
self.assertEqual(
'/etc/bluetooth/astronaut.conf',
json_obj.models[0].componentConfig.bluetoothConfigPath)
self.assertEqual(
'lava',
json_obj.models[1].name)
def testFamilyConfigInheritanceNoValue(self):
result = cros_config_schema.TransformConfig(INHERITED_CONFIG)
json_obj = cros_config_schema.GetNamedTuple(json.loads(result))
self.assertEqual(
'/etc/bluetooth/coral.conf',
json_obj.models[0].componentConfig.bluetoothConfigPath)
def testFamilyConfigInheritanceEmptyValue(self):
config = """
name: 'coral'
componentConfig:
bluetoothConfigPath: '/etc/bluetooth/coral.conf'
models:
- name: 'astronaut'
componentConfig:
bluetoothConfigPath: ''
"""
result = cros_config_schema.TransformConfig(config)
json_obj = cros_config_schema.GetNamedTuple(json.loads(result))
self.assertEqual(
'/etc/bluetooth/coral.conf',
json_obj.models[0].componentConfig.bluetoothConfigPath)
def testFullFamilyConfigInheritance(self):
config = """
name: 'coral'
componentConfig:
bluetoothConfigPath: '/etc/bluetooth/coral.conf'
models:
- name: 'astronaut'
"""
result = cros_config_schema.TransformConfig(config)
json_obj = cros_config_schema.GetNamedTuple(json.loads(result))
self.assertEqual(
'/etc/bluetooth/coral.conf',
json_obj.models[0].componentConfig.bluetoothConfigPath)
class ValidateConfigSchemaTests(unittest.TestCase):
def setUp(self):
with open('./cros_config_schema.json', 'r') as schema_stream:
self._schema = schema_stream.read()
def testBasicSchemaValidation(self):
cros_config_schema.ValidateConfigSchema(
self._schema, cros_config_schema.TransformConfig(BASIC_CONFIG))
def testFamilyConfigInheritance(self):
cros_config_schema.ValidateConfigSchema(
self._schema, cros_config_schema.TransformConfig(INHERITED_CONFIG))
def testMissingBluetoothPath(self):
config = """
name: 'coral'
models:
- name: 'astronaut'
componentConfig:
bluetoothConfigPath: ''
"""
try:
cros_config_schema.ValidateConfigSchema(
self._schema, cros_config_schema.TransformConfig(config))
except jsonschema.ValidationError as err:
self.assertIn('does not match', err.__str__())
self.assertIn('bluetooth', err.__str__())
def testInvalidBluetoothPath(self):
config = """
name: 'coral'
models:
- name: 'astronaut'
componentConfig:
bluetoothConfigPath: 'not a valid path'
"""
try:
cros_config_schema.ValidateConfigSchema(
self._schema, cros_config_schema.TransformConfig(config))
except jsonschema.ValidationError as err:
self.assertIn('does not match', err.__str__())
self.assertIn('bluetooth', err.__str__())
def testInvalidName(self):
config = """
name: 'ab'
models:
- name: 'astronaut'
componentConfig:
bluetoothConfigPath: '/etc/bluetooth/valid.conf'
"""
try:
cros_config_schema.ValidateConfigSchema(
self._schema, cros_config_schema.TransformConfig(config))
except jsonschema.ValidationError as err:
self.assertIn('does not match', err.__str__())
self.assertIn('name', err.__str__())
class ValidateConfigTests(unittest.TestCase):
def testBasicValidation(self):
cros_config_schema.ValidateConfig(
cros_config_schema.TransformConfig(BASIC_CONFIG))
def testModelNamesNotUnique(self):
config = """
name: 'coral'
models:
- name: 'astronaut'
componentConfig:
bluetoothConfigPath: '/etc/bluetooth/valid.conf'
- name: 'astronaut'
componentConfig:
bluetoothConfigPath: '/etc/bluetooth/valid.conf'
"""
try:
cros_config_schema.ValidateConfig(
cros_config_schema.TransformConfig(config))
except cros_config_schema.ValidationError as err:
self.assertIn('Model names are not unique', err.__str__())
class MainTests(unittest.TestCase):
def testMainWithExample(self):
output = tempfile.mktemp()
cros_config_schema.Main(
'./cros_config_schema.json',
'./cros_config_schema_example.yaml',
output)
with open(output, 'r') as output_stream:
with open('./test/cros_config_schema_example.json') as expected_stream:
self.assertEqual(expected_stream.read(), output_stream.read())
os.remove(output)
if __name__ == '__main__':
unittest.main()