1# Copyright 2017 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import logging
6import os
7import time
8
9from autotest_lib.server import test
10from autotest_lib.client.common_lib.cros import tpm_utils
11from autotest_lib.server.cros.multimedia import remote_facade_factory
12
13SHORT_TIMEOUT = 5
14
15
16class CfmBaseTest(test.test):
17    """
18    Base class for Cfm enterprise tests.
19
20    CfmBaseTest provides common setup and cleanup methods. This base class is
21    agnostic with respect to 'hangouts classic' vs. 'hangouts meet' - it works
22    for both flavors.
23    """
24
25    def initialize(self, host, run_test_only=False, skip_enrollment=False):
26        """
27        Initializes common test properties.
28
29        @param host: a host object representing the DUT.
30        @param run_test_only: Wheter to run only the test or to also perform
31            deprovisioning, enrollment and system reboot. If set to 'True',
32            the DUT must already be enrolled and past the OOB screen to be able
33            to execute the test.
34        @param skip_enrollment: Whether to skip the enrollment step. Cleanup
35            at the end of the test is done regardless.
36        """
37        super(CfmBaseTest, self).initialize()
38        self._host = host
39        self._run_test_only = run_test_only
40        self._skip_enrollment = skip_enrollment
41        self._facade_factory = remote_facade_factory.RemoteFacadeFactory(
42            self._host, no_chrome = True)
43        self.cfm_facade = self._facade_factory.create_cfm_facade()
44
45    def setup(self):
46        """
47        Performs common test setup operations:
48          - clears the TPM
49          - sets up servo
50          - enrolls the device
51          - skips OOBE
52        """
53        super(CfmBaseTest, self).setup()
54        if self._host.servo:
55            self._setup_servo()
56
57        if self._run_test_only or self._skip_enrollment:
58            # We need to restart the browser to obtain the handle for it when
59            # running in test_only mode.
60            self.cfm_facade.restart_chrome_for_cfm()
61        else:
62            tpm_utils.ClearTPMOwnerRequest(self._host)
63            self.cfm_facade.enroll_device()
64            self.cfm_facade.skip_oobe_after_enrollment()
65
66    def _setup_servo(self):
67        """
68        Enables the USB port such that any peripheral connected to it is visible
69        to the DUT.
70        """
71        self._host.servo.switch_usbkey('dut')
72        self._host.servo.set('usb_mux_sel3', 'dut_sees_usbkey')
73        time.sleep(SHORT_TIMEOUT)
74        self._host.servo.set('dut_hub1_rst1', 'off')
75        time.sleep(SHORT_TIMEOUT)
76
77    def cleanup(self, run_test_only=False):
78        """Takes a screenshot, saves log files and clears the TPM."""
79        self.take_screenshot('%s' % self.tagged_testname)
80        self.save_callgrok_logs()
81        self.save_packaged_app_logs()
82        if not self._run_test_only:
83            tpm_utils.ClearTPMOwnerRequest(self._host)
84        super(CfmBaseTest, self).cleanup()
85
86    def take_screenshot(self, screenshot_name):
87        """
88        Takes a screenshot (in .png format) and saves it in the debug dir.
89
90        @param screenshot_name: Name of the screenshot file without extension.
91        """
92        try:
93            target_dir = self.debugdir
94            logging.info('Taking screenshot and saving under %s...',
95                         target_dir)
96            remote_path = self.cfm_facade.take_screenshot()
97            if remote_path:
98                # Copy the screenshot from the DUT.
99                self._safe_copy_file(
100                    remote_path,
101                    os.path.join(target_dir, screenshot_name + '.png'))
102            else:
103                logging.warning('Taking screenshot failed')
104        except Exception as e:
105            logging.exception('Exception while taking a screenshot.')
106
107    def save_callgrok_logs(self):
108        """
109        Copies the callgrok logs from the client to test's debug directory.
110        """
111        callgrok_log_path = self.cfm_facade.get_latest_callgrok_file_path()
112        if callgrok_log_path:
113            self._safe_copy_file(
114                callgrok_log_path,
115                os.path.join(self.debugdir, 'callgrok_logs.txt'))
116        else:
117            logging.warning('No callgrok logs found on DUT.')
118
119    def save_packaged_app_logs(self):
120        """
121        Copies the packaged app logs from the client to test's debug directory.
122        """
123        pa_log_path = self.cfm_facade.get_latest_pa_logs_file_path()
124        if pa_log_path:
125            self._safe_copy_file(
126                pa_log_path,
127                os.path.join(self.debugdir, 'packaged_app_logs.txt'))
128        else:
129            logging.warning('No packaged app logs found on DUT.')
130
131    def _safe_copy_file(self, remote_path, local_path):
132        """
133        Copies the packaged app log file from CFM to test's debug directory.
134        """
135        try:
136            logging.info('Copying file "%s" from client to "%s"...',
137                         remote_path, local_path)
138            self._host.get_file(remote_path, local_path)
139        except Exception as e:
140            logging.exception(
141                'Exception while copying file "%s"', remote_path)
142
143