#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 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 json
import os
import re
import textwrap

import jsonschema  # pylint: disable=import-error
from six.moves import zip_longest
from packaging import version  # pylint: disable=import-error

import cros_config_schema
import libcros_schema

from chromite.lib import cros_test_lib

this_dir = os.path.dirname(__file__)

BASIC_CONFIG = """
reef-9042-fw: &reef-9042-fw
  bcs-overlay: 'overlay-reef-private'
  ec-ro-image: 'Reef_EC.9042.87.1.tbz2'
  main-ro-image: 'Reef.9042.87.1.tbz2'
  main-rw-image: 'Reef.9042.110.0.tbz2'
  build-targets:
    coreboot: 'reef'

chromeos:
  devices:
    - $name: 'basking'
      products:
        - $key-id: 'OEM2'
          $brand-code: 'ASUN'
      skus:
        - $sku-id: 0
          config:
            audio:
              main:
                $card: 'bxtda7219max'
                cras-config-dir: '{{$name}}'
                ucm-suffix: '{{$name}}'
                files:
                  - source: "{{$dsp-ini}}"
                    destination: "/etc/cras/{{$dsp-ini}}"
                    $dsp-ini: "{{cras-config-dir}}/dsp.ini"
            brand-code: '{{$brand-code}}'
            identity:
              platform-name: "Reef"
              smbios-name-match: "Reef"
              sku-id: "{{$sku-id}}"
            name: '{{$name}}'
            firmware: *reef-9042-fw
            firmware-signing:
              key-id: '{{$key-id}}'
              signature-id: '{{$name}}'
            test-label: 'reef'
"""


class MergeDictionaries(cros_test_lib.TestCase):

  def testBaseKeyMerge(self):
    primary = {'a': {'b': 1, 'c': 2}}
    overlay = {'a': {'c': 3}, 'b': 4}
    cros_config_schema.MergeDictionaries(primary, overlay)
    self.assertEqual({'a': {'b': 1, 'c': 3}, 'b': 4}, primary)

  def testBaseListAppend(self):
    primary = {'a': {'b': 1, 'c': [1, 2]}}
    overlay = {'a': {'c': [3, 4]}}
    cros_config_schema.MergeDictionaries(primary, overlay)
    self.assertEqual({'a': {'b': 1, 'c': [1, 2, 3, 4]}}, primary)


class ParseArgsTests(cros_test_lib.TestCase):

  def testParseArgs(self):
    argv = ['-s', 'schema', '-c', 'config', '-o', 'output', '-f', 'True']
    args = cros_config_schema.ParseArgs(argv)
    self.assertEqual(args.schema, 'schema')
    self.assertEqual(args.config, 'config')
    self.assertEqual(args.output, 'output')
    self.assertTrue(args.filter)

  def testParseArgsForConfigs(self):
    argv = ['-o', 'output', '-m', 'm1', 'm2', 'm3']
    args = cros_config_schema.ParseArgs(argv)
    self.assertEqual(args.output, 'output')
    self.assertEqual(args.configs, ['m1', 'm2', 'm3'])


