diff options
author | Tom Pollard <tom.pollard@codethink.co.uk> | 2019-11-14 14:11:08 +0000 |
---|---|---|
committer | Tom Pollard <tom.pollard@codethink.co.uk> | 2019-11-14 14:34:29 +0000 |
commit | b6ff02a198bd65c3e356ada1bb711d236e6a772f (patch) | |
tree | 35fd79b0beae2380baed1744db9de89fd05046e1 /src | |
parent | c3eee615fb5fe957d17151ff655ebebc3d029681 (diff) | |
download | buildstream-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.py | 10 | ||||
-rw-r--r-- | src/buildstream/_profile.py | 20 |
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")) |