233 lines
9.9 KiB
Python
233 lines
9.9 KiB
Python
import mock
|
|
import unittest
|
|
|
|
from autotest_lib.client.common_lib.cros.cfm.usb import usb_device
|
|
from autotest_lib.client.common_lib.cros.cfm.usb import usb_device_spec
|
|
from autotest_lib.server.cros.cfm.configurable_test import actions
|
|
from autotest_lib.server.cros.cfm.configurable_test import action_context
|
|
from autotest_lib.server.cros.cfm.configurable_test import scenario
|
|
|
|
# Constants to use in case the actual values are irrelevant.
|
|
USB_DEVICE_SPEC = usb_device_spec.UsbDeviceSpec(
|
|
'vid', 'pid', 'product', ['iface'])
|
|
|
|
USB_DEVICE = usb_device.UsbDevice('v', 'p', 'prod', ['if'], 1, 2, 1)
|
|
|
|
|
|
# Test, disable missing-docstring
|
|
# pylint: disable=missing-docstring
|
|
class TestActions(unittest.TestCase):
|
|
"""
|
|
Tests for the available actions for configurable CFM tests to run.
|
|
"""
|
|
|
|
def setUp(self):
|
|
self.host_mock = mock.MagicMock()
|
|
self.cfm_facade_mock = mock.MagicMock()
|
|
self.usb_device_collector_mock = mock.MagicMock()
|
|
self.usb_port_manager_mock = mock.MagicMock()
|
|
self.crash_detector_mock = mock.MagicMock()
|
|
self.metrics_collector_mock = mock.MagicMock()
|
|
self.context_with_mocks = action_context.ActionContext(
|
|
host=self.host_mock,
|
|
cfm_facade=self.cfm_facade_mock,
|
|
usb_device_collector=self.usb_device_collector_mock,
|
|
usb_port_manager=self.usb_port_manager_mock,
|
|
crash_detector=self.crash_detector_mock,
|
|
perf_metrics_collector=self.metrics_collector_mock)
|
|
|
|
|
|
def test_assert_file_does_not_contain_no_match(self):
|
|
action = actions.AssertFileDoesNotContain('/foo', ['EE', 'WW'])
|
|
context = action_context.ActionContext(
|
|
file_contents_collector=FakeCollector('abc\ndef'))
|
|
action.execute(context)
|
|
|
|
def test_assert_file_does_not_contain_match(self):
|
|
action = actions.AssertFileDoesNotContain('/foo', ['EE', 'WW'])
|
|
context = action_context.ActionContext(
|
|
file_contents_collector=FakeCollector('abc\naWWd'))
|
|
self.assertRaises(AssertionError, lambda: action.execute(context))
|
|
|
|
def test_assert_file_does_not_contain_regex_match(self):
|
|
action = actions.AssertFileDoesNotContain('/foo', ['EE', 'W{3}Q+'])
|
|
context = action_context.ActionContext(
|
|
file_contents_collector=FakeCollector('abc\naWWWQQd'))
|
|
self.assertRaises(AssertionError, lambda: action.execute(context))
|
|
|
|
def test_reboot_dut_no_restart(self):
|
|
action = actions.RebootDut()
|
|
action.execute(self.context_with_mocks)
|
|
self.host_mock.reboot.assert_called_once_with()
|
|
self.assertFalse(self.cfm_facade_mock.method_calls)
|
|
|
|
def test_reboot_dut_with_restart(self):
|
|
action = actions.RebootDut(restart_chrome_for_cfm=True)
|
|
action.execute(self.context_with_mocks)
|
|
self.host_mock.reboot.assert_called_once_with()
|
|
(self.cfm_facade_mock.restart_chrome_for_cfm
|
|
.assert_called_once_with())
|
|
(self.cfm_facade_mock.wait_for_telemetry_commands
|
|
.assert_called_once_with())
|
|
|
|
def test_assert_usb_device_collector(self):
|
|
spec = usb_device_spec.UsbDeviceSpec(
|
|
'vid', 'pid', 'product', ['iface'])
|
|
action = actions.AssertUsbDevices([spec], lambda x: True)
|
|
action.execute(self.context_with_mocks)
|
|
|
|
def test_assert_usb_device_collector_matching_predicate(self):
|
|
spec = usb_device_spec.UsbDeviceSpec(
|
|
'vid', 'pid', 'product', ['iface'])
|
|
device = usb_device.UsbDevice(
|
|
'v', 'p', 'prod', ['if'], 1, 2, 1)
|
|
self.usb_device_collector_mock.get_devices_by_spec = mock.Mock(
|
|
return_value=[device])
|
|
action = actions.AssertUsbDevices(
|
|
[spec], lambda x: x[0].product_id == 'p')
|
|
action.execute(self.context_with_mocks)
|
|
|
|
def test_assert_usb_device_collector_non_matching_predicate(self):
|
|
spec = usb_device_spec.UsbDeviceSpec(
|
|
'vid', 'pid', 'product', ['iface'])
|
|
device = usb_device.UsbDevice(
|
|
'v', 'p', 'prod', ['if'], 1, 2, 1)
|
|
self.usb_device_collector_mock.get_devices_by_spec = mock.Mock(
|
|
return_value=[device])
|
|
action = actions.AssertUsbDevices(
|
|
[spec], lambda x: x[0].product_id == 'r')
|
|
self.assertRaises(AssertionError, lambda: action.execute(
|
|
self.context_with_mocks))
|
|
|
|
def test_assert_usb_device_collector_default_predicate(self):
|
|
self.usb_device_collector_mock.get_devices_by_spec = mock.Mock(
|
|
return_value=[USB_DEVICE]) # Default checks list is of size 1
|
|
action = actions.AssertUsbDevices([USB_DEVICE_SPEC])
|
|
action.execute(self.context_with_mocks)
|
|
|
|
def test_select_scenario_at_random(self):
|
|
dummy_action1 = DummyAction()
|
|
dummy_action2 = DummyAction()
|
|
scenarios = [scenario.Scenario(dummy_action1),
|
|
scenario.Scenario(dummy_action2)]
|
|
action = actions.SelectScenarioAtRandom(scenarios, 10)
|
|
action.execute(self.context_with_mocks)
|
|
# Assert that our actions were executed the expected number of times.
|
|
total_executes = (dummy_action1.executed_times
|
|
+ dummy_action2.executed_times)
|
|
self.assertEqual(10, total_executes)
|
|
|
|
def test_select_scenario_at_random_str_contains_seed(self):
|
|
action = actions.SelectScenarioAtRandom([], 10, 123)
|
|
self.assertTrue('seed=123' in str(action))
|
|
|
|
def test_select_scenario_at_random_same_seed_same_actions(self):
|
|
scenario1_action1 = DummyAction()
|
|
scenario1_action2 = DummyAction()
|
|
scenarios1 = [scenario.Scenario(scenario1_action1),
|
|
scenario.Scenario(scenario1_action2)]
|
|
scenario2_action1 = DummyAction()
|
|
scenario2_action2 = DummyAction()
|
|
scenarios2 = [scenario.Scenario(scenario2_action1),
|
|
scenario.Scenario(scenario2_action2)]
|
|
action1 = actions.SelectScenarioAtRandom(scenarios1, 100, 0)
|
|
action2 = actions.SelectScenarioAtRandom(scenarios2, 100, 0)
|
|
action1.execute(self.context_with_mocks)
|
|
action2.execute(self.context_with_mocks)
|
|
self.assertEqual(scenario1_action1.executed_times,
|
|
scenario2_action1.executed_times)
|
|
self.assertEqual(scenario1_action2.executed_times,
|
|
scenario2_action2.executed_times)
|
|
|
|
def test_power_cycle_usb_port(self):
|
|
device = usb_device.UsbDevice(
|
|
'v', 'p', 'prod', ['if'], 1, 2, 1)
|
|
self.usb_device_collector_mock.get_devices_by_spec = mock.Mock(
|
|
side_effect=[[device, device], [device], [device, device]])
|
|
action = actions.PowerCycleUsbPort(
|
|
[USB_DEVICE_SPEC], 0, lambda x: [x[0]])
|
|
action.execute(self.context_with_mocks)
|
|
self.usb_port_manager_mock.set_port_power.assert_has_calls(
|
|
[mock.call([(1, 2)], False), mock.call([(1, 2)], True)])
|
|
|
|
def test_power_cycle_usb_port_device_does_not_turn_off(self):
|
|
# Return the same device all the time - i.e., it does not turn off.
|
|
self.usb_device_collector_mock.get_devices_by_spec = mock.Mock(
|
|
return_value=[USB_DEVICE])
|
|
action = actions.PowerCycleUsbPort([USB_DEVICE_SPEC], 0)
|
|
self.assertRaises(
|
|
actions.TimeoutError,
|
|
lambda: action.execute(self.context_with_mocks))
|
|
|
|
def test_power_cycle_usb_port_device_does_not_turn_on(self):
|
|
self.usb_device_collector_mock.get_devices_by_spec = mock.Mock(
|
|
side_effect=[[USB_DEVICE, USB_DEVICE], [], [USB_DEVICE]])
|
|
action = actions.PowerCycleUsbPort([USB_DEVICE_SPEC], 0)
|
|
self.assertRaises(
|
|
actions.TimeoutError,
|
|
lambda: action.execute(self.context_with_mocks))
|
|
|
|
def test_retry_action_success_after_retry(self):
|
|
action = actions.RetryAssertAction(RaisesFirstTimeAction(), 3, 0)
|
|
action.execute(self.context_with_mocks)
|
|
|
|
def test_retry_action_fail_when_no_more_retries(self):
|
|
action = actions.RetryAssertAction(RaisesFirstTimeAction(), 1)
|
|
self.assertRaises(
|
|
AssertionError, lambda: action.execute(self.context_with_mocks))
|
|
|
|
def test_assert_no_new_crashes(self):
|
|
action = actions.AssertNoNewCrashes()
|
|
self.crash_detector_mock.get_new_crash_files = mock.Mock(
|
|
return_value=[])
|
|
action.do_execute(self.context_with_mocks)
|
|
|
|
def test_assert_no_new_crashes_crash_detected(self):
|
|
action = actions.AssertNoNewCrashes()
|
|
self.crash_detector_mock.get_new_crash_files = mock.Mock(
|
|
return_value=['/a/new/crash/file'])
|
|
self.assertRaises(
|
|
AssertionError,
|
|
lambda: action.do_execute(self.context_with_mocks))
|
|
|
|
def test_start_metrics_colllection(self):
|
|
action = actions.StartPerfMetricsCollection()
|
|
action.execute(self.context_with_mocks)
|
|
self.metrics_collector_mock.start.assert_called_once_with()
|
|
|
|
def test_stop_metrics_colllection(self):
|
|
action = actions.StopPerfMetricsCollection()
|
|
action.execute(self.context_with_mocks)
|
|
self.metrics_collector_mock.stop.assert_called_once_with()
|
|
|
|
def test_upload_metrics(self):
|
|
action = actions.UploadPerfMetrics()
|
|
action.execute(self.context_with_mocks)
|
|
self.metrics_collector_mock.upload_metrics.assert_called_once_with()
|
|
|
|
|
|
|
|
class FakeCollector(object):
|
|
def __init__(self, contents):
|
|
self.contents = contents
|
|
|
|
def collect_file_contents(self, path):
|
|
return self.contents
|
|
|
|
class DummyAction(actions.Action):
|
|
def __init__(self):
|
|
self.executed_times = 0
|
|
|
|
def do_execute(self, context):
|
|
self.executed_times += 1
|
|
|
|
class RaisesFirstTimeAction(actions.Action):
|
|
def __init__(self):
|
|
self.executed = False
|
|
|
|
def do_execute(self, context):
|
|
if not self.executed:
|
|
self.executed = True
|
|
raise AssertionError()
|
|
|