class TransformConfigTests(cros_test_lib.TestCase):

  def testBasicTransform(self):
    result = cros_config_schema.TransformConfig(BASIC_CONFIG)
    json_dict = json.loads(result)
    self.assertEqual(len(json_dict), 1)
    json_obj = libcros_schema.GetNamedTuple(json_dict)
    self.assertEqual(1, len(json_obj.chromeos.configs))
    model = json_obj.chromeos.configs[0]
    self.assertEqual('basking', model.name)
    self.assertEqual('basking', model.audio.main.cras_config_dir)
    # Check multi-level template variable evaluation
    self.assertEqual('/etc/cras/basking/dsp.ini',
                     model.audio.main.files[0].destination)

  def testTransformConfig_NoMatch(self):
    result = cros_config_schema.TransformConfig(
        BASIC_CONFIG, model_filter_regex='abc123')
    json_dict = json.loads(result)
    json_obj = libcros_schema.GetNamedTuple(json_dict)
    self.assertEqual(0, len(json_obj.chromeos.configs))

  def testTransformConfig_FilterMatch(self):
    scoped_config = """
reef-9042-fw: &reef-9042-fw
  bcs-overlay: 'overlay-reef-private'
  ec-ro-image: 'Reef_EC.9042.87.1.tbz2'
  main-ro-image: 'Reef.9042.87.1.tbz2'
  main-rw-image: 'Reef.9042.110.0.tbz2'
  build-targets:
    coreboot: 'reef'
chromeos:
  devices:
    - $name: 'foo'
      products:
        - $key-id: 'OEM2'
      skus:
        - config:
            identity:
              sku-id: 0
            audio:
              main:
                cras-config-dir: '{{$name}}'
                ucm-suffix: '{{$name}}'
            name: '{{$name}}'
            firmware: *reef-9042-fw
            firmware-signing:
              key-id: '{{$key-id}}'
              signature-id: '{{$name}}'
    - $name: 'bar'
      products:
        - $key-id: 'OEM2'
      skus:
        - config:
            identity:
              sku-id: 0
            audio:
              main:
                cras-config-dir: '{{$name}}'
                ucm-suffix: '{{$name}}'
            name: '{{$name}}'
            firmware: *reef-9042-fw
            firmware-signing:
              key-id: '{{$key-id}}'
              signature-id: '{{$name}}'
"""

    result = cros_config_schema.TransformConfig(
        scoped_config, model_filter_regex='bar')
    json_dict = json.loads(result)
    json_obj = libcros_schema.GetNamedTuple(json_dict)
    self.assertEqual(1, len(json_obj.chromeos.configs))
    model = json_obj.chromeos.configs[0]
    self.assertEqual('bar', model.name)

  def testTemplateVariableScope(self):
    scoped_config = """
audio_common: &audio_common
  main:
    $ucm: "default"
    $cras: "default"
    ucm-suffix: "{{$ucm}}"
    cras-config-dir: "{{$cras}}"
chromeos:
  devices:
    - $name: "some"
      $ucm: "overridden-by-device-scope"
      products:
        - $key-id: 'SOME-KEY'
          $brand-code: 'SOME-BRAND'
          $cras: "overridden-by-product-scope"
      skus:
        - $sku-id: 0
          config:
            audio: *audio_common
            brand-code: '{{$brand-code}}'
            identity:
              platform-name: "Some"
              smbios-name-match: "Some"
            name: '{{$name}}'
            firmware:
              no-firmware: True
"""
    result = cros_config_schema.TransformConfig(scoped_config)
    json_dict = json.loads(result)
    json_obj = libcros_schema.GetNamedTuple(json_dict)
    config = json_obj.chromeos.configs[0]
    self.assertEqual(
        'overridden-by-product-scope', config.audio.main.cras_config_dir)
    self.assertEqual(
        'overridden-by-device-scope', config.audio.main.ucm_suffix)


