# Copyright 2017-2017 ARM Limited # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # from bart.common.Utils import select_window from test import LisaTest, experiment_test WORKLOAD_DURATION_S = 5 REQUIRED_CPU_ACTIVE_TIME_PCT = 95 class HeavyLoadTest(LisaTest): """ Test an EAS system under heavy load Runs N 100% RT-App threads where N is the number of CPUs, and checks that those tasks were spread across all CPUs in the system by asserting that all CPUs were fully utilized up until the first task completed. """ test_conf = { 'ftrace' : { 'events' : ['cpu_idle', 'sched_switch'], }, 'modules' : ['cgroups'], # Required by freeze_userspace flag } experiments_conf = { "wloads" : { "n_heavy_tasks" : { "type" : "rt-app", "conf" : { "class" : "profile", "params" : { "wmig" : { "kind" : "Periodic", "params" : { "duty_cycle_pct": 100, "duration_s": WORKLOAD_DURATION_S, }, # Create one task for each cpu "tasks" : "cpus", }, }, }, }, }, "confs" : [{ 'tag' : 'energy_aware', 'flags' : ['ftrace', 'freeze_userspace'], 'sched_features' : 'ENERGY_AWARE', }] } @classmethod def setUpClass(cls, *args, **kwargs): super(HeavyLoadTest, cls).runExperiments(*args, **kwargs) @experiment_test def test_tasks_spread(self, experiment, tasks): trace = self.get_trace(experiment) start, _ = self.get_window(experiment) end = min(self.get_end_times(experiment).values()) duration = end - start total_cpu_time = 0 active_proportions = [] for cpu, _ in enumerate(self.target.core_names): cpu_active = trace.getCPUActiveSignal(cpu) if cpu_active is None: raise RuntimeError( "Couldn't get CPU-active signal. " "Is the 'cpu_idle' ftrace event enabled in the kernel?") # Add extra events to cpu_active signal so that it matches the # window exactly new_index = sorted(cpu_active.index.tolist() + [start, end]) cpu_active = cpu_active.reindex(new_index, method='ffill') active_time = trace.integrate_square_wave(cpu_active[start:end]) active_proportions.append(active_time / duration) if any(a < (REQUIRED_CPU_ACTIVE_TIME_PCT / 100.) for a in active_proportions): proportions_str = "" for cpu, _ in enumerate(self.target.core_names): proportions_str += " {:3d} {:5.1f}%\n".format( cpu, active_proportions[cpu]*100) raise AssertionError( "Some CPUs were less than {}% utilized\n" " CPU active proportions:\n{}".format( REQUIRED_CPU_ACTIVE_TIME_PCT, proportions_str))