#!/usr/bin/python2
# Copyright 2015 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.
"""Unit tests for the libtpm2 structure_generator."""
from __future__ import print_function
import StringIO
import os
import unittest
import extract_structures
import structure_generator
class TestGenerators(unittest.TestCase):
"""Test structure_generator classes."""
def testTypedefMarshal(self):
"""Test generation of marshaling code for typedefs."""
marshalled_types = set(['int'])
typedef = structure_generator.Typedef('int', 'INT')
typedef2 = structure_generator.Typedef('INT', 'INT2')
typemap = {'INT': typedef}
out_file = StringIO.StringIO()
typedef2.OutputMarshalImpl(out_file, marshalled_types, typemap)
self.assertIn('INT', marshalled_types)
self.assertIn('INT2', marshalled_types)
out_file.close()
def testConstantTypeMarshal(self):
"""Test generation of marshaling code for constant types."""
marshalled_types = set(['int'])
typedef = structure_generator.Typedef('int', 'UINT16')
constant = structure_generator.ConstantType('UINT16', 'TPM_TYPE')
constant.valid_values.append('VALUE0')
constant.valid_values.append('VALUE1')
typemap = {'UINT16': typedef}
out_file = StringIO.StringIO()
constant.OutputMarshalImpl(out_file, marshalled_types, typemap)
self.assertIn('UINT16', marshalled_types)
self.assertIn('TPM_TYPE', marshalled_types)
out_file.close()
def testAttributeStructureMarshal(self):
"""Test generation of marshaling code for attribute structures."""
marshalled_types = set(['int'])
typedef = structure_generator.Typedef('int', 'UINT16')
attributeStruct = structure_generator.AttributeStructure(
'UINT16', 'TPM_TYPE')
attributeStruct.reserved.append('4_7')
attributeStruct.reserved.append('1')
typemap = {'UINT16': typedef}
out_file = StringIO.StringIO()
attributeStruct.OutputMarshalImpl(out_file, marshalled_types, typemap)
self.assertIn('UINT16', marshalled_types)
self.assertIn('TPM_TYPE', marshalled_types)
out_file.close()
def testInterfacemarshal(self):
"""test generation of marshaling code for interfaces."""
marshalled_types = set(['int'])
typedef = structure_generator.Typedef('int', 'UINT16')
interface = structure_generator.Interface('UINT16', 'TPM_TYPE')
interface.conditional = 'TPM_VALUE_NULL'
interface.bounds.append(('TPM_MIN', 'TPM_MAX'))
interface.valid_values.append('VALUE0')
interface.valid_values.append('VALUE1')
typemap = {'UINT16': typedef}
out_file = StringIO.StringIO()
interface.OutputMarshalImpl(out_file, marshalled_types, typemap)
self.assertIn('UINT16', marshalled_types)
self.assertIn('TPM_TYPE', marshalled_types)
out_file.close()
def testStructMarshal(self):
"""Test generation of marshaling code for structures."""
marshalled_types = set(['int'])
struct = structure_generator.Structure('TEST_STRUCT')
struct.AddField(structure_generator.Field('UINT16', 'type', None, False))
struct.AddField(structure_generator.Field('TPMI_TYPE', 'interfaceField0',
'TRUE', False))
struct.AddField(structure_generator.Field('TPMI_TYPE', 'interfaceField1',
'FALSE', False))
struct.AddField(structure_generator.Field('TPMU_SYM_MODE', 'unionField',
'type', False))
struct.AddField(structure_generator.Field('UINT16', 'arrayField',
'MAX_VALUE', True))
typedef = structure_generator.Typedef('int', 'UINT16')
interface = structure_generator.Interface('UINT16', 'TPMI_TYPE')
# Choose TPMU_SYM_MODE because it exists in selectors definition and it
# has few fields.
union = structure_generator.Union('TPMU_SYM_MODE')
union.AddField(structure_generator.Field('UINT16', 'aes', None))
union.AddField(structure_generator.Field('UINT16', 'SM4', None))
typemap = {
'UINT16': typedef,
'TPMI_TYPE': interface,
'TPMU_SYM_MODE': union
}
out_file = StringIO.StringIO()
struct.OutputMarshalImpl(out_file, marshalled_types, typemap)
self.assertIn('UINT16', marshalled_types)
self.assertIn('TPMI_TYPE', marshalled_types)
self.assertIn('TPMU_SYM_MODE', marshalled_types)
self.assertIn('TEST_STRUCT', marshalled_types)
out_file.close()
def testUnionMarshal(self):
"""Test generation of marshaling code for unions."""
marshalled_types = set(['int'])
union = structure_generator.Union('TPMU_SYM_MODE')
union.AddField(structure_generator.Field('UINT16', 'aes', None))
union.AddField(structure_generator.Field('UINT16', 'SM4', None))
typedef = structure_generator.Typedef('int', 'UINT16')
typemap = {'UINT16': typedef}
out_file = StringIO.StringIO()
union.OutputMarshalImpl(out_file, marshalled_types, typemap)
self.assertIn('UINT16', marshalled_types)
self.assertIn('TPMU_SYM_MODE', marshalled_types)
out_file.close()
def _MakeArg(self, arg_type, arg_name):
return {'type': arg_type,
'name': arg_name,
'command_code': None,
'description': None}
class TestParser(unittest.TestCase):
"""Test structure parser."""
def testStructureParser(self):
"""Test the structure parser with valid data.
One of each typedef, constant type, attribute structure, interface,
structure, and union. Should appear in types array in that order.
"""
html_parser = extract_structures.SpecParser()
html_file_name = os.path.join(os.path.dirname(__file__),
'test_structure_generator.html')
html_parser.feed(open(html_file_name).read())
html_parser.close()
types = html_parser.GetTable().GetTypeMap()
self.assertEqual(len(types), 6)
tpm_obj = types['UINT16']
self.assertEqual(tpm_obj.old_type, 'uint16_t')
self.assertEqual(tpm_obj.new_type, 'UINT16')
tpm_obj = types['TPMA_LOCALITY']
self.assertEqual(tpm_obj.old_type, 'base_type')
self.assertEqual(tpm_obj.new_type, 'TPMA_LOCALITY')
self.assertEqual(tpm_obj.reserved[0], '4_7')
self.assertEqual(tpm_obj.reserved[1], '9')
tpm_obj = types['const_type']
self.assertEqual(tpm_obj.old_type, 'base_type')
self.assertEqual(tpm_obj.new_type, 'const_type')
self.assertEqual(tpm_obj.valid_values[0], 'const_name')
self.assertEqual(tpm_obj.error_code, 'return_name')
tpm_obj = types['TPMI_DH_OBJECT']
self.assertEqual(tpm_obj.old_type, 'base_type')
self.assertEqual(tpm_obj.new_type, 'TPMI_DH_OBJECT')
self.assertEqual(tpm_obj.bounds[0][0], 'min_name')
self.assertEqual(tpm_obj.bounds[0][1], 'max_name')
self.assertEqual(tpm_obj.valid_values[0], 'const_name')
self.assertEqual(tpm_obj.conditional_value, 'null_name')
self.assertEqual(tpm_obj.error_code, 'return_name')
tpm_obj = types['struct_type']
self.assertEqual(tpm_obj.name, 'struct_type')
self.assertEqual(tpm_obj.fields[0].field_type, 'UINT16')
self.assertEqual(tpm_obj.fields[0].field_name, 'field1')
self.assertEqual(tpm_obj.fields[1].field_type, 'UINT16')
self.assertEqual(tpm_obj.fields[1].field_name, 'field2')
self.assertEqual(tpm_obj.fields[2].field_type, 'UINT16')
self.assertEqual(tpm_obj.fields[2].field_name, 'field3')
self.assertEqual(tpm_obj.fields[2].run_time_size, 'field1')
self.assertEqual(tpm_obj.fields[3].field_type, 'UINT16')
self.assertEqual(tpm_obj.fields[3].field_name, 'field4')
self.assertEqual(tpm_obj.fields[3].selector_value, 'field2')
self.assertEqual(tpm_obj.fields[4].field_type, 'interface_type')
self.assertEqual(tpm_obj.fields[4].field_name, 'field5')
self.assertEqual(tpm_obj.upper_bounds['field1'], 'max')
self.assertEqual(tpm_obj.lower_bounds['field1'], 'min')
tpm_obj = types['union_type']
self.assertEqual(tpm_obj.name, 'union_type')
self.assertEqual(tpm_obj.fields[0].field_type, 'field1_type')
self.assertEqual(tpm_obj.fields[0].field_name, 'field1')
self.assertEqual(tpm_obj.fields[1].field_type, 'field2_type')
self.assertEqual(tpm_obj.fields[1].field_name, 'field2')
if __name__ == '__main__':
unittest.main()