| ## @file | |
| # This file contain unit test for DecParser | |
| # | |
| # Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR> | |
| # | |
| # SPDX-License-Identifier: BSD-2-Clause-Patent | |
| import os | |
| import unittest | |
| from Logger.Log import FatalError | |
| from Parser.DecParser import \ | |
| Dec, \ | |
| _DecDefine, \ | |
| _DecLibraryclass, \ | |
| _DecPcd, \ | |
| _DecGuid, \ | |
| FileContent, \ | |
| _DecBase, \ | |
| CleanString | |
| from Object.Parser.DecObject import _DecComments | |
| # | |
| # Test CleanString | |
| # | |
| class CleanStringTestCase(unittest.TestCase): | |
| def testCleanString(self): | |
| Line, Comment = CleanString('') | |
| self.assertEqual(Line, '') | |
| self.assertEqual(Comment, '') | |
| Line, Comment = CleanString('line without comment') | |
| self.assertEqual(Line, 'line without comment') | |
| self.assertEqual(Comment, '') | |
| Line, Comment = CleanString('# pure comment') | |
| self.assertEqual(Line, '') | |
| self.assertEqual(Comment, '# pure comment') | |
| Line, Comment = CleanString('line # and comment') | |
| self.assertEqual(Line, 'line') | |
| self.assertEqual(Comment, '# and comment') | |
| def testCleanStringCpp(self): | |
| Line, Comment = CleanString('line // and comment', AllowCppStyleComment = True) | |
| self.assertEqual(Line, 'line') | |
| self.assertEqual(Comment, '# and comment') | |
| # | |
| # Test _DecBase._MacroParser function | |
| # | |
| class MacroParserTestCase(unittest.TestCase): | |
| def setUp(self): | |
| self.dec = _DecBase(FileContent('dummy', [])) | |
| def testCorrectMacro(self): | |
| self.dec._MacroParser('DEFINE MACRO1 = test1') | |
| self.failIf('MACRO1' not in self.dec._LocalMacro) | |
| self.assertEqual(self.dec._LocalMacro['MACRO1'], 'test1') | |
| def testErrorMacro1(self): | |
| # Raise fatal error, macro name must be upper case letter | |
| self.assertRaises(FatalError, self.dec._MacroParser, 'DEFINE not_upper_case = test2') | |
| def testErrorMacro2(self): | |
| # No macro name given | |
| self.assertRaises(FatalError, self.dec._MacroParser, 'DEFINE ') | |
| # | |
| # Test _DecBase._TryBackSlash function | |
| # | |
| class TryBackSlashTestCase(unittest.TestCase): | |
| def setUp(self): | |
| Content = [ | |
| # Right case | |
| 'test no backslash', | |
| 'test with backslash \\', | |
| 'continue second line', | |
| # Do not precede with whitespace | |
| '\\', | |
| # Empty line after backlash is not allowed | |
| 'line with backslash \\', | |
| '' | |
| ] | |
| self.dec = _DecBase(FileContent('dummy', Content)) | |
| def testBackSlash(self): | |
| # | |
| # Right case, assert return values | |
| # | |
| ConcatLine, CommentList = self.dec._TryBackSlash(self.dec._RawData.GetNextLine(), []) | |
| self.assertEqual(ConcatLine, 'test no backslash') | |
| self.assertEqual(CommentList, []) | |
| ConcatLine, CommentList = self.dec._TryBackSlash(self.dec._RawData.GetNextLine(), []) | |
| self.assertEqual(CommentList, []) | |
| self.assertEqual(ConcatLine, 'test with backslash continue second line') | |
| # | |
| # Error cases, assert raise exception | |
| # | |
| self.assertRaises(FatalError, self.dec._TryBackSlash, self.dec._RawData.GetNextLine(), []) | |
| self.assertRaises(FatalError, self.dec._TryBackSlash, self.dec._RawData.GetNextLine(), []) | |
| # | |
| # Test _DecBase.Parse function | |
| # | |
| class DataItem(_DecComments): | |
| def __init__(self): | |
| _DecComments.__init__(self) | |
| self.String = '' | |
| class Data(_DecComments): | |
| def __init__(self): | |
| _DecComments.__init__(self) | |
| # List of DataItem | |
| self.ItemList = [] | |
| class TestInner(_DecBase): | |
| def __init__(self, RawData): | |
| _DecBase.__init__(self, RawData) | |
| self.ItemObject = Data() | |
| def _StopCurrentParsing(self, Line): | |
| return Line == '[TOP]' | |
| def _ParseItem(self): | |
| Item = DataItem() | |
| Item.String = self._RawData.CurrentLine | |
| self.ItemObject.ItemList.append(Item) | |
| return Item | |
| def _TailCommentStrategy(self, Comment): | |
| return Comment.find('@comment') != -1 | |
| class TestTop(_DecBase): | |
| def __init__(self, RawData): | |
| _DecBase.__init__(self, RawData) | |
| # List of Data | |
| self.ItemObject = [] | |
| # Top parser | |
| def _StopCurrentParsing(self, Line): | |
| return False | |
| def _ParseItem(self): | |
| TestParser = TestInner(self._RawData) | |
| TestParser.Parse() | |
| self.ItemObject.append(TestParser.ItemObject) | |
| return TestParser.ItemObject | |
| class ParseTestCase(unittest.TestCase): | |
| def setUp(self): | |
| pass | |
| def testParse(self): | |
| Content = \ | |
| '''# Top comment | |
| [TOP] | |
| # sub1 head comment | |
| (test item has both head and tail comment) # sub1 tail comment | |
| # sub2 head comment | |
| (test item has head and special tail comment) | |
| # @comment test TailCommentStrategy branch | |
| (test item has no comment) | |
| # test NextLine branch | |
| [TOP] | |
| sub-item | |
| ''' | |
| dec = TestTop(FileContent('dummy', Content.splitlines())) | |
| dec.Parse() | |
| # Two sections | |
| self.assertEqual(len(dec.ItemObject), 2) | |
| data = dec.ItemObject[0] | |
| self.assertEqual(data._HeadComment[0][0], '# Top comment') | |
| self.assertEqual(data._HeadComment[0][1], 1) | |
| # 3 subitems | |
| self.assertEqual(len(data.ItemList), 3) | |
| dataitem = data.ItemList[0] | |
| self.assertEqual(dataitem.String, '(test item has both head and tail comment)') | |
| # Comment content | |
| self.assertEqual(dataitem._HeadComment[0][0], '# sub1 head comment') | |
| self.assertEqual(dataitem._TailComment[0][0], '# sub1 tail comment') | |
| # Comment line number | |
| self.assertEqual(dataitem._HeadComment[0][1], 3) | |
| self.assertEqual(dataitem._TailComment[0][1], 4) | |
| dataitem = data.ItemList[1] | |
| self.assertEqual(dataitem.String, '(test item has head and special tail comment)') | |
| # Comment content | |
| self.assertEqual(dataitem._HeadComment[0][0], '# sub2 head comment') | |
| self.assertEqual(dataitem._TailComment[0][0], '# @comment test TailCommentStrategy branch') | |
| # Comment line number | |
| self.assertEqual(dataitem._HeadComment[0][1], 5) | |
| self.assertEqual(dataitem._TailComment[0][1], 7) | |
| dataitem = data.ItemList[2] | |
| self.assertEqual(dataitem.String, '(test item has no comment)') | |
| # Comment content | |
| self.assertEqual(dataitem._HeadComment, []) | |
| self.assertEqual(dataitem._TailComment, []) | |
| data = dec.ItemObject[1] | |
| self.assertEqual(data._HeadComment[0][0], '# test NextLine branch') | |
| self.assertEqual(data._HeadComment[0][1], 11) | |
| # 1 subitems | |
| self.assertEqual(len(data.ItemList), 1) | |
| dataitem = data.ItemList[0] | |
| self.assertEqual(dataitem.String, 'sub-item') | |
| self.assertEqual(dataitem._HeadComment, []) | |
| self.assertEqual(dataitem._TailComment, []) | |
| # | |
| # Test _DecDefine._ParseItem | |
| # | |
| class DecDefineTestCase(unittest.TestCase): | |
| def GetObj(self, Content): | |
| Obj = _DecDefine(FileContent('dummy', Content.splitlines())) | |
| Obj._RawData.CurrentLine = Obj._RawData.GetNextLine() | |
| return Obj | |
| def testDecDefine(self): | |
| item = self.GetObj('PACKAGE_NAME = MdePkg')._ParseItem() | |
| self.assertEqual(item.Key, 'PACKAGE_NAME') | |
| self.assertEqual(item.Value, 'MdePkg') | |
| def testDecDefine1(self): | |
| obj = self.GetObj('PACKAGE_NAME') | |
| self.assertRaises(FatalError, obj._ParseItem) | |
| def testDecDefine2(self): | |
| obj = self.GetObj('unknown_key = ') | |
| self.assertRaises(FatalError, obj._ParseItem) | |
| def testDecDefine3(self): | |
| obj = self.GetObj('PACKAGE_NAME = ') | |
| self.assertRaises(FatalError, obj._ParseItem) | |
| # | |
| # Test _DecLibraryclass._ParseItem | |
| # | |
| class DecLibraryTestCase(unittest.TestCase): | |
| def GetObj(self, Content): | |
| Obj = _DecLibraryclass(FileContent('dummy', Content.splitlines())) | |
| Obj._RawData.CurrentLine = Obj._RawData.GetNextLine() | |
| return Obj | |
| def testNoInc(self): | |
| obj = self.GetObj('UefiRuntimeLib') | |
| self.assertRaises(FatalError, obj._ParseItem) | |
| def testEmpty(self): | |
| obj = self.GetObj(' | ') | |
| self.assertRaises(FatalError, obj._ParseItem) | |
| def testLibclassNaming(self): | |
| obj = self.GetObj('lowercase_efiRuntimeLib|Include/Library/UefiRuntimeLib.h') | |
| self.assertRaises(FatalError, obj._ParseItem) | |
| def testLibclassExt(self): | |
| obj = self.GetObj('RuntimeLib|Include/Library/UefiRuntimeLib.no_h') | |
| self.assertRaises(FatalError, obj._ParseItem) | |
| def testLibclassRelative(self): | |
| obj = self.GetObj('RuntimeLib|Include/../UefiRuntimeLib.h') | |
| self.assertRaises(FatalError, obj._ParseItem) | |
| # | |
| # Test _DecPcd._ParseItem | |
| # | |
| class DecPcdTestCase(unittest.TestCase): | |
| def GetObj(self, Content): | |
| Obj = _DecPcd(FileContent('dummy', Content.splitlines())) | |
| Obj._RawData.CurrentLine = Obj._RawData.GetNextLine() | |
| Obj._RawData.CurrentScope = [('PcdsFeatureFlag'.upper(), 'COMMON')] | |
| return Obj | |
| def testOK(self): | |
| item = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE|BOOLEAN|0x0000000d')._ParseItem() | |
| self.assertEqual(item.TokenSpaceGuidCName, 'gEfiMdePkgTokenSpaceGuid') | |
| self.assertEqual(item.TokenCName, 'PcdComponentNameDisable') | |
| self.assertEqual(item.DefaultValue, 'FALSE') | |
| self.assertEqual(item.DatumType, 'BOOLEAN') | |
| self.assertEqual(item.TokenValue, '0x0000000d') | |
| def testNoCvar(self): | |
| obj = self.GetObj('123ai.PcdComponentNameDisable|FALSE|BOOLEAN|0x0000000d') | |
| self.assertRaises(FatalError, obj._ParseItem) | |
| def testSplit(self): | |
| obj = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable FALSE|BOOLEAN|0x0000000d') | |
| self.assertRaises(FatalError, obj._ParseItem) | |
| obj = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE|BOOLEAN|0x0000000d | abc') | |
| self.assertRaises(FatalError, obj._ParseItem) | |
| def testUnknownType(self): | |
| obj = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE|unknown|0x0000000d') | |
| self.assertRaises(FatalError, obj._ParseItem) | |
| def testVoid(self): | |
| obj = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|abc|VOID*|0x0000000d') | |
| self.assertRaises(FatalError, obj._ParseItem) | |
| def testUINT(self): | |
| obj = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|0xabc|UINT8|0x0000000d') | |
| self.assertRaises(FatalError, obj._ParseItem) | |
| # | |
| # Test _DecInclude._ParseItem | |
| # | |
| class DecIncludeTestCase(unittest.TestCase): | |
| # | |
| # Test code to be added | |
| # | |
| pass | |
| # | |
| # Test _DecGuid._ParseItem | |
| # | |
| class DecGuidTestCase(unittest.TestCase): | |
| def GetObj(self, Content): | |
| Obj = _DecGuid(FileContent('dummy', Content.splitlines())) | |
| Obj._RawData.CurrentLine = Obj._RawData.GetNextLine() | |
| Obj._RawData.CurrentScope = [('guids'.upper(), 'COMMON')] | |
| return Obj | |
| def testCValue(self): | |
| item = self.GetObj('gEfiIpSecProtocolGuid={ 0xdfb386f7, 0xe100, 0x43ad,' | |
| ' {0x9c, 0x9a, 0xed, 0x90, 0xd0, 0x8a, 0x5e, 0x12 }}')._ParseItem() | |
| self.assertEqual(item.GuidCName, 'gEfiIpSecProtocolGuid') | |
| self.assertEqual(item.GuidCValue, '{ 0xdfb386f7, 0xe100, 0x43ad, {0x9c, 0x9a, 0xed, 0x90, 0xd0, 0x8a, 0x5e, 0x12 }}') | |
| def testGuidString(self): | |
| item = self.GetObj('gEfiIpSecProtocolGuid=1E73767F-8F52-4603-AEB4-F29B510B6766')._ParseItem() | |
| self.assertEqual(item.GuidCName, 'gEfiIpSecProtocolGuid') | |
| self.assertEqual(item.GuidCValue, '1E73767F-8F52-4603-AEB4-F29B510B6766') | |
| def testNoValue1(self): | |
| obj = self.GetObj('gEfiIpSecProtocolGuid') | |
| self.assertRaises(FatalError, obj._ParseItem) | |
| def testNoValue2(self): | |
| obj = self.GetObj('gEfiIpSecProtocolGuid=') | |
| self.assertRaises(FatalError, obj._ParseItem) | |
| def testNoName(self): | |
| obj = self.GetObj('=') | |
| self.assertRaises(FatalError, obj._ParseItem) | |
| # | |
| # Test Dec.__init__ | |
| # | |
| class DecDecInitTestCase(unittest.TestCase): | |
| def testNoDecFile(self): | |
| self.assertRaises(FatalError, Dec, 'No_Such_File') | |
| class TmpFile: | |
| def __init__(self, File): | |
| self.File = File | |
| def Write(self, Content): | |
| try: | |
| FileObj = open(self.File, 'w') | |
| FileObj.write(Content) | |
| FileObj.close() | |
| except: | |
| pass | |
| def Remove(self): | |
| try: | |
| os.remove(self.File) | |
| except: | |
| pass | |
| # | |
| # Test Dec._UserExtentionSectionParser | |
| # | |
| class DecUESectionTestCase(unittest.TestCase): | |
| def setUp(self): | |
| self.File = TmpFile('test.dec') | |
| self.File.Write( | |
| '''[userextensions.intel."myid"] | |
| [userextensions.intel."myid".IA32] | |
| [userextensions.intel."myid".IA32,] | |
| [userextensions.intel."myid] | |
| ''' | |
| ) | |
| def tearDown(self): | |
| self.File.Remove() | |
| def testUserExtentionHeader(self): | |
| dec = Dec('test.dec', False) | |
| # OK: [userextensions.intel."myid"] | |
| dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] | |
| dec._UserExtentionSectionParser() | |
| self.assertEqual(len(dec._RawData.CurrentScope), 1) | |
| self.assertEqual(dec._RawData.CurrentScope[0][0], 'userextensions'.upper()) | |
| self.assertEqual(dec._RawData.CurrentScope[0][1], 'intel') | |
| self.assertEqual(dec._RawData.CurrentScope[0][2], '"myid"') | |
| self.assertEqual(dec._RawData.CurrentScope[0][3], 'COMMON') | |
| # OK: [userextensions.intel."myid".IA32] | |
| dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] | |
| dec._UserExtentionSectionParser() | |
| self.assertEqual(len(dec._RawData.CurrentScope), 1) | |
| self.assertEqual(dec._RawData.CurrentScope[0][0], 'userextensions'.upper()) | |
| self.assertEqual(dec._RawData.CurrentScope[0][1], 'intel') | |
| self.assertEqual(dec._RawData.CurrentScope[0][2], '"myid"') | |
| self.assertEqual(dec._RawData.CurrentScope[0][3], 'IA32') | |
| # Fail: [userextensions.intel."myid".IA32,] | |
| dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] | |
| self.assertRaises(FatalError, dec._UserExtentionSectionParser) | |
| # Fail: [userextensions.intel."myid] | |
| dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] | |
| self.assertRaises(FatalError, dec._UserExtentionSectionParser) | |
| # | |
| # Test Dec._SectionHeaderParser | |
| # | |
| class DecSectionTestCase(unittest.TestCase): | |
| def setUp(self): | |
| self.File = TmpFile('test.dec') | |
| self.File.Write( | |
| '''[no section start or end | |
| [,] # empty sub-section | |
| [unknow_section_name] | |
| [Includes.IA32.other] # no third one | |
| [PcdsFeatureFlag, PcdsFixedAtBuild] # feature flag PCD must not be in the same section of other types of PCD | |
| [Includes.IA32, Includes.IA32] | |
| [Includes, Includes.IA32] # common cannot be with other arch | |
| [Includes.IA32, PcdsFeatureFlag] # different section name | |
| ''' ) | |
| def tearDown(self): | |
| self.File.Remove() | |
| def testSectionHeader(self): | |
| dec = Dec('test.dec', False) | |
| # [no section start or end | |
| dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] | |
| self.assertRaises(FatalError, dec._SectionHeaderParser) | |
| #[,] # empty sub-section | |
| dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] | |
| self.assertRaises(FatalError, dec._SectionHeaderParser) | |
| # [unknow_section_name] | |
| dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] | |
| self.assertRaises(FatalError, dec._SectionHeaderParser) | |
| # [Includes.IA32.other] # no third one | |
| dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] | |
| self.assertRaises(FatalError, dec._SectionHeaderParser) | |
| # [PcdsFeatureFlag, PcdsFixedAtBuild] | |
| dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] | |
| self.assertRaises(FatalError, dec._SectionHeaderParser) | |
| # [Includes.IA32, Includes.IA32] | |
| dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] | |
| dec._SectionHeaderParser() | |
| self.assertEqual(len(dec._RawData.CurrentScope), 1) | |
| self.assertEqual(dec._RawData.CurrentScope[0][0], 'Includes'.upper()) | |
| self.assertEqual(dec._RawData.CurrentScope[0][1], 'IA32') | |
| # [Includes, Includes.IA32] # common cannot be with other arch | |
| dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] | |
| self.assertRaises(FatalError, dec._SectionHeaderParser) | |
| # [Includes.IA32, PcdsFeatureFlag] # different section name not allowed | |
| dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] | |
| self.assertRaises(FatalError, dec._SectionHeaderParser) | |
| # | |
| # Test Dec._ParseDecComment | |
| # | |
| class DecDecCommentTestCase(unittest.TestCase): | |
| def testDecHeadComment(self): | |
| File = TmpFile('test.dec') | |
| File.Write( | |
| '''# abc | |
| ##''') | |
| dec = Dec('test.dec', False) | |
| dec.ParseDecComment() | |
| self.assertEqual(len(dec._HeadComment), 2) | |
| self.assertEqual(dec._HeadComment[0][0], '# abc') | |
| self.assertEqual(dec._HeadComment[0][1], 1) | |
| self.assertEqual(dec._HeadComment[1][0], '##') | |
| self.assertEqual(dec._HeadComment[1][1], 2) | |
| File.Remove() | |
| def testNoDoubleComment(self): | |
| File = TmpFile('test.dec') | |
| File.Write( | |
| '''# abc | |
| # | |
| [section_start]''') | |
| dec = Dec('test.dec', False) | |
| dec.ParseDecComment() | |
| self.assertEqual(len(dec._HeadComment), 2) | |
| self.assertEqual(dec._HeadComment[0][0], '# abc') | |
| self.assertEqual(dec._HeadComment[0][1], 1) | |
| self.assertEqual(dec._HeadComment[1][0], '#') | |
| self.assertEqual(dec._HeadComment[1][1], 2) | |
| File.Remove() | |
| if __name__ == '__main__': | |
| import Logger.Logger | |
| Logger.Logger.Initialize() | |
| unittest.main() | |