blob: aebea42502bee868af7c8c82b1f8bbf68d2a1ae5 [file] [log] [blame]
Brad Bishopc342db32019-05-15 21:57:59 -04001#
Patrick Williams92b42cb2022-09-03 06:53:57 -05002# Copyright OpenEmbedded Contributors
3#
Brad Bishopc342db32019-05-15 21:57:59 -04004# SPDX-License-Identifier: MIT
5#
6
Patrick Williams169d7bc2024-01-05 11:33:25 -06007import errno
Brad Bishopd7bf8c12018-02-25 22:55:05 -05008import os
9import shutil
10import tempfile
11import urllib.parse
12
13from oeqa.utils.commands import runCmd, bitbake, get_bb_var
14from oeqa.utils.commands import get_bb_vars, create_temp_layer
Brad Bishopd7bf8c12018-02-25 22:55:05 -050015from oeqa.selftest.cases import devtool
16
17templayerdir = None
18
19def setUpModule():
20 global templayerdir
21 templayerdir = tempfile.mkdtemp(prefix='recipetoolqa')
22 create_temp_layer(templayerdir, 'selftestrecipetool')
23 runCmd('bitbake-layers add-layer %s' % templayerdir)
24
25
26def tearDownModule():
27 runCmd('bitbake-layers remove-layer %s' % templayerdir, ignore_status=True)
28 runCmd('rm -rf %s' % templayerdir)
29
30
Patrick Williams73bd93f2024-02-20 08:07:48 -060031def needTomllib(test):
32 # This test require python 3.11 or above for the tomllib module or tomli module to be installed
33 try:
34 import tomllib
35 except ImportError:
36 try:
37 import tomli
38 except ImportError:
39 test.skipTest('Test requires python 3.11 or above for tomllib module or tomli module')
40
Andrew Geissler595f6302022-01-24 19:11:47 +000041class RecipetoolBase(devtool.DevtoolTestCase):
Brad Bishopd7bf8c12018-02-25 22:55:05 -050042
43 def setUpLocal(self):
44 super(RecipetoolBase, self).setUpLocal()
45 self.templayerdir = templayerdir
46 self.tempdir = tempfile.mkdtemp(prefix='recipetoolqa')
47 self.track_for_cleanup(self.tempdir)
48 self.testfile = os.path.join(self.tempdir, 'testfile')
49 with open(self.testfile, 'w') as f:
50 f.write('Test file\n')
Patrick Williams39653562024-03-01 08:54:02 -060051 config = 'BBMASK += "meta-poky/recipes-core/base-files/base-files_%.bbappend"\n'
52 self.append_config(config)
Brad Bishopd7bf8c12018-02-25 22:55:05 -050053
54 def tearDownLocal(self):
55 runCmd('rm -rf %s/recipes-*' % self.templayerdir)
56 super(RecipetoolBase, self).tearDownLocal()
57
58 def _try_recipetool_appendcmd(self, cmd, testrecipe, expectedfiles, expectedlines=None):
59 result = runCmd(cmd)
60 self.assertNotIn('Traceback', result.output)
61
62 # Check the bbappend was created and applies properly
63 recipefile = get_bb_var('FILE', testrecipe)
64 bbappendfile = self._check_bbappend(testrecipe, recipefile, self.templayerdir)
65
66 # Check the bbappend contents
67 if expectedlines is not None:
68 with open(bbappendfile, 'r') as f:
69 self.assertEqual(expectedlines, f.readlines(), "Expected lines are not present in %s" % bbappendfile)
70
71 # Check file was copied
72 filesdir = os.path.join(os.path.dirname(bbappendfile), testrecipe)
73 for expectedfile in expectedfiles:
74 self.assertTrue(os.path.isfile(os.path.join(filesdir, expectedfile)), 'Expected file %s to be copied next to bbappend, but it wasn\'t' % expectedfile)
75
76 # Check no other files created
77 createdfiles = []
78 for root, _, files in os.walk(filesdir):
79 for f in files:
80 createdfiles.append(os.path.relpath(os.path.join(root, f), filesdir))
81 self.assertTrue(sorted(createdfiles), sorted(expectedfiles))
82
83 return bbappendfile, result.output
84
85
Andrew Geissler595f6302022-01-24 19:11:47 +000086class RecipetoolAppendTests(RecipetoolBase):
Brad Bishopd7bf8c12018-02-25 22:55:05 -050087
88 @classmethod
89 def setUpClass(cls):
Andrew Geissler595f6302022-01-24 19:11:47 +000090 super(RecipetoolAppendTests, cls).setUpClass()
Brad Bishopd7bf8c12018-02-25 22:55:05 -050091 # Ensure we have the right data in shlibs/pkgdata
92 cls.logger.info('Running bitbake to generate pkgdata')
93 bitbake('-c packagedata base-files coreutils busybox selftest-recipetool-appendfile')
Andrew Geissler595f6302022-01-24 19:11:47 +000094 bb_vars = get_bb_vars(['COREBASE'])
Brad Bishopd7bf8c12018-02-25 22:55:05 -050095 cls.corebase = bb_vars['COREBASE']
Brad Bishopd7bf8c12018-02-25 22:55:05 -050096
97 def _try_recipetool_appendfile(self, testrecipe, destfile, newfile, options, expectedlines, expectedfiles):
98 cmd = 'recipetool appendfile %s %s %s %s' % (self.templayerdir, destfile, newfile, options)
99 return self._try_recipetool_appendcmd(cmd, testrecipe, expectedfiles, expectedlines)
100
101 def _try_recipetool_appendfile_fail(self, destfile, newfile, checkerror):
102 cmd = 'recipetool appendfile %s %s %s' % (self.templayerdir, destfile, newfile)
103 result = runCmd(cmd, ignore_status=True)
104 self.assertNotEqual(result.status, 0, 'Command "%s" should have failed but didn\'t' % cmd)
105 self.assertNotIn('Traceback', result.output)
106 for errorstr in checkerror:
107 self.assertIn(errorstr, result.output)
108
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500109 def test_recipetool_appendfile_basic(self):
110 # Basic test
Patrick Williams213cb262021-08-07 19:21:33 -0500111 expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500112 '\n']
113 _, output = self._try_recipetool_appendfile('base-files', '/etc/motd', self.testfile, '', expectedlines, ['motd'])
114 self.assertNotIn('WARNING: ', output)
115
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500116 def test_recipetool_appendfile_invalid(self):
117 # Test some commands that should error
118 self._try_recipetool_appendfile_fail('/etc/passwd', self.testfile, ['ERROR: /etc/passwd cannot be handled by this tool', 'useradd', 'extrausers'])
119 self._try_recipetool_appendfile_fail('/etc/timestamp', self.testfile, ['ERROR: /etc/timestamp cannot be handled by this tool'])
120 self._try_recipetool_appendfile_fail('/dev/console', self.testfile, ['ERROR: /dev/console cannot be handled by this tool'])
121
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500122 def test_recipetool_appendfile_alternatives(self):
123 # Now try with a file we know should be an alternative
124 # (this is very much a fake example, but one we know is reliably an alternative)
125 self._try_recipetool_appendfile_fail('/bin/ls', self.testfile, ['ERROR: File /bin/ls is an alternative possibly provided by the following recipes:', 'coreutils', 'busybox'])
126 # Need a test file - should be executable
127 testfile2 = os.path.join(self.corebase, 'oe-init-build-env')
128 testfile2name = os.path.basename(testfile2)
Patrick Williams213cb262021-08-07 19:21:33 -0500129 expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500130 '\n',
131 'SRC_URI += "file://%s"\n' % testfile2name,
132 '\n',
Patrick Williams213cb262021-08-07 19:21:33 -0500133 'do_install:append() {\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500134 ' install -d ${D}${base_bindir}\n',
135 ' install -m 0755 ${WORKDIR}/%s ${D}${base_bindir}/ls\n' % testfile2name,
136 '}\n']
137 self._try_recipetool_appendfile('coreutils', '/bin/ls', testfile2, '-r coreutils', expectedlines, [testfile2name])
138 # Now try bbappending the same file again, contents should not change
139 bbappendfile, _ = self._try_recipetool_appendfile('coreutils', '/bin/ls', self.testfile, '-r coreutils', expectedlines, [testfile2name])
140 # But file should have
141 copiedfile = os.path.join(os.path.dirname(bbappendfile), 'coreutils', testfile2name)
142 result = runCmd('diff -q %s %s' % (testfile2, copiedfile), ignore_status=True)
143 self.assertNotEqual(result.status, 0, 'New file should have been copied but was not %s' % result.output)
144
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500145 def test_recipetool_appendfile_binary(self):
146 # Try appending a binary file
147 # /bin/ls can be a symlink to /usr/bin/ls
148 ls = os.path.realpath("/bin/ls")
149 result = runCmd('recipetool appendfile %s /bin/ls %s -r coreutils' % (self.templayerdir, ls))
150 self.assertIn('WARNING: ', result.output)
151 self.assertIn('is a binary', result.output)
152
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500153 def test_recipetool_appendfile_add(self):
154 # Try arbitrary file add to a recipe
Patrick Williams213cb262021-08-07 19:21:33 -0500155 expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500156 '\n',
157 'SRC_URI += "file://testfile"\n',
158 '\n',
Patrick Williams213cb262021-08-07 19:21:33 -0500159 'do_install:append() {\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500160 ' install -d ${D}${datadir}\n',
161 ' install -m 0644 ${WORKDIR}/testfile ${D}${datadir}/something\n',
162 '}\n']
163 self._try_recipetool_appendfile('netbase', '/usr/share/something', self.testfile, '-r netbase', expectedlines, ['testfile'])
164 # Try adding another file, this time where the source file is executable
165 # (so we're testing that, plus modifying an existing bbappend)
166 testfile2 = os.path.join(self.corebase, 'oe-init-build-env')
167 testfile2name = os.path.basename(testfile2)
Patrick Williams213cb262021-08-07 19:21:33 -0500168 expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500169 '\n',
170 'SRC_URI += "file://testfile \\\n',
171 ' file://%s \\\n' % testfile2name,
172 ' "\n',
173 '\n',
Patrick Williams213cb262021-08-07 19:21:33 -0500174 'do_install:append() {\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500175 ' install -d ${D}${datadir}\n',
176 ' install -m 0644 ${WORKDIR}/testfile ${D}${datadir}/something\n',
177 ' install -m 0755 ${WORKDIR}/%s ${D}${datadir}/scriptname\n' % testfile2name,
178 '}\n']
179 self._try_recipetool_appendfile('netbase', '/usr/share/scriptname', testfile2, '-r netbase', expectedlines, ['testfile', testfile2name])
180
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500181 def test_recipetool_appendfile_add_bindir(self):
182 # Try arbitrary file add to a recipe, this time to a location such that should be installed as executable
Patrick Williams213cb262021-08-07 19:21:33 -0500183 expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500184 '\n',
185 'SRC_URI += "file://testfile"\n',
186 '\n',
Patrick Williams213cb262021-08-07 19:21:33 -0500187 'do_install:append() {\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500188 ' install -d ${D}${bindir}\n',
189 ' install -m 0755 ${WORKDIR}/testfile ${D}${bindir}/selftest-recipetool-testbin\n',
190 '}\n']
191 _, output = self._try_recipetool_appendfile('netbase', '/usr/bin/selftest-recipetool-testbin', self.testfile, '-r netbase', expectedlines, ['testfile'])
192 self.assertNotIn('WARNING: ', output)
193
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500194 def test_recipetool_appendfile_add_machine(self):
195 # Try arbitrary file add to a recipe, this time to a location such that should be installed as executable
Patrick Williams213cb262021-08-07 19:21:33 -0500196 expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500197 '\n',
198 'PACKAGE_ARCH = "${MACHINE_ARCH}"\n',
199 '\n',
Patrick Williams213cb262021-08-07 19:21:33 -0500200 'SRC_URI:append:mymachine = " file://testfile"\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500201 '\n',
Patrick Williams213cb262021-08-07 19:21:33 -0500202 'do_install:append:mymachine() {\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500203 ' install -d ${D}${datadir}\n',
204 ' install -m 0644 ${WORKDIR}/testfile ${D}${datadir}/something\n',
205 '}\n']
206 _, output = self._try_recipetool_appendfile('netbase', '/usr/share/something', self.testfile, '-r netbase -m mymachine', expectedlines, ['mymachine/testfile'])
207 self.assertNotIn('WARNING: ', output)
208
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500209 def test_recipetool_appendfile_orig(self):
210 # A file that's in SRC_URI and in do_install with the same name
Patrick Williams213cb262021-08-07 19:21:33 -0500211 expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500212 '\n']
213 _, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-orig', self.testfile, '', expectedlines, ['selftest-replaceme-orig'])
214 self.assertNotIn('WARNING: ', output)
215
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500216 def test_recipetool_appendfile_todir(self):
217 # A file that's in SRC_URI and in do_install with destination directory rather than file
Patrick Williams213cb262021-08-07 19:21:33 -0500218 expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500219 '\n']
220 _, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-todir', self.testfile, '', expectedlines, ['selftest-replaceme-todir'])
221 self.assertNotIn('WARNING: ', output)
222
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500223 def test_recipetool_appendfile_renamed(self):
224 # A file that's in SRC_URI with a different name to the destination file
Patrick Williams213cb262021-08-07 19:21:33 -0500225 expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500226 '\n']
227 _, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-renamed', self.testfile, '', expectedlines, ['file1'])
228 self.assertNotIn('WARNING: ', output)
229
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500230 def test_recipetool_appendfile_subdir(self):
231 # A file that's in SRC_URI in a subdir
Patrick Williams213cb262021-08-07 19:21:33 -0500232 expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500233 '\n',
234 'SRC_URI += "file://testfile"\n',
235 '\n',
Patrick Williams213cb262021-08-07 19:21:33 -0500236 'do_install:append() {\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500237 ' install -d ${D}${datadir}\n',
238 ' install -m 0644 ${WORKDIR}/testfile ${D}${datadir}/selftest-replaceme-subdir\n',
239 '}\n']
240 _, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-subdir', self.testfile, '', expectedlines, ['testfile'])
241 self.assertNotIn('WARNING: ', output)
242
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500243 def test_recipetool_appendfile_inst_glob(self):
244 # A file that's in do_install as a glob
Patrick Williams213cb262021-08-07 19:21:33 -0500245 expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500246 '\n']
247 _, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-inst-globfile', self.testfile, '', expectedlines, ['selftest-replaceme-inst-globfile'])
248 self.assertNotIn('WARNING: ', output)
249
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500250 def test_recipetool_appendfile_inst_todir_glob(self):
251 # A file that's in do_install as a glob with destination as a directory
Patrick Williams213cb262021-08-07 19:21:33 -0500252 expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500253 '\n']
254 _, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-inst-todir-globfile', self.testfile, '', expectedlines, ['selftest-replaceme-inst-todir-globfile'])
255 self.assertNotIn('WARNING: ', output)
256
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500257 def test_recipetool_appendfile_patch(self):
258 # A file that's added by a patch in SRC_URI
Patrick Williams213cb262021-08-07 19:21:33 -0500259 expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500260 '\n',
261 'SRC_URI += "file://testfile"\n',
262 '\n',
Patrick Williams213cb262021-08-07 19:21:33 -0500263 'do_install:append() {\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500264 ' install -d ${D}${sysconfdir}\n',
265 ' install -m 0644 ${WORKDIR}/testfile ${D}${sysconfdir}/selftest-replaceme-patched\n',
266 '}\n']
267 _, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/etc/selftest-replaceme-patched', self.testfile, '', expectedlines, ['testfile'])
268 for line in output.splitlines():
269 if 'WARNING: ' in line:
270 self.assertIn('add-file.patch', line, 'Unexpected warning found in output:\n%s' % line)
271 break
272 else:
273 self.fail('Patch warning not found in output:\n%s' % output)
274
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500275 def test_recipetool_appendfile_script(self):
276 # Now, a file that's in SRC_URI but installed by a script (so no mention in do_install)
Patrick Williams213cb262021-08-07 19:21:33 -0500277 expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500278 '\n',
279 'SRC_URI += "file://testfile"\n',
280 '\n',
Patrick Williams213cb262021-08-07 19:21:33 -0500281 'do_install:append() {\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500282 ' install -d ${D}${datadir}\n',
283 ' install -m 0644 ${WORKDIR}/testfile ${D}${datadir}/selftest-replaceme-scripted\n',
284 '}\n']
285 _, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-scripted', self.testfile, '', expectedlines, ['testfile'])
286 self.assertNotIn('WARNING: ', output)
287
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500288 def test_recipetool_appendfile_inst_func(self):
289 # A file that's installed from a function called by do_install
Patrick Williams213cb262021-08-07 19:21:33 -0500290 expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500291 '\n']
292 _, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-inst-func', self.testfile, '', expectedlines, ['selftest-replaceme-inst-func'])
293 self.assertNotIn('WARNING: ', output)
294
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500295 def test_recipetool_appendfile_postinstall(self):
296 # A file that's created by a postinstall script (and explicitly mentioned in it)
297 # First try without specifying recipe
298 self._try_recipetool_appendfile_fail('/usr/share/selftest-replaceme-postinst', self.testfile, ['File /usr/share/selftest-replaceme-postinst may be written out in a pre/postinstall script of the following recipes:', 'selftest-recipetool-appendfile'])
299 # Now specify recipe
Patrick Williams213cb262021-08-07 19:21:33 -0500300 expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500301 '\n',
302 'SRC_URI += "file://testfile"\n',
303 '\n',
Patrick Williams213cb262021-08-07 19:21:33 -0500304 'do_install:append() {\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500305 ' install -d ${D}${datadir}\n',
306 ' install -m 0644 ${WORKDIR}/testfile ${D}${datadir}/selftest-replaceme-postinst\n',
307 '}\n']
308 _, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-postinst', self.testfile, '-r selftest-recipetool-appendfile', expectedlines, ['testfile'])
309
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500310 def test_recipetool_appendfile_extlayer(self):
311 # Try creating a bbappend in a layer that's not in bblayers.conf and has a different structure
312 exttemplayerdir = os.path.join(self.tempdir, 'extlayer')
313 self._create_temp_layer(exttemplayerdir, False, 'oeselftestextlayer', recipepathspec='metadata/recipes/recipes-*/*')
314 result = runCmd('recipetool appendfile %s /usr/share/selftest-replaceme-orig %s' % (exttemplayerdir, self.testfile))
315 self.assertNotIn('Traceback', result.output)
316 createdfiles = []
317 for root, _, files in os.walk(exttemplayerdir):
318 for f in files:
319 createdfiles.append(os.path.relpath(os.path.join(root, f), exttemplayerdir))
320 createdfiles.remove('conf/layer.conf')
321 expectedfiles = ['metadata/recipes/recipes-test/selftest-recipetool-appendfile/selftest-recipetool-appendfile.bbappend',
322 'metadata/recipes/recipes-test/selftest-recipetool-appendfile/selftest-recipetool-appendfile/selftest-replaceme-orig']
323 self.assertEqual(sorted(createdfiles), sorted(expectedfiles))
324
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500325 def test_recipetool_appendfile_wildcard(self):
326
327 def try_appendfile_wc(options):
328 result = runCmd('recipetool appendfile %s /etc/profile %s %s' % (self.templayerdir, self.testfile, options))
329 self.assertNotIn('Traceback', result.output)
330 bbappendfile = None
331 for root, _, files in os.walk(self.templayerdir):
332 for f in files:
333 if f.endswith('.bbappend'):
334 bbappendfile = f
335 break
336 if not bbappendfile:
337 self.fail('No bbappend file created')
338 runCmd('rm -rf %s/recipes-*' % self.templayerdir)
339 return bbappendfile
340
341 # Check without wildcard option
342 recipefn = os.path.basename(get_bb_var('FILE', 'base-files'))
343 filename = try_appendfile_wc('')
344 self.assertEqual(filename, recipefn.replace('.bb', '.bbappend'))
345 # Now check with wildcard option
346 filename = try_appendfile_wc('-w')
347 self.assertEqual(filename, recipefn.split('_')[0] + '_%.bbappend')
348
Andrew Geissler595f6302022-01-24 19:11:47 +0000349
350class RecipetoolCreateTests(RecipetoolBase):
351
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500352 def test_recipetool_create(self):
353 # Try adding a recipe
354 tempsrc = os.path.join(self.tempdir, 'srctree')
355 os.makedirs(tempsrc)
356 recipefile = os.path.join(self.tempdir, 'logrotate_3.12.3.bb')
357 srcuri = 'https://github.com/logrotate/logrotate/releases/download/3.12.3/logrotate-3.12.3.tar.xz'
358 result = runCmd('recipetool create -o %s %s -x %s' % (recipefile, srcuri, tempsrc))
359 self.assertTrue(os.path.isfile(recipefile))
360 checkvars = {}
Andrew Geissler9aee5002022-03-30 16:27:02 +0000361 checkvars['LICENSE'] = 'GPL-2.0-only'
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500362 checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263'
363 checkvars['SRC_URI'] = 'https://github.com/logrotate/logrotate/releases/download/${PV}/logrotate-${PV}.tar.xz'
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500364 checkvars['SRC_URI[sha256sum]'] = '2e6a401cac9024db2288297e3be1a8ab60e7401ba8e91225218aaf4a27e82a07'
365 self._test_recipe_contents(recipefile, checkvars, [])
366
Andrew Geissler595f6302022-01-24 19:11:47 +0000367 def test_recipetool_create_autotools(self):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500368 if 'x11' not in get_bb_var('DISTRO_FEATURES'):
369 self.skipTest('Test requires x11 as distro feature')
370 # Ensure we have the right data in shlibs/pkgdata
371 bitbake('libpng pango libx11 libxext jpeg libcheck')
372 # Try adding a recipe
373 tempsrc = os.path.join(self.tempdir, 'srctree')
374 os.makedirs(tempsrc)
375 recipefile = os.path.join(self.tempdir, 'libmatchbox.bb')
Andrew Geissler028142b2023-05-05 11:29:21 -0500376 srcuri = 'git://git.yoctoproject.org/libmatchbox;protocol=https'
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500377 result = runCmd(['recipetool', 'create', '-o', recipefile, srcuri + ";rev=9f7cf8895ae2d39c465c04cc78e918c157420269", '-x', tempsrc])
378 self.assertTrue(os.path.isfile(recipefile), 'recipetool did not create recipe file; output:\n%s' % result.output)
379 checkvars = {}
Andrew Geissler9aee5002022-03-30 16:27:02 +0000380 checkvars['LICENSE'] = 'LGPL-2.1-only'
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500381 checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=7fbc338309ac38fefcd64b04bb903e34'
382 checkvars['S'] = '${WORKDIR}/git'
Andrew Geissler5082cc72023-09-11 08:41:39 -0400383 checkvars['PV'] = '1.11+git'
Andrew Geissler595f6302022-01-24 19:11:47 +0000384 checkvars['SRC_URI'] = srcuri + ';branch=master'
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500385 checkvars['DEPENDS'] = set(['libcheck', 'libjpeg-turbo', 'libpng', 'libx11', 'libxext', 'pango'])
386 inherits = ['autotools', 'pkgconfig']
387 self._test_recipe_contents(recipefile, checkvars, inherits)
388
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500389 def test_recipetool_create_simple(self):
390 # Try adding a recipe
391 temprecipe = os.path.join(self.tempdir, 'recipe')
392 os.makedirs(temprecipe)
Andrew Geissler5f350902021-07-23 13:09:54 -0400393 pv = '1.7.4.1'
Andrew Geissler9aee5002022-03-30 16:27:02 +0000394 srcuri = 'http://www.dest-unreach.org/socat/download/Archive/socat-%s.tar.bz2' % pv
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500395 result = runCmd('recipetool create %s -o %s' % (srcuri, temprecipe))
396 dirlist = os.listdir(temprecipe)
397 if len(dirlist) > 1:
398 self.fail('recipetool created more than just one file; output:\n%s\ndirlist:\n%s' % (result.output, str(dirlist)))
399 if len(dirlist) < 1 or not os.path.isfile(os.path.join(temprecipe, dirlist[0])):
400 self.fail('recipetool did not create recipe file; output:\n%s\ndirlist:\n%s' % (result.output, str(dirlist)))
401 self.assertEqual(dirlist[0], 'socat_%s.bb' % pv, 'Recipe file incorrectly named')
402 checkvars = {}
Andrew Geissler9aee5002022-03-30 16:27:02 +0000403 checkvars['LICENSE'] = set(['Unknown', 'GPL-2.0-only'])
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500404 checkvars['LIC_FILES_CHKSUM'] = set(['file://COPYING.OpenSSL;md5=5c9bccc77f67a8328ef4ebaf468116f4', 'file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263'])
405 # We don't check DEPENDS since they are variable for this recipe depending on what's in the sysroot
406 checkvars['S'] = None
407 checkvars['SRC_URI'] = srcuri.replace(pv, '${PV}')
408 inherits = ['autotools']
409 self._test_recipe_contents(os.path.join(temprecipe, dirlist[0]), checkvars, inherits)
410
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500411 def test_recipetool_create_cmake(self):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500412 temprecipe = os.path.join(self.tempdir, 'recipe')
413 os.makedirs(temprecipe)
Brad Bishop96ff1982019-08-19 13:50:42 -0400414 recipefile = os.path.join(temprecipe, 'taglib_1.11.1.bb')
415 srcuri = 'http://taglib.github.io/releases/taglib-1.11.1.tar.gz'
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500416 result = runCmd('recipetool create -o %s %s' % (temprecipe, srcuri))
417 self.assertTrue(os.path.isfile(recipefile))
418 checkvars = {}
Andrew Geissler9aee5002022-03-30 16:27:02 +0000419 checkvars['LICENSE'] = set(['LGPL-2.1-only', 'MPL-1.1-only'])
Brad Bishop96ff1982019-08-19 13:50:42 -0400420 checkvars['SRC_URI'] = 'http://taglib.github.io/releases/taglib-${PV}.tar.gz'
Brad Bishop96ff1982019-08-19 13:50:42 -0400421 checkvars['SRC_URI[sha256sum]'] = 'b6d1a5a610aae6ff39d93de5efd0fdc787aa9e9dc1e7026fa4c961b26563526b'
422 checkvars['DEPENDS'] = set(['boost', 'zlib'])
423 inherits = ['cmake']
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500424 self._test_recipe_contents(recipefile, checkvars, inherits)
425
Andrew Geissler82c905d2020-04-13 13:39:40 -0500426 def test_recipetool_create_npm(self):
Andrew Geisslerf0343792020-11-18 10:42:21 -0600427 collections = get_bb_var('BBFILE_COLLECTIONS').split()
428 if "openembedded-layer" not in collections:
429 self.skipTest("Test needs meta-oe for nodejs")
430
Andrew Geissler82c905d2020-04-13 13:39:40 -0500431 temprecipe = os.path.join(self.tempdir, 'recipe')
432 os.makedirs(temprecipe)
433 recipefile = os.path.join(temprecipe, 'savoirfairelinux-node-server-example_1.0.0.bb')
434 shrinkwrap = os.path.join(temprecipe, 'savoirfairelinux-node-server-example', 'npm-shrinkwrap.json')
435 srcuri = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=1.0.0'
436 result = runCmd('recipetool create -o %s \'%s\'' % (temprecipe, srcuri))
437 self.assertTrue(os.path.isfile(recipefile))
438 self.assertTrue(os.path.isfile(shrinkwrap))
439 checkvars = {}
440 checkvars['SUMMARY'] = 'Node Server Example'
441 checkvars['HOMEPAGE'] = 'https://github.com/savoirfairelinux/node-server-example#readme'
Andrew Geissler595f6302022-01-24 19:11:47 +0000442 checkvars['LICENSE'] = 'BSD-3-Clause & ISC & MIT & Unknown'
Andrew Geissler82c905d2020-04-13 13:39:40 -0500443 urls = []
444 urls.append('npm://registry.npmjs.org/;package=@savoirfairelinux/node-server-example;version=${PV}')
445 urls.append('npmsw://${THISDIR}/${BPN}/npm-shrinkwrap.json')
446 checkvars['SRC_URI'] = set(urls)
447 checkvars['S'] = '${WORKDIR}/npm'
Patrick Williams213cb262021-08-07 19:21:33 -0500448 checkvars['LICENSE:${PN}'] = 'MIT'
449 checkvars['LICENSE:${PN}-base64'] = 'Unknown'
450 checkvars['LICENSE:${PN}-accepts'] = 'MIT'
451 checkvars['LICENSE:${PN}-inherits'] = 'ISC'
Andrew Geissler82c905d2020-04-13 13:39:40 -0500452 inherits = ['npm']
453 self._test_recipe_contents(recipefile, checkvars, inherits)
454
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500455 def test_recipetool_create_github(self):
Patrick Williams73bd93f2024-02-20 08:07:48 -0600456 # Basic test to see if github URL mangling works. Deliberately use an
457 # older release of Meson at present so we don't need a toml parser.
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500458 temprecipe = os.path.join(self.tempdir, 'recipe')
459 os.makedirs(temprecipe)
Patrick Williamsac13d5f2023-11-24 18:59:46 -0600460 recipefile = os.path.join(temprecipe, 'python3-meson_git.bb')
Patrick Williams73bd93f2024-02-20 08:07:48 -0600461 srcuri = 'https://github.com/mesonbuild/meson;rev=0.52.1'
462 cmd = ['recipetool', 'create', '-o', temprecipe, srcuri]
463 result = runCmd(cmd)
464 self.assertTrue(os.path.isfile(recipefile), msg="recipe %s not created for command %s, output %s" % (recipefile, " ".join(cmd), result.output))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500465 checkvars = {}
Patrick Williams73bd93f2024-02-20 08:07:48 -0600466 checkvars['LICENSE'] = set(['Apache-2.0', "Unknown"])
467 checkvars['SRC_URI'] = 'git://github.com/mesonbuild/meson;protocol=https;branch=0.52'
Brad Bishop15ae2502019-06-18 21:44:24 -0400468 inherits = ['setuptools3']
469 self._test_recipe_contents(recipefile, checkvars, inherits)
470
471 def test_recipetool_create_python3_setuptools(self):
472 # Test creating python3 package from tarball (using setuptools3 class)
Patrick Williams169d7bc2024-01-05 11:33:25 -0600473 # Use the --no-pypi switch to avoid creating a pypi enabled recipe and
474 # and check the created recipe as if it was a more general tarball
475 temprecipe = os.path.join(self.tempdir, 'recipe')
476 os.makedirs(temprecipe)
477 pn = 'python-magic'
478 pv = '0.4.15'
479 recipefile = os.path.join(temprecipe, '%s_%s.bb' % (pn, pv))
480 srcuri = 'https://files.pythonhosted.org/packages/84/30/80932401906eaf787f2e9bd86dc458f1d2e75b064b4c187341f29516945c/python-magic-%s.tar.gz' % pv
481 result = runCmd('recipetool create --no-pypi -o %s %s' % (temprecipe, srcuri))
482 self.assertTrue(os.path.isfile(recipefile))
483 checkvars = {}
484 checkvars['LICENSE'] = set(['MIT'])
485 checkvars['LIC_FILES_CHKSUM'] = 'file://LICENSE;md5=16a934f165e8c3245f241e77d401bb88'
486 checkvars['SRC_URI'] = 'https://files.pythonhosted.org/packages/84/30/80932401906eaf787f2e9bd86dc458f1d2e75b064b4c187341f29516945c/python-magic-${PV}.tar.gz'
487 checkvars['SRC_URI[sha256sum]'] = 'f3765c0f582d2dfc72c15f3b5a82aecfae9498bd29ca840d72f37d7bd38bfcd5'
488 inherits = ['setuptools3']
489 self._test_recipe_contents(recipefile, checkvars, inherits)
490
491 def test_recipetool_create_python3_setuptools_pypi_tarball(self):
492 # Test creating python3 package from tarball (using setuptools3 and pypi classes)
Brad Bishop15ae2502019-06-18 21:44:24 -0400493 temprecipe = os.path.join(self.tempdir, 'recipe')
494 os.makedirs(temprecipe)
495 pn = 'python-magic'
496 pv = '0.4.15'
497 recipefile = os.path.join(temprecipe, '%s_%s.bb' % (pn, pv))
498 srcuri = 'https://files.pythonhosted.org/packages/84/30/80932401906eaf787f2e9bd86dc458f1d2e75b064b4c187341f29516945c/python-magic-%s.tar.gz' % pv
499 result = runCmd('recipetool create -o %s %s' % (temprecipe, srcuri))
500 self.assertTrue(os.path.isfile(recipefile))
501 checkvars = {}
502 checkvars['LICENSE'] = set(['MIT'])
503 checkvars['LIC_FILES_CHKSUM'] = 'file://LICENSE;md5=16a934f165e8c3245f241e77d401bb88'
Brad Bishop15ae2502019-06-18 21:44:24 -0400504 checkvars['SRC_URI[sha256sum]'] = 'f3765c0f582d2dfc72c15f3b5a82aecfae9498bd29ca840d72f37d7bd38bfcd5'
Patrick Williams169d7bc2024-01-05 11:33:25 -0600505 checkvars['PYPI_PACKAGE'] = pn
506 inherits = ['setuptools3', 'pypi']
507 self._test_recipe_contents(recipefile, checkvars, inherits)
508
509 def test_recipetool_create_python3_setuptools_pypi(self):
510 # Test creating python3 package from pypi url (using setuptools3 and pypi classes)
511 # Intentionnaly using setuptools3 class here instead of any of the pep517 class
512 # to avoid the toml dependency and allows this test to run on host autobuilders
513 # with older version of python
514 temprecipe = os.path.join(self.tempdir, 'recipe')
515 os.makedirs(temprecipe)
516 pn = 'python-magic'
517 pv = '0.4.15'
518 recipefile = os.path.join(temprecipe, '%s_%s.bb' % (pn, pv))
519 # First specify the required version in the url
520 srcuri = 'https://pypi.org/project/%s/%s' % (pn, pv)
521 runCmd('recipetool create -o %s %s' % (temprecipe, srcuri))
522 self.assertTrue(os.path.isfile(recipefile))
523 checkvars = {}
524 checkvars['LICENSE'] = set(['MIT'])
525 checkvars['LIC_FILES_CHKSUM'] = 'file://LICENSE;md5=16a934f165e8c3245f241e77d401bb88'
526 checkvars['SRC_URI[sha256sum]'] = 'f3765c0f582d2dfc72c15f3b5a82aecfae9498bd29ca840d72f37d7bd38bfcd5'
527 checkvars['PYPI_PACKAGE'] = pn
528 inherits = ['setuptools3', "pypi"]
529 self._test_recipe_contents(recipefile, checkvars, inherits)
530
531 # Now specify the version as a recipetool parameter
532 runCmd('rm -rf %s' % recipefile)
533 self.assertFalse(os.path.isfile(recipefile))
534 srcuri = 'https://pypi.org/project/%s' % pn
535 runCmd('recipetool create -o %s %s --version %s' % (temprecipe, srcuri, pv))
536 self.assertTrue(os.path.isfile(recipefile))
537 checkvars = {}
538 checkvars['LICENSE'] = set(['MIT'])
539 checkvars['LIC_FILES_CHKSUM'] = 'file://LICENSE;md5=16a934f165e8c3245f241e77d401bb88'
540 checkvars['SRC_URI[sha256sum]'] = 'f3765c0f582d2dfc72c15f3b5a82aecfae9498bd29ca840d72f37d7bd38bfcd5'
541 checkvars['PYPI_PACKAGE'] = pn
542 inherits = ['setuptools3', "pypi"]
543 self._test_recipe_contents(recipefile, checkvars, inherits)
544
545 # Now, try to grab latest version of the package, so we cannot guess the name of the recipe,
546 # unless hardcoding the latest version but it means we will need to update the test for each release,
547 # so use a regexp
548 runCmd('rm -rf %s' % recipefile)
549 self.assertFalse(os.path.isfile(recipefile))
550 recipefile_re = r'%s_(.*)\.bb' % pn
551 result = runCmd('recipetool create -o %s %s' % (temprecipe, srcuri))
552 dirlist = os.listdir(temprecipe)
553 if len(dirlist) > 1:
554 self.fail('recipetool created more than just one file; output:\n%s\ndirlist:\n%s' % (result.output, str(dirlist)))
555 if len(dirlist) < 1 or not os.path.isfile(os.path.join(temprecipe, dirlist[0])):
556 self.fail('recipetool did not create recipe file; output:\n%s\ndirlist:\n%s' % (result.output, str(dirlist)))
557 import re
558 match = re.match(recipefile_re, dirlist[0])
559 self.assertTrue(match)
560 latest_pv = match.group(1)
561 self.assertTrue(latest_pv != pv)
562 recipefile = os.path.join(temprecipe, '%s_%s.bb' % (pn, latest_pv))
563 # Do not check LIC_FILES_CHKSUM and SRC_URI checksum here to avoid having updating the test on each release
564 checkvars = {}
565 checkvars['LICENSE'] = set(['MIT'])
566 checkvars['PYPI_PACKAGE'] = pn
567 inherits = ['setuptools3', "pypi"]
Brad Bishop15ae2502019-06-18 21:44:24 -0400568 self._test_recipe_contents(recipefile, checkvars, inherits)
569
Patrick Williamsac13d5f2023-11-24 18:59:46 -0600570 def test_recipetool_create_python3_pep517_setuptools_build_meta(self):
Patrick Williams73bd93f2024-02-20 08:07:48 -0600571 # This test require python 3.11 or above for the tomllib module or tomli module to be installed
572 needTomllib(self)
Patrick Williamsac13d5f2023-11-24 18:59:46 -0600573
574 # Test creating python3 package from tarball (using setuptools.build_meta class)
575 temprecipe = os.path.join(self.tempdir, 'recipe')
576 os.makedirs(temprecipe)
577 pn = 'webcolors'
578 pv = '1.13'
579 recipefile = os.path.join(temprecipe, 'python3-%s_%s.bb' % (pn, pv))
580 srcuri = 'https://files.pythonhosted.org/packages/a1/fb/f95560c6a5d4469d9c49e24cf1b5d4d21ffab5608251c6020a965fb7791c/%s-%s.tar.gz' % (pn, pv)
581 result = runCmd('recipetool create -o %s %s' % (temprecipe, srcuri))
582 self.assertTrue(os.path.isfile(recipefile))
583 checkvars = {}
584 checkvars['SUMMARY'] = 'A library for working with the color formats defined by HTML and CSS.'
585 checkvars['LICENSE'] = set(['BSD-3-Clause'])
586 checkvars['LIC_FILES_CHKSUM'] = 'file://LICENSE;md5=702b1ef12cf66832a88f24c8f2ee9c19'
Patrick Williamsac13d5f2023-11-24 18:59:46 -0600587 checkvars['SRC_URI[sha256sum]'] = 'c225b674c83fa923be93d235330ce0300373d02885cef23238813b0d5668304a'
Patrick Williams169d7bc2024-01-05 11:33:25 -0600588 inherits = ['python_setuptools_build_meta', 'pypi']
Patrick Williamsac13d5f2023-11-24 18:59:46 -0600589
590 self._test_recipe_contents(recipefile, checkvars, inherits)
591
592 def test_recipetool_create_python3_pep517_poetry_core_masonry_api(self):
Patrick Williams73bd93f2024-02-20 08:07:48 -0600593 # This test require python 3.11 or above for the tomllib module or tomli module to be installed
594 needTomllib(self)
Patrick Williamsac13d5f2023-11-24 18:59:46 -0600595
596 # Test creating python3 package from tarball (using poetry.core.masonry.api class)
597 temprecipe = os.path.join(self.tempdir, 'recipe')
598 os.makedirs(temprecipe)
599 pn = 'iso8601'
600 pv = '2.1.0'
601 recipefile = os.path.join(temprecipe, 'python3-%s_%s.bb' % (pn, pv))
602 srcuri = 'https://files.pythonhosted.org/packages/b9/f3/ef59cee614d5e0accf6fd0cbba025b93b272e626ca89fb70a3e9187c5d15/%s-%s.tar.gz' % (pn, pv)
603 result = runCmd('recipetool create -o %s %s' % (temprecipe, srcuri))
604 self.assertTrue(os.path.isfile(recipefile))
605 checkvars = {}
606 checkvars['SUMMARY'] = 'Simple module to parse ISO 8601 dates'
607 checkvars['LICENSE'] = set(['MIT'])
608 checkvars['LIC_FILES_CHKSUM'] = 'file://LICENSE;md5=aab31f2ef7ba214a5a341eaa47a7f367'
Patrick Williamsac13d5f2023-11-24 18:59:46 -0600609 checkvars['SRC_URI[sha256sum]'] = '6b1d3829ee8921c4301998c909f7829fa9ed3cbdac0d3b16af2d743aed1ba8df'
Patrick Williams169d7bc2024-01-05 11:33:25 -0600610 inherits = ['python_poetry_core', 'pypi']
Patrick Williamsac13d5f2023-11-24 18:59:46 -0600611
612 self._test_recipe_contents(recipefile, checkvars, inherits)
613
614 def test_recipetool_create_python3_pep517_flit_core_buildapi(self):
Patrick Williams73bd93f2024-02-20 08:07:48 -0600615 # This test require python 3.11 or above for the tomllib module or tomli module to be installed
616 needTomllib(self)
Patrick Williamsac13d5f2023-11-24 18:59:46 -0600617
618 # Test creating python3 package from tarball (using flit_core.buildapi class)
619 temprecipe = os.path.join(self.tempdir, 'recipe')
620 os.makedirs(temprecipe)
621 pn = 'typing-extensions'
622 pv = '4.8.0'
623 recipefile = os.path.join(temprecipe, 'python3-%s_%s.bb' % (pn, pv))
624 srcuri = 'https://files.pythonhosted.org/packages/1f/7a/8b94bb016069caa12fc9f587b28080ac33b4fbb8ca369b98bc0a4828543e/typing_extensions-%s.tar.gz' % pv
625 result = runCmd('recipetool create -o %s %s' % (temprecipe, srcuri))
626 self.assertTrue(os.path.isfile(recipefile))
627 checkvars = {}
628 checkvars['SUMMARY'] = 'Backported and Experimental Type Hints for Python 3.8+'
629 checkvars['LICENSE'] = set(['PSF-2.0'])
630 checkvars['LIC_FILES_CHKSUM'] = 'file://LICENSE;md5=fcf6b249c2641540219a727f35d8d2c2'
Patrick Williamsac13d5f2023-11-24 18:59:46 -0600631 checkvars['SRC_URI[sha256sum]'] = 'df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef'
Patrick Williams169d7bc2024-01-05 11:33:25 -0600632 inherits = ['python_flit_core', 'pypi']
Patrick Williamsac13d5f2023-11-24 18:59:46 -0600633
634 self._test_recipe_contents(recipefile, checkvars, inherits)
635
636 def test_recipetool_create_python3_pep517_hatchling(self):
Patrick Williams73bd93f2024-02-20 08:07:48 -0600637 # This test require python 3.11 or above for the tomllib module or tomli module to be installed
638 needTomllib(self)
Patrick Williamsac13d5f2023-11-24 18:59:46 -0600639
640 # Test creating python3 package from tarball (using hatchling class)
641 temprecipe = os.path.join(self.tempdir, 'recipe')
642 os.makedirs(temprecipe)
643 pn = 'jsonschema'
644 pv = '4.19.1'
645 recipefile = os.path.join(temprecipe, 'python3-%s_%s.bb' % (pn, pv))
646 srcuri = 'https://files.pythonhosted.org/packages/e4/43/087b24516db11722c8687e0caf0f66c7785c0b1c51b0ab951dfde924e3f5/jsonschema-%s.tar.gz' % pv
647 result = runCmd('recipetool create -o %s %s' % (temprecipe, srcuri))
648 self.assertTrue(os.path.isfile(recipefile))
649 checkvars = {}
650 checkvars['SUMMARY'] = 'An implementation of JSON Schema validation for Python'
651 checkvars['HOMEPAGE'] = 'https://github.com/python-jsonschema/jsonschema'
652 checkvars['LICENSE'] = set(['MIT'])
653 checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=7a60a81c146ec25599a3e1dabb8610a8 file://json/LICENSE;md5=9d4de43111d33570c8fe49b4cb0e01af'
Patrick Williamsac13d5f2023-11-24 18:59:46 -0600654 checkvars['SRC_URI[sha256sum]'] = 'ec84cc37cfa703ef7cd4928db24f9cb31428a5d0fa77747b8b51a847458e0bbf'
Patrick Williams169d7bc2024-01-05 11:33:25 -0600655 inherits = ['python_hatchling', 'pypi']
656
657 self._test_recipe_contents(recipefile, checkvars, inherits)
658
659 def test_recipetool_create_python3_pep517_maturin(self):
Patrick Williams73bd93f2024-02-20 08:07:48 -0600660 # This test require python 3.11 or above for the tomllib module or tomli module to be installed
661 needTomllib(self)
Patrick Williams169d7bc2024-01-05 11:33:25 -0600662
663 # Test creating python3 package from tarball (using maturin class)
664 temprecipe = os.path.join(self.tempdir, 'recipe')
665 os.makedirs(temprecipe)
666 pn = 'pydantic-core'
667 pv = '2.14.5'
668 recipefile = os.path.join(temprecipe, 'python3-%s_%s.bb' % (pn, pv))
669 srcuri = 'https://files.pythonhosted.org/packages/64/26/cffb93fe9c6b5a91c497f37fae14a4b073ecbc47fc36a9979c7aa888b245/pydantic_core-%s.tar.gz' % pv
670 result = runCmd('recipetool create -o %s %s' % (temprecipe, srcuri))
671 self.assertTrue(os.path.isfile(recipefile))
672 checkvars = {}
673 checkvars['HOMEPAGE'] = 'https://github.com/pydantic/pydantic-core'
674 checkvars['LICENSE'] = set(['MIT'])
675 checkvars['LIC_FILES_CHKSUM'] = 'file://LICENSE;md5=ab599c188b4a314d2856b3a55030c75c'
676 checkvars['SRC_URI[sha256sum]'] = '6d30226dfc816dd0fdf120cae611dd2215117e4f9b124af8c60ab9093b6e8e71'
677 inherits = ['python_maturin', 'pypi']
Patrick Williamsac13d5f2023-11-24 18:59:46 -0600678
679 self._test_recipe_contents(recipefile, checkvars, inherits)
680
Patrick Williams73bd93f2024-02-20 08:07:48 -0600681 def test_recipetool_create_python3_pep517_mesonpy(self):
682 # This test require python 3.11 or above for the tomllib module or tomli module to be installed
683 needTomllib(self)
684
685 # Test creating python3 package from tarball (using mesonpy class)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500686 temprecipe = os.path.join(self.tempdir, 'recipe')
687 os.makedirs(temprecipe)
Patrick Williams73bd93f2024-02-20 08:07:48 -0600688 pn = 'siphash24'
689 pv = '1.4'
690 recipefile = os.path.join(temprecipe, 'python3-%s_%s.bb' % (pn, pv))
691 srcuri = 'https://files.pythonhosted.org/packages/c2/32/b934a70592f314afcfa86c7f7e388804a8061be65b822e2aa07e573b6477/%s-%s.tar.gz' % (pn, pv)
692 result = runCmd('recipetool create -o %s %s' % (temprecipe, srcuri))
693 self.assertTrue(os.path.isfile(recipefile))
694 checkvars = {}
695 checkvars['SRC_URI[sha256sum]'] = '7fd65e39b2a7c8c4ddc3a168a687f4610751b0ac2ebb518783c0cdfc30bec4a0'
696 inherits = ['python_mesonpy', 'pypi']
697
698 self._test_recipe_contents(recipefile, checkvars, inherits)
699
700 def test_recipetool_create_github_tarball(self):
701 # Basic test to ensure github URL mangling doesn't apply to release tarballs.
702 # Deliberately use an older release of Meson at present so we don't need a toml parser.
703 temprecipe = os.path.join(self.tempdir, 'recipe')
704 os.makedirs(temprecipe)
705 pv = '0.52.1'
Patrick Williamsac13d5f2023-11-24 18:59:46 -0600706 recipefile = os.path.join(temprecipe, 'python3-meson_%s.bb' % pv)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500707 srcuri = 'https://github.com/mesonbuild/meson/releases/download/%s/meson-%s.tar.gz' % (pv, pv)
708 result = runCmd('recipetool create -o %s %s' % (temprecipe, srcuri))
709 self.assertTrue(os.path.isfile(recipefile))
710 checkvars = {}
711 checkvars['LICENSE'] = set(['Apache-2.0'])
712 checkvars['SRC_URI'] = 'https://github.com/mesonbuild/meson/releases/download/${PV}/meson-${PV}.tar.gz'
Brad Bishop15ae2502019-06-18 21:44:24 -0400713 inherits = ['setuptools3']
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500714 self._test_recipe_contents(recipefile, checkvars, inherits)
715
Andrew Geissler595f6302022-01-24 19:11:47 +0000716 def _test_recipetool_create_git(self, srcuri, branch=None):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500717 # Basic test to check http git URL mangling works
718 temprecipe = os.path.join(self.tempdir, 'recipe')
719 os.makedirs(temprecipe)
Andrew Geissler595f6302022-01-24 19:11:47 +0000720 name = srcuri.split(';')[0].split('/')[-1]
721 recipefile = os.path.join(temprecipe, name + '_git.bb')
722 options = ' -B %s' % branch if branch else ''
723 result = runCmd('recipetool create -o %s%s "%s"' % (temprecipe, options, srcuri))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500724 self.assertTrue(os.path.isfile(recipefile))
725 checkvars = {}
Andrew Geissler595f6302022-01-24 19:11:47 +0000726 checkvars['SRC_URI'] = srcuri
727 for scheme in ['http', 'https']:
728 if srcuri.startswith(scheme + ":"):
729 checkvars['SRC_URI'] = 'git%s;protocol=%s' % (srcuri[len(scheme):], scheme)
730 if ';branch=' not in srcuri:
731 checkvars['SRC_URI'] += ';branch=' + (branch or 'master')
732 self._test_recipe_contents(recipefile, checkvars, [])
733
734 def test_recipetool_create_git_http(self):
735 self._test_recipetool_create_git('http://git.yoctoproject.org/git/matchbox-keyboard')
736
737 def test_recipetool_create_git_srcuri_master(self):
Andrew Geissler028142b2023-05-05 11:29:21 -0500738 self._test_recipetool_create_git('git://git.yoctoproject.org/matchbox-keyboard;branch=master;protocol=https')
Andrew Geissler595f6302022-01-24 19:11:47 +0000739
740 def test_recipetool_create_git_srcuri_branch(self):
Andrew Geissler028142b2023-05-05 11:29:21 -0500741 self._test_recipetool_create_git('git://git.yoctoproject.org/matchbox-keyboard;branch=matchbox-keyboard-0-1;protocol=https')
Andrew Geissler595f6302022-01-24 19:11:47 +0000742
743 def test_recipetool_create_git_srcbranch(self):
Andrew Geissler028142b2023-05-05 11:29:21 -0500744 self._test_recipetool_create_git('git://git.yoctoproject.org/matchbox-keyboard;protocol=https', 'matchbox-keyboard-0-1')
Andrew Geissler595f6302022-01-24 19:11:47 +0000745
Patrick Williams56b44a92024-01-19 08:49:29 -0600746 def _go_urifiy(self, url, version, modulepath = None, pathmajor = None, subdir = None):
747 modulepath = ",path='%s'" % modulepath if len(modulepath) else ''
748 pathmajor = ",pathmajor='%s'" % pathmajor if len(pathmajor) else ''
749 subdir = ",subdir='%s'" % subdir if len(subdir) else ''
750 return "${@go_src_uri('%s','%s'%s%s%s)}" % (url, version, modulepath, pathmajor, subdir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500751
Patrick Williamsac13d5f2023-11-24 18:59:46 -0600752 def test_recipetool_create_go(self):
753 # Basic test to check go recipe generation
Patrick Williamsac13d5f2023-11-24 18:59:46 -0600754 temprecipe = os.path.join(self.tempdir, 'recipe')
755 os.makedirs(temprecipe)
756
757 recipefile = os.path.join(temprecipe, 'edgex-go_git.bb')
758 deps_require_file = os.path.join(temprecipe, 'edgex-go', 'edgex-go-modules.inc')
759 lics_require_file = os.path.join(temprecipe, 'edgex-go', 'edgex-go-licenses.inc')
760 modules_txt_file = os.path.join(temprecipe, 'edgex-go', 'modules.txt')
761
762 srcuri = 'https://github.com/edgexfoundry/edgex-go.git'
763 srcrev = "v3.0.0"
764 srcbranch = "main"
765
766 result = runCmd('recipetool create -o %s %s -S %s -B %s' % (temprecipe, srcuri, srcrev, srcbranch))
767
768 self.maxDiff = None
769 inherits = ['go-vendor']
770
771 checkvars = {}
772 checkvars['GO_IMPORT'] = "github.com/edgexfoundry/edgex-go"
773 checkvars['SRC_URI'] = {'git://${GO_IMPORT};destsuffix=git/src/${GO_IMPORT};nobranch=1;name=${BPN};protocol=https',
774 'file://modules.txt'}
775 checkvars['LIC_FILES_CHKSUM'] = {'file://src/${GO_IMPORT}/LICENSE;md5=8f8bc924cf73f6a32381e5fd4c58d603'}
776
777 self.assertTrue(os.path.isfile(recipefile))
778 self._test_recipe_contents(recipefile, checkvars, inherits)
779
780 checkvars = {}
781 checkvars['VENDORED_LIC_FILES_CHKSUM'] = set(
782 ['file://src/${GO_IMPORT}/vendor/github.com/Microsoft/go-winio/LICENSE;md5=69205ff73858f2c22b2ca135b557e8ef',
783 'file://src/${GO_IMPORT}/vendor/github.com/armon/go-metrics/LICENSE;md5=d2d77030c0183e3d1e66d26dc1f243be',
784 'file://src/${GO_IMPORT}/vendor/github.com/cenkalti/backoff/LICENSE;md5=1571d94433e3f3aa05267efd4dbea68b',
785 'file://src/${GO_IMPORT}/vendor/github.com/davecgh/go-spew/LICENSE;md5=c06795ed54b2a35ebeeb543cd3a73e56',
786 'file://src/${GO_IMPORT}/vendor/github.com/eclipse/paho.mqtt.golang/LICENSE;md5=dcdb33474b60c38efd27356d8f2edec7',
787 'file://src/${GO_IMPORT}/vendor/github.com/eclipse/paho.mqtt.golang/edl-v10;md5=3adfcc70f5aeb7a44f3f9b495aa1fbf3',
788 'file://src/${GO_IMPORT}/vendor/github.com/edgexfoundry/go-mod-bootstrap/v3/LICENSE;md5=0d6dae39976133b2851fba4c1e1275ff',
789 'file://src/${GO_IMPORT}/vendor/github.com/edgexfoundry/go-mod-configuration/v3/LICENSE;md5=0d6dae39976133b2851fba4c1e1275ff',
790 'file://src/${GO_IMPORT}/vendor/github.com/edgexfoundry/go-mod-core-contracts/v3/LICENSE;md5=0d6dae39976133b2851fba4c1e1275ff',
791 'file://src/${GO_IMPORT}/vendor/github.com/edgexfoundry/go-mod-messaging/v3/LICENSE;md5=0d6dae39976133b2851fba4c1e1275ff',
792 'file://src/${GO_IMPORT}/vendor/github.com/edgexfoundry/go-mod-registry/v3/LICENSE;md5=0d6dae39976133b2851fba4c1e1275ff',
793 'file://src/${GO_IMPORT}/vendor/github.com/edgexfoundry/go-mod-secrets/v3/LICENSE;md5=f9fa2f4f8e0ef8cc7b5dd150963eb457',
794 'file://src/${GO_IMPORT}/vendor/github.com/fatih/color/LICENSE.md;md5=316e6d590bdcde7993fb175662c0dd5a',
795 'file://src/${GO_IMPORT}/vendor/github.com/fxamacker/cbor/v2/LICENSE;md5=827f5a2fa861382d35a3943adf9ebb86',
796 'file://src/${GO_IMPORT}/vendor/github.com/go-jose/go-jose/v3/LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57',
797 'file://src/${GO_IMPORT}/vendor/github.com/go-jose/go-jose/v3/json/LICENSE;md5=591778525c869cdde0ab5a1bf283cd81',
798 'file://src/${GO_IMPORT}/vendor/github.com/go-kit/log/LICENSE;md5=5b7c15ad5fffe2ff6e9d58a6c161f082',
799 'file://src/${GO_IMPORT}/vendor/github.com/go-logfmt/logfmt/LICENSE;md5=98e39517c38127f969de33057067091e',
800 'file://src/${GO_IMPORT}/vendor/github.com/go-playground/locales/LICENSE;md5=3ccbda375ee345400ad1da85ba522301',
801 'file://src/${GO_IMPORT}/vendor/github.com/go-playground/universal-translator/LICENSE;md5=2e2b21ef8f61057977d27c727c84bef1',
802 'file://src/${GO_IMPORT}/vendor/github.com/go-playground/validator/v10/LICENSE;md5=a718a0f318d76f7c5d510cbae84f0b60',
803 'file://src/${GO_IMPORT}/vendor/github.com/go-redis/redis/v7/LICENSE;md5=58103aa5ea1ee9b7a369c9c4a95ef9b5',
804 'file://src/${GO_IMPORT}/vendor/github.com/golang/protobuf/LICENSE;md5=939cce1ec101726fa754e698ac871622',
805 'file://src/${GO_IMPORT}/vendor/github.com/gomodule/redigo/LICENSE;md5=2ee41112a44fe7014dce33e26468ba93',
806 'file://src/${GO_IMPORT}/vendor/github.com/google/uuid/LICENSE;md5=88073b6dd8ec00fe09da59e0b6dfded1',
807 'file://src/${GO_IMPORT}/vendor/github.com/gorilla/mux/LICENSE;md5=33fa1116c45f9e8de714033f99edde13',
808 'file://src/${GO_IMPORT}/vendor/github.com/gorilla/websocket/LICENSE;md5=c007b54a1743d596f46b2748d9f8c044',
809 'file://src/${GO_IMPORT}/vendor/github.com/hashicorp/consul/api/LICENSE;md5=b8a277a612171b7526e9be072f405ef4',
810 'file://src/${GO_IMPORT}/vendor/github.com/hashicorp/errwrap/LICENSE;md5=b278a92d2c1509760384428817710378',
811 'file://src/${GO_IMPORT}/vendor/github.com/hashicorp/go-cleanhttp/LICENSE;md5=65d26fcc2f35ea6a181ac777e42db1ea',
812 'file://src/${GO_IMPORT}/vendor/github.com/hashicorp/go-hclog/LICENSE;md5=ec7f605b74b9ad03347d0a93a5cc7eb8',
813 'file://src/${GO_IMPORT}/vendor/github.com/hashicorp/go-immutable-radix/LICENSE;md5=65d26fcc2f35ea6a181ac777e42db1ea',
814 'file://src/${GO_IMPORT}/vendor/github.com/hashicorp/go-multierror/LICENSE;md5=d44fdeb607e2d2614db9464dbedd4094',
815 'file://src/${GO_IMPORT}/vendor/github.com/hashicorp/go-rootcerts/LICENSE;md5=65d26fcc2f35ea6a181ac777e42db1ea',
816 'file://src/${GO_IMPORT}/vendor/github.com/hashicorp/golang-lru/LICENSE;md5=f27a50d2e878867827842f2c60e30bfc',
817 'file://src/${GO_IMPORT}/vendor/github.com/hashicorp/serf/LICENSE;md5=b278a92d2c1509760384428817710378',
818 'file://src/${GO_IMPORT}/vendor/github.com/leodido/go-urn/LICENSE;md5=8f50db5538ec1148a9b3d14ed96c3418',
819 'file://src/${GO_IMPORT}/vendor/github.com/mattn/go-colorable/LICENSE;md5=24ce168f90aec2456a73de1839037245',
820 'file://src/${GO_IMPORT}/vendor/github.com/mattn/go-isatty/LICENSE;md5=f509beadd5a11227c27b5d2ad6c9f2c6',
821 'file://src/${GO_IMPORT}/vendor/github.com/mitchellh/consulstructure/LICENSE;md5=96ada10a9e51c98c4656f2cede08c673',
822 'file://src/${GO_IMPORT}/vendor/github.com/mitchellh/copystructure/LICENSE;md5=56da355a12d4821cda57b8f23ec34bc4',
823 'file://src/${GO_IMPORT}/vendor/github.com/mitchellh/go-homedir/LICENSE;md5=3f7765c3d4f58e1f84c4313cecf0f5bd',
824 'file://src/${GO_IMPORT}/vendor/github.com/mitchellh/mapstructure/LICENSE;md5=3f7765c3d4f58e1f84c4313cecf0f5bd',
825 'file://src/${GO_IMPORT}/vendor/github.com/mitchellh/reflectwalk/LICENSE;md5=3f7765c3d4f58e1f84c4313cecf0f5bd',
826 'file://src/${GO_IMPORT}/vendor/github.com/nats-io/nats.go/LICENSE;md5=86d3f3a95c324c9479bd8986968f4327',
827 'file://src/${GO_IMPORT}/vendor/github.com/nats-io/nkeys/LICENSE;md5=86d3f3a95c324c9479bd8986968f4327',
828 'file://src/${GO_IMPORT}/vendor/github.com/nats-io/nuid/LICENSE;md5=86d3f3a95c324c9479bd8986968f4327',
829 'file://src/${GO_IMPORT}/vendor/github.com/pmezard/go-difflib/LICENSE;md5=e9a2ebb8de779a07500ddecca806145e',
830 'file://src/${GO_IMPORT}/vendor/github.com/rcrowley/go-metrics/LICENSE;md5=1bdf5d819f50f141366dabce3be1460f',
831 'file://src/${GO_IMPORT}/vendor/github.com/spiffe/go-spiffe/v2/LICENSE;md5=86d3f3a95c324c9479bd8986968f4327',
832 'file://src/${GO_IMPORT}/vendor/github.com/stretchr/objx/LICENSE;md5=d023fd31d3ca39ec61eec65a91732735',
833 'file://src/${GO_IMPORT}/vendor/github.com/stretchr/testify/LICENSE;md5=188f01994659f3c0d310612333d2a26f',
834 'file://src/${GO_IMPORT}/vendor/github.com/x448/float16/LICENSE;md5=de8f8e025d57fe7ee0b67f30d571323b',
835 'file://src/${GO_IMPORT}/vendor/github.com/zeebo/errs/LICENSE;md5=84914ab36fc0eb48edbaa53e66e8d326',
836 'file://src/${GO_IMPORT}/vendor/golang.org/x/crypto/LICENSE;md5=5d4950ecb7b26d2c5e4e7b4e0dd74707',
837 'file://src/${GO_IMPORT}/vendor/golang.org/x/mod/LICENSE;md5=5d4950ecb7b26d2c5e4e7b4e0dd74707',
838 'file://src/${GO_IMPORT}/vendor/golang.org/x/net/LICENSE;md5=5d4950ecb7b26d2c5e4e7b4e0dd74707',
839 'file://src/${GO_IMPORT}/vendor/golang.org/x/sync/LICENSE;md5=5d4950ecb7b26d2c5e4e7b4e0dd74707',
840 'file://src/${GO_IMPORT}/vendor/golang.org/x/sys/LICENSE;md5=5d4950ecb7b26d2c5e4e7b4e0dd74707',
841 'file://src/${GO_IMPORT}/vendor/golang.org/x/text/LICENSE;md5=5d4950ecb7b26d2c5e4e7b4e0dd74707',
842 'file://src/${GO_IMPORT}/vendor/golang.org/x/tools/LICENSE;md5=5d4950ecb7b26d2c5e4e7b4e0dd74707',
843 'file://src/${GO_IMPORT}/vendor/google.golang.org/genproto/LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57',
844 'file://src/${GO_IMPORT}/vendor/google.golang.org/grpc/LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57',
845 'file://src/${GO_IMPORT}/vendor/google.golang.org/protobuf/LICENSE;md5=02d4002e9171d41a8fad93aa7faf3956',
846 'file://src/${GO_IMPORT}/vendor/gopkg.in/eapache/queue.v1/LICENSE;md5=1bfd4408d3de090ef6b908b0cc45a316',
847 'file://src/${GO_IMPORT}/vendor/gopkg.in/yaml.v3/LICENSE;md5=3c91c17266710e16afdbb2b6d15c761c'])
848
849 self.assertTrue(os.path.isfile(lics_require_file))
850 self._test_recipe_contents(lics_require_file, checkvars, [])
851
852 dependencies = \
853 [ ('github.com/eclipse/paho.mqtt.golang','v1.4.2', '', '', ''),
854 ('github.com/edgexfoundry/go-mod-bootstrap','v3.0.1','github.com/edgexfoundry/go-mod-bootstrap/v3','/v3', ''),
855 ('github.com/edgexfoundry/go-mod-configuration','v3.0.0','github.com/edgexfoundry/go-mod-configuration/v3','/v3', ''),
856 ('github.com/edgexfoundry/go-mod-core-contracts','v3.0.0','github.com/edgexfoundry/go-mod-core-contracts/v3','/v3', ''),
857 ('github.com/edgexfoundry/go-mod-messaging','v3.0.0','github.com/edgexfoundry/go-mod-messaging/v3','/v3', ''),
858 ('github.com/edgexfoundry/go-mod-secrets','v3.0.1','github.com/edgexfoundry/go-mod-secrets/v3','/v3', ''),
859 ('github.com/fxamacker/cbor','v2.4.0','github.com/fxamacker/cbor/v2','/v2', ''),
860 ('github.com/gomodule/redigo','v1.8.9', '', '', ''),
861 ('github.com/google/uuid','v1.3.0', '', '', ''),
862 ('github.com/gorilla/mux','v1.8.0', '', '', ''),
863 ('github.com/rcrowley/go-metrics','v0.0.0-20201227073835-cf1acfcdf475', '', '', ''),
864 ('github.com/spiffe/go-spiffe','v2.1.4','github.com/spiffe/go-spiffe/v2','/v2', ''),
865 ('github.com/stretchr/testify','v1.8.2', '', '', ''),
866 ('go.googlesource.com/crypto','v0.8.0','golang.org/x/crypto', '', ''),
867 ('gopkg.in/eapache/queue.v1','v1.1.0', '', '', ''),
868 ('gopkg.in/yaml.v3','v3.0.1', '', '', ''),
869 ('github.com/microsoft/go-winio','v0.6.0','github.com/Microsoft/go-winio', '', ''),
870 ('github.com/hashicorp/go-metrics','v0.3.10','github.com/armon/go-metrics', '', ''),
871 ('github.com/cenkalti/backoff','v2.2.1+incompatible', '', '', ''),
872 ('github.com/davecgh/go-spew','v1.1.1', '', '', ''),
873 ('github.com/edgexfoundry/go-mod-registry','v3.0.0','github.com/edgexfoundry/go-mod-registry/v3','/v3', ''),
874 ('github.com/fatih/color','v1.9.0', '', '', ''),
875 ('github.com/go-jose/go-jose','v3.0.0','github.com/go-jose/go-jose/v3','/v3', ''),
876 ('github.com/go-kit/log','v0.2.1', '', '', ''),
877 ('github.com/go-logfmt/logfmt','v0.5.1', '', '', ''),
878 ('github.com/go-playground/locales','v0.14.1', '', '', ''),
879 ('github.com/go-playground/universal-translator','v0.18.1', '', '', ''),
880 ('github.com/go-playground/validator','v10.13.0','github.com/go-playground/validator/v10','/v10', ''),
881 ('github.com/go-redis/redis','v7.3.0','github.com/go-redis/redis/v7','/v7', ''),
882 ('github.com/golang/protobuf','v1.5.2', '', '', ''),
883 ('github.com/gorilla/websocket','v1.4.2', '', '', ''),
884 ('github.com/hashicorp/consul','v1.20.0','github.com/hashicorp/consul/api', '', 'api'),
885 ('github.com/hashicorp/errwrap','v1.0.0', '', '', ''),
886 ('github.com/hashicorp/go-cleanhttp','v0.5.1', '', '', ''),
887 ('github.com/hashicorp/go-hclog','v0.14.1', '', '', ''),
888 ('github.com/hashicorp/go-immutable-radix','v1.3.0', '', '', ''),
889 ('github.com/hashicorp/go-multierror','v1.1.1', '', '', ''),
890 ('github.com/hashicorp/go-rootcerts','v1.0.2', '', '', ''),
891 ('github.com/hashicorp/golang-lru','v0.5.4', '', '', ''),
892 ('github.com/hashicorp/serf','v0.10.1', '', '', ''),
893 ('github.com/leodido/go-urn','v1.2.3', '', '', ''),
894 ('github.com/mattn/go-colorable','v0.1.12', '', '', ''),
895 ('github.com/mattn/go-isatty','v0.0.14', '', '', ''),
896 ('github.com/mitchellh/consulstructure','v0.0.0-20190329231841-56fdc4d2da54', '', '', ''),
897 ('github.com/mitchellh/copystructure','v1.2.0', '', '', ''),
898 ('github.com/mitchellh/go-homedir','v1.1.0', '', '', ''),
899 ('github.com/mitchellh/mapstructure','v1.5.0', '', '', ''),
900 ('github.com/mitchellh/reflectwalk','v1.0.2', '', '', ''),
901 ('github.com/nats-io/nats.go','v1.25.0', '', '', ''),
902 ('github.com/nats-io/nkeys','v0.4.4', '', '', ''),
903 ('github.com/nats-io/nuid','v1.0.1', '', '', ''),
904 ('github.com/pmezard/go-difflib','v1.0.0', '', '', ''),
905 ('github.com/stretchr/objx','v0.5.0', '', '', ''),
906 ('github.com/x448/float16','v0.8.4', '', '', ''),
907 ('github.com/zeebo/errs','v1.3.0', '', '', ''),
908 ('go.googlesource.com/mod','v0.8.0','golang.org/x/mod', '', ''),
909 ('go.googlesource.com/net','v0.9.0','golang.org/x/net', '', ''),
910 ('go.googlesource.com/sync','v0.1.0','golang.org/x/sync', '', ''),
911 ('go.googlesource.com/sys','v0.7.0','golang.org/x/sys', '', ''),
912 ('go.googlesource.com/text','v0.9.0','golang.org/x/text', '', ''),
913 ('go.googlesource.com/tools','v0.6.0','golang.org/x/tools', '', ''),
914 ('github.com/googleapis/go-genproto','v0.0.0-20230223222841-637eb2293923','google.golang.org/genproto', '', ''),
915 ('github.com/grpc/grpc-go','v1.53.0','google.golang.org/grpc', '', ''),
916 ('go.googlesource.com/protobuf','v1.28.1','google.golang.org/protobuf', '', ''),
917 ]
918
919 src_uri = set()
920 for d in dependencies:
Patrick Williams56b44a92024-01-19 08:49:29 -0600921 src_uri.add(self._go_urifiy(*d))
Patrick Williamsac13d5f2023-11-24 18:59:46 -0600922
923 checkvars = {}
924 checkvars['GO_DEPENDENCIES_SRC_URI'] = src_uri
925
926 self.assertTrue(os.path.isfile(deps_require_file))
927 self._test_recipe_contents(deps_require_file, checkvars, [])
928
Patrick Williams56b44a92024-01-19 08:49:29 -0600929 def test_recipetool_create_go_replace_modules(self):
930 # Check handling of replaced modules
931 temprecipe = os.path.join(self.tempdir, 'recipe')
932 os.makedirs(temprecipe)
Patrick Williamsac13d5f2023-11-24 18:59:46 -0600933
Patrick Williams56b44a92024-01-19 08:49:29 -0600934 recipefile = os.path.join(temprecipe, 'openapi-generator_git.bb')
935 deps_require_file = os.path.join(temprecipe, 'openapi-generator', 'go-modules.inc')
936 lics_require_file = os.path.join(temprecipe, 'openapi-generator', 'go-licenses.inc')
937 modules_txt_file = os.path.join(temprecipe, 'openapi-generator', 'modules.txt')
938
939 srcuri = 'https://github.com/OpenAPITools/openapi-generator.git'
940 srcrev = "v7.2.0"
941 srcbranch = "master"
942 srcsubdir = "samples/openapi3/client/petstore/go"
943
944 result = runCmd('recipetool create -o %s %s -S %s -B %s --src-subdir %s' % (temprecipe, srcuri, srcrev, srcbranch, srcsubdir))
945
946 self.maxDiff = None
947 inherits = ['go-vendor']
948
949 checkvars = {}
950 checkvars['GO_IMPORT'] = "github.com/OpenAPITools/openapi-generator/samples/openapi3/client/petstore/go"
951 checkvars['SRC_URI'] = {'git://${GO_IMPORT};destsuffix=git/src/${GO_IMPORT};nobranch=1;name=${BPN};protocol=https',
952 'file://modules.txt'}
953
954 self.assertNotIn('Traceback', result.output)
955 self.assertIn('No license file was detected for the main module', result.output)
956 self.assertTrue(os.path.isfile(recipefile))
957 self._test_recipe_contents(recipefile, checkvars, inherits)
958
959 # make sure that dependencies don't mention local directory ./go-petstore
960 dependencies = \
961 [ ('github.com/stretchr/testify','v1.8.4', '', '', ''),
962 ('go.googlesource.com/oauth2','v0.10.0','golang.org/x/oauth2', '', ''),
963 ('github.com/davecgh/go-spew','v1.1.1', '', '', ''),
964 ('github.com/golang/protobuf','v1.5.3', '', '', ''),
965 ('github.com/kr/pretty','v0.3.0', '', '', ''),
966 ('github.com/pmezard/go-difflib','v1.0.0', '', '', ''),
967 ('github.com/rogpeppe/go-internal','v1.9.0', '', '', ''),
968 ('go.googlesource.com/net','v0.12.0','golang.org/x/net', '', ''),
969 ('github.com/golang/appengine','v1.6.7','google.golang.org/appengine', '', ''),
970 ('go.googlesource.com/protobuf','v1.31.0','google.golang.org/protobuf', '', ''),
971 ('gopkg.in/check.v1','v1.0.0-20201130134442-10cb98267c6c', '', '', ''),
972 ('gopkg.in/yaml.v3','v3.0.1', '', '', ''),
973 ]
974
975 src_uri = set()
976 for d in dependencies:
977 src_uri.add(self._go_urifiy(*d))
978
979 checkvars = {}
980 checkvars['GO_DEPENDENCIES_SRC_URI'] = src_uri
981
982 self.assertTrue(os.path.isfile(deps_require_file))
983 self._test_recipe_contents(deps_require_file, checkvars, [])
984
985class RecipetoolTests(RecipetoolBase):
986
987 @classmethod
988 def setUpClass(cls):
989 import sys
990
991 super(RecipetoolTests, cls).setUpClass()
992 bb_vars = get_bb_vars(['BBPATH'])
993 cls.bbpath = bb_vars['BBPATH']
994 libpath = os.path.join(get_bb_var('COREBASE'), 'scripts', 'lib', 'recipetool')
995 sys.path.insert(0, libpath)
Patrick Williams169d7bc2024-01-05 11:33:25 -0600996
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500997 def _copy_file_with_cleanup(self, srcfile, basedstdir, *paths):
998 dstdir = basedstdir
999 self.assertTrue(os.path.exists(dstdir))
1000 for p in paths:
1001 dstdir = os.path.join(dstdir, p)
1002 if not os.path.exists(dstdir):
Patrick Williams169d7bc2024-01-05 11:33:25 -06001003 try:
1004 os.makedirs(dstdir)
1005 except PermissionError:
1006 return False
1007 except OSError as e:
1008 if e.errno == errno.EROFS:
1009 return False
1010 else:
1011 raise e
Andrew Geissler475cb722020-07-10 16:00:51 -05001012 if p == "lib":
1013 # Can race with other tests
1014 self.add_command_to_tearDown('rmdir --ignore-fail-on-non-empty %s' % dstdir)
1015 else:
1016 self.track_for_cleanup(dstdir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001017 dstfile = os.path.join(dstdir, os.path.basename(srcfile))
1018 if srcfile != dstfile:
Patrick Williams169d7bc2024-01-05 11:33:25 -06001019 try:
1020 shutil.copy(srcfile, dstfile)
1021 except PermissionError:
1022 return False
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001023 self.track_for_cleanup(dstfile)
Patrick Williams169d7bc2024-01-05 11:33:25 -06001024 return True
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001025
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001026 def test_recipetool_load_plugin(self):
1027 """Test that recipetool loads only the first found plugin in BBPATH."""
1028
1029 recipetool = runCmd("which recipetool")
1030 fromname = runCmd("recipetool --quiet pluginfile")
1031 srcfile = fromname.output
1032 searchpath = self.bbpath.split(':') + [os.path.dirname(recipetool.output)]
1033 plugincontent = []
1034 with open(srcfile) as fh:
1035 plugincontent = fh.readlines()
1036 try:
1037 self.assertIn('meta-selftest', srcfile, 'wrong bbpath plugin found')
Patrick Williams169d7bc2024-01-05 11:33:25 -06001038 searchpath = [
1039 path for path in searchpath
1040 if self._copy_file_with_cleanup(srcfile, path, 'lib', 'recipetool')
1041 ]
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001042 result = runCmd("recipetool --quiet count")
1043 self.assertEqual(result.output, '1')
1044 result = runCmd("recipetool --quiet multiloaded")
1045 self.assertEqual(result.output, "no")
1046 for path in searchpath:
1047 result = runCmd("recipetool --quiet bbdir")
Patrick Williams169d7bc2024-01-05 11:33:25 -06001048 self.assertEqual(os.path.realpath(result.output), os.path.realpath(path))
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001049 os.unlink(os.path.join(result.output, 'lib', 'recipetool', 'bbpath.py'))
1050 finally:
1051 with open(srcfile, 'w') as fh:
1052 fh.writelines(plugincontent)
1053
Andrew Geissler595f6302022-01-24 19:11:47 +00001054 def test_recipetool_handle_license_vars(self):
1055 from create import handle_license_vars
1056 from unittest.mock import Mock
1057
1058 commonlicdir = get_bb_var('COMMON_LICENSE_DIR')
1059
Andrew Geisslerfc113ea2023-03-31 09:59:46 -05001060 class DataConnectorCopy(bb.tinfoil.TinfoilDataStoreConnector):
1061 pass
1062
1063 d = DataConnectorCopy
Andrew Geissler595f6302022-01-24 19:11:47 +00001064 d.getVar = Mock(return_value=commonlicdir)
1065
1066 srctree = tempfile.mkdtemp(prefix='recipetoolqa')
1067 self.track_for_cleanup(srctree)
1068
1069 # Multiple licenses
1070 licenses = ['MIT', 'ISC', 'BSD-3-Clause', 'Apache-2.0']
1071 for licence in licenses:
1072 shutil.copy(os.path.join(commonlicdir, licence), os.path.join(srctree, 'LICENSE.' + licence))
1073 # Duplicate license
1074 shutil.copy(os.path.join(commonlicdir, 'MIT'), os.path.join(srctree, 'LICENSE'))
1075
1076 extravalues = {
1077 # Duplicate and missing licenses
1078 'LICENSE': 'Zlib & BSD-2-Clause & Zlib',
1079 'LIC_FILES_CHKSUM': [
1080 'file://README.md;md5=0123456789abcdef0123456789abcd'
1081 ]
1082 }
1083 lines_before = []
1084 handled = []
1085 licvalues = handle_license_vars(srctree, lines_before, handled, extravalues, d)
1086 expected_lines_before = [
1087 '# WARNING: the following LICENSE and LIC_FILES_CHKSUM values are best guesses - it is',
1088 '# your responsibility to verify that the values are complete and correct.',
1089 '# NOTE: Original package / source metadata indicates license is: BSD-2-Clause & Zlib',
1090 '#',
1091 '# NOTE: multiple licenses have been detected; they have been separated with &',
1092 '# in the LICENSE value for now since it is a reasonable assumption that all',
1093 '# of the licenses apply. If instead there is a choice between the multiple',
1094 '# licenses then you should change the value to separate the licenses with |',
1095 '# instead of &. If there is any doubt, check the accompanying documentation',
1096 '# to determine which situation is applicable.',
1097 'LICENSE = "Apache-2.0 & BSD-2-Clause & BSD-3-Clause & ISC & MIT & Zlib"',
1098 'LIC_FILES_CHKSUM = "file://LICENSE;md5=0835ade698e0bcf8506ecda2f7b4f302 \\\n'
1099 ' file://LICENSE.Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10 \\\n'
1100 ' file://LICENSE.BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9 \\\n'
1101 ' file://LICENSE.ISC;md5=f3b90e78ea0cffb20bf5cca7947a896d \\\n'
1102 ' file://LICENSE.MIT;md5=0835ade698e0bcf8506ecda2f7b4f302 \\\n'
1103 ' file://README.md;md5=0123456789abcdef0123456789abcd"',
1104 ''
1105 ]
1106 self.assertEqual(lines_before, expected_lines_before)
1107 expected_licvalues = [
1108 ('MIT', 'LICENSE', '0835ade698e0bcf8506ecda2f7b4f302'),
1109 ('Apache-2.0', 'LICENSE.Apache-2.0', '89aea4e17d99a7cacdbeed46a0096b10'),
1110 ('BSD-3-Clause', 'LICENSE.BSD-3-Clause', '550794465ba0ec5312d6919e203a55f9'),
1111 ('ISC', 'LICENSE.ISC', 'f3b90e78ea0cffb20bf5cca7947a896d'),
1112 ('MIT', 'LICENSE.MIT', '0835ade698e0bcf8506ecda2f7b4f302')
1113 ]
1114 self.assertEqual(handled, [('license', expected_licvalues)])
1115 self.assertEqual(extravalues, {})
1116 self.assertEqual(licvalues, expected_licvalues)
1117
1118
1119 def test_recipetool_split_pkg_licenses(self):
1120 from create import split_pkg_licenses
1121 licvalues = [
1122 # Duplicate licenses
1123 ('BSD-2-Clause', 'x/COPYING', None),
1124 ('BSD-2-Clause', 'x/LICENSE', None),
1125 # Multiple licenses
1126 ('MIT', 'x/a/LICENSE.MIT', None),
1127 ('ISC', 'x/a/LICENSE.ISC', None),
1128 # Alternative licenses
1129 ('(MIT | ISC)', 'x/b/LICENSE', None),
1130 # Alternative licenses without brackets
1131 ('MIT | BSD-2-Clause', 'x/c/LICENSE', None),
1132 # Multi licenses with alternatives
1133 ('MIT', 'x/d/COPYING', None),
1134 ('MIT | BSD-2-Clause', 'x/d/LICENSE', None),
1135 # Multi licenses with alternatives and brackets
1136 ('Apache-2.0 & ((MIT | ISC) & BSD-3-Clause)', 'x/e/LICENSE', None)
1137 ]
1138 packages = {
1139 '${PN}': '',
1140 'a': 'x/a',
1141 'b': 'x/b',
1142 'c': 'x/c',
1143 'd': 'x/d',
1144 'e': 'x/e',
1145 'f': 'x/f',
1146 'g': 'x/g',
1147 }
1148 fallback_licenses = {
1149 # Ignored
1150 'a': 'BSD-3-Clause',
1151 # Used
1152 'f': 'BSD-3-Clause'
1153 }
1154 outlines = []
1155 outlicenses = split_pkg_licenses(licvalues, packages, outlines, fallback_licenses)
1156 expected_outlicenses = {
1157 '${PN}': ['BSD-2-Clause'],
1158 'a': ['ISC', 'MIT'],
1159 'b': ['(ISC | MIT)'],
1160 'c': ['(BSD-2-Clause | MIT)'],
1161 'd': ['(BSD-2-Clause | MIT)', 'MIT'],
1162 'e': ['(ISC | MIT)', 'Apache-2.0', 'BSD-3-Clause'],
1163 'f': ['BSD-3-Clause'],
1164 'g': ['Unknown']
1165 }
1166 self.assertEqual(outlicenses, expected_outlicenses)
1167 expected_outlines = [
1168 'LICENSE:${PN} = "BSD-2-Clause"',
1169 'LICENSE:a = "ISC & MIT"',
1170 'LICENSE:b = "(ISC | MIT)"',
1171 'LICENSE:c = "(BSD-2-Clause | MIT)"',
1172 'LICENSE:d = "(BSD-2-Clause | MIT) & MIT"',
1173 'LICENSE:e = "(ISC | MIT) & Apache-2.0 & BSD-3-Clause"',
1174 'LICENSE:f = "BSD-3-Clause"',
1175 'LICENSE:g = "Unknown"'
1176 ]
1177 self.assertEqual(outlines, expected_outlines)
1178
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001179
1180class RecipetoolAppendsrcBase(RecipetoolBase):
1181 def _try_recipetool_appendsrcfile(self, testrecipe, newfile, destfile, options, expectedlines, expectedfiles):
1182 cmd = 'recipetool appendsrcfile %s %s %s %s %s' % (options, self.templayerdir, testrecipe, newfile, destfile)
1183 return self._try_recipetool_appendcmd(cmd, testrecipe, expectedfiles, expectedlines)
1184
1185 def _try_recipetool_appendsrcfiles(self, testrecipe, newfiles, expectedlines=None, expectedfiles=None, destdir=None, options=''):
1186
1187 if destdir:
1188 options += ' -D %s' % destdir
1189
1190 if expectedfiles is None:
1191 expectedfiles = [os.path.basename(f) for f in newfiles]
1192
1193 cmd = 'recipetool appendsrcfiles %s %s %s %s' % (options, self.templayerdir, testrecipe, ' '.join(newfiles))
1194 return self._try_recipetool_appendcmd(cmd, testrecipe, expectedfiles, expectedlines)
1195
1196 def _try_recipetool_appendsrcfile_fail(self, testrecipe, newfile, destfile, checkerror):
1197 cmd = 'recipetool appendsrcfile %s %s %s %s' % (self.templayerdir, testrecipe, newfile, destfile or '')
1198 result = runCmd(cmd, ignore_status=True)
1199 self.assertNotEqual(result.status, 0, 'Command "%s" should have failed but didn\'t' % cmd)
1200 self.assertNotIn('Traceback', result.output)
1201 for errorstr in checkerror:
1202 self.assertIn(errorstr, result.output)
1203
1204 @staticmethod
1205 def _get_first_file_uri(recipe):
1206 '''Return the first file:// in SRC_URI for the specified recipe.'''
1207 src_uri = get_bb_var('SRC_URI', recipe).split()
1208 for uri in src_uri:
1209 p = urllib.parse.urlparse(uri)
1210 if p.scheme == 'file':
Patrick Williams169d7bc2024-01-05 11:33:25 -06001211 return p.netloc + p.path, uri
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001212
Patrick Williams169d7bc2024-01-05 11:33:25 -06001213 def _test_appendsrcfile(self, testrecipe, filename=None, destdir=None, has_src_uri=True, srcdir=None, newfile=None, remove=None, machine=None , options=''):
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001214 if newfile is None:
1215 newfile = self.testfile
1216
1217 if srcdir:
1218 if destdir:
1219 expected_subdir = os.path.join(srcdir, destdir)
1220 else:
1221 expected_subdir = srcdir
1222 else:
1223 options += " -W"
1224 expected_subdir = destdir
1225
1226 if filename:
1227 if destdir:
1228 destpath = os.path.join(destdir, filename)
1229 else:
1230 destpath = filename
1231 else:
1232 filename = os.path.basename(newfile)
1233 if destdir:
1234 destpath = destdir + os.sep
1235 else:
1236 destpath = '.' + os.sep
1237
Patrick Williams213cb262021-08-07 19:21:33 -05001238 expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001239 '\n']
Patrick Williams169d7bc2024-01-05 11:33:25 -06001240
1241 override = ""
1242 if machine:
1243 options += ' -m %s' % machine
1244 override = ':append:%s' % machine
1245 expectedlines.extend(['PACKAGE_ARCH = "${MACHINE_ARCH}"\n',
1246 '\n'])
1247
1248 if remove:
1249 for entry in remove:
1250 if machine:
1251 entry_remove_line = 'SRC_URI:remove:%s = " %s"\n' % (machine, entry)
1252 else:
1253 entry_remove_line = 'SRC_URI:remove = "%s"\n' % entry
1254
1255 expectedlines.extend([entry_remove_line,
1256 '\n'])
1257
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001258 if has_src_uri:
1259 uri = 'file://%s' % filename
1260 if expected_subdir:
1261 uri += ';subdir=%s' % expected_subdir
Patrick Williams169d7bc2024-01-05 11:33:25 -06001262 if machine:
1263 src_uri_line = 'SRC_URI%s = " %s"\n' % (override, uri)
1264 else:
1265 src_uri_line = 'SRC_URI += "%s"\n' % uri
1266
1267 expectedlines.extend([src_uri_line, '\n'])
1268
1269 with open("/tmp/tmp.txt", "w") as file:
1270 print(expectedlines, file=file)
1271
1272 if machine:
1273 filename = '%s/%s' % (machine, filename)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001274
1275 return self._try_recipetool_appendsrcfile(testrecipe, newfile, destpath, options, expectedlines, [filename])
1276
1277 def _test_appendsrcfiles(self, testrecipe, newfiles, expectedfiles=None, destdir=None, options=''):
1278 if expectedfiles is None:
1279 expectedfiles = [os.path.basename(n) for n in newfiles]
1280
1281 self._try_recipetool_appendsrcfiles(testrecipe, newfiles, expectedfiles=expectedfiles, destdir=destdir, options=options)
1282
1283 bb_vars = get_bb_vars(['SRC_URI', 'FILE', 'FILESEXTRAPATHS'], testrecipe)
1284 src_uri = bb_vars['SRC_URI'].split()
1285 for f in expectedfiles:
1286 if destdir:
1287 self.assertIn('file://%s;subdir=%s' % (f, destdir), src_uri)
1288 else:
1289 self.assertIn('file://%s' % f, src_uri)
1290
1291 recipefile = bb_vars['FILE']
1292 bbappendfile = self._check_bbappend(testrecipe, recipefile, self.templayerdir)
1293 filesdir = os.path.join(os.path.dirname(bbappendfile), testrecipe)
1294 filesextrapaths = bb_vars['FILESEXTRAPATHS'].split(':')
1295 self.assertIn(filesdir, filesextrapaths)
1296
1297
1298
1299
1300class RecipetoolAppendsrcTests(RecipetoolAppendsrcBase):
1301
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001302 def test_recipetool_appendsrcfile_basic(self):
1303 self._test_appendsrcfile('base-files', 'a-file')
1304
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001305 def test_recipetool_appendsrcfile_basic_wildcard(self):
1306 testrecipe = 'base-files'
1307 self._test_appendsrcfile(testrecipe, 'a-file', options='-w')
1308 recipefile = get_bb_var('FILE', testrecipe)
1309 bbappendfile = self._check_bbappend(testrecipe, recipefile, self.templayerdir)
1310 self.assertEqual(os.path.basename(bbappendfile), '%s_%%.bbappend' % testrecipe)
1311
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001312 def test_recipetool_appendsrcfile_subdir_basic(self):
1313 self._test_appendsrcfile('base-files', 'a-file', 'tmp')
1314
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001315 def test_recipetool_appendsrcfile_subdir_basic_dirdest(self):
1316 self._test_appendsrcfile('base-files', destdir='tmp')
1317
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001318 def test_recipetool_appendsrcfile_srcdir_basic(self):
1319 testrecipe = 'bash'
1320 bb_vars = get_bb_vars(['S', 'WORKDIR'], testrecipe)
1321 srcdir = bb_vars['S']
1322 workdir = bb_vars['WORKDIR']
1323 subdir = os.path.relpath(srcdir, workdir)
1324 self._test_appendsrcfile(testrecipe, 'a-file', srcdir=subdir)
1325
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001326 def test_recipetool_appendsrcfile_existing_in_src_uri(self):
1327 testrecipe = 'base-files'
Patrick Williams169d7bc2024-01-05 11:33:25 -06001328 filepath,_ = self._get_first_file_uri(testrecipe)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001329 self.assertTrue(filepath, 'Unable to test, no file:// uri found in SRC_URI for %s' % testrecipe)
1330 self._test_appendsrcfile(testrecipe, filepath, has_src_uri=False)
1331
Patrick Williams169d7bc2024-01-05 11:33:25 -06001332 def test_recipetool_appendsrcfile_existing_in_src_uri_diff_params(self, machine=None):
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001333 testrecipe = 'base-files'
1334 subdir = 'tmp'
Patrick Williams169d7bc2024-01-05 11:33:25 -06001335 filepath, srcuri_entry = self._get_first_file_uri(testrecipe)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001336 self.assertTrue(filepath, 'Unable to test, no file:// uri found in SRC_URI for %s' % testrecipe)
1337
Patrick Williams169d7bc2024-01-05 11:33:25 -06001338 self._test_appendsrcfile(testrecipe, filepath, subdir, machine=machine, remove=[srcuri_entry])
1339
1340 def test_recipetool_appendsrcfile_machine(self):
1341 # A very basic test
1342 self._test_appendsrcfile('base-files', 'a-file', machine='mymachine')
1343
1344 # Force cleaning the output of previous test
1345 self.tearDownLocal()
1346
1347 # A more complex test: existing entry in src_uri with different param
1348 self.test_recipetool_appendsrcfile_existing_in_src_uri_diff_params(machine='mymachine')
1349
1350 def test_recipetool_appendsrcfile_update_recipe_basic(self):
1351 testrecipe = "mtd-utils-selftest"
1352 recipefile = get_bb_var('FILE', testrecipe)
1353 self.assertIn('meta-selftest', recipefile, 'This test expect %s recipe to be in meta-selftest')
1354 cmd = 'recipetool appendsrcfile -W -u meta-selftest %s %s' % (testrecipe, self.testfile)
1355 result = runCmd(cmd)
1356 self.assertNotIn('Traceback', result.output)
1357 self.add_command_to_tearDown('cd %s; rm -f %s/%s; git checkout .' % (os.path.dirname(recipefile), testrecipe, os.path.basename(self.testfile)))
1358
1359 expected_status = [(' M', '.*/%s$' % os.path.basename(recipefile)),
1360 ('??', '.*/%s/%s$' % (testrecipe, os.path.basename(self.testfile)))]
1361 self._check_repo_status(os.path.dirname(recipefile), expected_status)
1362 result = runCmd('git diff %s' % os.path.basename(recipefile), cwd=os.path.dirname(recipefile))
1363 removelines = []
1364 addlines = [
1365 'file://%s \\\\' % os.path.basename(self.testfile),
1366 ]
1367 self._check_diff(result.output, addlines, removelines)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001368
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001369 def test_recipetool_appendsrcfile_replace_file_srcdir(self):
1370 testrecipe = 'bash'
1371 filepath = 'Makefile.in'
1372 bb_vars = get_bb_vars(['S', 'WORKDIR'], testrecipe)
1373 srcdir = bb_vars['S']
1374 workdir = bb_vars['WORKDIR']
1375 subdir = os.path.relpath(srcdir, workdir)
1376
1377 self._test_appendsrcfile(testrecipe, filepath, srcdir=subdir)
1378 bitbake('%s:do_unpack' % testrecipe)
Brad Bishop64c979e2019-11-04 13:55:29 -05001379 with open(self.testfile, 'r') as testfile:
1380 with open(os.path.join(srcdir, filepath), 'r') as makefilein:
1381 self.assertEqual(testfile.read(), makefilein.read())
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001382
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001383 def test_recipetool_appendsrcfiles_basic(self, destdir=None):
1384 newfiles = [self.testfile]
1385 for i in range(1, 5):
1386 testfile = os.path.join(self.tempdir, 'testfile%d' % i)
1387 with open(testfile, 'w') as f:
1388 f.write('Test file %d\n' % i)
1389 newfiles.append(testfile)
1390 self._test_appendsrcfiles('gcc', newfiles, destdir=destdir, options='-W')
1391
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001392 def test_recipetool_appendsrcfiles_basic_subdir(self):
1393 self.test_recipetool_appendsrcfiles_basic(destdir='testdir')