# Copyright 2019 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
from autotest_lib.server.cros.bluetooth import bluetooth_test

AUTHOR = 'chromeos-bluetooth'
NAME = 'bluetooth_AdapterMDSanity.stress'
PURPOSE = ('Batch of Bluetooth MD sanity tests')
CRITERIA = 'Pass all sanity test'
ATTRIBUTES = 'suite:bluetooth_stress'
TIME = 'LONG'
TEST_CATEGORY = 'Functional'
TEST_CLASS = 'bluetooth'
TEST_TYPE = 'server'
DEPENDENCIES = 'bluetooth, chameleon:bt_hid, chameleon:bt_ble_hid'

DOC = """
    A Batch of Bluetooth multi-devices sanity tests. This test is written
    as a batch of tests in order to reduce test time, since auto-test ramp
    up time is costy. The batch is using BluetoothAdapterQuickTests wrapper
    methods to start and end a test and a batch of tests.

    This class can be called to run the entire test batch or to run a
    specific test only

    Currently, the batch contains the following tests:
    - md_two_connections_test
    """

args_dict = utils.args_to_dict(args)
#
# Bluetooth peers can be named hostname-<chameleon> or hostname-<btpeer[1-4]
# Check for both until we transition to new peer names
# TODO(b:149637050) Cleanup this code
#
chameleon_args = hosts.CrosHost.get_chameleon_arguments(args_dict)
btpeer_args = hosts.CrosHost.get_btpeer_arguments(args_dict)

def run(machine):
    host = hosts.create_host(machine, chameleon_args=chameleon_args)
    host.initialize_btpeer(btpeer_args)
    job.run_test('bluetooth_AdapterMDSanity', host=host,
                  num_iterations=15)

parallel_simple(run, machines)
