blob: 132a73d0ec7ef54efb64b1f94700b69b82eab5b7 [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:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050018 invar = None
19 invalue = None
Patrick Williamsc124f4f2015-09-15 14:41:29 -050020 for line in f:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050021 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:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050033 splitline = line.split('=', 1)
34 var = splitline[0].rstrip()
35 value = splitline[1].strip().strip('"')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050036 if value.endswith('\\'):
37 invalue = value[:-1].strip()
38 invar = var
39 continue
40 elif line.startswith('inherit '):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050041 inherits = line.split()[1:]
42
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050043 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')
47 if isinstance(needvalue, set):
48 value = set(value.split())
49 self.assertEqual(value, needvalue, 'values for %s do not match' % var)
50
51
52 missingvars = {}
53 for var, value in checkvars.iteritems():
54 if value is not None:
55 missingvars[var] = value
56 self.assertEqual(missingvars, {}, 'Some expected variables not found in recipe: %s' % checkvars)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050057
58 for inherit in checkinherits:
59 self.assertIn(inherit, inherits, 'Missing inherit of %s' % inherit)
60
61 def _check_bbappend(self, testrecipe, recipefile, appenddir):
62 result = runCmd('bitbake-layers show-appends', cwd=self.builddir)
63 resultlines = result.output.splitlines()
64 inrecipe = False
65 bbappends = []
66 bbappendfile = None
67 for line in resultlines:
68 if inrecipe:
69 if line.startswith(' '):
70 bbappends.append(line.strip())
71 else:
72 break
73 elif line == '%s:' % os.path.basename(recipefile):
74 inrecipe = True
75 self.assertLessEqual(len(bbappends), 2, '%s recipe is being bbappended by another layer - bbappends found:\n %s' % (testrecipe, '\n '.join(bbappends)))
76 for bbappend in bbappends:
77 if bbappend.startswith(appenddir):
78 bbappendfile = bbappend
79 break
80 else:
81 self.fail('bbappend for recipe %s does not seem to be created in test layer' % testrecipe)
82 return bbappendfile
83
84 def _create_temp_layer(self, templayerdir, addlayer, templayername, priority=999, recipepathspec='recipes-*/*'):
85 create_temp_layer(templayerdir, templayername, priority, recipepathspec)
86 if addlayer:
87 self.add_command_to_tearDown('bitbake-layers remove-layer %s || true' % templayerdir)
88 result = runCmd('bitbake-layers add-layer %s' % templayerdir, cwd=self.builddir)
89
90 def _process_ls_output(self, output):
91 """
92 Convert ls -l output to a format we can reasonably compare from one context
93 to another (e.g. from host to target)
94 """
95 filelist = []
96 for line in output.splitlines():
97 splitline = line.split()
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050098 if len(splitline) < 8:
99 self.fail('_process_ls_output: invalid output line: %s' % line)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500100 # Remove trailing . on perms
101 splitline[0] = splitline[0].rstrip('.')
102 # Remove leading . on paths
103 splitline[-1] = splitline[-1].lstrip('.')
104 # Drop fields we don't want to compare
105 del splitline[7]
106 del splitline[6]
107 del splitline[5]
108 del splitline[4]
109 del splitline[1]
110 filelist.append(' '.join(splitline))
111 return filelist
112
113
114class DevtoolTests(DevtoolBase):
115
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500116 def setUp(self):
117 """Test case setup function"""
118 super(DevtoolTests, self).setUp()
119 self.workspacedir = os.path.join(self.builddir, 'workspace')
120 self.assertTrue(not os.path.exists(self.workspacedir),
121 'This test cannot be run with a workspace directory '
122 'under the build directory')
123
124 def _check_src_repo(self, repo_dir):
125 """Check srctree git repository"""
126 self.assertTrue(os.path.isdir(os.path.join(repo_dir, '.git')),
127 'git repository for external source tree not found')
128 result = runCmd('git status --porcelain', cwd=repo_dir)
129 self.assertEqual(result.output.strip(), "",
130 'Created git repo is not clean')
131 result = runCmd('git symbolic-ref HEAD', cwd=repo_dir)
132 self.assertEqual(result.output.strip(), "refs/heads/devtool",
133 'Wrong branch in git repo')
134
135 def _check_repo_status(self, repo_dir, expected_status):
136 """Check the worktree status of a repository"""
137 result = runCmd('git status . --porcelain',
138 cwd=repo_dir)
139 for line in result.output.splitlines():
140 for ind, (f_status, fn_re) in enumerate(expected_status):
141 if re.match(fn_re, line[3:]):
142 if f_status != line[:2]:
143 self.fail('Unexpected status in line: %s' % line)
144 expected_status.pop(ind)
145 break
146 else:
147 self.fail('Unexpected modified file in line: %s' % line)
148 if expected_status:
149 self.fail('Missing file changes: %s' % expected_status)
150
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500151 @testcase(1158)
152 def test_create_workspace(self):
153 # Check preconditions
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500154 result = runCmd('bitbake-layers show-layers')
155 self.assertTrue('/workspace' not in result.output, 'This test cannot be run with a workspace layer in bblayers.conf')
156 # Try creating a workspace layer with a specific path
157 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
158 self.track_for_cleanup(tempdir)
159 result = runCmd('devtool create-workspace %s' % tempdir)
160 self.assertTrue(os.path.isfile(os.path.join(tempdir, 'conf', 'layer.conf')), msg = "No workspace created. devtool output: %s " % result.output)
161 result = runCmd('bitbake-layers show-layers')
162 self.assertIn(tempdir, result.output)
163 # Try creating a workspace layer with the default path
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500164 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500165 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
166 result = runCmd('devtool create-workspace')
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500167 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 -0500168 result = runCmd('bitbake-layers show-layers')
169 self.assertNotIn(tempdir, result.output)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500170 self.assertIn(self.workspacedir, result.output)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500171
172 @testcase(1159)
173 def test_devtool_add(self):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500174 # Fetch source
175 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
176 self.track_for_cleanup(tempdir)
177 url = 'http://www.ivarch.com/programs/sources/pv-1.5.3.tar.bz2'
178 result = runCmd('wget %s' % url, cwd=tempdir)
179 result = runCmd('tar xfv pv-1.5.3.tar.bz2', cwd=tempdir)
180 srcdir = os.path.join(tempdir, 'pv-1.5.3')
181 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure')), 'Unable to find configure script in source directory')
182 # Test devtool add
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500183 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500184 self.add_command_to_tearDown('bitbake -c cleansstate pv')
185 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
186 result = runCmd('devtool add pv %s' % srcdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500187 self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500188 # Test devtool status
189 result = runCmd('devtool status')
190 self.assertIn('pv', result.output)
191 self.assertIn(srcdir, result.output)
192 # Clean up anything in the workdir/sysroot/sstate cache (have to do this *after* devtool add since the recipe only exists then)
193 bitbake('pv -c cleansstate')
194 # Test devtool build
195 result = runCmd('devtool build pv')
196 installdir = get_bb_var('D', 'pv')
197 self.assertTrue(installdir, 'Could not query installdir variable')
198 bindir = get_bb_var('bindir', 'pv')
199 self.assertTrue(bindir, 'Could not query bindir variable')
200 if bindir[0] == '/':
201 bindir = bindir[1:]
202 self.assertTrue(os.path.isfile(os.path.join(installdir, bindir, 'pv')), 'pv binary not found in D')
203
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500204 @testcase(1423)
205 def test_devtool_add_git_local(self):
206 # Fetch source from a remote URL, but do it outside of devtool
207 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
208 self.track_for_cleanup(tempdir)
209 pn = 'dbus-wait'
210 # We choose an https:// git URL here to check rewriting the URL works
211 url = 'https://git.yoctoproject.org/git/dbus-wait'
212 # Force fetching to "noname" subdir so we verify we're picking up the name from autoconf
213 # instead of the directory name
214 result = runCmd('git clone %s noname' % url, cwd=tempdir)
215 srcdir = os.path.join(tempdir, 'noname')
216 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure.ac')), 'Unable to find configure script in source directory')
217 # Test devtool add
218 self.track_for_cleanup(self.workspacedir)
219 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
220 # Don't specify a name since we should be able to auto-detect it
221 result = runCmd('devtool add %s' % srcdir)
222 self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created')
223 # Check the recipe name is correct
224 recipefile = get_bb_var('FILE', pn)
225 self.assertIn('%s_git.bb' % pn, recipefile, 'Recipe file incorrectly named')
226 self.assertIn(recipefile, result.output)
227 # Test devtool status
228 result = runCmd('devtool status')
229 self.assertIn(pn, result.output)
230 self.assertIn(srcdir, result.output)
231 self.assertIn(recipefile, result.output)
232 checkvars = {}
233 checkvars['LICENSE'] = 'GPLv2'
234 checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263'
235 checkvars['S'] = '${WORKDIR}/git'
236 checkvars['PV'] = '0.1+git${SRCPV}'
237 checkvars['SRC_URI'] = 'git://git.yoctoproject.org/git/dbus-wait;protocol=https'
238 checkvars['SRCREV'] = '${AUTOREV}'
239 checkvars['DEPENDS'] = set(['dbus'])
240 self._test_recipe_contents(recipefile, checkvars, [])
241
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500242 @testcase(1162)
243 def test_devtool_add_library(self):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500244 # We don't have the ability to pick up this dependency automatically yet...
245 bitbake('libusb1')
246 # Fetch source
247 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
248 self.track_for_cleanup(tempdir)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500249 version = '1.1'
250 url = 'https://www.intra2net.com/en/developer/libftdi/download/libftdi1-%s.tar.bz2' % version
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500251 result = runCmd('wget %s' % url, cwd=tempdir)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500252 result = runCmd('tar xfv libftdi1-%s.tar.bz2' % version, cwd=tempdir)
253 srcdir = os.path.join(tempdir, 'libftdi1-%s' % version)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500254 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'CMakeLists.txt')), 'Unable to find CMakeLists.txt in source directory')
255 # Test devtool add (and use -V so we test that too)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500256 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500257 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500258 result = runCmd('devtool add libftdi %s -V %s' % (srcdir, version))
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500259 self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500260 # Test devtool status
261 result = runCmd('devtool status')
262 self.assertIn('libftdi', result.output)
263 self.assertIn(srcdir, result.output)
264 # Clean up anything in the workdir/sysroot/sstate cache (have to do this *after* devtool add since the recipe only exists then)
265 bitbake('libftdi -c cleansstate')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500266 # libftdi's python/CMakeLists.txt is a bit broken, so let's just disable it
267 # There's also the matter of it installing cmake files to a path we don't
268 # normally cover, which triggers the installed-vs-shipped QA test we have
269 # within do_package
270 recipefile = '%s/recipes/libftdi/libftdi_%s.bb' % (self.workspacedir, version)
271 result = runCmd('recipetool setvar %s EXTRA_OECMAKE -- \'-DPYTHON_BINDINGS=OFF -DLIBFTDI_CMAKE_CONFIG_DIR=${datadir}/cmake/Modules\'' % recipefile)
272 with open(recipefile, 'a') as f:
273 f.write('\nFILES_${PN}-dev += "${datadir}/cmake/Modules"\n')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500274 # Test devtool build
275 result = runCmd('devtool build libftdi')
276 staging_libdir = get_bb_var('STAGING_LIBDIR', 'libftdi')
277 self.assertTrue(staging_libdir, 'Could not query STAGING_LIBDIR variable')
278 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)
279 # Test devtool reset
280 stampprefix = get_bb_var('STAMP', 'libftdi')
281 result = runCmd('devtool reset libftdi')
282 result = runCmd('devtool status')
283 self.assertNotIn('libftdi', result.output)
284 self.assertTrue(stampprefix, 'Unable to get STAMP value for recipe libftdi')
285 matches = glob.glob(stampprefix + '*')
286 self.assertFalse(matches, 'Stamp files exist for recipe libftdi that should have been cleaned')
287 self.assertFalse(os.path.isfile(os.path.join(staging_libdir, 'libftdi1.so.2.1.0')), 'libftdi binary still found in STAGING_LIBDIR after cleaning')
288
289 @testcase(1160)
290 def test_devtool_add_fetch(self):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500291 # Fetch source
292 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
293 self.track_for_cleanup(tempdir)
294 testver = '0.23'
295 url = 'https://pypi.python.org/packages/source/M/MarkupSafe/MarkupSafe-%s.tar.gz' % testver
296 testrecipe = 'python-markupsafe'
297 srcdir = os.path.join(tempdir, testrecipe)
298 # Test devtool add
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500299 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500300 self.add_command_to_tearDown('bitbake -c cleansstate %s' % testrecipe)
301 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
302 result = runCmd('devtool add %s %s -f %s' % (testrecipe, srcdir, url))
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500303 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 -0500304 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'setup.py')), 'Unable to find setup.py in source directory')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500305 self.assertTrue(os.path.isdir(os.path.join(srcdir, '.git')), 'git repository for external source tree was not created')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500306 # Test devtool status
307 result = runCmd('devtool status')
308 self.assertIn(testrecipe, result.output)
309 self.assertIn(srcdir, result.output)
310 # Check recipe
311 recipefile = get_bb_var('FILE', testrecipe)
312 self.assertIn('%s_%s.bb' % (testrecipe, testver), recipefile, 'Recipe file incorrectly named')
313 checkvars = {}
314 checkvars['S'] = '${WORKDIR}/MarkupSafe-${PV}'
315 checkvars['SRC_URI'] = url.replace(testver, '${PV}')
316 self._test_recipe_contents(recipefile, checkvars, [])
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500317 # Try with version specified
318 result = runCmd('devtool reset -n %s' % testrecipe)
319 shutil.rmtree(srcdir)
320 fakever = '1.9'
321 result = runCmd('devtool add %s %s -f %s -V %s' % (testrecipe, srcdir, url, fakever))
322 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'setup.py')), 'Unable to find setup.py in source directory')
323 # Test devtool status
324 result = runCmd('devtool status')
325 self.assertIn(testrecipe, result.output)
326 self.assertIn(srcdir, result.output)
327 # Check recipe
328 recipefile = get_bb_var('FILE', testrecipe)
329 self.assertIn('%s_%s.bb' % (testrecipe, fakever), recipefile, 'Recipe file incorrectly named')
330 checkvars = {}
331 checkvars['S'] = '${WORKDIR}/MarkupSafe-%s' % testver
332 checkvars['SRC_URI'] = url
333 self._test_recipe_contents(recipefile, checkvars, [])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500334
335 @testcase(1161)
336 def test_devtool_add_fetch_git(self):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500337 # Fetch source
338 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
339 self.track_for_cleanup(tempdir)
340 url = 'git://git.yoctoproject.org/libmatchbox'
341 checkrev = '462f0652055d89c648ddd54fd7b03f175c2c6973'
342 testrecipe = 'libmatchbox2'
343 srcdir = os.path.join(tempdir, testrecipe)
344 # Test devtool add
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500345 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500346 self.add_command_to_tearDown('bitbake -c cleansstate %s' % testrecipe)
347 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
348 result = runCmd('devtool add %s %s -f %s' % (testrecipe, srcdir, url))
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500349 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 -0500350 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure.ac')), 'Unable to find configure.ac in source directory')
351 # Test devtool status
352 result = runCmd('devtool status')
353 self.assertIn(testrecipe, result.output)
354 self.assertIn(srcdir, result.output)
355 # Check recipe
356 recipefile = get_bb_var('FILE', testrecipe)
357 self.assertIn('_git.bb', recipefile, 'Recipe file incorrectly named')
358 checkvars = {}
359 checkvars['S'] = '${WORKDIR}/git'
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500360 checkvars['PV'] = '1.11+git${SRCPV}'
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500361 checkvars['SRC_URI'] = url
362 checkvars['SRCREV'] = '${AUTOREV}'
363 self._test_recipe_contents(recipefile, checkvars, [])
364 # Try with revision and version specified
365 result = runCmd('devtool reset -n %s' % testrecipe)
366 shutil.rmtree(srcdir)
367 url_rev = '%s;rev=%s' % (url, checkrev)
368 result = runCmd('devtool add %s %s -f "%s" -V 1.5' % (testrecipe, srcdir, url_rev))
369 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure.ac')), 'Unable to find configure.ac in source directory')
370 # Test devtool status
371 result = runCmd('devtool status')
372 self.assertIn(testrecipe, result.output)
373 self.assertIn(srcdir, result.output)
374 # Check recipe
375 recipefile = get_bb_var('FILE', testrecipe)
376 self.assertIn('_git.bb', recipefile, 'Recipe file incorrectly named')
377 checkvars = {}
378 checkvars['S'] = '${WORKDIR}/git'
379 checkvars['PV'] = '1.5+git${SRCPV}'
380 checkvars['SRC_URI'] = url
381 checkvars['SRCREV'] = checkrev
382 self._test_recipe_contents(recipefile, checkvars, [])
383
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500384 @testcase(1391)
385 def test_devtool_add_fetch_simple(self):
386 # Fetch source from a remote URL, auto-detecting name
387 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
388 self.track_for_cleanup(tempdir)
389 testver = '1.6.0'
390 url = 'http://www.ivarch.com/programs/sources/pv-%s.tar.bz2' % testver
391 testrecipe = 'pv'
392 srcdir = os.path.join(self.workspacedir, 'sources', testrecipe)
393 # Test devtool add
394 self.track_for_cleanup(self.workspacedir)
395 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
396 result = runCmd('devtool add %s' % url)
397 self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created. %s' % result.output)
398 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure')), 'Unable to find configure script in source directory')
399 self.assertTrue(os.path.isdir(os.path.join(srcdir, '.git')), 'git repository for external source tree was not created')
400 # Test devtool status
401 result = runCmd('devtool status')
402 self.assertIn(testrecipe, result.output)
403 self.assertIn(srcdir, result.output)
404 # Check recipe
405 recipefile = get_bb_var('FILE', testrecipe)
406 self.assertIn('%s_%s.bb' % (testrecipe, testver), recipefile, 'Recipe file incorrectly named')
407 checkvars = {}
408 checkvars['S'] = None
409 checkvars['SRC_URI'] = url.replace(testver, '${PV}')
410 self._test_recipe_contents(recipefile, checkvars, [])
411
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500412 @testcase(1164)
413 def test_devtool_modify(self):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500414 # Clean up anything in the workdir/sysroot/sstate cache
415 bitbake('mdadm -c cleansstate')
416 # Try modifying a recipe
417 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
418 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500419 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500420 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
421 self.add_command_to_tearDown('bitbake -c clean mdadm')
422 result = runCmd('devtool modify mdadm -x %s' % tempdir)
423 self.assertTrue(os.path.exists(os.path.join(tempdir, 'Makefile')), 'Extracted source could not be found')
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500424 self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created')
425 matches = glob.glob(os.path.join(self.workspacedir, 'appends', 'mdadm_*.bbappend'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500426 self.assertTrue(matches, 'bbappend not created %s' % result.output)
427 # Test devtool status
428 result = runCmd('devtool status')
429 self.assertIn('mdadm', result.output)
430 self.assertIn(tempdir, result.output)
431 # Check git repo
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500432 self._check_src_repo(tempdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500433 # Try building
434 bitbake('mdadm')
435 # Try making (minor) modifications to the source
436 result = runCmd("sed -i 's!^\.TH.*!.TH MDADM 8 \"\" v9.999-custom!' %s" % os.path.join(tempdir, 'mdadm.8.in'))
437 bitbake('mdadm -c package')
438 pkgd = get_bb_var('PKGD', 'mdadm')
439 self.assertTrue(pkgd, 'Could not query PKGD variable')
440 mandir = get_bb_var('mandir', 'mdadm')
441 self.assertTrue(mandir, 'Could not query mandir variable')
442 if mandir[0] == '/':
443 mandir = mandir[1:]
444 with open(os.path.join(pkgd, mandir, 'man8', 'mdadm.8'), 'r') as f:
445 for line in f:
446 if line.startswith('.TH'):
447 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'))
448 # Test devtool reset
449 stampprefix = get_bb_var('STAMP', 'mdadm')
450 result = runCmd('devtool reset mdadm')
451 result = runCmd('devtool status')
452 self.assertNotIn('mdadm', result.output)
453 self.assertTrue(stampprefix, 'Unable to get STAMP value for recipe mdadm')
454 matches = glob.glob(stampprefix + '*')
455 self.assertFalse(matches, 'Stamp files exist for recipe mdadm that should have been cleaned')
456
457 @testcase(1166)
458 def test_devtool_modify_invalid(self):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500459 # Try modifying some recipes
460 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
461 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500462 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500463 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
464
465 testrecipes = 'perf kernel-devsrc package-index core-image-minimal meta-toolchain packagegroup-core-sdk meta-ide-support'.split()
466 # Find actual name of gcc-source since it now includes the version - crude, but good enough for this purpose
467 result = runCmd('bitbake-layers show-recipes gcc-source*')
468 reading = False
469 for line in result.output.splitlines():
470 if line.startswith('=='):
471 reading = True
472 elif reading and not line.startswith(' '):
473 testrecipes.append(line.split(':')[0])
474 for testrecipe in testrecipes:
475 # Check it's a valid recipe
476 bitbake('%s -e' % testrecipe)
477 # devtool extract should fail
478 result = runCmd('devtool extract %s %s' % (testrecipe, os.path.join(tempdir, testrecipe)), ignore_status=True)
479 self.assertNotEqual(result.status, 0, 'devtool extract on %s should have failed. devtool output: %s' % (testrecipe, result.output))
480 self.assertNotIn('Fetching ', result.output, 'devtool extract on %s should have errored out before trying to fetch' % testrecipe)
481 self.assertIn('ERROR: ', result.output, 'devtool extract on %s should have given an ERROR' % testrecipe)
482 # devtool modify should fail
483 result = runCmd('devtool modify %s -x %s' % (testrecipe, os.path.join(tempdir, testrecipe)), ignore_status=True)
484 self.assertNotEqual(result.status, 0, 'devtool modify on %s should have failed. devtool output: %s' % (testrecipe, result.output))
485 self.assertIn('ERROR: ', result.output, 'devtool modify on %s should have given an ERROR' % testrecipe)
486
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500487 @testcase(1365)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500488 def test_devtool_modify_native(self):
489 # Check preconditions
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500490 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 -0500491 # Try modifying some recipes
492 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
493 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500494 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500495 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
496
497 bbclassextended = False
498 inheritnative = False
499 testrecipes = 'mtools-native apt-native desktop-file-utils-native'.split()
500 for testrecipe in testrecipes:
501 checkextend = 'native' in (get_bb_var('BBCLASSEXTEND', testrecipe) or '').split()
502 if not bbclassextended:
503 bbclassextended = checkextend
504 if not inheritnative:
505 inheritnative = not checkextend
506 result = runCmd('devtool modify %s -x %s' % (testrecipe, os.path.join(tempdir, testrecipe)))
507 self.assertNotIn('ERROR: ', result.output, 'ERROR in devtool modify output: %s' % result.output)
508 result = runCmd('devtool build %s' % testrecipe)
509 self.assertNotIn('ERROR: ', result.output, 'ERROR in devtool build output: %s' % result.output)
510 result = runCmd('devtool reset %s' % testrecipe)
511 self.assertNotIn('ERROR: ', result.output, 'ERROR in devtool reset output: %s' % result.output)
512
513 self.assertTrue(bbclassextended, 'None of these recipes are BBCLASSEXTENDed to native - need to adjust testrecipes list: %s' % ', '.join(testrecipes))
514 self.assertTrue(inheritnative, 'None of these recipes do "inherit native" - need to adjust testrecipes list: %s' % ', '.join(testrecipes))
515
516
517 @testcase(1165)
518 def test_devtool_modify_git(self):
519 # Check preconditions
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500520 testrecipe = 'mkelfimage'
521 src_uri = get_bb_var('SRC_URI', testrecipe)
522 self.assertIn('git://', src_uri, 'This test expects the %s recipe to be a git recipe' % testrecipe)
523 # Clean up anything in the workdir/sysroot/sstate cache
524 bitbake('%s -c cleansstate' % testrecipe)
525 # Try modifying a recipe
526 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
527 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500528 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500529 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
530 self.add_command_to_tearDown('bitbake -c clean %s' % testrecipe)
531 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
532 self.assertTrue(os.path.exists(os.path.join(tempdir, 'Makefile')), 'Extracted source could not be found')
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500533 self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created. devtool output: %s' % result.output)
534 matches = glob.glob(os.path.join(self.workspacedir, 'appends', 'mkelfimage_*.bbappend'))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500535 self.assertTrue(matches, 'bbappend not created')
536 # Test devtool status
537 result = runCmd('devtool status')
538 self.assertIn(testrecipe, result.output)
539 self.assertIn(tempdir, result.output)
540 # Check git repo
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500541 self._check_src_repo(tempdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500542 # Try building
543 bitbake(testrecipe)
544
545 @testcase(1167)
546 def test_devtool_modify_localfiles(self):
547 # Check preconditions
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500548 testrecipe = 'lighttpd'
549 src_uri = (get_bb_var('SRC_URI', testrecipe) or '').split()
550 foundlocal = False
551 for item in src_uri:
552 if item.startswith('file://') and '.patch' not in item:
553 foundlocal = True
554 break
555 self.assertTrue(foundlocal, 'This test expects the %s recipe to fetch local files and it seems that it no longer does' % testrecipe)
556 # Clean up anything in the workdir/sysroot/sstate cache
557 bitbake('%s -c cleansstate' % testrecipe)
558 # Try modifying a recipe
559 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
560 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500561 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500562 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
563 self.add_command_to_tearDown('bitbake -c clean %s' % testrecipe)
564 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
565 self.assertTrue(os.path.exists(os.path.join(tempdir, 'configure.ac')), 'Extracted source could not be found')
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500566 self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created')
567 matches = glob.glob(os.path.join(self.workspacedir, 'appends', '%s_*.bbappend' % testrecipe))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500568 self.assertTrue(matches, 'bbappend not created')
569 # Test devtool status
570 result = runCmd('devtool status')
571 self.assertIn(testrecipe, result.output)
572 self.assertIn(tempdir, result.output)
573 # Try building
574 bitbake(testrecipe)
575
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500576 @testcase(1378)
577 def test_devtool_modify_virtual(self):
578 # Try modifying a virtual recipe
579 virtrecipe = 'virtual/libx11'
580 realrecipe = 'libx11'
581 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
582 self.track_for_cleanup(tempdir)
583 self.track_for_cleanup(self.workspacedir)
584 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
585 result = runCmd('devtool modify %s -x %s' % (virtrecipe, tempdir))
586 self.assertTrue(os.path.exists(os.path.join(tempdir, 'Makefile.am')), 'Extracted source could not be found')
587 self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created')
588 matches = glob.glob(os.path.join(self.workspacedir, 'appends', '%s_*.bbappend' % realrecipe))
589 self.assertTrue(matches, 'bbappend not created %s' % result.output)
590 # Test devtool status
591 result = runCmd('devtool status')
592 self.assertNotIn(virtrecipe, result.output)
593 self.assertIn(realrecipe, result.output)
594 # Check git repo
595 self._check_src_repo(tempdir)
596 # This is probably sufficient
597
598
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500599 @testcase(1169)
600 def test_devtool_update_recipe(self):
601 # Check preconditions
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500602 testrecipe = 'minicom'
603 recipefile = get_bb_var('FILE', testrecipe)
604 src_uri = get_bb_var('SRC_URI', testrecipe)
605 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 -0500606 self._check_repo_status(os.path.dirname(recipefile), [])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500607 # First, modify a recipe
608 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
609 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500610 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500611 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
612 # (don't bother with cleaning the recipe on teardown, we won't be building it)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500613 # We don't use -x here so that we test the behaviour of devtool modify without it
614 result = runCmd('devtool modify %s %s' % (testrecipe, tempdir))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500615 # Check git repo
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500616 self._check_src_repo(tempdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500617 # Add a couple of commits
618 # FIXME: this only tests adding, need to also test update and remove
619 result = runCmd('echo "Additional line" >> README', cwd=tempdir)
620 result = runCmd('git commit -a -m "Change the README"', cwd=tempdir)
621 result = runCmd('echo "A new file" > devtool-new-file', cwd=tempdir)
622 result = runCmd('git add devtool-new-file', cwd=tempdir)
623 result = runCmd('git commit -m "Add a new file"', cwd=tempdir)
624 self.add_command_to_tearDown('cd %s; rm %s/*.patch; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, testrecipe, os.path.basename(recipefile)))
625 result = runCmd('devtool update-recipe %s' % testrecipe)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500626 expected_status = [(' M', '.*/%s$' % os.path.basename(recipefile)),
627 ('??', '.*/0001-Change-the-README.patch$'),
628 ('??', '.*/0002-Add-a-new-file.patch$')]
629 self._check_repo_status(os.path.dirname(recipefile), expected_status)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500630
631 @testcase(1172)
632 def test_devtool_update_recipe_git(self):
633 # Check preconditions
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500634 testrecipe = 'mtd-utils'
635 recipefile = get_bb_var('FILE', testrecipe)
636 src_uri = get_bb_var('SRC_URI', testrecipe)
637 self.assertIn('git://', src_uri, 'This test expects the %s recipe to be a git recipe' % testrecipe)
638 patches = []
639 for entry in src_uri.split():
640 if entry.startswith('file://') and entry.endswith('.patch'):
641 patches.append(entry[7:].split(';')[0])
642 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 -0500643 self._check_repo_status(os.path.dirname(recipefile), [])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500644 # First, modify a recipe
645 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
646 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500647 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500648 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
649 # (don't bother with cleaning the recipe on teardown, we won't be building it)
650 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
651 # Check git repo
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500652 self._check_src_repo(tempdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500653 # Add a couple of commits
654 # FIXME: this only tests adding, need to also test update and remove
655 result = runCmd('echo "# Additional line" >> Makefile', cwd=tempdir)
656 result = runCmd('git commit -a -m "Change the Makefile"', cwd=tempdir)
657 result = runCmd('echo "A new file" > devtool-new-file', cwd=tempdir)
658 result = runCmd('git add devtool-new-file', cwd=tempdir)
659 result = runCmd('git commit -m "Add a new file"', cwd=tempdir)
660 self.add_command_to_tearDown('cd %s; rm -rf %s; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, testrecipe, os.path.basename(recipefile)))
661 result = runCmd('devtool update-recipe -m srcrev %s' % testrecipe)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500662 expected_status = [(' M', '.*/%s$' % os.path.basename(recipefile))] + \
663 [(' D', '.*/%s$' % patch) for patch in patches]
664 self._check_repo_status(os.path.dirname(recipefile), expected_status)
665
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500666 result = runCmd('git diff %s' % os.path.basename(recipefile), cwd=os.path.dirname(recipefile))
667 addlines = ['SRCREV = ".*"', 'SRC_URI = "git://git.infradead.org/mtd-utils.git"']
668 srcurilines = src_uri.split()
669 srcurilines[0] = 'SRC_URI = "' + srcurilines[0]
670 srcurilines.append('"')
671 removelines = ['SRCREV = ".*"'] + srcurilines
672 for line in result.output.splitlines():
673 if line.startswith('+++') or line.startswith('---'):
674 continue
675 elif line.startswith('+'):
676 matched = False
677 for item in addlines:
678 if re.match(item, line[1:].strip()):
679 matched = True
680 break
681 self.assertTrue(matched, 'Unexpected diff add line: %s' % line)
682 elif line.startswith('-'):
683 matched = False
684 for item in removelines:
685 if re.match(item, line[1:].strip()):
686 matched = True
687 break
688 self.assertTrue(matched, 'Unexpected diff remove line: %s' % line)
689 # Now try with auto mode
690 runCmd('cd %s; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, os.path.basename(recipefile)))
691 result = runCmd('devtool update-recipe %s' % testrecipe)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500692 result = runCmd('git rev-parse --show-toplevel', cwd=os.path.dirname(recipefile))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500693 topleveldir = result.output.strip()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500694 relpatchpath = os.path.join(os.path.relpath(os.path.dirname(recipefile), topleveldir), testrecipe)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500695 expected_status = [(' M', os.path.relpath(recipefile, topleveldir)),
696 ('??', '%s/0001-Change-the-Makefile.patch' % relpatchpath),
697 ('??', '%s/0002-Add-a-new-file.patch' % relpatchpath)]
698 self._check_repo_status(os.path.dirname(recipefile), expected_status)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500699
700 @testcase(1170)
701 def test_devtool_update_recipe_append(self):
702 # Check preconditions
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500703 testrecipe = 'mdadm'
704 recipefile = get_bb_var('FILE', testrecipe)
705 src_uri = get_bb_var('SRC_URI', testrecipe)
706 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 -0500707 self._check_repo_status(os.path.dirname(recipefile), [])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500708 # First, modify a recipe
709 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
710 tempsrcdir = os.path.join(tempdir, 'source')
711 templayerdir = os.path.join(tempdir, 'layer')
712 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500713 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500714 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
715 # (don't bother with cleaning the recipe on teardown, we won't be building it)
716 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempsrcdir))
717 # Check git repo
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500718 self._check_src_repo(tempsrcdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500719 # Add a commit
720 result = runCmd("sed 's!\\(#define VERSION\\W*\"[^\"]*\\)\"!\\1-custom\"!' -i ReadMe.c", cwd=tempsrcdir)
721 result = runCmd('git commit -a -m "Add our custom version"', cwd=tempsrcdir)
722 self.add_command_to_tearDown('cd %s; rm -f %s/*.patch; git checkout .' % (os.path.dirname(recipefile), testrecipe))
723 # Create a temporary layer and add it to bblayers.conf
724 self._create_temp_layer(templayerdir, True, 'selftestupdaterecipe')
725 # Create the bbappend
726 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
727 self.assertNotIn('WARNING:', result.output)
728 # Check recipe is still clean
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500729 self._check_repo_status(os.path.dirname(recipefile), [])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500730 # Check bbappend was created
731 splitpath = os.path.dirname(recipefile).split(os.sep)
732 appenddir = os.path.join(templayerdir, splitpath[-2], splitpath[-1])
733 bbappendfile = self._check_bbappend(testrecipe, recipefile, appenddir)
734 patchfile = os.path.join(appenddir, testrecipe, '0001-Add-our-custom-version.patch')
735 self.assertTrue(os.path.exists(patchfile), 'Patch file not created')
736
737 # Check bbappend contents
738 expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
739 '\n',
740 'SRC_URI += "file://0001-Add-our-custom-version.patch"\n',
741 '\n']
742 with open(bbappendfile, 'r') as f:
743 self.assertEqual(expectedlines, f.readlines())
744
745 # Check we can run it again and bbappend isn't modified
746 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
747 with open(bbappendfile, 'r') as f:
748 self.assertEqual(expectedlines, f.readlines())
749 # Drop new commit and check patch gets deleted
750 result = runCmd('git reset HEAD^', cwd=tempsrcdir)
751 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
752 self.assertFalse(os.path.exists(patchfile), 'Patch file not deleted')
753 expectedlines2 = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
754 '\n']
755 with open(bbappendfile, 'r') as f:
756 self.assertEqual(expectedlines2, f.readlines())
757 # Put commit back and check we can run it if layer isn't in bblayers.conf
758 os.remove(bbappendfile)
759 result = runCmd('git commit -a -m "Add our custom version"', cwd=tempsrcdir)
760 result = runCmd('bitbake-layers remove-layer %s' % templayerdir, cwd=self.builddir)
761 result = runCmd('devtool update-recipe %s -a %s' % (testrecipe, templayerdir))
762 self.assertIn('WARNING: Specified layer is not currently enabled in bblayers.conf', result.output)
763 self.assertTrue(os.path.exists(patchfile), 'Patch file not created (with disabled layer)')
764 with open(bbappendfile, 'r') as f:
765 self.assertEqual(expectedlines, f.readlines())
766 # Deleting isn't expected to work under these circumstances
767
768 @testcase(1171)
769 def test_devtool_update_recipe_append_git(self):
770 # Check preconditions
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500771 testrecipe = 'mtd-utils'
772 recipefile = get_bb_var('FILE', testrecipe)
773 src_uri = get_bb_var('SRC_URI', testrecipe)
774 self.assertIn('git://', src_uri, 'This test expects the %s recipe to be a git recipe' % testrecipe)
775 for entry in src_uri.split():
776 if entry.startswith('git://'):
777 git_uri = entry
778 break
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500779 self._check_repo_status(os.path.dirname(recipefile), [])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500780 # First, modify a recipe
781 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
782 tempsrcdir = os.path.join(tempdir, 'source')
783 templayerdir = os.path.join(tempdir, 'layer')
784 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500785 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500786 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
787 # (don't bother with cleaning the recipe on teardown, we won't be building it)
788 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempsrcdir))
789 # Check git repo
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500790 self._check_src_repo(tempsrcdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500791 # Add a commit
792 result = runCmd('echo "# Additional line" >> Makefile', cwd=tempsrcdir)
793 result = runCmd('git commit -a -m "Change the Makefile"', cwd=tempsrcdir)
794 self.add_command_to_tearDown('cd %s; rm -f %s/*.patch; git checkout .' % (os.path.dirname(recipefile), testrecipe))
795 # Create a temporary layer
796 os.makedirs(os.path.join(templayerdir, 'conf'))
797 with open(os.path.join(templayerdir, 'conf', 'layer.conf'), 'w') as f:
798 f.write('BBPATH .= ":${LAYERDIR}"\n')
799 f.write('BBFILES += "${LAYERDIR}/recipes-*/*/*.bbappend"\n')
800 f.write('BBFILE_COLLECTIONS += "oeselftesttemplayer"\n')
801 f.write('BBFILE_PATTERN_oeselftesttemplayer = "^${LAYERDIR}/"\n')
802 f.write('BBFILE_PRIORITY_oeselftesttemplayer = "999"\n')
803 f.write('BBFILE_PATTERN_IGNORE_EMPTY_oeselftesttemplayer = "1"\n')
804 self.add_command_to_tearDown('bitbake-layers remove-layer %s || true' % templayerdir)
805 result = runCmd('bitbake-layers add-layer %s' % templayerdir, cwd=self.builddir)
806 # Create the bbappend
807 result = runCmd('devtool update-recipe -m srcrev %s -a %s' % (testrecipe, templayerdir))
808 self.assertNotIn('WARNING:', result.output)
809 # Check recipe is still clean
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500810 self._check_repo_status(os.path.dirname(recipefile), [])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500811 # Check bbappend was created
812 splitpath = os.path.dirname(recipefile).split(os.sep)
813 appenddir = os.path.join(templayerdir, splitpath[-2], splitpath[-1])
814 bbappendfile = self._check_bbappend(testrecipe, recipefile, appenddir)
815 self.assertFalse(os.path.exists(os.path.join(appenddir, testrecipe)), 'Patch directory should not be created')
816
817 # Check bbappend contents
818 result = runCmd('git rev-parse HEAD', cwd=tempsrcdir)
819 expectedlines = ['SRCREV = "%s"\n' % result.output,
820 '\n',
821 'SRC_URI = "%s"\n' % git_uri,
822 '\n']
823 with open(bbappendfile, 'r') as f:
824 self.assertEqual(expectedlines, f.readlines())
825
826 # Check we can run it again and bbappend isn't modified
827 result = runCmd('devtool update-recipe -m srcrev %s -a %s' % (testrecipe, templayerdir))
828 with open(bbappendfile, 'r') as f:
829 self.assertEqual(expectedlines, f.readlines())
830 # Drop new commit and check SRCREV changes
831 result = runCmd('git reset HEAD^', cwd=tempsrcdir)
832 result = runCmd('devtool update-recipe -m srcrev %s -a %s' % (testrecipe, templayerdir))
833 self.assertFalse(os.path.exists(os.path.join(appenddir, testrecipe)), 'Patch directory should not be created')
834 result = runCmd('git rev-parse HEAD', cwd=tempsrcdir)
835 expectedlines = ['SRCREV = "%s"\n' % result.output,
836 '\n',
837 'SRC_URI = "%s"\n' % git_uri,
838 '\n']
839 with open(bbappendfile, 'r') as f:
840 self.assertEqual(expectedlines, f.readlines())
841 # Put commit back and check we can run it if layer isn't in bblayers.conf
842 os.remove(bbappendfile)
843 result = runCmd('git commit -a -m "Change the Makefile"', cwd=tempsrcdir)
844 result = runCmd('bitbake-layers remove-layer %s' % templayerdir, cwd=self.builddir)
845 result = runCmd('devtool update-recipe -m srcrev %s -a %s' % (testrecipe, templayerdir))
846 self.assertIn('WARNING: Specified layer is not currently enabled in bblayers.conf', result.output)
847 self.assertFalse(os.path.exists(os.path.join(appenddir, testrecipe)), 'Patch directory should not be created')
848 result = runCmd('git rev-parse HEAD', cwd=tempsrcdir)
849 expectedlines = ['SRCREV = "%s"\n' % result.output,
850 '\n',
851 'SRC_URI = "%s"\n' % git_uri,
852 '\n']
853 with open(bbappendfile, 'r') as f:
854 self.assertEqual(expectedlines, f.readlines())
855 # Deleting isn't expected to work under these circumstances
856
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500857 @testcase(1370)
858 def test_devtool_update_recipe_local_files(self):
859 """Check that local source files are copied over instead of patched"""
860 testrecipe = 'makedevs'
861 recipefile = get_bb_var('FILE', testrecipe)
862 # Setup srctree for modifying the recipe
863 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
864 self.track_for_cleanup(tempdir)
865 self.track_for_cleanup(self.workspacedir)
866 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
867 # (don't bother with cleaning the recipe on teardown, we won't be
868 # building it)
869 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
870 # Check git repo
871 self._check_src_repo(tempdir)
872 # Edit / commit local source
873 runCmd('echo "/* Foobar */" >> oe-local-files/makedevs.c', cwd=tempdir)
874 runCmd('echo "Foo" > oe-local-files/new-local', cwd=tempdir)
875 runCmd('echo "Bar" > new-file', cwd=tempdir)
876 runCmd('git add new-file', cwd=tempdir)
877 runCmd('git commit -m "Add new file"', cwd=tempdir)
878 self.add_command_to_tearDown('cd %s; git clean -fd .; git checkout .' %
879 os.path.dirname(recipefile))
880 runCmd('devtool update-recipe %s' % testrecipe)
881 expected_status = [(' M', '.*/%s$' % os.path.basename(recipefile)),
882 (' M', '.*/makedevs/makedevs.c$'),
883 ('??', '.*/makedevs/new-local$'),
884 ('??', '.*/makedevs/0001-Add-new-file.patch$')]
885 self._check_repo_status(os.path.dirname(recipefile), expected_status)
886
887 @testcase(1371)
888 def test_devtool_update_recipe_local_files_2(self):
889 """Check local source files support when oe-local-files is in Git"""
890 testrecipe = 'lzo'
891 recipefile = get_bb_var('FILE', testrecipe)
892 # Setup srctree for modifying the recipe
893 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
894 self.track_for_cleanup(tempdir)
895 self.track_for_cleanup(self.workspacedir)
896 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
897 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
898 # Check git repo
899 self._check_src_repo(tempdir)
900 # Add oe-local-files to Git
901 runCmd('rm oe-local-files/.gitignore', cwd=tempdir)
902 runCmd('git add oe-local-files', cwd=tempdir)
903 runCmd('git commit -m "Add local sources"', cwd=tempdir)
904 # Edit / commit local sources
905 runCmd('echo "# Foobar" >> oe-local-files/acinclude.m4', cwd=tempdir)
906 runCmd('git commit -am "Edit existing file"', cwd=tempdir)
907 runCmd('git rm oe-local-files/run-ptest', cwd=tempdir)
908 runCmd('git commit -m"Remove file"', cwd=tempdir)
909 runCmd('echo "Foo" > oe-local-files/new-local', cwd=tempdir)
910 runCmd('git add oe-local-files/new-local', cwd=tempdir)
911 runCmd('git commit -m "Add new local file"', cwd=tempdir)
912 runCmd('echo "Gar" > new-file', cwd=tempdir)
913 runCmd('git add new-file', cwd=tempdir)
914 runCmd('git commit -m "Add new file"', cwd=tempdir)
915 self.add_command_to_tearDown('cd %s; git clean -fd .; git checkout .' %
916 os.path.dirname(recipefile))
917 # Checkout unmodified file to working copy -> devtool should still pick
918 # the modified version from HEAD
919 runCmd('git checkout HEAD^ -- oe-local-files/acinclude.m4', cwd=tempdir)
920 runCmd('devtool update-recipe %s' % testrecipe)
921 expected_status = [(' M', '.*/%s$' % os.path.basename(recipefile)),
922 (' M', '.*/acinclude.m4$'),
923 (' D', '.*/run-ptest$'),
924 ('??', '.*/new-local$'),
925 ('??', '.*/0001-Add-new-file.patch$')]
926 self._check_repo_status(os.path.dirname(recipefile), expected_status)
927
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500928 @testcase(1163)
929 def test_devtool_extract(self):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500930 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
931 # Try devtool extract
932 self.track_for_cleanup(tempdir)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500933 self.append_config('PREFERRED_PROVIDER_virtual/make = "remake"')
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500934 result = runCmd('devtool extract remake %s' % tempdir)
935 self.assertTrue(os.path.exists(os.path.join(tempdir, 'Makefile.am')), 'Extracted source could not be found')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500936 # devtool extract shouldn't create the workspace
937 self.assertFalse(os.path.exists(self.workspacedir))
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500938 self._check_src_repo(tempdir)
939
940 @testcase(1379)
941 def test_devtool_extract_virtual(self):
942 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
943 # Try devtool extract
944 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500945 result = runCmd('devtool extract virtual/libx11 %s' % tempdir)
946 self.assertTrue(os.path.exists(os.path.join(tempdir, 'Makefile.am')), 'Extracted source could not be found')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500947 # devtool extract shouldn't create the workspace
948 self.assertFalse(os.path.exists(self.workspacedir))
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500949 self._check_src_repo(tempdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500950
951 @testcase(1168)
952 def test_devtool_reset_all(self):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500953 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
954 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500955 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500956 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
957 testrecipe1 = 'mdadm'
958 testrecipe2 = 'cronie'
959 result = runCmd('devtool modify -x %s %s' % (testrecipe1, os.path.join(tempdir, testrecipe1)))
960 result = runCmd('devtool modify -x %s %s' % (testrecipe2, os.path.join(tempdir, testrecipe2)))
961 result = runCmd('devtool build %s' % testrecipe1)
962 result = runCmd('devtool build %s' % testrecipe2)
963 stampprefix1 = get_bb_var('STAMP', testrecipe1)
964 self.assertTrue(stampprefix1, 'Unable to get STAMP value for recipe %s' % testrecipe1)
965 stampprefix2 = get_bb_var('STAMP', testrecipe2)
966 self.assertTrue(stampprefix2, 'Unable to get STAMP value for recipe %s' % testrecipe2)
967 result = runCmd('devtool reset -a')
968 self.assertIn(testrecipe1, result.output)
969 self.assertIn(testrecipe2, result.output)
970 result = runCmd('devtool status')
971 self.assertNotIn(testrecipe1, result.output)
972 self.assertNotIn(testrecipe2, result.output)
973 matches1 = glob.glob(stampprefix1 + '*')
974 self.assertFalse(matches1, 'Stamp files exist for recipe %s that should have been cleaned' % testrecipe1)
975 matches2 = glob.glob(stampprefix2 + '*')
976 self.assertFalse(matches2, 'Stamp files exist for recipe %s that should have been cleaned' % testrecipe2)
977
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500978 @testcase(1272)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500979 def test_devtool_deploy_target(self):
980 # NOTE: Whilst this test would seemingly be better placed as a runtime test,
981 # unfortunately the runtime tests run under bitbake and you can't run
982 # devtool within bitbake (since devtool needs to run bitbake itself).
983 # Additionally we are testing build-time functionality as well, so
984 # really this has to be done as an oe-selftest test.
985 #
986 # Check preconditions
987 machine = get_bb_var('MACHINE')
988 if not machine.startswith('qemu'):
989 self.skipTest('This test only works with qemu machines')
990 if not os.path.exists('/etc/runqemu-nosudo'):
991 self.skipTest('You must set up tap devices with scripts/runqemu-gen-tapdevs before running this test')
992 result = runCmd('PATH="$PATH:/sbin:/usr/sbin" ip tuntap show', ignore_status=True)
993 if result.status != 0:
994 result = runCmd('PATH="$PATH:/sbin:/usr/sbin" ifconfig -a', ignore_status=True)
995 if result.status != 0:
996 self.skipTest('Failed to determine if tap devices exist with ifconfig or ip: %s' % result.output)
997 for line in result.output.splitlines():
998 if line.startswith('tap'):
999 break
1000 else:
1001 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 -05001002 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 -05001003 # Definitions
1004 testrecipe = 'mdadm'
1005 testfile = '/sbin/mdadm'
1006 testimage = 'oe-selftest-image'
1007 testcommand = '/sbin/mdadm --help'
1008 # Build an image to run
1009 bitbake("%s qemu-native qemu-helper-native" % testimage)
1010 deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
1011 self.add_command_to_tearDown('bitbake -c clean %s' % testimage)
1012 self.add_command_to_tearDown('rm -f %s/%s*' % (deploy_dir_image, testimage))
1013 # Clean recipe so the first deploy will fail
1014 bitbake("%s -c clean" % testrecipe)
1015 # Try devtool modify
1016 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1017 self.track_for_cleanup(tempdir)
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001018 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001019 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1020 self.add_command_to_tearDown('bitbake -c clean %s' % testrecipe)
1021 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
1022 # Test that deploy-target at this point fails (properly)
1023 result = runCmd('devtool deploy-target -n %s root@localhost' % testrecipe, ignore_status=True)
1024 self.assertNotEqual(result.output, 0, 'devtool deploy-target should have failed, output: %s' % result.output)
1025 self.assertNotIn(result.output, 'Traceback', 'devtool deploy-target should have failed with a proper error not a traceback, output: %s' % result.output)
1026 result = runCmd('devtool build %s' % testrecipe)
1027 # First try a dry-run of deploy-target
1028 result = runCmd('devtool deploy-target -n %s root@localhost' % testrecipe)
1029 self.assertIn(' %s' % testfile, result.output)
1030 # Boot the image
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001031 with runqemu(testimage) as qemu:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001032 # Now really test deploy-target
1033 result = runCmd('devtool deploy-target -c %s root@%s' % (testrecipe, qemu.ip))
1034 # Run a test command to see if it was installed properly
1035 sshargs = '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'
1036 result = runCmd('ssh %s root@%s %s' % (sshargs, qemu.ip, testcommand))
1037 # Check if it deployed all of the files with the right ownership/perms
1038 # First look on the host - need to do this under pseudo to get the correct ownership/perms
1039 installdir = get_bb_var('D', testrecipe)
1040 fakerootenv = get_bb_var('FAKEROOTENV', testrecipe)
1041 fakerootcmd = get_bb_var('FAKEROOTCMD', testrecipe)
1042 result = runCmd('%s %s find . -type f -exec ls -l {} \;' % (fakerootenv, fakerootcmd), cwd=installdir)
1043 filelist1 = self._process_ls_output(result.output)
1044
1045 # Now look on the target
1046 tempdir2 = tempfile.mkdtemp(prefix='devtoolqa')
1047 self.track_for_cleanup(tempdir2)
1048 tmpfilelist = os.path.join(tempdir2, 'files.txt')
1049 with open(tmpfilelist, 'w') as f:
1050 for line in filelist1:
1051 splitline = line.split()
1052 f.write(splitline[-1] + '\n')
1053 result = runCmd('cat %s | ssh -q %s root@%s \'xargs ls -l\'' % (tmpfilelist, sshargs, qemu.ip))
1054 filelist2 = self._process_ls_output(result.output)
1055 filelist1.sort(key=lambda item: item.split()[-1])
1056 filelist2.sort(key=lambda item: item.split()[-1])
1057 self.assertEqual(filelist1, filelist2)
1058 # Test undeploy-target
1059 result = runCmd('devtool undeploy-target -c %s root@%s' % (testrecipe, qemu.ip))
1060 result = runCmd('ssh %s root@%s %s' % (sshargs, qemu.ip, testcommand), ignore_status=True)
1061 self.assertNotEqual(result, 0, 'undeploy-target did not remove command as it should have')
1062
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001063 @testcase(1366)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001064 def test_devtool_build_image(self):
1065 """Test devtool build-image plugin"""
1066 # Check preconditions
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001067 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 -05001068 image = 'core-image-minimal'
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001069 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001070 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1071 self.add_command_to_tearDown('bitbake -c clean %s' % image)
1072 bitbake('%s -c clean' % image)
1073 # Add target and native recipes to workspace
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001074 recipes = ['mdadm', 'parted-native']
1075 for recipe in recipes:
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001076 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1077 self.track_for_cleanup(tempdir)
1078 self.add_command_to_tearDown('bitbake -c clean %s' % recipe)
1079 runCmd('devtool modify %s -x %s' % (recipe, tempdir))
1080 # Try to build image
1081 result = runCmd('devtool build-image %s' % image)
1082 self.assertNotEqual(result, 0, 'devtool build-image failed')
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001083 # Check if image contains expected packages
1084 deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
1085 image_link_name = get_bb_var('IMAGE_LINK_NAME', image)
1086 reqpkgs = [item for item in recipes if not item.endswith('-native')]
1087 with open(os.path.join(deploy_dir_image, image_link_name + '.manifest'), 'r') as f:
1088 for line in f:
1089 splitval = line.split()
1090 if splitval:
1091 pkg = splitval[0]
1092 if pkg in reqpkgs:
1093 reqpkgs.remove(pkg)
1094 if reqpkgs:
1095 self.fail('The following packages were not present in the image as expected: %s' % ', '.join(reqpkgs))
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001096
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001097 @testcase(1367)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001098 def test_devtool_upgrade(self):
1099 # Check preconditions
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001100 self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001101 self.track_for_cleanup(self.workspacedir)
1102 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001103 # Check parameters
1104 result = runCmd('devtool upgrade -h')
1105 for param in 'recipename srctree --version -V --branch -b --keep-temp --no-patch'.split():
1106 self.assertIn(param, result.output)
1107 # For the moment, we are using a real recipe.
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001108 recipe = 'devtool-upgrade-test1'
1109 version = '1.6.0'
1110 oldrecipefile = get_bb_var('FILE', recipe)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001111 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001112 self.track_for_cleanup(tempdir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001113 # Check that recipe is not already under devtool control
1114 result = runCmd('devtool status')
1115 self.assertNotIn(recipe, result.output)
1116 # Check upgrade. Code does not check if new PV is older or newer that current PV, so, it may be that
1117 # we are downgrading instead of upgrading.
1118 result = runCmd('devtool upgrade %s %s -V %s' % (recipe, tempdir, version))
1119 # Check if srctree at least is populated
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001120 self.assertTrue(len(os.listdir(tempdir)) > 0, 'srctree (%s) should be populated with new (%s) source code' % (tempdir, version))
1121 # Check new recipe subdirectory is present
1122 self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'recipes', recipe, '%s-%s' % (recipe, version))), 'Recipe folder should exist')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001123 # Check new recipe file is present
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001124 newrecipefile = os.path.join(self.workspacedir, 'recipes', recipe, '%s_%s.bb' % (recipe, version))
1125 self.assertTrue(os.path.exists(newrecipefile), 'Recipe file should exist after upgrade')
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001126 # Check devtool status and make sure recipe is present
1127 result = runCmd('devtool status')
1128 self.assertIn(recipe, result.output)
1129 self.assertIn(tempdir, result.output)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001130 # Check recipe got changed as expected
1131 with open(oldrecipefile + '.upgraded', 'r') as f:
1132 desiredlines = f.readlines()
1133 with open(newrecipefile, 'r') as f:
1134 newlines = f.readlines()
1135 self.assertEqual(desiredlines, newlines)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001136 # Check devtool reset recipe
1137 result = runCmd('devtool reset %s -n' % recipe)
1138 result = runCmd('devtool status')
1139 self.assertNotIn(recipe, result.output)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001140 self.assertFalse(os.path.exists(os.path.join(self.workspacedir, 'recipes', recipe)), 'Recipe directory should not exist after resetting')
1141
1142 @testcase(1433)
1143 def test_devtool_upgrade_git(self):
1144 # Check preconditions
1145 self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory')
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001146 self.track_for_cleanup(self.workspacedir)
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001147 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001148 recipe = 'devtool-upgrade-test2'
1149 commit = '6cc6077a36fe2648a5f993fe7c16c9632f946517'
1150 oldrecipefile = get_bb_var('FILE', recipe)
1151 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
1152 self.track_for_cleanup(tempdir)
1153 # Check that recipe is not already under devtool control
1154 result = runCmd('devtool status')
1155 self.assertNotIn(recipe, result.output)
1156 # Check upgrade
1157 result = runCmd('devtool upgrade %s %s -S %s' % (recipe, tempdir, commit))
1158 # Check if srctree at least is populated
1159 self.assertTrue(len(os.listdir(tempdir)) > 0, 'srctree (%s) should be populated with new (%s) source code' % (tempdir, commit))
1160 # Check new recipe file is present
1161 newrecipefile = os.path.join(self.workspacedir, 'recipes', recipe, os.path.basename(oldrecipefile))
1162 self.assertTrue(os.path.exists(newrecipefile), 'Recipe file should exist after upgrade')
1163 # Check devtool status and make sure recipe is present
1164 result = runCmd('devtool status')
1165 self.assertIn(recipe, result.output)
1166 self.assertIn(tempdir, result.output)
1167 # Check recipe got changed as expected
1168 with open(oldrecipefile + '.upgraded', 'r') as f:
1169 desiredlines = f.readlines()
1170 with open(newrecipefile, 'r') as f:
1171 newlines = f.readlines()
1172 self.assertEqual(desiredlines, newlines)
1173 # Check devtool reset recipe
1174 result = runCmd('devtool reset %s -n' % recipe)
1175 result = runCmd('devtool status')
1176 self.assertNotIn(recipe, result.output)
1177 self.assertFalse(os.path.exists(os.path.join(self.workspacedir, 'recipes', recipe)), 'Recipe directory should not exist after resetting')
Patrick Williamsf1e5d692016-03-30 15:21:19 -05001178
1179 @testcase(1352)
1180 def test_devtool_layer_plugins(self):
1181 """Test that devtool can use plugins from other layers.
1182
1183 This test executes the selftest-reverse command from meta-selftest."""
1184
1185 self.track_for_cleanup(self.workspacedir)
1186 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
1187
1188 s = "Microsoft Made No Profit From Anyone's Zunes Yo"
1189 result = runCmd("devtool --quiet selftest-reverse \"%s\"" % s)
1190 self.assertEqual(result.output, s[::-1])