summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim MacArthur <jim+gitlab@mode7.co.uk>2018-07-25 13:43:21 +0000
committerJim MacArthur <jim+gitlab@mode7.co.uk>2018-07-25 13:43:21 +0000
commit889bf23825d2627fec04443cc936f79d836c7486 (patch)
tree730cf53c1a6970e5b0583bf73ad0e2a77d085917
parent4a637d631814b0d3e20fd2d4ffb8b9d2f60d04a6 (diff)
parent95b4eae4954ba0f3d65c85f58a37fdcd46b4b8af (diff)
downloadbuildstream-889bf23825d2627fec04443cc936f79d836c7486.tar.gz
Merge branch 'phil/203-BuildStream-crashes-when-dependency-tree-too-deep' into 'master'
Phil/203 BuildStream crashes when dependency tree too deep See merge request BuildStream/buildstream!512
-rw-r--r--buildstream/_frontend/app.py4
-rw-r--r--tests/frontend/show.py60
2 files changed, 62 insertions, 2 deletions
diff --git a/buildstream/_frontend/app.py b/buildstream/_frontend/app.py
index c8f1f435d..5fae0307b 100644
--- a/buildstream/_frontend/app.py
+++ b/buildstream/_frontend/app.py
@@ -270,6 +270,10 @@ class App():
# Exit with the error
self._error_exit(e)
+ except RecursionError:
+ click.echo("RecursionError: Depency depth is too large. Maximum recursion depth exceeded.",
+ err=True)
+ sys.exit(-1)
else:
# No exceptions occurred, print session time and summary
diff --git a/tests/frontend/show.py b/tests/frontend/show.py
index 0276961ab..80c48381a 100644
--- a/tests/frontend/show.py
+++ b/tests/frontend/show.py
@@ -1,8 +1,9 @@
import os
-import pytest
+import sys
+import shutil
import itertools
+import pytest
from tests.testutils import cli
-
from buildstream import _yaml
from buildstream._exceptions import ErrorDomain, LoadErrorReason
@@ -232,3 +233,58 @@ def test_fetched_junction(cli, tmpdir, datafiles, element_name):
results = result.output.strip().splitlines()
assert 'junction.bst:import-etc.bst-buildable' in results
+
+
+###############################################################
+# Testing recursion depth #
+###############################################################
+@pytest.mark.parametrize("dependency_depth", [100, 500, 1200])
+def test_exceed_max_recursion_depth(cli, tmpdir, dependency_depth):
+ project_name = "recursion-test"
+ path = str(tmpdir)
+ project_path = os.path.join(path, project_name)
+
+ def setup_test():
+ """
+ Creates a bst project with dependencydepth + 1 elements, each of which
+ depends of the previous element to be created. Each element created
+ is of type import and has an empty source file.
+ """
+ os.mkdir(project_path)
+
+ result = cli.run(project=project_path, silent=True,
+ args=['init', '--project-name', project_name])
+ result.assert_success()
+
+ sourcefiles_path = os.path.join(project_path, "files")
+ os.mkdir(sourcefiles_path)
+
+ element_path = os.path.join(project_path, "elements")
+ for i in range(0, dependency_depth + 1):
+ element = {
+ 'kind': 'import',
+ 'sources': [{'kind': 'local',
+ 'path': 'files/source{}'.format(str(i))}],
+ 'depends': ['element{}.bst'.format(str(i - 1))]
+ }
+ if i == 0:
+ del element['depends']
+ _yaml.dump(element, os.path.join(element_path, "element{}.bst".format(str(i))))
+
+ source = os.path.join(sourcefiles_path, "source{}".format(str(i)))
+ open(source, 'x').close()
+ assert os.path.exists(source)
+
+ setup_test()
+ result = cli.run(project=project_path, silent=True,
+ args=['show', "element{}.bst".format(str(dependency_depth))])
+
+ recursion_limit = sys.getrecursionlimit()
+ if dependency_depth <= recursion_limit:
+ result.assert_success()
+ else:
+ # Assert exception is thown and handled
+ assert not result.unhandled_exception
+ assert result.exit_code == -1
+
+ shutil.rmtree(project_path)