aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcrosperf/benchmark_run_unittest.py1
-rwxr-xr-xcrosperf/crosperf_unittest.py2
-rw-r--r--crosperf/experiment_factory.py1
-rwxr-xr-xcrosperf/experiment_file_unittest.py2
-rw-r--r--crosperf/experiment_files/dut_config.exp3
-rw-r--r--crosperf/settings_factory.py9
-rwxr-xr-xcrosperf/settings_factory_unittest.py5
-rw-r--r--crosperf/suite_runner.py100
-rwxr-xr-xcrosperf/suite_runner_unittest.py174
9 files changed, 288 insertions, 9 deletions
diff --git a/crosperf/benchmark_run_unittest.py b/crosperf/benchmark_run_unittest.py
index 4c2a7e60..59d701b8 100755
--- a/crosperf/benchmark_run_unittest.py
+++ b/crosperf/benchmark_run_unittest.py
@@ -105,6 +105,7 @@ class BenchmarkRunTest(unittest.TestCase):
'cooldown_temp': 45,
'governor': 'powersave',
'cpu_usage': 'big_only',
+ 'cpu_freq_pct': 80,
}
b = benchmark_run.MockBenchmarkRun('test run', bench, my_label, 1, [], m,
logger.GetLogger(), logging_level, '',
diff --git a/crosperf/crosperf_unittest.py b/crosperf/crosperf_unittest.py
index 8d5569e0..84f646a6 100755
--- a/crosperf/crosperf_unittest.py
+++ b/crosperf/crosperf_unittest.py
@@ -67,7 +67,7 @@ class CrosperfTest(unittest.TestCase):
settings = crosperf.ConvertOptionsToSettings(options)
self.assertIsNotNone(settings)
self.assertIsInstance(settings, settings_factory.GlobalSettings)
- self.assertEqual(len(settings.fields), 35)
+ self.assertEqual(len(settings.fields), 36)
self.assertTrue(settings.GetField('rerun'))
argv = ['crosperf/crosperf.py', 'temp.exp']
options, _ = parser.parse_known_args(argv)
diff --git a/crosperf/experiment_factory.py b/crosperf/experiment_factory.py
index 28755c80..9bf42d4f 100644
--- a/crosperf/experiment_factory.py
+++ b/crosperf/experiment_factory.py
@@ -165,6 +165,7 @@ class ExperimentFactory(object):
'cooldown_temp': global_settings.GetField('cooldown_temp'),
'governor': global_settings.GetField('governor'),
'cpu_usage': global_settings.GetField('cpu_usage'),
+ 'cpu_freq_pct': global_settings.GetField('cpu_freq_pct'),
}
# Default cache hit conditions. The image checksum in the cache and the
diff --git a/crosperf/experiment_file_unittest.py b/crosperf/experiment_file_unittest.py
index 861e2549..f0d5178b 100755
--- a/crosperf/experiment_file_unittest.py
+++ b/crosperf/experiment_file_unittest.py
@@ -93,6 +93,7 @@ DUT_CONFIG_EXPERIMENT_FILE_GOOD = """
cooldown_time: 5
governor: powersave
cpu_usage: exclusive_cores
+ cpu_freq_pct: 50
benchmark: speedometer {
iterations: 3
@@ -217,6 +218,7 @@ class ExperimentFileTest(unittest.TestCase):
self.assertEqual(global_settings.GetField('intel_pstate'), 'no_hwp')
self.assertEqual(global_settings.GetField('governor'), 'powersave')
self.assertEqual(global_settings.GetField('cpu_usage'), 'exclusive_cores')
+ self.assertEqual(global_settings.GetField('cpu_freq_pct'), 50)
self.assertEqual(global_settings.GetField('cooldown_time'), 5)
self.assertEqual(global_settings.GetField('cooldown_temp'), 38)
diff --git a/crosperf/experiment_files/dut_config.exp b/crosperf/experiment_files/dut_config.exp
index f96242ff..fe8f8f77 100644
--- a/crosperf/experiment_files/dut_config.exp
+++ b/crosperf/experiment_files/dut_config.exp
@@ -34,6 +34,9 @@ governor: <one-of-scaling_available_governors-values>
# Restrict CPU usage to predefined "models":
# all, big_only, little_only, exclusive_cores.
cpu_usage: <usage-model>
+# Setup CPU frequency as percent of max_freq.
+# Default: 100
+cpu_freq_pct: <0-100>
# The example below will run Telemetry toolchain performance benchmarks.
# The exact list of benchmarks that will be run can be seen in
diff --git a/crosperf/settings_factory.py b/crosperf/settings_factory.py
index b96ad342..1fbc8e14 100644
--- a/crosperf/settings_factory.py
+++ b/crosperf/settings_factory.py
@@ -360,7 +360,7 @@ class GlobalSettings(Settings):
required=False,
default=0,
description='Wait specified time in minutes allowing'
- ' CPU to cool down. Zero value disables cooldown,'))
+ ' CPU to cool down. Zero value disables cooldown.'))
self.AddField(
EnumField(
'governor',
@@ -396,6 +396,13 @@ class GlobalSettings(Settings):
' applicable only on ARM;\n'
'exclusive-cores - (for future use)'
' isolate cores for exclusive use of benchmark processes.'))
+ self.AddField(
+ IntegerField(
+ 'cpu_freq_pct',
+ required=False,
+ default=100,
+ description='Setup CPU frequency to a supported value less than'
+ ' or equal to a percent of max_freq.'))
class SettingsFactory(object):
diff --git a/crosperf/settings_factory_unittest.py b/crosperf/settings_factory_unittest.py
index 6dfb0bff..633f2e5f 100755
--- a/crosperf/settings_factory_unittest.py
+++ b/crosperf/settings_factory_unittest.py
@@ -50,7 +50,7 @@ class GlobalSettingsTest(unittest.TestCase):
def test_init(self):
res = settings_factory.GlobalSettings('g_settings')
self.assertIsNotNone(res)
- self.assertEqual(len(res.fields), 35)
+ self.assertEqual(len(res.fields), 36)
self.assertEqual(res.GetField('name'), '')
self.assertEqual(res.GetField('board'), '')
self.assertEqual(res.GetField('skylab'), False)
@@ -82,6 +82,7 @@ class GlobalSettingsTest(unittest.TestCase):
self.assertEqual(res.GetField('cooldown_temp'), 40)
self.assertEqual(res.GetField('governor'), 'performance')
self.assertEqual(res.GetField('cpu_usage'), 'all')
+ self.assertEqual(res.GetField('cpu_freq_pct'), 100)
class SettingsFactoryTest(unittest.TestCase):
@@ -104,7 +105,7 @@ class SettingsFactoryTest(unittest.TestCase):
g_settings = settings_factory.SettingsFactory().GetSettings(
'global', 'global')
self.assertIsInstance(g_settings, settings_factory.GlobalSettings)
- self.assertEqual(len(g_settings.fields), 35)
+ self.assertEqual(len(g_settings.fields), 36)
if __name__ == '__main__':
diff --git a/crosperf/suite_runner.py b/crosperf/suite_runner.py
index 5b677949..faf40b52 100644
--- a/crosperf/suite_runner.py
+++ b/crosperf/suite_runner.py
@@ -119,6 +119,13 @@ class SuiteRunner(object):
if not self.enable_aslr:
self.DisableASLR(run_on_dut)
+ # CPU usage setup comes first where we enable/disable cores.
+ self.SetupCpuUsage(run_on_dut)
+ cpu_online_status = self.GetCpuOnline(run_on_dut)
+ # List of online cores of type int (core number).
+ online_cores = [
+ core for core, status in cpu_online_status.items() if status
+ ]
if self.dut_config['cooldown_time']:
# Setup power conservative mode for effective cool down.
# Set ignore status since powersave may no be available
@@ -138,13 +145,20 @@ class SuiteRunner(object):
# Setup CPU governor for the benchmark run.
# It overwrites the previous governor settings.
governor = self.dut_config['governor']
+ # FIXME(denik): Pass online cores to governor setup.
self.SetCpuGovernor(governor, run_on_dut, ignore_status=False)
+
+ # Disable Turbo and Setup CPU freq should ALWAYS proceed governor setup
+ # since governor may change:
+ # - frequency;
+ # - turbo/boost.
self.DisableTurbo(run_on_dut)
- self.SetupCpuUsage(run_on_dut)
+ self.SetupCpuFreq(run_on_dut, online_cores)
# FIXME(denik): Currently we are not recovering the previous cpufreq
# settings since we do reboot/setup every time anyway.
# But it may change in the future and then we have to recover the
# settings.
+
if benchmark.suite == 'telemetry_Crosperf':
self.DecreaseWaitTime(run_on_dut)
ret_tup = self.Telemetry_Crosperf_Run(machine, label, benchmark,
@@ -231,8 +245,7 @@ class SuiteRunner(object):
# 'cooldown_temp'. Exit the loop.
break
- self.logger.LogOutput(
- 'Cooldown wait time: %.1f min' % (float(waittime) / 60))
+ self.logger.LogOutput('Cooldown wait time: %.1f min' % (waittime / 60))
return waittime
def SetupCpuUsage(self, run_on_dut):
@@ -344,6 +357,87 @@ class SuiteRunner(object):
'Ignore ARM CPU setup and continue.' % (self.dut_config['cpu_usage'],
dut_big_cores, dut_lit_cores))
+ def GetCpuOnline(self, run_on_dut):
+ """Get online status of CPU cores.
+
+ Return dict of {int(cpu_num): <0|1>}.
+ """
+ get_cpu_online_cmd = ('paste -d" "'
+ ' <(ls /sys/devices/system/cpu/cpu*/online)'
+ ' <(cat /sys/devices/system/cpu/cpu*/online)')
+ _, online_output_str, _ = run_on_dut(get_cpu_online_cmd)
+
+ # Here is the output we expect to see:
+ # -----------------
+ # /sys/devices/system/cpu/cpu0/online 0
+ # /sys/devices/system/cpu/cpu1/online 1
+
+ cpu_online = {}
+ cpu_online_match = re.compile(r'^[/\S]+/cpu(\d+)/[/\S]+\s+(\d+)$')
+ for line in online_output_str.splitlines():
+ match = cpu_online_match.match(line)
+ if match:
+ cpu = int(match.group(1))
+ status = int(match.group(2))
+ cpu_online[cpu] = status
+ # At least one CPU has to be online.
+ assert cpu_online
+
+ return cpu_online
+
+ def SetupCpuFreq(self, run_on_dut, online_cores):
+ """Setup CPU frequency.
+
+ Based on self.dut_config['cpu_freq_pct'] setup frequency of online CPU cores
+ to a supported value which is less or equal to (freq_pct * max_freq / 100)
+ limited by min_freq.
+
+ NOTE: scaling_available_frequencies support is required.
+ Otherwise the function has no effect.
+ """
+ freq_percent = self.dut_config['cpu_freq_pct']
+ list_all_avail_freq_cmd = (
+ 'ls /sys/devices/system/cpu/cpu{%s}/cpufreq/'
+ 'scaling_available_frequencies'
+ )
+ # Ignore error to support general usage of frequency setup.
+ # Not all platforms support scaling_available_frequencies.
+ ret, all_avail_freq_str, _ = run_on_dut(
+ list_all_avail_freq_cmd % ','.join(str(core) for core in online_cores),
+ ignore_status=True)
+ if ret or not all_avail_freq_str:
+ # No scalable frequencies available for the core.
+ return ret
+ for avail_freq_path in all_avail_freq_str.split():
+ # Get available freq from every scaling_available_frequency path.
+ # Error is considered fatal in run_on_dut().
+ _, avail_freq_str, _ = run_on_dut('cat ' + avail_freq_path)
+ assert avail_freq_str
+
+ all_avail_freq = sorted(
+ int(freq_str) for freq_str in avail_freq_str.split())
+ min_freq = all_avail_freq[0]
+ max_freq = all_avail_freq[-1]
+ # Calculate the frequency we are targeting.
+ target_freq = round(max_freq * freq_percent / 100)
+ # More likely it's not in the list of supported frequencies
+ # and our goal is to find the one which is less or equal.
+ # Default is min and we will try to maximize it.
+ avail_ngt_target = min_freq
+ # Find the largest not greater than the target.
+ for next_largest in reversed(all_avail_freq):
+ if next_largest <= target_freq:
+ avail_ngt_target = next_largest
+ break
+
+ max_freq_path = avail_freq_path.replace('scaling_available_frequencies',
+ 'scaling_max_freq')
+ min_freq_path = avail_freq_path.replace('scaling_available_frequencies',
+ 'scaling_min_freq')
+ # With default ignore_status=False we expect 0 status or Fatal error.
+ run_on_dut('echo %s | tee %s %s' % (avail_ngt_target, max_freq_path,
+ min_freq_path))
+
def DecreaseWaitTime(self, run_on_dut):
"""Change the ten seconds wait time for pagecycler to two seconds."""
FILE = '/usr/local/telemetry/src/tools/perf/page_sets/page_cycler_story.py'
diff --git a/crosperf/suite_runner_unittest.py b/crosperf/suite_runner_unittest.py
index 6be3865f..2bc299cd 100755
--- a/crosperf/suite_runner_unittest.py
+++ b/crosperf/suite_runner_unittest.py
@@ -153,7 +153,7 @@ class SuiteRunnerTest(unittest.TestCase):
{}, self.mock_logger, 'verbose', self.mock_cmd_exec, self.mock_cmd_term)
def test_get_profiler_args(self):
- input_str = ('--profiler=custom_perf --profiler_args=\'perf_options'
+ input_str = ("--profiler=custom_perf --profiler_args='perf_options"
'="record -a -e cycles,instructions"\'')
output_str = ("profiler=custom_perf profiler_args='record -a -e "
"cycles,instructions'")
@@ -173,6 +173,8 @@ class SuiteRunnerTest(unittest.TestCase):
self.telemetry_crosperf_args = []
def FakeDisableASLR(runner):
+ # pylint fix for unused variable.
+ del runner
self.call_disable_aslr = True
def FakeSkylabRun(test_label, benchmark, test_args, profiler_args):
@@ -197,6 +199,8 @@ class SuiteRunnerTest(unittest.TestCase):
return 'Ran FakeTestThatRun'
def FakeRunner(command, ignore_status=False):
+ # pylint fix for unused variable.
+ del command, ignore_status
return 0, '', ''
self.runner.DisableASLR = FakeDisableASLR
@@ -204,12 +208,15 @@ class SuiteRunnerTest(unittest.TestCase):
self.runner.Telemetry_Crosperf_Run = FakeTelemetryCrosperfRun
self.runner.Test_That_Run = FakeTestThatRun
self.runner.SetupCpuUsage = mock.Mock()
+ self.runner.SetupCpuFreq = mock.Mock()
self.runner.DutWrapper = mock.Mock(return_value=FakeRunner)
self.runner.DisableTurbo = mock.Mock()
self.runner.SetCpuGovernor = mock.Mock()
self.runner.WaitCooldown = mock.Mock(return_value=0)
+ self.runner.GetCpuOnline = mock.Mock(return_value={0: 1, 1: 1, 2: 0})
self.runner.dut_config['cooldown_time'] = 0
self.runner.dut_config['governor'] = 'fake_governor'
+ self.runner.dut_config['cpu_freq_pct'] = 65
machine = 'fake_machine'
test_args = ''
profiler_args = ''
@@ -225,6 +232,8 @@ class SuiteRunnerTest(unittest.TestCase):
self.assertEqual(self.skylab_run_args,
[self.mock_label, self.telemetry_bench, '', ''])
self.runner.SetupCpuUsage.assert_not_called()
+ self.runner.SetupCpuFreq.assert_not_called()
+ self.runner.GetCpuOnline.assert_not_called()
self.runner.DutWrapper.assert_not_called()
self.runner.SetCpuGovernor.assert_not_called()
self.runner.DisableTurbo.assert_not_called()
@@ -241,6 +250,8 @@ class SuiteRunnerTest(unittest.TestCase):
self.test_that_args,
['fake_machine', self.mock_label, self.test_that_bench, '', ''])
self.runner.SetupCpuUsage.assert_called_once_with(FakeRunner)
+ self.runner.SetupCpuFreq.assert_called_once_with(FakeRunner, [0, 1])
+ self.runner.GetCpuOnline.assert_called_once_with(FakeRunner)
self.runner.DutWrapper.assert_called_once_with(
machine, self.mock_label.chromeos_root)
self.runner.SetCpuGovernor.assert_called_once_with(
@@ -263,6 +274,8 @@ class SuiteRunnerTest(unittest.TestCase):
def test_run_with_cooldown(self):
def FakeRunner(command, ignore_status=False):
+ # pylint fix for unused variable.
+ del command, ignore_status
return 0, '', ''
self.runner.DisableASLR = mock.Mock()
@@ -270,10 +283,13 @@ class SuiteRunnerTest(unittest.TestCase):
self.runner.DisableTurbo = mock.Mock()
self.runner.SetCpuGovernor = mock.Mock()
self.runner.SetupCpuUsage = mock.Mock()
+ self.runner.SetupCpuFreq = mock.Mock()
self.runner.WaitCooldown = mock.Mock(return_value=0)
+ self.runner.GetCpuOnline = mock.Mock(return_value={0: 0, 1: 1})
self.runner.Telemetry_Crosperf_Run = mock.Mock(return_value=(0, '', ''))
self.runner.dut_config['cooldown_time'] = 10
self.runner.dut_config['governor'] = 'fake_governor'
+ self.runner.dut_config['cpu_freq_pct'] = 75
self.runner.Run('fake_machine', self.mock_label,
self.telemetry_crosperf_bench, '', '')
@@ -283,7 +299,9 @@ class SuiteRunnerTest(unittest.TestCase):
self.runner.Telemetry_Crosperf_Run.assert_called_once()
self.runner.DisableTurbo.assert_called_once_with(FakeRunner)
self.runner.SetupCpuUsage.assert_called_once_with(FakeRunner)
+ self.runner.SetupCpuFreq.assert_called_once_with(FakeRunner, [1])
self.runner.SetCpuGovernor.assert_called()
+ self.runner.GetCpuOnline.assert_called_once_with(FakeRunner)
self.assertGreater(self.runner.SetCpuGovernor.call_count, 1)
self.assertEqual(
self.runner.SetCpuGovernor.call_args,
@@ -390,6 +408,7 @@ class SuiteRunnerTest(unittest.TestCase):
'done; ')
dut_runner.assert_called_once_with(
set_cpu_cmd % 'non-exist_governor', ignore_status=True)
+ self.assertEqual(ret_code, 1)
def test_disable_turbo(self):
dut_runner = mock.Mock(return_value=(0, '', ''))
@@ -403,6 +422,57 @@ class SuiteRunnerTest(unittest.TestCase):
'fi; ')
dut_runner.assert_called_once_with(set_cpu_cmd)
+ def test_get_cpu_online_two(self):
+ """Test one digit CPU #."""
+ dut_runner = mock.Mock(
+ return_value=(0, '/sys/devices/system/cpu/cpu0/online 0\n'
+ '/sys/devices/system/cpu/cpu1/online 1\n', ''))
+ cpu_online = self.runner.GetCpuOnline(dut_runner)
+ self.assertEqual(cpu_online, {0: 0, 1: 1})
+
+ def test_get_cpu_online_twelve(self):
+ """Test two digit CPU #."""
+ dut_runner = mock.Mock(
+ return_value=(0, '/sys/devices/system/cpu/cpu0/online 1\n'
+ '/sys/devices/system/cpu/cpu1/online 0\n'
+ '/sys/devices/system/cpu/cpu10/online 1\n'
+ '/sys/devices/system/cpu/cpu11/online 1\n'
+ '/sys/devices/system/cpu/cpu2/online 1\n'
+ '/sys/devices/system/cpu/cpu3/online 0\n'
+ '/sys/devices/system/cpu/cpu4/online 1\n'
+ '/sys/devices/system/cpu/cpu5/online 0\n'
+ '/sys/devices/system/cpu/cpu6/online 1\n'
+ '/sys/devices/system/cpu/cpu7/online 0\n'
+ '/sys/devices/system/cpu/cpu8/online 1\n'
+ '/sys/devices/system/cpu/cpu9/online 0\n', ''))
+ cpu_online = self.runner.GetCpuOnline(dut_runner)
+ self.assertEqual(cpu_online, {
+ 0: 1,
+ 1: 0,
+ 2: 1,
+ 3: 0,
+ 4: 1,
+ 5: 0,
+ 6: 1,
+ 7: 0,
+ 8: 1,
+ 9: 0,
+ 10: 1,
+ 11: 1
+ })
+
+ def test_get_cpu_online_no_output(self):
+ """Test error case, no output."""
+ dut_runner = mock.Mock(return_value=(0, '', ''))
+ with self.assertRaises(AssertionError):
+ self.runner.GetCpuOnline(dut_runner)
+
+ def test_get_cpu_online_command_error(self):
+ """Test error case, command error."""
+ dut_runner = mock.Mock(side_effect=AssertionError)
+ with self.assertRaises(AssertionError):
+ self.runner.GetCpuOnline(dut_runner)
+
@mock.patch.object(suite_runner.SuiteRunner, 'SetupArmCores')
def test_setup_cpu_usage_little_on_arm(self, mock_setup_arm):
self.runner.SetupArmCores = mock_setup_arm
@@ -487,6 +557,106 @@ class SuiteRunnerTest(unittest.TestCase):
# 'exclusive_cores' on ARM CPU setup.
dut_runner.assert_called_once_with('cat /proc/cpuinfo')
+ def test_setup_cpu_freq_single_full(self):
+ online = [0]
+ dut_runner = mock.Mock(side_effect=[
+ (0,
+ '/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies\n',
+ ''),
+ (0, '1 2 3 4 5 6 7 8 9 10', ''),
+ (0, '', '')])
+ self.runner.dut_config['cpu_freq_pct'] = 100
+ self.runner.SetupCpuFreq(dut_runner, online)
+ self.assertGreaterEqual(dut_runner.call_count, 3)
+ self.assertEqual(
+ dut_runner.call_args,
+ mock.call('echo 10 | tee '
+ '/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq '
+ '/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq'))
+
+ def test_setup_cpu_freq_middle(self):
+ online = [0]
+ dut_runner = mock.Mock(side_effect=[
+ (0,
+ '/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies\n',
+ ''),
+ (0, '1 2 3 4 5 6 7 8 9 10', ''),
+ (0, '', '')])
+ self.runner.dut_config['cpu_freq_pct'] = 60
+ self.runner.SetupCpuFreq(dut_runner, online)
+ self.assertGreaterEqual(dut_runner.call_count, 2)
+ self.assertEqual(
+ dut_runner.call_args,
+ mock.call('echo 6 | tee '
+ '/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq '
+ '/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq'))
+
+ def test_setup_cpu_freq_lowest(self):
+ online = [0]
+ dut_runner = mock.Mock(side_effect=[
+ (0,
+ '/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies\n',
+ ''),
+ (0, '1 2 3 4 5 6 7 8 9 10', ''),
+ (0, '', '')])
+ self.runner.dut_config['cpu_freq_pct'] = 0
+ self.runner.SetupCpuFreq(dut_runner, online)
+ self.assertGreaterEqual(dut_runner.call_count, 2)
+ self.assertEqual(
+ dut_runner.call_args,
+ mock.call('echo 1 | tee '
+ '/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq '
+ '/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq'))
+
+ def test_setup_cpu_freq_multiple_middle(self):
+ online = [0, 1]
+ dut_runner = mock.Mock(side_effect=[
+ (0,
+ '/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies\n'
+ '/sys/devices/system/cpu/cpu1/cpufreq/scaling_available_frequencies\n',
+ ''),
+ (0, '1 2 3 4 5 6 7 8 9 10', ''),
+ (0, '', ''),
+ (0, '1 4 6 8 10 12 14 16 18 20', ''),
+ (0, '', '')])
+ self.runner.dut_config['cpu_freq_pct'] = 70
+ self.runner.SetupCpuFreq(dut_runner, online)
+ self.assertEqual(dut_runner.call_count, 5)
+ self.assertEqual(
+ dut_runner.call_args_list[2],
+ mock.call('echo 7 | tee '
+ '/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq '
+ '/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq'))
+ self.assertEqual(
+ dut_runner.call_args_list[4],
+ mock.call('echo 14 | tee '
+ '/sys/devices/system/cpu/cpu1/cpufreq/scaling_max_freq '
+ '/sys/devices/system/cpu/cpu1/cpufreq/scaling_min_freq'))
+
+ def test_setup_cpu_freq_no_scaling_available(self):
+ online = [0, 1]
+ dut_runner = mock.Mock(return_value=(2, '', 'No such file or directory'))
+ self.runner.dut_config['cpu_freq_pct'] = 50
+ self.runner.SetupCpuFreq(dut_runner, online)
+ dut_runner.assert_called_once()
+ self.assertNotRegexpMatches(dut_runner.call_args_list[0][0][0],
+ '^echo.*scaling_max_freq$')
+
+ def test_setup_cpu_freq_multiple_no_access(self):
+ online = [0, 1]
+ dut_runner = mock.Mock(side_effect=[
+ (0,
+ '/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies\n'
+ '/sys/devices/system/cpu/cpu1/cpufreq/scaling_available_frequencies\n',
+ ''),
+ (0, '1 4 6 8 10 12 14 16 18 20', ''),
+ AssertionError(),
+ ])
+ self.runner.dut_config['cpu_freq_pct'] = 30
+ # Error status causes log fatal.
+ with self.assertRaises(AssertionError):
+ self.runner.SetupCpuFreq(dut_runner, online)
+
def test_wait_cooldown_nowait(self):
dut_runner = mock.Mock(return_value=(0, '39000', ''))
self.runner.dut_config['cooldown_time'] = 10
@@ -607,7 +777,7 @@ class SuiteRunnerTest(unittest.TestCase):
mock_isdir.return_value = True
mock_chroot_runcmd.return_value = 0
self.mock_cmd_exec.ChrootRunCommandWOutput = mock_chroot_runcmd
- profiler_args = ('--profiler=custom_perf --profiler_args=\'perf_options'
+ profiler_args = ("--profiler=custom_perf --profiler_args='perf_options"
'="record -a -e cycles,instructions"\'')
res = self.runner.Telemetry_Crosperf_Run('lumpy1.cros', self.mock_label,
self.telemetry_crosperf_bench, '',