summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Pollard <tom.pollard@codethink.co.uk>2019-11-14 14:11:08 +0000
committerTom Pollard <tom.pollard@codethink.co.uk>2019-11-14 14:34:29 +0000
commitb6ff02a198bd65c3e356ada1bb711d236e6a772f (patch)
tree35fd79b0beae2380baed1744db9de89fd05046e1 /src
parentc3eee615fb5fe957d17151ff655ebebc3d029681 (diff)
downloadbuildstream-b6ff02a198bd65c3e356ada1bb711d236e6a772f.tar.gz
_profile.py: Raise exception if invalid BST_PROFILE topics
This is implemented with a new ProfileError, ensuring a user doesn't wait for a profile to complete that was never valid.
Diffstat (limited to 'src')
-rw-r--r--src/buildstream/_exceptions.py10
-rw-r--r--src/buildstream/_profile.py20
2 files changed, 30 insertions, 0 deletions
diff --git a/src/buildstream/_exceptions.py b/src/buildstream/_exceptions.py
index 947b83149..46de90796 100644
--- a/src/buildstream/_exceptions.py
+++ b/src/buildstream/_exceptions.py
@@ -97,6 +97,7 @@ class ErrorDomain(Enum):
CAS = 14
PROG_NOT_FOUND = 15
REMOTE = 16
+ PROFILE = 17
# BstError is an internal base exception class for BuildStream
@@ -378,3 +379,12 @@ class SkipJob(Exception):
class ArtifactElementError(BstError):
def __init__(self, message, *, detail=None, reason=None):
super().__init__(message, detail=detail, domain=ErrorDomain.ELEMENT, reason=reason)
+
+
+# ProfileError
+#
+# Raised when a user provided profile choice isn't valid
+#
+class ProfileError(BstError):
+ def __init__(self, message, detail=None, reason=None):
+ super().__init__(message, detail=detail, domain=ErrorDomain.PROFILE, reason=reason)
diff --git a/src/buildstream/_profile.py b/src/buildstream/_profile.py
index b17215d0e..c68d058ad 100644
--- a/src/buildstream/_profile.py
+++ b/src/buildstream/_profile.py
@@ -27,6 +27,7 @@ import pstats
import os
import datetime
import time
+from ._exceptions import ProfileError
# Use the topic values here to decide what to profile
@@ -112,6 +113,7 @@ class _Profiler:
self.active_topics = set()
self.enabled_topics = set()
self._active_profilers = []
+ self._valid_topics = False
if settings:
self.enabled_topics = {
@@ -121,6 +123,15 @@ class _Profiler:
@contextlib.contextmanager
def profile(self, topic, key, message=None):
+
+ # Check if the user enabled topics are valid
+ # NOTE: This is done in the first PROFILER.profile() call and
+ # not __init__ to ensure we handle the exception. This also means
+ # we cannot test for the exception due to the early instantiation and
+ # how the environment is set in the test invocation.
+ if not self._valid_topics:
+ self._check_valid_topics()
+
if not self._is_profile_enabled(topic):
yield
return
@@ -155,6 +166,15 @@ class _Profiler:
def _is_profile_enabled(self, topic):
return topic in self.enabled_topics or Topics.ALL in self.enabled_topics
+ def _check_valid_topics(self):
+ non_valid_topics = [topic for topic in self.enabled_topics if topic not in vars(Topics).values()]
+
+ if non_valid_topics:
+ raise ProfileError("Provided BST_PROFILE topics do not exist: {}"
+ .format(", ".join(non_valid_topics)))
+
+ self._valid_topics = True
+
# Export a profiler to be used by BuildStream
PROFILER = _Profiler(os.getenv("BST_PROFILE"))