| #!/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() |