From 503a43969a84e0e61e562247035a519a63f16ffa Mon Sep 17 00:00:00 2001 From: Douglas Raillard Date: Wed, 14 Jun 2023 13:19:24 +0100 Subject: [PATCH 1/2] lisa.conf: Deal with import errors more cleanly. FIX If a module declaring a configuration class fails to import, it might be re-executed again (from another import statement). This currently leads to an exception because two classes tried to register the same top-level key, but they are actually the same class. Instead of raising an exception, ignore that conflict and register the latest type we encounter. This allows ensuring that the real import error will surface, without extra noise from the conf system. --- lisa/conf.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lisa/conf.py b/lisa/conf.py index 254f4471e..685b7f933 100644 --- a/lisa/conf.py +++ b/lisa/conf.py @@ -901,12 +901,22 @@ class MultiSrcConfABC(Serializable, abc.ABC): return tuple(key1[:len_]) == tuple(key2[:len_]) offending = [ - cls_.__qualname__ + cls_ for keys, cls_ in cls._REGISTERED_TOPLEVEL_KEYS.items() if eq_prefix_keys(toplevel_keys, keys) ] - if offending: + # If the offending class has the same name and was declared in the + # same module, we ignore the conflict as this is probably arising + # from an import error in that module, that lead to the module + # being re-imported again (by another import statement). + if offending and not all( + ( + cls_.__qualname__ == cls.__qualname__ and + cls_.__module__ == cls.__module__ + ) + for cls_ in offending + ): raise RuntimeError(f'Class {cls.__qualname__} cannot reuse top level key "{format_keys(toplevel_keys)}" as it is already used by {", ".join(offending)}') else: cls._REGISTERED_TOPLEVEL_KEYS[toplevel_keys] = cls -- GitLab From 2c2edd4a5a44705e6f2f5b78bdb91d574f890060 Mon Sep 17 00:00:00 2001 From: Douglas Raillard Date: Wed, 14 Jun 2023 12:56:54 +0100 Subject: [PATCH 2/2] lisa.trace: Do not apply event namespace if the event is already namespaces FEATURE If the event name already contains the namespace (XXX__ when considering namespace XXX) then do not reapply the namespace to that name. This avoids XXX__XXX__ to be generated. Note that this does not prevent XXX__YYY__ from being created. --- lisa/tests/base.py | 4 ++++ lisa/trace.py | 17 +++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/lisa/tests/base.py b/lisa/tests/base.py index 5fe208eab..661e9d758 100644 --- a/lisa/tests/base.py +++ b/lisa/tests/base.py @@ -1372,6 +1372,10 @@ class FtraceTestBundleBase(TestBundleBase): # iterations of the tests with exekall, leading to crashes. # Therefore, disable the on-disk swap. enable_swap=False, + # The event list that gets passed has already undergone namespace + # expansion when multiple ftrace conf got merged together, so there + # is no need to repeat it again. + events_namespaces=[], ) def get_trace(self, events=None, **kwargs): diff --git a/lisa/trace.py b/lisa/trace.py index e52a51855..63e04e8f2 100644 --- a/lisa/trace.py +++ b/lisa/trace.py @@ -3702,7 +3702,7 @@ class Trace(Loggable, TraceBase): self.events = events # Pre-load the selected events if events: - preload_events = AndTraceEventChecker.from_events( + preload_events = OptionalTraceEventChecker.from_events( event_ for event in events for event_ in self._expand_namespaces(event, events_namespaces) @@ -3738,24 +3738,25 @@ class Trace(Loggable, TraceBase): namespaces = self_or_cls._resolve_namespaces(namespaces) def expand(event, namespace): - if self_or_cls._is_meta_event(event): + ns_prefix = f'{namespace}__' + if not namespace: + return [event] + elif self_or_cls._is_meta_event(event): prefix, _ = event.split('@', 1) return [ f'{prefix}@{source_}' for source in self_or_cls.get_event_sources(event) for source_ in expand(source, namespace) ] + elif event.startswith(ns_prefix): + return [event] else: - return [f'{namespace}__{event}'] + return [f'{ns_prefix}{event}'] return [ event_ for namespace in namespaces - for event_ in ( - expand(event, namespace) - if namespace - else [event] - ) + for event_ in expand(event, namespace) ] _CACHEABLE_METADATA = { -- GitLab