class ValidateConfigSchemaTests(cros_test_lib.TestCase):

  def setUp(self):
    self._schema = cros_config_schema.ReadSchema()

  def testBasicSchemaValidation(self):
    libcros_schema.ValidateConfigSchema(
        self._schema, cros_config_schema.TransformConfig(BASIC_CONFIG))

  def testMissingRequiredElement(self):
    config = re.sub(r' *cras-config-dir: .*', '', BASIC_CONFIG)
    config = re.sub(r' *volume: .*', '', BASIC_CONFIG)
    try:
      libcros_schema.ValidateConfigSchema(
          self._schema, cros_config_schema.TransformConfig(config))
    except jsonschema.ValidationError as err:
      self.assertIn('required', err.__str__())
      self.assertIn('cras-config-dir', err.__str__())

  def testReferencedNonExistentTemplateVariable(self):
    config = re.sub(r' *$card: .*', '', BASIC_CONFIG)
    try:
      libcros_schema.ValidateConfigSchema(
          self._schema, cros_config_schema.TransformConfig(config))
    except cros_config_schema.ValidationError as err:
      self.assertIn('Referenced template variable', err.__str__())
      self.assertIn('cras-config-dir', err.__str__())

  def testSkuIdOutOfBound(self):
    config = BASIC_CONFIG.replace('$sku-id: 0', '$sku-id: 0x80000000')
    with self.assertRaises(jsonschema.ValidationError) as ctx:
      libcros_schema.ValidateConfigSchema(
          self._schema, cros_config_schema.TransformConfig(config))
    if version.parse(jsonschema.__version__) >= version.Version('3.0.0'):
      self.assertIn(
          '%i is greater than the maximum' % 0x80000000, str(ctx.exception))
      self.assertIn('sku-id', str(ctx.exception))
    else:
      self.assertIn("'sku-id': %i" % 0x80000000, str(ctx.exception))
      self.assertIn('is not valid', str(ctx.exception))


class ValidateFingerprintSchema(cros_test_lib.TestCase):

  def setUp(self):
    self._schema = cros_config_schema.ReadSchema()

  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 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'")


class ValidateCameraSchema(cros_test_lib.TestCase):

  def setUp(self):
    self._schema = cros_config_schema.ReadSchema()

  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))


WHITELABEL_CONFIG = """
chromeos:
  devices:
    - $name: 'whitelabel'
      products:
        - $key-id: 'DEFAULT'
          $wallpaper: 'DEFAULT_WALLPAPER'
          $regulatory-label: 'DEFAULT_LABEL'
          $whitelabel-tag: ''
          $brand-code: 'DEFAULT_BRAND_CODE'
          $stylus-category: 'none'
          $test-label: 'DEFAULT_TEST_LABEL'
        - $key-id: 'WL1'
          $wallpaper: 'WL1_WALLPAPER'
          $regulatory-label: 'WL1_LABEL'
          $whitelabel-tag: 'WL1_TAG'
          $brand-code: 'WL1_BRAND_CODE'
          $stylus-category: 'none'
          $test-label: 'WL1_TEST_LABEL'
          $marketing-name: 'BRAND1_MARKETING_NAME1'
        - $key-id: 'WL2'
          $wallpaper: 'WL2_WALLPAPER'
          $regulatory-label: 'WL2_LABEL'
          $whitelabel-tag: 'WL2_TAG'
          $brand-code: 'WL2_BRAND_CODE'
          $stylus-category: 'external'
          $test-label: 'WL2_TEST_LABEL'
          $marketing-name: 'BRAND2_MARKETING_NAME2'
      skus:
        - config:
            identity:
              sku-id: 0
              whitelabel-tag: '{{$whitelabel-tag}}'
            name: '{{$name}}'
            brand-code: '{{$brand-code}}'
            wallpaper: '{{$wallpaper}}'
            regulatory-label: '{{$regulatory-label}}'
            hardware-properties:
              stylus-category: '{{$stylus-category}}'
            arc:
              build-properties:
                $marketing-name: ''
                marketing-name: '{{$marketing-name}}'
"""

INVALID_WHITELABEL_CONFIG = """
            # THIS WILL CAUSE THE FAILURE
            test-label: '{{$test-label}}'
"""


