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

from autotest_lib.server import utils

AUTHOR = "Chrome OS Team"
NAME = "platform_ExternalUsbPeripherals.detect.login_unplug_closelid_openlid_plug"
PURPOSE = "Servo based USB boot stress test"
CRITERIA = "This test will fail if any of the actions or checks fail."
TIME = "SHORT"
TEST_CATEGORY = "Functional"
TEST_CLASS = "platform"
TEST_TYPE = "server"
ATTRIBUTES = "suite:usb_detect"
DEPENDENCIES = "servo_state:WORKING"
JOB_RETRIES = 2

DOC = """
This test uses servo to connect/disconnect servo USB hub before and
after events like reboot, login, closelid, openlid etc.

The test fails if
- device is pingable when suspended
- wrong action passed through action_sequence flag
- USB detected peripherals are different than expected
- there is no servo board attached
- USB peripherals checks(usb_checks below) on command line fail
Other detection checks can be added for each peripheral

Set of four USB peripherals plugged
- USB headset
- USB HD Webcam - should be Logitech HD Pro Webcam C920
- USB stick with four partitions named ExFAT  Ext4  FAT  NTFS
- USB mouse
- USB 3G modem
- USB SD card reader(one microSD card plugged)
- USB connected phone(optional)
"""

args_dict = utils.args_to_dict(args)
servo_args = hosts.CrosHost.get_servo_arguments(args_dict)

def run(machine):
    host = hosts.create_host(machine, servo_args=servo_args)

    repeat = int(args_dict.get("repeat", 1))

    default_actions = str("login,unplug,closelid,openlid,plug")

    action_sequence = str(args_dict.get("action_sequence", default_actions))

    usb_list = ["\"Kingston Technology Company Inc.\"",
                "\"Alcor Micro Corp.|GEMBIRD\"",
                "\"USB PnP Sound Device: USB Audio|C-Media Electronics, Inc.* Audio\"",
               ]
    usb_checks = {
        # USB Audio Output devices
        str("cras_test_client --dump_server_info | "
            "awk \"/Output Devices:/,/Output Nodes:/\" | grep -E ") :
            ["\"USB PnP Sound Device: USB Audio|C-Media USB Headphone Set: USB Audio\"" ],
        # USB Audio Input devices
        str("loggedin:cras_test_client --dump_server_info | "
            "awk \"/Input Devices:/,/Input Nodes:/\" | grep -iE ") :
            ["\"TeckNet: USB Audio|USB ?2.0 PC Camera\"",
             "\"USB PnP Sound Device: USB Audio|C-Media USB Headphone Set: USB Audio\""],
        # USB stick four partitions volumes
        "loggedin:ls -l /media/removable/ | grep -i " :
            ["ExFAT", "Ext4", "FAT", "NTFS"],
        # USB Web camera
        "cat /sys/class/video4linux/video*/name | grep -iE " :
            ["\"TeckNet|USB ?2.0 PC Camera\""],
        }

    job.run_test("platform_ExternalUsbPeripherals", host=host,
                 disable_sysinfo=True, client_autotest="desktopui_SimpleLogin",
                 action_sequence=action_sequence, repeat=repeat,
                 usb_list=usb_list, usb_checks=usb_checks, tag="login_unplug_closelid_openlid_plug")

parallel_simple(run, machines)
