164cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn#!/usr/bin/python
264cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn
3bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi#
4bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi# Copyright (C) 2014 The Android Open Source Project
5bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi#
6bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi# Licensed under the Apache License, Version 2.0 (the "License");
7bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi# you may not use this file except in compliance with the License.
8bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi# You may obtain a copy of the License at
9bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi#
10bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi#      http://www.apache.org/licenses/LICENSE-2.0
11bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi#
12bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi# Unless required by applicable law or agreed to in writing, software
13bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi# distributed under the License is distributed on an "AS IS" BASIS,
14bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi# See the License for the specific language governing permissions and
16bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi# limitations under the License.
17bbef5dff2b94fef72012e721cd6124cd87621af4Utkarsh Sanghi#
1864cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn
1964cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn"""Unit tests for the TPM 2.0 code generator."""
2064cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn
2113aa3598a0849d860d494410822fe94c624a7511Darren Krahnfrom __future__ import print_function
2213aa3598a0849d860d494410822fe94c624a7511Darren Krahn
2364cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahnimport StringIO
2464cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahnimport unittest
2564cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn
2664cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahnimport generator
2764cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn
2864cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn
2964cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahnclass TestGenerators(unittest.TestCase):
3064cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn  """Test generator classes."""
3164cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn
3264cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn  def testTypedef(self):
3364cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    """Test generation of typedefs and dependencies."""
3464cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    typedef = generator.Typedef('int', 'INT')
3564cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    defined_types = set(['int'])
3664cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    typemap = {}
3764cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    out_file = StringIO.StringIO()
3864cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    # Expect this to just write the typedef.
3964cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    typedef.OutputForward(out_file, defined_types, typemap)
4064cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    # Expect this to know it has already been written.
4164cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    typedef.Output(out_file, defined_types, typemap)
4264cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(out_file.getvalue(), 'typedef int INT;\n')
4364cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertIn('INT', defined_types)
4464cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    typedef2 = generator.Typedef('TYPE1', 'TYPE2')
4564cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    typemap = {'TYPE1': generator.Structure('TYPE1', False)}
4664cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    defined_types = set([])
4764cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    out_file2 = StringIO.StringIO()
4864cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    # Expect this to write first TYPE1 forward then TYPE2 typedef.
4964cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    typedef2.Output(out_file2, defined_types, typemap)
5064cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    output_re = r'struct TYPE1;\s+typedef TYPE1 TYPE2;\s+'
5164cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertRegexpMatches(out_file2.getvalue(), output_re)
5264cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertIn('TYPE2', defined_types)
5364cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    out_file.close()
5464cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    out_file2.close()
5564cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn
56b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn  def testTypedefSerialize(self):
57b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    """Test generation of serialization code for typedefs."""
58b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    serialized_types = set(['int'])
59b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    typedef = generator.Typedef('int', 'INT')
60b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    typedef2 = generator.Typedef('INT', 'INT2')
61b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    typemap = {'INT': typedef}
62b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    out_file = StringIO.StringIO()
63b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    typedef2.OutputSerialize(out_file, serialized_types, typemap)
64b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    self.assertIn('INT', serialized_types)
65b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    self.assertIn('INT2', serialized_types)
66b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    out_file.close()
67b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn
6864cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn  def testConstant(self):
6964cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    """Test generation of constant definitions and type dependencies."""
7064cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    constant = generator.Constant('INT', 'test', '1')
7164cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    typemap = {'INT': generator.Structure('INT', False)}
7264cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    defined_types = set([])
7364cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    out_file = StringIO.StringIO()
7464cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    constant.Output(out_file, defined_types, typemap)
7564cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    output_re = r'struct INT;\s+const INT test = 1;\s+'
7664cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertRegexpMatches(out_file.getvalue(), output_re)
7764cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    out_file.close()
7864cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn
7964cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn  def testStructure(self):
8064cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    """Test generation of structure declarations and field dependencies."""
8164cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    struct = generator.Structure('STRUCT', False)
8264cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    struct.AddField('int', 'i')
8364cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    struct.AddDependency('DEPEND')
8464cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    union = generator.Structure('UNION', True)
8564cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    union.AddField('STRUCT', 'inner')
8664cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    depend = generator.Structure('DEPEND', False)
8764cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    defined_types = set(['int'])
8864cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    out_file = StringIO.StringIO()
8964cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    typemap = {'STRUCT': struct, 'DEPEND': depend}
9064cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    # Only output |union|, this will test the dependency logic.
9164cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    union.OutputForward(out_file, defined_types, typemap)
9264cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    union.OutputForward(out_file, defined_types, typemap)
9364cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    union.Output(out_file, defined_types, typemap)
9464cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    output_re = r'union UNION;\s+struct DEPEND {\s+};\s+'
9564cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    output_re += r'struct STRUCT {\s+int i;\s+};\s+'
9664cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    output_re += r'union UNION {\s+STRUCT inner;\s+};\s+'
9764cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertRegexpMatches(out_file.getvalue(), output_re)
9864cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    for t in ('STRUCT', 'DEPEND', 'UNION'):
9964cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn      self.assertIn(t, defined_types)
100b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    # Test serialize / parse code generation.
101b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    out_file.close()
102b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn
103b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn  def testStructSerialize(self):
104b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    """Test generation of serialization code for typedefs."""
105b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    serialized_types = set(['int', 'FOO', 'BAR', 'TPMI_ALG_SYM_OBJECT'])
106b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    struct = generator.Structure('TEST_STRUCT', False)
107b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    struct.fields = [('TPMI_ALG_SYM_OBJECT', 'selector'),
108b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn                     ('TPMU_SYM_MODE', 'mode'),
109b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn                     ('int', 'sizeOfFoo'),
110b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn                     ('int', 'foo[FOO_MAX]')]
111b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    # Choose TPMU_SYM_MODE because it exists in the selectors definition and it
112b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    # has few fields.
113b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    union = generator.Structure('TPMU_SYM_MODE', True)
114a0471fe9c5a68344516f5897a1f1c342438e514eDarren Krahn    union.fields = [('FOO', 'aes'), ('BAR', 'sm4')]
115b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    typemap = {'TPMU_SYM_MODE': union}
116b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    out_file = StringIO.StringIO()
117b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    struct.OutputSerialize(out_file, serialized_types, typemap)
118b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    self.assertIn('TPMU_SYM_MODE', serialized_types)
119b49375c15718568c70ebfd55eaee790a2b693944Darren Krahn    self.assertIn('TEST_STRUCT', serialized_types)
12064cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    out_file.close()
12164cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn
12264cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn  def testDefine(self):
12364cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    """Test generation of preprocessor defines."""
12464cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    define = generator.Define('name', 'value')
12564cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    out_file = StringIO.StringIO()
12664cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    define.Output(out_file)
12764cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    output_re = r'#if !defined\(name\)\s+#define name value\s+#endif\s+'
12864cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertRegexpMatches(out_file.getvalue(), output_re)
12964cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    out_file.close()
13064cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn
13164cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn  def _MakeArg(self, arg_type, arg_name):
13264cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    return {'type': arg_type,
13364cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn            'name': arg_name,
13464cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn            'command_code': None,
13564cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn            'description': None}
13664cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn
13764cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn  def testCommand(self):
13864cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    """Test generation of command methods and callbacks."""
13964cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    command = generator.Command('TPM2_Test')
14064cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    command.request_args = [self._MakeArg('int', 'input')]
14113aa3598a0849d860d494410822fe94c624a7511Darren Krahn    command.response_args = [self._MakeArg('char', 'output')]
14264cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    out_file = StringIO.StringIO()
14364cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    command.OutputDeclarations(out_file)
14413aa3598a0849d860d494410822fe94c624a7511Darren Krahn    expected_callback = """typedef base::Callback<void(
14513aa3598a0849d860d494410822fe94c624a7511Darren Krahn      TPM_RC response_code,
14613aa3598a0849d860d494410822fe94c624a7511Darren Krahn      const char& output)> TestResponse;"""
14713aa3598a0849d860d494410822fe94c624a7511Darren Krahn    self.assertIn(expected_callback, out_file.getvalue())
14813aa3598a0849d860d494410822fe94c624a7511Darren Krahn    expected_serialize = """static TPM_RC SerializeCommand_Test(
14913aa3598a0849d860d494410822fe94c624a7511Darren Krahn      const int& input,
15013aa3598a0849d860d494410822fe94c624a7511Darren Krahn      std::string* serialized_command,
15113aa3598a0849d860d494410822fe94c624a7511Darren Krahn      AuthorizationDelegate* authorization_delegate);"""
15213aa3598a0849d860d494410822fe94c624a7511Darren Krahn    self.assertIn(expected_serialize, out_file.getvalue())
15313aa3598a0849d860d494410822fe94c624a7511Darren Krahn    expected_parse = """static TPM_RC ParseResponse_Test(
15413aa3598a0849d860d494410822fe94c624a7511Darren Krahn      const std::string& response,
15513aa3598a0849d860d494410822fe94c624a7511Darren Krahn      char* output,
15613aa3598a0849d860d494410822fe94c624a7511Darren Krahn      AuthorizationDelegate* authorization_delegate);"""
15713aa3598a0849d860d494410822fe94c624a7511Darren Krahn    self.assertIn(expected_parse, out_file.getvalue())
15813aa3598a0849d860d494410822fe94c624a7511Darren Krahn    expected_async = """virtual void Test(
15913aa3598a0849d860d494410822fe94c624a7511Darren Krahn      const int& input,
16013aa3598a0849d860d494410822fe94c624a7511Darren Krahn      AuthorizationDelegate* authorization_delegate,
16113aa3598a0849d860d494410822fe94c624a7511Darren Krahn      const TestResponse& callback);"""
16213aa3598a0849d860d494410822fe94c624a7511Darren Krahn    self.assertIn(expected_async, out_file.getvalue())
16313aa3598a0849d860d494410822fe94c624a7511Darren Krahn    expected_sync = """virtual TPM_RC TestSync(
16413aa3598a0849d860d494410822fe94c624a7511Darren Krahn      const int& input,
16513aa3598a0849d860d494410822fe94c624a7511Darren Krahn      char* output,
16613aa3598a0849d860d494410822fe94c624a7511Darren Krahn      AuthorizationDelegate* authorization_delegate);"""
16713aa3598a0849d860d494410822fe94c624a7511Darren Krahn    self.assertIn(expected_sync, out_file.getvalue())
16864cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    out_file.close()
16964cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn
17064cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn
17164cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahnclass TestParsers(unittest.TestCase):
17264cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn  """Test parser classes."""
17364cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn
17464cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn  FAKE_TYPEDEF = '_BEGIN_TYPES\n_OLD_TYPE type1\n_NEW_TYPE type2\n_END\n'
17564cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn  FAKE_CONSTANT = ('_BEGIN_CONSTANTS\n_CONSTANTS (base_type) const_type\n'
17664cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn                   '_TYPE base_type\n_NAME const_name\n_VALUE const_value\n'
17764cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn                   '_END\n')
17864cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn  FAKE_STRUCTURE = ('_BEGIN_STRUCTURES\n_STRUCTURE struct_type\n'
17964cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn                    '_TYPE field_type\n'
18064cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn                    '_NAME field_name[sizeof(depend_type)]\n_END\n')
18164cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn  FAKE_DEFINE = '_BEGIN_DEFINES\n_NAME define_name\n_VALUE define_value\n_END'
18264cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn  FAKE_COMMAND = ('_BEGIN\n_INPUT_START TPM2_Test\n'
18364cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn                  '_TYPE UINT32\n_NAME commandSize\n'
18464cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn                  '_TYPE TPM_CC\n_NAME commandCode\n_COMMENT TPM_CC_Test\n'
18564cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn                  '_TYPE UINT16\n_NAME input\n'
18664cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn                  '_OUTPUT_START TPM2_Test\n_END\n')
18764cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn
18864cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn  def testStructureParserWithBadData(self):
18964cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    """Test the structure parser with invalid data."""
19064cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    input_data = 'bad_data'
19164cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    in_file = StringIO.StringIO(input_data)
19264cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    parser = generator.StructureParser(in_file)
19364cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    types, constants, structs, defines, typemap = parser.Parse()
19464cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertIsNotNone(types)
19564cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertIsNotNone(constants)
19664cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertIsNotNone(structs)
19764cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertIsNotNone(defines)
19864cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertIsNotNone(typemap)
19964cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn
20064cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn  def testStructureParser(self):
20164cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    """Test the structure parser with valid data."""
20264cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    input_data = (self.FAKE_TYPEDEF + self.FAKE_CONSTANT + self.FAKE_STRUCTURE +
20364cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn                  self.FAKE_DEFINE)
20464cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    in_file = StringIO.StringIO(input_data)
20564cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    parser = generator.StructureParser(in_file)
20664cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    types, constants, structs, defines, typemap = parser.Parse()
20764cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    # Be flexible on these counts because the parser may add special cases.
20864cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertGreaterEqual(len(types), 2)
20964cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertGreaterEqual(len(constants), 1)
21064cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertGreaterEqual(len(structs), 1)
21164cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertGreaterEqual(len(defines), 1)
21264cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertGreaterEqual(len(typemap), 3)
21364cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(types[0].old_type, 'type1')
21464cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(types[0].new_type, 'type2')
21564cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(types[1].old_type, 'base_type')
21664cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(types[1].new_type, 'const_type')
21764cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(constants[0].const_type, 'const_type')
21864cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(constants[0].name, 'const_name')
21964cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(constants[0].value, 'const_value')
22064cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(structs[0].name, 'struct_type')
22164cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(structs[0].is_union, False)
22264cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(len(structs[0].fields), 1)
22364cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(structs[0].fields[0][0], 'field_type')
22464cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(structs[0].fields[0][1], 'field_name[sizeof(depend_type)]')
22564cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(len(structs[0].depends_on), 1)
22664cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(structs[0].depends_on[0], 'depend_type')
22764cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(defines[0].name, 'define_name')
22864cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(defines[0].value, 'define_value')
22964cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn
23064cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn  def testCommandParserWithBadData(self):
23164cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    """Test the command parser with invalid data."""
23264cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    input_data = 'bad_data'
23364cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    in_file = StringIO.StringIO(input_data)
23464cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    parser = generator.CommandParser(in_file)
23564cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    commands = parser.Parse()
23664cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertIsNotNone(commands)
23764cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn
23864cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn  def testCommandParser(self):
23964cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    """Test the command parser with valid data."""
24064cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    input_data = self.FAKE_COMMAND
24164cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    in_file = StringIO.StringIO(input_data)
24264cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    parser = generator.CommandParser(in_file)
24364cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    commands = parser.Parse()
24464cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(len(commands), 1)
24564cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(commands[0].name, 'TPM2_Test')
24664cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(commands[0].command_code, 'TPM_CC_Test')
24764cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    # We expect the 'commandSize' and 'commandCode' args to be filtered out.
24864cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(len(commands[0].request_args), 1)
24964cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(commands[0].request_args[0]['type'], 'UINT16')
25064cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertEqual(commands[0].request_args[0]['name'], 'input')
25164cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertIsNotNone(commands[0].response_args)
25264cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn    self.assertFalse(commands[0].response_args)
25364cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn
25464cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn
25564cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahnif __name__ == '__main__':
25664cad7ce8e7c1e7ee10e25a162af219b0e06741cDarren Krahn  unittest.main()
257