CloverBootloader/BaseTools/Source/Python/UPT/UnitTest/DecParserUnitTest.py

529 lines
18 KiB
Python
Raw Normal View History

## @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()