class ValidateConfigTests(cros_test_lib.TestCase):

  def testBasicValidation(self):
    cros_config_schema.ValidateConfig(
        cros_config_schema.TransformConfig(BASIC_CONFIG))

  def testIdentitiesNotUnique(self):
    config = """
reef-9042-fw: &reef-9042-fw
  bcs-overlay: 'overlay-reef-private'
  ec-ro-image: 'Reef_EC.9042.87.1.tbz2'
  main-ro-image: 'Reef.9042.87.1.tbz2'
  main-rw-image: 'Reef.9042.110.0.tbz2'
  build-targets:
    coreboot: 'reef'
chromeos:
  devices:
    - $name: 'astronaut'
      products:
        - $key-id: 'OEM2'
      skus:
        - config:
            identity:
              sku-id: 0
            audio:
              main:
                cras-config-dir: '{{$name}}'
                ucm-suffix: '{{$name}}'
            name: '{{$name}}'
            firmware: *reef-9042-fw
            firmware-signing:
              key-id: '{{$key-id}}'
              signature-id: '{{$name}}'
    - $name: 'astronaut'
      products:
        - $key-id: 'OEM2'
      skus:
        - config:
            identity:
              sku-id: 0
            audio:
              main:
                cras-config-dir: '{{$name}}'
                ucm-suffix: '{{$name}}'
            name: '{{$name}}'
            firmware: *reef-9042-fw
            firmware-signing:
              key-id: '{{$key-id}}'
              signature-id: '{{$name}}'
"""
    with self.assertRaises(cros_config_schema.ValidationError) as ctx:
      cros_config_schema.ValidateConfig(
          cros_config_schema.TransformConfig(config))
    self.assertIn('Identities are not unique', str(ctx.exception))

  def testWhitelabelWithExternalStylus(self):
    config = WHITELABEL_CONFIG
    cros_config_schema.ValidateConfig(
        cros_config_schema.TransformConfig(config))

  def testWhitelabelWithOtherThanBrandChanges(self):
    config = WHITELABEL_CONFIG + INVALID_WHITELABEL_CONFIG
    with self.assertRaises(cros_config_schema.ValidationError) as ctx:
      cros_config_schema.ValidateConfig(
          cros_config_schema.TransformConfig(config))
    self.assertIn('Whitelabel configs can only', str(ctx.exception))

  def testHardwarePropertiesInvalid(self):
    config = """
chromeos:
  devices:
    - $name: 'bad_device'
      skus:
        - config:
            identity:
              sku-id: 0
            # THIS WILL CAUSE THE FAILURE
            hardware-properties:
              has-base-accelerometer: true
              has-base-gyroscope: 7
              has-lid-accelerometer: false
              is-lid-convertible: false
              has-base-magnetometer: false
              has-touchscreen: true
"""
    try:
      cros_config_schema.ValidateConfig(
          cros_config_schema.TransformConfig(config))
    except cros_config_schema.ValidationError as err:
      self.assertIn('must be boolean', err.__str__())
    else:
      self.fail('ValidationError not raised')

  def testHardwarePropertiesBoolean(self):
    config = """
chromeos:
  devices:
    - $name: 'good_device'
      skus:
        - config:
            identity:
              sku-id: 0
            hardware-properties:
              has-base-accelerometer: true
              has-base-gyroscope: true
              has-lid-accelerometer: true
              is-lid-convertible: false
              has-base-magnetometer: true
              has-touchscreen: false
"""
    cros_config_schema.ValidateConfig(
        cros_config_schema.TransformConfig(config))

  def testMultipleMosysPlatformsInvalid(self):
    config = {
        'chromeos': {
            'configs': [
                {'identity': {'platform-name': 'SomePlatform',
                              'sku-id': 1}},
                {'identity': {'platform-name': 'SomePlatform',
                              'sku-id': 2}},
                # This causes the ValidationError.
                {'identity': {'platform-name': 'AnotherPlatform',
                              'sku-id': 3}},
            ],
        },
    }
    with self.assertRaises(cros_config_schema.ValidationError):
      cros_config_schema.ValidateConfig(json.dumps(config))

    # Removing the offending config should clear the ValidationError.
    config['chromeos']['configs'].pop()
    try:
      cros_config_schema.ValidateConfig(json.dumps(config))
    except cros_config_schema.ValidationError:
      self.fail('Removing the offending config should have cleared the '
                'ValidationError.')

  def testMultipleFingerprintFirmwareROVersionInvalid(self):
    config = {
        'chromeos': {
            'configs': [
                {'identity': {'platform-name': 'foo',
                              'sku-id': 1},
                 'fingerprint': {
                     'board': 'bloonchipper',
                     'ro-version': '123'}
                 },
                {'identity': {'platform-name': 'foo',
                              'sku-id': 2},
                 'fingerprint': {
                     'board': 'bloonchipper',
                     'ro-version': '123'}
                 },
                # This causes the ValidationError.
                {'identity': {'platform-name': 'foo',
                              'sku-id': 3},
                 'fingerprint': {
                     'board': 'bloonchipper',
                     'ro-version': '456'}
                 }
            ],
        },
    }
    with self.assertRaises(cros_config_schema.ValidationError) as ctx:
      cros_config_schema.ValidateConfig(json.dumps(config))

    self.assertRegex(str(ctx.exception), re.compile(
        'You may not use different fingerprint firmware RO versions on the '
        'same board:.*'))

  def testMultipleFingerprintFirmwareROVersionsValid(self):
    config = {
        'chromeos': {
            'configs': [
                {'identity': {'platform-name': 'foo',
                              'sku-id': 1},
                 'fingerprint': {
                     'board': 'bloonchipper',
                     'ro-version': '123'}
                 },
                {'identity': {'platform-name': 'foo',
                              'sku-id': 2},
                 'fingerprint': {
                     'board': 'dartmonkey',
                     'ro-version': '456'}
                 },
            ],
        },
    }
    cros_config_schema.ValidateConfig(json.dumps(config))

  def testFingerprintFirmwareROVersionsValid(self):
    config = {
        'chromeos': {
            'configs': [
                {'identity': {'platform-name': 'foo',
                              'sku-id': 1},
                 'fingerprint': {
                     'ro-version': '123'}
                 },
                # This device does not have fingerprint
                {'identity': {'platform-name': 'foo',
                              'sku-id': 2},
                 },
            ],
        },
    }
    cros_config_schema.ValidateConfig(json.dumps(config))


