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 16from Logger.Log import FatalError 17 18from Parser.DecParser import \ 19 Dec, \ 20 _DecDefine, \ 21 _DecLibraryclass, \ 22 _DecPcd, \ 23 _DecGuid, \ 24 FileContent, \ 25 _DecBase, \ 26 CleanString 27 28from Object.Parser.DecObject import _DecComments 29 30# 31# Test CleanString 32# 33class CleanStringTestCase(unittest.TestCase): 34 def testCleanString(self): 35 Line, Comment = CleanString('') 36 self.assertEqual(Line, '') 37 self.assertEqual(Comment, '') 38 39 Line, Comment = CleanString('line without comment') 40 self.assertEqual(Line, 'line without comment') 41 self.assertEqual(Comment, '') 42 43 Line, Comment = CleanString('# pure comment') 44 self.assertEqual(Line, '') 45 self.assertEqual(Comment, '# pure comment') 46 47 Line, Comment = CleanString('line # and comment') 48 self.assertEqual(Line, 'line') 49 self.assertEqual(Comment, '# and comment') 50 51 def testCleanStringCpp(self): 52 Line, Comment = CleanString('line // and comment', AllowCppStyleComment = True) 53 self.assertEqual(Line, 'line') 54 self.assertEqual(Comment, '# and comment') 55 56# 57# Test _DecBase._MacroParser function 58# 59class MacroParserTestCase(unittest.TestCase): 60 def setUp(self): 61 self.dec = _DecBase(FileContent('dummy', [])) 62 63 def testCorrectMacro(self): 64 self.dec._MacroParser('DEFINE MARCRO1 = test1') 65 self.failIf('MARCRO1' not in self.dec._LocalMacro) 66 self.assertEqual(self.dec._LocalMacro['MARCRO1'], 'test1') 67 68 def testErrorMacro1(self): 69 # Raise fatal error, macro name must be upper case letter 70 self.assertRaises(FatalError, self.dec._MacroParser, 'DEFINE not_upper_case = test2') 71 72 def testErrorMacro2(self): 73 # No macro name given 74 self.assertRaises(FatalError, self.dec._MacroParser, 'DEFINE ') 75 76# 77# Test _DecBase._TryBackSlash function 78# 79class TryBackSlashTestCase(unittest.TestCase): 80 def setUp(self): 81 Content = [ 82 # Right case 83 'test no backslash', 84 85 'test with backslash \\', 86 'continue second line', 87 88 # Do not precede with whitespace 89 '\\', 90 91 # Empty line after backlash is not allowed 92 'line with backslash \\', 93 '' 94 ] 95 self.dec = _DecBase(FileContent('dummy', Content)) 96 97 def testBackSlash(self): 98 # 99 # Right case, assert return values 100 # 101 ConcatLine, CommentList = self.dec._TryBackSlash(self.dec._RawData.GetNextLine(), []) 102 self.assertEqual(ConcatLine, 'test no backslash') 103 self.assertEqual(CommentList, []) 104 105 ConcatLine, CommentList = self.dec._TryBackSlash(self.dec._RawData.GetNextLine(), []) 106 self.assertEqual(CommentList, []) 107 self.assertEqual(ConcatLine, 'test with backslash continue second line') 108 109 # 110 # Error cases, assert raise exception 111 # 112 self.assertRaises(FatalError, self.dec._TryBackSlash, self.dec._RawData.GetNextLine(), []) 113 self.assertRaises(FatalError, self.dec._TryBackSlash, self.dec._RawData.GetNextLine(), []) 114 115# 116# Test _DecBase.Parse function 117# 118class DataItem(_DecComments): 119 def __init__(self): 120 _DecComments.__init__(self) 121 self.String = '' 122 123class Data(_DecComments): 124 def __init__(self): 125 _DecComments.__init__(self) 126 # List of DataItem 127 self.ItemList = [] 128 129class TestInner(_DecBase): 130 def __init__(self, RawData): 131 _DecBase.__init__(self, RawData) 132 self.ItemObject = Data() 133 134 def _StopCurrentParsing(self, Line): 135 return Line == '[TOP]' 136 137 def _ParseItem(self): 138 Item = DataItem() 139 Item.String = self._RawData.CurrentLine 140 self.ItemObject.ItemList.append(Item) 141 return Item 142 143 def _TailCommentStrategy(self, Comment): 144 return Comment.find('@comment') != -1 145 146class TestTop(_DecBase): 147 def __init__(self, RawData): 148 _DecBase.__init__(self, RawData) 149 # List of Data 150 self.ItemObject = [] 151 152 # Top parser 153 def _StopCurrentParsing(self, Line): 154 return False 155 156 def _ParseItem(self): 157 TestParser = TestInner(self._RawData) 158 TestParser.Parse() 159 self.ItemObject.append(TestParser.ItemObject) 160 return TestParser.ItemObject 161 162class ParseTestCase(unittest.TestCase): 163 def setUp(self): 164 pass 165 166 def testParse(self): 167 Content = \ 168 '''# Top comment 169 [TOP] 170 # sub1 head comment 171 (test item has both head and tail comment) # sub1 tail comment 172 # sub2 head comment 173 (test item has head and special tail comment) 174 # @comment test TailCommentStrategy branch 175 176 (test item has no comment) 177 178 # test NextLine branch 179 [TOP] 180 sub-item 181 ''' 182 dec = TestTop(FileContent('dummy', Content.splitlines())) 183 dec.Parse() 184 185 # Two sections 186 self.assertEqual(len(dec.ItemObject), 2) 187 188 data = dec.ItemObject[0] 189 self.assertEqual(data._HeadComment[0][0], '# Top comment') 190 self.assertEqual(data._HeadComment[0][1], 1) 191 192 # 3 subitems 193 self.assertEqual(len(data.ItemList), 3) 194 195 dataitem = data.ItemList[0] 196 self.assertEqual(dataitem.String, '(test item has both head and tail comment)') 197 # Comment content 198 self.assertEqual(dataitem._HeadComment[0][0], '# sub1 head comment') 199 self.assertEqual(dataitem._TailComment[0][0], '# sub1 tail comment') 200 # Comment line number 201 self.assertEqual(dataitem._HeadComment[0][1], 3) 202 self.assertEqual(dataitem._TailComment[0][1], 4) 203 204 dataitem = data.ItemList[1] 205 self.assertEqual(dataitem.String, '(test item has head and special tail comment)') 206 # Comment content 207 self.assertEqual(dataitem._HeadComment[0][0], '# sub2 head comment') 208 self.assertEqual(dataitem._TailComment[0][0], '# @comment test TailCommentStrategy branch') 209 # Comment line number 210 self.assertEqual(dataitem._HeadComment[0][1], 5) 211 self.assertEqual(dataitem._TailComment[0][1], 7) 212 213 dataitem = data.ItemList[2] 214 self.assertEqual(dataitem.String, '(test item has no comment)') 215 # Comment content 216 self.assertEqual(dataitem._HeadComment, []) 217 self.assertEqual(dataitem._TailComment, []) 218 219 data = dec.ItemObject[1] 220 self.assertEqual(data._HeadComment[0][0], '# test NextLine branch') 221 self.assertEqual(data._HeadComment[0][1], 11) 222 223 # 1 subitems 224 self.assertEqual(len(data.ItemList), 1) 225 226 dataitem = data.ItemList[0] 227 self.assertEqual(dataitem.String, 'sub-item') 228 self.assertEqual(dataitem._HeadComment, []) 229 self.assertEqual(dataitem._TailComment, []) 230 231# 232# Test _DecDefine._ParseItem 233# 234class DecDefineTestCase(unittest.TestCase): 235 def GetObj(self, Content): 236 Obj = _DecDefine(FileContent('dummy', Content.splitlines())) 237 Obj._RawData.CurrentLine = Obj._RawData.GetNextLine() 238 return Obj 239 240 def testDecDefine(self): 241 item = self.GetObj('PACKAGE_NAME = MdePkg')._ParseItem() 242 self.assertEqual(item.Key, 'PACKAGE_NAME') 243 self.assertEqual(item.Value, 'MdePkg') 244 245 def testDecDefine1(self): 246 obj = self.GetObj('PACKAGE_NAME') 247 self.assertRaises(FatalError, obj._ParseItem) 248 249 def testDecDefine2(self): 250 obj = self.GetObj('unknown_key = ') 251 self.assertRaises(FatalError, obj._ParseItem) 252 253 def testDecDefine3(self): 254 obj = self.GetObj('PACKAGE_NAME = ') 255 self.assertRaises(FatalError, obj._ParseItem) 256 257# 258# Test _DecLibraryclass._ParseItem 259# 260class DecLibraryTestCase(unittest.TestCase): 261 def GetObj(self, Content): 262 Obj = _DecLibraryclass(FileContent('dummy', Content.splitlines())) 263 Obj._RawData.CurrentLine = Obj._RawData.GetNextLine() 264 return Obj 265 266 def testNoInc(self): 267 obj = self.GetObj('UefiRuntimeLib') 268 self.assertRaises(FatalError, obj._ParseItem) 269 270 def testEmpty(self): 271 obj = self.GetObj(' | ') 272 self.assertRaises(FatalError, obj._ParseItem) 273 274 def testLibclassNaming(self): 275 obj = self.GetObj('lowercase_efiRuntimeLib|Include/Library/UefiRuntimeLib.h') 276 self.assertRaises(FatalError, obj._ParseItem) 277 278 def testLibclassExt(self): 279 obj = self.GetObj('RuntimeLib|Include/Library/UefiRuntimeLib.no_h') 280 self.assertRaises(FatalError, obj._ParseItem) 281 282 def testLibclassRelative(self): 283 obj = self.GetObj('RuntimeLib|Include/../UefiRuntimeLib.h') 284 self.assertRaises(FatalError, obj._ParseItem) 285 286# 287# Test _DecPcd._ParseItem 288# 289class DecPcdTestCase(unittest.TestCase): 290 def GetObj(self, Content): 291 Obj = _DecPcd(FileContent('dummy', Content.splitlines())) 292 Obj._RawData.CurrentLine = Obj._RawData.GetNextLine() 293 Obj._RawData.CurrentScope = [('PcdsFeatureFlag'.upper(), 'COMMON')] 294 return Obj 295 296 def testOK(self): 297 item = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE|BOOLEAN|0x0000000d')._ParseItem() 298 self.assertEqual(item.TokenSpaceGuidCName, 'gEfiMdePkgTokenSpaceGuid') 299 self.assertEqual(item.TokenCName, 'PcdComponentNameDisable') 300 self.assertEqual(item.DefaultValue, 'FALSE') 301 self.assertEqual(item.DatumType, 'BOOLEAN') 302 self.assertEqual(item.TokenValue, '0x0000000d') 303 304 def testNoCvar(self): 305 obj = self.GetObj('123ai.PcdComponentNameDisable|FALSE|BOOLEAN|0x0000000d') 306 self.assertRaises(FatalError, obj._ParseItem) 307 308 def testSplit(self): 309 obj = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable FALSE|BOOLEAN|0x0000000d') 310 self.assertRaises(FatalError, obj._ParseItem) 311 312 obj = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE|BOOLEAN|0x0000000d | abc') 313 self.assertRaises(FatalError, obj._ParseItem) 314 315 def testUnknownType(self): 316 obj = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE|unknown|0x0000000d') 317 self.assertRaises(FatalError, obj._ParseItem) 318 319 def testVoid(self): 320 obj = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|abc|VOID*|0x0000000d') 321 self.assertRaises(FatalError, obj._ParseItem) 322 323 def testUINT(self): 324 obj = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|0xabc|UINT8|0x0000000d') 325 self.assertRaises(FatalError, obj._ParseItem) 326 327# 328# Test _DecInclude._ParseItem 329# 330class DecIncludeTestCase(unittest.TestCase): 331 # 332 # Test code to be added 333 # 334 pass 335 336# 337# Test _DecGuid._ParseItem 338# 339class DecGuidTestCase(unittest.TestCase): 340 def GetObj(self, Content): 341 Obj = _DecGuid(FileContent('dummy', Content.splitlines())) 342 Obj._RawData.CurrentLine = Obj._RawData.GetNextLine() 343 Obj._RawData.CurrentScope = [('guids'.upper(), 'COMMON')] 344 return Obj 345 346 def testCValue(self): 347 item = self.GetObj('gEfiIpSecProtocolGuid={ 0xdfb386f7, 0xe100, 0x43ad,' 348 ' {0x9c, 0x9a, 0xed, 0x90, 0xd0, 0x8a, 0x5e, 0x12 }}')._ParseItem() 349 self.assertEqual(item.GuidCName, 'gEfiIpSecProtocolGuid') 350 self.assertEqual(item.GuidCValue, '{ 0xdfb386f7, 0xe100, 0x43ad, {0x9c, 0x9a, 0xed, 0x90, 0xd0, 0x8a, 0x5e, 0x12 }}') 351 352 def testGuidString(self): 353 item = self.GetObj('gEfiIpSecProtocolGuid=1E73767F-8F52-4603-AEB4-F29B510B6766')._ParseItem() 354 self.assertEqual(item.GuidCName, 'gEfiIpSecProtocolGuid') 355 self.assertEqual(item.GuidCValue, '1E73767F-8F52-4603-AEB4-F29B510B6766') 356 357 def testNoValue1(self): 358 obj = self.GetObj('gEfiIpSecProtocolGuid') 359 self.assertRaises(FatalError, obj._ParseItem) 360 361 def testNoValue2(self): 362 obj = self.GetObj('gEfiIpSecProtocolGuid=') 363 self.assertRaises(FatalError, obj._ParseItem) 364 365 def testNoName(self): 366 obj = self.GetObj('=') 367 self.assertRaises(FatalError, obj._ParseItem) 368 369# 370# Test Dec.__init__ 371# 372class DecDecInitTestCase(unittest.TestCase): 373 def testNoDecFile(self): 374 self.assertRaises(FatalError, Dec, 'No_Such_File') 375 376class TmpFile: 377 def __init__(self, File): 378 self.File = File 379 380 def Write(self, Content): 381 try: 382 FileObj = open(self.File, 'w') 383 FileObj.write(Content) 384 FileObj.close() 385 except: 386 pass 387 388 def Remove(self): 389 try: 390 os.remove(self.File) 391 except: 392 pass 393 394# 395# Test Dec._UserExtentionSectionParser 396# 397class DecUESectionTestCase(unittest.TestCase): 398 def setUp(self): 399 self.File = TmpFile('test.dec') 400 self.File.Write( 401'''[userextensions.intel."myid"] 402[userextensions.intel."myid".IA32] 403[userextensions.intel."myid".IA32,] 404[userextensions.intel."myid] 405''' 406 ) 407 408 def tearDown(self): 409 self.File.Remove() 410 411 def testUserExtentionHeader(self): 412 dec = Dec('test.dec', False) 413 414 # OK: [userextensions.intel."myid"] 415 dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] 416 dec._UserExtentionSectionParser() 417 self.assertEqual(len(dec._RawData.CurrentScope), 1) 418 self.assertEqual(dec._RawData.CurrentScope[0][0], 'userextensions'.upper()) 419 self.assertEqual(dec._RawData.CurrentScope[0][1], 'intel') 420 self.assertEqual(dec._RawData.CurrentScope[0][2], '"myid"') 421 self.assertEqual(dec._RawData.CurrentScope[0][3], 'COMMON') 422 423 # OK: [userextensions.intel."myid".IA32] 424 dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] 425 dec._UserExtentionSectionParser() 426 self.assertEqual(len(dec._RawData.CurrentScope), 1) 427 self.assertEqual(dec._RawData.CurrentScope[0][0], 'userextensions'.upper()) 428 self.assertEqual(dec._RawData.CurrentScope[0][1], 'intel') 429 self.assertEqual(dec._RawData.CurrentScope[0][2], '"myid"') 430 self.assertEqual(dec._RawData.CurrentScope[0][3], 'IA32') 431 432 # Fail: [userextensions.intel."myid".IA32,] 433 dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] 434 self.assertRaises(FatalError, dec._UserExtentionSectionParser) 435 436 # Fail: [userextensions.intel."myid] 437 dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] 438 self.assertRaises(FatalError, dec._UserExtentionSectionParser) 439 440# 441# Test Dec._SectionHeaderParser 442# 443class DecSectionTestCase(unittest.TestCase): 444 def setUp(self): 445 self.File = TmpFile('test.dec') 446 self.File.Write( 447'''[no section start or end 448[,] # empty sub-section 449[unknow_section_name] 450[Includes.IA32.other] # no third one 451[PcdsFeatureFlag, PcdsFixedAtBuild] # feature flag PCD must not be in the same section of other types of PCD 452[Includes.IA32, Includes.IA32] 453[Includes, Includes.IA32] # common cannot be with other arch 454[Includes.IA32, PcdsFeatureFlag] # different section name 455''' ) 456 457 def tearDown(self): 458 self.File.Remove() 459 460 def testSectionHeader(self): 461 dec = Dec('test.dec', False) 462 # [no section start or end 463 dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] 464 self.assertRaises(FatalError, dec._SectionHeaderParser) 465 466 #[,] # empty sub-section 467 dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] 468 self.assertRaises(FatalError, dec._SectionHeaderParser) 469 470 # [unknow_section_name] 471 dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] 472 self.assertRaises(FatalError, dec._SectionHeaderParser) 473 474 # [Includes.IA32.other] # no third one 475 dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] 476 self.assertRaises(FatalError, dec._SectionHeaderParser) 477 478 # [PcdsFeatureFlag, PcdsFixedAtBuild] 479 dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] 480 self.assertRaises(FatalError, dec._SectionHeaderParser) 481 482 # [Includes.IA32, Includes.IA32] 483 dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] 484 dec._SectionHeaderParser() 485 self.assertEqual(len(dec._RawData.CurrentScope), 1) 486 self.assertEqual(dec._RawData.CurrentScope[0][0], 'Includes'.upper()) 487 self.assertEqual(dec._RawData.CurrentScope[0][1], 'IA32') 488 489 # [Includes, Includes.IA32] # common cannot be with other arch 490 dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] 491 self.assertRaises(FatalError, dec._SectionHeaderParser) 492 493 # [Includes.IA32, PcdsFeatureFlag] # different section name not allowed 494 dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0] 495 self.assertRaises(FatalError, dec._SectionHeaderParser) 496 497# 498# Test Dec._ParseDecComment 499# 500class DecDecCommentTestCase(unittest.TestCase): 501 def testDecHeadComment(self): 502 File = TmpFile('test.dec') 503 File.Write( 504 '''# abc 505 ##''') 506 dec = Dec('test.dec', False) 507 dec.ParseDecComment() 508 self.assertEqual(len(dec._HeadComment), 2) 509 self.assertEqual(dec._HeadComment[0][0], '# abc') 510 self.assertEqual(dec._HeadComment[0][1], 1) 511 self.assertEqual(dec._HeadComment[1][0], '##') 512 self.assertEqual(dec._HeadComment[1][1], 2) 513 File.Remove() 514 515 def testNoDoubleComment(self): 516 File = TmpFile('test.dec') 517 File.Write( 518 '''# abc 519 # 520 [section_start]''') 521 dec = Dec('test.dec', False) 522 dec.ParseDecComment() 523 self.assertEqual(len(dec._HeadComment), 2) 524 self.assertEqual(dec._HeadComment[0][0], '# abc') 525 self.assertEqual(dec._HeadComment[0][1], 1) 526 self.assertEqual(dec._HeadComment[1][0], '#') 527 self.assertEqual(dec._HeadComment[1][1], 2) 528 File.Remove() 529 530if __name__ == '__main__': 531 import Logger.Logger 532 Logger.Logger.Initialize() 533 unittest.main() 534 535