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 bb 11import os 12import tempfile 13import subprocess 14 15# 16# TODO: 17# Add tests on task ordering (X happens before Y after Z) 18# 19 20class RunQueueTests(unittest.TestCase): 21 22 alltasks = ['package', 'fetch', 'unpack', 'patch', 'prepare_recipe_sysroot', 'configure', 23 'compile', 'install', 'packagedata', 'package_qa', 'package_write_rpm', 'package_write_ipk', 24 'populate_sysroot', 'build'] 25 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" 26 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" 27 28 def run_bitbakecmd(self, cmd, builddir, sstatevalid="", slowtasks="", extraenv=None): 29 env = os.environ.copy() 30 env["BBPATH"] = os.path.realpath(os.path.join(os.path.dirname(__file__), "runqueue-tests")) 31 env["BB_ENV_EXTRAWHITE"] = "SSTATEVALID SLOWTASKS" 32 env["SSTATEVALID"] = sstatevalid 33 env["SLOWTASKS"] = slowtasks 34 if extraenv: 35 for k in extraenv: 36 env[k] = extraenv[k] 37 env["BB_ENV_EXTRAWHITE"] = env["BB_ENV_EXTRAWHITE"] + " " + k 38 try: 39 output = subprocess.check_output(cmd, env=env, stderr=subprocess.STDOUT,universal_newlines=True, cwd=builddir) 40 except subprocess.CalledProcessError as e: 41 self.fail("Command %s failed with %s" % (cmd, e.output)) 42 tasks = [] 43 with open(builddir + "/task.log", "r") as f: 44 tasks = [line.rstrip() for line in f] 45 return tasks 46 47 def test_no_setscenevalid(self): 48 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 49 cmd = ["bitbake", "a1"] 50 sstatevalid = "" 51 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 52 expected = ['a1:' + x for x in self.alltasks] 53 self.assertEqual(set(tasks), set(expected)) 54 55 def test_single_setscenevalid(self): 56 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 57 cmd = ["bitbake", "a1"] 58 sstatevalid = "a1:do_package" 59 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 60 expected = ['a1:package_setscene', 'a1:fetch', 'a1:unpack', 'a1:patch', 'a1:prepare_recipe_sysroot', 'a1:configure', 61 'a1:compile', 'a1:install', 'a1:packagedata', 'a1:package_qa', 'a1:package_write_rpm', 'a1:package_write_ipk', 62 'a1:populate_sysroot', 'a1:build'] 63 self.assertEqual(set(tasks), set(expected)) 64 65 def test_intermediate_setscenevalid(self): 66 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 67 cmd = ["bitbake", "a1"] 68 sstatevalid = "a1:do_package a1:do_populate_sysroot" 69 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 70 expected = ['a1:package_setscene', 'a1:packagedata', 'a1:package_qa', 'a1:package_write_rpm', 'a1:package_write_ipk', 71 'a1:populate_sysroot_setscene', 'a1:build'] 72 self.assertEqual(set(tasks), set(expected)) 73 74 def test_intermediate_notcovered(self): 75 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 76 cmd = ["bitbake", "a1"] 77 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" 78 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 79 expected = ['a1:package_write_ipk_setscene', 'a1:package_write_rpm_setscene', 'a1:packagedata_setscene', 80 'a1:package_qa_setscene', 'a1:build', 'a1:populate_sysroot_setscene'] 81 self.assertEqual(set(tasks), set(expected)) 82 83 def test_all_setscenevalid(self): 84 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 85 cmd = ["bitbake", "a1"] 86 sstatevalid = self.a1_sstatevalid 87 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 88 expected = ['a1:package_write_ipk_setscene', 'a1:package_write_rpm_setscene', 'a1:packagedata_setscene', 89 'a1:package_qa_setscene', 'a1:build', 'a1:populate_sysroot_setscene'] 90 self.assertEqual(set(tasks), set(expected)) 91 92 def test_no_settasks(self): 93 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 94 cmd = ["bitbake", "a1", "-c", "patch"] 95 sstatevalid = self.a1_sstatevalid 96 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 97 expected = ['a1:fetch', 'a1:unpack', 'a1:patch'] 98 self.assertEqual(set(tasks), set(expected)) 99 100 def test_mix_covered_notcovered(self): 101 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 102 cmd = ["bitbake", "a1:do_patch", "a1:do_populate_sysroot"] 103 sstatevalid = self.a1_sstatevalid 104 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 105 expected = ['a1:fetch', 'a1:unpack', 'a1:patch', 'a1:populate_sysroot_setscene'] 106 self.assertEqual(set(tasks), set(expected)) 107 108 109 # Test targets with intermediate setscene tasks alongside a target with no intermediate setscene tasks 110 def test_mixed_direct_tasks_setscene_tasks(self): 111 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 112 cmd = ["bitbake", "c1:do_patch", "a1"] 113 sstatevalid = self.a1_sstatevalid 114 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 115 expected = ['c1:fetch', 'c1:unpack', 'c1:patch', 'a1:package_write_ipk_setscene', 'a1:package_write_rpm_setscene', 'a1:packagedata_setscene', 116 'a1:package_qa_setscene', 'a1:build', 'a1:populate_sysroot_setscene'] 117 self.assertEqual(set(tasks), set(expected)) 118 119 # This test slows down the execution of do_package_setscene until after other real tasks have 120 # started running which tests for a bug where tasks were being lost from the buildable list of real 121 # tasks if they weren't in tasks_covered or tasks_notcovered 122 def test_slow_setscene(self): 123 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 124 cmd = ["bitbake", "a1"] 125 sstatevalid = "a1:do_package" 126 slowtasks = "a1:package_setscene" 127 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, slowtasks) 128 expected = ['a1:package_setscene', 'a1:fetch', 'a1:unpack', 'a1:patch', 'a1:prepare_recipe_sysroot', 'a1:configure', 129 'a1:compile', 'a1:install', 'a1:packagedata', 'a1:package_qa', 'a1:package_write_rpm', 'a1:package_write_ipk', 130 'a1:populate_sysroot', 'a1:build'] 131 self.assertEqual(set(tasks), set(expected)) 132 133 def test_setscenewhitelist(self): 134 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 135 cmd = ["bitbake", "a1"] 136 extraenv = { 137 "BB_SETSCENE_ENFORCE" : "1", 138 "BB_SETSCENE_ENFORCE_WHITELIST" : "a1:do_package_write_rpm a1:do_build" 139 } 140 sstatevalid = "a1:do_package a1:do_package_qa a1:do_packagedata a1:do_package_write_ipk a1:do_populate_lic a1:do_populate_sysroot" 141 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv) 142 expected = ['a1:packagedata_setscene', 'a1:package_qa_setscene', 'a1:package_write_ipk_setscene', 143 'a1:populate_sysroot_setscene', 'a1:package_setscene'] 144 self.assertEqual(set(tasks), set(expected)) 145 146 # Tests for problems with dependencies between setscene tasks 147 def test_no_setscenevalid_harddeps(self): 148 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 149 cmd = ["bitbake", "d1"] 150 sstatevalid = "" 151 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 152 expected = ['a1:package', 'a1:fetch', 'a1:unpack', 'a1:patch', 'a1:prepare_recipe_sysroot', 'a1:configure', 153 'a1:compile', 'a1:install', 'a1:packagedata', 'a1:package_write_rpm', 'a1:package_write_ipk', 154 'a1:populate_sysroot', 'd1:package', 'd1:fetch', 'd1:unpack', 'd1:patch', 'd1:prepare_recipe_sysroot', 'd1:configure', 155 'd1:compile', 'd1:install', 'd1:packagedata', 'd1:package_qa', 'd1:package_write_rpm', 'd1:package_write_ipk', 156 'd1:populate_sysroot', 'd1:build'] 157 self.assertEqual(set(tasks), set(expected)) 158 159 def test_no_setscenevalid_withdeps(self): 160 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 161 cmd = ["bitbake", "b1"] 162 sstatevalid = "" 163 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 164 expected = ['a1:' + x for x in self.alltasks] + ['b1:' + x for x in self.alltasks] 165 expected.remove('a1:build') 166 expected.remove('a1:package_qa') 167 self.assertEqual(set(tasks), set(expected)) 168 169 def test_single_a1_setscenevalid_withdeps(self): 170 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 171 cmd = ["bitbake", "b1"] 172 sstatevalid = "a1:do_package" 173 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 174 expected = ['a1:package_setscene', 'a1:fetch', 'a1:unpack', 'a1:patch', 'a1:prepare_recipe_sysroot', 'a1:configure', 175 'a1:compile', 'a1:install', 'a1:packagedata', 'a1:package_write_rpm', 'a1:package_write_ipk', 176 'a1:populate_sysroot'] + ['b1:' + x for x in self.alltasks] 177 self.assertEqual(set(tasks), set(expected)) 178 179 def test_single_b1_setscenevalid_withdeps(self): 180 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 181 cmd = ["bitbake", "b1"] 182 sstatevalid = "b1:do_package" 183 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 184 expected = ['a1:package', 'a1:fetch', 'a1:unpack', 'a1:patch', 'a1:prepare_recipe_sysroot', 'a1:configure', 185 'a1:compile', 'a1:install', 'a1:packagedata', 'a1:package_write_rpm', 'a1:package_write_ipk', 186 'a1:populate_sysroot', 'b1:package_setscene'] + ['b1:' + x for x in self.alltasks] 187 expected.remove('b1:package') 188 self.assertEqual(set(tasks), set(expected)) 189 190 def test_intermediate_setscenevalid_withdeps(self): 191 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 192 cmd = ["bitbake", "b1"] 193 sstatevalid = "a1:do_package a1:do_populate_sysroot b1:do_package" 194 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 195 expected = ['a1:package_setscene', 'a1:packagedata', 'a1:package_write_rpm', 'a1:package_write_ipk', 196 'a1:populate_sysroot_setscene', 'b1:package_setscene'] + ['b1:' + x for x in self.alltasks] 197 expected.remove('b1:package') 198 self.assertEqual(set(tasks), set(expected)) 199 200 def test_all_setscenevalid_withdeps(self): 201 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 202 cmd = ["bitbake", "b1"] 203 sstatevalid = self.a1_sstatevalid + " " + self.b1_sstatevalid 204 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid) 205 expected = ['a1:package_write_ipk_setscene', 'a1:package_write_rpm_setscene', 'a1:packagedata_setscene', 206 'b1:build', 'a1:populate_sysroot_setscene', 'b1:package_write_ipk_setscene', 'b1:package_write_rpm_setscene', 207 'b1:packagedata_setscene', 'b1:package_qa_setscene', 'b1:populate_sysroot_setscene'] 208 self.assertEqual(set(tasks), set(expected)) 209 210 def test_multiconfig_setscene_optimise(self): 211 with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir: 212 extraenv = { 213 "BBMULTICONFIG" : "mc1 mc2", 214 "BB_SIGNATURE_HANDLER" : "basic" 215 } 216 cmd = ["bitbake", "b1", "mc:mc1:b1", "mc:mc2:b1"] 217 setscenetasks = ['package_write_ipk_setscene', 'package_write_rpm_setscene', 'packagedata_setscene', 218 'populate_sysroot_setscene', 'package_qa_setscene'] 219 sstatevalid = "" 220 tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv) 221 expected = ['a1:' + x for x in self.alltasks] + ['b1:' + x for x in self.alltasks] + \ 222 ['mc1:b1:' + x for x in setscenetasks] + ['mc1:a1:' + x for x in setscenetasks] + \ 223 ['mc2:b1:' + x for x in setscenetasks] + ['mc2:a1:' + x for x in setscenetasks] + \ 224 ['mc1:b1:build', 'mc2:b1:build'] 225 for x in ['mc1:a1:package_qa_setscene', 'mc2:a1:package_qa_setscene', 'a1:build', 'a1:package_qa']: 226 expected.remove(x) 227 self.assertEqual(set(tasks), set(expected)) 228 229