blob: dcdef5a14be9d6753d117e16cfc72f31551ddcf4 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001import unittest
2import os
3import logging
4import re
5import shutil
6import tempfile
7import glob
8
9import oeqa.utils.ftools as ftools
10from oeqa.selftest.base import oeSelfTest
11from oeqa.utils.commands import runCmd, bitbake, get_bb_var, create_temp_layer, runqemu
12from oeqa.utils.decorators import testcase
13
14class DevtoolBase(oeSelfTest):
15
16 def _test_recipe_contents(self, recipefile, checkvars, checkinherits):
17 with open(recipefile, 'r') as f:
18 for line in f:
19 if '=' in line:
20 splitline = line.split('=', 1)
21 var = splitline[0].rstrip()
22 value = splitline[1].strip().strip('"')
23 if var in checkvars:
24 needvalue = checkvars.pop(var)
25 self.assertEqual(value, needvalue, 'values for %s do not match' % var)
26 if line.startswith('inherit '):
27 inherits = line.split()[1:]
28
29 self.assertEqual(checkvars, {}, 'Some variables not found: %s' % checkvars)
30
31 for inherit in checkinherits:
32 self.assertIn(inherit, inherits, 'Missing inherit of %s' % inherit)
33
34 def _check_bbappend(self, testrecipe, recipefile, appenddir):
35 result = runCmd('bitbake-layers show-appends', cwd=self.builddir)
36 resultlines = result.output.splitlines()
37 inrecipe = False
38 bbappends = []
39 bbappendfile = None
40 for line in resultlines:
41 if inrecipe:
42 if line.startswith(' '):
43 bbappends.append(line.strip())
44 else:
45 break
46 elif line == '%s:' % os.path.basename(recipefile):
47 inrecipe = True
48 self.assertLessEqual(len(bbappends), 2, '%s recipe is being bbappended by another layer - bbappends found:\n %s' % (testrecipe, '\n '.join(bbappends)))
49 for bbappend in bbappends:
50 if bbappend.startswith(appenddir):
51 bbappendfile = bbappend
52 break
53 else:
54 self.fail('bbappend for recipe %s does not seem to be created in test layer' % testrecipe)
55 return bbappendfile
56
57 def _create_temp_layer(self, templayerdir, addlayer, templayername, priority=999, recipepathspec='recipes-*/*'):
58 create_temp_layer(templayerdir, templayername, priority, recipepathspec)
59 if addlayer:
60 self.add_command_to_tearDown('bitbake-layers remove-layer %s || true' % templayerdir)
61 result = runCmd('bitbake-layers add-layer %s' % templayerdir, cwd=self.builddir)
62
63 def _process_ls_output(self, output):
64 """
65 Convert ls -l output to a format we can reasonably compare from one context
66 to another (e.g. from host to target)
67 """
68 filelist = []
69 for line in output.splitlines():
70 splitline = line.split()
71 # Remove trailing . on perms
72 splitline[0] = splitline[0].rstrip('.')
73 # Remove leading . on paths
74 splitline[-1] = splitline[-1].lstrip('.')
75 # Drop fields we don't want to compare
76 del splitline[7]
77 del splitline[6]
78 del splitline[5]
79 del splitline[4]
80 del splitline[1]
81 filelist.append(' '.join(splitline))
82 return filelist
83
84
85class DevtoolTests(DevtoolBase):
86
Patrick Williamsf1e5d692016-03-30 15:21:19 -050087 def setUp(self):
88 """Test case setup function"""
89 super(DevtoolTests, self).setUp()
90 self.workspacedir = os.path.join(self.builddir, 'workspace')
91 self.assertTrue(not os.path.exists(self.workspacedir),
92 'This test cannot be run with a workspace directory '
93 'under the build directory')
94
95 def _check_src_repo(self, repo_dir):
96 """Check srctree git repository"""
97 self.assertTrue(os.path.isdir(os.path.join(repo_dir, '.git')),
98 'git repository for external source tree not found')
99 result = runCmd('git status --porcelain', cwd=repo_dir)
100 self.assertEqual(result.output.strip(), "",
101 'Created git repo is not clean')
102 result = runCmd('git symbolic-ref HEAD', cwd=repo_dir)
103 self.assertEqual(result.output.strip(), "refs/heads/devtool",
104 'Wrong branch in git repo')
105
106 def _check_repo_status(self, repo_dir, expected_status):
107 """Check the worktree status of a repository"""
108 result = runCmd('git status . --porcelain',
109 cwd=repo_dir)
110 for line in result.output.splitlines():
111 for ind, (f_status, fn_re) in enumerate(expected_status):
112 if re.match(fn_re, line[3:]):
113 if f_status != line[:2]:
114 self.fail('Unexpected status in line: %s' % line)
115 expected_status.pop(ind)
116 break
117 else:
118 self.fail('Unexpected modified file in line: %s' % line)
119 if expected_status:
120 self.fail('Missing file changes: %s' % expected_status)
121
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500122 @testcase(1158)
123 def test_create_workspace(self):
124 # Check preconditions
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500125 result = runCmd('bitbake-layers show-layers')
126 self.assertTrue('/workspace' not in result.output, 'This test cannot be run with a workspace layer in bblayers.conf')
127 # Try creating a workspace layer with a specific path
128 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
129 self.track_for_cleanup(tempdir)
130 result = runCmd('devtool create-workspace %s' % tempdir)
131 self.assertTrue(os.path.isfile(os.path.join(tempdir, 'conf', 'layer.conf')), msg = "No workspace created. devtool output: %s " % result.output)
132 result = runCmd('bitbake-layers show-layers')
133 self.assertIn(tempdir, result.output)
134 # Try creating a workspace layer with the default path
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500135 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500136 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
137 result = runCmd('devtool create-workspace')
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500138 self.assertTrue(os.path.isfile(os.path.join(self.workspacedir, 'conf', 'layer.conf')), msg = "No workspace created. devtool output: %s " % result.output)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500139 result = runCmd('bitbake-layers show-layers')
140 self.assertNotIn(tempdir, result.output)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500141 self.assertIn(self.workspacedir, result.output)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500142
143 @testcase(1159)
144 def test_devtool_add(self):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500145 # Fetch source
146 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
147 self.track_for_cleanup(tempdir)
148 url = 'http://www.ivarch.com/programs/sources/pv-1.5.3.tar.bz2'
149 result = runCmd('wget %s' % url, cwd=tempdir)
150 result = runCmd('tar xfv pv-1.5.3.tar.bz2', cwd=tempdir)
151 srcdir = os.path.join(tempdir, 'pv-1.5.3')
152 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure')), 'Unable to find configure script in source directory')
153 # Test devtool add
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500154 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500155 self.add_command_to_tearDown('bitbake -c cleansstate pv')
156 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
157 result = runCmd('devtool add pv %s' % srcdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500158 self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500159 # Test devtool status
160 result = runCmd('devtool status')
161 self.assertIn('pv', result.output)
162 self.assertIn(srcdir, result.output)
163 # Clean up anything in the workdir/sysroot/sstate cache (have to do this *after* devtool add since the recipe only exists then)
164 bitbake('pv -c cleansstate')
165 # Test devtool build
166 result = runCmd('devtool build pv')
167 installdir = get_bb_var('D', 'pv')
168 self.assertTrue(installdir, 'Could not query installdir variable')
169 bindir = get_bb_var('bindir', 'pv')
170 self.assertTrue(bindir, 'Could not query bindir variable')
171 if bindir[0] == '/':
172 bindir = bindir[1:]
173 self.assertTrue(os.path.isfile(os.path.join(installdir, bindir, 'pv')), 'pv binary not found in D')
174
175 @testcase(1162)
176 def test_devtool_add_library(self):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500177 # We don't have the ability to pick up this dependency automatically yet...
178 bitbake('libusb1')
179 # Fetch source
180 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
181 self.track_for_cleanup(tempdir)
182 url = 'http://www.intra2net.com/en/developer/libftdi/download/libftdi1-1.1.tar.bz2'
183 result = runCmd('wget %s' % url, cwd=tempdir)
184 result = runCmd('tar xfv libftdi1-1.1.tar.bz2', cwd=tempdir)
185 srcdir = os.path.join(tempdir, 'libftdi1-1.1')
186 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'CMakeLists.txt')), 'Unable to find CMakeLists.txt in source directory')
187 # Test devtool add (and use -V so we test that too)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500188 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500189 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
190 result = runCmd('devtool add libftdi %s -V 1.1' % srcdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500191 self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500192 # Test devtool status
193 result = runCmd('devtool status')
194 self.assertIn('libftdi', result.output)
195 self.assertIn(srcdir, result.output)
196 # Clean up anything in the workdir/sysroot/sstate cache (have to do this *after* devtool add since the recipe only exists then)
197 bitbake('libftdi -c cleansstate')
198 # Test devtool build
199 result = runCmd('devtool build libftdi')
200 staging_libdir = get_bb_var('STAGING_LIBDIR', 'libftdi')
201 self.assertTrue(staging_libdir, 'Could not query STAGING_LIBDIR variable')
202 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)
203 # Test devtool reset
204 stampprefix = get_bb_var('STAMP', 'libftdi')
205 result = runCmd('devtool reset libftdi')
206 result = runCmd('devtool status')
207 self.assertNotIn('libftdi', result.output)
208 self.assertTrue(stampprefix, 'Unable to get STAMP value for recipe libftdi')
209 matches = glob.glob(stampprefix + '*')
210 self.assertFalse(matches, 'Stamp files exist for recipe libftdi that should have been cleaned')
211 self.assertFalse(os.path.isfile(os.path.join(staging_libdir, 'libftdi1.so.2.1.0')), 'libftdi binary still found in STAGING_LIBDIR after cleaning')
212
213 @testcase(1160)
214 def test_devtool_add_fetch(self):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500215 # Fetch source
216 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
217 self.track_for_cleanup(tempdir)
218 testver = '0.23'
219 url = 'https://pypi.python.org/packages/source/M/MarkupSafe/MarkupSafe-%s.tar.gz' % testver
220 testrecipe = 'python-markupsafe'
221 srcdir = os.path.join(tempdir, testrecipe)
222 # Test devtool add
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500223 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500224 self.add_command_to_tearDown('bitbake -c cleansstate %s' % testrecipe)
225 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
226 result = runCmd('devtool add %s %s -f %s' % (testrecipe, srcdir, url))
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500227 self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created. %s' % result.output)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500228 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'setup.py')), 'Unable to find setup.py in source directory')
229 # Test devtool status
230 result = runCmd('devtool status')
231 self.assertIn(testrecipe, result.output)
232 self.assertIn(srcdir, result.output)
233 # Check recipe
234 recipefile = get_bb_var('FILE', testrecipe)
235 self.assertIn('%s.bb' % testrecipe, recipefile, 'Recipe file incorrectly named')
236 checkvars = {}
237 checkvars['S'] = '${WORKDIR}/MarkupSafe-%s' % testver
238 checkvars['SRC_URI'] = url
239 self._test_recipe_contents(recipefile, checkvars, [])
240 # Try with version specified
241 result = runCmd('devtool reset -n %s' % testrecipe)
242 shutil.rmtree(srcdir)
243 result = runCmd('devtool add %s %s -f %s -V %s' % (testrecipe, srcdir, url, testver))
244 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'setup.py')), 'Unable to find setup.py in source directory')
245 # Test devtool status
246 result = runCmd('devtool status')
247 self.assertIn(testrecipe, result.output)
248 self.assertIn(srcdir, result.output)
249 # Check recipe
250 recipefile = get_bb_var('FILE', testrecipe)
251 self.assertIn('%s_%s.bb' % (testrecipe, testver), recipefile, 'Recipe file incorrectly named')
252 checkvars = {}
253 checkvars['S'] = '${WORKDIR}/MarkupSafe-${PV}'
254 checkvars['SRC_URI'] = url.replace(testver, '${PV}')
255 self._test_recipe_contents(recipefile, checkvars, [])
256
257 @testcase(1161)
258 def test_devtool_add_fetch_git(self):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500259 # Fetch source
260 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
261 self.track_for_cleanup(tempdir)
262 url = 'git://git.yoctoproject.org/libmatchbox'
263 checkrev = '462f0652055d89c648ddd54fd7b03f175c2c6973'
264 testrecipe = 'libmatchbox2'
265 srcdir = os.path.join(tempdir, testrecipe)
266 # Test devtool add
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500267 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500268 self.add_command_to_tearDown('bitbake -c cleansstate %s' % testrecipe)
269 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
270 result = runCmd('devtool add %s %s -f %s' % (testrecipe, srcdir, url))
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500271 self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created: %s' % result.output)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500272 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure.ac')), 'Unable to find configure.ac in source directory')
273 # Test devtool status
274 result = runCmd('devtool status')
275 self.assertIn(testrecipe, result.output)
276 self.assertIn(srcdir, result.output)
277 # Check recipe
278 recipefile = get_bb_var('FILE', testrecipe)
279 self.assertIn('_git.bb', recipefile, 'Recipe file incorrectly named')
280 checkvars = {}
281 checkvars['S'] = '${WORKDIR}/git'
282 checkvars['PV'] = '1.0+git${SRCPV}'
283 checkvars['SRC_URI'] = url
284 checkvars['SRCREV'] = '${AUTOREV}'
285 self._test_recipe_contents(recipefile, checkvars, [])
286 # Try with revision and version specified
287 result = runCmd('devtool reset -n %s' % testrecipe)
288 shutil.rmtree(srcdir)
289 url_rev = '%s;rev=%s' % (url, checkrev)
290 result = runCmd('devtool add %s %s -f "%s" -V 1.5' % (testrecipe, srcdir, url_rev))
291 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure.ac')), 'Unable to find configure.ac in source directory')
292 # Test devtool status
293 result = runCmd('devtool status')
294 self.assertIn(testrecipe, result.output)
295 self.assertIn(srcdir, result.output)
296 # Check recipe
297 recipefile = get_bb_var('FILE', testrecipe)
298 self.assertIn('_git.bb', recipefile, 'Recipe file incorrectly named')
299 checkvars = {}
300 checkvars['S'] = '${WORKDIR}/git'
301 checkvars['PV'] = '1.5+git${SRCPV}'
302 checkvars['SRC_URI'] = url
303 checkvars['SRCREV'] = checkrev
304 self._test_recipe_contents(recipefile, checkvars, [])
305
306 @testcase(1164)
307 def test_devtool_modify(self):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500308 # Clean up anything in the workdir/sysroot/sstate cache
309 bitbake('mdadm -c cleansstate')
310 # Try modifying a recipe
311 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
312 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500313 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500314 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
315 self.add_command_to_tearDown('bitbake -c clean mdadm')
316 result = runCmd('devtool modify mdadm -x %s' % tempdir)
317 self.assertTrue(os.path.exists(os.path.join(tempdir, 'Makefile')), 'Extracted source could not be found')
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500318 self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created')
319 matches = glob.glob(os.path.join(self.workspacedir, 'appends', 'mdadm_*.bbappend'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500320 self.assertTrue(matches, 'bbappend not created %s' % result.output)
321 # Test devtool status
322 result = runCmd('devtool status')
323 self.assertIn('mdadm', result.output)
324 self.assertIn(tempdir, result.output)
325 # Check git repo
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500326 self._check_src_repo(tempdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500327 # Try building
328 bitbake('mdadm')
329 # Try making (minor) modifications to the source
330 result = runCmd("sed -i 's!^\.TH.*!.TH MDADM 8 \"\" v9.999-custom!' %s" % os.path.join(tempdir, 'mdadm.8.in'))
331 bitbake('mdadm -c package')
332 pkgd = get_bb_var('PKGD', 'mdadm')
333 self.assertTrue(pkgd, 'Could not query PKGD variable')
334 mandir = get_bb_var('mandir', 'mdadm')
335 self.assertTrue(mandir, 'Could not query mandir variable')
336 if mandir[0] == '/':
337 mandir = mandir[1:]
338 with open(os.path.join(pkgd, mandir, 'man8', 'mdadm.8'), 'r') as f:
339 for line in f:
340 if line.startswith('.TH'):
341 self.assertEqual(line.rstrip(), '.TH MDADM 8 "" v9.999-custom', 'man file not modified. man searched file path: %s' % os.path.join(pkgd, mandir, 'man8', 'mdadm.8'))
342 # Test devtool reset
343 stampprefix = get_bb_var('STAMP', 'mdadm')
344 result = runCmd('devtool reset mdadm')
345 result = runCmd('devtool status')
346 self.assertNotIn('mdadm', result.output)
347 self.assertTrue(stampprefix, 'Unable to get STAMP value for recipe mdadm')
348 matches = glob.glob(stampprefix + '*')
349 self.assertFalse(matches, 'Stamp files exist for recipe mdadm that should have been cleaned')
350
351 @testcase(1166)
352 def test_devtool_modify_invalid(self):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500353 # Try modifying some recipes
354 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
355 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500356 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500357 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
358
359 testrecipes = 'perf kernel-devsrc package-index core-image-minimal meta-toolchain packagegroup-core-sdk meta-ide-support'.split()
360 # Find actual name of gcc-source since it now includes the version - crude, but good enough for this purpose
361 result = runCmd('bitbake-layers show-recipes gcc-source*')
362 reading = False
363 for line in result.output.splitlines():
364 if line.startswith('=='):
365 reading = True
366 elif reading and not line.startswith(' '):
367 testrecipes.append(line.split(':')[0])
368 for testrecipe in testrecipes:
369 # Check it's a valid recipe
370 bitbake('%s -e' % testrecipe)
371 # devtool extract should fail
372 result = runCmd('devtool extract %s %s' % (testrecipe, os.path.join(tempdir, testrecipe)), ignore_status=True)
373 self.assertNotEqual(result.status, 0, 'devtool extract on %s should have failed. devtool output: %s' % (testrecipe, result.output))
374 self.assertNotIn('Fetching ', result.output, 'devtool extract on %s should have errored out before trying to fetch' % testrecipe)
375 self.assertIn('ERROR: ', result.output, 'devtool extract on %s should have given an ERROR' % testrecipe)
376 # devtool modify should fail
377 result = runCmd('devtool modify %s -x %s' % (testrecipe, os.path.join(tempdir, testrecipe)), ignore_status=True)
378 self.assertNotEqual(result.status, 0, 'devtool modify on %s should have failed. devtool output: %s' % (testrecipe, result.output))
379 self.assertIn('ERROR: ', result.output, 'devtool modify on %s should have given an ERROR' % testrecipe)
380
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500381 @testcase(1365)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500382 def test_devtool_modify_native(self):
383 # Check preconditions
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500384 self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500385 # Try modifying some recipes
386 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
387 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500388 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500389 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
390
391 bbclassextended = False
392 inheritnative = False
393 testrecipes = 'mtools-native apt-native desktop-file-utils-native'.split()
394 for testrecipe in testrecipes:
395 checkextend = 'native' in (get_bb_var('BBCLASSEXTEND', testrecipe) or '').split()
396 if not bbclassextended:
397 bbclassextended = checkextend
398 if not inheritnative:
399 inheritnative = not checkextend
400 result = runCmd('devtool modify %s -x %s' % (testrecipe, os.path.join(tempdir, testrecipe)))
401 self.assertNotIn('ERROR: ', result.output, 'ERROR in devtool modify output: %s' % result.output)
402 result = runCmd('devtool build %s' % testrecipe)
403 self.assertNotIn('ERROR: ', result.output, 'ERROR in devtool build output: %s' % result.output)
404 result = runCmd('devtool reset %s' % testrecipe)
405 self.assertNotIn('ERROR: ', result.output, 'ERROR in devtool reset output: %s' % result.output)
406
407 self.assertTrue(bbclassextended, 'None of these recipes are BBCLASSEXTENDed to native - need to adjust testrecipes list: %s' % ', '.join(testrecipes))
408 self.assertTrue(inheritnative, 'None of these recipes do "inherit native" - need to adjust testrecipes list: %s' % ', '.join(testrecipes))
409
410
411 @testcase(1165)
412 def test_devtool_modify_git(self):
413 # Check preconditions
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500414 testrecipe = 'mkelfimage'
415 src_uri = get_bb_var('SRC_URI', testrecipe)
416 self.assertIn('git://', src_uri, 'This test expects the %s recipe to be a git recipe' % testrecipe)
417 # Clean up anything in the workdir/sysroot/sstate cache
418 bitbake('%s -c cleansstate' % testrecipe)
419 # Try modifying a recipe
420 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
421 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500422 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500423 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
424 self.add_command_to_tearDown('bitbake -c clean %s' % testrecipe)
425 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
426 self.assertTrue(os.path.exists(os.path.join(tempdir, 'Makefile')), 'Extracted source could not be found')
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500427 self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created. devtool output: %s' % result.output)
428 matches = glob.glob(os.path.join(self.workspacedir, 'appends', 'mkelfimage_*.bbappend'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500429 self.assertTrue(matches, 'bbappend not created')
430 # Test devtool status
431 result = runCmd('devtool status')
432 self.assertIn(testrecipe, result.output)
433 self.assertIn(tempdir, result.output)
434 # Check git repo
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500435 self._check_src_repo(tempdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500436 # Try building
437 bitbake(testrecipe)
438
439 @testcase(1167)
440 def test_devtool_modify_localfiles(self):
441 # Check preconditions
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500442 testrecipe = 'lighttpd'
443 src_uri = (get_bb_var('SRC_URI', testrecipe) or '').split()
444 foundlocal = False
445 for item in src_uri:
446 if item.startswith('file://') and '.patch' not in item:
447 foundlocal = True
448 break
449 self.assertTrue(foundlocal, 'This test expects the %s recipe to fetch local files and it seems that it no longer does' % testrecipe)
450 # Clean up anything in the workdir/sysroot/sstate cache
451 bitbake('%s -c cleansstate' % testrecipe)
452 # Try modifying a recipe
453 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
454 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500455 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500456 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
457 self.add_command_to_tearDown('bitbake -c clean %s' % testrecipe)
458 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
459 self.assertTrue(os.path.exists(os.path.join(tempdir, 'configure.ac')), 'Extracted source could not be found')
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500460 self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created')
461 matches = glob.glob(os.path.join(self.workspacedir, 'appends', '%s_*.bbappend' % testrecipe))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500462 self.assertTrue(matches, 'bbappend not created')
463 # Test devtool status
464 result = runCmd('devtool status')
465 self.assertIn(testrecipe, result.output)
466 self.assertIn(tempdir, result.output)
467 # Try building
468 bitbake(testrecipe)
469
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500470 @testcase(1378)
471 def test_devtool_modify_virtual(self):
472 # Try modifying a virtual recipe
473 virtrecipe = 'virtual/libx11'
474 realrecipe = 'libx11'
475 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
476 self.track_for_cleanup(tempdir)
477 self.track_for_cleanup(self.workspacedir)
478 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
479 result = runCmd('devtool modify %s -x %s' % (virtrecipe, tempdir))
480 self.assertTrue(os.path.exists(os.path.join(tempdir, 'Makefile.am')), 'Extracted source could not be found')
481 self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created')
482 matches = glob.glob(os.path.join(self.workspacedir, 'appends', '%s_*.bbappend' % realrecipe))
483 self.assertTrue(matches, 'bbappend not created %s' % result.output)
484 # Test devtool status
485 result = runCmd('devtool status')
486 self.assertNotIn(virtrecipe, result.output)
487 self.assertIn(realrecipe, result.output)
488 # Check git repo
489 self._check_src_repo(tempdir)
490 # This is probably sufficient
491
492
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500493 @testcase(1169)
494 def test_devtool_update_recipe(self):
495 # Check preconditions
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500496 testrecipe = 'minicom'
497 recipefile = get_bb_var('FILE', testrecipe)
498 src_uri = get_bb_var('SRC_URI', testrecipe)
499 self.assertNotIn('git://', src_uri, 'This test expects the %s recipe to NOT be a git recipe' % testrecipe)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500500 self._check_repo_status(os.path.dirname(recipefile), [])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500501 # First, modify a recipe
502 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
503 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500504 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500505 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
506 # (don't bother with cleaning the recipe on teardown, we won't be building it)
507 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
508 # Check git repo
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500509 self._check_src_repo(tempdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500510 # Add a couple of commits
511 # FIXME: this only tests adding, need to also test update and remove
512 result = runCmd('echo "Additional line" >> README', cwd=tempdir)
513 result = runCmd('git commit -a -m "Change the README"', cwd=tempdir)
514 result = runCmd('echo "A new file" > devtool-new-file', cwd=tempdir)
515 result = runCmd('git add devtool-new-file', cwd=tempdir)
516 result = runCmd('git commit -m "Add a new file"', cwd=tempdir)
517 self.add_command_to_tearDown('cd %s; rm %s/*.patch; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, testrecipe, os.path.basename(recipefile)))
518 result = runCmd('devtool update-recipe %s' % testrecipe)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500519 expected_status = [(' M', '.*/%s$' % os.path.basename(recipefile)),
520 ('??', '.*/0001-Change-the-README.patch$'),
521 ('??', '.*/0002-Add-a-new-file.patch$')]
522 self._check_repo_status(os.path.dirname(recipefile), expected_status)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500523
524 @testcase(1172)
525 def test_devtool_update_recipe_git(self):
526 # Check preconditions
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500527 testrecipe = 'mtd-utils'
528 recipefile = get_bb_var('FILE', testrecipe)
529 src_uri = get_bb_var('SRC_URI', testrecipe)
530 self.assertIn('git://', src_uri, 'This test expects the %s recipe to be a git recipe' % testrecipe)
531 patches = []
532 for entry in src_uri.split():
533 if entry.startswith('file://') and entry.endswith('.patch'):
534 patches.append(entry[7:].split(';')[0])
535 self.assertGreater(len(patches), 0, 'The %s recipe does not appear to contain any patches, so this test will not be effective' % testrecipe)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500536 self._check_repo_status(os.path.dirname(recipefile), [])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500537 # First, modify a recipe
538 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
539 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500540 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500541 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
542 # (don't bother with cleaning the recipe on teardown, we won't be building it)
543 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
544 # Check git repo
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500545 self._check_src_repo(tempdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500546 # Add a couple of commits
547 # FIXME: this only tests adding, need to also test update and remove
548 result = runCmd('echo "# Additional line" >> Makefile', cwd=tempdir)
549 result = runCmd('git commit -a -m "Change the Makefile"', cwd=tempdir)
550 result = runCmd('echo "A new file" > devtool-new-file', cwd=tempdir)
551 result = runCmd('git add devtool-new-file', cwd=tempdir)
552 result = runCmd('git commit -m "Add a new file"', cwd=tempdir)
553 self.add_command_to_tearDown('cd %s; rm -rf %s; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, testrecipe, os.path.basename(recipefile)))
554 result = runCmd('devtool update-recipe -m srcrev %s' % testrecipe)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500555 expected_status = [(' M', '.*/%s$' % os.path.basename(recipefile))] + \
556 [(' D', '.*/%s$' % patch) for patch in patches]
557 self._check_repo_status(os.path.dirname(recipefile), expected_status)
558
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500559 result = runCmd('git diff %s' % os.path.basename(recipefile), cwd=os.path.dirname(recipefile))
560 addlines = ['SRCREV = ".*"', 'SRC_URI = "git://git.infradead.org/mtd-utils.git"']
561 srcurilines = src_uri.split()
562 srcurilines[0] = 'SRC_URI = "' + srcurilines[0]
563 srcurilines.append('"')
564 removelines = ['SRCREV = ".*"'] + srcurilines
565 for line in result.output.splitlines():
566 if line.startswith('+++') or line.startswith('---'):
567 continue
568 elif line.startswith('+'):
569 matched = False
570 for item in addlines:
571 if re.match(item, line[1:].strip()):
572 matched = True
573 break
574 self.assertTrue(matched, 'Unexpected diff add line: %s' % line)
575 elif line.startswith('-'):
576 matched = False
577 for item in removelines:
578 if re.match(item, line[1:].strip()):
579 matched = True
580 break
581 self.assertTrue(matched, 'Unexpected diff remove line: %s' % line)
582 # Now try with auto mode
583 runCmd('cd %s; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, os.path.basename(recipefile)))
584 result = runCmd('devtool update-recipe %s' % testrecipe)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500585 result = runCmd('git rev-parse --show-toplevel', cwd=os.path.dirname(recipefile))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500586 topleveldir = result.output.strip()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500587 relpatchpath = os.path.join(os.path.relpath(os.path.dirname(recipefile), topleveldir), testrecipe)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500588 expected_status = [(' M', os.path.relpath(recipefile, topleveldir)),
589 ('??', '%s/0001-Change-the-Makefile.patch' % relpatchpath),
590 ('??', '%s/0002-Add-a-new-file.patch' % relpatchpath)]
591 self._check_repo_status(os.path.dirname(recipefile), expected_status)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500592
593 @testcase(1170)
594 def test_devtool_update_recipe_append(self):
595 # Check preconditions
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500596 testrecipe = 'mdadm'
597 recipefile = get_bb_var('FILE', testrecipe)
598 src_uri = get_bb_var('SRC_URI', testrecipe)
599 self.assertNotIn('git://', src_uri, 'This test expects the %s recipe to NOT be a git recipe' % testrecipe)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500600 self._check_repo_status(os.path.dirname(recipefile), [])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500601 # First, modify a recipe
602 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
603 tempsrcdir = os.path.join(tempdir, 'source')
604 templayerdir = os.path.join(tempdir, 'layer')
605 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500606 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500607 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
608 # (don't bother with cleaning the recipe on teardown, we won't be building it)
609 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempsrcdir))
610 # Check git repo
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500611 self._check_src_repo(tempsrcdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500612 # Add a commit
613 result = runCmd("sed 's!\\(#define VERSION\\W*\"[^\"]*\\)\"!\\1-custom\"!' -i ReadMe.c", cwd=tempsrcdir)
614 result = runCmd('git commit -a -m "Add our custom version"', cwd=tempsrcdir)
615 self.add_command_to_tearDown('cd %s; rm -f %s/*.patch; git checkout .' % (os.path.dirname(recipefile), testrecipe))
616 # Create a temporary layer and add it to bblayers.conf
617 self._create_temp_layer(templayerdir, True, 'selftestupdaterecipe')
618 # Create the bbappend
619 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
620 self.assertNotIn('WARNING:', result.output)
621 # Check recipe is still clean
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500622 self._check_repo_status(os.path.dirname(recipefile), [])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500623 # Check bbappend was created
624 splitpath = os.path.dirname(recipefile).split(os.sep)
625 appenddir = os.path.join(templayerdir, splitpath[-2], splitpath[-1])
626 bbappendfile = self._check_bbappend(testrecipe, recipefile, appenddir)
627 patchfile = os.path.join(appenddir, testrecipe, '0001-Add-our-custom-version.patch')
628 self.assertTrue(os.path.exists(patchfile), 'Patch file not created')
629
630 # Check bbappend contents
631 expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
632 '\n',
633 'SRC_URI += "file://0001-Add-our-custom-version.patch"\n',
634 '\n']
635 with open(bbappendfile, 'r') as f:
636 self.assertEqual(expectedlines, f.readlines())
637
638 # Check we can run it again and bbappend isn't modified
639 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
640 with open(bbappendfile, 'r') as f:
641 self.assertEqual(expectedlines, f.readlines())
642 # Drop new commit and check patch gets deleted
643 result = runCmd('git reset HEAD^', cwd=tempsrcdir)
644 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
645 self.assertFalse(os.path.exists(patchfile), 'Patch file not deleted')
646 expectedlines2 = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
647 '\n']
648 with open(bbappendfile, 'r') as f:
649 self.assertEqual(expectedlines2, f.readlines())
650 # Put commit back and check we can run it if layer isn't in bblayers.conf
651 os.remove(bbappendfile)
652 result = runCmd('git commit -a -m "Add our custom version"', cwd=tempsrcdir)
653 result = runCmd('bitbake-layers remove-layer %s' % templayerdir, cwd=self.builddir)
654 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
655 self.assertIn('WARNING: Specified layer is not currently enabled in bblayers.conf', result.output)
656 self.assertTrue(os.path.exists(patchfile), 'Patch file not created (with disabled layer)')
657 with open(bbappendfile, 'r') as f:
658 self.assertEqual(expectedlines, f.readlines())
659 # Deleting isn't expected to work under these circumstances
660
661 @testcase(1171)
662 def test_devtool_update_recipe_append_git(self):
663 # Check preconditions
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500664 testrecipe = 'mtd-utils'
665 recipefile = get_bb_var('FILE', testrecipe)
666 src_uri = get_bb_var('SRC_URI', testrecipe)
667 self.assertIn('git://', src_uri, 'This test expects the %s recipe to be a git recipe' % testrecipe)
668 for entry in src_uri.split():
669 if entry.startswith('git://'):
670 git_uri = entry
671 break
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500672 self._check_repo_status(os.path.dirname(recipefile), [])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500673 # First, modify a recipe
674 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
675 tempsrcdir = os.path.join(tempdir, 'source')
676 templayerdir = os.path.join(tempdir, 'layer')
677 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500678 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500679 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
680 # (don't bother with cleaning the recipe on teardown, we won't be building it)
681 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempsrcdir))
682 # Check git repo
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500683 self._check_src_repo(tempsrcdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500684 # Add a commit
685 result = runCmd('echo "# Additional line" >> Makefile', cwd=tempsrcdir)
686 result = runCmd('git commit -a -m "Change the Makefile"', cwd=tempsrcdir)
687 self.add_command_to_tearDown('cd %s; rm -f %s/*.patch; git checkout .' % (os.path.dirname(recipefile), testrecipe))
688 # Create a temporary layer
689 os.makedirs(os.path.join(templayerdir, 'conf'))
690 with open(os.path.join(templayerdir, 'conf', 'layer.conf'), 'w') as f:
691 f.write('BBPATH .= ":${LAYERDIR}"\n')
692 f.write('BBFILES += "${LAYERDIR}/recipes-*/*/*.bbappend"\n')
693 f.write('BBFILE_COLLECTIONS += "oeselftesttemplayer"\n')
694 f.write('BBFILE_PATTERN_oeselftesttemplayer = "^${LAYERDIR}/"\n')
695 f.write('BBFILE_PRIORITY_oeselftesttemplayer = "999"\n')
696 f.write('BBFILE_PATTERN_IGNORE_EMPTY_oeselftesttemplayer = "1"\n')
697 self.add_command_to_tearDown('bitbake-layers remove-layer %s || true' % templayerdir)
698 result = runCmd('bitbake-layers add-layer %s' % templayerdir, cwd=self.builddir)
699 # Create the bbappend
700 result = runCmd('devtool update-recipe -m srcrev %s -a %s' % (testrecipe, templayerdir))
701 self.assertNotIn('WARNING:', result.output)
702 # Check recipe is still clean
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500703 self._check_repo_status(os.path.dirname(recipefile), [])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500704 # Check bbappend was created
705 splitpath = os.path.dirname(recipefile).split(os.sep)
706 appenddir = os.path.join(templayerdir, splitpath[-2], splitpath[-1])
707 bbappendfile = self._check_bbappend(testrecipe, recipefile, appenddir)
708 self.assertFalse(os.path.exists(os.path.join(appenddir, testrecipe)), 'Patch directory should not be created')
709
710 # Check bbappend contents
711 result = runCmd('git rev-parse HEAD', cwd=tempsrcdir)
712 expectedlines = ['SRCREV = "%s"\n' % result.output,
713 '\n',
714 'SRC_URI = "%s"\n' % git_uri,
715 '\n']
716 with open(bbappendfile, 'r') as f:
717 self.assertEqual(expectedlines, f.readlines())
718
719 # Check we can run it again and bbappend isn't modified
720 result = runCmd('devtool update-recipe -m srcrev %s -a %s' % (testrecipe, templayerdir))
721 with open(bbappendfile, 'r') as f:
722 self.assertEqual(expectedlines, f.readlines())
723 # Drop new commit and check SRCREV changes
724 result = runCmd('git reset HEAD^', cwd=tempsrcdir)
725 result = runCmd('devtool update-recipe -m srcrev %s -a %s' % (testrecipe, templayerdir))
726 self.assertFalse(os.path.exists(os.path.join(appenddir, testrecipe)), 'Patch directory should not be created')
727 result = runCmd('git rev-parse HEAD', cwd=tempsrcdir)
728 expectedlines = ['SRCREV = "%s"\n' % result.output,
729 '\n',
730 'SRC_URI = "%s"\n' % git_uri,
731 '\n']
732 with open(bbappendfile, 'r') as f:
733 self.assertEqual(expectedlines, f.readlines())
734 # Put commit back and check we can run it if layer isn't in bblayers.conf
735 os.remove(bbappendfile)
736 result = runCmd('git commit -a -m "Change the Makefile"', cwd=tempsrcdir)
737 result = runCmd('bitbake-layers remove-layer %s' % templayerdir, cwd=self.builddir)
738 result = runCmd('devtool update-recipe -m srcrev %s -a %s' % (testrecipe, templayerdir))
739 self.assertIn('WARNING: Specified layer is not currently enabled in bblayers.conf', result.output)
740 self.assertFalse(os.path.exists(os.path.join(appenddir, testrecipe)), 'Patch directory should not be created')
741 result = runCmd('git rev-parse HEAD', cwd=tempsrcdir)
742 expectedlines = ['SRCREV = "%s"\n' % result.output,
743 '\n',
744 'SRC_URI = "%s"\n' % git_uri,
745 '\n']
746 with open(bbappendfile, 'r') as f:
747 self.assertEqual(expectedlines, f.readlines())
748 # Deleting isn't expected to work under these circumstances
749
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500750 @testcase(1370)
751 def test_devtool_update_recipe_local_files(self):
752 """Check that local source files are copied over instead of patched"""
753 testrecipe = 'makedevs'
754 recipefile = get_bb_var('FILE', testrecipe)
755 # Setup srctree for modifying the recipe
756 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
757 self.track_for_cleanup(tempdir)
758 self.track_for_cleanup(self.workspacedir)
759 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
760 # (don't bother with cleaning the recipe on teardown, we won't be
761 # building it)
762 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
763 # Check git repo
764 self._check_src_repo(tempdir)
765 # Edit / commit local source
766 runCmd('echo "/* Foobar */" >> oe-local-files/makedevs.c', cwd=tempdir)
767 runCmd('echo "Foo" > oe-local-files/new-local', cwd=tempdir)
768 runCmd('echo "Bar" > new-file', cwd=tempdir)
769 runCmd('git add new-file', cwd=tempdir)
770 runCmd('git commit -m "Add new file"', cwd=tempdir)
771 self.add_command_to_tearDown('cd %s; git clean -fd .; git checkout .' %
772 os.path.dirname(recipefile))
773 runCmd('devtool update-recipe %s' % testrecipe)
774 expected_status = [(' M', '.*/%s$' % os.path.basename(recipefile)),
775 (' M', '.*/makedevs/makedevs.c$'),
776 ('??', '.*/makedevs/new-local$'),
777 ('??', '.*/makedevs/0001-Add-new-file.patch$')]
778 self._check_repo_status(os.path.dirname(recipefile), expected_status)
779
780 @testcase(1371)
781 def test_devtool_update_recipe_local_files_2(self):
782 """Check local source files support when oe-local-files is in Git"""
783 testrecipe = 'lzo'
784 recipefile = get_bb_var('FILE', testrecipe)
785 # Setup srctree for modifying the recipe
786 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
787 self.track_for_cleanup(tempdir)
788 self.track_for_cleanup(self.workspacedir)
789 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
790 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
791 # Check git repo
792 self._check_src_repo(tempdir)
793 # Add oe-local-files to Git
794 runCmd('rm oe-local-files/.gitignore', cwd=tempdir)
795 runCmd('git add oe-local-files', cwd=tempdir)
796 runCmd('git commit -m "Add local sources"', cwd=tempdir)
797 # Edit / commit local sources
798 runCmd('echo "# Foobar" >> oe-local-files/acinclude.m4', cwd=tempdir)
799 runCmd('git commit -am "Edit existing file"', cwd=tempdir)
800 runCmd('git rm oe-local-files/run-ptest', cwd=tempdir)
801 runCmd('git commit -m"Remove file"', cwd=tempdir)
802 runCmd('echo "Foo" > oe-local-files/new-local', cwd=tempdir)
803 runCmd('git add oe-local-files/new-local', cwd=tempdir)
804 runCmd('git commit -m "Add new local file"', cwd=tempdir)
805 runCmd('echo "Gar" > new-file', cwd=tempdir)
806 runCmd('git add new-file', cwd=tempdir)
807 runCmd('git commit -m "Add new file"', cwd=tempdir)
808 self.add_command_to_tearDown('cd %s; git clean -fd .; git checkout .' %
809 os.path.dirname(recipefile))
810 # Checkout unmodified file to working copy -> devtool should still pick
811 # the modified version from HEAD
812 runCmd('git checkout HEAD^ -- oe-local-files/acinclude.m4', cwd=tempdir)
813 runCmd('devtool update-recipe %s' % testrecipe)
814 expected_status = [(' M', '.*/%s$' % os.path.basename(recipefile)),
815 (' M', '.*/acinclude.m4$'),
816 (' D', '.*/run-ptest$'),
817 ('??', '.*/new-local$'),
818 ('??', '.*/0001-Add-new-file.patch$')]
819 self._check_repo_status(os.path.dirname(recipefile), expected_status)
820
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500821 @testcase(1163)
822 def test_devtool_extract(self):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500823 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
824 # Try devtool extract
825 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500826 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500827 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
828 result = runCmd('devtool extract remake %s' % tempdir)
829 self.assertTrue(os.path.exists(os.path.join(tempdir, 'Makefile.am')), 'Extracted source could not be found')
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500830 self._check_src_repo(tempdir)
831
832 @testcase(1379)
833 def test_devtool_extract_virtual(self):
834 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
835 # Try devtool extract
836 self.track_for_cleanup(tempdir)
837 self.track_for_cleanup(self.workspacedir)
838 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
839 result = runCmd('devtool extract virtual/libx11 %s' % tempdir)
840 self.assertTrue(os.path.exists(os.path.join(tempdir, 'Makefile.am')), 'Extracted source could not be found')
841 self._check_src_repo(tempdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500842
843 @testcase(1168)
844 def test_devtool_reset_all(self):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500845 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
846 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500847 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500848 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
849 testrecipe1 = 'mdadm'
850 testrecipe2 = 'cronie'
851 result = runCmd('devtool modify -x %s %s' % (testrecipe1, os.path.join(tempdir, testrecipe1)))
852 result = runCmd('devtool modify -x %s %s' % (testrecipe2, os.path.join(tempdir, testrecipe2)))
853 result = runCmd('devtool build %s' % testrecipe1)
854 result = runCmd('devtool build %s' % testrecipe2)
855 stampprefix1 = get_bb_var('STAMP', testrecipe1)
856 self.assertTrue(stampprefix1, 'Unable to get STAMP value for recipe %s' % testrecipe1)
857 stampprefix2 = get_bb_var('STAMP', testrecipe2)
858 self.assertTrue(stampprefix2, 'Unable to get STAMP value for recipe %s' % testrecipe2)
859 result = runCmd('devtool reset -a')
860 self.assertIn(testrecipe1, result.output)
861 self.assertIn(testrecipe2, result.output)
862 result = runCmd('devtool status')
863 self.assertNotIn(testrecipe1, result.output)
864 self.assertNotIn(testrecipe2, result.output)
865 matches1 = glob.glob(stampprefix1 + '*')
866 self.assertFalse(matches1, 'Stamp files exist for recipe %s that should have been cleaned' % testrecipe1)
867 matches2 = glob.glob(stampprefix2 + '*')
868 self.assertFalse(matches2, 'Stamp files exist for recipe %s that should have been cleaned' % testrecipe2)
869
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500870 @testcase(1272)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500871 def test_devtool_deploy_target(self):
872 # NOTE: Whilst this test would seemingly be better placed as a runtime test,
873 # unfortunately the runtime tests run under bitbake and you can't run
874 # devtool within bitbake (since devtool needs to run bitbake itself).
875 # Additionally we are testing build-time functionality as well, so
876 # really this has to be done as an oe-selftest test.
877 #
878 # Check preconditions
879 machine = get_bb_var('MACHINE')
880 if not machine.startswith('qemu'):
881 self.skipTest('This test only works with qemu machines')
882 if not os.path.exists('/etc/runqemu-nosudo'):
883 self.skipTest('You must set up tap devices with scripts/runqemu-gen-tapdevs before running this test')
884 result = runCmd('PATH="$PATH:/sbin:/usr/sbin" ip tuntap show', ignore_status=True)
885 if result.status != 0:
886 result = runCmd('PATH="$PATH:/sbin:/usr/sbin" ifconfig -a', ignore_status=True)
887 if result.status != 0:
888 self.skipTest('Failed to determine if tap devices exist with ifconfig or ip: %s' % result.output)
889 for line in result.output.splitlines():
890 if line.startswith('tap'):
891 break
892 else:
893 self.skipTest('No tap devices found - you must set up tap devices with scripts/runqemu-gen-tapdevs before running this test')
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500894 self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500895 # Definitions
896 testrecipe = 'mdadm'
897 testfile = '/sbin/mdadm'
898 testimage = 'oe-selftest-image'
899 testcommand = '/sbin/mdadm --help'
900 # Build an image to run
901 bitbake("%s qemu-native qemu-helper-native" % testimage)
902 deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
903 self.add_command_to_tearDown('bitbake -c clean %s' % testimage)
904 self.add_command_to_tearDown('rm -f %s/%s*' % (deploy_dir_image, testimage))
905 # Clean recipe so the first deploy will fail
906 bitbake("%s -c clean" % testrecipe)
907 # Try devtool modify
908 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
909 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500910 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500911 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
912 self.add_command_to_tearDown('bitbake -c clean %s' % testrecipe)
913 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
914 # Test that deploy-target at this point fails (properly)
915 result = runCmd('devtool deploy-target -n %s root@localhost' % testrecipe, ignore_status=True)
916 self.assertNotEqual(result.output, 0, 'devtool deploy-target should have failed, output: %s' % result.output)
917 self.assertNotIn(result.output, 'Traceback', 'devtool deploy-target should have failed with a proper error not a traceback, output: %s' % result.output)
918 result = runCmd('devtool build %s' % testrecipe)
919 # First try a dry-run of deploy-target
920 result = runCmd('devtool deploy-target -n %s root@localhost' % testrecipe)
921 self.assertIn(' %s' % testfile, result.output)
922 # Boot the image
923 with runqemu(testimage, self) as qemu:
924 # Now really test deploy-target
925 result = runCmd('devtool deploy-target -c %s root@%s' % (testrecipe, qemu.ip))
926 # Run a test command to see if it was installed properly
927 sshargs = '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'
928 result = runCmd('ssh %s root@%s %s' % (sshargs, qemu.ip, testcommand))
929 # Check if it deployed all of the files with the right ownership/perms
930 # First look on the host - need to do this under pseudo to get the correct ownership/perms
931 installdir = get_bb_var('D', testrecipe)
932 fakerootenv = get_bb_var('FAKEROOTENV', testrecipe)
933 fakerootcmd = get_bb_var('FAKEROOTCMD', testrecipe)
934 result = runCmd('%s %s find . -type f -exec ls -l {} \;' % (fakerootenv, fakerootcmd), cwd=installdir)
935 filelist1 = self._process_ls_output(result.output)
936
937 # Now look on the target
938 tempdir2 = tempfile.mkdtemp(prefix='devtoolqa')
939 self.track_for_cleanup(tempdir2)
940 tmpfilelist = os.path.join(tempdir2, 'files.txt')
941 with open(tmpfilelist, 'w') as f:
942 for line in filelist1:
943 splitline = line.split()
944 f.write(splitline[-1] + '\n')
945 result = runCmd('cat %s | ssh -q %s root@%s \'xargs ls -l\'' % (tmpfilelist, sshargs, qemu.ip))
946 filelist2 = self._process_ls_output(result.output)
947 filelist1.sort(key=lambda item: item.split()[-1])
948 filelist2.sort(key=lambda item: item.split()[-1])
949 self.assertEqual(filelist1, filelist2)
950 # Test undeploy-target
951 result = runCmd('devtool undeploy-target -c %s root@%s' % (testrecipe, qemu.ip))
952 result = runCmd('ssh %s root@%s %s' % (sshargs, qemu.ip, testcommand), ignore_status=True)
953 self.assertNotEqual(result, 0, 'undeploy-target did not remove command as it should have')
954
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500955 @testcase(1366)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500956 def test_devtool_build_image(self):
957 """Test devtool build-image plugin"""
958 # Check preconditions
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500959 self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500960 image = 'core-image-minimal'
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500961 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500962 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
963 self.add_command_to_tearDown('bitbake -c clean %s' % image)
964 bitbake('%s -c clean' % image)
965 # Add target and native recipes to workspace
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500966 recipes = ['mdadm', 'parted-native']
967 for recipe in recipes:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500968 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
969 self.track_for_cleanup(tempdir)
970 self.add_command_to_tearDown('bitbake -c clean %s' % recipe)
971 runCmd('devtool modify %s -x %s' % (recipe, tempdir))
972 # Try to build image
973 result = runCmd('devtool build-image %s' % image)
974 self.assertNotEqual(result, 0, 'devtool build-image failed')
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500975 # Check if image contains expected packages
976 deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
977 image_link_name = get_bb_var('IMAGE_LINK_NAME', image)
978 reqpkgs = [item for item in recipes if not item.endswith('-native')]
979 with open(os.path.join(deploy_dir_image, image_link_name + '.manifest'), 'r') as f:
980 for line in f:
981 splitval = line.split()
982 if splitval:
983 pkg = splitval[0]
984 if pkg in reqpkgs:
985 reqpkgs.remove(pkg)
986 if reqpkgs:
987 self.fail('The following packages were not present in the image as expected: %s' % ', '.join(reqpkgs))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500988
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500989 @testcase(1367)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500990 def test_devtool_upgrade(self):
991 # Check preconditions
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500992 self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500993 # Check parameters
994 result = runCmd('devtool upgrade -h')
995 for param in 'recipename srctree --version -V --branch -b --keep-temp --no-patch'.split():
996 self.assertIn(param, result.output)
997 # For the moment, we are using a real recipe.
998 recipe='devtool-upgrade'
999 version='0.2'
1000 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1001 # Check that recipe is not already under devtool control
1002 result = runCmd('devtool status')
1003 self.assertNotIn(recipe, result.output)
1004 # Check upgrade. Code does not check if new PV is older or newer that current PV, so, it may be that
1005 # we are downgrading instead of upgrading.
1006 result = runCmd('devtool upgrade %s %s -V %s' % (recipe, tempdir, version))
1007 # Check if srctree at least is populated
1008 self.assertTrue(len(os.listdir(tempdir)) > 0, 'scrtree (%s) should be populated with new (%s) source code' % (tempdir, version))
1009 # Check new recipe folder is present
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001010 self.assertTrue(os.path.exists(os.path.join(self.workspacedir,'recipes',recipe)), 'Recipe folder should exist')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001011 # Check new recipe file is present
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001012 self.assertTrue(os.path.exists(os.path.join(self.workspacedir,'recipes',recipe,"%s_%s.bb" % (recipe,version))), 'Recipe folder should exist')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001013 # Check devtool status and make sure recipe is present
1014 result = runCmd('devtool status')
1015 self.assertIn(recipe, result.output)
1016 self.assertIn(tempdir, result.output)
1017 # Check devtool reset recipe
1018 result = runCmd('devtool reset %s -n' % recipe)
1019 result = runCmd('devtool status')
1020 self.assertNotIn(recipe, result.output)
1021 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001022 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001023 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001024
1025 @testcase(1352)
1026 def test_devtool_layer_plugins(self):
1027 """Test that devtool can use plugins from other layers.
1028
1029 This test executes the selftest-reverse command from meta-selftest."""
1030
1031 self.track_for_cleanup(self.workspacedir)
1032 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1033
1034 s = "Microsoft Made No Profit From Anyone's Zunes Yo"
1035 result = runCmd("devtool --quiet selftest-reverse \"%s\"" % s)
1036 self.assertEqual(result.output, s[::-1])