]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/UPT/UnitTest/DecParserUnitTest.py
BaseTools: Clean up source files
[mirror_edk2.git] / BaseTools / Source / Python / UPT / UnitTest / DecParserUnitTest.py
1 ## @file
2 # This file contain unit test for DecParser
3 #
4 # Copyright (c) 2011 - 2018, 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
14 import os
15 import unittest
16 from Logger.Log import FatalError
17
18 from Parser.DecParser import \
19 Dec, \
20 _DecDefine, \
21 _DecLibraryclass, \
22 _DecPcd, \
23 _DecGuid, \
24 FileContent, \
25 _DecBase, \
26 CleanString
27
28 from Object.Parser.DecObject import _DecComments
29
30 #
31 # Test CleanString
32 #
33 class 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 #
59 class 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 #
79 class 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 #
118 class DataItem(_DecComments):
119 def __init__(self):
120 _DecComments.__init__(self)
121 self.String = ''
122
123 class Data(_DecComments):
124 def __init__(self):
125 _DecComments.__init__(self)
126 # List of DataItem
127 self.ItemList = []
128
129 class 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
146 class 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
162 class 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 #
234 class 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 #
260 class 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 #
289 class 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 #
330 class DecIncludeTestCase(unittest.TestCase):
331 #
332 # Test code to be added
333 #
334 pass
335
336 #
337 # Test _DecGuid._ParseItem
338 #
339 class 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 #
372 class DecDecInitTestCase(unittest.TestCase):
373 def testNoDecFile(self):
374 self.assertRaises(FatalError, Dec, 'No_Such_File')
375
376 class 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 #
397 class 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 #
443 class 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 #
500 class 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
530 if __name__ == '__main__':
531 import Logger.Logger
532 Logger.Logger.Initialize()
533 unittest.main()
534