# Copyright 2021 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.

import base64
import logging
from autotest_lib.client.common_lib.error import TestFail
from autotest_lib.server import utils

AUTHOR = 'Chromium OS team'
NAME = 'tast.lacros'
TIME = 'MEDIUM'
TEST_TYPE = 'Server'

MAX_RESULT_SIZE_KB = 256 * 1024

# tast.py uses binaries installed from autotest_server_package.tar.bz2.
REQUIRE_SSP = True

DOC = '''
Run the lacros test.

This is a wrapper for lacros tast. In POC stage, we download a lacros
artifact in the autotest run and configure the tast to execute lacros
tests upon the downloaded binary.

Tast is an integration-testing framework analogous to the test-running portion
of Autotest. See https://chromium.googlesource.com/chromiumos/platform/tast/ for
more information.

See http://go/tast-failures for information about investigating failures.
'''

def run(machine):
    host=hosts.create_host(machine)
    varslist = []
    # TODO(crbug.com/1139516): Revisit the args dict once the POC is done.
    # The goal is to control the browser tests from chromium side.
    args_dict = utils.args_to_dict(args)
    expr = args_dict.get('tast_expr')
    if not expr:
      expr_b64 = args_dict.get('tast_expr_b64')
      if expr_b64:
        expr = base64.b64decode(expr_b64)
    if not expr:
        raise TestFail(
            'Attribute expression is unspecified; set tast_expr in --args.\n'
            '  Example: test_that --args="tast_expr=lacros.Basic"\n'
            '  If the expression contains spaces, consider transforming it to\n'
            '  base64 and passing it via tast_expr_b64 flag.\n'
            '  Example: test_that --args="tast_expr_b64=KCJncm91cDptYWlubGluZSIgJiYgImRlcDpsYWNyb3MiKQ=="\n'
            '  More details at go/lacros-on-skylab.')

    # TODO(crbug.com/1155637): Once CTP could provision lacros versions,
    # remove below lines which download a lacros artifact before tast runs.
    lacros_gcs_path = args_dict.get('lacros_gcs_path')
    if lacros_gcs_path:
        logging.info('Expect to download lacros from %s', lacros_gcs_path)
        # Skip the default boto config to apply the service account of
        # drones. The GCS bucket storing Chrome builds only allows this
        # service account to access.
        utils.system_output('BOTO_CONFIG= '
            'gsutil -o Credentials:gs_service_key_file='
            '/creds/service_accounts/skylab-drone.json cp %s /tmp/lacros.zip' %
            lacros_gcs_path)
        utils.system_output('unzip -o /tmp/lacros.zip -d /tmp/lacros')
        host.run('mkdir -p /usr/local/lacros/')
        host.send_file('/tmp/lacros/', '/usr/local/lacros/', delete_dest=True)
        varslist.append('lacrosDeployedBinary=/usr/local/lacros')
        # Clean the files downloaded to drone server.
        utils.system_output('rm -rf /tmp/lacros.zip /tmp/lacros')
    logging.info('Tast expr: %s', expr)
    job.run_test('tast',
                 host=host,
                 test_exprs=[expr],
                 download_data_lazily=False,
                 ignore_test_failures=False, max_run_sec=3600,
                 command_args=args,
                 varslist=varslist,
                 clear_tpm=True)

parallel_simple(run, machines)
