diff options
author | Jim MacArthur <jim+gitlab@mode7.co.uk> | 2018-07-25 13:43:21 +0000 |
---|---|---|
committer | Jim MacArthur <jim+gitlab@mode7.co.uk> | 2018-07-25 13:43:21 +0000 |
commit | 889bf23825d2627fec04443cc936f79d836c7486 (patch) | |
tree | 730cf53c1a6970e5b0583bf73ad0e2a77d085917 | |
parent | 4a637d631814b0d3e20fd2d4ffb8b9d2f60d04a6 (diff) | |
parent | 95b4eae4954ba0f3d65c85f58a37fdcd46b4b8af (diff) | |
download | buildstream-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.py | 4 | ||||
-rw-r--r-- | tests/frontend/show.py | 60 |
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) |