## @file | |
# This file contain unit test for DecParser | |
# | |
# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR> | |
# | |
# This program and the accompanying materials are licensed and made available | |
# under the terms and conditions of the BSD License which accompanies this | |
# distribution. The full text of the license may be found at | |
# http://opensource.org/licenses/bsd-license.php | |
# | |
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
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 MARCRO1 = test1') | |
self.failIf('MARCRO1' not in self.dec._LocalMacro) | |
self.assertEqual(self.dec._LocalMacro['MARCRO1'], '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() | |