1#!/usr/bin/python2 2 3# Copyright 2015 The Chromium OS Authors. All rights reserved. 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7"""Unit tests for the libtpm2 structure_generator.""" 8 9from __future__ import print_function 10 11import StringIO 12import os 13import unittest 14 15import extract_structures 16import structure_generator 17 18 19class TestGenerators(unittest.TestCase): 20 """Test structure_generator classes.""" 21 22 def testTypedefMarshal(self): 23 """Test generation of marshaling code for typedefs.""" 24 marshalled_types = set(['int']) 25 typedef = structure_generator.Typedef('int', 'INT') 26 typedef2 = structure_generator.Typedef('INT', 'INT2') 27 typemap = {'INT': typedef} 28 out_file = StringIO.StringIO() 29 typedef2.OutputMarshalImpl(out_file, marshalled_types, typemap) 30 self.assertIn('INT', marshalled_types) 31 self.assertIn('INT2', marshalled_types) 32 out_file.close() 33 34 def testConstantTypeMarshal(self): 35 """Test generation of marshaling code for constant types.""" 36 marshalled_types = set(['int']) 37 typedef = structure_generator.Typedef('int', 'UINT16') 38 constant = structure_generator.ConstantType('UINT16', 'TPM_TYPE') 39 constant.valid_values.append('VALUE0') 40 constant.valid_values.append('VALUE1') 41 typemap = {'UINT16': typedef} 42 out_file = StringIO.StringIO() 43 constant.OutputMarshalImpl(out_file, marshalled_types, typemap) 44 self.assertIn('UINT16', marshalled_types) 45 self.assertIn('TPM_TYPE', marshalled_types) 46 out_file.close() 47 48 def testAttributeStructureMarshal(self): 49 """Test generation of marshaling code for attribute structures.""" 50 marshalled_types = set(['int']) 51 typedef = structure_generator.Typedef('int', 'UINT16') 52 attributeStruct = structure_generator.AttributeStructure( 53 'UINT16', 'TPM_TYPE') 54 attributeStruct.reserved.append('4_7') 55 attributeStruct.reserved.append('1') 56 typemap = {'UINT16': typedef} 57 out_file = StringIO.StringIO() 58 attributeStruct.OutputMarshalImpl(out_file, marshalled_types, typemap) 59 self.assertIn('UINT16', marshalled_types) 60 self.assertIn('TPM_TYPE', marshalled_types) 61 out_file.close() 62 63 def testInterfacemarshal(self): 64 """test generation of marshaling code for interfaces.""" 65 marshalled_types = set(['int']) 66 typedef = structure_generator.Typedef('int', 'UINT16') 67 interface = structure_generator.Interface('UINT16', 'TPM_TYPE') 68 interface.conditional = 'TPM_VALUE_NULL' 69 interface.bounds.append(('TPM_MIN', 'TPM_MAX')) 70 interface.valid_values.append('VALUE0') 71 interface.valid_values.append('VALUE1') 72 typemap = {'UINT16': typedef} 73 out_file = StringIO.StringIO() 74 interface.OutputMarshalImpl(out_file, marshalled_types, typemap) 75 self.assertIn('UINT16', marshalled_types) 76 self.assertIn('TPM_TYPE', marshalled_types) 77 out_file.close() 78 79 def testStructMarshal(self): 80 """Test generation of marshaling code for structures.""" 81 marshalled_types = set(['int']) 82 struct = structure_generator.Structure('TEST_STRUCT') 83 struct.AddField(structure_generator.Field('UINT16', 'type', None, False)) 84 struct.AddField(structure_generator.Field('TPMI_TYPE', 'interfaceField0', 85 'TRUE', False)) 86 struct.AddField(structure_generator.Field('TPMI_TYPE', 'interfaceField1', 87 'FALSE', False)) 88 struct.AddField(structure_generator.Field('TPMU_SYM_MODE', 'unionField', 89 'type', False)) 90 struct.AddField(structure_generator.Field('UINT16', 'arrayField', 91 'MAX_VALUE', True)) 92 typedef = structure_generator.Typedef('int', 'UINT16') 93 interface = structure_generator.Interface('UINT16', 'TPMI_TYPE') 94 # Choose TPMU_SYM_MODE because it exists in selectors definition and it 95 # has few fields. 96 union = structure_generator.Union('TPMU_SYM_MODE') 97 union.AddField(structure_generator.Field('UINT16', 'aes', None)) 98 union.AddField(structure_generator.Field('UINT16', 'SM4', None)) 99 typemap = { 100 'UINT16': typedef, 101 'TPMI_TYPE': interface, 102 'TPMU_SYM_MODE': union 103 } 104 out_file = StringIO.StringIO() 105 struct.OutputMarshalImpl(out_file, marshalled_types, typemap) 106 self.assertIn('UINT16', marshalled_types) 107 self.assertIn('TPMI_TYPE', marshalled_types) 108 self.assertIn('TPMU_SYM_MODE', marshalled_types) 109 self.assertIn('TEST_STRUCT', marshalled_types) 110 out_file.close() 111 112 def testUnionMarshal(self): 113 """Test generation of marshaling code for unions.""" 114 marshalled_types = set(['int']) 115 union = structure_generator.Union('TPMU_SYM_MODE') 116 union.AddField(structure_generator.Field('UINT16', 'aes', None)) 117 union.AddField(structure_generator.Field('UINT16', 'SM4', None)) 118 typedef = structure_generator.Typedef('int', 'UINT16') 119 typemap = {'UINT16': typedef} 120 out_file = StringIO.StringIO() 121 union.OutputMarshalImpl(out_file, marshalled_types, typemap) 122 self.assertIn('UINT16', marshalled_types) 123 self.assertIn('TPMU_SYM_MODE', marshalled_types) 124 out_file.close() 125 126 def _MakeArg(self, arg_type, arg_name): 127 return {'type': arg_type, 128 'name': arg_name, 129 'command_code': None, 130 'description': None} 131 132 133class TestParser(unittest.TestCase): 134 """Test structure parser.""" 135 136 def testStructureParser(self): 137 """Test the structure parser with valid data. 138 139 One of each typedef, constant type, attribute structure, interface, 140 structure, and union. Should appear in types array in that order. 141 """ 142 html_parser = extract_structures.SpecParser() 143 html_file_name = os.path.join(os.path.dirname(__file__), 144 'test_structure_generator.html') 145 html_parser.feed(open(html_file_name).read()) 146 html_parser.close() 147 types = html_parser.GetTable().GetTypeMap() 148 self.assertEqual(len(types), 6) 149 tpm_obj = types['UINT16'] 150 self.assertEqual(tpm_obj.old_type, 'uint16_t') 151 self.assertEqual(tpm_obj.new_type, 'UINT16') 152 tpm_obj = types['TPMA_LOCALITY'] 153 self.assertEqual(tpm_obj.old_type, 'base_type') 154 self.assertEqual(tpm_obj.new_type, 'TPMA_LOCALITY') 155 self.assertEqual(tpm_obj.reserved[0], '4_7') 156 self.assertEqual(tpm_obj.reserved[1], '9') 157 tpm_obj = types['const_type'] 158 self.assertEqual(tpm_obj.old_type, 'base_type') 159 self.assertEqual(tpm_obj.new_type, 'const_type') 160 self.assertEqual(tpm_obj.valid_values[0], 'const_name') 161 self.assertEqual(tpm_obj.error_code, 'return_name') 162 tpm_obj = types['TPMI_DH_OBJECT'] 163 self.assertEqual(tpm_obj.old_type, 'base_type') 164 self.assertEqual(tpm_obj.new_type, 'TPMI_DH_OBJECT') 165 self.assertEqual(tpm_obj.bounds[0][0], 'min_name') 166 self.assertEqual(tpm_obj.bounds[0][1], 'max_name') 167 self.assertEqual(tpm_obj.valid_values[0], 'const_name') 168 self.assertEqual(tpm_obj.conditional_value, 'null_name') 169 self.assertEqual(tpm_obj.error_code, 'return_name') 170 tpm_obj = types['struct_type'] 171 self.assertEqual(tpm_obj.name, 'struct_type') 172 self.assertEqual(tpm_obj.fields[0].field_type, 'UINT16') 173 self.assertEqual(tpm_obj.fields[0].field_name, 'field1') 174 self.assertEqual(tpm_obj.fields[1].field_type, 'UINT16') 175 self.assertEqual(tpm_obj.fields[1].field_name, 'field2') 176 self.assertEqual(tpm_obj.fields[2].field_type, 'UINT16') 177 self.assertEqual(tpm_obj.fields[2].field_name, 'field3') 178 self.assertEqual(tpm_obj.fields[2].run_time_size, 'field1') 179 self.assertEqual(tpm_obj.fields[3].field_type, 'UINT16') 180 self.assertEqual(tpm_obj.fields[3].field_name, 'field4') 181 self.assertEqual(tpm_obj.fields[3].selector_value, 'field2') 182 self.assertEqual(tpm_obj.fields[4].field_type, 'interface_type') 183 self.assertEqual(tpm_obj.fields[4].field_name, 'field5') 184 self.assertEqual(tpm_obj.upper_bounds['field1'], 'max') 185 self.assertEqual(tpm_obj.lower_bounds['field1'], 'min') 186 tpm_obj = types['union_type'] 187 self.assertEqual(tpm_obj.name, 'union_type') 188 self.assertEqual(tpm_obj.fields[0].field_type, 'field1_type') 189 self.assertEqual(tpm_obj.fields[0].field_name, 'field1') 190 self.assertEqual(tpm_obj.fields[1].field_type, 'field2_type') 191 self.assertEqual(tpm_obj.fields[1].field_name, 'field2') 192 193if __name__ == '__main__': 194 unittest.main() 195