|
1
|
+import os
|
|
2
|
+
|
|
3
|
+import pytest
|
|
4
|
+from tests.testutils import cli, create_repo
|
|
5
|
+
|
|
6
|
+from buildstream import _yaml
|
|
7
|
+
|
|
8
|
+# Project directory
|
|
9
|
+DATA_DIR = os.path.join(
|
|
10
|
+ os.path.dirname(os.path.realpath(__file__)),
|
|
11
|
+ "project",
|
|
12
|
+)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+def create_element(repo, name, path, dependencies, ref=None):
|
|
16
|
+ element = {
|
|
17
|
+ 'kind': 'import',
|
|
18
|
+ 'sources': [
|
|
19
|
+ repo.source_config(ref=ref)
|
|
20
|
+ ],
|
|
21
|
+ 'depends': dependencies
|
|
22
|
+ }
|
|
23
|
+ _yaml.dump(element, os.path.join(path, name))
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+# This tests a variety of scenarios and checks that the order in
|
|
27
|
+# which things are processed remains stable.
|
|
28
|
+#
|
|
29
|
+# This is especially important in order to ensure that our
|
|
30
|
+# depth sorting and optimization of which elements should be
|
|
31
|
+# processed first is doing it's job right, and that we are
|
|
32
|
+# promoting elements to the build queue as soon as possible
|
|
33
|
+#
|
|
34
|
+# Parameters:
|
|
35
|
+# targets (target elements): The targets to invoke bst with
|
|
36
|
+# template (dict): The project template dictionary, for create_element()
|
|
37
|
+# expected (list): A list of element names in the expected order
|
|
38
|
+#
|
|
39
|
+@pytest.mark.datafiles(os.path.join(DATA_DIR))
|
|
40
|
+@pytest.mark.parametrize("target,template,expected", [
|
|
41
|
+ # First simple test
|
|
42
|
+ ('3.bst', {
|
|
43
|
+ '0.bst': ['1.bst'],
|
|
44
|
+ '1.bst': [],
|
|
45
|
+ '2.bst': ['0.bst'],
|
|
46
|
+ '3.bst': ['0.bst', '1.bst', '2.bst']
|
|
47
|
+ }, ['1.bst', '0.bst', '2.bst', '3.bst']),
|
|
48
|
+
|
|
49
|
+ # A more complicated test with build of build dependencies
|
|
50
|
+ ('target.bst', {
|
|
51
|
+ 'a.bst': [],
|
|
52
|
+ 'base.bst': [],
|
|
53
|
+ 'timezones.bst': [],
|
|
54
|
+ 'middleware.bst': [{'filename': 'base.bst', 'type': 'build'}],
|
|
55
|
+ 'app.bst': [{'filename': 'middleware.bst', 'type': 'build'}],
|
|
56
|
+ 'target.bst': ['a.bst', 'base.bst', 'middleware.bst', 'app.bst', 'timezones.bst']
|
|
57
|
+ }, ['base.bst', 'middleware.bst', 'a.bst', 'app.bst', 'timezones.bst', 'target.bst']),
|
|
58
|
+])
|
|
59
|
+@pytest.mark.parametrize("operation", [('show'), ('fetch'), ('build')])
|
|
60
|
+def test_order(cli, datafiles, tmpdir, operation, target, template, expected):
|
|
61
|
+ project = os.path.join(datafiles.dirname, datafiles.basename)
|
|
62
|
+ dev_files_path = os.path.join(project, 'files', 'dev-files')
|
|
63
|
+ element_path = os.path.join(project, 'elements')
|
|
64
|
+
|
|
65
|
+ # FIXME: Remove this when the test passes reliably.
|
|
66
|
+ #
|
|
67
|
+ # There is no reason why the order should not
|
|
68
|
+ # be preserved when the builders is set to 1,
|
|
69
|
+ # the scheduler queue processing still seems to
|
|
70
|
+ # be losing the order.
|
|
71
|
+ #
|
|
72
|
+ if operation == 'build':
|
|
73
|
+ pytest.skip("FIXME: This still only sometimes passes")
|
|
74
|
+
|
|
75
|
+ # Configure to only allow one fetcher at a time, make it easy to
|
|
76
|
+ # determine what is being planned in what order.
|
|
77
|
+ cli.configure({
|
|
78
|
+ 'scheduler': {
|
|
79
|
+ 'fetchers': 1,
|
|
80
|
+ 'builders': 1
|
|
81
|
+ }
|
|
82
|
+ })
|
|
83
|
+
|
|
84
|
+ # Build the project from the template, make import elements
|
|
85
|
+ # all with the same repo
|
|
86
|
+ #
|
|
87
|
+ repo = create_repo('git', str(tmpdir))
|
|
88
|
+ ref = repo.create(dev_files_path)
|
|
89
|
+ for element, dependencies in template.items():
|
|
90
|
+ create_element(repo, element, element_path, dependencies, ref=ref)
|
|
91
|
+ repo.add_commit()
|
|
92
|
+
|
|
93
|
+ # Run test and collect results
|
|
94
|
+ if operation == 'show':
|
|
95
|
+ result = cli.run(args=['show', '--deps', 'plan', '--format', '%{name}', target], project=project, silent=True)
|
|
96
|
+ result.assert_success()
|
|
97
|
+ results = result.output.splitlines()
|
|
98
|
+ else:
|
|
99
|
+ if operation == 'fetch':
|
|
100
|
+ result = cli.run(args=['source', 'fetch', target], project=project, silent=True)
|
|
101
|
+ else:
|
|
102
|
+ result = cli.run(args=[operation, target], project=project, silent=True)
|
|
103
|
+ result.assert_success()
|
|
104
|
+ results = result.get_start_order(operation)
|
|
105
|
+
|
|
106
|
+ # Assert the order
|
|
107
|
+ print("Expected order: {}".format(expected))
|
|
108
|
+ print("Observed result order: {}".format(results))
|
|
109
|
+ assert results == expected
|