| # Copyright 2022 The ChromiumOS Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import logging |
| import os |
| import sys |
| import shutil |
| |
| from autotest_lib.client.common_lib import error |
| from autotest_lib.client.common_lib import utils |
| from autotest_lib.client.common_lib.cros import tpm_utils |
| from autotest_lib.server import test |
| from autotest_lib.server.cros import chrome_sideloader |
| |
| MAX_GPU_TELEMETRY_TIMEOUT_SEC = 3600 |
| |
| |
| class chromium_Graphics(test.test): |
| """Run graphics tests for the Chrome built by browser infra. |
| |
| This is a wrapper class to exeucte run_gpu_integration_test.py |
| on Skylab bot for chrome artifacts built by browser infra. |
| """ |
| version = 1 |
| |
| # The path where we install chromium/src. In this experimental |
| # stage, we may use existing lacros image, which built at src. |
| CHROME_BUILD = '/usr/local/lacros-build' |
| |
| # run_gpu_integration_test are calling telemetry to manipulate the DUT. |
| # In telemetry the lacros chrome must be stored at below path. |
| # See go/lacros_browser_backend. |
| LACROS_MOUNT_POINT = '/usr/local/lacros-chrome' |
| CHROME_MOUNT_POINT = '/opt/google/chrome' |
| |
| def initialize(self, host=None, args=None): |
| self.host = host |
| |
| self.args_dict = utils.args_to_dict(args) |
| self.test_args = chrome_sideloader.get_test_args( |
| self.args_dict, 'test_args').split(' ') |
| |
| if not self.args_dict.get('run_private_tests', |
| True) in [False, 'False']: |
| tpm_utils.ClearTPMOwnerRequest(self.host, wait_for_ready=True) |
| |
| # 'chromite_deploy_chrome' installs Ash/Lacros via chromite and leave |
| # chrome checkout on Drone, which contains the GPU test's server package. |
| archive_type = 'chrome' if self.is_cros_chrome else 'lacros' |
| self.server_pkg = chrome_sideloader.chromite_deploy_chrome( |
| self.host, self.args_dict.get('lacros_gcs_path'), archive_type, |
| **self.args_dict) |
| |
| os.environ['GTEST_TOTAL_SHARDS'] = self.args_dict.get( |
| 'total_shards', '1') |
| os.environ['GTEST_SHARD_INDEX'] = self.args_dict.get( |
| 'shard_index', '0') |
| |
| # The test script needs to know it is running in Skylab environment. |
| os.environ['RUNNING_IN_SKYLAB'] = '1' |
| |
| @property |
| def is_cros_chrome(self): |
| return any(['--browser=cros-chrome' in x for x in self.test_args]) |
| |
| def run_once(self): |
| """Invoke run_gpu_integration_test.""" |
| cmd = [ |
| 'vpython3', |
| '-vpython-spec', |
| '../../.vpython3', |
| os.path.join('../../testing', 'scripts', |
| 'run_gpu_integration_test_as_googletest.py'), |
| os.path.join('../../content', 'test', 'gpu', |
| 'run_gpu_integration_test.py'), |
| # Generate a gtest-ish result file. This is mostly for reference now, |
| # because GPU tests do not upload it to RDB. |
| '--isolated-script-test-output={}'.format( |
| os.path.join(self.resultsdir, 'output.json')), |
| # GPU team requires a bunch of tags with the results, and the |
| # gtest output does not suffice. |
| # GPU test script exports each test result into a json string |
| # in sinkpb.TestResult, aka the native RDB format. |
| # Test runner recipe will call native result_adapter |
| # to upload them to RDB. See crrev.com/c/4081733. |
| '--rdb-content-output-file={}'.format( |
| os.path.join(self.resultsdir, 'native_results.jsonl')), |
| '--chromium-output-directory=./', |
| '--remote={}'.format(self.host.hostname), |
| ] |
| # Pass the test arguments from the browser test owners. |
| # Note utils.run() quotes all members in the cmd list. We have |
| # to split our test_args, or it will feed to |
| # run_gpu_integration_test.py as a single string. The same |
| # reason we have to pass extra-browser-args separately. |
| cmd.extend(self.test_args) |
| # Autotest does not recognize args with '-'. |
| cmd.append('--extra-browser-args={}'.format( |
| chrome_sideloader.get_test_args(self.args_dict, |
| 'extra_browser_args'))) |
| # In CFT mode, test driver is running inside a docker, which |
| # connects to the DUT via SSH proxy served by the host machine. |
| # Need to explicitly specify the port and identity. |
| if self.args_dict.get('is_cft'): |
| cmd.extend([ |
| '--identity=/home/chromeos-test/.ssh/testing_rsa', |
| f'--remote-ssh-port={self.host.port}' |
| ]) |
| |
| logging.debug('Running: %s', cmd) |
| exit_code = 0 |
| # We must kick off the test from src/out/Release, because |
| # the flags configured by browser side are assumed so. |
| os.chdir(os.path.join(self.server_pkg, 'out', 'Release')) |
| logging.debug('CWD: %s', os.getcwd()) |
| try: |
| result = utils.run( |
| cmd, |
| stdout_tee=sys.stdout, |
| stderr_tee=sys.stderr, |
| timeout=MAX_GPU_TELEMETRY_TIMEOUT_SEC, |
| extra_paths=['/opt/infra-tools', '/opt/browser-tools']) |
| exit_code = result.exit_status |
| except error.CmdError as e: |
| logging.debug('Error occurred executing GPU integration tests.') |
| exit_code = e.result_obj.exit_status |
| |
| if exit_code: |
| raise error.TestFail('Chromium GPU Integration Test' |
| ' failed to run.') |
| |
| def cleanup(self): |
| chrome_sideloader.cleanup_host( |
| self.host, |
| self.CHROME_BUILD, |
| self.CHROME_MOUNT_POINT |
| if self.is_cros_chrome else self.LACROS_MOUNT_POINT, |
| is_cros_chrome=self.is_cros_chrome) |
| shutil.rmtree(self.server_pkg) |