diff options
Diffstat (limited to 'meta/lib/oeqa/selftest/devtool.py')
-rw-r--r-- | meta/lib/oeqa/selftest/devtool.py | 157 |
1 files changed, 156 insertions, 1 deletions
diff --git a/meta/lib/oeqa/selftest/devtool.py b/meta/lib/oeqa/selftest/devtool.py index 0b305c893e..974333f555 100644 --- a/meta/lib/oeqa/selftest/devtool.py +++ b/meta/lib/oeqa/selftest/devtool.py | |||
@@ -5,10 +5,11 @@ import re | |||
5 | import shutil | 5 | import shutil |
6 | import tempfile | 6 | import tempfile |
7 | import glob | 7 | import glob |
8 | import fnmatch | ||
8 | 9 | ||
9 | import oeqa.utils.ftools as ftools | 10 | import oeqa.utils.ftools as ftools |
10 | from oeqa.selftest.base import oeSelfTest | 11 | from oeqa.selftest.base import oeSelfTest |
11 | from oeqa.utils.commands import runCmd, bitbake, get_bb_var, create_temp_layer, runqemu | 12 | from oeqa.utils.commands import runCmd, bitbake, get_bb_var, create_temp_layer, runqemu, get_test_layer |
12 | from oeqa.utils.decorators import testcase | 13 | from oeqa.utils.decorators import testcase |
13 | 14 | ||
14 | class DevtoolBase(oeSelfTest): | 15 | class DevtoolBase(oeSelfTest): |
@@ -1189,3 +1190,157 @@ class DevtoolTests(DevtoolBase): | |||
1189 | s = "Microsoft Made No Profit From Anyone's Zunes Yo" | 1190 | s = "Microsoft Made No Profit From Anyone's Zunes Yo" |
1190 | result = runCmd("devtool --quiet selftest-reverse \"%s\"" % s) | 1191 | result = runCmd("devtool --quiet selftest-reverse \"%s\"" % s) |
1191 | self.assertEqual(result.output, s[::-1]) | 1192 | self.assertEqual(result.output, s[::-1]) |
1193 | |||
1194 | def _setup_test_devtool_finish_upgrade(self): | ||
1195 | # Check preconditions | ||
1196 | self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory') | ||
1197 | self.track_for_cleanup(self.workspacedir) | ||
1198 | self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') | ||
1199 | # Use a "real" recipe from meta-selftest | ||
1200 | recipe = 'devtool-upgrade-test1' | ||
1201 | oldversion = '1.5.3' | ||
1202 | newversion = '1.6.0' | ||
1203 | oldrecipefile = get_bb_var('FILE', recipe) | ||
1204 | recipedir = os.path.dirname(oldrecipefile) | ||
1205 | result = runCmd('git status --porcelain .', cwd=recipedir) | ||
1206 | if result.output.strip(): | ||
1207 | self.fail('Recipe directory for %s contains uncommitted changes' % recipe) | ||
1208 | tempdir = tempfile.mkdtemp(prefix='devtoolqa') | ||
1209 | self.track_for_cleanup(tempdir) | ||
1210 | # Check that recipe is not already under devtool control | ||
1211 | result = runCmd('devtool status') | ||
1212 | self.assertNotIn(recipe, result.output) | ||
1213 | # Do the upgrade | ||
1214 | result = runCmd('devtool upgrade %s %s -V %s' % (recipe, tempdir, newversion)) | ||
1215 | # Check devtool status and make sure recipe is present | ||
1216 | result = runCmd('devtool status') | ||
1217 | self.assertIn(recipe, result.output) | ||
1218 | self.assertIn(tempdir, result.output) | ||
1219 | # Make a change to the source | ||
1220 | result = runCmd('sed -i \'/^#include "pv.h"/a \\/* Here is a new comment *\\/\' src/pv/number.c', cwd=tempdir) | ||
1221 | result = runCmd('git status --porcelain', cwd=tempdir) | ||
1222 | self.assertIn('M src/pv/number.c', result.output) | ||
1223 | result = runCmd('git commit src/pv/number.c -m "Add a comment to the code"', cwd=tempdir) | ||
1224 | # Check if patch is there | ||
1225 | recipedir = os.path.dirname(oldrecipefile) | ||
1226 | olddir = os.path.join(recipedir, recipe + '-' + oldversion) | ||
1227 | patchfn = '0001-Add-a-note-line-to-the-quick-reference.patch' | ||
1228 | self.assertTrue(os.path.exists(os.path.join(olddir, patchfn)), 'Original patch file does not exist') | ||
1229 | return recipe, oldrecipefile, recipedir, olddir, newversion, patchfn | ||
1230 | |||
1231 | def test_devtool_finish_upgrade_origlayer(self): | ||
1232 | recipe, oldrecipefile, recipedir, olddir, newversion, patchfn = self._setup_test_devtool_finish_upgrade() | ||
1233 | # Ensure the recipe is where we think it should be (so that cleanup doesn't trash things) | ||
1234 | self.assertIn('/meta-selftest/', recipedir) | ||
1235 | # Try finish to the original layer | ||
1236 | self.add_command_to_tearDown('rm -rf %s ; cd %s ; git checkout %s' % (recipedir, os.path.dirname(recipedir), recipedir)) | ||
1237 | result = runCmd('devtool finish %s meta-selftest' % recipe) | ||
1238 | result = runCmd('devtool status') | ||
1239 | self.assertNotIn(recipe, result.output, 'Recipe should have been reset by finish but wasn\'t') | ||
1240 | self.assertFalse(os.path.exists(os.path.join(self.workspacedir, 'recipes', recipe)), 'Recipe directory should not exist after finish') | ||
1241 | self.assertFalse(os.path.exists(oldrecipefile), 'Old recipe file should have been deleted but wasn\'t') | ||
1242 | self.assertFalse(os.path.exists(os.path.join(olddir, patchfn)), 'Old patch file should have been deleted but wasn\'t') | ||
1243 | newrecipefile = os.path.join(recipedir, '%s_%s.bb' % (recipe, newversion)) | ||
1244 | newdir = os.path.join(recipedir, recipe + '-' + newversion) | ||
1245 | self.assertTrue(os.path.exists(newrecipefile), 'New recipe file should have been copied into existing layer but wasn\'t') | ||
1246 | self.assertTrue(os.path.exists(os.path.join(newdir, patchfn)), 'Patch file should have been copied into new directory but wasn\'t') | ||
1247 | self.assertTrue(os.path.exists(os.path.join(newdir, '0002-Add-a-comment-to-the-code.patch')), 'New patch file should have been created but wasn\'t') | ||
1248 | |||
1249 | def test_devtool_finish_upgrade_otherlayer(self): | ||
1250 | recipe, oldrecipefile, recipedir, olddir, newversion, patchfn = self._setup_test_devtool_finish_upgrade() | ||
1251 | # Ensure the recipe is where we think it should be (so that cleanup doesn't trash things) | ||
1252 | self.assertIn('/meta-selftest/', recipedir) | ||
1253 | # Try finish to a different layer - should create a bbappend | ||
1254 | # This cleanup isn't strictly necessary but do it anyway just in case it goes wrong and writes to here | ||
1255 | self.add_command_to_tearDown('rm -rf %s ; cd %s ; git checkout %s' % (recipedir, os.path.dirname(recipedir), recipedir)) | ||
1256 | oe_core_dir = os.path.join(get_bb_var('COREBASE'), 'meta') | ||
1257 | newrecipedir = os.path.join(oe_core_dir, 'recipes-test', 'devtool') | ||
1258 | newrecipefile = os.path.join(newrecipedir, '%s_%s.bb' % (recipe, newversion)) | ||
1259 | self.track_for_cleanup(newrecipedir) | ||
1260 | result = runCmd('devtool finish %s oe-core' % recipe) | ||
1261 | result = runCmd('devtool status') | ||
1262 | self.assertNotIn(recipe, result.output, 'Recipe should have been reset by finish but wasn\'t') | ||
1263 | self.assertFalse(os.path.exists(os.path.join(self.workspacedir, 'recipes', recipe)), 'Recipe directory should not exist after finish') | ||
1264 | self.assertTrue(os.path.exists(oldrecipefile), 'Old recipe file should not have been deleted') | ||
1265 | self.assertTrue(os.path.exists(os.path.join(olddir, patchfn)), 'Old patch file should not have been deleted') | ||
1266 | newdir = os.path.join(newrecipedir, recipe + '-' + newversion) | ||
1267 | self.assertTrue(os.path.exists(newrecipefile), 'New recipe file should have been copied into existing layer but wasn\'t') | ||
1268 | self.assertTrue(os.path.exists(os.path.join(newdir, patchfn)), 'Patch file should have been copied into new directory but wasn\'t') | ||
1269 | self.assertTrue(os.path.exists(os.path.join(newdir, '0002-Add-a-comment-to-the-code.patch')), 'New patch file should have been created but wasn\'t') | ||
1270 | |||
1271 | def _setup_test_devtool_finish_modify(self): | ||
1272 | # Check preconditions | ||
1273 | self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory') | ||
1274 | # Try modifying a recipe | ||
1275 | self.track_for_cleanup(self.workspacedir) | ||
1276 | recipe = 'mdadm' | ||
1277 | oldrecipefile = get_bb_var('FILE', recipe) | ||
1278 | recipedir = os.path.dirname(oldrecipefile) | ||
1279 | result = runCmd('git status --porcelain .', cwd=recipedir) | ||
1280 | if result.output.strip(): | ||
1281 | self.fail('Recipe directory for %s contains uncommitted changes' % recipe) | ||
1282 | tempdir = tempfile.mkdtemp(prefix='devtoolqa') | ||
1283 | self.track_for_cleanup(tempdir) | ||
1284 | self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') | ||
1285 | result = runCmd('devtool modify %s %s' % (recipe, tempdir)) | ||
1286 | self.assertTrue(os.path.exists(os.path.join(tempdir, 'Makefile')), 'Extracted source could not be found') | ||
1287 | # Test devtool status | ||
1288 | result = runCmd('devtool status') | ||
1289 | self.assertIn(recipe, result.output) | ||
1290 | self.assertIn(tempdir, result.output) | ||
1291 | # Make a change to the source | ||
1292 | result = runCmd('sed -i \'/^#include "mdadm.h"/a \\/* Here is a new comment *\\/\' maps.c', cwd=tempdir) | ||
1293 | result = runCmd('git status --porcelain', cwd=tempdir) | ||
1294 | self.assertIn('M maps.c', result.output) | ||
1295 | result = runCmd('git commit maps.c -m "Add a comment to the code"', cwd=tempdir) | ||
1296 | for entry in os.listdir(recipedir): | ||
1297 | filesdir = os.path.join(recipedir, entry) | ||
1298 | if os.path.isdir(filesdir): | ||
1299 | break | ||
1300 | else: | ||
1301 | self.fail('Unable to find recipe files directory for %s' % recipe) | ||
1302 | return recipe, oldrecipefile, recipedir, filesdir | ||
1303 | |||
1304 | def test_devtool_finish_modify_origlayer(self): | ||
1305 | recipe, oldrecipefile, recipedir, filesdir = self._setup_test_devtool_finish_modify() | ||
1306 | # Ensure the recipe is where we think it should be (so that cleanup doesn't trash things) | ||
1307 | self.assertIn('/meta/', recipedir) | ||
1308 | # Try finish to the original layer | ||
1309 | self.add_command_to_tearDown('rm -rf %s ; cd %s ; git checkout %s' % (recipedir, os.path.dirname(recipedir), recipedir)) | ||
1310 | result = runCmd('devtool finish %s meta' % recipe) | ||
1311 | result = runCmd('devtool status') | ||
1312 | self.assertNotIn(recipe, result.output, 'Recipe should have been reset by finish but wasn\'t') | ||
1313 | self.assertFalse(os.path.exists(os.path.join(self.workspacedir, 'recipes', recipe)), 'Recipe directory should not exist after finish') | ||
1314 | expected_status = [(' M', '.*/%s$' % os.path.basename(oldrecipefile)), | ||
1315 | ('??', '.*/.*-Add-a-comment-to-the-code.patch$')] | ||
1316 | self._check_repo_status(recipedir, expected_status) | ||
1317 | |||
1318 | def test_devtool_finish_modify_otherlayer(self): | ||
1319 | recipe, oldrecipefile, recipedir, filesdir = self._setup_test_devtool_finish_modify() | ||
1320 | # Ensure the recipe is where we think it should be (so that cleanup doesn't trash things) | ||
1321 | self.assertIn('/meta/', recipedir) | ||
1322 | relpth = os.path.relpath(recipedir, os.path.join(get_bb_var('COREBASE'), 'meta')) | ||
1323 | appenddir = os.path.join(get_test_layer(), relpth) | ||
1324 | self.track_for_cleanup(appenddir) | ||
1325 | # Try finish to the original layer | ||
1326 | self.add_command_to_tearDown('rm -rf %s ; cd %s ; git checkout %s' % (recipedir, os.path.dirname(recipedir), recipedir)) | ||
1327 | result = runCmd('devtool finish %s meta-selftest' % recipe) | ||
1328 | result = runCmd('devtool status') | ||
1329 | self.assertNotIn(recipe, result.output, 'Recipe should have been reset by finish but wasn\'t') | ||
1330 | self.assertFalse(os.path.exists(os.path.join(self.workspacedir, 'recipes', recipe)), 'Recipe directory should not exist after finish') | ||
1331 | result = runCmd('git status --porcelain .', cwd=recipedir) | ||
1332 | if result.output.strip(): | ||
1333 | self.fail('Recipe directory for %s contains the following unexpected changes after finish:\n%s' % (recipe, result.output.strip())) | ||
1334 | appendfile = os.path.join(appenddir, os.path.splitext(os.path.basename(oldrecipefile))[0] + '.bbappend') | ||
1335 | self.assertTrue(os.path.exists(appendfile), 'bbappend %s should have been created but wasn\'t' % appendfile) | ||
1336 | newdir = os.path.join(appenddir, recipe) | ||
1337 | files = os.listdir(newdir) | ||
1338 | foundpatch = None | ||
1339 | for fn in files: | ||
1340 | if fnmatch.fnmatch(fn, '*-Add-a-comment-to-the-code.patch'): | ||
1341 | foundpatch = fn | ||
1342 | if not foundpatch: | ||
1343 | self.fail('No patch file created next to bbappend') | ||
1344 | files.remove(foundpatch) | ||
1345 | if files: | ||
1346 | self.fail('Unexpected file(s) copied next to bbappend: %s' % ', '.join(files)) | ||