## @file # This file contain unit test for DecParser # # Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
# # 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()