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, cleanup=False):
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            print(output)
41        except subprocess.CalledProcessError as e:
42            self.fail("Command %s failed with %s" % (cmd, e.output))
43        tasks = []
44        tasklog = builddir + "/task.log"
45        if os.path.exists(tasklog):
46            with open(tasklog, "r") as f:
47                tasks = [line.rstrip() for line in f]
48            if cleanup:
49                os.remove(tasklog)
50        return tasks
51
52    def test_no_setscenevalid(self):
53        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
54            cmd = ["bitbake", "a1"]
55            sstatevalid = ""
56            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
57            expected = ['a1:' + x for x in self.alltasks]
58            self.assertEqual(set(tasks), set(expected))
59
60    def test_single_setscenevalid(self):
61        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
62            cmd = ["bitbake", "a1"]
63            sstatevalid = "a1:do_package"
64            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
65            expected = ['a1:package_setscene', 'a1:fetch', 'a1:unpack', 'a1:patch', 'a1:prepare_recipe_sysroot', 'a1:configure',
66                        'a1:compile', 'a1:install', 'a1:packagedata', 'a1:package_qa', 'a1:package_write_rpm', 'a1:package_write_ipk',
67                        'a1:populate_sysroot', 'a1:build']
68            self.assertEqual(set(tasks), set(expected))
69
70    def test_intermediate_setscenevalid(self):
71        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
72            cmd = ["bitbake", "a1"]
73            sstatevalid = "a1:do_package a1:do_populate_sysroot"
74            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
75            expected = ['a1:package_setscene', 'a1:packagedata', 'a1:package_qa', 'a1:package_write_rpm', 'a1:package_write_ipk',
76                        'a1:populate_sysroot_setscene', 'a1:build']
77            self.assertEqual(set(tasks), set(expected))
78
79    def test_intermediate_notcovered(self):
80        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
81            cmd = ["bitbake", "a1"]
82            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"
83            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
84            expected = ['a1:package_write_ipk_setscene', 'a1:package_write_rpm_setscene', 'a1:packagedata_setscene',
85                        'a1:package_qa_setscene', 'a1:build', 'a1:populate_sysroot_setscene']
86            self.assertEqual(set(tasks), set(expected))
87
88    def test_all_setscenevalid(self):
89        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
90            cmd = ["bitbake", "a1"]
91            sstatevalid = self.a1_sstatevalid
92            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
93            expected = ['a1:package_write_ipk_setscene', 'a1:package_write_rpm_setscene', 'a1:packagedata_setscene',
94                        'a1:package_qa_setscene', 'a1:build', 'a1:populate_sysroot_setscene']
95            self.assertEqual(set(tasks), set(expected))
96
97    def test_no_settasks(self):
98        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
99            cmd = ["bitbake", "a1", "-c", "patch"]
100            sstatevalid = self.a1_sstatevalid
101            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
102            expected = ['a1:fetch', 'a1:unpack', 'a1:patch']
103            self.assertEqual(set(tasks), set(expected))
104
105    def test_mix_covered_notcovered(self):
106        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
107            cmd = ["bitbake", "a1:do_patch", "a1:do_populate_sysroot"]
108            sstatevalid = self.a1_sstatevalid
109            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
110            expected = ['a1:fetch', 'a1:unpack', 'a1:patch', 'a1:populate_sysroot_setscene']
111            self.assertEqual(set(tasks), set(expected))
112
113
114    # Test targets with intermediate setscene tasks alongside a target with no intermediate setscene tasks
115    def test_mixed_direct_tasks_setscene_tasks(self):
116        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
117            cmd = ["bitbake", "c1:do_patch", "a1"]
118            sstatevalid = self.a1_sstatevalid
119            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
120            expected = ['c1:fetch', 'c1:unpack', 'c1:patch', 'a1:package_write_ipk_setscene', 'a1:package_write_rpm_setscene', 'a1:packagedata_setscene',
121                        'a1:package_qa_setscene', 'a1:build', 'a1:populate_sysroot_setscene']
122            self.assertEqual(set(tasks), set(expected))
123
124    # This test slows down the execution of do_package_setscene until after other real tasks have
125    # started running which tests for a bug where tasks were being lost from the buildable list of real
126    # tasks if they weren't in tasks_covered or tasks_notcovered
127    def test_slow_setscene(self):
128        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
129            cmd = ["bitbake", "a1"]
130            sstatevalid = "a1:do_package"
131            slowtasks = "a1:package_setscene"
132            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, slowtasks)
133            expected = ['a1:package_setscene', 'a1:fetch', 'a1:unpack', 'a1:patch', 'a1:prepare_recipe_sysroot', 'a1:configure',
134                        'a1:compile', 'a1:install', 'a1:packagedata', 'a1:package_qa', 'a1:package_write_rpm', 'a1:package_write_ipk',
135                        'a1:populate_sysroot', 'a1:build']
136            self.assertEqual(set(tasks), set(expected))
137
138    def test_setscenewhitelist(self):
139        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
140            cmd = ["bitbake", "a1"]
141            extraenv = {
142                "BB_SETSCENE_ENFORCE" : "1",
143                "BB_SETSCENE_ENFORCE_WHITELIST" : "a1:do_package_write_rpm a1:do_build"
144            }
145            sstatevalid = "a1:do_package a1:do_package_qa a1:do_packagedata a1:do_package_write_ipk a1:do_populate_lic a1:do_populate_sysroot"
146            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv)
147            expected = ['a1:packagedata_setscene', 'a1:package_qa_setscene', 'a1:package_write_ipk_setscene',
148                        'a1:populate_sysroot_setscene', 'a1:package_setscene']
149            self.assertEqual(set(tasks), set(expected))
150
151    # Tests for problems with dependencies between setscene tasks
152    def test_no_setscenevalid_harddeps(self):
153        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
154            cmd = ["bitbake", "d1"]
155            sstatevalid = ""
156            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
157            expected = ['a1:package', 'a1:fetch', 'a1:unpack', 'a1:patch', 'a1:prepare_recipe_sysroot', 'a1:configure',
158                        'a1:compile', 'a1:install', 'a1:packagedata', 'a1:package_write_rpm', 'a1:package_write_ipk',
159                        'a1:populate_sysroot', 'd1:package', 'd1:fetch', 'd1:unpack', 'd1:patch', 'd1:prepare_recipe_sysroot', 'd1:configure',
160                        'd1:compile', 'd1:install', 'd1:packagedata', 'd1:package_qa', 'd1:package_write_rpm', 'd1:package_write_ipk',
161                        'd1:populate_sysroot', 'd1:build']
162            self.assertEqual(set(tasks), set(expected))
163
164    def test_no_setscenevalid_withdeps(self):
165        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
166            cmd = ["bitbake", "b1"]
167            sstatevalid = ""
168            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
169            expected = ['a1:' + x for x in self.alltasks] + ['b1:' + x for x in self.alltasks]
170            expected.remove('a1:build')
171            expected.remove('a1:package_qa')
172            self.assertEqual(set(tasks), set(expected))
173
174    def test_single_a1_setscenevalid_withdeps(self):
175        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
176            cmd = ["bitbake", "b1"]
177            sstatevalid = "a1:do_package"
178            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
179            expected = ['a1:package_setscene', 'a1:fetch', 'a1:unpack', 'a1:patch', 'a1:prepare_recipe_sysroot', 'a1:configure',
180                        'a1:compile', 'a1:install', 'a1:packagedata', 'a1:package_write_rpm', 'a1:package_write_ipk',
181                        'a1:populate_sysroot'] + ['b1:' + x for x in self.alltasks]
182            self.assertEqual(set(tasks), set(expected))
183
184    def test_single_b1_setscenevalid_withdeps(self):
185        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
186            cmd = ["bitbake", "b1"]
187            sstatevalid = "b1:do_package"
188            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
189            expected = ['a1:package', 'a1:fetch', 'a1:unpack', 'a1:patch', 'a1:prepare_recipe_sysroot', 'a1:configure',
190                        'a1:compile', 'a1:install', 'a1:packagedata', 'a1:package_write_rpm', 'a1:package_write_ipk',
191                        'a1:populate_sysroot', 'b1:package_setscene'] + ['b1:' + x for x in self.alltasks]
192            expected.remove('b1:package')
193            self.assertEqual(set(tasks), set(expected))
194
195    def test_intermediate_setscenevalid_withdeps(self):
196        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
197            cmd = ["bitbake", "b1"]
198            sstatevalid = "a1:do_package a1:do_populate_sysroot b1:do_package"
199            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
200            expected = ['a1:package_setscene', 'a1:packagedata', 'a1:package_write_rpm', 'a1:package_write_ipk',
201                        'a1:populate_sysroot_setscene', 'b1:package_setscene'] + ['b1:' + x for x in self.alltasks]
202            expected.remove('b1:package')
203            self.assertEqual(set(tasks), set(expected))
204
205    def test_all_setscenevalid_withdeps(self):
206        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
207            cmd = ["bitbake", "b1"]
208            sstatevalid = self.a1_sstatevalid + " " + self.b1_sstatevalid
209            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid)
210            expected = ['a1:package_write_ipk_setscene', 'a1:package_write_rpm_setscene', 'a1:packagedata_setscene',
211                        'b1:build', 'a1:populate_sysroot_setscene', 'b1:package_write_ipk_setscene', 'b1:package_write_rpm_setscene',
212                        'b1:packagedata_setscene', 'b1:package_qa_setscene', 'b1:populate_sysroot_setscene']
213            self.assertEqual(set(tasks), set(expected))
214
215    def test_multiconfig_setscene_optimise(self):
216        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
217            extraenv = {
218                "BBMULTICONFIG" : "mc1 mc2",
219                "BB_SIGNATURE_HANDLER" : "basic"
220            }
221            cmd = ["bitbake", "b1", "mc:mc1:b1", "mc:mc2:b1"]
222            setscenetasks = ['package_write_ipk_setscene', 'package_write_rpm_setscene', 'packagedata_setscene',
223                             'populate_sysroot_setscene', 'package_qa_setscene']
224            sstatevalid = ""
225            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv)
226            expected = ['a1:' + x for x in self.alltasks] + ['b1:' + x for x in self.alltasks] + \
227                       ['mc1:b1:' + x for x in setscenetasks] + ['mc1:a1:' + x for x in setscenetasks] + \
228                       ['mc2:b1:' + x for x in setscenetasks] + ['mc2:a1:' + x for x in setscenetasks] + \
229                       ['mc1:b1:build', 'mc2:b1:build']
230            for x in ['mc1:a1:package_qa_setscene', 'mc2:a1:package_qa_setscene', 'a1:build', 'a1:package_qa']:
231                expected.remove(x)
232            self.assertEqual(set(tasks), set(expected))
233
234
235    def test_hashserv_single(self):
236        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
237            extraenv = {
238                "BB_HASHSERVE" : "localhost:0",
239                "BB_SIGNATURE_HANDLER" : "TestEquivHash"
240            }
241            cmd = ["bitbake", "a1", "b1"]
242            setscenetasks = ['package_write_ipk_setscene', 'package_write_rpm_setscene', 'packagedata_setscene',
243                             'populate_sysroot_setscene', 'package_qa_setscene']
244            sstatevalid = ""
245            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True)
246            expected = ['a1:' + x for x in self.alltasks] + ['b1:' + x for x in self.alltasks]
247            self.assertEqual(set(tasks), set(expected))
248            cmd = ["bitbake", "a1", "-c", "install", "-f"]
249            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True)
250            expected = ['a1:install']
251            self.assertEqual(set(tasks), set(expected))
252            cmd = ["bitbake", "a1", "b1"]
253            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True)
254            expected = ['a1:populate_sysroot', 'a1:package', 'a1:package_write_rpm_setscene', 'a1:packagedata_setscene',
255                        'a1:package_write_ipk_setscene', 'a1:package_qa_setscene']
256            self.assertEqual(set(tasks), set(expected))
257
258    def test_hashserv_double(self):
259        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
260            extraenv = {
261                "BB_HASHSERVE" : "localhost:0",
262                "BB_SIGNATURE_HANDLER" : "TestEquivHash"
263            }
264            cmd = ["bitbake", "a1", "b1", "e1"]
265            setscenetasks = ['package_write_ipk_setscene', 'package_write_rpm_setscene', 'packagedata_setscene',
266                             'populate_sysroot_setscene', 'package_qa_setscene']
267            sstatevalid = ""
268            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True)
269            expected = ['a1:' + x for x in self.alltasks] + ['b1:' + x for x in self.alltasks] + ['e1:' + x for x in self.alltasks]
270            self.assertEqual(set(tasks), set(expected))
271            cmd = ["bitbake", "a1", "b1", "-c", "install", "-fn"]
272            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True)
273            cmd = ["bitbake", "e1"]
274            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True)
275            expected = ['a1:package', 'a1:install', 'b1:package', 'b1:install', 'a1:populate_sysroot', 'b1:populate_sysroot',
276                        'a1:package_write_ipk_setscene', 'b1:packagedata_setscene', 'b1:package_write_rpm_setscene',
277                        'a1:package_write_rpm_setscene', 'b1:package_write_ipk_setscene', 'a1:packagedata_setscene']
278            self.assertEqual(set(tasks), set(expected))
279
280
281    def test_hashserv_multiple_setscene(self):
282        # Runs e1:do_package_setscene twice
283        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
284            extraenv = {
285                "BB_HASHSERVE" : "localhost:0",
286                "BB_SIGNATURE_HANDLER" : "TestEquivHash"
287            }
288            cmd = ["bitbake", "a1", "b1", "e1"]
289            setscenetasks = ['package_write_ipk_setscene', 'package_write_rpm_setscene', 'packagedata_setscene',
290                             'populate_sysroot_setscene', 'package_qa_setscene']
291            sstatevalid = ""
292            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True)
293            expected = ['a1:' + x for x in self.alltasks] + ['b1:' + x for x in self.alltasks] + ['e1:' + x for x in self.alltasks]
294            self.assertEqual(set(tasks), set(expected))
295            cmd = ["bitbake", "a1", "b1", "-c", "install", "-fn"]
296            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True)
297            cmd = ["bitbake", "e1"]
298            sstatevalid = "e1:do_package"
299            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True, slowtasks="a1:populate_sysroot b1:populate_sysroot")
300            expected = ['a1:package', 'a1:install', 'b1:package', 'b1:install', 'a1:populate_sysroot', 'b1:populate_sysroot',
301                        'a1:package_write_ipk_setscene', 'b1:packagedata_setscene', 'b1:package_write_rpm_setscene',
302                        'a1:package_write_rpm_setscene', 'b1:package_write_ipk_setscene', 'a1:packagedata_setscene',
303                        'e1:package_setscene']
304            self.assertEqual(set(tasks), set(expected))
305            for i in expected:
306                if i in ["e1:package_setscene"]:
307                    self.assertEqual(tasks.count(i), 4, "%s not in task list four times" % i)
308                else:
309                    self.assertEqual(tasks.count(i), 1, "%s not in task list once" % i)
310
311    def test_hashserv_partial_match(self):
312        # e1:do_package matches initial built but not second hash value
313        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
314            extraenv = {
315                "BB_HASHSERVE" : "localhost:0",
316                "BB_SIGNATURE_HANDLER" : "TestEquivHash"
317            }
318            cmd = ["bitbake", "a1", "b1"]
319            setscenetasks = ['package_write_ipk_setscene', 'package_write_rpm_setscene', 'packagedata_setscene',
320                             'populate_sysroot_setscene', 'package_qa_setscene']
321            sstatevalid = ""
322            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True)
323            expected = ['a1:' + x for x in self.alltasks] + ['b1:' + x for x in self.alltasks]
324            self.assertEqual(set(tasks), set(expected))
325            with open(tempdir + "/stamps/a1.do_install.taint", "w") as f:
326               f.write("d460a29e-903f-4b76-a96b-3bcc22a65994")
327            with open(tempdir + "/stamps/b1.do_install.taint", "w") as f:
328               f.write("ed36d46a-2977-458a-b3de-eef885bc1817")
329            cmd = ["bitbake", "e1"]
330            sstatevalid = "e1:do_package:685e69a026b2f029483fdefe6a11e1e06641dd2a0f6f86e27b9b550f8f21229d"
331            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True)
332            expected = ['a1:package', 'a1:install', 'b1:package', 'b1:install', 'a1:populate_sysroot', 'b1:populate_sysroot',
333                        'a1:package_write_ipk_setscene', 'b1:packagedata_setscene', 'b1:package_write_rpm_setscene',
334                        'a1:package_write_rpm_setscene', 'b1:package_write_ipk_setscene', 'a1:packagedata_setscene',
335                        'e1:package_setscene'] + ['e1:' + x for x in self.alltasks]
336            expected.remove('e1:package')
337            self.assertEqual(set(tasks), set(expected))
338
339    def test_hashserv_partial_match2(self):
340        # e1:do_package + e1:do_populate_sysroot matches initial built but not second hash value
341        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
342            extraenv = {
343                "BB_HASHSERVE" : "localhost:0",
344                "BB_SIGNATURE_HANDLER" : "TestEquivHash"
345            }
346            cmd = ["bitbake", "a1", "b1"]
347            setscenetasks = ['package_write_ipk_setscene', 'package_write_rpm_setscene', 'packagedata_setscene',
348                             'populate_sysroot_setscene', 'package_qa_setscene']
349            sstatevalid = ""
350            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True)
351            expected = ['a1:' + x for x in self.alltasks] + ['b1:' + x for x in self.alltasks]
352            self.assertEqual(set(tasks), set(expected))
353            with open(tempdir + "/stamps/a1.do_install.taint", "w") as f:
354               f.write("d460a29e-903f-4b76-a96b-3bcc22a65994")
355            with open(tempdir + "/stamps/b1.do_install.taint", "w") as f:
356               f.write("ed36d46a-2977-458a-b3de-eef885bc1817")
357            cmd = ["bitbake", "e1"]
358            sstatevalid = "e1:do_package:685e69a026b2f029483fdefe6a11e1e06641dd2a0f6f86e27b9b550f8f21229d e1:do_populate_sysroot:ef7dc0e2dd55d0534e75cba50731ff42f949818b6f29a65d72bc05856e56711d"
359            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True)
360            expected = ['a1:package', 'a1:install', 'b1:package', 'b1:install', 'a1:populate_sysroot', 'b1:populate_sysroot',
361                        'a1:package_write_ipk_setscene', 'b1:packagedata_setscene', 'b1:package_write_rpm_setscene',
362                        'a1:package_write_rpm_setscene', 'b1:package_write_ipk_setscene', 'a1:packagedata_setscene',
363                        'e1:package_setscene', 'e1:populate_sysroot_setscene', 'e1:build', 'e1:package_qa', 'e1:package_write_rpm', 'e1:package_write_ipk', 'e1:packagedata']
364            self.assertEqual(set(tasks), set(expected))
365
366    def test_hashserv_partial_match3(self):
367        # e1:do_package is valid for a1 but not after b1
368        # In former buggy code, this triggered e1:do_fetch, then e1:do_populate_sysroot to run
369        # with none of the intermediate tasks which is a serious bug
370        with tempfile.TemporaryDirectory(prefix="runqueuetest") as tempdir:
371            extraenv = {
372                "BB_HASHSERVE" : "localhost:0",
373                "BB_SIGNATURE_HANDLER" : "TestEquivHash"
374            }
375            cmd = ["bitbake", "a1", "b1"]
376            setscenetasks = ['package_write_ipk_setscene', 'package_write_rpm_setscene', 'packagedata_setscene',
377                             'populate_sysroot_setscene', 'package_qa_setscene']
378            sstatevalid = ""
379            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True)
380            expected = ['a1:' + x for x in self.alltasks] + ['b1:' + x for x in self.alltasks]
381            self.assertEqual(set(tasks), set(expected))
382            with open(tempdir + "/stamps/a1.do_install.taint", "w") as f:
383               f.write("d460a29e-903f-4b76-a96b-3bcc22a65994")
384            with open(tempdir + "/stamps/b1.do_install.taint", "w") as f:
385               f.write("ed36d46a-2977-458a-b3de-eef885bc1817")
386            cmd = ["bitbake", "e1", "-DD"]
387            sstatevalid = "e1:do_package:af056eae12a733a6a8c4f4da8c6757e588e13565852c94e2aad4d953a3989c13 e1:do_package:a3677703db82b22d28d57c1820a47851dd780104580863f5bd32e66e003a779d"
388            tasks = self.run_bitbakecmd(cmd, tempdir, sstatevalid, extraenv=extraenv, cleanup=True, slowtasks="e1:fetch b1:install")
389            expected = ['a1:package', 'a1:install', 'b1:package', 'b1:install', 'a1:populate_sysroot', 'b1:populate_sysroot',
390                        'a1:package_write_ipk_setscene', 'b1:packagedata_setscene', 'b1:package_write_rpm_setscene',
391                        'a1:package_write_rpm_setscene', 'b1:package_write_ipk_setscene', 'a1:packagedata_setscene',
392                        'e1:package_setscene']  + ['e1:' + x for x in self.alltasks]
393            expected.remove('e1:package')
394            self.assertEqual(set(tasks), set(expected))
395
396
397