blob: 43280cdc0e5a6783358973d6f20320c3484624ae [file] [log] [blame]
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001import os
2import re
3import shutil
4import tempfile
5import glob
6import fnmatch
7
8import oeqa.utils.ftools as ftools
9from oeqa.selftest.case import OESelftestTestCase
10from oeqa.utils.commands import runCmd, bitbake, get_bb_var, create_temp_layer
11from oeqa.utils.commands import get_bb_vars, runqemu, get_test_layer
12from oeqa.core.decorator.oeid import OETestID
13
14class DevtoolBase(OESelftestTestCase):
15
16 buffer = True
17
18 def _test_recipe_contents(self, recipefile, checkvars, checkinherits):
19 with open(recipefile, 'r') as f:
20 invar = None
21 invalue = None
22 for line in f:
23 var = None
24 if invar:
25 value = line.strip().strip('"')
26 if value.endswith('\\'):
27 invalue += ' ' + value[:-1].strip()
28 continue
29 else:
30 invalue += ' ' + value.strip()
31 var = invar
32 value = invalue
33 invar = None
34 elif '=' in line:
35 splitline = line.split('=', 1)
36 var = splitline[0].rstrip()
37 value = splitline[1].strip().strip('"')
38 if value.endswith('\\'):
39 invalue = value[:-1].strip()
40 invar = var
41 continue
42 elif line.startswith('inherit '):
43 inherits = line.split()[1:]
44
45 if var and var in checkvars:
46 needvalue = checkvars.pop(var)
47 if needvalue is None:
48 self.fail('Variable %s should not appear in recipe, but value is being set to "%s"' % (var, value))
49 if isinstance(needvalue, set):
50 if var == 'LICENSE':
51 value = set(value.split(' & '))
52 else:
53 value = set(value.split())
54 self.assertEqual(value, needvalue, 'values for %s do not match' % var)
55
56
57 missingvars = {}
58 for var, value in checkvars.items():
59 if value is not None:
60 missingvars[var] = value
61 self.assertEqual(missingvars, {}, 'Some expected variables not found in recipe: %s' % checkvars)
62
63 for inherit in checkinherits:
64 self.assertIn(inherit, inherits, 'Missing inherit of %s' % inherit)
65
66 def _check_bbappend(self, testrecipe, recipefile, appenddir):
67 result = runCmd('bitbake-layers show-appends', cwd=self.builddir)
68 resultlines = result.output.splitlines()
69 inrecipe = False
70 bbappends = []
71 bbappendfile = None
72 for line in resultlines:
73 if inrecipe:
74 if line.startswith(' '):
75 bbappends.append(line.strip())
76 else:
77 break
78 elif line == '%s:' % os.path.basename(recipefile):
79 inrecipe = True
80 self.assertLessEqual(len(bbappends), 2, '%s recipe is being bbappended by another layer - bbappends found:\n %s' % (testrecipe, '\n '.join(bbappends)))
81 for bbappend in bbappends:
82 if bbappend.startswith(appenddir):
83 bbappendfile = bbappend
84 break
85 else:
86 self.fail('bbappend for recipe %s does not seem to be created in test layer' % testrecipe)
87 return bbappendfile
88
89 def _create_temp_layer(self, templayerdir, addlayer, templayername, priority=999, recipepathspec='recipes-*/*'):
90 create_temp_layer(templayerdir, templayername, priority, recipepathspec)
91 if addlayer:
92 self.add_command_to_tearDown('bitbake-layers remove-layer %s || true' % templayerdir)
93 result = runCmd('bitbake-layers add-layer %s' % templayerdir, cwd=self.builddir)
94
95 def _process_ls_output(self, output):
96 """
97 Convert ls -l output to a format we can reasonably compare from one context
98 to another (e.g. from host to target)
99 """
100 filelist = []
101 for line in output.splitlines():
102 splitline = line.split()
103 if len(splitline) < 8:
104 self.fail('_process_ls_output: invalid output line: %s' % line)
105 # Remove trailing . on perms
106 splitline[0] = splitline[0].rstrip('.')
107 # Remove leading . on paths
108 splitline[-1] = splitline[-1].lstrip('.')
109 # Drop fields we don't want to compare
110 del splitline[7]
111 del splitline[6]
112 del splitline[5]
113 del splitline[4]
114 del splitline[1]
115 filelist.append(' '.join(splitline))
116 return filelist
117
118
119class DevtoolTests(DevtoolBase):
120
121 @classmethod
122 def setUpClass(cls):
123 super(DevtoolTests, cls).setUpClass()
124 bb_vars = get_bb_vars(['TOPDIR', 'SSTATE_DIR'])
125 cls.original_sstate = bb_vars['SSTATE_DIR']
126 cls.devtool_sstate = os.path.join(bb_vars['TOPDIR'], 'sstate_devtool')
127 cls.sstate_conf = 'SSTATE_DIR = "%s"\n' % cls.devtool_sstate
128 cls.sstate_conf += ('SSTATE_MIRRORS += "file://.* file:///%s/PATH"\n'
129 % cls.original_sstate)
130
131 @classmethod
132 def tearDownClass(cls):
133 cls.logger.debug('Deleting devtool sstate cache on %s' % cls.devtool_sstate)
134 runCmd('rm -rf %s' % cls.devtool_sstate)
135 super(DevtoolTests, cls).tearDownClass()
136
137 def setUp(self):
138 """Test case setup function"""
139 super(DevtoolTests, self).setUp()
140 self.workspacedir = os.path.join(self.builddir, 'workspace')
141 self.assertTrue(not os.path.exists(self.workspacedir),
142 'This test cannot be run with a workspace directory '
143 'under the build directory')
144 self.append_config(self.sstate_conf)
145
146 def _check_src_repo(self, repo_dir):
147 """Check srctree git repository"""
148 self.assertTrue(os.path.isdir(os.path.join(repo_dir, '.git')),
149 'git repository for external source tree not found')
150 result = runCmd('git status --porcelain', cwd=repo_dir)
151 self.assertEqual(result.output.strip(), "",
152 'Created git repo is not clean')
153 result = runCmd('git symbolic-ref HEAD', cwd=repo_dir)
154 self.assertEqual(result.output.strip(), "refs/heads/devtool",
155 'Wrong branch in git repo')
156
157 def _check_repo_status(self, repo_dir, expected_status):
158 """Check the worktree status of a repository"""
159 result = runCmd('git status . --porcelain',
160 cwd=repo_dir)
161 for line in result.output.splitlines():
162 for ind, (f_status, fn_re) in enumerate(expected_status):
163 if re.match(fn_re, line[3:]):
164 if f_status != line[:2]:
165 self.fail('Unexpected status in line: %s' % line)
166 expected_status.pop(ind)
167 break
168 else:
169 self.fail('Unexpected modified file in line: %s' % line)
170 if expected_status:
171 self.fail('Missing file changes: %s' % expected_status)
172
173 @OETestID(1158)
174 def test_create_workspace(self):
175 # Check preconditions
176 result = runCmd('bitbake-layers show-layers')
177 self.assertTrue('/workspace' not in result.output, 'This test cannot be run with a workspace layer in bblayers.conf')
178 # Try creating a workspace layer with a specific path
179 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
180 self.track_for_cleanup(tempdir)
181 result = runCmd('devtool create-workspace %s' % tempdir)
182 self.assertTrue(os.path.isfile(os.path.join(tempdir, 'conf', 'layer.conf')), msg = "No workspace created. devtool output: %s " % result.output)
183 result = runCmd('bitbake-layers show-layers')
184 self.assertIn(tempdir, result.output)
185 # Try creating a workspace layer with the default path
186 self.track_for_cleanup(self.workspacedir)
187 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
188 result = runCmd('devtool create-workspace')
189 self.assertTrue(os.path.isfile(os.path.join(self.workspacedir, 'conf', 'layer.conf')), msg = "No workspace created. devtool output: %s " % result.output)
190 result = runCmd('bitbake-layers show-layers')
191 self.assertNotIn(tempdir, result.output)
192 self.assertIn(self.workspacedir, result.output)
193
194 @OETestID(1159)
195 def test_devtool_add(self):
196 # Fetch source
197 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
198 self.track_for_cleanup(tempdir)
199 pn = 'pv'
200 pv = '1.5.3'
201 url = 'http://www.ivarch.com/programs/sources/pv-1.5.3.tar.bz2'
202 result = runCmd('wget %s' % url, cwd=tempdir)
203 result = runCmd('tar xfv %s' % os.path.basename(url), cwd=tempdir)
204 srcdir = os.path.join(tempdir, '%s-%s' % (pn, pv))
205 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure')), 'Unable to find configure script in source directory')
206 # Test devtool add
207 self.track_for_cleanup(self.workspacedir)
208 self.add_command_to_tearDown('bitbake -c cleansstate %s' % pn)
209 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
210 result = runCmd('devtool add %s %s' % (pn, srcdir))
211 self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created')
212 # Test devtool status
213 result = runCmd('devtool status')
214 recipepath = '%s/recipes/%s/%s_%s.bb' % (self.workspacedir, pn, pn, pv)
215 self.assertIn(recipepath, result.output)
216 self.assertIn(srcdir, result.output)
217 # Test devtool find-recipe
218 result = runCmd('devtool -q find-recipe %s' % pn)
219 self.assertEqual(recipepath, result.output.strip())
220 # Test devtool edit-recipe
221 result = runCmd('VISUAL="echo 123" devtool -q edit-recipe %s' % pn)
222 self.assertEqual('123 %s' % recipepath, result.output.strip())
223 # Clean up anything in the workdir/sysroot/sstate cache (have to do this *after* devtool add since the recipe only exists then)
224 bitbake('%s -c cleansstate' % pn)
225 # Test devtool build
226 result = runCmd('devtool build %s' % pn)
227 bb_vars = get_bb_vars(['D', 'bindir'], pn)
228 installdir = bb_vars['D']
229 self.assertTrue(installdir, 'Could not query installdir variable')
230 bindir = bb_vars['bindir']
231 self.assertTrue(bindir, 'Could not query bindir variable')
232 if bindir[0] == '/':
233 bindir = bindir[1:]
234 self.assertTrue(os.path.isfile(os.path.join(installdir, bindir, 'pv')), 'pv binary not found in D')
235
236 @OETestID(1423)
237 def test_devtool_add_git_local(self):
238 # Fetch source from a remote URL, but do it outside of devtool
239 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
240 self.track_for_cleanup(tempdir)
241 pn = 'dbus-wait'
242 srcrev = '6cc6077a36fe2648a5f993fe7c16c9632f946517'
243 # We choose an https:// git URL here to check rewriting the URL works
244 url = 'https://git.yoctoproject.org/git/dbus-wait'
245 # Force fetching to "noname" subdir so we verify we're picking up the name from autoconf
246 # instead of the directory name
247 result = runCmd('git clone %s noname' % url, cwd=tempdir)
248 srcdir = os.path.join(tempdir, 'noname')
249 result = runCmd('git reset --hard %s' % srcrev, cwd=srcdir)
250 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure.ac')), 'Unable to find configure script in source directory')
251 # Test devtool add
252 self.track_for_cleanup(self.workspacedir)
253 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
254 # Don't specify a name since we should be able to auto-detect it
255 result = runCmd('devtool add %s' % srcdir)
256 self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created')
257 # Check the recipe name is correct
258 recipefile = get_bb_var('FILE', pn)
259 self.assertIn('%s_git.bb' % pn, recipefile, 'Recipe file incorrectly named')
260 self.assertIn(recipefile, result.output)
261 # Test devtool status
262 result = runCmd('devtool status')
263 self.assertIn(pn, result.output)
264 self.assertIn(srcdir, result.output)
265 self.assertIn(recipefile, result.output)
266 checkvars = {}
267 checkvars['LICENSE'] = 'GPLv2'
268 checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263'
269 checkvars['S'] = '${WORKDIR}/git'
270 checkvars['PV'] = '0.1+git${SRCPV}'
271 checkvars['SRC_URI'] = 'git://git.yoctoproject.org/git/dbus-wait;protocol=https'
272 checkvars['SRCREV'] = srcrev
273 checkvars['DEPENDS'] = set(['dbus'])
274 self._test_recipe_contents(recipefile, checkvars, [])
275
276 @OETestID(1162)
277 def test_devtool_add_library(self):
278 # Fetch source
279 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
280 self.track_for_cleanup(tempdir)
281 version = '1.1'
282 url = 'https://www.intra2net.com/en/developer/libftdi/download/libftdi1-%s.tar.bz2' % version
283 result = runCmd('wget %s' % url, cwd=tempdir)
284 result = runCmd('tar xfv libftdi1-%s.tar.bz2' % version, cwd=tempdir)
285 srcdir = os.path.join(tempdir, 'libftdi1-%s' % version)
286 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'CMakeLists.txt')), 'Unable to find CMakeLists.txt in source directory')
287 # Test devtool add (and use -V so we test that too)
288 self.track_for_cleanup(self.workspacedir)
289 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
290 result = runCmd('devtool add libftdi %s -V %s' % (srcdir, version))
291 self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created')
292 # Test devtool status
293 result = runCmd('devtool status')
294 self.assertIn('libftdi', result.output)
295 self.assertIn(srcdir, result.output)
296 # Clean up anything in the workdir/sysroot/sstate cache (have to do this *after* devtool add since the recipe only exists then)
297 bitbake('libftdi -c cleansstate')
298 # libftdi's python/CMakeLists.txt is a bit broken, so let's just disable it
299 # There's also the matter of it installing cmake files to a path we don't
300 # normally cover, which triggers the installed-vs-shipped QA test we have
301 # within do_package
302 recipefile = '%s/recipes/libftdi/libftdi_%s.bb' % (self.workspacedir, version)
303 result = runCmd('recipetool setvar %s EXTRA_OECMAKE -- \'-DPYTHON_BINDINGS=OFF -DLIBFTDI_CMAKE_CONFIG_DIR=${datadir}/cmake/Modules\'' % recipefile)
304 with open(recipefile, 'a') as f:
305 f.write('\nFILES_${PN}-dev += "${datadir}/cmake/Modules"\n')
306 # We don't have the ability to pick up this dependency automatically yet...
307 f.write('\nDEPENDS += "libusb1"\n')
308 f.write('\nTESTLIBOUTPUT = "${COMPONENTS_DIR}/${TUNE_PKGARCH}/${PN}/${libdir}"\n')
309 # Test devtool build
310 result = runCmd('devtool build libftdi')
311 bb_vars = get_bb_vars(['TESTLIBOUTPUT', 'STAMP'], 'libftdi')
312 staging_libdir = bb_vars['TESTLIBOUTPUT']
313 self.assertTrue(staging_libdir, 'Could not query TESTLIBOUTPUT variable')
314 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)
315 # Test devtool reset
316 stampprefix = bb_vars['STAMP']
317 result = runCmd('devtool reset libftdi')
318 result = runCmd('devtool status')
319 self.assertNotIn('libftdi', result.output)
320 self.assertTrue(stampprefix, 'Unable to get STAMP value for recipe libftdi')
321 matches = glob.glob(stampprefix + '*')
322 self.assertFalse(matches, 'Stamp files exist for recipe libftdi that should have been cleaned')
323 self.assertFalse(os.path.isfile(os.path.join(staging_libdir, 'libftdi1.so.2.1.0')), 'libftdi binary still found in STAGING_LIBDIR after cleaning')
324
325 @OETestID(1160)
326 def test_devtool_add_fetch(self):
327 # Fetch source
328 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
329 self.track_for_cleanup(tempdir)
330 testver = '0.23'
331 url = 'https://pypi.python.org/packages/source/M/MarkupSafe/MarkupSafe-%s.tar.gz' % testver
332 testrecipe = 'python-markupsafe'
333 srcdir = os.path.join(tempdir, testrecipe)
334 # Test devtool add
335 self.track_for_cleanup(self.workspacedir)
336 self.add_command_to_tearDown('bitbake -c cleansstate %s' % testrecipe)
337 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
338 result = runCmd('devtool add %s %s -f %s' % (testrecipe, srcdir, url))
339 self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created. %s' % result.output)
340 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'setup.py')), 'Unable to find setup.py in source directory')
341 self.assertTrue(os.path.isdir(os.path.join(srcdir, '.git')), 'git repository for external source tree was not created')
342 # Test devtool status
343 result = runCmd('devtool status')
344 self.assertIn(testrecipe, result.output)
345 self.assertIn(srcdir, result.output)
346 # Check recipe
347 recipefile = get_bb_var('FILE', testrecipe)
348 self.assertIn('%s_%s.bb' % (testrecipe, testver), recipefile, 'Recipe file incorrectly named')
349 checkvars = {}
350 checkvars['S'] = '${WORKDIR}/MarkupSafe-${PV}'
351 checkvars['SRC_URI'] = url.replace(testver, '${PV}')
352 self._test_recipe_contents(recipefile, checkvars, [])
353 # Try with version specified
354 result = runCmd('devtool reset -n %s' % testrecipe)
355 shutil.rmtree(srcdir)
356 fakever = '1.9'
357 result = runCmd('devtool add %s %s -f %s -V %s' % (testrecipe, srcdir, url, fakever))
358 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'setup.py')), 'Unable to find setup.py in source directory')
359 # Test devtool status
360 result = runCmd('devtool status')
361 self.assertIn(testrecipe, result.output)
362 self.assertIn(srcdir, result.output)
363 # Check recipe
364 recipefile = get_bb_var('FILE', testrecipe)
365 self.assertIn('%s_%s.bb' % (testrecipe, fakever), recipefile, 'Recipe file incorrectly named')
366 checkvars = {}
367 checkvars['S'] = '${WORKDIR}/MarkupSafe-%s' % testver
368 checkvars['SRC_URI'] = url
369 self._test_recipe_contents(recipefile, checkvars, [])
370
371 @OETestID(1161)
372 def test_devtool_add_fetch_git(self):
373 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
374 self.track_for_cleanup(tempdir)
375 url = 'gitsm://git.yoctoproject.org/mraa'
376 checkrev = 'ae127b19a50aa54255e4330ccfdd9a5d058e581d'
377 testrecipe = 'mraa'
378 srcdir = os.path.join(tempdir, testrecipe)
379 # Test devtool add
380 self.track_for_cleanup(self.workspacedir)
381 self.add_command_to_tearDown('bitbake -c cleansstate %s' % testrecipe)
382 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
383 result = runCmd('devtool add %s %s -a -f %s' % (testrecipe, srcdir, url))
384 self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created: %s' % result.output)
385 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'imraa', 'imraa.c')), 'Unable to find imraa/imraa.c in source directory')
386 # Test devtool status
387 result = runCmd('devtool status')
388 self.assertIn(testrecipe, result.output)
389 self.assertIn(srcdir, result.output)
390 # Check recipe
391 recipefile = get_bb_var('FILE', testrecipe)
392 self.assertIn('_git.bb', recipefile, 'Recipe file incorrectly named')
393 checkvars = {}
394 checkvars['S'] = '${WORKDIR}/git'
395 checkvars['PV'] = '1.0+git${SRCPV}'
396 checkvars['SRC_URI'] = url
397 checkvars['SRCREV'] = '${AUTOREV}'
398 self._test_recipe_contents(recipefile, checkvars, [])
399 # Try with revision and version specified
400 result = runCmd('devtool reset -n %s' % testrecipe)
401 shutil.rmtree(srcdir)
402 url_rev = '%s;rev=%s' % (url, checkrev)
403 result = runCmd('devtool add %s %s -f "%s" -V 1.5' % (testrecipe, srcdir, url_rev))
404 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'imraa', 'imraa.c')), 'Unable to find imraa/imraa.c in source directory')
405 # Test devtool status
406 result = runCmd('devtool status')
407 self.assertIn(testrecipe, result.output)
408 self.assertIn(srcdir, result.output)
409 # Check recipe
410 recipefile = get_bb_var('FILE', testrecipe)
411 self.assertIn('_git.bb', recipefile, 'Recipe file incorrectly named')
412 checkvars = {}
413 checkvars['S'] = '${WORKDIR}/git'
414 checkvars['PV'] = '1.5+git${SRCPV}'
415 checkvars['SRC_URI'] = url
416 checkvars['SRCREV'] = checkrev
417 self._test_recipe_contents(recipefile, checkvars, [])
418
419 @OETestID(1391)
420 def test_devtool_add_fetch_simple(self):
421 # Fetch source from a remote URL, auto-detecting name
422 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
423 self.track_for_cleanup(tempdir)
424 testver = '1.6.0'
425 url = 'http://www.ivarch.com/programs/sources/pv-%s.tar.bz2' % testver
426 testrecipe = 'pv'
427 srcdir = os.path.join(self.workspacedir, 'sources', testrecipe)
428 # Test devtool add
429 self.track_for_cleanup(self.workspacedir)
430 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
431 result = runCmd('devtool add %s' % url)
432 self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created. %s' % result.output)
433 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure')), 'Unable to find configure script in source directory')
434 self.assertTrue(os.path.isdir(os.path.join(srcdir, '.git')), 'git repository for external source tree was not created')
435 # Test devtool status
436 result = runCmd('devtool status')
437 self.assertIn(testrecipe, result.output)
438 self.assertIn(srcdir, result.output)
439 # Check recipe
440 recipefile = get_bb_var('FILE', testrecipe)
441 self.assertIn('%s_%s.bb' % (testrecipe, testver), recipefile, 'Recipe file incorrectly named')
442 checkvars = {}
443 checkvars['S'] = None
444 checkvars['SRC_URI'] = url.replace(testver, '${PV}')
445 self._test_recipe_contents(recipefile, checkvars, [])
446
447 @OETestID(1164)
448 def test_devtool_modify(self):
449 import oe.path
450
451 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
452 self.track_for_cleanup(tempdir)
453 self.track_for_cleanup(self.workspacedir)
454 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
455 self.add_command_to_tearDown('bitbake -c clean mdadm')
456 result = runCmd('devtool modify mdadm -x %s' % tempdir)
457 self.assertExists(os.path.join(tempdir, 'Makefile'), 'Extracted source could not be found')
458 self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created')
459 matches = glob.glob(os.path.join(self.workspacedir, 'appends', 'mdadm_*.bbappend'))
460 self.assertTrue(matches, 'bbappend not created %s' % result.output)
461
462 # Test devtool status
463 result = runCmd('devtool status')
464 self.assertIn('mdadm', result.output)
465 self.assertIn(tempdir, result.output)
466 self._check_src_repo(tempdir)
467
468 bitbake('mdadm -C unpack')
469
470 def check_line(checkfile, expected, message, present=True):
471 # Check for $expected, on a line on its own, in checkfile.
472 with open(checkfile, 'r') as f:
473 if present:
474 self.assertIn(expected + '\n', f, message)
475 else:
476 self.assertNotIn(expected + '\n', f, message)
477
478 modfile = os.path.join(tempdir, 'mdadm.8.in')
479 bb_vars = get_bb_vars(['PKGD', 'mandir'], 'mdadm')
480 pkgd = bb_vars['PKGD']
481 self.assertTrue(pkgd, 'Could not query PKGD variable')
482 mandir = bb_vars['mandir']
483 self.assertTrue(mandir, 'Could not query mandir variable')
484 manfile = oe.path.join(pkgd, mandir, 'man8', 'mdadm.8')
485
486 check_line(modfile, 'Linux Software RAID', 'Could not find initial string')
487 check_line(modfile, 'antique pin sardine', 'Unexpectedly found replacement string', present=False)
488
489 result = runCmd("sed -i 's!^Linux Software RAID$!antique pin sardine!' %s" % modfile)
490 check_line(modfile, 'antique pin sardine', 'mdadm.8.in file not modified (sed failed)')
491
492 bitbake('mdadm -c package')
493 check_line(manfile, 'antique pin sardine', 'man file not modified. man searched file path: %s' % manfile)
494
495 result = runCmd('git checkout -- %s' % modfile, cwd=tempdir)
496 check_line(modfile, 'Linux Software RAID', 'man .in file not restored (git failed)')
497
498 bitbake('mdadm -c package')
499 check_line(manfile, 'Linux Software RAID', 'man file not updated. man searched file path: %s' % manfile)
500
501 result = runCmd('devtool reset mdadm')
502 result = runCmd('devtool status')
503 self.assertNotIn('mdadm', result.output)
504
505 @OETestID(1620)
506 def test_devtool_buildclean(self):
507 def assertFile(path, *paths):
508 f = os.path.join(path, *paths)
509 self.assertExists(f)
510 def assertNoFile(path, *paths):
511 f = os.path.join(path, *paths)
512 self.assertNotExists(f)
513
514 # Clean up anything in the workdir/sysroot/sstate cache
515 bitbake('mdadm m4 -c cleansstate')
516 # Try modifying a recipe
517 tempdir_mdadm = tempfile.mkdtemp(prefix='devtoolqa')
518 tempdir_m4 = tempfile.mkdtemp(prefix='devtoolqa')
519 builddir_m4 = tempfile.mkdtemp(prefix='devtoolqa')
520 self.track_for_cleanup(tempdir_mdadm)
521 self.track_for_cleanup(tempdir_m4)
522 self.track_for_cleanup(builddir_m4)
523 self.track_for_cleanup(self.workspacedir)
524 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
525 self.add_command_to_tearDown('bitbake -c clean mdadm m4')
526 self.write_recipeinc('m4', 'EXTERNALSRC_BUILD = "%s"\ndo_clean() {\n\t:\n}\n' % builddir_m4)
527 try:
528 runCmd('devtool modify mdadm -x %s' % tempdir_mdadm)
529 runCmd('devtool modify m4 -x %s' % tempdir_m4)
530 assertNoFile(tempdir_mdadm, 'mdadm')
531 assertNoFile(builddir_m4, 'src/m4')
532 result = bitbake('m4 -e')
533 result = bitbake('mdadm m4 -c compile')
534 self.assertEqual(result.status, 0)
535 assertFile(tempdir_mdadm, 'mdadm')
536 assertFile(builddir_m4, 'src/m4')
537 # Check that buildclean task exists and does call make clean
538 bitbake('mdadm m4 -c buildclean')
539 assertNoFile(tempdir_mdadm, 'mdadm')
540 assertNoFile(builddir_m4, 'src/m4')
541 bitbake('mdadm m4 -c compile')
542 assertFile(tempdir_mdadm, 'mdadm')
543 assertFile(builddir_m4, 'src/m4')
544 bitbake('mdadm m4 -c clean')
545 # Check that buildclean task is run before clean for B == S
546 assertNoFile(tempdir_mdadm, 'mdadm')
547 # Check that buildclean task is not run before clean for B != S
548 assertFile(builddir_m4, 'src/m4')
549 finally:
550 self.delete_recipeinc('m4')
551
552 @OETestID(1166)
553 def test_devtool_modify_invalid(self):
554 # Try modifying some recipes
555 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
556 self.track_for_cleanup(tempdir)
557 self.track_for_cleanup(self.workspacedir)
558 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
559
560 testrecipes = 'perf kernel-devsrc package-index core-image-minimal meta-toolchain packagegroup-core-sdk meta-ide-support'.split()
561 # Find actual name of gcc-source since it now includes the version - crude, but good enough for this purpose
562 result = runCmd('bitbake-layers show-recipes gcc-source*')
563 for line in result.output.splitlines():
564 # just match those lines that contain a real target
565 m = re.match('(?P<recipe>^[a-zA-Z0-9.-]+)(?P<colon>:$)', line)
566 if m:
567 testrecipes.append(m.group('recipe'))
568 for testrecipe in testrecipes:
569 # Check it's a valid recipe
570 bitbake('%s -e' % testrecipe)
571 # devtool extract should fail
572 result = runCmd('devtool extract %s %s' % (testrecipe, os.path.join(tempdir, testrecipe)), ignore_status=True)
573 self.assertNotEqual(result.status, 0, 'devtool extract on %s should have failed. devtool output: %s' % (testrecipe, result.output))
574 self.assertNotIn('Fetching ', result.output, 'devtool extract on %s should have errored out before trying to fetch' % testrecipe)
575 self.assertIn('ERROR: ', result.output, 'devtool extract on %s should have given an ERROR' % testrecipe)
576 # devtool modify should fail
577 result = runCmd('devtool modify %s -x %s' % (testrecipe, os.path.join(tempdir, testrecipe)), ignore_status=True)
578 self.assertNotEqual(result.status, 0, 'devtool modify on %s should have failed. devtool output: %s' % (testrecipe, result.output))
579 self.assertIn('ERROR: ', result.output, 'devtool modify on %s should have given an ERROR' % testrecipe)
580
581 @OETestID(1365)
582 def test_devtool_modify_native(self):
583 # Check preconditions
584 self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
585 # Try modifying some recipes
586 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
587 self.track_for_cleanup(tempdir)
588 self.track_for_cleanup(self.workspacedir)
589 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
590
591 bbclassextended = False
592 inheritnative = False
593 testrecipes = 'mtools-native apt-native desktop-file-utils-native'.split()
594 for testrecipe in testrecipes:
595 checkextend = 'native' in (get_bb_var('BBCLASSEXTEND', testrecipe) or '').split()
596 if not bbclassextended:
597 bbclassextended = checkextend
598 if not inheritnative:
599 inheritnative = not checkextend
600 result = runCmd('devtool modify %s -x %s' % (testrecipe, os.path.join(tempdir, testrecipe)))
601 self.assertNotIn('ERROR: ', result.output, 'ERROR in devtool modify output: %s' % result.output)
602 result = runCmd('devtool build %s' % testrecipe)
603 self.assertNotIn('ERROR: ', result.output, 'ERROR in devtool build output: %s' % result.output)
604 result = runCmd('devtool reset %s' % testrecipe)
605 self.assertNotIn('ERROR: ', result.output, 'ERROR in devtool reset output: %s' % result.output)
606
607 self.assertTrue(bbclassextended, 'None of these recipes are BBCLASSEXTENDed to native - need to adjust testrecipes list: %s' % ', '.join(testrecipes))
608 self.assertTrue(inheritnative, 'None of these recipes do "inherit native" - need to adjust testrecipes list: %s' % ', '.join(testrecipes))
609
610
611 @OETestID(1165)
612 def test_devtool_modify_git(self):
613 # Check preconditions
614 testrecipe = 'mkelfimage'
615 src_uri = get_bb_var('SRC_URI', testrecipe)
616 self.assertIn('git://', src_uri, 'This test expects the %s recipe to be a git recipe' % testrecipe)
617 # Clean up anything in the workdir/sysroot/sstate cache
618 bitbake('%s -c cleansstate' % testrecipe)
619 # Try modifying a recipe
620 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
621 self.track_for_cleanup(tempdir)
622 self.track_for_cleanup(self.workspacedir)
623 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
624 self.add_command_to_tearDown('bitbake -c clean %s' % testrecipe)
625 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
626 self.assertExists(os.path.join(tempdir, 'Makefile'), 'Extracted source could not be found')
627 self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created. devtool output: %s' % result.output)
628 matches = glob.glob(os.path.join(self.workspacedir, 'appends', 'mkelfimage_*.bbappend'))
629 self.assertTrue(matches, 'bbappend not created')
630 # Test devtool status
631 result = runCmd('devtool status')
632 self.assertIn(testrecipe, result.output)
633 self.assertIn(tempdir, result.output)
634 # Check git repo
635 self._check_src_repo(tempdir)
636 # Try building
637 bitbake(testrecipe)
638
639 @OETestID(1167)
640 def test_devtool_modify_localfiles(self):
641 # Check preconditions
642 testrecipe = 'lighttpd'
643 src_uri = (get_bb_var('SRC_URI', testrecipe) or '').split()
644 foundlocal = False
645 for item in src_uri:
646 if item.startswith('file://') and '.patch' not in item:
647 foundlocal = True
648 break
649 self.assertTrue(foundlocal, 'This test expects the %s recipe to fetch local files and it seems that it no longer does' % testrecipe)
650 # Clean up anything in the workdir/sysroot/sstate cache
651 bitbake('%s -c cleansstate' % testrecipe)
652 # Try modifying a recipe
653 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
654 self.track_for_cleanup(tempdir)
655 self.track_for_cleanup(self.workspacedir)
656 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
657 self.add_command_to_tearDown('bitbake -c clean %s' % testrecipe)
658 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
659 self.assertExists(os.path.join(tempdir, 'configure.ac'), 'Extracted source could not be found')
660 self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created')
661 matches = glob.glob(os.path.join(self.workspacedir, 'appends', '%s_*.bbappend' % testrecipe))
662 self.assertTrue(matches, 'bbappend not created')
663 # Test devtool status
664 result = runCmd('devtool status')
665 self.assertIn(testrecipe, result.output)
666 self.assertIn(tempdir, result.output)
667 # Try building
668 bitbake(testrecipe)
669
670 @OETestID(1378)
671 def test_devtool_modify_virtual(self):
672 # Try modifying a virtual recipe
673 virtrecipe = 'virtual/make'
674 realrecipe = 'make'
675 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
676 self.track_for_cleanup(tempdir)
677 self.track_for_cleanup(self.workspacedir)
678 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
679 result = runCmd('devtool modify %s -x %s' % (virtrecipe, tempdir))
680 self.assertExists(os.path.join(tempdir, 'Makefile.am'), 'Extracted source could not be found')
681 self.assertExists(os.path.join(self.workspacedir, 'conf', 'layer.conf'), 'Workspace directory not created')
682 matches = glob.glob(os.path.join(self.workspacedir, 'appends', '%s_*.bbappend' % realrecipe))
683 self.assertTrue(matches, 'bbappend not created %s' % result.output)
684 # Test devtool status
685 result = runCmd('devtool status')
686 self.assertNotIn(virtrecipe, result.output)
687 self.assertIn(realrecipe, result.output)
688 # Check git repo
689 self._check_src_repo(tempdir)
690 # This is probably sufficient
691
692
693 @OETestID(1169)
694 def test_devtool_update_recipe(self):
695 # Check preconditions
696 testrecipe = 'minicom'
697 bb_vars = get_bb_vars(['FILE', 'SRC_URI'], testrecipe)
698 recipefile = bb_vars['FILE']
699 src_uri = bb_vars['SRC_URI']
700 self.assertNotIn('git://', src_uri, 'This test expects the %s recipe to NOT be a git recipe' % testrecipe)
701 self._check_repo_status(os.path.dirname(recipefile), [])
702 # First, modify a recipe
703 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
704 self.track_for_cleanup(tempdir)
705 self.track_for_cleanup(self.workspacedir)
706 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
707 # (don't bother with cleaning the recipe on teardown, we won't be building it)
708 # We don't use -x here so that we test the behaviour of devtool modify without it
709 result = runCmd('devtool modify %s %s' % (testrecipe, tempdir))
710 # Check git repo
711 self._check_src_repo(tempdir)
712 # Add a couple of commits
713 # FIXME: this only tests adding, need to also test update and remove
714 result = runCmd('echo "Additional line" >> README', cwd=tempdir)
715 result = runCmd('git commit -a -m "Change the README"', cwd=tempdir)
716 result = runCmd('echo "A new file" > devtool-new-file', cwd=tempdir)
717 result = runCmd('git add devtool-new-file', cwd=tempdir)
718 result = runCmd('git commit -m "Add a new file"', cwd=tempdir)
719 self.add_command_to_tearDown('cd %s; rm %s/*.patch; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, testrecipe, os.path.basename(recipefile)))
720 result = runCmd('devtool update-recipe %s' % testrecipe)
721 expected_status = [(' M', '.*/%s$' % os.path.basename(recipefile)),
722 ('??', '.*/0001-Change-the-README.patch$'),
723 ('??', '.*/0002-Add-a-new-file.patch$')]
724 self._check_repo_status(os.path.dirname(recipefile), expected_status)
725
726 @OETestID(1172)
727 def test_devtool_update_recipe_git(self):
728 # Check preconditions
729 testrecipe = 'mtd-utils'
730 bb_vars = get_bb_vars(['FILE', 'SRC_URI'], testrecipe)
731 recipefile = bb_vars['FILE']
732 src_uri = bb_vars['SRC_URI']
733 self.assertIn('git://', src_uri, 'This test expects the %s recipe to be a git recipe' % testrecipe)
734 patches = []
735 for entry in src_uri.split():
736 if entry.startswith('file://') and entry.endswith('.patch'):
737 patches.append(entry[7:].split(';')[0])
738 self.assertGreater(len(patches), 0, 'The %s recipe does not appear to contain any patches, so this test will not be effective' % testrecipe)
739 self._check_repo_status(os.path.dirname(recipefile), [])
740 # First, modify a recipe
741 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
742 self.track_for_cleanup(tempdir)
743 self.track_for_cleanup(self.workspacedir)
744 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
745 # (don't bother with cleaning the recipe on teardown, we won't be building it)
746 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
747 # Check git repo
748 self._check_src_repo(tempdir)
749 # Add a couple of commits
750 # FIXME: this only tests adding, need to also test update and remove
751 result = runCmd('echo "# Additional line" >> Makefile.am', cwd=tempdir)
752 result = runCmd('git commit -a -m "Change the Makefile"', cwd=tempdir)
753 result = runCmd('echo "A new file" > devtool-new-file', cwd=tempdir)
754 result = runCmd('git add devtool-new-file', cwd=tempdir)
755 result = runCmd('git commit -m "Add a new file"', cwd=tempdir)
756 self.add_command_to_tearDown('cd %s; rm -rf %s; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, testrecipe, os.path.basename(recipefile)))
757 result = runCmd('devtool update-recipe -m srcrev %s' % testrecipe)
758 expected_status = [(' M', '.*/%s$' % os.path.basename(recipefile))] + \
759 [(' D', '.*/%s$' % patch) for patch in patches]
760 self._check_repo_status(os.path.dirname(recipefile), expected_status)
761
762 result = runCmd('git diff %s' % os.path.basename(recipefile), cwd=os.path.dirname(recipefile))
763 addlines = ['SRCREV = ".*"', 'SRC_URI = "git://git.infradead.org/mtd-utils.git"']
764 srcurilines = src_uri.split()
765 srcurilines[0] = 'SRC_URI = "' + srcurilines[0]
766 srcurilines.append('"')
767 removelines = ['SRCREV = ".*"'] + srcurilines
768 for line in result.output.splitlines():
769 if line.startswith('+++') or line.startswith('---'):
770 continue
771 elif line.startswith('+'):
772 matched = False
773 for item in addlines:
774 if re.match(item, line[1:].strip()):
775 matched = True
776 break
777 self.assertTrue(matched, 'Unexpected diff add line: %s' % line)
778 elif line.startswith('-'):
779 matched = False
780 for item in removelines:
781 if re.match(item, line[1:].strip()):
782 matched = True
783 break
784 self.assertTrue(matched, 'Unexpected diff remove line: %s' % line)
785 # Now try with auto mode
786 runCmd('cd %s; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, os.path.basename(recipefile)))
787 result = runCmd('devtool update-recipe %s' % testrecipe)
788 result = runCmd('git rev-parse --show-toplevel', cwd=os.path.dirname(recipefile))
789 topleveldir = result.output.strip()
790 relpatchpath = os.path.join(os.path.relpath(os.path.dirname(recipefile), topleveldir), testrecipe)
791 expected_status = [(' M', os.path.relpath(recipefile, topleveldir)),
792 ('??', '%s/0001-Change-the-Makefile.patch' % relpatchpath),
793 ('??', '%s/0002-Add-a-new-file.patch' % relpatchpath)]
794 self._check_repo_status(os.path.dirname(recipefile), expected_status)
795
796 @OETestID(1170)
797 def test_devtool_update_recipe_append(self):
798 # Check preconditions
799 testrecipe = 'mdadm'
800 bb_vars = get_bb_vars(['FILE', 'SRC_URI'], testrecipe)
801 recipefile = bb_vars['FILE']
802 src_uri = bb_vars['SRC_URI']
803 self.assertNotIn('git://', src_uri, 'This test expects the %s recipe to NOT be a git recipe' % testrecipe)
804 self._check_repo_status(os.path.dirname(recipefile), [])
805 # First, modify a recipe
806 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
807 tempsrcdir = os.path.join(tempdir, 'source')
808 templayerdir = os.path.join(tempdir, 'layer')
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 # (don't bother with cleaning the recipe on teardown, we won't be building it)
813 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempsrcdir))
814 # Check git repo
815 self._check_src_repo(tempsrcdir)
816 # Add a commit
817 result = runCmd("sed 's!\\(#define VERSION\\W*\"[^\"]*\\)\"!\\1-custom\"!' -i ReadMe.c", cwd=tempsrcdir)
818 result = runCmd('git commit -a -m "Add our custom version"', cwd=tempsrcdir)
819 self.add_command_to_tearDown('cd %s; rm -f %s/*.patch; git checkout .' % (os.path.dirname(recipefile), testrecipe))
820 # Create a temporary layer and add it to bblayers.conf
821 self._create_temp_layer(templayerdir, True, 'selftestupdaterecipe')
822 # Create the bbappend
823 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
824 self.assertNotIn('WARNING:', result.output)
825 # Check recipe is still clean
826 self._check_repo_status(os.path.dirname(recipefile), [])
827 # Check bbappend was created
828 splitpath = os.path.dirname(recipefile).split(os.sep)
829 appenddir = os.path.join(templayerdir, splitpath[-2], splitpath[-1])
830 bbappendfile = self._check_bbappend(testrecipe, recipefile, appenddir)
831 patchfile = os.path.join(appenddir, testrecipe, '0001-Add-our-custom-version.patch')
832 self.assertExists(patchfile, 'Patch file not created')
833
834 # Check bbappend contents
835 expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
836 '\n',
837 'SRC_URI += "file://0001-Add-our-custom-version.patch"\n',
838 '\n']
839 with open(bbappendfile, 'r') as f:
840 self.assertEqual(expectedlines, f.readlines())
841
842 # Check we can run it again and bbappend isn't modified
843 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
844 with open(bbappendfile, 'r') as f:
845 self.assertEqual(expectedlines, f.readlines())
846 # Drop new commit and check patch gets deleted
847 result = runCmd('git reset HEAD^', cwd=tempsrcdir)
848 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
849 self.assertNotExists(patchfile, 'Patch file not deleted')
850 expectedlines2 = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
851 '\n']
852 with open(bbappendfile, 'r') as f:
853 self.assertEqual(expectedlines2, f.readlines())
854 # Put commit back and check we can run it if layer isn't in bblayers.conf
855 os.remove(bbappendfile)
856 result = runCmd('git commit -a -m "Add our custom version"', cwd=tempsrcdir)
857 result = runCmd('bitbake-layers remove-layer %s' % templayerdir, cwd=self.builddir)
858 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
859 self.assertIn('WARNING: Specified layer is not currently enabled in bblayers.conf', result.output)
860 self.assertExists(patchfile, 'Patch file not created (with disabled layer)')
861 with open(bbappendfile, 'r') as f:
862 self.assertEqual(expectedlines, f.readlines())
863 # Deleting isn't expected to work under these circumstances
864
865 @OETestID(1171)
866 def test_devtool_update_recipe_append_git(self):
867 # Check preconditions
868 testrecipe = 'mtd-utils'
869 bb_vars = get_bb_vars(['FILE', 'SRC_URI'], testrecipe)
870 recipefile = bb_vars['FILE']
871 src_uri = bb_vars['SRC_URI']
872 self.assertIn('git://', src_uri, 'This test expects the %s recipe to be a git recipe' % testrecipe)
873 for entry in src_uri.split():
874 if entry.startswith('git://'):
875 git_uri = entry
876 break
877 self._check_repo_status(os.path.dirname(recipefile), [])
878 # First, modify a recipe
879 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
880 tempsrcdir = os.path.join(tempdir, 'source')
881 templayerdir = os.path.join(tempdir, 'layer')
882 self.track_for_cleanup(tempdir)
883 self.track_for_cleanup(self.workspacedir)
884 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
885 # (don't bother with cleaning the recipe on teardown, we won't be building it)
886 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempsrcdir))
887 # Check git repo
888 self._check_src_repo(tempsrcdir)
889 # Add a commit
890 result = runCmd('echo "# Additional line" >> Makefile.am', cwd=tempsrcdir)
891 result = runCmd('git commit -a -m "Change the Makefile"', cwd=tempsrcdir)
892 self.add_command_to_tearDown('cd %s; rm -f %s/*.patch; git checkout .' % (os.path.dirname(recipefile), testrecipe))
893 # Create a temporary layer
894 os.makedirs(os.path.join(templayerdir, 'conf'))
895 with open(os.path.join(templayerdir, 'conf', 'layer.conf'), 'w') as f:
896 f.write('BBPATH .= ":${LAYERDIR}"\n')
897 f.write('BBFILES += "${LAYERDIR}/recipes-*/*/*.bbappend"\n')
898 f.write('BBFILE_COLLECTIONS += "oeselftesttemplayer"\n')
899 f.write('BBFILE_PATTERN_oeselftesttemplayer = "^${LAYERDIR}/"\n')
900 f.write('BBFILE_PRIORITY_oeselftesttemplayer = "999"\n')
901 f.write('BBFILE_PATTERN_IGNORE_EMPTY_oeselftesttemplayer = "1"\n')
902 self.add_command_to_tearDown('bitbake-layers remove-layer %s || true' % templayerdir)
903 result = runCmd('bitbake-layers add-layer %s' % templayerdir, cwd=self.builddir)
904 # Create the bbappend
905 result = runCmd('devtool update-recipe -m srcrev %s -a %s' % (testrecipe, templayerdir))
906 self.assertNotIn('WARNING:', result.output)
907 # Check recipe is still clean
908 self._check_repo_status(os.path.dirname(recipefile), [])
909 # Check bbappend was created
910 splitpath = os.path.dirname(recipefile).split(os.sep)
911 appenddir = os.path.join(templayerdir, splitpath[-2], splitpath[-1])
912 bbappendfile = self._check_bbappend(testrecipe, recipefile, appenddir)
913 self.assertNotExists(os.path.join(appenddir, testrecipe), 'Patch directory should not be created')
914
915 # Check bbappend contents
916 result = runCmd('git rev-parse HEAD', cwd=tempsrcdir)
917 expectedlines = set(['SRCREV = "%s"\n' % result.output,
918 '\n',
919 'SRC_URI = "%s"\n' % git_uri,
920 '\n'])
921 with open(bbappendfile, 'r') as f:
922 self.assertEqual(expectedlines, set(f.readlines()))
923
924 # Check we can run it again and bbappend isn't modified
925 result = runCmd('devtool update-recipe -m srcrev %s -a %s' % (testrecipe, templayerdir))
926 with open(bbappendfile, 'r') as f:
927 self.assertEqual(expectedlines, set(f.readlines()))
928 # Drop new commit and check SRCREV changes
929 result = runCmd('git reset HEAD^', cwd=tempsrcdir)
930 result = runCmd('devtool update-recipe -m srcrev %s -a %s' % (testrecipe, templayerdir))
931 self.assertNotExists(os.path.join(appenddir, testrecipe), 'Patch directory should not be created')
932 result = runCmd('git rev-parse HEAD', cwd=tempsrcdir)
933 expectedlines = set(['SRCREV = "%s"\n' % result.output,
934 '\n',
935 'SRC_URI = "%s"\n' % git_uri,
936 '\n'])
937 with open(bbappendfile, 'r') as f:
938 self.assertEqual(expectedlines, set(f.readlines()))
939 # Put commit back and check we can run it if layer isn't in bblayers.conf
940 os.remove(bbappendfile)
941 result = runCmd('git commit -a -m "Change the Makefile"', cwd=tempsrcdir)
942 result = runCmd('bitbake-layers remove-layer %s' % templayerdir, cwd=self.builddir)
943 result = runCmd('devtool update-recipe -m srcrev %s -a %s' % (testrecipe, templayerdir))
944 self.assertIn('WARNING: Specified layer is not currently enabled in bblayers.conf', result.output)
945 self.assertNotExists(os.path.join(appenddir, testrecipe), 'Patch directory should not be created')
946 result = runCmd('git rev-parse HEAD', cwd=tempsrcdir)
947 expectedlines = set(['SRCREV = "%s"\n' % result.output,
948 '\n',
949 'SRC_URI = "%s"\n' % git_uri,
950 '\n'])
951 with open(bbappendfile, 'r') as f:
952 self.assertEqual(expectedlines, set(f.readlines()))
953 # Deleting isn't expected to work under these circumstances
954
955 @OETestID(1370)
956 def test_devtool_update_recipe_local_files(self):
957 """Check that local source files are copied over instead of patched"""
958 testrecipe = 'makedevs'
959 recipefile = get_bb_var('FILE', testrecipe)
960 # Setup srctree for modifying the recipe
961 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
962 self.track_for_cleanup(tempdir)
963 self.track_for_cleanup(self.workspacedir)
964 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
965 # (don't bother with cleaning the recipe on teardown, we won't be
966 # building it)
967 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
968 # Check git repo
969 self._check_src_repo(tempdir)
970 # Try building just to ensure we haven't broken that
971 bitbake("%s" % testrecipe)
972 # Edit / commit local source
973 runCmd('echo "/* Foobar */" >> oe-local-files/makedevs.c', cwd=tempdir)
974 runCmd('echo "Foo" > oe-local-files/new-local', cwd=tempdir)
975 runCmd('echo "Bar" > new-file', cwd=tempdir)
976 runCmd('git add new-file', cwd=tempdir)
977 runCmd('git commit -m "Add new file"', cwd=tempdir)
978 self.add_command_to_tearDown('cd %s; git clean -fd .; git checkout .' %
979 os.path.dirname(recipefile))
980 runCmd('devtool update-recipe %s' % testrecipe)
981 expected_status = [(' M', '.*/%s$' % os.path.basename(recipefile)),
982 (' M', '.*/makedevs/makedevs.c$'),
983 ('??', '.*/makedevs/new-local$'),
984 ('??', '.*/makedevs/0001-Add-new-file.patch$')]
985 self._check_repo_status(os.path.dirname(recipefile), expected_status)
986
987 @OETestID(1371)
988 def test_devtool_update_recipe_local_files_2(self):
989 """Check local source files support when oe-local-files is in Git"""
990 testrecipe = 'lzo'
991 recipefile = get_bb_var('FILE', testrecipe)
992 # Setup srctree for modifying the recipe
993 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
994 self.track_for_cleanup(tempdir)
995 self.track_for_cleanup(self.workspacedir)
996 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
997 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
998 # Check git repo
999 self._check_src_repo(tempdir)
1000 # Add oe-local-files to Git
1001 runCmd('rm oe-local-files/.gitignore', cwd=tempdir)
1002 runCmd('git add oe-local-files', cwd=tempdir)
1003 runCmd('git commit -m "Add local sources"', cwd=tempdir)
1004 # Edit / commit local sources
1005 runCmd('echo "# Foobar" >> oe-local-files/acinclude.m4', cwd=tempdir)
1006 runCmd('git commit -am "Edit existing file"', cwd=tempdir)
1007 runCmd('git rm oe-local-files/run-ptest', cwd=tempdir)
1008 runCmd('git commit -m"Remove file"', cwd=tempdir)
1009 runCmd('echo "Foo" > oe-local-files/new-local', cwd=tempdir)
1010 runCmd('git add oe-local-files/new-local', cwd=tempdir)
1011 runCmd('git commit -m "Add new local file"', cwd=tempdir)
1012 runCmd('echo "Gar" > new-file', cwd=tempdir)
1013 runCmd('git add new-file', cwd=tempdir)
1014 runCmd('git commit -m "Add new file"', cwd=tempdir)
1015 self.add_command_to_tearDown('cd %s; git clean -fd .; git checkout .' %
1016 os.path.dirname(recipefile))
1017 # Checkout unmodified file to working copy -> devtool should still pick
1018 # the modified version from HEAD
1019 runCmd('git checkout HEAD^ -- oe-local-files/acinclude.m4', cwd=tempdir)
1020 runCmd('devtool update-recipe %s' % testrecipe)
1021 expected_status = [(' M', '.*/%s$' % os.path.basename(recipefile)),
1022 (' M', '.*/acinclude.m4$'),
1023 (' D', '.*/run-ptest$'),
1024 ('??', '.*/new-local$'),
1025 ('??', '.*/0001-Add-new-file.patch$')]
1026 self._check_repo_status(os.path.dirname(recipefile), expected_status)
1027
1028 @OETestID(1627)
1029 def test_devtool_update_recipe_local_files_3(self):
1030 # First, modify the recipe
1031 testrecipe = 'devtool-test-localonly'
1032 bb_vars = get_bb_vars(['FILE', 'SRC_URI'], testrecipe)
1033 recipefile = bb_vars['FILE']
1034 src_uri = bb_vars['SRC_URI']
1035 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1036 self.track_for_cleanup(tempdir)
1037 self.track_for_cleanup(self.workspacedir)
1038 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1039 # (don't bother with cleaning the recipe on teardown, we won't be building it)
1040 result = runCmd('devtool modify %s' % testrecipe)
1041 # Modify one file
1042 runCmd('echo "Another line" >> file2', cwd=os.path.join(self.workspacedir, 'sources', testrecipe, 'oe-local-files'))
1043 self.add_command_to_tearDown('cd %s; rm %s/*; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, testrecipe, os.path.basename(recipefile)))
1044 result = runCmd('devtool update-recipe %s' % testrecipe)
1045 expected_status = [(' M', '.*/%s/file2$' % testrecipe)]
1046 self._check_repo_status(os.path.dirname(recipefile), expected_status)
1047
1048 @OETestID(1629)
1049 def test_devtool_update_recipe_local_patch_gz(self):
1050 # First, modify the recipe
1051 testrecipe = 'devtool-test-patch-gz'
1052 if get_bb_var('DISTRO') == 'poky-tiny':
1053 self.skipTest("The DISTRO 'poky-tiny' does not provide the dependencies needed by %s" % testrecipe)
1054 bb_vars = get_bb_vars(['FILE', 'SRC_URI'], testrecipe)
1055 recipefile = bb_vars['FILE']
1056 src_uri = bb_vars['SRC_URI']
1057 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1058 self.track_for_cleanup(tempdir)
1059 self.track_for_cleanup(self.workspacedir)
1060 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1061 # (don't bother with cleaning the recipe on teardown, we won't be building it)
1062 result = runCmd('devtool modify %s' % testrecipe)
1063 # Modify one file
1064 srctree = os.path.join(self.workspacedir, 'sources', testrecipe)
1065 runCmd('echo "Another line" >> README', cwd=srctree)
1066 runCmd('git commit -a --amend --no-edit', cwd=srctree)
1067 self.add_command_to_tearDown('cd %s; rm %s/*; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, testrecipe, os.path.basename(recipefile)))
1068 result = runCmd('devtool update-recipe %s' % testrecipe)
1069 expected_status = [(' M', '.*/%s/readme.patch.gz$' % testrecipe)]
1070 self._check_repo_status(os.path.dirname(recipefile), expected_status)
1071 patch_gz = os.path.join(os.path.dirname(recipefile), testrecipe, 'readme.patch.gz')
1072 result = runCmd('file %s' % patch_gz)
1073 if 'gzip compressed data' not in result.output:
1074 self.fail('New patch file is not gzipped - file reports:\n%s' % result.output)
1075
1076 @OETestID(1628)
1077 def test_devtool_update_recipe_local_files_subdir(self):
1078 # Try devtool update-recipe on a recipe that has a file with subdir= set in
1079 # SRC_URI such that it overwrites a file that was in an archive that
1080 # was also in SRC_URI
1081 # First, modify the recipe
1082 testrecipe = 'devtool-test-subdir'
1083 bb_vars = get_bb_vars(['FILE', 'SRC_URI'], testrecipe)
1084 recipefile = bb_vars['FILE']
1085 src_uri = bb_vars['SRC_URI']
1086 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1087 self.track_for_cleanup(tempdir)
1088 self.track_for_cleanup(self.workspacedir)
1089 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1090 # (don't bother with cleaning the recipe on teardown, we won't be building it)
1091 result = runCmd('devtool modify %s' % testrecipe)
1092 testfile = os.path.join(self.workspacedir, 'sources', testrecipe, 'testfile')
1093 self.assertExists(testfile, 'Extracted source could not be found')
1094 with open(testfile, 'r') as f:
1095 contents = f.read().rstrip()
1096 self.assertEqual(contents, 'Modified version', 'File has apparently not been overwritten as it should have been')
1097 # Test devtool update-recipe without modifying any files
1098 self.add_command_to_tearDown('cd %s; rm %s/*; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, testrecipe, os.path.basename(recipefile)))
1099 result = runCmd('devtool update-recipe %s' % testrecipe)
1100 expected_status = []
1101 self._check_repo_status(os.path.dirname(recipefile), expected_status)
1102
1103 @OETestID(1163)
1104 def test_devtool_extract(self):
1105 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1106 # Try devtool extract
1107 self.track_for_cleanup(tempdir)
1108 self.track_for_cleanup(self.workspacedir)
1109 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1110 result = runCmd('devtool extract matchbox-terminal %s' % tempdir)
1111 self.assertExists(os.path.join(tempdir, 'Makefile.am'), 'Extracted source could not be found')
1112 self._check_src_repo(tempdir)
1113
1114 @OETestID(1379)
1115 def test_devtool_extract_virtual(self):
1116 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1117 # Try devtool extract
1118 self.track_for_cleanup(tempdir)
1119 self.track_for_cleanup(self.workspacedir)
1120 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1121 result = runCmd('devtool extract virtual/make %s' % tempdir)
1122 self.assertExists(os.path.join(tempdir, 'Makefile.am'), 'Extracted source could not be found')
1123 self._check_src_repo(tempdir)
1124
1125 @OETestID(1168)
1126 def test_devtool_reset_all(self):
1127 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1128 self.track_for_cleanup(tempdir)
1129 self.track_for_cleanup(self.workspacedir)
1130 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1131 testrecipe1 = 'mdadm'
1132 testrecipe2 = 'cronie'
1133 result = runCmd('devtool modify -x %s %s' % (testrecipe1, os.path.join(tempdir, testrecipe1)))
1134 result = runCmd('devtool modify -x %s %s' % (testrecipe2, os.path.join(tempdir, testrecipe2)))
1135 result = runCmd('devtool build %s' % testrecipe1)
1136 result = runCmd('devtool build %s' % testrecipe2)
1137 stampprefix1 = get_bb_var('STAMP', testrecipe1)
1138 self.assertTrue(stampprefix1, 'Unable to get STAMP value for recipe %s' % testrecipe1)
1139 stampprefix2 = get_bb_var('STAMP', testrecipe2)
1140 self.assertTrue(stampprefix2, 'Unable to get STAMP value for recipe %s' % testrecipe2)
1141 result = runCmd('devtool reset -a')
1142 self.assertIn(testrecipe1, result.output)
1143 self.assertIn(testrecipe2, result.output)
1144 result = runCmd('devtool status')
1145 self.assertNotIn(testrecipe1, result.output)
1146 self.assertNotIn(testrecipe2, result.output)
1147 matches1 = glob.glob(stampprefix1 + '*')
1148 self.assertFalse(matches1, 'Stamp files exist for recipe %s that should have been cleaned' % testrecipe1)
1149 matches2 = glob.glob(stampprefix2 + '*')
1150 self.assertFalse(matches2, 'Stamp files exist for recipe %s that should have been cleaned' % testrecipe2)
1151
1152 @OETestID(1272)
1153 def test_devtool_deploy_target(self):
1154 # NOTE: Whilst this test would seemingly be better placed as a runtime test,
1155 # unfortunately the runtime tests run under bitbake and you can't run
1156 # devtool within bitbake (since devtool needs to run bitbake itself).
1157 # Additionally we are testing build-time functionality as well, so
1158 # really this has to be done as an oe-selftest test.
1159 #
1160 # Check preconditions
1161 machine = get_bb_var('MACHINE')
1162 if not machine.startswith('qemu'):
1163 self.skipTest('This test only works with qemu machines')
1164 if not os.path.exists('/etc/runqemu-nosudo'):
1165 self.skipTest('You must set up tap devices with scripts/runqemu-gen-tapdevs before running this test')
1166 result = runCmd('PATH="$PATH:/sbin:/usr/sbin" ip tuntap show', ignore_status=True)
1167 if result.status != 0:
1168 result = runCmd('PATH="$PATH:/sbin:/usr/sbin" ifconfig -a', ignore_status=True)
1169 if result.status != 0:
1170 self.skipTest('Failed to determine if tap devices exist with ifconfig or ip: %s' % result.output)
1171 for line in result.output.splitlines():
1172 if line.startswith('tap'):
1173 break
1174 else:
1175 self.skipTest('No tap devices found - you must set up tap devices with scripts/runqemu-gen-tapdevs before running this test')
1176 self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
1177 # Definitions
1178 testrecipe = 'mdadm'
1179 testfile = '/sbin/mdadm'
1180 testimage = 'oe-selftest-image'
1181 testcommand = '/sbin/mdadm --help'
1182 # Build an image to run
1183 bitbake("%s qemu-native qemu-helper-native" % testimage)
1184 deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
1185 self.add_command_to_tearDown('bitbake -c clean %s' % testimage)
1186 self.add_command_to_tearDown('rm -f %s/%s*' % (deploy_dir_image, testimage))
1187 # Clean recipe so the first deploy will fail
1188 bitbake("%s -c clean" % testrecipe)
1189 # Try devtool modify
1190 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1191 self.track_for_cleanup(tempdir)
1192 self.track_for_cleanup(self.workspacedir)
1193 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1194 self.add_command_to_tearDown('bitbake -c clean %s' % testrecipe)
1195 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
1196 # Test that deploy-target at this point fails (properly)
1197 result = runCmd('devtool deploy-target -n %s root@localhost' % testrecipe, ignore_status=True)
1198 self.assertNotEqual(result.output, 0, 'devtool deploy-target should have failed, output: %s' % result.output)
1199 self.assertNotIn(result.output, 'Traceback', 'devtool deploy-target should have failed with a proper error not a traceback, output: %s' % result.output)
1200 result = runCmd('devtool build %s' % testrecipe)
1201 # First try a dry-run of deploy-target
1202 result = runCmd('devtool deploy-target -n %s root@localhost' % testrecipe)
1203 self.assertIn(' %s' % testfile, result.output)
1204 # Boot the image
1205 with runqemu(testimage) as qemu:
1206 # Now really test deploy-target
1207 result = runCmd('devtool deploy-target -c %s root@%s' % (testrecipe, qemu.ip))
1208 # Run a test command to see if it was installed properly
1209 sshargs = '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'
1210 result = runCmd('ssh %s root@%s %s' % (sshargs, qemu.ip, testcommand))
1211 # Check if it deployed all of the files with the right ownership/perms
1212 # First look on the host - need to do this under pseudo to get the correct ownership/perms
1213 bb_vars = get_bb_vars(['D', 'FAKEROOTENV', 'FAKEROOTCMD'], testrecipe)
1214 installdir = bb_vars['D']
1215 fakerootenv = bb_vars['FAKEROOTENV']
1216 fakerootcmd = bb_vars['FAKEROOTCMD']
1217 result = runCmd('%s %s find . -type f -exec ls -l {} \;' % (fakerootenv, fakerootcmd), cwd=installdir)
1218 filelist1 = self._process_ls_output(result.output)
1219
1220 # Now look on the target
1221 tempdir2 = tempfile.mkdtemp(prefix='devtoolqa')
1222 self.track_for_cleanup(tempdir2)
1223 tmpfilelist = os.path.join(tempdir2, 'files.txt')
1224 with open(tmpfilelist, 'w') as f:
1225 for line in filelist1:
1226 splitline = line.split()
1227 f.write(splitline[-1] + '\n')
1228 result = runCmd('cat %s | ssh -q %s root@%s \'xargs ls -l\'' % (tmpfilelist, sshargs, qemu.ip))
1229 filelist2 = self._process_ls_output(result.output)
1230 filelist1.sort(key=lambda item: item.split()[-1])
1231 filelist2.sort(key=lambda item: item.split()[-1])
1232 self.assertEqual(filelist1, filelist2)
1233 # Test undeploy-target
1234 result = runCmd('devtool undeploy-target -c %s root@%s' % (testrecipe, qemu.ip))
1235 result = runCmd('ssh %s root@%s %s' % (sshargs, qemu.ip, testcommand), ignore_status=True)
1236 self.assertNotEqual(result, 0, 'undeploy-target did not remove command as it should have')
1237
1238 @OETestID(1366)
1239 def test_devtool_build_image(self):
1240 """Test devtool build-image plugin"""
1241 # Check preconditions
1242 self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
1243 image = 'core-image-minimal'
1244 self.track_for_cleanup(self.workspacedir)
1245 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1246 self.add_command_to_tearDown('bitbake -c clean %s' % image)
1247 bitbake('%s -c clean' % image)
1248 # Add target and native recipes to workspace
1249 recipes = ['mdadm', 'parted-native']
1250 for recipe in recipes:
1251 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1252 self.track_for_cleanup(tempdir)
1253 self.add_command_to_tearDown('bitbake -c clean %s' % recipe)
1254 runCmd('devtool modify %s -x %s' % (recipe, tempdir))
1255 # Try to build image
1256 result = runCmd('devtool build-image %s' % image)
1257 self.assertNotEqual(result, 0, 'devtool build-image failed')
1258 # Check if image contains expected packages
1259 deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
1260 image_link_name = get_bb_var('IMAGE_LINK_NAME', image)
1261 reqpkgs = [item for item in recipes if not item.endswith('-native')]
1262 with open(os.path.join(deploy_dir_image, image_link_name + '.manifest'), 'r') as f:
1263 for line in f:
1264 splitval = line.split()
1265 if splitval:
1266 pkg = splitval[0]
1267 if pkg in reqpkgs:
1268 reqpkgs.remove(pkg)
1269 if reqpkgs:
1270 self.fail('The following packages were not present in the image as expected: %s' % ', '.join(reqpkgs))
1271
1272 @OETestID(1367)
1273 def test_devtool_upgrade(self):
1274 # Check preconditions
1275 self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
1276 self.track_for_cleanup(self.workspacedir)
1277 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1278 # Check parameters
1279 result = runCmd('devtool upgrade -h')
1280 for param in 'recipename srctree --version -V --branch -b --keep-temp --no-patch'.split():
1281 self.assertIn(param, result.output)
1282 # For the moment, we are using a real recipe.
1283 recipe = 'devtool-upgrade-test1'
1284 version = '1.6.0'
1285 oldrecipefile = get_bb_var('FILE', recipe)
1286 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1287 self.track_for_cleanup(tempdir)
1288 # Check that recipe is not already under devtool control
1289 result = runCmd('devtool status')
1290 self.assertNotIn(recipe, result.output)
1291 # Check upgrade. Code does not check if new PV is older or newer that current PV, so, it may be that
1292 # we are downgrading instead of upgrading.
1293 result = runCmd('devtool upgrade %s %s -V %s' % (recipe, tempdir, version))
1294 # Check if srctree at least is populated
1295 self.assertTrue(len(os.listdir(tempdir)) > 0, 'srctree (%s) should be populated with new (%s) source code' % (tempdir, version))
1296 # Check new recipe subdirectory is present
1297 self.assertExists(os.path.join(self.workspacedir, 'recipes', recipe, '%s-%s' % (recipe, version)), 'Recipe folder should exist')
1298 # Check new recipe file is present
1299 newrecipefile = os.path.join(self.workspacedir, 'recipes', recipe, '%s_%s.bb' % (recipe, version))
1300 self.assertExists(newrecipefile, 'Recipe file should exist after upgrade')
1301 # Check devtool status and make sure recipe is present
1302 result = runCmd('devtool status')
1303 self.assertIn(recipe, result.output)
1304 self.assertIn(tempdir, result.output)
1305 # Check recipe got changed as expected
1306 with open(oldrecipefile + '.upgraded', 'r') as f:
1307 desiredlines = f.readlines()
1308 with open(newrecipefile, 'r') as f:
1309 newlines = f.readlines()
1310 self.assertEqual(desiredlines, newlines)
1311 # Check devtool reset recipe
1312 result = runCmd('devtool reset %s -n' % recipe)
1313 result = runCmd('devtool status')
1314 self.assertNotIn(recipe, result.output)
1315 self.assertNotExists(os.path.join(self.workspacedir, 'recipes', recipe), 'Recipe directory should not exist after resetting')
1316
1317 @OETestID(1433)
1318 def test_devtool_upgrade_git(self):
1319 # Check preconditions
1320 self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
1321 self.track_for_cleanup(self.workspacedir)
1322 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1323 recipe = 'devtool-upgrade-test2'
1324 commit = '6cc6077a36fe2648a5f993fe7c16c9632f946517'
1325 oldrecipefile = get_bb_var('FILE', recipe)
1326 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1327 self.track_for_cleanup(tempdir)
1328 # Check that recipe is not already under devtool control
1329 result = runCmd('devtool status')
1330 self.assertNotIn(recipe, result.output)
1331 # Check upgrade
1332 result = runCmd('devtool upgrade %s %s -S %s' % (recipe, tempdir, commit))
1333 # Check if srctree at least is populated
1334 self.assertTrue(len(os.listdir(tempdir)) > 0, 'srctree (%s) should be populated with new (%s) source code' % (tempdir, commit))
1335 # Check new recipe file is present
1336 newrecipefile = os.path.join(self.workspacedir, 'recipes', recipe, os.path.basename(oldrecipefile))
1337 self.assertExists(newrecipefile, 'Recipe file should exist after upgrade')
1338 # Check devtool status and make sure recipe is present
1339 result = runCmd('devtool status')
1340 self.assertIn(recipe, result.output)
1341 self.assertIn(tempdir, result.output)
1342 # Check recipe got changed as expected
1343 with open(oldrecipefile + '.upgraded', 'r') as f:
1344 desiredlines = f.readlines()
1345 with open(newrecipefile, 'r') as f:
1346 newlines = f.readlines()
1347 self.assertEqual(desiredlines, newlines)
1348 # Check devtool reset recipe
1349 result = runCmd('devtool reset %s -n' % recipe)
1350 result = runCmd('devtool status')
1351 self.assertNotIn(recipe, result.output)
1352 self.assertNotExists(os.path.join(self.workspacedir, 'recipes', recipe), 'Recipe directory should not exist after resetting')
1353
1354 @OETestID(1352)
1355 def test_devtool_layer_plugins(self):
1356 """Test that devtool can use plugins from other layers.
1357
1358 This test executes the selftest-reverse command from meta-selftest."""
1359
1360 self.track_for_cleanup(self.workspacedir)
1361 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1362
1363 s = "Microsoft Made No Profit From Anyone's Zunes Yo"
1364 result = runCmd("devtool --quiet selftest-reverse \"%s\"" % s)
1365 self.assertEqual(result.output, s[::-1])
1366
1367 def _copy_file_with_cleanup(self, srcfile, basedstdir, *paths):
1368 dstdir = basedstdir
1369 self.assertExists(dstdir)
1370 for p in paths:
1371 dstdir = os.path.join(dstdir, p)
1372 if not os.path.exists(dstdir):
1373 os.makedirs(dstdir)
1374 self.track_for_cleanup(dstdir)
1375 dstfile = os.path.join(dstdir, os.path.basename(srcfile))
1376 if srcfile != dstfile:
1377 shutil.copy(srcfile, dstfile)
1378 self.track_for_cleanup(dstfile)
1379
1380 @OETestID(1625)
1381 def test_devtool_load_plugin(self):
1382 """Test that devtool loads only the first found plugin in BBPATH."""
1383
1384 self.track_for_cleanup(self.workspacedir)
1385 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1386
1387 devtool = runCmd("which devtool")
1388 fromname = runCmd("devtool --quiet pluginfile")
1389 srcfile = fromname.output
1390 bbpath = get_bb_var('BBPATH')
1391 searchpath = bbpath.split(':') + [os.path.dirname(devtool.output)]
1392 plugincontent = []
1393 with open(srcfile) as fh:
1394 plugincontent = fh.readlines()
1395 try:
1396 self.assertIn('meta-selftest', srcfile, 'wrong bbpath plugin found')
1397 for path in searchpath:
1398 self._copy_file_with_cleanup(srcfile, path, 'lib', 'devtool')
1399 result = runCmd("devtool --quiet count")
1400 self.assertEqual(result.output, '1')
1401 result = runCmd("devtool --quiet multiloaded")
1402 self.assertEqual(result.output, "no")
1403 for path in searchpath:
1404 result = runCmd("devtool --quiet bbdir")
1405 self.assertEqual(result.output, path)
1406 os.unlink(os.path.join(result.output, 'lib', 'devtool', 'bbpath.py'))
1407 finally:
1408 with open(srcfile, 'w') as fh:
1409 fh.writelines(plugincontent)
1410
1411 def _setup_test_devtool_finish_upgrade(self):
1412 # Check preconditions
1413 self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
1414 self.track_for_cleanup(self.workspacedir)
1415 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1416 # Use a "real" recipe from meta-selftest
1417 recipe = 'devtool-upgrade-test1'
1418 oldversion = '1.5.3'
1419 newversion = '1.6.0'
1420 oldrecipefile = get_bb_var('FILE', recipe)
1421 recipedir = os.path.dirname(oldrecipefile)
1422 result = runCmd('git status --porcelain .', cwd=recipedir)
1423 if result.output.strip():
1424 self.fail('Recipe directory for %s contains uncommitted changes' % recipe)
1425 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1426 self.track_for_cleanup(tempdir)
1427 # Check that recipe is not already under devtool control
1428 result = runCmd('devtool status')
1429 self.assertNotIn(recipe, result.output)
1430 # Do the upgrade
1431 result = runCmd('devtool upgrade %s %s -V %s' % (recipe, tempdir, newversion))
1432 # Check devtool status and make sure recipe is present
1433 result = runCmd('devtool status')
1434 self.assertIn(recipe, result.output)
1435 self.assertIn(tempdir, result.output)
1436 # Make a change to the source
1437 result = runCmd('sed -i \'/^#include "pv.h"/a \\/* Here is a new comment *\\/\' src/pv/number.c', cwd=tempdir)
1438 result = runCmd('git status --porcelain', cwd=tempdir)
1439 self.assertIn('M src/pv/number.c', result.output)
1440 result = runCmd('git commit src/pv/number.c -m "Add a comment to the code"', cwd=tempdir)
1441 # Check if patch is there
1442 recipedir = os.path.dirname(oldrecipefile)
1443 olddir = os.path.join(recipedir, recipe + '-' + oldversion)
1444 patchfn = '0001-Add-a-note-line-to-the-quick-reference.patch'
1445 self.assertExists(os.path.join(olddir, patchfn), 'Original patch file does not exist')
1446 return recipe, oldrecipefile, recipedir, olddir, newversion, patchfn
1447
1448 @OETestID(1623)
1449 def test_devtool_finish_upgrade_origlayer(self):
1450 recipe, oldrecipefile, recipedir, olddir, newversion, patchfn = self._setup_test_devtool_finish_upgrade()
1451 # Ensure the recipe is where we think it should be (so that cleanup doesn't trash things)
1452 self.assertIn('/meta-selftest/', recipedir)
1453 # Try finish to the original layer
1454 self.add_command_to_tearDown('rm -rf %s ; cd %s ; git checkout %s' % (recipedir, os.path.dirname(recipedir), recipedir))
1455 result = runCmd('devtool finish %s meta-selftest' % recipe)
1456 result = runCmd('devtool status')
1457 self.assertNotIn(recipe, result.output, 'Recipe should have been reset by finish but wasn\'t')
1458 self.assertNotExists(os.path.join(self.workspacedir, 'recipes', recipe), 'Recipe directory should not exist after finish')
1459 self.assertNotExists(oldrecipefile, 'Old recipe file should have been deleted but wasn\'t')
1460 self.assertNotExists(os.path.join(olddir, patchfn), 'Old patch file should have been deleted but wasn\'t')
1461 newrecipefile = os.path.join(recipedir, '%s_%s.bb' % (recipe, newversion))
1462 newdir = os.path.join(recipedir, recipe + '-' + newversion)
1463 self.assertExists(newrecipefile, 'New recipe file should have been copied into existing layer but wasn\'t')
1464 self.assertExists(os.path.join(newdir, patchfn), 'Patch file should have been copied into new directory but wasn\'t')
1465 self.assertExists(os.path.join(newdir, '0002-Add-a-comment-to-the-code.patch'), 'New patch file should have been created but wasn\'t')
1466
1467 @OETestID(1624)
1468 def test_devtool_finish_upgrade_otherlayer(self):
1469 recipe, oldrecipefile, recipedir, olddir, newversion, patchfn = self._setup_test_devtool_finish_upgrade()
1470 # Ensure the recipe is where we think it should be (so that cleanup doesn't trash things)
1471 self.assertIn('/meta-selftest/', recipedir)
1472 # Try finish to a different layer - should create a bbappend
1473 # This cleanup isn't strictly necessary but do it anyway just in case it goes wrong and writes to here
1474 self.add_command_to_tearDown('rm -rf %s ; cd %s ; git checkout %s' % (recipedir, os.path.dirname(recipedir), recipedir))
1475 oe_core_dir = os.path.join(get_bb_var('COREBASE'), 'meta')
1476 newrecipedir = os.path.join(oe_core_dir, 'recipes-test', 'devtool')
1477 newrecipefile = os.path.join(newrecipedir, '%s_%s.bb' % (recipe, newversion))
1478 self.track_for_cleanup(newrecipedir)
1479 result = runCmd('devtool finish %s oe-core' % recipe)
1480 result = runCmd('devtool status')
1481 self.assertNotIn(recipe, result.output, 'Recipe should have been reset by finish but wasn\'t')
1482 self.assertNotExists(os.path.join(self.workspacedir, 'recipes', recipe), 'Recipe directory should not exist after finish')
1483 self.assertExists(oldrecipefile, 'Old recipe file should not have been deleted')
1484 self.assertExists(os.path.join(olddir, patchfn), 'Old patch file should not have been deleted')
1485 newdir = os.path.join(newrecipedir, recipe + '-' + newversion)
1486 self.assertExists(newrecipefile, 'New recipe file should have been copied into existing layer but wasn\'t')
1487 self.assertExists(os.path.join(newdir, patchfn), 'Patch file should have been copied into new directory but wasn\'t')
1488 self.assertExists(os.path.join(newdir, '0002-Add-a-comment-to-the-code.patch'), 'New patch file should have been created but wasn\'t')
1489
1490 def _setup_test_devtool_finish_modify(self):
1491 # Check preconditions
1492 self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
1493 # Try modifying a recipe
1494 self.track_for_cleanup(self.workspacedir)
1495 recipe = 'mdadm'
1496 oldrecipefile = get_bb_var('FILE', recipe)
1497 recipedir = os.path.dirname(oldrecipefile)
1498 result = runCmd('git status --porcelain .', cwd=recipedir)
1499 if result.output.strip():
1500 self.fail('Recipe directory for %s contains uncommitted changes' % recipe)
1501 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1502 self.track_for_cleanup(tempdir)
1503 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1504 result = runCmd('devtool modify %s %s' % (recipe, tempdir))
1505 self.assertExists(os.path.join(tempdir, 'Makefile'), 'Extracted source could not be found')
1506 # Test devtool status
1507 result = runCmd('devtool status')
1508 self.assertIn(recipe, result.output)
1509 self.assertIn(tempdir, result.output)
1510 # Make a change to the source
1511 result = runCmd('sed -i \'/^#include "mdadm.h"/a \\/* Here is a new comment *\\/\' maps.c', cwd=tempdir)
1512 result = runCmd('git status --porcelain', cwd=tempdir)
1513 self.assertIn('M maps.c', result.output)
1514 result = runCmd('git commit maps.c -m "Add a comment to the code"', cwd=tempdir)
1515 for entry in os.listdir(recipedir):
1516 filesdir = os.path.join(recipedir, entry)
1517 if os.path.isdir(filesdir):
1518 break
1519 else:
1520 self.fail('Unable to find recipe files directory for %s' % recipe)
1521 return recipe, oldrecipefile, recipedir, filesdir
1522
1523 @OETestID(1621)
1524 def test_devtool_finish_modify_origlayer(self):
1525 recipe, oldrecipefile, recipedir, filesdir = self._setup_test_devtool_finish_modify()
1526 # Ensure the recipe is where we think it should be (so that cleanup doesn't trash things)
1527 self.assertIn('/meta/', recipedir)
1528 # Try finish to the original layer
1529 self.add_command_to_tearDown('rm -rf %s ; cd %s ; git checkout %s' % (recipedir, os.path.dirname(recipedir), recipedir))
1530 result = runCmd('devtool finish %s meta' % recipe)
1531 result = runCmd('devtool status')
1532 self.assertNotIn(recipe, result.output, 'Recipe should have been reset by finish but wasn\'t')
1533 self.assertNotExists(os.path.join(self.workspacedir, 'recipes', recipe), 'Recipe directory should not exist after finish')
1534 expected_status = [(' M', '.*/%s$' % os.path.basename(oldrecipefile)),
1535 ('??', '.*/.*-Add-a-comment-to-the-code.patch$')]
1536 self._check_repo_status(recipedir, expected_status)
1537
1538 @OETestID(1622)
1539 def test_devtool_finish_modify_otherlayer(self):
1540 recipe, oldrecipefile, recipedir, filesdir = self._setup_test_devtool_finish_modify()
1541 # Ensure the recipe is where we think it should be (so that cleanup doesn't trash things)
1542 self.assertIn('/meta/', recipedir)
1543 relpth = os.path.relpath(recipedir, os.path.join(get_bb_var('COREBASE'), 'meta'))
1544 appenddir = os.path.join(get_test_layer(), relpth)
1545 self.track_for_cleanup(appenddir)
1546 # Try finish to the original layer
1547 self.add_command_to_tearDown('rm -rf %s ; cd %s ; git checkout %s' % (recipedir, os.path.dirname(recipedir), recipedir))
1548 result = runCmd('devtool finish %s meta-selftest' % recipe)
1549 result = runCmd('devtool status')
1550 self.assertNotIn(recipe, result.output, 'Recipe should have been reset by finish but wasn\'t')
1551 self.assertNotExists(os.path.join(self.workspacedir, 'recipes', recipe), 'Recipe directory should not exist after finish')
1552 result = runCmd('git status --porcelain .', cwd=recipedir)
1553 if result.output.strip():
1554 self.fail('Recipe directory for %s contains the following unexpected changes after finish:\n%s' % (recipe, result.output.strip()))
1555 recipefn = os.path.splitext(os.path.basename(oldrecipefile))[0]
1556 recipefn = recipefn.split('_')[0] + '_%'
1557 appendfile = os.path.join(appenddir, recipefn + '.bbappend')
1558 self.assertExists(appendfile, 'bbappend %s should have been created but wasn\'t' % appendfile)
1559 newdir = os.path.join(appenddir, recipe)
1560 files = os.listdir(newdir)
1561 foundpatch = None
1562 for fn in files:
1563 if fnmatch.fnmatch(fn, '*-Add-a-comment-to-the-code.patch'):
1564 foundpatch = fn
1565 if not foundpatch:
1566 self.fail('No patch file created next to bbappend')
1567 files.remove(foundpatch)
1568 if files:
1569 self.fail('Unexpected file(s) copied next to bbappend: %s' % ', '.join(files))
1570
1571 @OETestID(1626)
1572 def test_devtool_rename(self):
1573 # Check preconditions
1574 self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
1575 self.track_for_cleanup(self.workspacedir)
1576 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1577
1578 # First run devtool add
1579 # We already have this recipe in OE-Core, but that doesn't matter
1580 recipename = 'i2c-tools'
1581 recipever = '3.1.2'
1582 recipefile = os.path.join(self.workspacedir, 'recipes', recipename, '%s_%s.bb' % (recipename, recipever))
1583 url = 'http://downloads.yoctoproject.org/mirror/sources/i2c-tools-%s.tar.bz2' % recipever
1584 def add_recipe():
1585 result = runCmd('devtool add %s' % url)
1586 self.assertExists(recipefile, 'Expected recipe file not created')
1587 self.assertExists(os.path.join(self.workspacedir, 'sources', recipename), 'Source directory not created')
1588 checkvars = {}
1589 checkvars['S'] = None
1590 checkvars['SRC_URI'] = url.replace(recipever, '${PV}')
1591 self._test_recipe_contents(recipefile, checkvars, [])
1592 add_recipe()
1593 # Now rename it - change both name and version
1594 newrecipename = 'mynewrecipe'
1595 newrecipever = '456'
1596 newrecipefile = os.path.join(self.workspacedir, 'recipes', newrecipename, '%s_%s.bb' % (newrecipename, newrecipever))
1597 result = runCmd('devtool rename %s %s -V %s' % (recipename, newrecipename, newrecipever))
1598 self.assertExists(newrecipefile, 'Recipe file not renamed')
1599 self.assertNotExists(os.path.join(self.workspacedir, 'recipes', recipename), 'Old recipe directory still exists')
1600 newsrctree = os.path.join(self.workspacedir, 'sources', newrecipename)
1601 self.assertExists(newsrctree, 'Source directory not renamed')
1602 checkvars = {}
1603 checkvars['S'] = '${WORKDIR}/%s-%s' % (recipename, recipever)
1604 checkvars['SRC_URI'] = url
1605 self._test_recipe_contents(newrecipefile, checkvars, [])
1606 # Try again - change just name this time
1607 result = runCmd('devtool reset -n %s' % newrecipename)
1608 shutil.rmtree(newsrctree)
1609 add_recipe()
1610 newrecipefile = os.path.join(self.workspacedir, 'recipes', newrecipename, '%s_%s.bb' % (newrecipename, recipever))
1611 result = runCmd('devtool rename %s %s' % (recipename, newrecipename))
1612 self.assertExists(newrecipefile, 'Recipe file not renamed')
1613 self.assertNotExists(os.path.join(self.workspacedir, 'recipes', recipename), 'Old recipe directory still exists')
1614 self.assertExists(os.path.join(self.workspacedir, 'sources', newrecipename), 'Source directory not renamed')
1615 checkvars = {}
1616 checkvars['S'] = '${WORKDIR}/%s-${PV}' % recipename
1617 checkvars['SRC_URI'] = url.replace(recipever, '${PV}')
1618 self._test_recipe_contents(newrecipefile, checkvars, [])
1619 # Try again - change just version this time
1620 result = runCmd('devtool reset -n %s' % newrecipename)
1621 shutil.rmtree(newsrctree)
1622 add_recipe()
1623 newrecipefile = os.path.join(self.workspacedir, 'recipes', recipename, '%s_%s.bb' % (recipename, newrecipever))
1624 result = runCmd('devtool rename %s -V %s' % (recipename, newrecipever))
1625 self.assertExists(newrecipefile, 'Recipe file not renamed')
1626 self.assertExists(os.path.join(self.workspacedir, 'sources', recipename), 'Source directory no longer exists')
1627 checkvars = {}
1628 checkvars['S'] = '${WORKDIR}/${BPN}-%s' % recipever
1629 checkvars['SRC_URI'] = url
1630 self._test_recipe_contents(newrecipefile, checkvars, [])
1631
1632 @OETestID(1577)
1633 def test_devtool_virtual_kernel_modify(self):
1634 """
1635 Summary: The purpose of this test case is to verify that
1636 devtool modify works correctly when building
1637 the kernel.
1638 Dependencies: NA
1639 Steps: 1. Build kernel with bitbake.
1640 2. Save the config file generated.
1641 3. Clean the environment.
1642 4. Use `devtool modify virtual/kernel` to validate following:
1643 4.1 The source is checked out correctly.
1644 4.2 The resulting configuration is the same as
1645 what was get on step 2.
1646 4.3 The Kernel can be build correctly.
1647 4.4 Changes made on the source are reflected on the
1648 subsequent builds.
1649 4.5 Changes on the configuration are reflected on the
1650 subsequent builds
1651 Expected: devtool modify is able to checkout the source of the kernel
1652 and modification to the source and configurations are reflected
1653 when building the kernel.
1654 """
1655 kernel_provider = get_bb_var('PREFERRED_PROVIDER_virtual/kernel')
1656 # Clean up the enviroment
1657 bitbake('%s -c clean' % kernel_provider)
1658 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1659 tempdir_cfg = tempfile.mkdtemp(prefix='config_qa')
1660 self.track_for_cleanup(tempdir)
1661 self.track_for_cleanup(tempdir_cfg)
1662 self.track_for_cleanup(self.workspacedir)
1663 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1664 self.add_command_to_tearDown('bitbake -c clean %s' % kernel_provider)
1665 #Step 1
1666 #Here is just generated the config file instead of all the kernel to optimize the
1667 #time of executing this test case.
1668 bitbake('%s -c configure' % kernel_provider)
1669 bbconfig = os.path.join(get_bb_var('B', kernel_provider),'.config')
1670 #Step 2
1671 runCmd('cp %s %s' % (bbconfig, tempdir_cfg))
1672 self.assertExists(os.path.join(tempdir_cfg, '.config'), 'Could not copy .config file from kernel')
1673
1674 tmpconfig = os.path.join(tempdir_cfg, '.config')
1675 #Step 3
1676 bitbake('%s -c clean' % kernel_provider)
1677 #Step 4.1
1678 runCmd('devtool modify virtual/kernel -x %s' % tempdir)
1679 self.assertExists(os.path.join(tempdir, 'Makefile'), 'Extracted source could not be found')
1680 #Step 4.2
1681 configfile = os.path.join(tempdir,'.config')
1682 diff = runCmd('diff %s %s' % (tmpconfig, configfile))
1683 self.assertEqual(0,diff.status,'Kernel .config file is not the same using bitbake and devtool')
1684 #Step 4.3
1685 #NOTE: virtual/kernel is mapped to kernel_provider
1686 result = runCmd('devtool build %s' % kernel_provider)
1687 self.assertEqual(0,result.status,'Cannot build kernel using `devtool build`')
1688 kernelfile = os.path.join(get_bb_var('KBUILD_OUTPUT', kernel_provider), 'vmlinux')
1689 self.assertExists(kernelfile, 'Kernel was not build correctly')
1690
1691 #Modify the kernel source
1692 modfile = os.path.join(tempdir,'arch/x86/boot/header.S')
1693 modstring = "Use a boot loader. Devtool testing."
1694 modapplied = runCmd("sed -i 's/Use a boot loader./%s/' %s" % (modstring, modfile))
1695 self.assertEqual(0,modapplied.status,'Modification to %s on kernel source failed' % modfile)
1696 #Modify the configuration
1697 codeconfigfile = os.path.join(tempdir,'.config.new')
1698 modconfopt = "CONFIG_SG_POOL=n"
1699 modconf = runCmd("sed -i 's/CONFIG_SG_POOL=y/%s/' %s" % (modconfopt, codeconfigfile))
1700 self.assertEqual(0,modconf.status,'Modification to %s failed' % codeconfigfile)
1701 #Build again kernel with devtool
1702 rebuild = runCmd('devtool build %s' % kernel_provider)
1703 self.assertEqual(0,rebuild.status,'Fail to build kernel after modification of source and config')
1704 #Step 4.4
1705 bzimagename = 'bzImage-' + get_bb_var('KERNEL_VERSION_NAME', kernel_provider)
1706 bzimagefile = os.path.join(get_bb_var('D', kernel_provider),'boot', bzimagename)
1707 checkmodcode = runCmd("grep '%s' %s" % (modstring, bzimagefile))
1708 self.assertEqual(0,checkmodcode.status,'Modification on kernel source failed')
1709 #Step 4.5
1710 checkmodconfg = runCmd("grep %s %s" % (modconfopt, codeconfigfile))
1711 self.assertEqual(0,checkmodconfg.status,'Modification to configuration file failed')