class FilterBuildElements(cros_test_lib.TestCase):

  def testBasicFilterBuildElements(self):
    json_dict = json.loads(
        cros_config_schema.FilterBuildElements(
            cros_config_schema.TransformConfig(BASIC_CONFIG), ['/firmware']))
    self.assertNotIn('firmware', json_dict['chromeos']['configs'][0])


class GetValidSchemaProperties(cros_test_lib.TestCase):

  def testGetValidSchemaProperties(self):
    schema_props = cros_config_schema.GetValidSchemaProperties()
    self.assertIn('cras-config-dir', schema_props['/audio/main'])
    self.assertIn('key-id', schema_props['/firmware-signing'])
    self.assertIn('files', schema_props['/audio/main'])
    self.assertIn('has-touchscreen', schema_props['/hardware-properties'])
    self.assertIn('count', schema_props['/camera'])


class MainTests(cros_test_lib.TempDirTestCase):

  def _GetSchemaYaml(self):
    with open(os.path.join(
        this_dir, 'cros_config_schema.yaml')) as schema_stream:
      schema_contents = schema_stream.read()
      return libcros_schema.LoadYaml(schema_contents)

  def assertFileEqual(self, file_expected, file_actual):
    self.assertTrue(os.path.isfile(file_expected),
                    'Expected file does not exist at path: {}'
                    .format(file_expected))

    self.assertTrue(os.path.isfile(file_actual),
                    'Actual file does not exist at path: {}'
                    .format(file_actual))

    regen_message = 'Please run ./regen.sh in the chromeos-config directory.'

    with open(file_expected, 'r') as expected, open(file_actual, 'r') as actual:
      for line_num, (line_expected, line_actual) in \
          enumerate(zip_longest(expected, actual)):
        self.assertEqual(line_expected, line_actual, \
           ('Files differ at line {0}\n'
            'Expected: {1}\n'
            'Actual  : {2}\n'
            'Path of expected output file: {3}\n'
            'Path of actual output file: {4}\n'
            '{5}').format(line_num, repr(line_expected), repr(line_actual),
                          file_expected, file_actual, regen_message))

  def assertMultilineStringEqual(self, str_expected, str_actual):
    expected = str_expected.strip().split('\n')
    actual = str_actual.strip().split('\n')
    for line_num, (line_expected, line_actual) in \
        enumerate(zip_longest(expected, actual)):
      self.assertEqual(line_expected, line_actual, \
         ('Strings differ at line {0}\n'
          'Expected: {1}\n'
          'Actual  : {2}\n').format(line_num, repr(line_expected),
                                    repr(line_actual)))

  def testMainWithExampleWithBuildAndMosysCBindings(self):
    json_output = os.path.join(self.tempdir, 'output.json')
    c_output = os.path.join(self.tempdir, 'config.c')
    cros_config_schema.Main(
        None,
        os.path.join(this_dir, '../test_data/test.yaml'),
        json_output,
        gen_c_output_dir=self.tempdir)

    expected_json_file = os.path.join(this_dir, '../test_data/test_build.json')
    self.assertFileEqual(expected_json_file, json_output)

    expected_c_file = os.path.join(this_dir, '../test_data/test.c')
    self.assertFileEqual(expected_c_file, c_output)

  def testMainWithExampleWithoutBuild(self):
    output = os.path.join(self.tempdir, 'output')
    cros_config_schema.Main(
        None,
        os.path.join(this_dir, '../test_data/test.yaml'),
        output,
        filter_build_details=True)

    expected_file = os.path.join(this_dir, '../test_data/test.json')
    self.assertFileEqual(expected_file, output)

  def testMainArmExample(self):
    json_output = os.path.join(self.tempdir, 'output.json')
    c_output = os.path.join(self.tempdir, 'config.c')
    cros_config_schema.Main(
        None,
        os.path.join(this_dir, '../test_data/test_arm.yaml'),
        json_output,
        filter_build_details=True,
        gen_c_output_dir=self.tempdir)

    expected_json_file = os.path.join(this_dir, '../test_data/test_arm.json')
    self.assertFileEqual(expected_json_file, json_output)

    expected_c_file = os.path.join(this_dir, '../test_data/test_arm.c')
    self.assertFileEqual(expected_c_file, c_output)

  def testMainImportExample(self):
    output = os.path.join(self.tempdir, 'output')
    cros_config_schema.Main(
        None,
        os.path.join(this_dir, '../test_data/test_import.yaml'),
        output)
    expected_file = os.path.join(this_dir, '../test_data/test_import.json')
    self.assertFileEqual(expected_file, output)

  def testMainMergeExample(self):
    output = os.path.join(self.tempdir, 'output')
    base_path = os.path.join(this_dir, '../test_data')
    cros_config_schema.Main(
        None,
        None,
        output,
        configs=[os.path.join(base_path, 'test_merge_base.yaml'),
                 os.path.join(base_path, 'test_merge_overlay.yaml')])
    expected_file = os.path.join(this_dir, '../test_data/test_merge.json')
    self.assertFileEqual(expected_file, output)

  def testMainZephyrFilter(self):
    output = os.path.join(self.tempdir, 'output')
    base_path = os.path.join(this_dir, '../test_data')
    cros_config_schema.Main(
        None,
        None,
        output,
        configs=[os.path.join(base_path, 'test.yaml')],
        zephyr_ec_configs_only=True)
    expected_file = os.path.join(base_path, 'test_zephyr.json')
    self.assertFileEqual(expected_file, output)

  def testClangFormat(self):
    test_input = 'int main(int argc, char **argv) { return 0; }'
    expected = textwrap.dedent("""\
    int main(int argc, char** argv) {
      return 0;
    }""")
    formatted = cros_config_schema.ClangFormat(test_input)
    self.assertEqual(formatted, expected)


if __name__ == '__main__':
  cros_test_lib.main(module=__name__)
