parse.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #
  2. # BitBake Test for lib/bb/parse/
  3. #
  4. # Copyright (C) 2015 Richard Purdie
  5. #
  6. # SPDX-License-Identifier: GPL-2.0-only
  7. #
  8. import unittest
  9. import tempfile
  10. import logging
  11. import bb
  12. import os
  13. logger = logging.getLogger('BitBake.TestParse')
  14. import bb.parse
  15. import bb.data
  16. import bb.siggen
  17. class ParseTest(unittest.TestCase):
  18. testfile = """
  19. A = "1"
  20. B = "2"
  21. do_install() {
  22. echo "hello"
  23. }
  24. C = "3"
  25. """
  26. def setUp(self):
  27. self.origdir = os.getcwd()
  28. self.d = bb.data.init()
  29. bb.parse.siggen = bb.siggen.init(self.d)
  30. def tearDown(self):
  31. os.chdir(self.origdir)
  32. def parsehelper(self, content, suffix = ".bb"):
  33. f = tempfile.NamedTemporaryFile(suffix = suffix)
  34. f.write(bytes(content, "utf-8"))
  35. f.flush()
  36. os.chdir(os.path.dirname(f.name))
  37. return f
  38. def test_parse_simple(self):
  39. f = self.parsehelper(self.testfile)
  40. d = bb.parse.handle(f.name, self.d)['']
  41. self.assertEqual(d.getVar("A"), "1")
  42. self.assertEqual(d.getVar("B"), "2")
  43. self.assertEqual(d.getVar("C"), "3")
  44. def test_parse_incomplete_function(self):
  45. testfileB = self.testfile.replace("}", "")
  46. f = self.parsehelper(testfileB)
  47. with self.assertRaises(bb.parse.ParseError):
  48. d = bb.parse.handle(f.name, self.d)['']
  49. unsettest = """
  50. A = "1"
  51. B = "2"
  52. B[flag] = "3"
  53. unset A
  54. unset B[flag]
  55. """
  56. def test_parse_unset(self):
  57. f = self.parsehelper(self.unsettest)
  58. d = bb.parse.handle(f.name, self.d)['']
  59. self.assertEqual(d.getVar("A"), None)
  60. self.assertEqual(d.getVarFlag("A","flag"), None)
  61. self.assertEqual(d.getVar("B"), "2")
  62. exporttest = """
  63. A = "a"
  64. export B = "b"
  65. export C
  66. exportD = "d"
  67. """
  68. def test_parse_exports(self):
  69. f = self.parsehelper(self.exporttest)
  70. d = bb.parse.handle(f.name, self.d)['']
  71. self.assertEqual(d.getVar("A"), "a")
  72. self.assertIsNone(d.getVarFlag("A", "export"))
  73. self.assertEqual(d.getVar("B"), "b")
  74. self.assertEqual(d.getVarFlag("B", "export"), 1)
  75. self.assertIsNone(d.getVar("C"))
  76. self.assertEqual(d.getVarFlag("C", "export"), 1)
  77. self.assertIsNone(d.getVar("D"))
  78. self.assertIsNone(d.getVarFlag("D", "export"))
  79. self.assertEqual(d.getVar("exportD"), "d")
  80. self.assertIsNone(d.getVarFlag("exportD", "export"))
  81. overridetest = """
  82. RRECOMMENDS_${PN} = "a"
  83. RRECOMMENDS_${PN}_libc = "b"
  84. OVERRIDES = "libc:${PN}"
  85. PN = "gtk+"
  86. """
  87. def test_parse_overrides(self):
  88. f = self.parsehelper(self.overridetest)
  89. d = bb.parse.handle(f.name, self.d)['']
  90. self.assertEqual(d.getVar("RRECOMMENDS"), "b")
  91. bb.data.expandKeys(d)
  92. self.assertEqual(d.getVar("RRECOMMENDS"), "b")
  93. d.setVar("RRECOMMENDS_gtk+", "c")
  94. self.assertEqual(d.getVar("RRECOMMENDS"), "c")
  95. overridetest2 = """
  96. EXTRA_OECONF = ""
  97. EXTRA_OECONF_class-target = "b"
  98. EXTRA_OECONF_append = " c"
  99. """
  100. def test_parse_overrides(self):
  101. f = self.parsehelper(self.overridetest2)
  102. d = bb.parse.handle(f.name, self.d)['']
  103. d.appendVar("EXTRA_OECONF", " d")
  104. d.setVar("OVERRIDES", "class-target")
  105. self.assertEqual(d.getVar("EXTRA_OECONF"), "b c d")
  106. overridetest3 = """
  107. DESCRIPTION = "A"
  108. DESCRIPTION_${PN}-dev = "${DESCRIPTION} B"
  109. PN = "bc"
  110. """
  111. def test_parse_combinations(self):
  112. f = self.parsehelper(self.overridetest3)
  113. d = bb.parse.handle(f.name, self.d)['']
  114. bb.data.expandKeys(d)
  115. self.assertEqual(d.getVar("DESCRIPTION_bc-dev"), "A B")
  116. d.setVar("DESCRIPTION", "E")
  117. d.setVar("DESCRIPTION_bc-dev", "C D")
  118. d.setVar("OVERRIDES", "bc-dev")
  119. self.assertEqual(d.getVar("DESCRIPTION"), "C D")
  120. classextend = """
  121. VAR_var_override1 = "B"
  122. EXTRA = ":override1"
  123. OVERRIDES = "nothing${EXTRA}"
  124. BBCLASSEXTEND = "###CLASS###"
  125. """
  126. classextend_bbclass = """
  127. EXTRA = ""
  128. python () {
  129. d.renameVar("VAR_var", "VAR_var2")
  130. }
  131. """
  132. #
  133. # Test based upon a real world data corruption issue. One
  134. # data store changing a variable poked through into a different data
  135. # store. This test case replicates that issue where the value 'B' would
  136. # become unset/disappear.
  137. #
  138. def test_parse_classextend_contamination(self):
  139. cls = self.parsehelper(self.classextend_bbclass, suffix=".bbclass")
  140. #clsname = os.path.basename(cls.name).replace(".bbclass", "")
  141. self.classextend = self.classextend.replace("###CLASS###", cls.name)
  142. f = self.parsehelper(self.classextend)
  143. alldata = bb.parse.handle(f.name, self.d)
  144. d1 = alldata['']
  145. d2 = alldata[cls.name]
  146. self.assertEqual(d1.getVar("VAR_var"), "B")
  147. self.assertEqual(d2.getVar("VAR_var"), None)
  148. addtask_deltask = """
  149. addtask do_patch after do_foo after do_unpack before do_configure before do_compile
  150. addtask do_fetch do_patch
  151. deltask do_fetch do_patch
  152. """
  153. def test_parse_addtask_deltask(self):
  154. import sys
  155. f = self.parsehelper(self.addtask_deltask)
  156. d = bb.parse.handle(f.name, self.d)['']
  157. stdout = sys.stdout.getvalue()
  158. self.assertTrue("addtask contained multiple 'before' keywords" in stdout)
  159. self.assertTrue("addtask contained multiple 'after' keywords" in stdout)
  160. self.assertTrue('addtask ignored: " do_patch"' in stdout)
  161. self.assertTrue('deltask ignored: " do_patch"' in stdout)
  162. #self.assertTrue('dependent task do_foo for do_patch does not exist' in stdout)