summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim MacArthur <jim.macarthur@codethink.co.uk>2018-01-19 15:14:13 +0000
committerJim MacArthur <jim.macarthur@codethink.co.uk>2018-03-22 18:44:53 +0000
commit2053ee754fcb83a28f5a85b043f2ecdf4b9b33d7 (patch)
treef0db3674f3818a552df385de39954fc39f619972
parent9c418946bb55fa1e4cf2216f1dff316482b3484a (diff)
downloadbuildstream-2053ee754fcb83a28f5a85b043f2ecdf4b9b33d7.tar.gz
Add a test for unhandled exceptions.
This reproduces one of the conditions which caused issue #197. The test uses subprocess instead of the usual Cli class because with Cli.invoke(), PyTest would handle the exception before our custom excepthook has a chance to.
-rw-r--r--tests/pipeline/unhandled-error/error.bst4
-rw-r--r--tests/pipeline/unhandled-error/errorplugin/preflighterror.py36
-rw-r--r--tests/pipeline/unhandled-error/project.conf11
-rw-r--r--tests/pipeline/unhandled.py35
4 files changed, 86 insertions, 0 deletions
diff --git a/tests/pipeline/unhandled-error/error.bst b/tests/pipeline/unhandled-error/error.bst
new file mode 100644
index 000000000..a9772770c
--- /dev/null
+++ b/tests/pipeline/unhandled-error/error.bst
@@ -0,0 +1,4 @@
+kind: import
+description: An element with a failing source at preflight time
+sources:
+- kind: preflighterror
diff --git a/tests/pipeline/unhandled-error/errorplugin/preflighterror.py b/tests/pipeline/unhandled-error/errorplugin/preflighterror.py
new file mode 100644
index 000000000..5d39746d0
--- /dev/null
+++ b/tests/pipeline/unhandled-error/errorplugin/preflighterror.py
@@ -0,0 +1,36 @@
+from buildstream import Source, SourceError, Consistency
+
+
+class PreflightErrorSource(Source):
+
+ def configure(self, node):
+ pass
+
+ def preflight(self):
+
+ # Raise an untyped exception unconditionally.
+ # This is expected not to be handled and should test the behaviour of
+ # unhandled exceptions going off in the main buildstream application.
+ raise Exception("preflighterror: Unsatisfied requirements in preflight, raising this error")
+
+ def get_unique_key(self):
+ return {}
+
+ def get_consistency(self):
+ return Consistency.CACHED
+
+ def get_ref(self):
+ return None
+
+ def set_ref(self, ref, node):
+ pass
+
+ def fetch(self):
+ pass
+
+ def stage(self, directory):
+ pass
+
+
+def setup():
+ return PreflightErrorSource
diff --git a/tests/pipeline/unhandled-error/project.conf b/tests/pipeline/unhandled-error/project.conf
new file mode 100644
index 000000000..20a234413
--- /dev/null
+++ b/tests/pipeline/unhandled-error/project.conf
@@ -0,0 +1,11 @@
+# Basic project configuration that doesnt override anything
+#
+name: pony
+
+# Whitelist the local test Source "errorplugin" to be loaded
+#
+plugins:
+- origin: local
+ path: errorplugin
+ sources:
+ preflighterror: 0
diff --git a/tests/pipeline/unhandled.py b/tests/pipeline/unhandled.py
new file mode 100644
index 000000000..114900d36
--- /dev/null
+++ b/tests/pipeline/unhandled.py
@@ -0,0 +1,35 @@
+import os
+import pytest
+import re
+import subprocess
+import sys
+
+from buildstream._exceptions import ErrorDomain
+from tests.testutils.runcli import cli
+
+DATA_DIR = os.path.join(
+ os.path.dirname(os.path.realpath(__file__)),
+ 'unhandled-error',
+)
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_load_simple(cli, datafiles, tmpdir):
+ basedir = os.path.join(datafiles.dirname, datafiles.basename)
+
+ process = subprocess.Popen(['bst', 'fetch', 'error.bst'],
+ cwd=basedir, stderr=subprocess.PIPE)
+ try:
+ (stdout, stderr) = process.communicate()
+ except TimeoutExpired:
+ proc.kill()
+ (stdout, stderr) = process.communicate()
+
+ # The process should have caught the exception and explicitly exited with code -1
+ assert process.returncode == 255
+ assert stderr is not None
+
+ expected_error = "BUG\s+preflighterror: Unsatisfied requirements in preflight, raising this error"
+
+ match = re.search(expected_error, stderr.decode("utf-8"))
+ assert match is not None