summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggleton <paul.eggleton@linux.intel.com>2014-12-19 11:41:57 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-12-23 10:18:16 +0000
commit8d46255a56f85f0d9fe1d00138f3855a54e3b510 (patch)
treebb1c5192e607728f71aec31b6800f534547318c7
parent0d686ccc7c7facdaa36df5c340d000c3674e58c5 (diff)
downloadpoky-8d46255a56f85f0d9fe1d00138f3855a54e3b510.tar.gz
devtool: add QA tests
Add some QA tests for devtool (and recipetool). These aren't comprehensive but at least they are a start, and have already helped me catch and fix a number of regressions. (From OE-Core rev: 79486a8aea7af138535e139e696fbdbd5d57581b) Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/lib/oeqa/selftest/devtool.py239
1 files changed, 239 insertions, 0 deletions
diff --git a/meta/lib/oeqa/selftest/devtool.py b/meta/lib/oeqa/selftest/devtool.py
new file mode 100644
index 0000000000..e8ff536c16
--- /dev/null
+++ b/meta/lib/oeqa/selftest/devtool.py
@@ -0,0 +1,239 @@
1import 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
12from oeqa.utils.decorators import testcase
13
14class DevtoolTests(oeSelfTest):
15
16 def test_create_workspace(self):
17 # Check preconditions
18 workspacedir = os.path.join(self.builddir, 'workspace')
19 self.assertTrue(not os.path.exists(workspacedir), 'This test cannot be run with a workspace directory under the build directory')
20 result = runCmd('bitbake-layers show-layers')
21 self.assertTrue('/workspace' not in result.output, 'This test cannot be run with a workspace layer in bblayers.conf')
22 # Try creating a workspace layer with a specific path
23 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
24 self.track_for_cleanup(tempdir)
25 result = runCmd('devtool create-workspace %s' % tempdir)
26 self.assertTrue(os.path.isfile(os.path.join(tempdir, 'conf', 'layer.conf')))
27 result = runCmd('bitbake-layers show-layers')
28 self.assertTrue(tempdir in result.output)
29 # Try creating a workspace layer with the default path
30 self.track_for_cleanup(workspacedir)
31 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
32 result = runCmd('devtool create-workspace')
33 self.assertTrue(os.path.isfile(os.path.join(workspacedir, 'conf', 'layer.conf')))
34 result = runCmd('bitbake-layers show-layers')
35 self.assertTrue(tempdir not in result.output)
36 self.assertTrue(workspacedir in result.output)
37
38 def test_recipetool_create(self):
39 # Try adding a recipe
40 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
41 self.track_for_cleanup(tempdir)
42 tempsrc = os.path.join(tempdir, 'srctree')
43 os.makedirs(tempsrc)
44 recipefile = os.path.join(tempdir, 'logrotate_3.8.7.bb')
45 srcuri = 'https://fedorahosted.org/releases/l/o/logrotate/logrotate-3.8.7.tar.gz'
46 result = runCmd('recipetool create -o %s %s -x %s' % (recipefile, srcuri, tempsrc))
47 self.assertTrue(os.path.isfile(recipefile))
48 checkvars = {}
49 checkvars['LICENSE'] = 'GPLv2'
50 checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=18810669f13b87348459e611d31ab760'
51 checkvars['SRC_URI'] = 'https://fedorahosted.org/releases/l/o/logrotate/logrotate-${PV}.tar.gz'
52 checkvars['SRC_URI[md5sum]'] = '99e08503ef24c3e2e3ff74cc5f3be213'
53 checkvars['SRC_URI[sha256sum]'] = 'f6ba691f40e30e640efa2752c1f9499a3f9738257660994de70a45fe00d12b64'
54 with open(recipefile, 'r') as f:
55 for line in f:
56 if '=' in line:
57 splitline = line.split('=', 1)
58 var = splitline[0].rstrip()
59 value = splitline[1].strip().strip('"')
60 if var in checkvars:
61 needvalue = checkvars.pop(var)
62 self.assertEqual(value, needvalue)
63 if line.startswith('inherit '):
64 inherits = line.split()[1:]
65
66 self.assertEqual(checkvars, {}, 'Some variables not found')
67
68 def test_recipetool_create_git(self):
69 # Try adding a recipe
70 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
71 self.track_for_cleanup(tempdir)
72 tempsrc = os.path.join(tempdir, 'srctree')
73 os.makedirs(tempsrc)
74 recipefile = os.path.join(tempdir, 'libmatchbox.bb')
75 srcuri = 'git://git.yoctoproject.org/libmatchbox'
76 result = runCmd('recipetool create -o %s %s -x %s' % (recipefile, srcuri, tempsrc))
77 self.assertTrue(os.path.isfile(recipefile))
78 checkvars = {}
79 checkvars['LICENSE'] = 'LGPLv2.1'
80 checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=7fbc338309ac38fefcd64b04bb903e34'
81 checkvars['S'] = '${WORKDIR}/git'
82 checkvars['PV'] = '1.0+git${SRCPV}'
83 checkvars['SRC_URI'] = srcuri
84 checkvars['DEPENDS'] = 'libpng pango libx11 libxext'
85 inherits = []
86 with open(recipefile, 'r') as f:
87 for line in f:
88 if '=' in line:
89 splitline = line.split('=', 1)
90 var = splitline[0].rstrip()
91 value = splitline[1].strip().strip('"')
92 if var in checkvars:
93 needvalue = checkvars.pop(var)
94 self.assertEqual(value, needvalue)
95 if line.startswith('inherit '):
96 inherits = line.split()[1:]
97
98 self.assertEqual(checkvars, {}, 'Some variables not found')
99
100 self.assertIn('autotools', inherits, 'Missing inherit of autotools')
101 self.assertIn('pkgconfig', inherits, 'Missing inherit of pkgconfig')
102
103 def test_devtool_add(self):
104 # Check preconditions
105 workspacedir = os.path.join(self.builddir, 'workspace')
106 self.assertTrue(not os.path.exists(workspacedir), 'This test cannot be run with a workspace directory under the build directory')
107 # Fetch source
108 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
109 self.track_for_cleanup(tempdir)
110 url = 'http://www.ivarch.com/programs/sources/pv-1.5.3.tar.bz2'
111 result = runCmd('wget %s' % url, cwd=tempdir)
112 result = runCmd('tar xfv pv-1.5.3.tar.bz2', cwd=tempdir)
113 srcdir = os.path.join(tempdir, 'pv-1.5.3')
114 self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure')))
115 # Test devtool add
116 self.track_for_cleanup(workspacedir)
117 self.add_command_to_tearDown('bitbake -c cleansstate pv')
118 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
119 result = runCmd('devtool add pv %s' % srcdir)
120 self.assertTrue(os.path.exists(os.path.join(workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created')
121 # Test devtool status
122 result = runCmd('devtool status')
123 self.assertIn('pv', result.output)
124 self.assertIn(srcdir, result.output)
125 # Clean up anything in the workdir/sysroot/sstate cache (have to do this *after* devtool add since the recipe only exists then)
126 bitbake('pv -c cleansstate')
127 # Test devtool build
128 result = runCmd('devtool build pv')
129 installdir = get_bb_var('D', 'pv')
130 self.assertTrue(installdir)
131 bindir = get_bb_var('bindir', 'pv')
132 self.assertTrue(bindir)
133 if bindir[0] == '/':
134 bindir = bindir[1:]
135 self.assertTrue(os.path.isfile(os.path.join(installdir, bindir, 'pv')), 'pv binary not found in D')
136
137 def test_devtool_modify(self):
138 # Check preconditions
139 workspacedir = os.path.join(self.builddir, 'workspace')
140 self.assertTrue(not os.path.exists(workspacedir), 'This test cannot be run with a workspace directory under the build directory')
141 # Clean up anything in the workdir/sysroot/sstate cache
142 bitbake('mdadm -c cleansstate')
143 # Try modifying a recipe
144 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
145 self.track_for_cleanup(tempdir)
146 self.track_for_cleanup(workspacedir)
147 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
148 self.add_command_to_tearDown('bitbake -c clean mdadm')
149 result = runCmd('devtool modify mdadm -x %s' % tempdir)
150 self.assertTrue(os.path.exists(os.path.join(tempdir, 'Makefile')), 'Extracted source could not be found')
151 self.assertTrue(os.path.isdir(os.path.join(tempdir, '.git')), 'git repository for external source tree not found')
152 self.assertTrue(os.path.exists(os.path.join(workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created')
153 matches = glob.glob(os.path.join(workspacedir, 'appends', 'mdadm_*.bbappend'))
154 self.assertTrue(matches, 'bbappend not created')
155 # Test devtool status
156 result = runCmd('devtool status')
157 self.assertIn('mdadm', result.output)
158 self.assertIn(tempdir, result.output)
159 # Check git repo
160 result = runCmd('git status --porcelain', cwd=tempdir)
161 self.assertEqual(result.output.strip(), "", 'Created git repo is not clean')
162 result = runCmd('git symbolic-ref HEAD', cwd=tempdir)
163 self.assertEqual(result.output.strip(), "refs/heads/devtool", 'Wrong branch in git repo')
164 # Try building
165 bitbake('mdadm')
166 # Try making (minor) modifications to the source
167 result = runCmd("sed -i 's!^\.TH.*!.TH MDADM 8 \"\" v9.999-custom!' %s" % os.path.join(tempdir, 'mdadm.8.in'))
168 bitbake('mdadm -c package')
169 pkgd = get_bb_var('PKGD', 'mdadm')
170 self.assertTrue(pkgd)
171 mandir = get_bb_var('mandir', 'mdadm')
172 self.assertTrue(mandir)
173 if mandir[0] == '/':
174 mandir = mandir[1:]
175 with open(os.path.join(pkgd, mandir, 'man8', 'mdadm.8'), 'r') as f:
176 for line in f:
177 if line.startswith('.TH'):
178 self.assertEqual(line.rstrip(), '.TH MDADM 8 "" v9.999-custom', 'man file not modified')
179 # Test devtool reset
180 result = runCmd('devtool reset mdadm')
181 result = runCmd('devtool status')
182 self.assertNotIn('mdadm', result.output)
183
184 def test_devtool_update_recipe(self):
185 # Check preconditions
186 workspacedir = os.path.join(self.builddir, 'workspace')
187 self.assertTrue(not os.path.exists(workspacedir), 'This test cannot be run with a workspace directory under the build directory')
188 testrecipe = 'minicom'
189 recipefile = get_bb_var('FILE', testrecipe)
190 result = runCmd('git status . --porcelain', cwd=os.path.dirname(recipefile))
191 self.assertEqual(result.output.strip(), "", '%s recipe is not clean' % testrecipe)
192 # First, modify a recipe
193 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
194 self.track_for_cleanup(tempdir)
195 self.track_for_cleanup(workspacedir)
196 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
197 # (don't bother with cleaning the recipe on teardown, we won't be building it)
198 result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir))
199 # Check git repo
200 self.assertTrue(os.path.isdir(os.path.join(tempdir, '.git')), 'git repository for external source tree not found')
201 result = runCmd('git status --porcelain', cwd=tempdir)
202 self.assertEqual(result.output.strip(), "", 'Created git repo is not clean')
203 result = runCmd('git symbolic-ref HEAD', cwd=tempdir)
204 self.assertEqual(result.output.strip(), "refs/heads/devtool", 'Wrong branch in git repo')
205 # Add a couple of commits
206 # FIXME: this only tests adding, need to also test update and remove
207 result = runCmd('echo "Additional line" >> README', cwd=tempdir)
208 result = runCmd('git commit -a -m "Change the README"', cwd=tempdir)
209 result = runCmd('echo "A new file" > devtool-new-file', cwd=tempdir)
210 result = runCmd('git add devtool-new-file', cwd=tempdir)
211 result = runCmd('git commit -m "Add a new file"', cwd=tempdir)
212 self.add_command_to_tearDown('cd %s; rm %s/*.patch; git checkout %s %s' % (os.path.dirname(recipefile), testrecipe, testrecipe, os.path.basename(recipefile)))
213 result = runCmd('devtool update-recipe %s' % testrecipe)
214 result = runCmd('git status . --porcelain', cwd=os.path.dirname(recipefile))
215 self.assertNotEqual(result.output.strip(), "", '%s recipe should be modified' % testrecipe)
216 status = result.output.splitlines()
217 self.assertEqual(len(status), 3, 'Less/more files modified than expected. Entire status:\n%s' % result.output)
218 for line in status:
219 if line.endswith('0001-Change-the-README.patch'):
220 self.assertEqual(line[:3], '?? ', 'Unexpected status in line: %s' % line)
221 elif line.endswith('0002-Add-a-new-file.patch'):
222 self.assertEqual(line[:3], '?? ', 'Unexpected status in line: %s' % line)
223 elif re.search('minicom_[^_]*.bb$', line):
224 self.assertEqual(line[:3], ' M ', 'Unexpected status in line: %s' % line)
225 else:
226 self.assertTrue(False, 'Unexpected modified file in status: %s' % line)
227
228 def test_devtool_extract(self):
229 # Check preconditions
230 workspacedir = os.path.join(self.builddir, 'workspace')
231 self.assertTrue(not os.path.exists(workspacedir), 'This test cannot be run with a workspace directory under the build directory')
232 tempdir = tempfile.mkdtemp(prefix='devtoolqa')
233 # Try devtool extract
234 self.track_for_cleanup(tempdir)
235 self.track_for_cleanup(workspacedir)
236 self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
237 result = runCmd('devtool extract remake %s' % tempdir)
238 self.assertTrue(os.path.exists(os.path.join(tempdir, 'Makefile.am')), 'Extracted source could not be found')
239 self.assertTrue(os.path.isdir(os.path.join(tempdir, '.git')), 'git repository for external source tree not found')