diff --git a/lisa/tests/base.py b/lisa/tests/base.py index 3ca8538c62d42f0485ff04922293419ed82772be..05ae3200a974d52c3b2e46da135728a45abe1bd2 100644 --- a/lisa/tests/base.py +++ b/lisa/tests/base.py @@ -1452,33 +1452,14 @@ class RTATestBundle(FtraceTestBundle, DmesgTestBundle): ) return trace.get_view(self.trace_window(trace), clear_base_cache=True) - @TestBundle.add_undecided_filter - @TasksAnalysis.df_tasks_runtime.used_events - def test_noisy_tasks(self, *, noise_threshold_pct=None, noise_threshold_ms=None): + def df_noisy_tasks(self, with_threshold_exclusion=True): """ - Test that no non-rtapp ("noisy") task ran for longer than the specified thresholds - - :param noise_threshold_pct: The maximum allowed runtime for noisy tasks in - percentage of the total rt-app execution time - :type noise_threshold_pct: float - - :param noise_threshold_ms: The maximum allowed runtime for noisy tasks in ms - :type noise_threshold_ms: float + :returns: a DataFrame containing all tasks that participate to the test + noise. i.e. all non rt-app tasks. - If both are specified, the smallest threshold (in seconds) will be used. + :param with_threshold_exclusion: When set to True, known noisy services + will be ignored. """ - if noise_threshold_pct is None and noise_threshold_ms is None: - raise ValueError('Both "noise_threshold_pct" and "noise_threshold_ms" cannot be None') - - # No task can run longer than the recorded duration - threshold_s = self.trace.time_range - - if noise_threshold_pct is not None: - threshold_s = noise_threshold_pct * self.trace.time_range / 100 - - if noise_threshold_ms is not None: - threshold_s = min(threshold_s, noise_threshold_ms * 1e3) - df = self.trace.analysis.tasks.df_tasks_runtime() # We don't want to account the test tasks @@ -1487,8 +1468,10 @@ class RTATestBundle(FtraceTestBundle, DmesgTestBundle): df['runtime_pct'] = df['runtime'] * (100 / self.trace.time_range) df['pid'] = df.index + threshold_exclusion = self.NOISE_ACCOUNTING_THRESHOLDS if with_threshold_exclusion else {} + # Figure out which PIDs to exclude from the thresholds - for key, threshold in self.NOISE_ACCOUNTING_THRESHOLDS.items(): + for key, threshold in threshold_exclusion.items(): # Find out which task(s) this threshold is about if isinstance(key, str): comms = df.loc[df['comm'].str.match(key), 'comm'] @@ -1508,7 +1491,38 @@ class RTATestBundle(FtraceTestBundle, DmesgTestBundle): self.get_logger().info(f"Ignored PIDs for noise contribution: {', '.join(map(str, ignored_ids))}") # Filter out unwanted tasks (rt-app tasks + thresholds) - df_noise = df_filter_task_ids(df, ignored_ids, invert=True) + df = df_filter_task_ids(df, ignored_ids, invert=True) + + return df.loc[df['runtime'] > 0] + + @TestBundle.add_undecided_filter + @TasksAnalysis.df_tasks_runtime.used_events + def test_noisy_tasks(self, *, noise_threshold_pct=None, noise_threshold_ms=None): + """ + Test that no non-rtapp ("noisy") task ran for longer than the specified thresholds + + :param noise_threshold_pct: The maximum allowed runtime for noisy tasks in + percentage of the total rt-app execution time + :type noise_threshold_pct: float + + :param noise_threshold_ms: The maximum allowed runtime for noisy tasks in ms + :type noise_threshold_ms: float + + If both are specified, the smallest threshold (in seconds) will be used. + """ + if noise_threshold_pct is None and noise_threshold_ms is None: + raise ValueError('Both "noise_threshold_pct" and "noise_threshold_ms" cannot be None') + + # No task can run longer than the recorded duration + threshold_s = self.trace.time_range + + if noise_threshold_pct is not None: + threshold_s = noise_threshold_pct * self.trace.time_range / 100 + + if noise_threshold_ms is not None: + threshold_s = min(threshold_s, noise_threshold_ms * 1e3) + + df_noise = self.df_noisy_tasks() if df_noise.empty: return ResultBundle.from_bool(True)