1import logging
2
3from autotest_lib.client.common_lib.cros import crash_detector
4from autotest_lib.client.common_lib.cros.cfm.usb import usb_device_collector
5from autotest_lib.client.common_lib.cros.cfm.usb import usb_port_manager
6from autotest_lib.server.cros.cfm import cfm_base_test
7from autotest_lib.server.cros.cfm.configurable_test import action_context
8from autotest_lib.server.cros.cfm.utils import bond_http_api
9from autotest_lib.server.cros.cfm.utils import perf_metrics_collector
10
11
12class TestRunner(object):
13    """
14    Runs a test.
15    """
16    def __init__(self, context):
17        """
18        Initializes.
19
20        @param context ActionContext providing the dependencies for the test.
21        """
22        self.context = context
23
24    def run_test(self, cfm_test):
25        """
26        Runs one test.
27
28        @param cfm_test CfmTest instance to execute.
29        """
30        logging.info('RUNNING:\n%s', str(cfm_test))
31        cfm_test.scenario.execute(self.context)
32
33
34class HostFileContentsCollector(object):
35    """
36    File contents collector that executes commands against the host.
37    """
38    def __init__(self, host):
39        """
40        Initializes with a host.
41
42        @param host a host object as available from CfmBaseTest.host
43        """
44        self.host = host
45
46    def collect_file_contents(self, path):
47        """
48        Returns the file contents of the file at the specified path.
49
50        @param path The path of the file.
51        @returns The contents of the file
52        """
53        return self.host.run_output('cat "%s"' % path)
54
55
56class ConfigurableCfmTest(cfm_base_test.CfmBaseTest):
57    """
58    Base class for the actual Autotests that execute configurable CFM tests.
59    """
60    version = 1
61
62    def initialize(self, host, cfm_test):
63        """
64        Initializes the test.
65
66        @param host The host the test is run against
67        @param cfm_test CfmTest instance to execute.
68        """
69        (super(ConfigurableCfmTest, self)
70            .initialize(host,
71                        cfm_test.configuration.run_test_only,
72                        cfm_test.configuration.skip_enrollment))
73        self.cfm_test = cfm_test
74        device_collector = usb_device_collector.UsbDeviceCollector(host)
75        port_manager = usb_port_manager.UsbPortManager(host)
76        crash_file_detector = crash_detector.CrashDetector(host)
77        # Call get_new_crash_files() once. This records the current crash
78        # files so that subsequent calls only check the delta, i.e.
79        # new crash files from here on.
80        crash_file_detector.get_new_crash_files()
81        # self.cfm_facade is inherited from CfmBaseTest.
82        context = action_context.ActionContext(
83                cfm_facade=self.cfm_facade,
84                file_contents_collector=HostFileContentsCollector(host),
85                host=host,
86                usb_device_collector=device_collector,
87                usb_port_manager=port_manager,
88                crash_detector=crash_file_detector,
89                perf_metrics_collector=self._create_perf_metrics_collector(),
90                bond_api=bond_http_api.BondHttpApi())
91        self.test_runner = TestRunner(context)
92
93    def _create_perf_metrics_collector(self):
94        system_facade = self._facade_factory.create_system_facade()
95        return perf_metrics_collector.PerfMetricsCollector(system_facade,
96            self.cfm_facade, self.output_perf_value)
97
98    def run_once(self):
99        """
100        Runs the test.
101        """
102        self.test_runner.run_test(self.cfm_test)
103