1## @file
2# This file contain unit test for DecParser
3#
4# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
5#
6# This program and the accompanying materials are licensed and made available
7# under the terms and conditions of the BSD License which accompanies this
8# distribution. The full text of the license may be found at
9# http://opensource.org/licenses/bsd-license.php
10#
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14import os
15import unittest
16
17from Parser.DecParserMisc import \
18    IsValidCArray, \
19    IsValidPcdDatum
20
21from Parser.DecParser import Dec
22
23from Library.ParserValidate import IsValidCFormatGuid
24
25#
26# Test tool function
27#
28def TestToolFuncs():
29    assert IsValidCArray('{0x1, 0x23}')
30
31    # Empty after comma
32    assert not IsValidCArray('{0x1, 0x23, }')
33
34    # 0x2345 too long
35    assert not IsValidCArray('{0x1, 0x2345}')
36
37    # Must end with '}'
38    assert not IsValidCArray('{0x1, 0x23, ')
39
40    # Whitespace between numbers
41    assert not IsValidCArray('{0x1, 0x2 3, }')
42
43    assert IsValidPcdDatum('VOID*', '"test"')[0]
44    assert IsValidPcdDatum('VOID*', 'L"test"')[0]
45    assert IsValidPcdDatum('BOOLEAN', 'TRUE')[0]
46    assert IsValidPcdDatum('BOOLEAN', 'FALSE')[0]
47    assert IsValidPcdDatum('BOOLEAN', '0')[0]
48    assert IsValidPcdDatum('BOOLEAN', '1')[0]
49    assert IsValidPcdDatum('UINT8', '0xab')[0]
50
51    assert not IsValidPcdDatum('UNKNOWNTYPE', '0xabc')[0]
52    assert not IsValidPcdDatum('UINT8', 'not number')[0]
53
54    assert( IsValidCFormatGuid('{ 0xfa0b1735 , 0x87a0, 0x4193, {0xb2, 0x66 , 0x53, 0x8c , 0x38, 0xaf, 0x48, 0xce }}'))
55    assert( not IsValidCFormatGuid('{ 0xfa0b1735 , 0x87a0, 0x4193, {0xb2, 0x66 , 0x53, 0x8c , 0x38, 0xaf, 0x48, 0xce }} 0xaa'))
56
57def TestTemplate(TestString, TestFunc):
58    Path = os.path.join(os.getcwd(), 'test.dec')
59    Path = os.path.normpath(Path)
60    try:
61        f = open(Path, 'w')
62
63        # Write test string to file
64        f.write(TestString)
65
66        # Close file
67        f.close()
68    except:
69        print 'Can not create temporary file [%s]!' % Path
70        exit(-1)
71
72    # Call test function to test
73    Ret = TestFunc(Path, TestString)
74
75    # Test done, remove temporary file
76    os.remove(Path)
77    return Ret
78
79# To make test unit works OK, must set IsRaiseError to True
80# This function test right syntax DEC file
81# @retval: parser object
82#
83def TestOK(Path, TestString):
84    try:
85        Parser = Dec(Path)
86    except:
87        raise 'Bug!!! Correct syntax in DEC file, but exception raised!\n' + TestString
88    return Parser
89
90# This function test wrong syntax DEC file
91# if parser checked wrong syntax, exception thrown and it's expected result
92def TestError(Path, TestString):
93    try:
94        Dec(Path)
95    except:
96        # Raise error, get expected result
97        return True
98    raise 'Bug!!! Wrong syntax in DEC file, but passed by DEC parser!!\n' + TestString
99
100def TestDecDefine():
101    TestString = '''
102    [Defines]
103      DEC_SPECIFICATION              = 0x00010005
104      PACKAGE_NAME                   = MdePkg
105      PACKAGE_GUID                   = 1E73767F-8F52-4603-AEB4-F29B510B6766
106      PACKAGE_VERSION                = 1.02
107    '''
108    Parser = TestTemplate(TestString, TestOK)
109    DefObj = Parser.GetDefineSectionObject()
110    assert DefObj.GetPackageSpecification() == '0x00010005'
111    assert DefObj.GetPackageName() == 'MdePkg'
112    assert DefObj.GetPackageGuid() == '1E73767F-8F52-4603-AEB4-F29B510B6766'
113    assert DefObj.GetPackageVersion() == '1.02'
114
115    TestString = '''
116    [Defines]
117      UNKNOW_KEY              = 0x00010005 # A unknown key
118    '''
119    assert TestTemplate(TestString, TestError)
120
121    TestString = '''
122    [Defines]
123      PACKAGE_GUID                   = F-8F52-4603-AEB4-F29B510B6766 # Error GUID
124    '''
125    assert TestTemplate(TestString, TestError)
126
127def TestDecInclude():
128    TestString = '''
129    [Defines]
130      DEC_SPECIFICATION              = 0x00010005
131      PACKAGE_NAME                   = MdePkg
132      PACKAGE_GUID                   = 1E73767F-8F52-4603-AEB4-F29B510B6766
133      PACKAGE_VERSION                = 1.02
134    [ \\
135    Includes]
136      Include
137    [Includes.IA32]
138      Include/Ia32
139    '''
140
141    # Create directory in current directory
142    try:
143        os.makedirs('Include/Ia32')
144    except:
145        pass
146    Parser = TestTemplate(TestString, TestOK)
147
148    IncObj = Parser.GetIncludeSectionObject()
149    Items = IncObj.GetIncludes()
150    assert len(Items) == 1
151    assert Items[0].File == 'Include'
152
153    Items = IncObj.GetIncludes('IA32')
154    assert len(Items) == 1
155    # normpath is called in DEC parser so '/' is converted to '\'
156    assert Items[0].File == 'Include\\Ia32'
157
158    TestString = '''
159    [Defines]
160      DEC_SPECIFICATION              = 0x00010005
161      PACKAGE_NAME                   = MdePkg
162      PACKAGE_GUID                   = 1E73767F-8F52-4603-AEB4-F29B510B6766
163      PACKAGE_VERSION                = 1.02
164    [Includes]
165      Include_not_exist  # directory does not exist
166    '''
167    assert TestTemplate(TestString, TestError)
168
169    os.removedirs('Include/Ia32')
170
171def TestDecGuidPpiProtocol():
172    TestString = '''
173    [Defines]
174      DEC_SPECIFICATION              = 0x00010005
175      PACKAGE_NAME                   = MdePkg
176      PACKAGE_GUID                   = 1E73767F-8F52-4603-AEB4-F29B510B6766
177      PACKAGE_VERSION                = 1.02
178    [Guids]
179      #
180      # GUID defined in UEFI2.1/UEFI2.0/EFI1.1
181      #
182      ## Include/Guid/GlobalVariable.h
183      gEfiGlobalVariableGuid         = { 0x8BE4DF61, 0x93CA, 0x11D2, { 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C }}
184    [Protocols]
185      ## Include/Protocol/Bds.h
186      gEfiBdsArchProtocolGuid        = { 0x665E3FF6, 0x46CC, 0x11D4, { 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }}
187    [Ppis]
188      ## Include/Ppi/MasterBootMode.h
189      gEfiPeiMasterBootModePpiGuid = { 0x7408d748, 0xfc8c, 0x4ee6, {0x92, 0x88, 0xc4, 0xbe, 0xc0, 0x92, 0xa4, 0x10 } }
190    '''
191    Parser = TestTemplate(TestString, TestOK)
192    Obj = Parser.GetGuidSectionObject()
193    Items = Obj.GetGuids()
194    assert Obj.GetSectionName() == 'Guids'.upper()
195    assert len(Items) == 1
196    assert Items[0].GuidCName == 'gEfiGlobalVariableGuid'
197    assert Items[0].GuidCValue == '{ 0x8BE4DF61, 0x93CA, 0x11D2, { 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C }}'
198
199    Obj = Parser.GetProtocolSectionObject()
200    Items = Obj.GetProtocols()
201    assert Obj.GetSectionName() == 'Protocols'.upper()
202    assert len(Items) == 1
203    assert Items[0].GuidCName == 'gEfiBdsArchProtocolGuid'
204    assert Items[0].GuidCValue == '{ 0x665E3FF6, 0x46CC, 0x11D4, { 0x9A, 0x38, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }}'
205
206    Obj = Parser.GetPpiSectionObject()
207    Items = Obj.GetPpis()
208    assert Obj.GetSectionName() == 'Ppis'.upper()
209    assert len(Items) == 1
210    assert Items[0].GuidCName == 'gEfiPeiMasterBootModePpiGuid'
211    assert Items[0].GuidCValue == '{ 0x7408d748, 0xfc8c, 0x4ee6, {0x92, 0x88, 0xc4, 0xbe, 0xc0, 0x92, 0xa4, 0x10 } }'
212
213def TestDecPcd():
214    TestString = '''
215    [Defines]
216      DEC_SPECIFICATION              = 0x00010005
217      PACKAGE_NAME                   = MdePkg
218      PACKAGE_GUID                   = 1E73767F-8F52-4603-AEB4-F29B510B6766
219      PACKAGE_VERSION                = 1.02
220    [PcdsFeatureFlag]
221      ## If TRUE, the component name protocol will not be installed.
222      gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE|BOOLEAN|0x0000000d
223
224    [PcdsFixedAtBuild]
225      ## Indicates the maximum length of unicode string
226      gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000|UINT32|0x00000001
227
228    [PcdsFixedAtBuild.IPF]
229      ## The base address of IO port space for IA64 arch
230      gEfiMdePkgTokenSpaceGuid.PcdIoBlockBaseAddressForIpf|0x0ffffc000000|UINT64|0x0000000f
231
232    [PcdsFixedAtBuild,PcdsPatchableInModule]
233      ## This flag is used to control the printout of DebugLib
234      gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000000|UINT32|0x00000006
235
236    [PcdsFixedAtBuild,PcdsPatchableInModule,PcdsDynamic]
237      ## This value is used to set the base address of pci express hierarchy
238      gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xE0000000|UINT64|0x0000000a
239    '''
240    Parser = TestTemplate(TestString, TestOK)
241    Obj = Parser.GetPcdSectionObject()
242    Items = Obj.GetPcds('PcdsFeatureFlag', 'COMMON')
243    assert len(Items) == 1
244    assert Items[0].TokenSpaceGuidCName == 'gEfiMdePkgTokenSpaceGuid'
245    assert Items[0].TokenCName == 'PcdComponentNameDisable'
246    assert Items[0].DefaultValue == 'FALSE'
247    assert Items[0].DatumType == 'BOOLEAN'
248    assert Items[0].TokenValue == '0x0000000d'
249
250    Items = Obj.GetPcdsByType('PcdsFixedAtBuild')
251    assert len(Items) == 4
252    assert len(Obj.GetPcdsByType('PcdsPatchableInModule')) == 2
253
254def TestDecUserExtension():
255    TestString = '''
256    [Defines]
257      DEC_SPECIFICATION              = 0x00010005
258      PACKAGE_NAME                   = MdePkg
259      PACKAGE_GUID                   = 1E73767F-8F52-4603-AEB4-F29B510B6766
260      PACKAGE_VERSION                = 1.02
261    [UserExtensions.MyID."TestString".IA32]
262      Some Strings...
263    '''
264    Parser = TestTemplate(TestString, TestOK)
265    Obj = Parser.GetUserExtensionSectionObject()
266    Items = Obj.GetAllUserExtensions()
267    assert len(Items) == 1
268    assert Items[0].UserString == 'Some Strings...'
269    assert len(Items[0].ArchAndModuleType) == 1
270    assert ['MyID', '"TestString"', 'IA32'] in Items[0].ArchAndModuleType
271
272if __name__ == '__main__':
273    import Logger.Logger
274    Logger.Logger.Initialize()
275    unittest.FunctionTestCase(TestToolFuncs).runTest()
276    unittest.FunctionTestCase(TestDecDefine).runTest()
277    unittest.FunctionTestCase(TestDecInclude).runTest()
278    unittest.FunctionTestCase(TestDecGuidPpiProtocol).runTest()
279    unittest.FunctionTestCase(TestDecPcd).runTest()
280    unittest.FunctionTestCase(TestDecUserExtension).runTest()
281
282    print 'All tests passed...'
283
284
285