# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

NAME = "power_Dashboard.fast_lab"
METADATA = {
    "contacts": ["chromeos-platform-power@google.com"],
    "author": "puthik",
    "bug_component": "b:1361410",
    "criteria": "This test is a benchmark test",
    "hw_agnostic": False,
}
TIME = "MEDIUM"
TEST_CATEGORY = "Stress"
TEST_CLASS = "suite"
TEST_TYPE = "server"
PY_VERSION = 3

DOC = """
Sequence to make sure that power_Dashboard.full_lab tests work fine.
"""

import datetime
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import utils

# Need separate list for client and server test due to how these test work.
CLIENT_TESTS = [
    ('power_Standby', {
        'tag' : '36sec', 'sample_hours' : 0.01, 'test_hours' : 0.01,
        'bypass_check' : True}),
    ('power_LoadTest', {
        'tag' : 'fast', 'loop_time' : 180, 'loop_count' : 1,
        'test_low_batt_p' : 6, 'check_network': False, 'ac_ok' : True,
        'gaia_login' : False}),
    ('power_Idle', {
        'tag' : 'fast', 'warmup_secs' : 2, 'idle_secs' : 10}),
    ('power_VideoPlayback', {
        'tag' : 'fast', 'secs_per_video' : 10, 'fast' : True }),
    ('power_VideoPlayback', {
        'tag' : 'sw_decoder_fast', 'use_hw_decode' : False,
        'secs_per_video' : 10, 'fast' : True }),
    ('power_Display', {
        'tag' : 'fast', 'secs_per_page' : 2}),
]

SERVO_V4_ETH_VENDOR = '0bda'
SERVO_V4_ETH_PRODUCT = '8153'
WIFI_SSID = 'powertest_ap'

# Workaround to make it compatible with moblab autotest UI.
global args_dict
try:
    args_dict
except NameError:
    args_dict = utils.args_to_dict(args)

# Use time as pdash_note if not supplied to track all tests in same suite.
pdash_note = args_dict.get('pdash_note',
                           NAME + '_' + datetime.datetime.utcnow().isoformat())
def run_client_test(machine):
    client = hosts.create_host(machine)

    wlan_ip = client.get_wlan_ip()
    if not wlan_ip:
        autotest.Autotest(client).run_test('stub_Pass')
        if not client.connect_to_wifi(WIFI_SSID):
            raise error.TestFail('Can not connect to wifi.')
        wlan_ip = client.get_wlan_ip()
        if not wlan_ip:
            raise error.TestFail('Can not find wlan ip.')

    # Check if we have servo v4 ethernet and can switch to wlan.
    eth_usb = client.find_usb_devices(SERVO_V4_ETH_VENDOR, SERVO_V4_ETH_PRODUCT)
    can_switch_to_wlan = len(eth_usb) == 1 and eth_usb[0] and wlan_ip
    if can_switch_to_wlan:
        wlan_machine = machine
        if utils.host_is_in_power_lab(machine['hostname']):
            wlan_machine['hostname'] = \
                utils.get_power_lab_wlan_hostname(machine['hostname'])
        else:
            wlan_machine['hostname'] = wlan_ip
        client = hosts.create_host(wlan_machine)
        eth_node = eth_usb[0]

    client_at = autotest.Autotest(client)

    for test, argv in CLIENT_TESTS:
        client.reboot()
        if can_switch_to_wlan:
            client.unbind_usb_device(eth_node)
        argv['pdash_note'] = pdash_note
        argv['force_discharge'] = True
        client_at.run_test(test, **argv)

    client.reboot()


parallel_simple(run_client_test, machines)
