#!/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, regen_cmd=''):
    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))

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

  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)
    regen_cmd = ('To regenerate the expected output, run:\n'
                 '\tpython -m cros_config_host.cros_config_schema '
                 '-c test_data/test.yaml '
                 '-o test_data/test_build.json '
                 '-g test_data')

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

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

  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)

    regen_cmd = ('To regenerate the expected output, run:\n'
                 '\tpython -m cros_config_host.cros_config_schema '
                 '-f True '
                 '-c test_data/test.yaml '
                 '-o test_data/test.json')

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

  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)
    regen_cmd = ('To regenerate the expected output, run:\n'
                 '\tpython -m cros_config_host.cros_config_schema '
                 '-f True '
                 '-c test_data/test_arm.yaml '
                 '-o test_data/test_arm.json '
                 '-g test_data')

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

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

  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)
    regen_cmd = ('To regenerate the expected output, run:\n'
                 '\tpython -m cros_config_host.cros_config_schema '
                 '-c test_data/test_import.yaml '
                 '-o test_data/test_import.json')
    expected_file = os.path.join(this_dir, '../test_data/test_import.json')
    self.assertFileEqual(expected_file, output, regen_cmd)

  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')])
    regen_cmd = ('To regenerate the expected output, run:\n'
                 '\tpython -m cros_config_host.cros_config_schema '
                 '-o test_data/test_merge.json '
                 '-m test_data/test_merge_base.yaml '
                 'test_data/test_merge_overlay.yaml')
    expected_file = os.path.join(this_dir, '../test_data/test_merge.json')
    self.assertFileEqual(expected_file, output, regen_cmd)

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