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