1# 2# BitBake Tests for runqueue task processing 3# 4# Copyright (C) 2019 Richard Purdie 5# 6# SPDX-License-Identifier: GPL-2.0-only 7# 8 9import unittest 10import os 11import tempfile 12import subprocess 13import sys 14import time 15 16# 17# TODO: 18# Add tests on task ordering (X happens before Y after Z) 19# 20 21class RunQueueTests(unittest.TestCase): 22 23 alltasks = ['package', 'fetch', 'unpack', 'patch', 'prepare_recipe_sysroot', 'configure', 24 'compile', 'install', 'packagedata', 'package_qa', 'package_write_rpm', 'package_write_ipk', 25 'populate_sysroot', 'build'] 26 a1_sstatevalid = "a1:do_package a1:do_package_qa a1:do_packagedata a1:do_package_write_ipk a1:do_package_write_rpm a1:do_populate_lic a1:do_populate_sysroot" 27 b1_sstatevalid = "b1:do_package b1:do_package_qa b1:do_packagedata b1:do_package_write_ipk b1:do_package_write_rpm b1:do_populate_lic b1:do_populate_sysroot" 28 29 def run_bitbakecmd(self, cmd, builddir, sstatevalid="", slowtasks="", extraenv=None, cleanup=False, allowfailure=False): 30 env = os.environ.copy() 31 env["BBPATH"] = os.path.realpath(os.path.join(os.path.dirname(__file__), "runqueue-tests")) 32 env["BB_ENV_PASSTHROUGH_ADDITIONS"] = "SSTATEVALID SLOWTASKS TOPDIR" 33 env["SSTATEVALID"] = sstatevalid 34 env["SLOWTASKS"] = slowtasks 35 env["TOPDIR"] = builddir 36 if extraenv: 37 for k in extraenv: 38 env[k] = extraenv[k] 39 env["BB_ENV_PASSTHROUGH_ADDITIONS"] = env["BB_ENV_PASSTHROUGH_ADDITIONS"] + " " + k 40 try: 41 output = subprocess.check_output(cmd, env=env, stderr=subprocess.STDOUT,universal_newlines=True, cwd=builddir) 42 print(output) 43 except subprocess.CalledProcessError as e: 44 if allowfailure: 45 return e.output 46 self.fail("Command %s failed with %s" % (cmd, e.output)) 47 tasks = [] 48 tasklog = builddir + "/task.log" 49 if os.path.exists(tasklog): 50 with open(tasklog, "r") as f: 51 tasks = [line.rstrip() for line in f] 52 if cleanup: 53 os.remove(tasklog) 54 return tasks 55 56 def test_no_setscenevalid(self): 57 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 58 cmd = ["bitbake", "a1"] 59 sstatevalid = "" 60 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 61 expected = ['a1:' + x for x in self.alltasks] 62 self.assertEqual(set(tasks), set(expected)) 63 64 self.shutdown(tempdir) 65 66 def test_single_setscenevalid(self): 67 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 68 cmd = ["bitbake", "a1"] 69 sstatevalid = "a1:do_package" 70 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 71 expected = ['a1:package_setscene', 'a1:fetch', 'a1:unpack', 'a1:patch', 'a1:prepare_recipe_sysroot', 'a1:configure', 72 'a1:compile', 'a1:install', 'a1:packagedata', 'a1:package_qa', 'a1:package_write_rpm', 'a1:package_write_ipk', 73 'a1:populate_sysroot', 'a1:build'] 74 self.assertEqual(set(tasks), set(expected)) 75 76 self.shutdown(tempdir) 77 78 def test_intermediate_setscenevalid(self): 79 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 80 cmd = ["bitbake", "a1"] 81 sstatevalid = "a1:do_package a1:do_populate_sysroot" 82 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 83 expected = ['a1:package_setscene', 'a1:packagedata', 'a1:package_qa', 'a1:package_write_rpm', 'a1:package_write_ipk', 84 'a1:populate_sysroot_setscene', 'a1:build'] 85 self.assertEqual(set(tasks), set(expected)) 86 87 self.shutdown(tempdir) 88 89 def test_intermediate_notcovered(self): 90 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 91 cmd = ["bitbake", "a1"] 92 sstatevalid = "a1:do_package_qa a1:do_packagedata a1:do_package_write_ipk a1:do_package_write_rpm a1:do_populate_lic a1:do_populate_sysroot" 93 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 94 expected = ['a1:package_write_ipk_setscene', 'a1:package_write_rpm_setscene', 'a1:packagedata_setscene', 95 'a1:package_qa_setscene', 'a1:build', 'a1:populate_sysroot_setscene'] 96 self.assertEqual(set(tasks), set(expected)) 97 98 self.shutdown(tempdir) 99 100 def test_all_setscenevalid(self): 101 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 102 cmd = ["bitbake", "a1"] 103 sstatevalid = self.a1_sstatevalid 104 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 105 expected = ['a1:package_write_ipk_setscene', 'a1:package_write_rpm_setscene', 'a1:packagedata_setscene', 106 'a1:package_qa_setscene', 'a1:build', 'a1:populate_sysroot_setscene'] 107 self.assertEqual(set(tasks), set(expected)) 108 109 self.shutdown(tempdir) 110 111 def test_no_settasks(self): 112 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 113 cmd = ["bitbake", "a1", "-c", "patch"] 114 sstatevalid = self.a1_sstatevalid 115 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 116 expected = ['a1:fetch', 'a1:unpack', 'a1:patch'] 117 self.assertEqual(set(tasks), set(expected)) 118 119 self.shutdown(tempdir) 120 121 def test_mix_covered_notcovered(self): 122 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 123 cmd = ["bitbake", "a1:do_patch", "a1:do_populate_sysroot"] 124 sstatevalid = self.a1_sstatevalid 125 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 126 expected = ['a1:fetch', 'a1:unpack', 'a1:patch', 'a1:populate_sysroot_setscene'] 127 self.assertEqual(set(tasks), set(expected)) 128 129 self.shutdown(tempdir) 130 131 # Test targets with intermediate setscene tasks alongside a target with no intermediate setscene tasks 132 def test_mixed_direct_tasks_setscene_tasks(self): 133 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 134 cmd = ["bitbake", "c1:do_patch", "a1"] 135 sstatevalid = self.a1_sstatevalid 136 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 137 expected = ['c1:fetch', 'c1:unpack', 'c1:patch', 'a1:package_write_ipk_setscene', 'a1:package_write_rpm_setscene', 'a1:packagedata_setscene', 138 'a1:package_qa_setscene', 'a1:build', 'a1:populate_sysroot_setscene'] 139 self.assertEqual(set(tasks), set(expected)) 140 141 self.shutdown(tempdir) 142 143 # This test slows down the execution of do_package_setscene until after other real tasks have 144 # started running which tests for a bug where tasks were being lost from the buildable list of real 145 # tasks if they weren't in tasks_covered or tasks_notcovered 146 def test_slow_setscene(self): 147 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 148 cmd = ["bitbake", "a1"] 149 sstatevalid = "a1:do_package" 150 slowtasks = "a1:package_setscene" 151 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, slowtasks) 152 expected = ['a1:package_setscene', 'a1:fetch', 'a1:unpack', 'a1:patch', 'a1:prepare_recipe_sysroot', 'a1:configure', 153 'a1:compile', 'a1:install', 'a1:packagedata', 'a1:package_qa', 'a1:package_write_rpm', 'a1:package_write_ipk', 154 'a1:populate_sysroot', 'a1:build'] 155 self.assertEqual(set(tasks), set(expected)) 156 157 self.shutdown(tempdir) 158 159 def test_setscene_ignore_tasks(self): 160 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 161 cmd = ["bitbake", "a1"] 162 extraenv = { 163 "BB_SETSCENE_ENFORCE" : "1", 164 "BB_SETSCENE_ENFORCE_IGNORE_TASKS" : "a1:do_package_write_rpm a1:do_build" 165 } 166 sstatevalid = "a1:do_package a1:do_package_qa a1:do_packagedata a1:do_package_write_ipk a1:do_populate_lic a1:do_populate_sysroot" 167 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv) 168 expected = ['a1:packagedata_setscene', 'a1:package_qa_setscene', 'a1:package_write_ipk_setscene', 169 'a1:populate_sysroot_setscene', 'a1:package_setscene'] 170 self.assertEqual(set(tasks), set(expected)) 171 172 self.shutdown(tempdir) 173 174 # Tests for problems with dependencies between setscene tasks 175 def test_no_setscenevalid_harddeps(self): 176 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 177 cmd = ["bitbake", "d1"] 178 sstatevalid = "" 179 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 180 expected = ['a1:package', 'a1:fetch', 'a1:unpack', 'a1:patch', 'a1:prepare_recipe_sysroot', 'a1:configure', 181 'a1:compile', 'a1:install', 'a1:packagedata', 'a1:package_write_rpm', 'a1:package_write_ipk', 182 'a1:populate_sysroot', 'd1:package', 'd1:fetch', 'd1:unpack', 'd1:patch', 'd1:prepare_recipe_sysroot', 'd1:configure', 183 'd1:compile', 'd1:install', 'd1:packagedata', 'd1:package_qa', 'd1:package_write_rpm', 'd1:package_write_ipk', 184 'd1:populate_sysroot', 'd1:build'] 185 self.assertEqual(set(tasks), set(expected)) 186 187 self.shutdown(tempdir) 188 189 def test_no_setscenevalid_withdeps(self): 190 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 191 cmd = ["bitbake", "b1"] 192 sstatevalid = "" 193 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 194 expected = ['a1:' + x for x in self.alltasks] + ['b1:' + x for x in self.alltasks] 195 expected.remove('a1:build') 196 expected.remove('a1:package_qa') 197 self.assertEqual(set(tasks), set(expected)) 198 199 self.shutdown(tempdir) 200 201 def test_single_a1_setscenevalid_withdeps(self): 202 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 203 cmd = ["bitbake", "b1"] 204 sstatevalid = "a1:do_package" 205 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 206 expected = ['a1:package_setscene', 'a1:fetch', 'a1:unpack', 'a1:patch', 'a1:prepare_recipe_sysroot', 'a1:configure', 207 'a1:compile', 'a1:install', 'a1:packagedata', 'a1:package_write_rpm', 'a1:package_write_ipk', 208 'a1:populate_sysroot'] + ['b1:' + x for x in self.alltasks] 209 self.assertEqual(set(tasks), set(expected)) 210 211 self.shutdown(tempdir) 212 213 def test_single_b1_setscenevalid_withdeps(self): 214 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 215 cmd = ["bitbake", "b1"] 216 sstatevalid = "b1:do_package" 217 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 218 expected = ['a1:package', 'a1:fetch', 'a1:unpack', 'a1:patch', 'a1:prepare_recipe_sysroot', 'a1:configure', 219 'a1:compile', 'a1:install', 'a1:packagedata', 'a1:package_write_rpm', 'a1:package_write_ipk', 220 'a1:populate_sysroot', 'b1:package_setscene'] + ['b1:' + x for x in self.alltasks] 221 expected.remove('b1:package') 222 self.assertEqual(set(tasks), set(expected)) 223 224 self.shutdown(tempdir) 225 226 def test_intermediate_setscenevalid_withdeps(self): 227 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 228 cmd = ["bitbake", "b1"] 229 sstatevalid = "a1:do_package a1:do_populate_sysroot b1:do_package" 230 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 231 expected = ['a1:package_setscene', 'a1:packagedata', 'a1:package_write_rpm', 'a1:package_write_ipk', 232 'a1:populate_sysroot_setscene', 'b1:package_setscene'] + ['b1:' + x for x in self.alltasks] 233 expected.remove('b1:package') 234 self.assertEqual(set(tasks), set(expected)) 235 236 self.shutdown(tempdir) 237 238 def test_all_setscenevalid_withdeps(self): 239 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 240 cmd = ["bitbake", "b1"] 241 sstatevalid = self.a1_sstatevalid + " " + self.b1_sstatevalid 242 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 243 expected = ['a1:package_write_ipk_setscene', 'a1:package_write_rpm_setscene', 'a1:packagedata_setscene', 244 'b1:build', 'a1:populate_sysroot_setscene', 'b1:package_write_ipk_setscene', 'b1:package_write_rpm_setscene', 245 'b1:packagedata_setscene', 'b1:package_qa_setscene', 'b1:populate_sysroot_setscene'] 246 self.assertEqual(set(tasks), set(expected)) 247 248 self.shutdown(tempdir) 249 250 def test_multiconfig_setscene_optimise(self): 251 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 252 extraenv = { 253 "BBMULTICONFIG" : "mc-1 mc_2", 254 "BB_SIGNATURE_HANDLER" : "basic" 255 } 256 cmd = ["bitbake", "b1", "mc:mc-1:b1", "mc:mc_2:b1"] 257 setscenetasks = ['package_write_ipk_setscene', 'package_write_rpm_setscene', 'packagedata_setscene', 258 'populate_sysroot_setscene', 'package_qa_setscene'] 259 sstatevalid = "" 260 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv) 261 expected = ['a1:' + x for x in self.alltasks] + ['b1:' + x for x in self.alltasks] + \ 262 ['mc-1:b1:' + x for x in setscenetasks] + ['mc-1:a1:' + x for x in setscenetasks] + \ 263 ['mc_2:b1:' + x for x in setscenetasks] + ['mc_2:a1:' + x for x in setscenetasks] + \ 264 ['mc-1:b1:build', 'mc_2:b1:build'] 265 for x in ['mc-1:a1:package_qa_setscene', 'mc_2:a1:package_qa_setscene', 'a1:build', 'a1:package_qa']: 266 expected.remove(x) 267 self.assertEqual(set(tasks), set(expected)) 268 269 self.shutdown(tempdir) 270 271 def test_multiconfig_bbmask(self): 272 # This test validates that multiconfigs can independently mask off 273 # recipes they do not want with BBMASK. It works by having recipes 274 # that will fail to parse for mc-1 and mc_2, then making each multiconfig 275 # build the one that does parse. This ensures that the recipes are in 276 # each multiconfigs BBFILES, but each is masking only the one that 277 # doesn't parse 278 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 279 extraenv = { 280 "BBMULTICONFIG" : "mc-1 mc_2", 281 "BB_SIGNATURE_HANDLER" : "basic", 282 "EXTRA_BBFILES": "${COREBASE}/recipes/fails-mc/*.bb", 283 } 284 cmd = ["bitbake", "mc:mc-1:fails-mc2", "mc:mc_2:fails-mc1"] 285 self.run_bitbakecmd(cmd, tempdir, "", extraenv=extraenv) 286 287 self.shutdown(tempdir) 288 289 def test_multiconfig_mcdepends(self): 290 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 291 extraenv = { 292 "BBMULTICONFIG" : "mc-1 mc_2", 293 "BB_SIGNATURE_HANDLER" : "basichash", 294 "EXTRA_BBFILES": "${COREBASE}/recipes/fails-mc/*.bb", 295 } 296 tasks = self.run_bitbakecmd(["bitbake", "mc:mc-1:f1"], tempdir, "", extraenv=extraenv, cleanup=True) 297 expected = ["mc-1:f1:%s" % t for t in self.alltasks] + \ 298 ["mc_2:a1:%s" % t for t in self.alltasks] 299 self.assertEqual(set(tasks), set(expected)) 300 301 # A rebuild does nothing 302 tasks = self.run_bitbakecmd(["bitbake", "mc:mc-1:f1"], tempdir, "", extraenv=extraenv, cleanup=True) 303 self.assertEqual(set(tasks), set()) 304 305 # Test that a signature change in the dependent task causes 306 # mcdepends to rebuild 307 tasks = self.run_bitbakecmd(["bitbake", "mc:mc_2:a1", "-c", "compile", "-f"], tempdir, "", extraenv=extraenv, cleanup=True) 308 expected = ["mc_2:a1:compile"] 309 self.assertEqual(set(tasks), set(expected)) 310 311 rerun_tasks = self.alltasks[:] 312 for x in ("fetch", "unpack", "patch", "prepare_recipe_sysroot", "configure", "compile"): 313 rerun_tasks.remove(x) 314 tasks = self.run_bitbakecmd(["bitbake", "mc:mc-1:f1"], tempdir, "", extraenv=extraenv, cleanup=True) 315 expected = ["mc-1:f1:%s" % t for t in rerun_tasks] + \ 316 ["mc_2:a1:%s" % t for t in rerun_tasks] 317 self.assertEqual(set(tasks), set(expected)) 318 319 # Check that a multiconfig that doesn't exist rasies a correct error message 320 error_output = self.run_bitbakecmd(["bitbake", "g1"], tempdir, "", extraenv=extraenv, cleanup=True, allowfailure=True) 321 self.assertIn("non-existent task", error_output) 322 # If the word 'Traceback' or 'KeyError' is in the output we've regressed 323 self.assertNotIn("Traceback", error_output) 324 self.assertNotIn("KeyError", error_output) 325 326 self.shutdown(tempdir) 327 328 def test_hashserv_single(self): 329 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 330 extraenv = { 331 "BB_HASHSERVE" : "auto", 332 "BB_SIGNATURE_HANDLER" : "TestEquivHash" 333 } 334 cmd = ["bitbake", "a1", "b1"] 335 setscenetasks = ['package_write_ipk_setscene', 'package_write_rpm_setscene', 'packagedata_setscene', 336 'populate_sysroot_setscene', 'package_qa_setscene'] 337 sstatevalid = "" 338 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True) 339 expected = ['a1:' + x for x in self.alltasks] + ['b1:' + x for x in self.alltasks] 340 self.assertEqual(set(tasks), set(expected)) 341 cmd = ["bitbake", "a1", "-c", "install", "-f"] 342 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True) 343 expected = ['a1:install'] 344 self.assertEqual(set(tasks), set(expected)) 345 cmd = ["bitbake", "a1", "b1"] 346 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True) 347 expected = ['a1:populate_sysroot', 'a1:package', 'a1:package_write_rpm_setscene', 'a1:packagedata_setscene', 348 'a1:package_write_ipk_setscene', 'a1:package_qa_setscene', 'a1:build'] 349 self.assertEqual(set(tasks), set(expected)) 350 351 self.shutdown(tempdir) 352 353 def test_hashserv_double(self): 354 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 355 extraenv = { 356 "BB_HASHSERVE" : "auto", 357 "BB_SIGNATURE_HANDLER" : "TestEquivHash" 358 } 359 cmd = ["bitbake", "a1", "b1", "e1"] 360 setscenetasks = ['package_write_ipk_setscene', 'package_write_rpm_setscene', 'packagedata_setscene', 361 'populate_sysroot_setscene', 'package_qa_setscene'] 362 sstatevalid = "" 363 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True) 364 expected = ['a1:' + x for x in self.alltasks] + ['b1:' + x for x in self.alltasks] + ['e1:' + x for x in self.alltasks] 365 self.assertEqual(set(tasks), set(expected)) 366 cmd = ["bitbake", "a1", "b1", "-c", "install", "-fn"] 367 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True) 368 cmd = ["bitbake", "e1"] 369 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True) 370 expected = ['a1:package', 'a1:install', 'b1:package', 'b1:install', 'a1:populate_sysroot', 'b1:populate_sysroot', 371 'a1:package_write_ipk_setscene', 'b1:packagedata_setscene', 'b1:package_write_rpm_setscene', 372 'a1:package_write_rpm_setscene', 'b1:package_write_ipk_setscene', 'a1:packagedata_setscene'] 373 self.assertEqual(set(tasks), set(expected)) 374 375 self.shutdown(tempdir) 376 377 def test_hashserv_multiple_setscene(self): 378 # Runs e1:do_package_setscene twice 379 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 380 extraenv = { 381 "BB_HASHSERVE" : "auto", 382 "BB_SIGNATURE_HANDLER" : "TestEquivHash" 383 } 384 cmd = ["bitbake", "a1", "b1", "e1"] 385 setscenetasks = ['package_write_ipk_setscene', 'package_write_rpm_setscene', 'packagedata_setscene', 386 'populate_sysroot_setscene', 'package_qa_setscene'] 387 sstatevalid = "" 388 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True) 389 expected = ['a1:' + x for x in self.alltasks] + ['b1:' + x for x in self.alltasks] + ['e1:' + x for x in self.alltasks] 390 self.assertEqual(set(tasks), set(expected)) 391 cmd = ["bitbake", "a1", "b1", "-c", "install", "-fn"] 392 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True) 393 cmd = ["bitbake", "e1"] 394 sstatevalid = "e1:do_package" 395 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True, slowtasks="a1:populate_sysroot b1:populate_sysroot") 396 expected = ['a1:package', 'a1:install', 'b1:package', 'b1:install', 'a1:populate_sysroot', 'b1:populate_sysroot', 397 'a1:package_write_ipk_setscene', 'b1:packagedata_setscene', 'b1:package_write_rpm_setscene', 398 'a1:package_write_rpm_setscene', 'b1:package_write_ipk_setscene', 'a1:packagedata_setscene', 399 'e1:package_setscene'] 400 self.assertEqual(set(tasks), set(expected)) 401 for i in expected: 402 self.assertEqual(tasks.count(i), 1, "%s not in task list once" % i) 403 404 self.shutdown(tempdir) 405 406 def shutdown(self, tempdir): 407 # Wait for the hashserve socket to disappear else we'll see races with the tempdir cleanup 408 while (os.path.exists(tempdir + "/hashserve.sock") or os.path.exists(tempdir + "cache/hashserv.db-wal") or os.path.exists(tempdir + "/bitbake.lock")): 409 time.sleep(0.5) 410 411