TT#190200 build: detect circular dependencies

Change-Id: Ib98fef31cb51d447518ec0471a9bbf02beff6fe8
pull/9/head
Victor Seva 3 years ago
parent 1d507a302c
commit 6cf063d908

@ -48,3 +48,7 @@ class PreviousBuildNotDone(Error):
"""same release is building right now"""
pass
class CircularBuildDependencies(Error):
pass

@ -363,16 +363,8 @@ class BuildRelease(models.Model):
return res
@property
def build_deps(self):
if getattr(self, "_build_deps", None) is None:
self._build_deps = []
step = 0
deps = list(self.config.wanna_build_deps(step))
while len(deps) > 0:
self._build_deps.append(deps)
step = step + 1
deps = list(self.config.wanna_build_deps(step))
return self._build_deps
def build_deps(self) -> list:
return self.config.levels_build_deps
@property
def config(self):

@ -512,3 +512,80 @@ class RemoveList(BaseTest):
self.br.triggered_projects = "fake-project"
remove_from_textlist(self.br, "triggered_projects", "fake-project")
self.assertIsNone(self.br.triggered_projects)
class WannaBuildTestCase(SimpleTestCase):
class FakeConfig(ReleaseConfig):
build_deps = dict()
def __init__(self, build_deps=None):
if build_deps:
self.build_deps = build_deps
def test_deps(self):
build_deps = {
"A": ["A1", "A2", "A3"],
"B": ["A2"],
"C": ["A2", "B"],
"A2": ["D"],
}
config = self.FakeConfig(build_deps)
wb = ReleaseConfig.WannaBuild(config, 0)
self.assertListEqual(list(wb), ["A", "C"])
wb = ReleaseConfig.WannaBuild(config, 1)
self.assertListEqual(list(wb), ["B"])
wb = ReleaseConfig.WannaBuild(config, 2)
self.assertListEqual(list(wb), ["A2"])
wb = ReleaseConfig.WannaBuild(config, 3)
self.assertListEqual(list(wb), [])
def test_deps_ko(self):
build_deps = {"A": ["A1", "A2", "A3", "A"]}
config = self.FakeConfig(build_deps)
wb = ReleaseConfig.WannaBuild(config, 0)
self.assertListEqual(list(wb), [])
def test_circular_simple_deps(self):
build_deps = {
"A": ["A1", "A2", "A3"],
"B": ["A2"],
"C": ["A2", "B"],
"A2": ["A"],
}
config = self.FakeConfig(build_deps)
with self.assertRaisesRegex(
err.CircularBuildDependencies, r"\['A', 'A2'\]"
):
config.check_circular_dependencies()
def test_circular_simple_deps_more(self):
build_deps = {
"A": ["A1", "A2", "A3"],
"B": ["A2"],
"C": ["A2", "B"],
"A2": ["A3"],
"A3": ["C"],
}
config = self.FakeConfig(build_deps)
with self.assertRaisesRegex(
err.CircularBuildDependencies, r"\['B', 'C', 'A2', 'A3'\]"
):
config.check_circular_dependencies()
def test_circular_simple(self):
build_deps = {
"A": ["A1", "A2", "A3", "A"],
}
config = self.FakeConfig(build_deps)
with self.assertRaisesRegex(err.CircularBuildDependencies, r"\['A'\]"):
config.check_circular_dependencies()
def test_circular_deps_ok(self):
build_deps = {
"A": ["A1", "A2", "A3"],
"B": ["A2"],
"C": ["A2", "B"],
"A2": ["D"],
}
config = self.FakeConfig(build_deps)
config.check_circular_dependencies()

@ -183,8 +183,6 @@ class ReleaseConfig(object):
for name in search_map:
flag = False
for prj, values in search_map.items():
if name == prj:
continue
if name in values:
flag = True
deps[name] = search_map[name]
@ -225,6 +223,18 @@ class ReleaseConfig(object):
return list_prj.pop(0)
raise StopIteration
def check_circular_dependencies(self):
levels = self.levels_build_deps
builds = list(self.build_deps.keys())
print(f"{levels}")
for vals in levels:
for prj in vals:
builds.remove(prj)
if len(builds) > 0:
raise err.CircularBuildDependencies(
f"problems detected with {builds}"
)
@classmethod
def load_config(cls, config_path):
try:
@ -289,14 +299,27 @@ class ReleaseConfig(object):
except KeyError:
msg = "{} has no 'distris' info"
raise err.NoDistrisInfo(msg.format(self.config_file))
self.check_circular_dependencies()
@property
def build_deps(self):
def build_deps(self) -> dict:
return self.jenkins_jobs.get("build_deps", dict())
def wanna_build_deps(self, step=0):
return ReleaseConfig.WannaBuild(self, step)
@property
def levels_build_deps(self) -> list:
if getattr(self, "_levels_build_deps", None) is None:
self._levels_build_deps = []
step = 0
deps = list(self.wanna_build_deps(step))
while len(deps) > 0:
self._levels_build_deps.append(deps)
step = step + 1
deps = list(self.wanna_build_deps(step))
return self._levels_build_deps
@property
def branch(self):
release = self.release

Loading…
Cancel
Save