diff options
Diffstat (limited to 'crosperf/suite_runner_unittest.py')
-rwxr-xr-x | crosperf/suite_runner_unittest.py | 846 |
1 files changed, 124 insertions, 722 deletions
diff --git a/crosperf/suite_runner_unittest.py b/crosperf/suite_runner_unittest.py index 8b336eda..d7b9e770 100755 --- a/crosperf/suite_runner_unittest.py +++ b/crosperf/suite_runner_unittest.py @@ -1,10 +1,6 @@ #!/usr/bin/env python2 -# -*- coding: utf-8 -*- # -# Copyright (c) 2014 The Chromium OS Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - +# Copyright 2014 Google Inc. All Rights Reserved. """Unittest for suite_runner.""" from __future__ import print_function @@ -12,91 +8,18 @@ from __future__ import print_function import os.path import time -import unittest import mock +import unittest import suite_runner import label +import test_flag from benchmark import Benchmark from cros_utils import command_executer from cros_utils import logger -BIG_LITTLE_CPUINFO = """processor : 0 -model name : ARMv8 Processor rev 4 (v8l) -BogoMIPS : 48.00 -Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 -CPU implementer : 0x41 -CPU architecture: 8 -CPU variant : 0x0 -CPU part : 0xd03 -CPU revision : 4 - -processor : 1 -model name : ARMv8 Processor rev 4 (v8l) -BogoMIPS : 48.00 -Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 -CPU implementer : 0x41 -CPU architecture: 8 -CPU variant : 0x0 -CPU part : 0xd03 -CPU revision : 4 - -processor : 2 -model name : ARMv8 Processor rev 2 (v8l) -BogoMIPS : 48.00 -Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 -CPU implementer : 0x41 -CPU architecture: 8 -CPU variant : 0x0 -CPU part : 0xd08 -CPU revision : 2 -""" -LITTLE_ONLY_CPUINFO = """processor : 0 -model name : ARMv8 Processor rev 4 (v8l) -BogoMIPS : 48.00 -Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 -CPU implementer : 0x41 -CPU architecture: 8 -CPU variant : 0x0 -CPU part : 0xd03 -CPU revision : 4 - -processor : 1 -model name : ARMv8 Processor rev 4 (v8l) -BogoMIPS : 48.00 -Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 -CPU implementer : 0x41 -CPU architecture: 8 -CPU variant : 0x0 -CPU part : 0xd03 -CPU revision : 4 -""" - -NOT_BIG_LITTLE_CPUINFO = """processor : 0 -model name : ARMv7 Processor rev 1 (v7l) -Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls vfpv4 -CPU implementer : 0x41 -CPU architecture: 7 -CPU variant : 0x0 -CPU part : 0xc0d -CPU revision : 1 - -processor : 1 -model name : ARMv7 Processor rev 1 (v7l) -Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls vfpv4 -CPU implementer : 0x41 -CPU architecture: 7 -CPU variant : 0x0 -CPU part : 0xc0d -CPU revision : 1 - -Hardware : Rockchip (Device Tree) -Revision : 0000 -Serial : 0000000000000000 -""" - class SuiteRunnerTest(unittest.TestCase): """Class of SuiteRunner test.""" @@ -105,10 +28,9 @@ class SuiteRunnerTest(unittest.TestCase): mock_cmd_exec = mock.Mock(spec=command_executer.CommandExecuter) mock_cmd_term = mock.Mock(spec=command_executer.CommandTerminator) mock_logger = mock.Mock(spec=logger.Logger) - mock_label = label.MockLabel('lumpy', 'build', 'lumpy_chromeos_image', '', '', - '/tmp/chromeos', 'lumpy', - ['lumpy1.cros', 'lumpy.cros2'], '', '', False, - 'average', 'gcc', False, '') + mock_label = label.MockLabel( + 'lumpy', 'lumpy_chromeos_image', '', '/tmp/chromeos', 'lumpy', + ['lumpy1.cros', 'lumpy.cros2'], '', '', False, 'average', 'gcc', '') telemetry_crosperf_bench = Benchmark( 'b1_test', # name 'octane', # test_name @@ -140,20 +62,20 @@ class SuiteRunnerTest(unittest.TestCase): def __init__(self, *args, **kwargs): super(SuiteRunnerTest, self).__init__(*args, **kwargs) self.call_test_that_run = False - self.skylab_run_args = [] + self.pin_governor_args = [] self.test_that_args = [] self.telemetry_run_args = [] self.telemetry_crosperf_args = [] - self.call_skylab_run = False self.call_telemetry_crosperf_run = False - self.call_disable_aslr = False + self.call_pin_governor = False + self.call_telemetry_run = False def setUp(self): self.runner = suite_runner.SuiteRunner( - {}, self.mock_logger, 'verbose', self.mock_cmd_exec, self.mock_cmd_term) + 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'") @@ -163,24 +85,23 @@ class SuiteRunnerTest(unittest.TestCase): def test_run(self): def reset(): + self.call_pin_governor = False self.call_test_that_run = False - self.call_skylab_run = False + self.call_telemetry_run = False self.call_telemetry_crosperf_run = False - self.call_disable_aslr = False - self.skylab_run_args = [] + self.pin_governor_args = [] self.test_that_args = [] self.telemetry_run_args = [] self.telemetry_crosperf_args = [] - def FakeDisableASLR(runner): - # pylint fix for unused variable. - del runner - self.call_disable_aslr = True + def FakePinGovernor(machine, chroot): + self.call_pin_governor = True + self.pin_governor_args = [machine, chroot] - def FakeSkylabRun(test_label, benchmark, test_args, profiler_args): - self.skylab_run_args = [test_label, benchmark, test_args, profiler_args] - self.call_skylab_run = True - return 'Ran FakeSkylabRun' + def FakeTelemetryRun(machine, test_label, benchmark, profiler_args): + self.telemetry_run_args = [machine, test_label, benchmark, profiler_args] + self.call_telemetry_run = True + return 'Ran FakeTelemetryRun' def FakeTelemetryCrosperfRun(machine, test_label, benchmark, test_args, profiler_args): @@ -198,621 +119,95 @@ class SuiteRunnerTest(unittest.TestCase): self.call_test_that_run = True return 'Ran FakeTestThatRun' - def FakeRunner(command, ignore_status=False): - # pylint fix for unused variable. - del command, ignore_status - return 0, '', '' - - self.runner.DisableASLR = FakeDisableASLR - self.runner.Skylab_Run = FakeSkylabRun + self.runner.PinGovernorExecutionFrequencies = FakePinGovernor + self.runner.Telemetry_Run = FakeTelemetryRun 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 = '' - reset() - self.mock_label.skylab = True self.runner.Run(machine, self.mock_label, self.telemetry_bench, test_args, profiler_args) - self.assertFalse(self.call_disable_aslr) - self.assertTrue(self.call_skylab_run) + self.assertTrue(self.call_pin_governor) + self.assertTrue(self.call_telemetry_run) self.assertFalse(self.call_test_that_run) self.assertFalse(self.call_telemetry_crosperf_run) - 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() - self.runner.WaitCooldown.assert_not_called() - self.mock_label.skylab = False + self.assertEqual( + self.telemetry_run_args, + ['fake_machine', self.mock_label, self.telemetry_bench, '']) reset() self.runner.Run(machine, self.mock_label, self.test_that_bench, test_args, profiler_args) - self.assertTrue(self.call_disable_aslr) + self.assertTrue(self.call_pin_governor) + self.assertFalse(self.call_telemetry_run) self.assertTrue(self.call_test_that_run) self.assertFalse(self.call_telemetry_crosperf_run) self.assertEqual( 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( - 'fake_governor', FakeRunner, ignore_status=False) - self.runner.DisableTurbo.assert_called_once_with(FakeRunner) - self.runner.WaitCooldown.assert_not_called() reset() self.runner.Run(machine, self.mock_label, self.telemetry_crosperf_bench, test_args, profiler_args) - self.assertTrue(self.call_disable_aslr) + self.assertTrue(self.call_pin_governor) + self.assertFalse(self.call_telemetry_run) self.assertFalse(self.call_test_that_run) self.assertTrue(self.call_telemetry_crosperf_run) self.assertEqual(self.telemetry_crosperf_args, [ 'fake_machine', self.mock_label, self.telemetry_crosperf_bench, '', '' ]) - self.runner.DutWrapper.assert_called_with(machine, - self.mock_label.chromeos_root) - - 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() - self.runner.DutWrapper = mock.Mock(return_value=FakeRunner) - 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, '', '') - - self.runner.WaitCooldown.assert_called_once_with(FakeRunner) - self.runner.DisableASLR.assert_called_once() - 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, - mock.call('fake_governor', FakeRunner, ignore_status=False)) - - @mock.patch.object(command_executer.CommandExecuter, 'CrosRunCommandWOutput') - def test_dut_wrapper(self, mock_cros_runcmd): - self.mock_cmd_exec.CrosRunCommandWOutput = mock_cros_runcmd - mock_cros_runcmd.return_value = (0, '', '') - run_on_dut = self.runner.DutWrapper('lumpy.cros2', '/tmp/chromeos') - mock_cros_runcmd.assert_not_called() - run_on_dut('run command;') - mock_cros_runcmd.assert_called_once_with( - 'run command;', chromeos_root='/tmp/chromeos', machine='lumpy.cros2') - - @mock.patch.object(command_executer.CommandExecuter, 'CrosRunCommandWOutput') - def test_dut_wrapper_fatal_error(self, mock_cros_runcmd): - self.mock_cmd_exec.CrosRunCommandWOutput = mock_cros_runcmd - # Command returns error 1. - mock_cros_runcmd.return_value = (1, '', 'Error!') - run_on_dut = self.runner.DutWrapper('lumpy.cros2', '/tmp/chromeos') - mock_cros_runcmd.assert_not_called() - run_on_dut('run command;') - mock_cros_runcmd.assert_called_once_with( - 'run command;', chromeos_root='/tmp/chromeos', machine='lumpy.cros2') - # Error status causes log fatal. - self.assertEqual( - self.mock_logger.method_calls[-1], - mock.call.LogFatal('Command execution on DUT lumpy.cros2 failed.\n' - 'Failing command: run command;\nreturned 1\n' - 'Error message: Error!')) - - @mock.patch.object(command_executer.CommandExecuter, 'CrosRunCommandWOutput') - def test_dut_wrapper_ignore_error(self, mock_cros_runcmd): - self.mock_cmd_exec.CrosRunCommandWOutput = mock_cros_runcmd - # Command returns error 1. - mock_cros_runcmd.return_value = (1, '', 'Error!') - run_on_dut = self.runner.DutWrapper('lumpy.cros2', '/tmp/chromeos') - run_on_dut('run command;', ignore_status=True) - mock_cros_runcmd.assert_called_once_with( - 'run command;', chromeos_root='/tmp/chromeos', machine='lumpy.cros2') - # Error status is not fatal. LogError records the error message. - self.assertEqual( - self.mock_logger.method_calls[-1], - mock.call.LogError('Command execution on DUT lumpy.cros2 failed.\n' - 'Failing command: run command;\nreturned 1\n' - 'Error message: Error!\n' - '(Failure is considered non-fatal. Continue.)')) - - def test_disable_aslr(self): - run_on_dut = mock.Mock() - self.runner.DisableASLR(run_on_dut) + + @mock.patch.object(command_executer.CommandExecuter, 'CrosRunCommand') + def test_pin_governor_execution_frequencies(self, mock_cros_runcmd): + self.mock_cmd_exec.CrosRunCommand = mock_cros_runcmd + self.runner.PinGovernorExecutionFrequencies('lumpy1.cros', '/tmp/chromeos') + self.assertEqual(mock_cros_runcmd.call_count, 1) + cmd = mock_cros_runcmd.call_args_list[0][0] # pyformat: disable - set_cpu_cmd = ('set -e && ' - 'stop ui; ' - 'if [[ -e /proc/sys/kernel/randomize_va_space ]]; then ' - ' echo 0 > /proc/sys/kernel/randomize_va_space; ' - 'fi; ' - 'start ui ') - run_on_dut.assert_called_once_with(set_cpu_cmd) - - def test_set_cpu_governor(self): - dut_runner = mock.Mock(return_value=(0, '', '')) - self.runner.SetCpuGovernor('new_governor', dut_runner, ignore_status=False) - set_cpu_cmd = ( - 'for f in `ls -d /sys/devices/system/cpu/cpu*/cpufreq 2>/dev/null`; do ' - # Skip writing scaling_governor if cpu is not online. - ' [[ -e ${f/cpufreq/online} ]] && grep -q 0 ${f/cpufreq/online} ' - ' && continue; ' - ' cd $f; ' - ' if [[ -e scaling_governor ]]; then ' - ' echo %s > scaling_governor; fi; ' - 'done; ') - dut_runner.assert_called_once_with( - set_cpu_cmd % 'new_governor', ignore_status=False) - - def test_set_cpu_governor_propagate_error(self): - dut_runner = mock.Mock(return_value=(1, '', 'Error.')) - self.runner.SetCpuGovernor('non-exist_governor', dut_runner) - set_cpu_cmd = ( - 'for f in `ls -d /sys/devices/system/cpu/cpu*/cpufreq 2>/dev/null`; do ' - # Skip writing scaling_governor if cpu is not online. - ' [[ -e ${f/cpufreq/online} ]] && grep -q 0 ${f/cpufreq/online} ' - ' && continue; ' - ' cd $f; ' - ' if [[ -e scaling_governor ]]; then ' - ' echo %s > scaling_governor; fi; ' - 'done; ') - # By default error status is fatal. - dut_runner.assert_called_once_with( - set_cpu_cmd % 'non-exist_governor', ignore_status=False) - - def test_set_cpu_governor_ignore_status(self): - dut_runner = mock.Mock(return_value=(1, '', 'Error.')) - ret_code = self.runner.SetCpuGovernor( - 'non-exist_governor', dut_runner, ignore_status=True) - set_cpu_cmd = ( - 'for f in `ls -d /sys/devices/system/cpu/cpu*/cpufreq 2>/dev/null`; do ' - # Skip writing scaling_governor if cpu is not online. - ' [[ -e ${f/cpufreq/online} ]] && grep -q 0 ${f/cpufreq/online} ' - ' && continue; ' - ' cd $f; ' - ' if [[ -e scaling_governor ]]; then ' - ' echo %s > scaling_governor; fi; ' - '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, '', '')) - self.runner.DisableTurbo(dut_runner) set_cpu_cmd = ( + 'set -e && ' # Disable Turbo in Intel pstate driver 'if [[ -e /sys/devices/system/cpu/intel_pstate/no_turbo ]]; then ' ' if grep -q 0 /sys/devices/system/cpu/intel_pstate/no_turbo; then ' ' echo -n 1 > /sys/devices/system/cpu/intel_pstate/no_turbo; ' ' fi; ' - '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 - dut_runner = mock.Mock(return_value=(0, 'armv7l', '')) - self.runner.dut_config['cpu_usage'] = 'little_only' - self.runner.SetupCpuUsage(dut_runner) - self.runner.SetupArmCores.assert_called_once_with(dut_runner) - - @mock.patch.object(suite_runner.SuiteRunner, 'SetupArmCores') - def test_setup_cpu_usage_big_on_aarch64(self, mock_setup_arm): - self.runner.SetupArmCores = mock_setup_arm - dut_runner = mock.Mock(return_value=(0, 'aarch64', '')) - self.runner.dut_config['cpu_usage'] = 'big_only' - self.runner.SetupCpuUsage(dut_runner) - self.runner.SetupArmCores.assert_called_once_with(dut_runner) - - @mock.patch.object(suite_runner.SuiteRunner, 'SetupArmCores') - def test_setup_cpu_usage_big_on_intel(self, mock_setup_arm): - self.runner.SetupArmCores = mock_setup_arm - dut_runner = mock.Mock(return_value=(0, 'x86_64', '')) - self.runner.dut_config['cpu_usage'] = 'big_only' - self.runner.SetupCpuUsage(dut_runner) - # Check that SetupArmCores not called with invalid setup. - self.runner.SetupArmCores.assert_not_called() - - @mock.patch.object(suite_runner.SuiteRunner, 'SetupArmCores') - def test_setup_cpu_usage_all_on_intel(self, mock_setup_arm): - self.runner.SetupArmCores = mock_setup_arm - dut_runner = mock.Mock(return_value=(0, 'x86_64', '')) - self.runner.dut_config['cpu_usage'] = 'all' - self.runner.SetupCpuUsage(dut_runner) - # Check that SetupArmCores not called in general case. - self.runner.SetupArmCores.assert_not_called() - - def test_setup_arm_cores_big_on_big_little(self): - dut_runner = mock.Mock(side_effect=[ - (0, BIG_LITTLE_CPUINFO, ''), - (0, '', ''), - ]) - self.runner.dut_config['cpu_usage'] = 'big_only' - self.runner.SetupArmCores(dut_runner) - dut_runner.assert_called_with( - 'echo 1 | tee /sys/devices/system/cpu/cpu{2}/online; ' - 'echo 0 | tee /sys/devices/system/cpu/cpu{0,1}/online') - - def test_setup_arm_cores_little_on_big_little(self): - dut_runner = mock.Mock(side_effect=[ - (0, BIG_LITTLE_CPUINFO, ''), - (0, '', ''), - ]) - self.runner.dut_config['cpu_usage'] = 'little_only' - self.runner.SetupArmCores(dut_runner) - dut_runner.assert_called_with( - 'echo 1 | tee /sys/devices/system/cpu/cpu{0,1}/online; ' - 'echo 0 | tee /sys/devices/system/cpu/cpu{2}/online') - - def test_setup_arm_cores_invalid_config(self): - dut_runner = mock.Mock(side_effect=[ - (0, LITTLE_ONLY_CPUINFO, ''), - (0, '', ''), - ]) - self.runner.dut_config['cpu_usage'] = 'big_only' - self.runner.SetupArmCores(dut_runner) - # Check that setup command is not sent when trying - # to use 'big_only' on a platform with all little cores. - dut_runner.assert_called_once_with('cat /proc/cpuinfo') - - def test_setup_arm_cores_not_big_little(self): - dut_runner = mock.Mock(side_effect=[ - (0, NOT_BIG_LITTLE_CPUINFO, ''), - (0, '', ''), - ]) - self.runner.dut_config['cpu_usage'] = 'big_only' - self.runner.SetupArmCores(dut_runner) - # Check that setup command is not sent when trying - # to use 'big_only' on a platform w/o support of big/little. - dut_runner.assert_called_once_with('cat /proc/cpuinfo') - - def test_setup_arm_cores_unsupported_cpu_usage(self): - dut_runner = mock.Mock(side_effect=[ - (0, BIG_LITTLE_CPUINFO, ''), - (0, '', ''), - ]) - self.runner.dut_config['cpu_usage'] = 'exclusive_cores' - self.runner.SetupArmCores(dut_runner) - # Check that setup command is not sent when trying to use - # '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) - - @mock.patch.object(time, 'sleep') - def test_wait_cooldown_nowait(self, mock_sleep): - mock_sleep.return_value = 0 - dut_runner = mock.Mock(return_value=(0, '39000', '')) - self.runner.dut_config['cooldown_time'] = 10 - self.runner.dut_config['cooldown_temp'] = 40 - wait_time = self.runner.WaitCooldown(dut_runner) - # Send command to DUT only once to check temperature - # and make sure it does not exceed the threshold. - dut_runner.assert_called_once() - mock_sleep.assert_not_called() - self.assertEqual(wait_time, 0) - - @mock.patch.object(time, 'sleep') - def test_wait_cooldown_needwait_once(self, mock_sleep): - """Wait one iteration for cooldown. - - Set large enough timeout and changing temperature - output. Make sure it exits when expected value - received. - Expect that WaitCooldown check temp twice. - """ - mock_sleep.return_value = 0 - dut_runner = mock.Mock(side_effect=[(0, '41000', ''), (0, '39999', '')]) - self.runner.dut_config['cooldown_time'] = 100 - self.runner.dut_config['cooldown_temp'] = 40 - wait_time = self.runner.WaitCooldown(dut_runner) - dut_runner.assert_called() - self.assertEqual(dut_runner.call_count, 2) - mock_sleep.assert_called() - self.assertGreater(wait_time, 0) - - @mock.patch.object(time, 'sleep') - def test_wait_cooldown_needwait(self, mock_sleep): - """Test exit by timeout. - - Send command to DUT checking the temperature and - check repeatedly until timeout goes off. - Output from temperature sensor never changes. - """ - mock_sleep.return_value = 0 - dut_runner = mock.Mock(return_value=(0, '41000', '')) - self.runner.dut_config['cooldown_time'] = 60 - self.runner.dut_config['cooldown_temp'] = 40 - wait_time = self.runner.WaitCooldown(dut_runner) - dut_runner.assert_called() - self.assertGreater(dut_runner.call_count, 2) - mock_sleep.assert_called() - self.assertGreater(wait_time, 0) - - @mock.patch.object(time, 'sleep') - def test_wait_cooldown_needwait_multtemp(self, mock_sleep): - """Wait until all temps go down. - - Set large enough timeout and changing temperature - output. Make sure it exits when expected value - for all temperatures received. - Expect 3 checks. - """ - mock_sleep.return_value = 0 - dut_runner = mock.Mock(side_effect=[ - (0, '41000\n20000\n30000\n45000', ''), - (0, '39000\n20000\n30000\n41000', ''), - (0, '39000\n20000\n30000\n31000', ''), - ]) - self.runner.dut_config['cooldown_time'] = 100 - self.runner.dut_config['cooldown_temp'] = 40 - wait_time = self.runner.WaitCooldown(dut_runner) - dut_runner.assert_called() - self.assertEqual(dut_runner.call_count, 3) - mock_sleep.assert_called() - self.assertGreater(wait_time, 0) + 'fi; ' + # Set governor to performance for each cpu + 'for f in /sys/devices/system/cpu/cpu*/cpufreq; do ' + 'cd $f; ' + 'echo performance > scaling_governor; ' + 'done' + ) + # pyformat: enable + self.assertEqual(cmd, (set_cpu_cmd,)) @mock.patch.object(time, 'sleep') - def test_wait_cooldown_thermal_error(self, mock_sleep): - """Handle error status. - - Any error should be considered non-fatal. - """ - mock_sleep.return_value = 0 - dut_runner = mock.Mock(side_effect=[ - (1, '39000\n20000\n30000\n41000', 'Thermal error'), - (1, '39000\n20000\n30000\n31000', 'Thermal error'), - ]) - self.runner.dut_config['cooldown_time'] = 10 - self.runner.dut_config['cooldown_temp'] = 40 - wait_time = self.runner.WaitCooldown(dut_runner) - # Check that errors are ignored. - dut_runner.assert_called_with( - 'cat /sys/class/thermal/thermal_zone*/temp', ignore_status=True) - self.assertEqual(dut_runner.call_count, 2) - # Check that we are waiting even when an error is returned - # as soon as data is coming. - mock_sleep.assert_called() - self.assertGreater(wait_time, 0) - - @mock.patch.object(time, 'sleep') - def test_wait_cooldown_thermal_no_output(self, mock_sleep): - """Handle no output. - - Check handling of empty stdout. - """ - mock_sleep.return_value = 0 - dut_runner = mock.Mock(side_effect=[(1, '', 'Thermal error')]) - self.runner.dut_config['cooldown_time'] = 10 - self.runner.dut_config['cooldown_temp'] = 40 - wait_time = self.runner.WaitCooldown(dut_runner) - # Check that errors are ignored. - dut_runner.assert_called_once_with( - 'cat /sys/class/thermal/thermal_zone*/temp', ignore_status=True) - # No wait. - mock_sleep.assert_not_called() - self.assertEqual(wait_time, 0) + @mock.patch.object(command_executer.CommandExecuter, 'CrosRunCommand') + def test_reboot_machine(self, mock_cros_runcmd, mock_sleep): - @mock.patch.object(time, 'sleep') - def test_wait_cooldown_thermal_ws_output(self, mock_sleep): - """Handle whitespace output. - - Check handling of whitespace only. - """ - mock_sleep.return_value = 0 - dut_runner = mock.Mock(side_effect=[(1, '\n', 'Thermal error')]) - self.runner.dut_config['cooldown_time'] = 10 - self.runner.dut_config['cooldown_temp'] = 40 - wait_time = self.runner.WaitCooldown(dut_runner) - # Check that errors are ignored. - dut_runner.assert_called_once_with( - 'cat /sys/class/thermal/thermal_zone*/temp', ignore_status=True) - # No wait. - mock_sleep.assert_not_called() - self.assertEqual(wait_time, 0) + def FakePinGovernor(machine_name, chromeos_root): + if machine_name or chromeos_root: + pass - @mock.patch.object(command_executer.CommandExecuter, 'CrosRunCommand') - def test_restart_ui(self, mock_cros_runcmd): self.mock_cmd_exec.CrosRunCommand = mock_cros_runcmd + self.runner.PinGovernorExecutionFrequencies = FakePinGovernor self.runner.RestartUI('lumpy1.cros', '/tmp/chromeos') - mock_cros_runcmd.assert_called_once_with( - 'stop ui; sleep 5; start ui', - chromeos_root='/tmp/chromeos', - machine='lumpy1.cros') + self.assertEqual(mock_cros_runcmd.call_count, 1) + self.assertEqual(mock_cros_runcmd.call_args_list[0][0], + ('stop ui; sleep 5; start ui',)) @mock.patch.object(command_executer.CommandExecuter, 'CrosRunCommand') @mock.patch.object(command_executer.CommandExecuter, 'ChrootRunCommandWOutput') def test_test_that_run(self, mock_chroot_runcmd, mock_cros_runcmd): + def FakeRebootMachine(machine, chroot): + if machine or chroot: + pass + def FakeLogMsg(fd, termfd, msg, flush=True): if fd or termfd or msg or flush: pass @@ -820,6 +215,7 @@ class SuiteRunnerTest(unittest.TestCase): save_log_msg = self.real_logger.LogMsg self.real_logger.LogMsg = FakeLogMsg self.runner.logger = self.real_logger + self.runner.RebootMachine = FakeRebootMachine raised_exception = False try: @@ -857,9 +253,8 @@ 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"\'') - self.runner.dut_config['top_interval'] = 3 res = self.runner.Telemetry_Crosperf_Run('lumpy1.cros', self.mock_label, self.telemetry_crosperf_bench, '', profiler_args) @@ -870,11 +265,10 @@ class SuiteRunnerTest(unittest.TestCase): self.assertEqual(args_list[0], '/tmp/chromeos') self.assertEqual(args_list[1], ('/usr/bin/test_that --autotest_dir ' - '~/trunk/src/third_party/autotest/files --fast ' - '--board=lumpy --args=" run_local=False test=octane ' - 'turbostat=True top_interval=3 profiler=custom_perf ' - 'profiler_args=\'record -a -e cycles,instructions\'" ' - 'lumpy1.cros telemetry_Crosperf')) + '~/trunk/src/third_party/autotest/files ' + ' --board=lumpy --args=" run_local=False test=octane ' + 'profiler=custom_perf profiler_args=\'record -a -e ' + 'cycles,instructions\'" lumpy1.cros telemetry_Crosperf')) self.assertEqual(args_dict['cros_sdk_options'], ('--no-ns-pid --chrome_root= ' '--chrome_root_mount=/tmp/chrome_root ' @@ -882,59 +276,67 @@ class SuiteRunnerTest(unittest.TestCase): self.assertEqual(args_dict['command_terminator'], self.mock_cmd_term) self.assertEqual(len(args_dict), 2) + @mock.patch.object(os.path, 'isdir') + @mock.patch.object(os.path, 'exists') @mock.patch.object(command_executer.CommandExecuter, 'RunCommandWOutput') - def test_skylab_run(self, mock_runcmd): + def test_telemetry_run(self, mock_runcmd, mock_exists, mock_isdir): + + def FakeLogMsg(fd, termfd, msg, flush=True): + if fd or termfd or msg or flush: + pass - def FakeDownloadResult(l, task_id): - if l and task_id: - self.assertEqual(task_id, '12345') - return 0 + save_log_msg = self.real_logger.LogMsg + self.real_logger.LogMsg = FakeLogMsg + mock_runcmd.return_value = 0 - mock_runcmd.return_value = \ - (0, - '"success":true\nCreated Swarming task https://swarming/task?id=12345', - '') self.mock_cmd_exec.RunCommandWOutput = mock_runcmd - self.mock_label.skylab = True - self.runner.DownloadResult = FakeDownloadResult - res = self.runner.Skylab_Run(self.mock_label, self.test_that_bench, '', '') - ret_tup = (0, '\nResults placed in tmp/swarming-12345\n', '') - self.assertEqual(res, ret_tup) - self.assertEqual(mock_runcmd.call_count, 2) - - args_list = mock_runcmd.call_args_list[0][0] - args_dict = mock_runcmd.call_args_list[0][1] - self.assertEqual(args_list[0], - ('/usr/local/bin/skylab create-test ' - '-dim dut_name:lumpy1 -dim dut_name:lumpy.cros2 ' - '-bb=false -client-test -board=lumpy -image=build ' - '-pool=DUT_POOL_QUOTA octane')) - self.assertEqual(args_dict['command_terminator'], self.mock_cmd_term) + self.runner.logger = self.real_logger - args_list = mock_runcmd.call_args_list[1][0] - self.assertEqual(args_list[0], ('skylab wait-task -bb=false 12345')) - self.assertEqual(args_dict['command_terminator'], self.mock_cmd_term) + profiler_args = ('--profiler=custom_perf --profiler_args=\'perf_options' + '="record -a -e cycles,instructions"\'') - @mock.patch.object(time, 'sleep') - @mock.patch.object(command_executer.CommandExecuter, 'RunCommand') - def test_download_result(self, mock_runcmd, mock_sleep): - mock_runcmd.return_value = 0 - mock_sleep.return_value = 0 - self.mock_cmd_exec.RunCommand = mock_runcmd - - self.runner.DownloadResult(self.mock_label, '12345') - - self.assertEqual(mock_runcmd.call_count, 2) - cmd = mock_runcmd.call_args_list[0][0][0] - self.assertEqual(cmd, - ('/tmp/chromeos/src/chromium/depot_tools/gsutil.py ls ' - 'gs://chromeos-autotest-results/swarming-12345/' - 'autoserv_test')) - cmd = mock_runcmd.call_args_list[1][0][0] - self.assertEqual(cmd, - ('/tmp/chromeos/src/chromium/depot_tools/gsutil.py -mq ' - 'cp -r gs://chromeos-autotest-results/swarming-12345 ' - '/tmp/chromeos/chroot/tmp')) + raises_exception = False + mock_isdir.return_value = False + try: + self.runner.Telemetry_Run('lumpy1.cros', self.mock_label, + self.telemetry_bench, '') + except SystemExit: + raises_exception = True + self.assertTrue(raises_exception) + + raises_exception = False + mock_isdir.return_value = True + mock_exists.return_value = False + try: + self.runner.Telemetry_Run('lumpy1.cros', self.mock_label, + self.telemetry_bench, '') + except SystemExit: + raises_exception = True + self.assertTrue(raises_exception) + + raises_exception = False + mock_isdir.return_value = True + mock_exists.return_value = True + try: + self.runner.Telemetry_Run('lumpy1.cros', self.mock_label, + self.telemetry_bench, profiler_args) + except SystemExit: + raises_exception = True + self.assertTrue(raises_exception) + + test_flag.SetTestMode(True) + res = self.runner.Telemetry_Run('lumpy1.cros', self.mock_label, + self.telemetry_bench, '') + self.assertEqual(res, 0) + self.assertEqual(mock_runcmd.call_count, 1) + self.assertEqual( + mock_runcmd.call_args_list[0][0], + (('cd src/tools/perf && ./run_measurement ' + '--browser=cros-chrome --output-format=csv ' + '--remote=lumpy1.cros --identity /tmp/chromeos/src/scripts' + '/mod_for_test_scripts/ssh_keys/testing_rsa octane '),)) + + self.real_logger.LogMsg = save_log_msg if __name__ == '__main__': |