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