blob: 3eea2b1a0eaef9ac693171a3654c21de965cf5a9 [file] [log] [blame]
Brad Bishopc342db32019-05-15 21:57:59 -04001#
2# SPDX-License-Identifier: MIT
3#
4
Brad Bishopd7bf8c12018-02-25 22:55:05 -05005import os
6import re
7import shutil
8import tempfile
9import glob
10import fnmatch
11
Brad Bishopd7bf8c12018-02-25 22:55:05 -050012from oeqa.selftest.case import OESelftestTestCase
13from oeqa.utils.commands import runCmd, bitbake, get_bb_var, create_temp_layer
14from oeqa.utils.commands import get_bb_vars, runqemu, get_test_layer
Patrick Williams45852732022-04-02 08:58:32 -050015from oeqa.core.decorator import OETestTag
Brad Bishopd7bf8c12018-02-25 22:55:05 -050016
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080017oldmetapath = None
18
19def setUpModule():
20 import bb.utils
21
22 global templayerdir
23 templayerdir = tempfile.mkdtemp(prefix='devtoolqa')
24 corecopydir = os.path.join(templayerdir, 'core-copy')
25 bblayers_conf = os.path.join(os.environ['BUILDDIR'], 'conf', 'bblayers.conf')
26 edited_layers = []
27
28 # We need to take a copy of the meta layer so we can modify it and not
29 # have any races against other tests that might be running in parallel
30 # however things like COREBASE mean that you can't just copy meta, you
31 # need the whole repository.
32 def bblayers_edit_cb(layerpath, canonical_layerpath):
33 global oldmetapath
34 if not canonical_layerpath.endswith('/'):
35 # This helps us match exactly when we're using this path later
36 canonical_layerpath += '/'
37 if not edited_layers and canonical_layerpath.endswith('/meta/'):
38 canonical_layerpath = os.path.realpath(canonical_layerpath) + '/'
39 edited_layers.append(layerpath)
40 oldmetapath = os.path.realpath(layerpath)
41 result = runCmd('git rev-parse --show-toplevel', cwd=canonical_layerpath)
42 oldreporoot = result.output.rstrip()
43 newmetapath = os.path.join(corecopydir, os.path.relpath(oldmetapath, oldreporoot))
44 runCmd('git clone %s %s' % (oldreporoot, corecopydir), cwd=templayerdir)
45 # Now we need to copy any modified files
46 # You might ask "why not just copy the entire tree instead of
47 # cloning and doing this?" - well, the problem with that is
48 # TMPDIR or an equally large subdirectory might exist
49 # under COREBASE and we don't want to copy that, so we have
50 # to be selective.
51 result = runCmd('git status --porcelain', cwd=oldreporoot)
52 for line in result.output.splitlines():
53 if line.startswith(' M ') or line.startswith('?? '):
54 relpth = line.split()[1]
55 pth = os.path.join(oldreporoot, relpth)
56 if pth.startswith(canonical_layerpath):
57 if relpth.endswith('/'):
58 destdir = os.path.join(corecopydir, relpth)
Andrew Geisslerc3d88e42020-10-02 09:45:00 -050059 # avoid race condition by not copying .pyc files YPBZ#13421,13803
Andrew Geisslerd1e89492021-02-12 15:35:20 -060060 shutil.copytree(pth, destdir, ignore=shutil.ignore_patterns('*.pyc', '__pycache__'))
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080061 else:
62 destdir = os.path.join(corecopydir, os.path.dirname(relpth))
63 bb.utils.mkdirhier(destdir)
64 shutil.copy2(pth, destdir)
65 return newmetapath
66 else:
67 return layerpath
68 bb.utils.edit_bblayers_conf(bblayers_conf, None, None, bblayers_edit_cb)
69
70def tearDownModule():
71 if oldmetapath:
72 edited_layers = []
73 def bblayers_edit_cb(layerpath, canonical_layerpath):
74 if not edited_layers and canonical_layerpath.endswith('/meta'):
75 edited_layers.append(layerpath)
76 return oldmetapath
77 else:
78 return layerpath
79 bblayers_conf = os.path.join(os.environ['BUILDDIR'], 'conf', 'bblayers.conf')
80 bb.utils.edit_bblayers_conf(bblayers_conf, None, None, bblayers_edit_cb)
81 shutil.rmtree(templayerdir)
82
Andrew Geissler595f6302022-01-24 19:11:47 +000083class DevtoolTestCase(OESelftestTestCase):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080084
85 def setUp(self):
86 """Test case setup function"""
Andrew Geissler595f6302022-01-24 19:11:47 +000087 super(DevtoolTestCase, self).setUp()
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080088 self.workspacedir = os.path.join(self.builddir, 'workspace')
89 self.assertTrue(not os.path.exists(self.workspacedir),
90 'This test cannot be run with a workspace directory '
91 'under the build directory')
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080092
93 def _check_src_repo(self, repo_dir):
94 """Check srctree git repository"""
95 self.assertTrue(os.path.isdir(os.path.join(repo_dir, '.git')),
96 'git repository for external source tree not found')
97 result = runCmd('git status --porcelain', cwd=repo_dir)
98 self.assertEqual(result.output.strip(), "",
99 'Created git repo is not clean')
100 result = runCmd('git symbolic-ref HEAD', cwd=repo_dir)
101 self.assertEqual(result.output.strip(), "refs/heads/devtool",
102 'Wrong branch in git repo')
103
104 def _check_repo_status(self, repo_dir, expected_status):
105 """Check the worktree status of a repository"""
106 result = runCmd('git status . --porcelain',
107 cwd=repo_dir)
108 for line in result.output.splitlines():
109 for ind, (f_status, fn_re) in enumerate(expected_status):
110 if re.match(fn_re, line[3:]):
111 if f_status != line[:2]:
112 self.fail('Unexpected status in line: %s' % line)
113 expected_status.pop(ind)
114 break
115 else:
116 self.fail('Unexpected modified file in line: %s' % line)
117 if expected_status:
118 self.fail('Missing file changes: %s' % expected_status)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500119
120 def _test_recipe_contents(self, recipefile, checkvars, checkinherits):
121 with open(recipefile, 'r') as f:
122 invar = None
123 invalue = None
Brad Bishop6dbb3162019-11-25 09:41:34 -0500124 inherits = set()
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500125 for line in f:
126 var = None
127 if invar:
128 value = line.strip().strip('"')
129 if value.endswith('\\'):
130 invalue += ' ' + value[:-1].strip()
131 continue
132 else:
133 invalue += ' ' + value.strip()
134 var = invar
135 value = invalue
136 invar = None
137 elif '=' in line:
138 splitline = line.split('=', 1)
139 var = splitline[0].rstrip()
140 value = splitline[1].strip().strip('"')
141 if value.endswith('\\'):
142 invalue = value[:-1].strip()
143 invar = var
144 continue
145 elif line.startswith('inherit '):
Brad Bishop6dbb3162019-11-25 09:41:34 -0500146 inherits.update(line.split()[1:])
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500147
148 if var and var in checkvars:
149 needvalue = checkvars.pop(var)
150 if needvalue is None:
151 self.fail('Variable %s should not appear in recipe, but value is being set to "%s"' % (var, value))
152 if isinstance(needvalue, set):
153 if var == 'LICENSE':
154 value = set(value.split(' & '))
155 else:
156 value = set(value.split())
157 self.assertEqual(value, needvalue, 'values for %s do not match' % var)
158
159
160 missingvars = {}
161 for var, value in checkvars.items():
162 if value is not None:
163 missingvars[var] = value
164 self.assertEqual(missingvars, {}, 'Some expected variables not found in recipe: %s' % checkvars)
165
166 for inherit in checkinherits:
167 self.assertIn(inherit, inherits, 'Missing inherit of %s' % inherit)
168
169 def _check_bbappend(self, testrecipe, recipefile, appenddir):
170 result = runCmd('bitbake-layers show-appends', cwd=self.builddir)
171 resultlines = result.output.splitlines()
172 inrecipe = False
173 bbappends = []
174 bbappendfile = None
175 for line in resultlines:
176 if inrecipe:
177 if line.startswith(' '):
178 bbappends.append(line.strip())
179 else:
180 break
181 elif line == '%s:' % os.path.basename(recipefile):
182 inrecipe = True
183 self.assertLessEqual(len(bbappends), 2, '%s recipe is being bbappended by another layer - bbappends found:\n %s' % (testrecipe, '\n '.join(bbappends)))
184 for bbappend in bbappends:
185 if bbappend.startswith(appenddir):
186 bbappendfile = bbappend
187 break
188 else:
189 self.fail('bbappend for recipe %s does not seem to be created in test layer' % testrecipe)
190 return bbappendfile
191
192 def _create_temp_layer(self, templayerdir, addlayer, templayername, priority=999, recipepathspec='recipes-*/*'):
193 create_temp_layer(templayerdir, templayername, priority, recipepathspec)
194 if addlayer:
195 self.add_command_to_tearDown('bitbake-layers remove-layer %s || true' % templayerdir)
196 result = runCmd('bitbake-layers add-layer %s' % templayerdir, cwd=self.builddir)
197
198 def _process_ls_output(self, output):
199 """
200 Convert ls -l output to a format we can reasonably compare from one context
201 to another (e.g. from host to target)
202 """
203 filelist = []
204 for line in output.splitlines():
205 splitline = line.split()
206 if len(splitline) < 8:
207 self.fail('_process_ls_output: invalid output line: %s' % line)
208 # Remove trailing . on perms
209 splitline[0] = splitline[0].rstrip('.')
210 # Remove leading . on paths
211 splitline[-1] = splitline[-1].lstrip('.')
212 # Drop fields we don't want to compare
213 del splitline[7]
214 del splitline[6]
215 del splitline[5]
216 del splitline[4]
217 del splitline[1]
218 filelist.append(' '.join(splitline))
219 return filelist
220
221
Andrew Geissler595f6302022-01-24 19:11:47 +0000222class DevtoolBase(DevtoolTestCase):
223
224 @classmethod
225 def setUpClass(cls):
226 super(DevtoolBase, cls).setUpClass()
227 bb_vars = get_bb_vars(['TOPDIR', 'SSTATE_DIR'])
228 cls.original_sstate = bb_vars['SSTATE_DIR']
229 cls.devtool_sstate = os.path.join(bb_vars['TOPDIR'], 'sstate_devtool')
230 cls.sstate_conf = 'SSTATE_DIR = "%s"\n' % cls.devtool_sstate
231 cls.sstate_conf += ('SSTATE_MIRRORS += "file://.* file:///%s/PATH"\n'
232 % cls.original_sstate)
233
234 @classmethod
235 def tearDownClass(cls):
236 cls.logger.debug('Deleting devtool sstate cache on %s' % cls.devtool_sstate)
237 runCmd('rm -rf %s' % cls.devtool_sstate)
238 super(DevtoolBase, cls).tearDownClass()
239
240 def setUp(self):
241 """Test case setup function"""
242 super(DevtoolBase, self).setUp()
243 self.append_config(self.sstate_conf)
244
245
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500246class DevtoolTests(DevtoolBase):
247
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500248 def test_create_workspace(self):
249 # Check preconditions
250 result = runCmd('bitbake-layers show-layers')
Brad Bishop316dfdd2018-06-25 12:45:53 -0400251 self.assertTrue('\nworkspace' not in result.output, 'This test cannot be run with a workspace layer in bblayers.conf')
Brad Bishop96ff1982019-08-19 13:50:42 -0400252 # remove conf/devtool.conf to avoid it corrupting tests
253 devtoolconf = os.path.join(self.builddir, 'conf', 'devtool.conf')
254 self.track_for_cleanup(devtoolconf)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500255 # Try creating a workspace layer with a specific path
256 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
257 self.track_for_cleanup(tempdir)
258 result = runCmd('devtool create-workspace %s' % tempdir)
259 self.assertTrue(os.path.isfile(os.path.join(tempdir, 'conf', 'layer.conf')), msg = "No workspace created. devtool output: %s " % result.output)
260 result = runCmd('bitbake-layers show-layers')
261 self.assertIn(tempdir, result.output)
262 # Try creating a workspace layer with the default path
263 self.track_for_cleanup(self.workspacedir)
264 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
265 result = runCmd('devtool create-workspace')
266 self.assertTrue(os.path.isfile(os.path.join(self.workspacedir, 'conf', 'layer.conf')), msg = "No workspace created. devtool output: %s " % result.output)
267 result = runCmd('bitbake-layers show-layers')
268 self.assertNotIn(tempdir, result.output)
269 self.assertIn(self.workspacedir, result.output)
270
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800271class DevtoolAddTests(DevtoolBase):
272
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500273 def test_devtool_add(self):
274 # Fetch source
275 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
276 self.track_for_cleanup(tempdir)
277 pn = 'pv'
278 pv = '1.5.3'
Andrew Geissler09209ee2020-12-13 08:44:15 -0600279 url = 'http://downloads.yoctoproject.org/mirror/sources/pv-1.5.3.tar.bz2'
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500280 result = runCmd('wget %s' % url, cwd=tempdir)
281 result = runCmd('tar xfv %s' % os.path.basename(url), cwd=tempdir)
282 srcdir = os.path.join(tempdir, '%s-%s' % (pn, pv))
283 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure')), 'Unable to find configure script in source directory')
284 # Test devtool add
285 self.track_for_cleanup(self.workspacedir)
286 self.add_command_to_tearDown('bitbake -c cleansstate %s' % pn)
287 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
288 result = runCmd('devtool add %s %s' % (pn, srcdir))
289 self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created')
290 # Test devtool status
291 result = runCmd('devtool status')
292 recipepath = '%s/recipes/%s/%s_%s.bb' % (self.workspacedir, pn, pn, pv)
293 self.assertIn(recipepath, result.output)
294 self.assertIn(srcdir, result.output)
295 # Test devtool find-recipe
296 result = runCmd('devtool -q find-recipe %s' % pn)
297 self.assertEqual(recipepath, result.output.strip())
298 # Test devtool edit-recipe
299 result = runCmd('VISUAL="echo 123" devtool -q edit-recipe %s' % pn)
300 self.assertEqual('123 %s' % recipepath, result.output.strip())
301 # Clean up anything in the workdir/sysroot/sstate cache (have to do this *after* devtool add since the recipe only exists then)
302 bitbake('%s -c cleansstate' % pn)
303 # Test devtool build
304 result = runCmd('devtool build %s' % pn)
305 bb_vars = get_bb_vars(['D', 'bindir'], pn)
306 installdir = bb_vars['D']
307 self.assertTrue(installdir, 'Could not query installdir variable')
308 bindir = bb_vars['bindir']
309 self.assertTrue(bindir, 'Could not query bindir variable')
310 if bindir[0] == '/':
311 bindir = bindir[1:]
312 self.assertTrue(os.path.isfile(os.path.join(installdir, bindir, 'pv')), 'pv binary not found in D')
313
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500314 def test_devtool_add_git_local(self):
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800315 # We need dbus built so that DEPENDS recognition works
316 bitbake('dbus')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500317 # Fetch source from a remote URL, but do it outside of devtool
318 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
319 self.track_for_cleanup(tempdir)
320 pn = 'dbus-wait'
321 srcrev = '6cc6077a36fe2648a5f993fe7c16c9632f946517'
322 # We choose an https:// git URL here to check rewriting the URL works
323 url = 'https://git.yoctoproject.org/git/dbus-wait'
324 # Force fetching to "noname" subdir so we verify we're picking up the name from autoconf
325 # instead of the directory name
326 result = runCmd('git clone %s noname' % url, cwd=tempdir)
327 srcdir = os.path.join(tempdir, 'noname')
328 result = runCmd('git reset --hard %s' % srcrev, cwd=srcdir)
329 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure.ac')), 'Unable to find configure script in source directory')
330 # Test devtool add
331 self.track_for_cleanup(self.workspacedir)
332 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
333 # Don't specify a name since we should be able to auto-detect it
334 result = runCmd('devtool add %s' % srcdir)
335 self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created')
336 # Check the recipe name is correct
337 recipefile = get_bb_var('FILE', pn)
338 self.assertIn('%s_git.bb' % pn, recipefile, 'Recipe file incorrectly named')
339 self.assertIn(recipefile, result.output)
340 # Test devtool status
341 result = runCmd('devtool status')
342 self.assertIn(pn, result.output)
343 self.assertIn(srcdir, result.output)
344 self.assertIn(recipefile, result.output)
345 checkvars = {}
Andrew Geissler9aee5002022-03-30 16:27:02 +0000346 checkvars['LICENSE'] = 'GPL-2.0-only'
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500347 checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263'
348 checkvars['S'] = '${WORKDIR}/git'
349 checkvars['PV'] = '0.1+git${SRCPV}'
Andrew Geissler595f6302022-01-24 19:11:47 +0000350 checkvars['SRC_URI'] = 'git://git.yoctoproject.org/git/dbus-wait;protocol=https;branch=master'
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500351 checkvars['SRCREV'] = srcrev
352 checkvars['DEPENDS'] = set(['dbus'])
353 self._test_recipe_contents(recipefile, checkvars, [])
354
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500355 def test_devtool_add_library(self):
356 # Fetch source
357 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
358 self.track_for_cleanup(tempdir)
359 version = '1.1'
360 url = 'https://www.intra2net.com/en/developer/libftdi/download/libftdi1-%s.tar.bz2' % version
361 result = runCmd('wget %s' % url, cwd=tempdir)
362 result = runCmd('tar xfv libftdi1-%s.tar.bz2' % version, cwd=tempdir)
363 srcdir = os.path.join(tempdir, 'libftdi1-%s' % version)
364 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'CMakeLists.txt')), 'Unable to find CMakeLists.txt in source directory')
365 # Test devtool add (and use -V so we test that too)
366 self.track_for_cleanup(self.workspacedir)
367 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
368 result = runCmd('devtool add libftdi %s -V %s' % (srcdir, version))
369 self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created')
370 # Test devtool status
371 result = runCmd('devtool status')
372 self.assertIn('libftdi', result.output)
373 self.assertIn(srcdir, result.output)
374 # Clean up anything in the workdir/sysroot/sstate cache (have to do this *after* devtool add since the recipe only exists then)
375 bitbake('libftdi -c cleansstate')
376 # libftdi's python/CMakeLists.txt is a bit broken, so let's just disable it
377 # There's also the matter of it installing cmake files to a path we don't
378 # normally cover, which triggers the installed-vs-shipped QA test we have
379 # within do_package
380 recipefile = '%s/recipes/libftdi/libftdi_%s.bb' % (self.workspacedir, version)
381 result = runCmd('recipetool setvar %s EXTRA_OECMAKE -- \'-DPYTHON_BINDINGS=OFF -DLIBFTDI_CMAKE_CONFIG_DIR=${datadir}/cmake/Modules\'' % recipefile)
382 with open(recipefile, 'a') as f:
Patrick Williams213cb262021-08-07 19:21:33 -0500383 f.write('\nFILES:${PN}-dev += "${datadir}/cmake/Modules"\n')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500384 # We don't have the ability to pick up this dependency automatically yet...
385 f.write('\nDEPENDS += "libusb1"\n')
386 f.write('\nTESTLIBOUTPUT = "${COMPONENTS_DIR}/${TUNE_PKGARCH}/${PN}/${libdir}"\n')
387 # Test devtool build
388 result = runCmd('devtool build libftdi')
389 bb_vars = get_bb_vars(['TESTLIBOUTPUT', 'STAMP'], 'libftdi')
390 staging_libdir = bb_vars['TESTLIBOUTPUT']
391 self.assertTrue(staging_libdir, 'Could not query TESTLIBOUTPUT variable')
392 self.assertTrue(os.path.isfile(os.path.join(staging_libdir, 'libftdi1.so.2.1.0')), "libftdi binary not found in STAGING_LIBDIR. Output of devtool build libftdi %s" % result.output)
393 # Test devtool reset
394 stampprefix = bb_vars['STAMP']
395 result = runCmd('devtool reset libftdi')
396 result = runCmd('devtool status')
397 self.assertNotIn('libftdi', result.output)
398 self.assertTrue(stampprefix, 'Unable to get STAMP value for recipe libftdi')
399 matches = glob.glob(stampprefix + '*')
400 self.assertFalse(matches, 'Stamp files exist for recipe libftdi that should have been cleaned')
401 self.assertFalse(os.path.isfile(os.path.join(staging_libdir, 'libftdi1.so.2.1.0')), 'libftdi binary still found in STAGING_LIBDIR after cleaning')
402
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500403 def test_devtool_add_fetch(self):
404 # Fetch source
405 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
406 self.track_for_cleanup(tempdir)
407 testver = '0.23'
Brad Bishop15ae2502019-06-18 21:44:24 -0400408 url = 'https://files.pythonhosted.org/packages/c0/41/bae1254e0396c0cc8cf1751cb7d9afc90a602353695af5952530482c963f/MarkupSafe-%s.tar.gz' % testver
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500409 testrecipe = 'python-markupsafe'
410 srcdir = os.path.join(tempdir, testrecipe)
411 # Test devtool add
412 self.track_for_cleanup(self.workspacedir)
413 self.add_command_to_tearDown('bitbake -c cleansstate %s' % testrecipe)
414 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
415 result = runCmd('devtool add %s %s -f %s' % (testrecipe, srcdir, url))
416 self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created. %s' % result.output)
417 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'setup.py')), 'Unable to find setup.py in source directory')
418 self.assertTrue(os.path.isdir(os.path.join(srcdir, '.git')), 'git repository for external source tree was not created')
419 # Test devtool status
420 result = runCmd('devtool status')
421 self.assertIn(testrecipe, result.output)
422 self.assertIn(srcdir, result.output)
423 # Check recipe
424 recipefile = get_bb_var('FILE', testrecipe)
425 self.assertIn('%s_%s.bb' % (testrecipe, testver), recipefile, 'Recipe file incorrectly named')
426 checkvars = {}
427 checkvars['S'] = '${WORKDIR}/MarkupSafe-${PV}'
428 checkvars['SRC_URI'] = url.replace(testver, '${PV}')
429 self._test_recipe_contents(recipefile, checkvars, [])
430 # Try with version specified
431 result = runCmd('devtool reset -n %s' % testrecipe)
432 shutil.rmtree(srcdir)
433 fakever = '1.9'
434 result = runCmd('devtool add %s %s -f %s -V %s' % (testrecipe, srcdir, url, fakever))
435 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'setup.py')), 'Unable to find setup.py in source directory')
436 # Test devtool status
437 result = runCmd('devtool status')
438 self.assertIn(testrecipe, result.output)
439 self.assertIn(srcdir, result.output)
440 # Check recipe
441 recipefile = get_bb_var('FILE', testrecipe)
442 self.assertIn('%s_%s.bb' % (testrecipe, fakever), recipefile, 'Recipe file incorrectly named')
443 checkvars = {}
444 checkvars['S'] = '${WORKDIR}/MarkupSafe-%s' % testver
445 checkvars['SRC_URI'] = url
446 self._test_recipe_contents(recipefile, checkvars, [])
447
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500448 def test_devtool_add_fetch_git(self):
449 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
450 self.track_for_cleanup(tempdir)
451 url = 'gitsm://git.yoctoproject.org/mraa'
Andrew Geissler595f6302022-01-24 19:11:47 +0000452 url_branch = '%s;branch=master' % url
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500453 checkrev = 'ae127b19a50aa54255e4330ccfdd9a5d058e581d'
454 testrecipe = 'mraa'
455 srcdir = os.path.join(tempdir, testrecipe)
456 # Test devtool add
457 self.track_for_cleanup(self.workspacedir)
458 self.add_command_to_tearDown('bitbake -c cleansstate %s' % testrecipe)
459 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
460 result = runCmd('devtool add %s %s -a -f %s' % (testrecipe, srcdir, url))
461 self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created: %s' % result.output)
462 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'imraa', 'imraa.c')), 'Unable to find imraa/imraa.c in source directory')
463 # Test devtool status
464 result = runCmd('devtool status')
465 self.assertIn(testrecipe, result.output)
466 self.assertIn(srcdir, result.output)
467 # Check recipe
468 recipefile = get_bb_var('FILE', testrecipe)
469 self.assertIn('_git.bb', recipefile, 'Recipe file incorrectly named')
470 checkvars = {}
471 checkvars['S'] = '${WORKDIR}/git'
472 checkvars['PV'] = '1.0+git${SRCPV}'
Andrew Geissler595f6302022-01-24 19:11:47 +0000473 checkvars['SRC_URI'] = url_branch
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500474 checkvars['SRCREV'] = '${AUTOREV}'
475 self._test_recipe_contents(recipefile, checkvars, [])
476 # Try with revision and version specified
477 result = runCmd('devtool reset -n %s' % testrecipe)
478 shutil.rmtree(srcdir)
479 url_rev = '%s;rev=%s' % (url, checkrev)
480 result = runCmd('devtool add %s %s -f "%s" -V 1.5' % (testrecipe, srcdir, url_rev))
481 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'imraa', 'imraa.c')), 'Unable to find imraa/imraa.c in source directory')
482 # Test devtool status
483 result = runCmd('devtool status')
484 self.assertIn(testrecipe, result.output)
485 self.assertIn(srcdir, result.output)
486 # Check recipe
487 recipefile = get_bb_var('FILE', testrecipe)
488 self.assertIn('_git.bb', recipefile, 'Recipe file incorrectly named')
489 checkvars = {}
490 checkvars['S'] = '${WORKDIR}/git'
491 checkvars['PV'] = '1.5+git${SRCPV}'
Andrew Geissler595f6302022-01-24 19:11:47 +0000492 checkvars['SRC_URI'] = url_branch
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500493 checkvars['SRCREV'] = checkrev
494 self._test_recipe_contents(recipefile, checkvars, [])
495
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500496 def test_devtool_add_fetch_simple(self):
497 # Fetch source from a remote URL, auto-detecting name
498 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
499 self.track_for_cleanup(tempdir)
500 testver = '1.6.0'
501 url = 'http://www.ivarch.com/programs/sources/pv-%s.tar.bz2' % testver
502 testrecipe = 'pv'
503 srcdir = os.path.join(self.workspacedir, 'sources', testrecipe)
504 # Test devtool add
505 self.track_for_cleanup(self.workspacedir)
506 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
507 result = runCmd('devtool add %s' % url)
508 self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created. %s' % result.output)
509 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure')), 'Unable to find configure script in source directory')
510 self.assertTrue(os.path.isdir(os.path.join(srcdir, '.git')), 'git repository for external source tree was not created')
511 # Test devtool status
512 result = runCmd('devtool status')
513 self.assertIn(testrecipe, result.output)
514 self.assertIn(srcdir, result.output)
515 # Check recipe
516 recipefile = get_bb_var('FILE', testrecipe)
517 self.assertIn('%s_%s.bb' % (testrecipe, testver), recipefile, 'Recipe file incorrectly named')
518 checkvars = {}
519 checkvars['S'] = None
520 checkvars['SRC_URI'] = url.replace(testver, '${PV}')
521 self._test_recipe_contents(recipefile, checkvars, [])
522
Andrew Geissler82c905d2020-04-13 13:39:40 -0500523 def test_devtool_add_npm(self):
Andrew Geisslerf0343792020-11-18 10:42:21 -0600524 collections = get_bb_var('BBFILE_COLLECTIONS').split()
525 if "openembedded-layer" not in collections:
526 self.skipTest("Test needs meta-oe for nodejs")
527
Andrew Geissler82c905d2020-04-13 13:39:40 -0500528 pn = 'savoirfairelinux-node-server-example'
529 pv = '1.0.0'
530 url = 'npm://registry.npmjs.org;package=@savoirfairelinux/node-server-example;version=' + pv
531 # Test devtool add
532 self.track_for_cleanup(self.workspacedir)
533 self.add_command_to_tearDown('bitbake -c cleansstate %s' % pn)
534 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
535 result = runCmd('devtool add \'%s\'' % url)
536 self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created')
537 self.assertExists(os.path.join(self.workspacedir, 'recipes', pn, '%s_%s.bb' % (pn, pv)), 'Recipe not created')
538 self.assertExists(os.path.join(self.workspacedir, 'recipes', pn, pn, 'npm-shrinkwrap.json'), 'Shrinkwrap not created')
539 # Test devtool status
540 result = runCmd('devtool status')
541 self.assertIn(pn, result.output)
542 # Clean up anything in the workdir/sysroot/sstate cache (have to do this *after* devtool add since the recipe only exists then)
543 bitbake('%s -c cleansstate' % pn)
544 # Test devtool build
545 result = runCmd('devtool build %s' % pn)
546
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800547class DevtoolModifyTests(DevtoolBase):
548
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500549 def test_devtool_modify(self):
550 import oe.path
551
552 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
553 self.track_for_cleanup(tempdir)
554 self.track_for_cleanup(self.workspacedir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500555 self.add_command_to_tearDown('bitbake -c clean mdadm')
Brad Bishop00e122a2019-10-05 11:10:57 -0400556 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500557 result = runCmd('devtool modify mdadm -x %s' % tempdir)
558 self.assertExists(os.path.join(tempdir, 'Makefile'), 'Extracted source could not be found')
559 self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created')
560 matches = glob.glob(os.path.join(self.workspacedir, 'appends', 'mdadm_*.bbappend'))
561 self.assertTrue(matches, 'bbappend not created %s' % result.output)
562
563 # Test devtool status
564 result = runCmd('devtool status')
565 self.assertIn('mdadm', result.output)
566 self.assertIn(tempdir, result.output)
567 self._check_src_repo(tempdir)
568
569 bitbake('mdadm -C unpack')
570
571 def check_line(checkfile, expected, message, present=True):
572 # Check for $expected, on a line on its own, in checkfile.
573 with open(checkfile, 'r') as f:
574 if present:
575 self.assertIn(expected + '\n', f, message)
576 else:
577 self.assertNotIn(expected + '\n', f, message)
578
579 modfile = os.path.join(tempdir, 'mdadm.8.in')
580 bb_vars = get_bb_vars(['PKGD', 'mandir'], 'mdadm')
581 pkgd = bb_vars['PKGD']
582 self.assertTrue(pkgd, 'Could not query PKGD variable')
583 mandir = bb_vars['mandir']
584 self.assertTrue(mandir, 'Could not query mandir variable')
585 manfile = oe.path.join(pkgd, mandir, 'man8', 'mdadm.8')
586
587 check_line(modfile, 'Linux Software RAID', 'Could not find initial string')
588 check_line(modfile, 'antique pin sardine', 'Unexpectedly found replacement string', present=False)
589
590 result = runCmd("sed -i 's!^Linux Software RAID$!antique pin sardine!' %s" % modfile)
591 check_line(modfile, 'antique pin sardine', 'mdadm.8.in file not modified (sed failed)')
592
593 bitbake('mdadm -c package')
594 check_line(manfile, 'antique pin sardine', 'man file not modified. man searched file path: %s' % manfile)
595
596 result = runCmd('git checkout -- %s' % modfile, cwd=tempdir)
597 check_line(modfile, 'Linux Software RAID', 'man .in file not restored (git failed)')
598
599 bitbake('mdadm -c package')
600 check_line(manfile, 'Linux Software RAID', 'man file not updated. man searched file path: %s' % manfile)
601
602 result = runCmd('devtool reset mdadm')
603 result = runCmd('devtool status')
604 self.assertNotIn('mdadm', result.output)
605
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500606 def test_devtool_buildclean(self):
607 def assertFile(path, *paths):
608 f = os.path.join(path, *paths)
609 self.assertExists(f)
610 def assertNoFile(path, *paths):
611 f = os.path.join(path, *paths)
612 self.assertNotExists(f)
613
614 # Clean up anything in the workdir/sysroot/sstate cache
615 bitbake('mdadm m4 -c cleansstate')
616 # Try modifying a recipe
617 tempdir_mdadm = tempfile.mkdtemp(prefix='devtoolqa')
618 tempdir_m4 = tempfile.mkdtemp(prefix='devtoolqa')
619 builddir_m4 = tempfile.mkdtemp(prefix='devtoolqa')
620 self.track_for_cleanup(tempdir_mdadm)
621 self.track_for_cleanup(tempdir_m4)
622 self.track_for_cleanup(builddir_m4)
623 self.track_for_cleanup(self.workspacedir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500624 self.add_command_to_tearDown('bitbake -c clean mdadm m4')
Brad Bishop00e122a2019-10-05 11:10:57 -0400625 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500626 self.write_recipeinc('m4', 'EXTERNALSRC_BUILD = "%s"\ndo_clean() {\n\t:\n}\n' % builddir_m4)
627 try:
628 runCmd('devtool modify mdadm -x %s' % tempdir_mdadm)
629 runCmd('devtool modify m4 -x %s' % tempdir_m4)
630 assertNoFile(tempdir_mdadm, 'mdadm')
631 assertNoFile(builddir_m4, 'src/m4')
632 result = bitbake('m4 -e')
633 result = bitbake('mdadm m4 -c compile')
634 self.assertEqual(result.status, 0)
635 assertFile(tempdir_mdadm, 'mdadm')
636 assertFile(builddir_m4, 'src/m4')
637 # Check that buildclean task exists and does call make clean
638 bitbake('mdadm m4 -c buildclean')
639 assertNoFile(tempdir_mdadm, 'mdadm')
640 assertNoFile(builddir_m4, 'src/m4')
Brad Bishop00e122a2019-10-05 11:10:57 -0400641 runCmd('echo "#Trigger rebuild" >> %s/Makefile' % tempdir_mdadm)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500642 bitbake('mdadm m4 -c compile')
643 assertFile(tempdir_mdadm, 'mdadm')
644 assertFile(builddir_m4, 'src/m4')
645 bitbake('mdadm m4 -c clean')
646 # Check that buildclean task is run before clean for B == S
647 assertNoFile(tempdir_mdadm, 'mdadm')
648 # Check that buildclean task is not run before clean for B != S
649 assertFile(builddir_m4, 'src/m4')
650 finally:
651 self.delete_recipeinc('m4')
652
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500653 def test_devtool_modify_invalid(self):
654 # Try modifying some recipes
655 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
656 self.track_for_cleanup(tempdir)
657 self.track_for_cleanup(self.workspacedir)
658 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
659
Andrew Geissler5199d832021-09-24 16:47:35 -0500660 testrecipes = 'perf kernel-devsrc package-index core-image-minimal meta-toolchain packagegroup-core-sdk'.split()
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500661 # Find actual name of gcc-source since it now includes the version - crude, but good enough for this purpose
662 result = runCmd('bitbake-layers show-recipes gcc-source*')
663 for line in result.output.splitlines():
664 # just match those lines that contain a real target
665 m = re.match('(?P<recipe>^[a-zA-Z0-9.-]+)(?P<colon>:$)', line)
666 if m:
667 testrecipes.append(m.group('recipe'))
668 for testrecipe in testrecipes:
669 # Check it's a valid recipe
670 bitbake('%s -e' % testrecipe)
671 # devtool extract should fail
672 result = runCmd('devtool extract %s %s' % (testrecipe, os.path.join(tempdir, testrecipe)), ignore_status=True)
673 self.assertNotEqual(result.status, 0, 'devtool extract on %s should have failed. devtool output: %s' % (testrecipe, result.output))
674 self.assertNotIn('Fetching ', result.output, 'devtool extract on %s should have errored out before trying to fetch' % testrecipe)
675 self.assertIn('ERROR: ', result.output, 'devtool extract on %s should have given an ERROR' % testrecipe)
676 # devtool modify should fail
677 result = runCmd('devtool modify %s -x %s' % (testrecipe, os.path.join(tempdir, testrecipe)), ignore_status=True)
678 self.assertNotEqual(result.status, 0, 'devtool modify on %s should have failed. devtool output: %s' % (testrecipe, result.output))
679 self.assertIn('ERROR: ', result.output, 'devtool modify on %s should have given an ERROR' % testrecipe)
680
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500681 def test_devtool_modify_native(self):
682 # Check preconditions
683 self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
684 # Try modifying some recipes
685 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
686 self.track_for_cleanup(tempdir)
687 self.track_for_cleanup(self.workspacedir)
688 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
689
690 bbclassextended = False
691 inheritnative = False
Andrew Geissler4ed12e12020-06-05 18:00:41 -0500692 testrecipes = 'cdrtools-native mtools-native apt-native desktop-file-utils-native'.split()
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500693 for testrecipe in testrecipes:
694 checkextend = 'native' in (get_bb_var('BBCLASSEXTEND', testrecipe) or '').split()
695 if not bbclassextended:
696 bbclassextended = checkextend
697 if not inheritnative:
698 inheritnative = not checkextend
699 result = runCmd('devtool modify %s -x %s' % (testrecipe, os.path.join(tempdir, testrecipe)))
700 self.assertNotIn('ERROR: ', result.output, 'ERROR in devtool modify output: %s' % result.output)
701 result = runCmd('devtool build %s' % testrecipe)
702 self.assertNotIn('ERROR: ', result.output, 'ERROR in devtool build output: %s' % result.output)
703 result = runCmd('devtool reset %s' % testrecipe)
704 self.assertNotIn('ERROR: ', result.output, 'ERROR in devtool reset output: %s' % result.output)
705
706 self.assertTrue(bbclassextended, 'None of these recipes are BBCLASSEXTENDed to native - need to adjust testrecipes list: %s' % ', '.join(testrecipes))
707 self.assertTrue(inheritnative, 'None of these recipes do "inherit native" - need to adjust testrecipes list: %s' % ', '.join(testrecipes))
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600708 def test_devtool_modify_localfiles_only(self):
709 # Check preconditions
710 testrecipe = 'base-files'
711 src_uri = (get_bb_var('SRC_URI', testrecipe) or '').split()
712 foundlocalonly = False
713 correct_symlink = False
714 for item in src_uri:
715 if item.startswith('file://'):
716 if '.patch' not in item:
717 foundlocalonly = True
718 else:
719 foundlocalonly = False
720 break
721 self.assertTrue(foundlocalonly, 'This test expects the %s recipe to fetch local files only and it seems that it no longer does' % testrecipe)
722 # Clean up anything in the workdir/sysroot/sstate cache
723 bitbake('%s -c cleansstate' % testrecipe)
724 # Try modifying a recipe
725 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
726 self.track_for_cleanup(tempdir)
727 self.track_for_cleanup(self.workspacedir)
728 self.add_command_to_tearDown('bitbake -c clean %s' % testrecipe)
729 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
730 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
731 srcfile = os.path.join(tempdir, 'oe-local-files/share/dot.bashrc')
732 srclink = os.path.join(tempdir, 'share/dot.bashrc')
733 self.assertExists(srcfile, 'Extracted source could not be found')
734 if os.path.islink(srclink) and os.path.exists(srclink) and os.path.samefile(srcfile, srclink):
735 correct_symlink = True
736 self.assertTrue(correct_symlink, 'Source symlink to oe-local-files is broken')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500737
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600738 matches = glob.glob(os.path.join(self.workspacedir, 'appends', '%s_*.bbappend' % testrecipe))
739 self.assertTrue(matches, 'bbappend not created')
740 # Test devtool status
741 result = runCmd('devtool status')
742 self.assertIn(testrecipe, result.output)
743 self.assertIn(tempdir, result.output)
744 # Try building
745 bitbake(testrecipe)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500746
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500747 def test_devtool_modify_git(self):
748 # Check preconditions
Brad Bishop316dfdd2018-06-25 12:45:53 -0400749 testrecipe = 'psplash'
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500750 src_uri = get_bb_var('SRC_URI', testrecipe)
751 self.assertIn('git://', src_uri, 'This test expects the %s recipe to be a git recipe' % testrecipe)
752 # Clean up anything in the workdir/sysroot/sstate cache
753 bitbake('%s -c cleansstate' % testrecipe)
754 # Try modifying a recipe
755 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
756 self.track_for_cleanup(tempdir)
757 self.track_for_cleanup(self.workspacedir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500758 self.add_command_to_tearDown('bitbake -c clean %s' % testrecipe)
Brad Bishop00e122a2019-10-05 11:10:57 -0400759 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500760 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
Brad Bishop316dfdd2018-06-25 12:45:53 -0400761 self.assertExists(os.path.join(tempdir, 'Makefile.am'), 'Extracted source could not be found')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500762 self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created. devtool output: %s' % result.output)
Brad Bishop316dfdd2018-06-25 12:45:53 -0400763 matches = glob.glob(os.path.join(self.workspacedir, 'appends', 'psplash_*.bbappend'))
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500764 self.assertTrue(matches, 'bbappend not created')
765 # Test devtool status
766 result = runCmd('devtool status')
767 self.assertIn(testrecipe, result.output)
768 self.assertIn(tempdir, result.output)
769 # Check git repo
770 self._check_src_repo(tempdir)
771 # Try building
772 bitbake(testrecipe)
773
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500774 def test_devtool_modify_localfiles(self):
775 # Check preconditions
776 testrecipe = 'lighttpd'
777 src_uri = (get_bb_var('SRC_URI', testrecipe) or '').split()
778 foundlocal = False
779 for item in src_uri:
780 if item.startswith('file://') and '.patch' not in item:
781 foundlocal = True
782 break
783 self.assertTrue(foundlocal, 'This test expects the %s recipe to fetch local files and it seems that it no longer does' % testrecipe)
784 # Clean up anything in the workdir/sysroot/sstate cache
785 bitbake('%s -c cleansstate' % testrecipe)
786 # Try modifying a recipe
787 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
788 self.track_for_cleanup(tempdir)
789 self.track_for_cleanup(self.workspacedir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500790 self.add_command_to_tearDown('bitbake -c clean %s' % testrecipe)
Brad Bishop00e122a2019-10-05 11:10:57 -0400791 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500792 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
793 self.assertExists(os.path.join(tempdir, 'configure.ac'), 'Extracted source could not be found')
794 self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created')
795 matches = glob.glob(os.path.join(self.workspacedir, 'appends', '%s_*.bbappend' % testrecipe))
796 self.assertTrue(matches, 'bbappend not created')
797 # Test devtool status
798 result = runCmd('devtool status')
799 self.assertIn(testrecipe, result.output)
800 self.assertIn(tempdir, result.output)
801 # Try building
802 bitbake(testrecipe)
803
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500804 def test_devtool_modify_virtual(self):
805 # Try modifying a virtual recipe
806 virtrecipe = 'virtual/make'
807 realrecipe = 'make'
808 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
809 self.track_for_cleanup(tempdir)
810 self.track_for_cleanup(self.workspacedir)
811 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
812 result = runCmd('devtool modify %s -x %s' % (virtrecipe, tempdir))
813 self.assertExists(os.path.join(tempdir, 'Makefile.am'), 'Extracted source could not be found')
814 self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created')
815 matches = glob.glob(os.path.join(self.workspacedir, 'appends', '%s_*.bbappend' % realrecipe))
816 self.assertTrue(matches, 'bbappend not created %s' % result.output)
817 # Test devtool status
818 result = runCmd('devtool status')
819 self.assertNotIn(virtrecipe, result.output)
820 self.assertIn(realrecipe, result.output)
821 # Check git repo
822 self._check_src_repo(tempdir)
823 # This is probably sufficient
824
Andrew Geisslerf0343792020-11-18 10:42:21 -0600825 def test_devtool_modify_overrides(self):
826 # Try modifying a recipe with patches in overrides
827 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
828 self.track_for_cleanup(tempdir)
829 self.track_for_cleanup(self.workspacedir)
830 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
831 result = runCmd('devtool modify devtool-patch-overrides -x %s' % (tempdir))
832
833 self._check_src_repo(tempdir)
834 source = os.path.join(tempdir, "source")
835 def check(branch, expected):
836 runCmd('git -C %s checkout %s' % (tempdir, branch))
837 with open(source, "rt") as f:
838 content = f.read()
839 self.assertEquals(content, expected)
840 check('devtool', 'This is a test for something\n')
841 check('devtool-no-overrides', 'This is a test for something\n')
842 check('devtool-override-qemuarm', 'This is a test for qemuarm\n')
843 check('devtool-override-qemux86', 'This is a test for qemux86\n')
844
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800845class DevtoolUpdateTests(DevtoolBase):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500846
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500847 def test_devtool_update_recipe(self):
848 # Check preconditions
849 testrecipe = 'minicom'
850 bb_vars = get_bb_vars(['FILE', 'SRC_URI'], testrecipe)
851 recipefile = bb_vars['FILE']
852 src_uri = bb_vars['SRC_URI']
853 self.assertNotIn('git://', src_uri, 'This test expects the %s recipe to NOT be a git recipe' % testrecipe)
854 self._check_repo_status(os.path.dirname(recipefile), [])
855 # First, modify a recipe
856 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
857 self.track_for_cleanup(tempdir)
858 self.track_for_cleanup(self.workspacedir)
859 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
860 # (don't bother with cleaning the recipe on teardown, we won't be building it)
861 # We don't use -x here so that we test the behaviour of devtool modify without it
862 result = runCmd('devtool modify %s %s' % (testrecipe, tempdir))
863 # Check git repo
864 self._check_src_repo(tempdir)
865 # Add a couple of commits
866 # FIXME: this only tests adding, need to also test update and remove
867 result = runCmd('echo "Additional line" >> README', cwd=tempdir)
868 result = runCmd('git commit -a -m "Change the README"', cwd=tempdir)
869 result = runCmd('echo "A new file" > devtool-new-file', cwd=tempdir)
870 result = runCmd('git add devtool-new-file', cwd=tempdir)
871 result = runCmd('git commit -m "Add a new file"', cwd=tempdir)
872 self.add_command_to_tearDown('cd %s; rm %s/*.patch; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, testrecipe, os.path.basename(recipefile)))
873 result = runCmd('devtool update-recipe %s' % testrecipe)
874 expected_status = [(' M', '.*/%s$' % os.path.basename(recipefile)),
875 ('??', '.*/0001-Change-the-README.patch$'),
876 ('??', '.*/0002-Add-a-new-file.patch$')]
877 self._check_repo_status(os.path.dirname(recipefile), expected_status)
878
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500879 def test_devtool_update_recipe_git(self):
880 # Check preconditions
881 testrecipe = 'mtd-utils'
882 bb_vars = get_bb_vars(['FILE', 'SRC_URI'], testrecipe)
883 recipefile = bb_vars['FILE']
884 src_uri = bb_vars['SRC_URI']
885 self.assertIn('git://', src_uri, 'This test expects the %s recipe to be a git recipe' % testrecipe)
886 patches = []
887 for entry in src_uri.split():
888 if entry.startswith('file://') and entry.endswith('.patch'):
889 patches.append(entry[7:].split(';')[0])
890 self.assertGreater(len(patches), 0, 'The %s recipe does not appear to contain any patches, so this test will not be effective' % testrecipe)
891 self._check_repo_status(os.path.dirname(recipefile), [])
892 # First, modify a recipe
893 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
894 self.track_for_cleanup(tempdir)
895 self.track_for_cleanup(self.workspacedir)
896 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
897 # (don't bother with cleaning the recipe on teardown, we won't be building it)
898 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
899 # Check git repo
900 self._check_src_repo(tempdir)
901 # Add a couple of commits
902 # FIXME: this only tests adding, need to also test update and remove
903 result = runCmd('echo "# Additional line" >> Makefile.am', cwd=tempdir)
904 result = runCmd('git commit -a -m "Change the Makefile"', cwd=tempdir)
905 result = runCmd('echo "A new file" > devtool-new-file', cwd=tempdir)
906 result = runCmd('git add devtool-new-file', cwd=tempdir)
907 result = runCmd('git commit -m "Add a new file"', cwd=tempdir)
908 self.add_command_to_tearDown('cd %s; rm -rf %s; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, testrecipe, os.path.basename(recipefile)))
909 result = runCmd('devtool update-recipe -m srcrev %s' % testrecipe)
910 expected_status = [(' M', '.*/%s$' % os.path.basename(recipefile))] + \
911 [(' D', '.*/%s$' % patch) for patch in patches]
912 self._check_repo_status(os.path.dirname(recipefile), expected_status)
913
914 result = runCmd('git diff %s' % os.path.basename(recipefile), cwd=os.path.dirname(recipefile))
Andrew Geissler595f6302022-01-24 19:11:47 +0000915 addlines = ['SRCREV = ".*"', 'SRC_URI = "git://git.infradead.org/mtd-utils.git;branch=master"']
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500916 srcurilines = src_uri.split()
917 srcurilines[0] = 'SRC_URI = "' + srcurilines[0]
918 srcurilines.append('"')
919 removelines = ['SRCREV = ".*"'] + srcurilines
920 for line in result.output.splitlines():
921 if line.startswith('+++') or line.startswith('---'):
922 continue
923 elif line.startswith('+'):
924 matched = False
925 for item in addlines:
926 if re.match(item, line[1:].strip()):
927 matched = True
928 break
929 self.assertTrue(matched, 'Unexpected diff add line: %s' % line)
930 elif line.startswith('-'):
931 matched = False
932 for item in removelines:
933 if re.match(item, line[1:].strip()):
934 matched = True
935 break
936 self.assertTrue(matched, 'Unexpected diff remove line: %s' % line)
937 # Now try with auto mode
938 runCmd('cd %s; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, os.path.basename(recipefile)))
939 result = runCmd('devtool update-recipe %s' % testrecipe)
940 result = runCmd('git rev-parse --show-toplevel', cwd=os.path.dirname(recipefile))
941 topleveldir = result.output.strip()
942 relpatchpath = os.path.join(os.path.relpath(os.path.dirname(recipefile), topleveldir), testrecipe)
943 expected_status = [(' M', os.path.relpath(recipefile, topleveldir)),
944 ('??', '%s/0001-Change-the-Makefile.patch' % relpatchpath),
945 ('??', '%s/0002-Add-a-new-file.patch' % relpatchpath)]
946 self._check_repo_status(os.path.dirname(recipefile), expected_status)
947
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500948 def test_devtool_update_recipe_append(self):
949 # Check preconditions
950 testrecipe = 'mdadm'
951 bb_vars = get_bb_vars(['FILE', 'SRC_URI'], testrecipe)
952 recipefile = bb_vars['FILE']
953 src_uri = bb_vars['SRC_URI']
954 self.assertNotIn('git://', src_uri, 'This test expects the %s recipe to NOT be a git recipe' % testrecipe)
955 self._check_repo_status(os.path.dirname(recipefile), [])
956 # First, modify a recipe
957 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
958 tempsrcdir = os.path.join(tempdir, 'source')
959 templayerdir = os.path.join(tempdir, 'layer')
960 self.track_for_cleanup(tempdir)
961 self.track_for_cleanup(self.workspacedir)
962 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
963 # (don't bother with cleaning the recipe on teardown, we won't be building it)
964 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempsrcdir))
965 # Check git repo
966 self._check_src_repo(tempsrcdir)
967 # Add a commit
968 result = runCmd("sed 's!\\(#define VERSION\\W*\"[^\"]*\\)\"!\\1-custom\"!' -i ReadMe.c", cwd=tempsrcdir)
969 result = runCmd('git commit -a -m "Add our custom version"', cwd=tempsrcdir)
970 self.add_command_to_tearDown('cd %s; rm -f %s/*.patch; git checkout .' % (os.path.dirname(recipefile), testrecipe))
971 # Create a temporary layer and add it to bblayers.conf
972 self._create_temp_layer(templayerdir, True, 'selftestupdaterecipe')
973 # Create the bbappend
974 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
975 self.assertNotIn('WARNING:', result.output)
976 # Check recipe is still clean
977 self._check_repo_status(os.path.dirname(recipefile), [])
978 # Check bbappend was created
979 splitpath = os.path.dirname(recipefile).split(os.sep)
980 appenddir = os.path.join(templayerdir, splitpath[-2], splitpath[-1])
981 bbappendfile = self._check_bbappend(testrecipe, recipefile, appenddir)
982 patchfile = os.path.join(appenddir, testrecipe, '0001-Add-our-custom-version.patch')
983 self.assertExists(patchfile, 'Patch file not created')
984
985 # Check bbappend contents
Patrick Williams213cb262021-08-07 19:21:33 -0500986 expectedlines = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500987 '\n',
988 'SRC_URI += "file://0001-Add-our-custom-version.patch"\n',
989 '\n']
990 with open(bbappendfile, 'r') as f:
991 self.assertEqual(expectedlines, f.readlines())
992
993 # Check we can run it again and bbappend isn't modified
994 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
995 with open(bbappendfile, 'r') as f:
996 self.assertEqual(expectedlines, f.readlines())
997 # Drop new commit and check patch gets deleted
998 result = runCmd('git reset HEAD^', cwd=tempsrcdir)
999 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
1000 self.assertNotExists(patchfile, 'Patch file not deleted')
Patrick Williams213cb262021-08-07 19:21:33 -05001001 expectedlines2 = ['FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"\n',
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001002 '\n']
1003 with open(bbappendfile, 'r') as f:
1004 self.assertEqual(expectedlines2, f.readlines())
1005 # Put commit back and check we can run it if layer isn't in bblayers.conf
1006 os.remove(bbappendfile)
1007 result = runCmd('git commit -a -m "Add our custom version"', cwd=tempsrcdir)
1008 result = runCmd('bitbake-layers remove-layer %s' % templayerdir, cwd=self.builddir)
1009 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
1010 self.assertIn('WARNING: Specified layer is not currently enabled in bblayers.conf', result.output)
1011 self.assertExists(patchfile, 'Patch file not created (with disabled layer)')
1012 with open(bbappendfile, 'r') as f:
1013 self.assertEqual(expectedlines, f.readlines())
1014 # Deleting isn't expected to work under these circumstances
1015
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001016 def test_devtool_update_recipe_append_git(self):
1017 # Check preconditions
1018 testrecipe = 'mtd-utils'
1019 bb_vars = get_bb_vars(['FILE', 'SRC_URI'], testrecipe)
1020 recipefile = bb_vars['FILE']
1021 src_uri = bb_vars['SRC_URI']
1022 self.assertIn('git://', src_uri, 'This test expects the %s recipe to be a git recipe' % testrecipe)
1023 for entry in src_uri.split():
1024 if entry.startswith('git://'):
1025 git_uri = entry
1026 break
1027 self._check_repo_status(os.path.dirname(recipefile), [])
1028 # First, modify a recipe
1029 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1030 tempsrcdir = os.path.join(tempdir, 'source')
1031 templayerdir = os.path.join(tempdir, 'layer')
1032 self.track_for_cleanup(tempdir)
1033 self.track_for_cleanup(self.workspacedir)
1034 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1035 # (don't bother with cleaning the recipe on teardown, we won't be building it)
1036 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempsrcdir))
1037 # Check git repo
1038 self._check_src_repo(tempsrcdir)
1039 # Add a commit
1040 result = runCmd('echo "# Additional line" >> Makefile.am', cwd=tempsrcdir)
1041 result = runCmd('git commit -a -m "Change the Makefile"', cwd=tempsrcdir)
1042 self.add_command_to_tearDown('cd %s; rm -f %s/*.patch; git checkout .' % (os.path.dirname(recipefile), testrecipe))
1043 # Create a temporary layer
1044 os.makedirs(os.path.join(templayerdir, 'conf'))
1045 with open(os.path.join(templayerdir, 'conf', 'layer.conf'), 'w') as f:
1046 f.write('BBPATH .= ":${LAYERDIR}"\n')
1047 f.write('BBFILES += "${LAYERDIR}/recipes-*/*/*.bbappend"\n')
1048 f.write('BBFILE_COLLECTIONS += "oeselftesttemplayer"\n')
1049 f.write('BBFILE_PATTERN_oeselftesttemplayer = "^${LAYERDIR}/"\n')
1050 f.write('BBFILE_PRIORITY_oeselftesttemplayer = "999"\n')
1051 f.write('BBFILE_PATTERN_IGNORE_EMPTY_oeselftesttemplayer = "1"\n')
Brad Bishop316dfdd2018-06-25 12:45:53 -04001052 f.write('LAYERSERIES_COMPAT_oeselftesttemplayer = "${LAYERSERIES_COMPAT_core}"\n')
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001053 self.add_command_to_tearDown('bitbake-layers remove-layer %s || true' % templayerdir)
1054 result = runCmd('bitbake-layers add-layer %s' % templayerdir, cwd=self.builddir)
1055 # Create the bbappend
1056 result = runCmd('devtool update-recipe -m srcrev %s -a %s' % (testrecipe, templayerdir))
1057 self.assertNotIn('WARNING:', result.output)
1058 # Check recipe is still clean
1059 self._check_repo_status(os.path.dirname(recipefile), [])
1060 # Check bbappend was created
1061 splitpath = os.path.dirname(recipefile).split(os.sep)
1062 appenddir = os.path.join(templayerdir, splitpath[-2], splitpath[-1])
1063 bbappendfile = self._check_bbappend(testrecipe, recipefile, appenddir)
1064 self.assertNotExists(os.path.join(appenddir, testrecipe), 'Patch directory should not be created')
1065
1066 # Check bbappend contents
1067 result = runCmd('git rev-parse HEAD', cwd=tempsrcdir)
1068 expectedlines = set(['SRCREV = "%s"\n' % result.output,
1069 '\n',
1070 'SRC_URI = "%s"\n' % git_uri,
1071 '\n'])
1072 with open(bbappendfile, 'r') as f:
1073 self.assertEqual(expectedlines, set(f.readlines()))
1074
1075 # Check we can run it again and bbappend isn't modified
1076 result = runCmd('devtool update-recipe -m srcrev %s -a %s' % (testrecipe, templayerdir))
1077 with open(bbappendfile, 'r') as f:
1078 self.assertEqual(expectedlines, set(f.readlines()))
1079 # Drop new commit and check SRCREV changes
1080 result = runCmd('git reset HEAD^', cwd=tempsrcdir)
1081 result = runCmd('devtool update-recipe -m srcrev %s -a %s' % (testrecipe, templayerdir))
1082 self.assertNotExists(os.path.join(appenddir, testrecipe), 'Patch directory should not be created')
1083 result = runCmd('git rev-parse HEAD', cwd=tempsrcdir)
1084 expectedlines = set(['SRCREV = "%s"\n' % result.output,
1085 '\n',
1086 'SRC_URI = "%s"\n' % git_uri,
1087 '\n'])
1088 with open(bbappendfile, 'r') as f:
1089 self.assertEqual(expectedlines, set(f.readlines()))
1090 # Put commit back and check we can run it if layer isn't in bblayers.conf
1091 os.remove(bbappendfile)
1092 result = runCmd('git commit -a -m "Change the Makefile"', cwd=tempsrcdir)
1093 result = runCmd('bitbake-layers remove-layer %s' % templayerdir, cwd=self.builddir)
1094 result = runCmd('devtool update-recipe -m srcrev %s -a %s' % (testrecipe, templayerdir))
1095 self.assertIn('WARNING: Specified layer is not currently enabled in bblayers.conf', result.output)
1096 self.assertNotExists(os.path.join(appenddir, testrecipe), 'Patch directory should not be created')
1097 result = runCmd('git rev-parse HEAD', cwd=tempsrcdir)
1098 expectedlines = set(['SRCREV = "%s"\n' % result.output,
1099 '\n',
1100 'SRC_URI = "%s"\n' % git_uri,
1101 '\n'])
1102 with open(bbappendfile, 'r') as f:
1103 self.assertEqual(expectedlines, set(f.readlines()))
1104 # Deleting isn't expected to work under these circumstances
1105
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001106 def test_devtool_update_recipe_local_files(self):
1107 """Check that local source files are copied over instead of patched"""
1108 testrecipe = 'makedevs'
1109 recipefile = get_bb_var('FILE', testrecipe)
1110 # Setup srctree for modifying the recipe
1111 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1112 self.track_for_cleanup(tempdir)
1113 self.track_for_cleanup(self.workspacedir)
1114 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1115 # (don't bother with cleaning the recipe on teardown, we won't be
1116 # building it)
1117 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
1118 # Check git repo
1119 self._check_src_repo(tempdir)
1120 # Try building just to ensure we haven't broken that
1121 bitbake("%s" % testrecipe)
1122 # Edit / commit local source
1123 runCmd('echo "/* Foobar */" >> oe-local-files/makedevs.c', cwd=tempdir)
1124 runCmd('echo "Foo" > oe-local-files/new-local', cwd=tempdir)
1125 runCmd('echo "Bar" > new-file', cwd=tempdir)
1126 runCmd('git add new-file', cwd=tempdir)
1127 runCmd('git commit -m "Add new file"', cwd=tempdir)
1128 self.add_command_to_tearDown('cd %s; git clean -fd .; git checkout .' %
1129 os.path.dirname(recipefile))
1130 runCmd('devtool update-recipe %s' % testrecipe)
1131 expected_status = [(' M', '.*/%s$' % os.path.basename(recipefile)),
1132 (' M', '.*/makedevs/makedevs.c$'),
1133 ('??', '.*/makedevs/new-local$'),
1134 ('??', '.*/makedevs/0001-Add-new-file.patch$')]
1135 self._check_repo_status(os.path.dirname(recipefile), expected_status)
1136
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001137 def test_devtool_update_recipe_local_files_2(self):
1138 """Check local source files support when oe-local-files is in Git"""
Brad Bishop316dfdd2018-06-25 12:45:53 -04001139 testrecipe = 'devtool-test-local'
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001140 recipefile = get_bb_var('FILE', testrecipe)
Brad Bishop316dfdd2018-06-25 12:45:53 -04001141 recipedir = os.path.dirname(recipefile)
1142 result = runCmd('git status --porcelain .', cwd=recipedir)
1143 if result.output.strip():
1144 self.fail('Recipe directory for %s contains uncommitted changes' % testrecipe)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001145 # Setup srctree for modifying the recipe
1146 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1147 self.track_for_cleanup(tempdir)
1148 self.track_for_cleanup(self.workspacedir)
1149 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1150 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
1151 # Check git repo
1152 self._check_src_repo(tempdir)
1153 # Add oe-local-files to Git
1154 runCmd('rm oe-local-files/.gitignore', cwd=tempdir)
1155 runCmd('git add oe-local-files', cwd=tempdir)
1156 runCmd('git commit -m "Add local sources"', cwd=tempdir)
1157 # Edit / commit local sources
Brad Bishop316dfdd2018-06-25 12:45:53 -04001158 runCmd('echo "# Foobar" >> oe-local-files/file1', cwd=tempdir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001159 runCmd('git commit -am "Edit existing file"', cwd=tempdir)
Brad Bishop316dfdd2018-06-25 12:45:53 -04001160 runCmd('git rm oe-local-files/file2', cwd=tempdir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001161 runCmd('git commit -m"Remove file"', cwd=tempdir)
1162 runCmd('echo "Foo" > oe-local-files/new-local', cwd=tempdir)
1163 runCmd('git add oe-local-files/new-local', cwd=tempdir)
1164 runCmd('git commit -m "Add new local file"', cwd=tempdir)
1165 runCmd('echo "Gar" > new-file', cwd=tempdir)
1166 runCmd('git add new-file', cwd=tempdir)
1167 runCmd('git commit -m "Add new file"', cwd=tempdir)
1168 self.add_command_to_tearDown('cd %s; git clean -fd .; git checkout .' %
1169 os.path.dirname(recipefile))
1170 # Checkout unmodified file to working copy -> devtool should still pick
1171 # the modified version from HEAD
Brad Bishop316dfdd2018-06-25 12:45:53 -04001172 runCmd('git checkout HEAD^ -- oe-local-files/file1', cwd=tempdir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001173 runCmd('devtool update-recipe %s' % testrecipe)
1174 expected_status = [(' M', '.*/%s$' % os.path.basename(recipefile)),
Brad Bishop316dfdd2018-06-25 12:45:53 -04001175 (' M', '.*/file1$'),
1176 (' D', '.*/file2$'),
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001177 ('??', '.*/new-local$'),
1178 ('??', '.*/0001-Add-new-file.patch$')]
1179 self._check_repo_status(os.path.dirname(recipefile), expected_status)
1180
Andrew Geissler4ed12e12020-06-05 18:00:41 -05001181 def test_devtool_update_recipe_with_gitignore(self):
1182 # First, modify the recipe
1183 testrecipe = 'devtool-test-ignored'
1184 bb_vars = get_bb_vars(['FILE'], testrecipe)
1185 recipefile = bb_vars['FILE']
1186 patchfile = os.path.join(os.path.dirname(recipefile), testrecipe, testrecipe + '.patch')
1187 newpatchfile = os.path.join(os.path.dirname(recipefile), testrecipe, testrecipe + '.patch.expected')
1188 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1189 self.track_for_cleanup(tempdir)
1190 self.track_for_cleanup(self.workspacedir)
1191 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1192 # (don't bother with cleaning the recipe on teardown, we won't be building it)
1193 result = runCmd('devtool modify %s' % testrecipe)
1194 self.add_command_to_tearDown('cd %s; rm %s/*; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, testrecipe, os.path.basename(recipefile)))
1195 result = runCmd('devtool finish --force-patch-refresh %s meta-selftest' % testrecipe)
1196 # Check recipe got changed as expected
1197 with open(newpatchfile, 'r') as f:
1198 desiredlines = f.readlines()
1199 with open(patchfile, 'r') as f:
1200 newlines = f.readlines()
1201 # Ignore the initial lines, because oe-selftest creates own meta-selftest repo
1202 # which changes the metadata subject which is added into the patch, but keep
1203 # .patch.expected as it is in case someone runs devtool finish --force-patch-refresh
1204 # devtool-test-ignored manually, then it should generate exactly the same .patch file
1205 self.assertEqual(desiredlines[5:], newlines[5:])
1206
1207 def test_devtool_update_recipe_long_filename(self):
1208 # First, modify the recipe
1209 testrecipe = 'devtool-test-long-filename'
1210 bb_vars = get_bb_vars(['FILE'], testrecipe)
1211 recipefile = bb_vars['FILE']
1212 patchfilename = '0001-I-ll-patch-you-only-if-devtool-lets-me-to-do-it-corr.patch'
1213 patchfile = os.path.join(os.path.dirname(recipefile), testrecipe, patchfilename)
1214 newpatchfile = os.path.join(os.path.dirname(recipefile), testrecipe, patchfilename + '.expected')
1215 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1216 self.track_for_cleanup(tempdir)
1217 self.track_for_cleanup(self.workspacedir)
1218 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1219 # (don't bother with cleaning the recipe on teardown, we won't be building it)
1220 result = runCmd('devtool modify %s' % testrecipe)
1221 self.add_command_to_tearDown('cd %s; rm %s/*; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, testrecipe, os.path.basename(recipefile)))
1222 result = runCmd('devtool finish --force-patch-refresh %s meta-selftest' % testrecipe)
1223 # Check recipe got changed as expected
1224 with open(newpatchfile, 'r') as f:
1225 desiredlines = f.readlines()
1226 with open(patchfile, 'r') as f:
1227 newlines = f.readlines()
1228 # Ignore the initial lines, because oe-selftest creates own meta-selftest repo
1229 # which changes the metadata subject which is added into the patch, but keep
1230 # .patch.expected as it is in case someone runs devtool finish --force-patch-refresh
1231 # devtool-test-ignored manually, then it should generate exactly the same .patch file
1232 self.assertEqual(desiredlines[5:], newlines[5:])
1233
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001234 def test_devtool_update_recipe_local_files_3(self):
1235 # First, modify the recipe
1236 testrecipe = 'devtool-test-localonly'
1237 bb_vars = get_bb_vars(['FILE', 'SRC_URI'], testrecipe)
1238 recipefile = bb_vars['FILE']
1239 src_uri = bb_vars['SRC_URI']
1240 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1241 self.track_for_cleanup(tempdir)
1242 self.track_for_cleanup(self.workspacedir)
1243 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1244 # (don't bother with cleaning the recipe on teardown, we won't be building it)
1245 result = runCmd('devtool modify %s' % testrecipe)
1246 # Modify one file
1247 runCmd('echo "Another line" >> file2', cwd=os.path.join(self.workspacedir, 'sources', testrecipe, 'oe-local-files'))
1248 self.add_command_to_tearDown('cd %s; rm %s/*; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, testrecipe, os.path.basename(recipefile)))
1249 result = runCmd('devtool update-recipe %s' % testrecipe)
1250 expected_status = [(' M', '.*/%s/file2$' % testrecipe)]
1251 self._check_repo_status(os.path.dirname(recipefile), expected_status)
1252
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001253 def test_devtool_update_recipe_local_patch_gz(self):
1254 # First, modify the recipe
1255 testrecipe = 'devtool-test-patch-gz'
1256 if get_bb_var('DISTRO') == 'poky-tiny':
1257 self.skipTest("The DISTRO 'poky-tiny' does not provide the dependencies needed by %s" % testrecipe)
1258 bb_vars = get_bb_vars(['FILE', 'SRC_URI'], testrecipe)
1259 recipefile = bb_vars['FILE']
1260 src_uri = bb_vars['SRC_URI']
1261 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1262 self.track_for_cleanup(tempdir)
1263 self.track_for_cleanup(self.workspacedir)
1264 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1265 # (don't bother with cleaning the recipe on teardown, we won't be building it)
1266 result = runCmd('devtool modify %s' % testrecipe)
1267 # Modify one file
1268 srctree = os.path.join(self.workspacedir, 'sources', testrecipe)
1269 runCmd('echo "Another line" >> README', cwd=srctree)
1270 runCmd('git commit -a --amend --no-edit', cwd=srctree)
1271 self.add_command_to_tearDown('cd %s; rm %s/*; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, testrecipe, os.path.basename(recipefile)))
1272 result = runCmd('devtool update-recipe %s' % testrecipe)
1273 expected_status = [(' M', '.*/%s/readme.patch.gz$' % testrecipe)]
1274 self._check_repo_status(os.path.dirname(recipefile), expected_status)
1275 patch_gz = os.path.join(os.path.dirname(recipefile), testrecipe, 'readme.patch.gz')
1276 result = runCmd('file %s' % patch_gz)
1277 if 'gzip compressed data' not in result.output:
1278 self.fail('New patch file is not gzipped - file reports:\n%s' % result.output)
1279
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001280 def test_devtool_update_recipe_local_files_subdir(self):
1281 # Try devtool update-recipe on a recipe that has a file with subdir= set in
1282 # SRC_URI such that it overwrites a file that was in an archive that
1283 # was also in SRC_URI
1284 # First, modify the recipe
1285 testrecipe = 'devtool-test-subdir'
1286 bb_vars = get_bb_vars(['FILE', 'SRC_URI'], testrecipe)
1287 recipefile = bb_vars['FILE']
1288 src_uri = bb_vars['SRC_URI']
1289 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1290 self.track_for_cleanup(tempdir)
1291 self.track_for_cleanup(self.workspacedir)
1292 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1293 # (don't bother with cleaning the recipe on teardown, we won't be building it)
1294 result = runCmd('devtool modify %s' % testrecipe)
1295 testfile = os.path.join(self.workspacedir, 'sources', testrecipe, 'testfile')
1296 self.assertExists(testfile, 'Extracted source could not be found')
1297 with open(testfile, 'r') as f:
1298 contents = f.read().rstrip()
1299 self.assertEqual(contents, 'Modified version', 'File has apparently not been overwritten as it should have been')
1300 # Test devtool update-recipe without modifying any files
1301 self.add_command_to_tearDown('cd %s; rm %s/*; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, testrecipe, os.path.basename(recipefile)))
1302 result = runCmd('devtool update-recipe %s' % testrecipe)
1303 expected_status = []
1304 self._check_repo_status(os.path.dirname(recipefile), expected_status)
1305
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001306class DevtoolExtractTests(DevtoolBase):
1307
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001308 def test_devtool_extract(self):
1309 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1310 # Try devtool extract
1311 self.track_for_cleanup(tempdir)
1312 self.track_for_cleanup(self.workspacedir)
1313 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1314 result = runCmd('devtool extract matchbox-terminal %s' % tempdir)
1315 self.assertExists(os.path.join(tempdir, 'Makefile.am'), 'Extracted source could not be found')
1316 self._check_src_repo(tempdir)
1317
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001318 def test_devtool_extract_virtual(self):
1319 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1320 # Try devtool extract
1321 self.track_for_cleanup(tempdir)
1322 self.track_for_cleanup(self.workspacedir)
1323 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1324 result = runCmd('devtool extract virtual/make %s' % tempdir)
1325 self.assertExists(os.path.join(tempdir, 'Makefile.am'), 'Extracted source could not be found')
1326 self._check_src_repo(tempdir)
1327
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001328 def test_devtool_reset_all(self):
1329 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1330 self.track_for_cleanup(tempdir)
1331 self.track_for_cleanup(self.workspacedir)
1332 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1333 testrecipe1 = 'mdadm'
1334 testrecipe2 = 'cronie'
1335 result = runCmd('devtool modify -x %s %s' % (testrecipe1, os.path.join(tempdir, testrecipe1)))
1336 result = runCmd('devtool modify -x %s %s' % (testrecipe2, os.path.join(tempdir, testrecipe2)))
1337 result = runCmd('devtool build %s' % testrecipe1)
1338 result = runCmd('devtool build %s' % testrecipe2)
1339 stampprefix1 = get_bb_var('STAMP', testrecipe1)
1340 self.assertTrue(stampprefix1, 'Unable to get STAMP value for recipe %s' % testrecipe1)
1341 stampprefix2 = get_bb_var('STAMP', testrecipe2)
1342 self.assertTrue(stampprefix2, 'Unable to get STAMP value for recipe %s' % testrecipe2)
1343 result = runCmd('devtool reset -a')
1344 self.assertIn(testrecipe1, result.output)
1345 self.assertIn(testrecipe2, result.output)
1346 result = runCmd('devtool status')
1347 self.assertNotIn(testrecipe1, result.output)
1348 self.assertNotIn(testrecipe2, result.output)
1349 matches1 = glob.glob(stampprefix1 + '*')
1350 self.assertFalse(matches1, 'Stamp files exist for recipe %s that should have been cleaned' % testrecipe1)
1351 matches2 = glob.glob(stampprefix2 + '*')
1352 self.assertFalse(matches2, 'Stamp files exist for recipe %s that should have been cleaned' % testrecipe2)
1353
Patrick Williams45852732022-04-02 08:58:32 -05001354 @OETestTag("runqemu")
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001355 def test_devtool_deploy_target(self):
1356 # NOTE: Whilst this test would seemingly be better placed as a runtime test,
1357 # unfortunately the runtime tests run under bitbake and you can't run
1358 # devtool within bitbake (since devtool needs to run bitbake itself).
1359 # Additionally we are testing build-time functionality as well, so
1360 # really this has to be done as an oe-selftest test.
1361 #
1362 # Check preconditions
1363 machine = get_bb_var('MACHINE')
1364 if not machine.startswith('qemu'):
1365 self.skipTest('This test only works with qemu machines')
1366 if not os.path.exists('/etc/runqemu-nosudo'):
1367 self.skipTest('You must set up tap devices with scripts/runqemu-gen-tapdevs before running this test')
1368 result = runCmd('PATH="$PATH:/sbin:/usr/sbin" ip tuntap show', ignore_status=True)
1369 if result.status != 0:
1370 result = runCmd('PATH="$PATH:/sbin:/usr/sbin" ifconfig -a', ignore_status=True)
1371 if result.status != 0:
1372 self.skipTest('Failed to determine if tap devices exist with ifconfig or ip: %s' % result.output)
1373 for line in result.output.splitlines():
1374 if line.startswith('tap'):
1375 break
1376 else:
1377 self.skipTest('No tap devices found - you must set up tap devices with scripts/runqemu-gen-tapdevs before running this test')
1378 self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
1379 # Definitions
1380 testrecipe = 'mdadm'
1381 testfile = '/sbin/mdadm'
1382 testimage = 'oe-selftest-image'
1383 testcommand = '/sbin/mdadm --help'
1384 # Build an image to run
1385 bitbake("%s qemu-native qemu-helper-native" % testimage)
1386 deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
1387 self.add_command_to_tearDown('bitbake -c clean %s' % testimage)
1388 self.add_command_to_tearDown('rm -f %s/%s*' % (deploy_dir_image, testimage))
1389 # Clean recipe so the first deploy will fail
1390 bitbake("%s -c clean" % testrecipe)
1391 # Try devtool modify
1392 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1393 self.track_for_cleanup(tempdir)
1394 self.track_for_cleanup(self.workspacedir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001395 self.add_command_to_tearDown('bitbake -c clean %s' % testrecipe)
Brad Bishop00e122a2019-10-05 11:10:57 -04001396 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001397 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
1398 # Test that deploy-target at this point fails (properly)
1399 result = runCmd('devtool deploy-target -n %s root@localhost' % testrecipe, ignore_status=True)
1400 self.assertNotEqual(result.output, 0, 'devtool deploy-target should have failed, output: %s' % result.output)
1401 self.assertNotIn(result.output, 'Traceback', 'devtool deploy-target should have failed with a proper error not a traceback, output: %s' % result.output)
1402 result = runCmd('devtool build %s' % testrecipe)
1403 # First try a dry-run of deploy-target
1404 result = runCmd('devtool deploy-target -n %s root@localhost' % testrecipe)
1405 self.assertIn(' %s' % testfile, result.output)
1406 # Boot the image
1407 with runqemu(testimage) as qemu:
1408 # Now really test deploy-target
1409 result = runCmd('devtool deploy-target -c %s root@%s' % (testrecipe, qemu.ip))
1410 # Run a test command to see if it was installed properly
1411 sshargs = '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'
1412 result = runCmd('ssh %s root@%s %s' % (sshargs, qemu.ip, testcommand))
1413 # Check if it deployed all of the files with the right ownership/perms
1414 # First look on the host - need to do this under pseudo to get the correct ownership/perms
1415 bb_vars = get_bb_vars(['D', 'FAKEROOTENV', 'FAKEROOTCMD'], testrecipe)
1416 installdir = bb_vars['D']
1417 fakerootenv = bb_vars['FAKEROOTENV']
1418 fakerootcmd = bb_vars['FAKEROOTCMD']
Brad Bishop19323692019-04-05 15:28:33 -04001419 result = runCmd('%s %s find . -type f -exec ls -l {} \\;' % (fakerootenv, fakerootcmd), cwd=installdir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001420 filelist1 = self._process_ls_output(result.output)
1421
1422 # Now look on the target
1423 tempdir2 = tempfile.mkdtemp(prefix='devtoolqa')
1424 self.track_for_cleanup(tempdir2)
1425 tmpfilelist = os.path.join(tempdir2, 'files.txt')
1426 with open(tmpfilelist, 'w') as f:
1427 for line in filelist1:
1428 splitline = line.split()
1429 f.write(splitline[-1] + '\n')
1430 result = runCmd('cat %s | ssh -q %s root@%s \'xargs ls -l\'' % (tmpfilelist, sshargs, qemu.ip))
1431 filelist2 = self._process_ls_output(result.output)
1432 filelist1.sort(key=lambda item: item.split()[-1])
1433 filelist2.sort(key=lambda item: item.split()[-1])
1434 self.assertEqual(filelist1, filelist2)
1435 # Test undeploy-target
1436 result = runCmd('devtool undeploy-target -c %s root@%s' % (testrecipe, qemu.ip))
1437 result = runCmd('ssh %s root@%s %s' % (sshargs, qemu.ip, testcommand), ignore_status=True)
1438 self.assertNotEqual(result, 0, 'undeploy-target did not remove command as it should have')
1439
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001440 def test_devtool_build_image(self):
1441 """Test devtool build-image plugin"""
1442 # Check preconditions
1443 self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
1444 image = 'core-image-minimal'
1445 self.track_for_cleanup(self.workspacedir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001446 self.add_command_to_tearDown('bitbake -c clean %s' % image)
Brad Bishop00e122a2019-10-05 11:10:57 -04001447 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001448 bitbake('%s -c clean' % image)
1449 # Add target and native recipes to workspace
1450 recipes = ['mdadm', 'parted-native']
1451 for recipe in recipes:
1452 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1453 self.track_for_cleanup(tempdir)
1454 self.add_command_to_tearDown('bitbake -c clean %s' % recipe)
1455 runCmd('devtool modify %s -x %s' % (recipe, tempdir))
1456 # Try to build image
1457 result = runCmd('devtool build-image %s' % image)
1458 self.assertNotEqual(result, 0, 'devtool build-image failed')
1459 # Check if image contains expected packages
1460 deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
1461 image_link_name = get_bb_var('IMAGE_LINK_NAME', image)
1462 reqpkgs = [item for item in recipes if not item.endswith('-native')]
1463 with open(os.path.join(deploy_dir_image, image_link_name + '.manifest'), 'r') as f:
1464 for line in f:
1465 splitval = line.split()
1466 if splitval:
1467 pkg = splitval[0]
1468 if pkg in reqpkgs:
1469 reqpkgs.remove(pkg)
1470 if reqpkgs:
1471 self.fail('The following packages were not present in the image as expected: %s' % ', '.join(reqpkgs))
1472
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001473class DevtoolUpgradeTests(DevtoolBase):
1474
Patrick Williams45852732022-04-02 08:58:32 -05001475 def setUp(self):
1476 super().setUp()
1477 try:
1478 runCmd("git config --global user.name")
1479 runCmd("git config --global user.email")
1480 except:
1481 self.skip("Git user.name and user.email must be set")
1482
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001483 def test_devtool_upgrade(self):
1484 # Check preconditions
1485 self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
1486 self.track_for_cleanup(self.workspacedir)
1487 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1488 # Check parameters
1489 result = runCmd('devtool upgrade -h')
1490 for param in 'recipename srctree --version -V --branch -b --keep-temp --no-patch'.split():
1491 self.assertIn(param, result.output)
1492 # For the moment, we are using a real recipe.
1493 recipe = 'devtool-upgrade-test1'
1494 version = '1.6.0'
1495 oldrecipefile = get_bb_var('FILE', recipe)
1496 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1497 self.track_for_cleanup(tempdir)
1498 # Check that recipe is not already under devtool control
1499 result = runCmd('devtool status')
1500 self.assertNotIn(recipe, result.output)
1501 # Check upgrade. Code does not check if new PV is older or newer that current PV, so, it may be that
1502 # we are downgrading instead of upgrading.
1503 result = runCmd('devtool upgrade %s %s -V %s' % (recipe, tempdir, version))
1504 # Check if srctree at least is populated
1505 self.assertTrue(len(os.listdir(tempdir)) > 0, 'srctree (%s) should be populated with new (%s) source code' % (tempdir, version))
1506 # Check new recipe subdirectory is present
1507 self.assertExists(os.path.join(self.workspacedir, 'recipes', recipe, '%s-%s' % (recipe, version)), 'Recipe folder should exist')
1508 # Check new recipe file is present
1509 newrecipefile = os.path.join(self.workspacedir, 'recipes', recipe, '%s_%s.bb' % (recipe, version))
1510 self.assertExists(newrecipefile, 'Recipe file should exist after upgrade')
1511 # Check devtool status and make sure recipe is present
1512 result = runCmd('devtool status')
1513 self.assertIn(recipe, result.output)
1514 self.assertIn(tempdir, result.output)
1515 # Check recipe got changed as expected
1516 with open(oldrecipefile + '.upgraded', 'r') as f:
1517 desiredlines = f.readlines()
1518 with open(newrecipefile, 'r') as f:
1519 newlines = f.readlines()
1520 self.assertEqual(desiredlines, newlines)
1521 # Check devtool reset recipe
1522 result = runCmd('devtool reset %s -n' % recipe)
1523 result = runCmd('devtool status')
1524 self.assertNotIn(recipe, result.output)
1525 self.assertNotExists(os.path.join(self.workspacedir, 'recipes', recipe), 'Recipe directory should not exist after resetting')
1526
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001527 def test_devtool_upgrade_git(self):
1528 # Check preconditions
1529 self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
1530 self.track_for_cleanup(self.workspacedir)
1531 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1532 recipe = 'devtool-upgrade-test2'
1533 commit = '6cc6077a36fe2648a5f993fe7c16c9632f946517'
1534 oldrecipefile = get_bb_var('FILE', recipe)
1535 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1536 self.track_for_cleanup(tempdir)
1537 # Check that recipe is not already under devtool control
1538 result = runCmd('devtool status')
1539 self.assertNotIn(recipe, result.output)
1540 # Check upgrade
1541 result = runCmd('devtool upgrade %s %s -S %s' % (recipe, tempdir, commit))
1542 # Check if srctree at least is populated
1543 self.assertTrue(len(os.listdir(tempdir)) > 0, 'srctree (%s) should be populated with new (%s) source code' % (tempdir, commit))
1544 # Check new recipe file is present
1545 newrecipefile = os.path.join(self.workspacedir, 'recipes', recipe, os.path.basename(oldrecipefile))
1546 self.assertExists(newrecipefile, 'Recipe file should exist after upgrade')
1547 # Check devtool status and make sure recipe is present
1548 result = runCmd('devtool status')
1549 self.assertIn(recipe, result.output)
1550 self.assertIn(tempdir, result.output)
1551 # Check recipe got changed as expected
1552 with open(oldrecipefile + '.upgraded', 'r') as f:
1553 desiredlines = f.readlines()
1554 with open(newrecipefile, 'r') as f:
1555 newlines = f.readlines()
1556 self.assertEqual(desiredlines, newlines)
1557 # Check devtool reset recipe
1558 result = runCmd('devtool reset %s -n' % recipe)
1559 result = runCmd('devtool status')
1560 self.assertNotIn(recipe, result.output)
1561 self.assertNotExists(os.path.join(self.workspacedir, 'recipes', recipe), 'Recipe directory should not exist after resetting')
1562
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001563 def test_devtool_layer_plugins(self):
1564 """Test that devtool can use plugins from other layers.
1565
1566 This test executes the selftest-reverse command from meta-selftest."""
1567
1568 self.track_for_cleanup(self.workspacedir)
1569 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1570
1571 s = "Microsoft Made No Profit From Anyone's Zunes Yo"
1572 result = runCmd("devtool --quiet selftest-reverse \"%s\"" % s)
1573 self.assertEqual(result.output, s[::-1])
1574
1575 def _copy_file_with_cleanup(self, srcfile, basedstdir, *paths):
1576 dstdir = basedstdir
1577 self.assertExists(dstdir)
1578 for p in paths:
1579 dstdir = os.path.join(dstdir, p)
1580 if not os.path.exists(dstdir):
1581 os.makedirs(dstdir)
Andrew Geissler475cb722020-07-10 16:00:51 -05001582 if p == "lib":
1583 # Can race with other tests
1584 self.add_command_to_tearDown('rmdir --ignore-fail-on-non-empty %s' % dstdir)
1585 else:
1586 self.track_for_cleanup(dstdir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001587 dstfile = os.path.join(dstdir, os.path.basename(srcfile))
1588 if srcfile != dstfile:
1589 shutil.copy(srcfile, dstfile)
1590 self.track_for_cleanup(dstfile)
1591
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001592 def test_devtool_load_plugin(self):
1593 """Test that devtool loads only the first found plugin in BBPATH."""
1594
1595 self.track_for_cleanup(self.workspacedir)
1596 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1597
1598 devtool = runCmd("which devtool")
1599 fromname = runCmd("devtool --quiet pluginfile")
1600 srcfile = fromname.output
1601 bbpath = get_bb_var('BBPATH')
1602 searchpath = bbpath.split(':') + [os.path.dirname(devtool.output)]
1603 plugincontent = []
1604 with open(srcfile) as fh:
1605 plugincontent = fh.readlines()
1606 try:
1607 self.assertIn('meta-selftest', srcfile, 'wrong bbpath plugin found')
1608 for path in searchpath:
1609 self._copy_file_with_cleanup(srcfile, path, 'lib', 'devtool')
1610 result = runCmd("devtool --quiet count")
1611 self.assertEqual(result.output, '1')
1612 result = runCmd("devtool --quiet multiloaded")
1613 self.assertEqual(result.output, "no")
1614 for path in searchpath:
1615 result = runCmd("devtool --quiet bbdir")
1616 self.assertEqual(result.output, path)
1617 os.unlink(os.path.join(result.output, 'lib', 'devtool', 'bbpath.py'))
1618 finally:
1619 with open(srcfile, 'w') as fh:
1620 fh.writelines(plugincontent)
1621
1622 def _setup_test_devtool_finish_upgrade(self):
1623 # Check preconditions
1624 self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
1625 self.track_for_cleanup(self.workspacedir)
1626 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1627 # Use a "real" recipe from meta-selftest
1628 recipe = 'devtool-upgrade-test1'
1629 oldversion = '1.5.3'
1630 newversion = '1.6.0'
1631 oldrecipefile = get_bb_var('FILE', recipe)
1632 recipedir = os.path.dirname(oldrecipefile)
1633 result = runCmd('git status --porcelain .', cwd=recipedir)
1634 if result.output.strip():
1635 self.fail('Recipe directory for %s contains uncommitted changes' % recipe)
1636 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1637 self.track_for_cleanup(tempdir)
1638 # Check that recipe is not already under devtool control
1639 result = runCmd('devtool status')
1640 self.assertNotIn(recipe, result.output)
1641 # Do the upgrade
1642 result = runCmd('devtool upgrade %s %s -V %s' % (recipe, tempdir, newversion))
1643 # Check devtool status and make sure recipe is present
1644 result = runCmd('devtool status')
1645 self.assertIn(recipe, result.output)
1646 self.assertIn(tempdir, result.output)
1647 # Make a change to the source
1648 result = runCmd('sed -i \'/^#include "pv.h"/a \\/* Here is a new comment *\\/\' src/pv/number.c', cwd=tempdir)
1649 result = runCmd('git status --porcelain', cwd=tempdir)
1650 self.assertIn('M src/pv/number.c', result.output)
1651 result = runCmd('git commit src/pv/number.c -m "Add a comment to the code"', cwd=tempdir)
1652 # Check if patch is there
1653 recipedir = os.path.dirname(oldrecipefile)
1654 olddir = os.path.join(recipedir, recipe + '-' + oldversion)
1655 patchfn = '0001-Add-a-note-line-to-the-quick-reference.patch'
Brad Bishop6dbb3162019-11-25 09:41:34 -05001656 backportedpatchfn = 'backported.patch'
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001657 self.assertExists(os.path.join(olddir, patchfn), 'Original patch file does not exist')
Brad Bishop6dbb3162019-11-25 09:41:34 -05001658 self.assertExists(os.path.join(olddir, backportedpatchfn), 'Backported patch file does not exist')
1659 return recipe, oldrecipefile, recipedir, olddir, newversion, patchfn, backportedpatchfn
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001660
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001661 def test_devtool_finish_upgrade_origlayer(self):
Brad Bishop6dbb3162019-11-25 09:41:34 -05001662 recipe, oldrecipefile, recipedir, olddir, newversion, patchfn, backportedpatchfn = self._setup_test_devtool_finish_upgrade()
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001663 # Ensure the recipe is where we think it should be (so that cleanup doesn't trash things)
1664 self.assertIn('/meta-selftest/', recipedir)
1665 # Try finish to the original layer
1666 self.add_command_to_tearDown('rm -rf %s ; cd %s ; git checkout %s' % (recipedir, os.path.dirname(recipedir), recipedir))
1667 result = runCmd('devtool finish %s meta-selftest' % recipe)
1668 result = runCmd('devtool status')
1669 self.assertNotIn(recipe, result.output, 'Recipe should have been reset by finish but wasn\'t')
1670 self.assertNotExists(os.path.join(self.workspacedir, 'recipes', recipe), 'Recipe directory should not exist after finish')
1671 self.assertNotExists(oldrecipefile, 'Old recipe file should have been deleted but wasn\'t')
1672 self.assertNotExists(os.path.join(olddir, patchfn), 'Old patch file should have been deleted but wasn\'t')
Brad Bishop6dbb3162019-11-25 09:41:34 -05001673 self.assertNotExists(os.path.join(olddir, backportedpatchfn), 'Old backported patch file should have been deleted but wasn\'t')
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001674 newrecipefile = os.path.join(recipedir, '%s_%s.bb' % (recipe, newversion))
1675 newdir = os.path.join(recipedir, recipe + '-' + newversion)
1676 self.assertExists(newrecipefile, 'New recipe file should have been copied into existing layer but wasn\'t')
1677 self.assertExists(os.path.join(newdir, patchfn), 'Patch file should have been copied into new directory but wasn\'t')
Brad Bishop6dbb3162019-11-25 09:41:34 -05001678 self.assertNotExists(os.path.join(newdir, backportedpatchfn), 'Backported patch file should not have been copied into new directory but was')
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001679 self.assertExists(os.path.join(newdir, '0002-Add-a-comment-to-the-code.patch'), 'New patch file should have been created but wasn\'t')
Brad Bishop6dbb3162019-11-25 09:41:34 -05001680 with open(newrecipefile, 'r') as f:
1681 newcontent = f.read()
1682 self.assertNotIn(backportedpatchfn, newcontent, "Backported patch should have been removed from the recipe but wasn't")
1683 self.assertIn(patchfn, newcontent, "Old patch should have not been removed from the recipe but was")
1684 self.assertIn("0002-Add-a-comment-to-the-code.patch", newcontent, "New patch should have been added to the recipe but wasn't")
1685 self.assertIn("http://www.ivarch.com/programs/sources/pv-${PV}.tar.gz", newcontent, "New recipe no longer has upstream source in SRC_URI")
1686
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001687
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001688 def test_devtool_finish_upgrade_otherlayer(self):
Brad Bishop6dbb3162019-11-25 09:41:34 -05001689 recipe, oldrecipefile, recipedir, olddir, newversion, patchfn, backportedpatchfn = self._setup_test_devtool_finish_upgrade()
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001690 # Ensure the recipe is where we think it should be (so that cleanup doesn't trash things)
1691 self.assertIn('/meta-selftest/', recipedir)
1692 # Try finish to a different layer - should create a bbappend
1693 # This cleanup isn't strictly necessary but do it anyway just in case it goes wrong and writes to here
1694 self.add_command_to_tearDown('rm -rf %s ; cd %s ; git checkout %s' % (recipedir, os.path.dirname(recipedir), recipedir))
1695 oe_core_dir = os.path.join(get_bb_var('COREBASE'), 'meta')
1696 newrecipedir = os.path.join(oe_core_dir, 'recipes-test', 'devtool')
1697 newrecipefile = os.path.join(newrecipedir, '%s_%s.bb' % (recipe, newversion))
1698 self.track_for_cleanup(newrecipedir)
1699 result = runCmd('devtool finish %s oe-core' % recipe)
1700 result = runCmd('devtool status')
1701 self.assertNotIn(recipe, result.output, 'Recipe should have been reset by finish but wasn\'t')
1702 self.assertNotExists(os.path.join(self.workspacedir, 'recipes', recipe), 'Recipe directory should not exist after finish')
1703 self.assertExists(oldrecipefile, 'Old recipe file should not have been deleted')
1704 self.assertExists(os.path.join(olddir, patchfn), 'Old patch file should not have been deleted')
Brad Bishop6dbb3162019-11-25 09:41:34 -05001705 self.assertExists(os.path.join(olddir, backportedpatchfn), 'Old backported patch file should not have been deleted')
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001706 newdir = os.path.join(newrecipedir, recipe + '-' + newversion)
1707 self.assertExists(newrecipefile, 'New recipe file should have been copied into existing layer but wasn\'t')
1708 self.assertExists(os.path.join(newdir, patchfn), 'Patch file should have been copied into new directory but wasn\'t')
Brad Bishop6dbb3162019-11-25 09:41:34 -05001709 self.assertNotExists(os.path.join(newdir, backportedpatchfn), 'Backported patch file should not have been copied into new directory but was')
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001710 self.assertExists(os.path.join(newdir, '0002-Add-a-comment-to-the-code.patch'), 'New patch file should have been created but wasn\'t')
Brad Bishop6dbb3162019-11-25 09:41:34 -05001711 with open(newrecipefile, 'r') as f:
1712 newcontent = f.read()
1713 self.assertNotIn(backportedpatchfn, newcontent, "Backported patch should have been removed from the recipe but wasn't")
1714 self.assertIn(patchfn, newcontent, "Old patch should have not been removed from the recipe but was")
1715 self.assertIn("0002-Add-a-comment-to-the-code.patch", newcontent, "New patch should have been added to the recipe but wasn't")
1716 self.assertIn("http://www.ivarch.com/programs/sources/pv-${PV}.tar.gz", newcontent, "New recipe no longer has upstream source in SRC_URI")
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001717
1718 def _setup_test_devtool_finish_modify(self):
1719 # Check preconditions
1720 self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
1721 # Try modifying a recipe
1722 self.track_for_cleanup(self.workspacedir)
1723 recipe = 'mdadm'
1724 oldrecipefile = get_bb_var('FILE', recipe)
1725 recipedir = os.path.dirname(oldrecipefile)
1726 result = runCmd('git status --porcelain .', cwd=recipedir)
1727 if result.output.strip():
1728 self.fail('Recipe directory for %s contains uncommitted changes' % recipe)
1729 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1730 self.track_for_cleanup(tempdir)
1731 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1732 result = runCmd('devtool modify %s %s' % (recipe, tempdir))
1733 self.assertExists(os.path.join(tempdir, 'Makefile'), 'Extracted source could not be found')
1734 # Test devtool status
1735 result = runCmd('devtool status')
1736 self.assertIn(recipe, result.output)
1737 self.assertIn(tempdir, result.output)
1738 # Make a change to the source
1739 result = runCmd('sed -i \'/^#include "mdadm.h"/a \\/* Here is a new comment *\\/\' maps.c', cwd=tempdir)
1740 result = runCmd('git status --porcelain', cwd=tempdir)
1741 self.assertIn('M maps.c', result.output)
1742 result = runCmd('git commit maps.c -m "Add a comment to the code"', cwd=tempdir)
1743 for entry in os.listdir(recipedir):
1744 filesdir = os.path.join(recipedir, entry)
1745 if os.path.isdir(filesdir):
1746 break
1747 else:
1748 self.fail('Unable to find recipe files directory for %s' % recipe)
1749 return recipe, oldrecipefile, recipedir, filesdir
1750
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001751 def test_devtool_finish_modify_origlayer(self):
1752 recipe, oldrecipefile, recipedir, filesdir = self._setup_test_devtool_finish_modify()
1753 # Ensure the recipe is where we think it should be (so that cleanup doesn't trash things)
1754 self.assertIn('/meta/', recipedir)
1755 # Try finish to the original layer
1756 self.add_command_to_tearDown('rm -rf %s ; cd %s ; git checkout %s' % (recipedir, os.path.dirname(recipedir), recipedir))
1757 result = runCmd('devtool finish %s meta' % recipe)
1758 result = runCmd('devtool status')
1759 self.assertNotIn(recipe, result.output, 'Recipe should have been reset by finish but wasn\'t')
1760 self.assertNotExists(os.path.join(self.workspacedir, 'recipes', recipe), 'Recipe directory should not exist after finish')
1761 expected_status = [(' M', '.*/%s$' % os.path.basename(oldrecipefile)),
1762 ('??', '.*/.*-Add-a-comment-to-the-code.patch$')]
1763 self._check_repo_status(recipedir, expected_status)
1764
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001765 def test_devtool_finish_modify_otherlayer(self):
1766 recipe, oldrecipefile, recipedir, filesdir = self._setup_test_devtool_finish_modify()
1767 # Ensure the recipe is where we think it should be (so that cleanup doesn't trash things)
1768 self.assertIn('/meta/', recipedir)
1769 relpth = os.path.relpath(recipedir, os.path.join(get_bb_var('COREBASE'), 'meta'))
1770 appenddir = os.path.join(get_test_layer(), relpth)
1771 self.track_for_cleanup(appenddir)
1772 # Try finish to the original layer
1773 self.add_command_to_tearDown('rm -rf %s ; cd %s ; git checkout %s' % (recipedir, os.path.dirname(recipedir), recipedir))
1774 result = runCmd('devtool finish %s meta-selftest' % recipe)
1775 result = runCmd('devtool status')
1776 self.assertNotIn(recipe, result.output, 'Recipe should have been reset by finish but wasn\'t')
1777 self.assertNotExists(os.path.join(self.workspacedir, 'recipes', recipe), 'Recipe directory should not exist after finish')
1778 result = runCmd('git status --porcelain .', cwd=recipedir)
1779 if result.output.strip():
1780 self.fail('Recipe directory for %s contains the following unexpected changes after finish:\n%s' % (recipe, result.output.strip()))
1781 recipefn = os.path.splitext(os.path.basename(oldrecipefile))[0]
1782 recipefn = recipefn.split('_')[0] + '_%'
1783 appendfile = os.path.join(appenddir, recipefn + '.bbappend')
1784 self.assertExists(appendfile, 'bbappend %s should have been created but wasn\'t' % appendfile)
1785 newdir = os.path.join(appenddir, recipe)
1786 files = os.listdir(newdir)
1787 foundpatch = None
1788 for fn in files:
1789 if fnmatch.fnmatch(fn, '*-Add-a-comment-to-the-code.patch'):
1790 foundpatch = fn
1791 if not foundpatch:
1792 self.fail('No patch file created next to bbappend')
1793 files.remove(foundpatch)
1794 if files:
1795 self.fail('Unexpected file(s) copied next to bbappend: %s' % ', '.join(files))
1796
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001797 def test_devtool_rename(self):
1798 # Check preconditions
1799 self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
1800 self.track_for_cleanup(self.workspacedir)
1801 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1802
1803 # First run devtool add
1804 # We already have this recipe in OE-Core, but that doesn't matter
1805 recipename = 'i2c-tools'
1806 recipever = '3.1.2'
1807 recipefile = os.path.join(self.workspacedir, 'recipes', recipename, '%s_%s.bb' % (recipename, recipever))
1808 url = 'http://downloads.yoctoproject.org/mirror/sources/i2c-tools-%s.tar.bz2' % recipever
1809 def add_recipe():
1810 result = runCmd('devtool add %s' % url)
1811 self.assertExists(recipefile, 'Expected recipe file not created')
1812 self.assertExists(os.path.join(self.workspacedir, 'sources', recipename), 'Source directory not created')
1813 checkvars = {}
1814 checkvars['S'] = None
1815 checkvars['SRC_URI'] = url.replace(recipever, '${PV}')
1816 self._test_recipe_contents(recipefile, checkvars, [])
1817 add_recipe()
1818 # Now rename it - change both name and version
1819 newrecipename = 'mynewrecipe'
1820 newrecipever = '456'
1821 newrecipefile = os.path.join(self.workspacedir, 'recipes', newrecipename, '%s_%s.bb' % (newrecipename, newrecipever))
1822 result = runCmd('devtool rename %s %s -V %s' % (recipename, newrecipename, newrecipever))
1823 self.assertExists(newrecipefile, 'Recipe file not renamed')
1824 self.assertNotExists(os.path.join(self.workspacedir, 'recipes', recipename), 'Old recipe directory still exists')
1825 newsrctree = os.path.join(self.workspacedir, 'sources', newrecipename)
1826 self.assertExists(newsrctree, 'Source directory not renamed')
1827 checkvars = {}
1828 checkvars['S'] = '${WORKDIR}/%s-%s' % (recipename, recipever)
1829 checkvars['SRC_URI'] = url
1830 self._test_recipe_contents(newrecipefile, checkvars, [])
1831 # Try again - change just name this time
1832 result = runCmd('devtool reset -n %s' % newrecipename)
1833 shutil.rmtree(newsrctree)
1834 add_recipe()
1835 newrecipefile = os.path.join(self.workspacedir, 'recipes', newrecipename, '%s_%s.bb' % (newrecipename, recipever))
1836 result = runCmd('devtool rename %s %s' % (recipename, newrecipename))
1837 self.assertExists(newrecipefile, 'Recipe file not renamed')
1838 self.assertNotExists(os.path.join(self.workspacedir, 'recipes', recipename), 'Old recipe directory still exists')
1839 self.assertExists(os.path.join(self.workspacedir, 'sources', newrecipename), 'Source directory not renamed')
1840 checkvars = {}
1841 checkvars['S'] = '${WORKDIR}/%s-${PV}' % recipename
1842 checkvars['SRC_URI'] = url.replace(recipever, '${PV}')
1843 self._test_recipe_contents(newrecipefile, checkvars, [])
1844 # Try again - change just version this time
1845 result = runCmd('devtool reset -n %s' % newrecipename)
1846 shutil.rmtree(newsrctree)
1847 add_recipe()
1848 newrecipefile = os.path.join(self.workspacedir, 'recipes', recipename, '%s_%s.bb' % (recipename, newrecipever))
1849 result = runCmd('devtool rename %s -V %s' % (recipename, newrecipever))
1850 self.assertExists(newrecipefile, 'Recipe file not renamed')
1851 self.assertExists(os.path.join(self.workspacedir, 'sources', recipename), 'Source directory no longer exists')
1852 checkvars = {}
1853 checkvars['S'] = '${WORKDIR}/${BPN}-%s' % recipever
1854 checkvars['SRC_URI'] = url
1855 self._test_recipe_contents(newrecipefile, checkvars, [])
1856
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001857 def test_devtool_virtual_kernel_modify(self):
1858 """
1859 Summary: The purpose of this test case is to verify that
1860 devtool modify works correctly when building
1861 the kernel.
1862 Dependencies: NA
1863 Steps: 1. Build kernel with bitbake.
1864 2. Save the config file generated.
1865 3. Clean the environment.
1866 4. Use `devtool modify virtual/kernel` to validate following:
1867 4.1 The source is checked out correctly.
1868 4.2 The resulting configuration is the same as
1869 what was get on step 2.
1870 4.3 The Kernel can be build correctly.
1871 4.4 Changes made on the source are reflected on the
1872 subsequent builds.
1873 4.5 Changes on the configuration are reflected on the
1874 subsequent builds
1875 Expected: devtool modify is able to checkout the source of the kernel
1876 and modification to the source and configurations are reflected
1877 when building the kernel.
Patrick Williams45852732022-04-02 08:58:32 -05001878 """
1879 kernel_provider = self.td['PREFERRED_PROVIDER_virtual/kernel']
1880
Andrew Geissler82c905d2020-04-13 13:39:40 -05001881 # Clean up the environment
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001882 bitbake('%s -c clean' % kernel_provider)
1883 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1884 tempdir_cfg = tempfile.mkdtemp(prefix='config_qa')
1885 self.track_for_cleanup(tempdir)
1886 self.track_for_cleanup(tempdir_cfg)
1887 self.track_for_cleanup(self.workspacedir)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001888 self.add_command_to_tearDown('bitbake -c clean %s' % kernel_provider)
Brad Bishop00e122a2019-10-05 11:10:57 -04001889 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001890 #Step 1
1891 #Here is just generated the config file instead of all the kernel to optimize the
1892 #time of executing this test case.
1893 bitbake('%s -c configure' % kernel_provider)
1894 bbconfig = os.path.join(get_bb_var('B', kernel_provider),'.config')
1895 #Step 2
1896 runCmd('cp %s %s' % (bbconfig, tempdir_cfg))
1897 self.assertExists(os.path.join(tempdir_cfg, '.config'), 'Could not copy .config file from kernel')
1898
1899 tmpconfig = os.path.join(tempdir_cfg, '.config')
1900 #Step 3
1901 bitbake('%s -c clean' % kernel_provider)
1902 #Step 4.1
1903 runCmd('devtool modify virtual/kernel -x %s' % tempdir)
1904 self.assertExists(os.path.join(tempdir, 'Makefile'), 'Extracted source could not be found')
1905 #Step 4.2
1906 configfile = os.path.join(tempdir,'.config')
Patrick Williams45852732022-04-02 08:58:32 -05001907 runCmd('diff %s %s' % (tmpconfig, configfile))
1908
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001909 #Step 4.3
1910 #NOTE: virtual/kernel is mapped to kernel_provider
Patrick Williams45852732022-04-02 08:58:32 -05001911 runCmd('devtool build %s' % kernel_provider)
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001912 kernelfile = os.path.join(get_bb_var('KBUILD_OUTPUT', kernel_provider), 'vmlinux')
1913 self.assertExists(kernelfile, 'Kernel was not build correctly')
1914
1915 #Modify the kernel source
Patrick Williams45852732022-04-02 08:58:32 -05001916 modfile = os.path.join(tempdir, 'init/version.c')
1917 runCmd("sed -i 's/Linux/LiNuX/g' %s" % (modfile))
1918
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001919 #Modify the configuration
Patrick Williams45852732022-04-02 08:58:32 -05001920 codeconfigfile = os.path.join(tempdir, '.config.new')
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001921 modconfopt = "CONFIG_SG_POOL=n"
Patrick Williams45852732022-04-02 08:58:32 -05001922 runCmd("sed -i 's/CONFIG_SG_POOL=y/%s/' %s" % (modconfopt, codeconfigfile))
1923
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001924 #Build again kernel with devtool
Patrick Williams45852732022-04-02 08:58:32 -05001925 runCmd('devtool build %s' % kernel_provider)
1926
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001927 #Step 4.4
Patrick Williams45852732022-04-02 08:58:32 -05001928 runCmd("grep '%s' %s" % ('LiNuX', kernelfile))
1929
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001930 #Step 4.5
Patrick Williams45852732022-04-02 08:58:32 -05001931 runCmd("grep %s %s" % (modconfopt, codeconfigfile))