#!/usr/bin/env python3
#
#   Copyright 2016 - The Android Open Source Project
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

import logging
import time
import unittest

import mock

from acts import utils
from acts import signals
from acts.controllers.adb_lib.error import AdbError
from acts.controllers.android_device import AndroidDevice
from acts.controllers.fuchsia_device import FuchsiaDevice
from acts.controllers.utils_lib.ssh.connection import SshConnection
from acts.libs.proc import job

PROVISIONED_STATE_GOOD = 1

MOCK_IP_ADDRESSES = """eno1 100.127.110.79
eno1 2401:fa00:480:7a00:8d4f:85ff:cc5c:787e
eno1 2401:fa00:480:7a00:459:b993:fcbf:1419
eno1 fe80::c66d:3c75:2cec:1d72
enx00e04c000d06 192.168.42.220
enx00e04c000d06 fe80::2c68:f1b7:eaaa:52e7"""

MOCK_IFCONFIG_OUTPUT = """eno1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 100.127.110.79  netmask 255.255.255.0  broadcast 100.127.110.255
        inet6 2401:fa00:480:7a00:8d4f:85ff:cc5c:787e  prefixlen 64  scopeid 0x0<global>
        inet6 fe80::c66d:3c75:2cec:1d72  prefixlen 64  scopeid 0x20<link>
        inet6 2401:fa00:480:7a00:459:b993:fcbf:1419  prefixlen 64  scopeid 0x0<global>
        ether 54:b2:03:13:36:05  txqueuelen 1000  (Ethernet)
        RX packets 32943262  bytes 13324306863 (13.3 GB)
        RX errors 669  dropped 0  overruns 0  frame 669
        TX packets 4778580  bytes 3012041798 (3.0 GB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 16  memory 0xdf200000-df220000

enx00e04c000d06: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.42.220  netmask 255.255.255.0  broadcast 192.168.42.255
        inet6 fe80::2c68:f1b7:eaaa:52e7  prefixlen 64  scopeid 0x20<link>
        ether 00:e0:4c:00:0d:06  txqueuelen 1000  (Ethernet)
        RX packets 10212416  bytes 3204008175 (3.2 GB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 9868425  bytes 5641667955 (5.6 GB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 42779835  bytes 6144028882 (6.1 GB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 42779835  bytes 6144028882 (6.1 GB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

"""

FUCHSIA_INTERFACES = {
    'id':
    '1',
    'result': [
        {
            'id': 1,
            'name': 'lo',
            'ipv4_addresses': [
                [127, 0, 0, 1],
            ],
            'ipv6_addresses': [
                [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
            ],
            'online': True,
            'mac': [0, 0, 0, 0, 0, 0],
        },
        {
            'id':
            2,
            'name':
            'eno1',
            'ipv4_addresses': [
                [100, 127, 110, 79],
            ],
            'ipv6_addresses': [
                [
                    254, 128, 0, 0, 0, 0, 0, 0, 198, 109, 60, 117, 44, 236, 29,
                    114
                ],
                [
                    36, 1, 250, 0, 4, 128, 122, 0, 141, 79, 133, 255, 204, 92,
                    120, 126
                ],
                [
                    36, 1, 250, 0, 4, 128, 122, 0, 4, 89, 185, 147, 252, 191,
                    20, 25
                ],
            ],
            'online':
            True,
            'mac': [0, 224, 76, 5, 76, 229],
        },
        {
            'id':
            3,
            'name':
            'wlanxc0',
            'ipv4_addresses': [],
            'ipv6_addresses': [
                [
                    254, 128, 0, 0, 0, 0, 0, 0, 96, 255, 93, 96, 52, 253, 253,
                    243
                ],
                [
                    254, 128, 0, 0, 0, 0, 0, 0, 70, 7, 11, 255, 254, 118, 126,
                    192
                ],
            ],
            'online':
            False,
            'mac': [68, 7, 11, 118, 126, 192],
        },
    ],
    'error':
    None,
}

CORRECT_FULL_IP_LIST = {
    'ipv4_private': [],
    'ipv4_public': ['100.127.110.79'],
    'ipv6_link_local': ['fe80::c66d:3c75:2cec:1d72'],
    'ipv6_private_local': [],
    'ipv6_public': [
        '2401:fa00:480:7a00:8d4f:85ff:cc5c:787e',
        '2401:fa00:480:7a00:459:b993:fcbf:1419'
    ]
}

CORRECT_EMPTY_IP_LIST = {
    'ipv4_private': [],
    'ipv4_public': [],
    'ipv6_link_local': [],
    'ipv6_private_local': [],
    'ipv6_public': []
}

FUCHSIA_INIT_SERVER = ('acts.controllers.fuchsia_device.FuchsiaDevice.'
                       'init_server_connection')
FUCHSIA_INIT_FFX = ('acts.controllers.fuchsia_device.FuchsiaDevice.'
                    'init_ffx_connection')
FUCHSIA_SET_CONTROL_PATH_CONFIG = ('acts.controllers.fuchsia_device.'
                                   'FuchsiaDevice._set_control_path_config')
FUCHSIA_START_SERVICES = ('acts.controllers.fuchsia_device.FuchsiaDevice.'
                          'start_services')
FUCHSIA_NETSTACK_LIST_INTERFACES = (
    'acts.controllers.'
    'fuchsia_lib.netstack.netstack_lib.'
    'FuchsiaNetstackLib.netstackListInterfaces')
FUCHSIA_INIT_NETSTACK = ('acts.controllers.fuchsia_lib.netstack.'
                         'netstack_lib.FuchsiaNetstackLib.init')


class ByPassSetupWizardTests(unittest.TestCase):
    """This test class for unit testing acts.utils.bypass_setup_wizard."""

    def test_start_standing_subproc(self):
        with self.assertRaisesRegex(utils.ActsUtilsError,
                                    'Process .* has terminated'):
            utils.start_standing_subprocess('sleep 0', check_health_delay=0.1)

    def test_stop_standing_subproc(self):
        p = utils.start_standing_subprocess('sleep 0')
        time.sleep(0.1)
        with self.assertRaisesRegex(utils.ActsUtilsError,
                                    'Process .* has terminated'):
            utils.stop_standing_subprocess(p)

    @mock.patch('time.sleep')
    def test_bypass_setup_wizard_no_complications(self, _):
        ad = mock.Mock()
        ad.adb.shell.side_effect = [
            # Return value for SetupWizardExitActivity
            BypassSetupWizardReturn.NO_COMPLICATIONS,
            # Return value for device_provisioned
            PROVISIONED_STATE_GOOD,
        ]
        ad.adb.return_state = BypassSetupWizardReturn.NO_COMPLICATIONS
        self.assertTrue(utils.bypass_setup_wizard(ad))
        self.assertFalse(
            ad.adb.root_adb.called,
            'The root command should not be called if there are no '
            'complications.')

    @mock.patch('time.sleep')
    def test_bypass_setup_wizard_unrecognized_error(self, _):
        ad = mock.Mock()
        ad.adb.shell.side_effect = [
            # Return value for SetupWizardExitActivity
            BypassSetupWizardReturn.UNRECOGNIZED_ERR,
            # Return value for device_provisioned
            PROVISIONED_STATE_GOOD,
        ]
        with self.assertRaises(AdbError):
            utils.bypass_setup_wizard(ad)
        self.assertFalse(
            ad.adb.root_adb.called,
            'The root command should not be called if we do not have a '
            'codepath for recovering from the failure.')

    @mock.patch('time.sleep')
    def test_bypass_setup_wizard_need_root_access(self, _):
        ad = mock.Mock()
        ad.adb.shell.side_effect = [
            # Return value for SetupWizardExitActivity
            BypassSetupWizardReturn.ROOT_ADB_NO_COMP,
            # Return value for rooting the device
            BypassSetupWizardReturn.NO_COMPLICATIONS,
            # Return value for device_provisioned
            PROVISIONED_STATE_GOOD
        ]

        utils.bypass_setup_wizard(ad)

        self.assertTrue(
            ad.adb.root_adb_called,
            'The command required root access, but the device was never '
            'rooted.')

    @mock.patch('time.sleep')
    def test_bypass_setup_wizard_need_root_already_skipped(self, _):
        ad = mock.Mock()
        ad.adb.shell.side_effect = [
            # Return value for SetupWizardExitActivity
            BypassSetupWizardReturn.ROOT_ADB_SKIPPED,
            # Return value for SetupWizardExitActivity after root
            BypassSetupWizardReturn.ALREADY_BYPASSED,
            # Return value for device_provisioned
            PROVISIONED_STATE_GOOD
        ]
        self.assertTrue(utils.bypass_setup_wizard(ad))
        self.assertTrue(ad.adb.root_adb_called)

    @mock.patch('time.sleep')
    def test_bypass_setup_wizard_root_access_still_fails(self, _):
        ad = mock.Mock()
        ad.adb.shell.side_effect = [
            # Return value for SetupWizardExitActivity
            BypassSetupWizardReturn.ROOT_ADB_FAILS,
            # Return value for SetupWizardExitActivity after root
            BypassSetupWizardReturn.UNRECOGNIZED_ERR,
            # Return value for device_provisioned
            PROVISIONED_STATE_GOOD
        ]

        with self.assertRaises(AdbError):
            utils.bypass_setup_wizard(ad)
        self.assertTrue(ad.adb.root_adb_called)


class BypassSetupWizardReturn:
    # No complications. Bypass works the first time without issues.
    NO_COMPLICATIONS = (
        'Starting: Intent { cmp=com.google.android.setupwizard/'
        '.SetupWizardExitActivity }')

    # Fail with doesn't need to be skipped/was skipped already.
    ALREADY_BYPASSED = AdbError('', 'ADB_CMD_OUTPUT:0', 'Error type 3\n'
                                'Error: Activity class', 1)
    # Fail with different error.
    UNRECOGNIZED_ERR = AdbError('', 'ADB_CMD_OUTPUT:0', 'Error type 4\n'
                                'Error: Activity class', 0)
    # Fail, get root access, then no complications arise.
    ROOT_ADB_NO_COMP = AdbError(
        '', 'ADB_CMD_OUTPUT:255', 'Security exception: Permission Denial: '
        'starting Intent { flg=0x10000000 '
        'cmp=com.google.android.setupwizard/'
        '.SetupWizardExitActivity } from null '
        '(pid=5045, uid=2000) not exported from uid '
        '10000', 0)
    # Even with root access, the bypass setup wizard doesn't need to be skipped.
    ROOT_ADB_SKIPPED = AdbError(
        '', 'ADB_CMD_OUTPUT:255', 'Security exception: Permission Denial: '
        'starting Intent { flg=0x10000000 '
        'cmp=com.google.android.setupwizard/'
        '.SetupWizardExitActivity } from null '
        '(pid=5045, uid=2000) not exported from '
        'uid 10000', 0)
    # Even with root access, the bypass setup wizard fails
    ROOT_ADB_FAILS = AdbError(
        '', 'ADB_CMD_OUTPUT:255',
        'Security exception: Permission Denial: starting Intent { '
        'flg=0x10000000 cmp=com.google.android.setupwizard/'
        '.SetupWizardExitActivity } from null (pid=5045, uid=2000) not '
        'exported from uid 10000', 0)


class ConcurrentActionsTest(unittest.TestCase):
    """Tests acts.utils.run_concurrent_actions and related functions."""

    @staticmethod
    def function_returns_passed_in_arg(arg):
        return arg

    @staticmethod
    def function_raises_passed_in_exception_type(exception_type):
        raise exception_type

    def test_run_concurrent_actions_no_raise_returns_proper_return_values(
            self):
        """Tests run_concurrent_actions_no_raise returns in the correct order.

        Each function passed into run_concurrent_actions_no_raise returns the
        values returned from each individual callable in the order passed in.
        """
        ret_values = utils.run_concurrent_actions_no_raise(
            lambda: self.function_returns_passed_in_arg(
                'ARG1'), lambda: self.function_returns_passed_in_arg('ARG2'),
            lambda: self.function_returns_passed_in_arg('ARG3'))

        self.assertEqual(len(ret_values), 3)
        self.assertEqual(ret_values[0], 'ARG1')
        self.assertEqual(ret_values[1], 'ARG2')
        self.assertEqual(ret_values[2], 'ARG3')

    def test_run_concurrent_actions_no_raise_returns_raised_exceptions(self):
        """Tests run_concurrent_actions_no_raise returns raised exceptions.

        Instead of allowing raised exceptions to be raised in the main thread,
        this function should capture the exception and return them in the slot
        the return value should have been returned in.
        """
        ret_values = utils.run_concurrent_actions_no_raise(
            lambda: self.function_raises_passed_in_exception_type(IndexError),
            lambda: self.function_raises_passed_in_exception_type(KeyError))

        self.assertEqual(len(ret_values), 2)
        self.assertEqual(ret_values[0].__class__, IndexError)
        self.assertEqual(ret_values[1].__class__, KeyError)

    def test_run_concurrent_actions_returns_proper_return_values(self):
        """Tests run_concurrent_actions returns in the correct order.

        Each function passed into run_concurrent_actions returns the values
        returned from each individual callable in the order passed in.
        """

        ret_values = utils.run_concurrent_actions(
            lambda: self.function_returns_passed_in_arg(
                'ARG1'), lambda: self.function_returns_passed_in_arg('ARG2'),
            lambda: self.function_returns_passed_in_arg('ARG3'))

        self.assertEqual(len(ret_values), 3)
        self.assertEqual(ret_values[0], 'ARG1')
        self.assertEqual(ret_values[1], 'ARG2')
        self.assertEqual(ret_values[2], 'ARG3')

    def test_run_concurrent_actions_raises_exceptions(self):
        """Tests run_concurrent_actions raises exceptions from given actions."""
        with self.assertRaises(KeyError):
            utils.run_concurrent_actions(
                lambda: self.function_returns_passed_in_arg('ARG1'), lambda:
                self.function_raises_passed_in_exception_type(KeyError))

    def test_test_concurrent_actions_raises_non_test_failure(self):
        """Tests test_concurrent_actions raises the given exception."""
        with self.assertRaises(KeyError):
            utils.test_concurrent_actions(
                lambda: self.function_raises_passed_in_exception_type(KeyError
                                                                      ),
                failure_exceptions=signals.TestFailure)

    def test_test_concurrent_actions_raises_test_failure(self):
        """Tests test_concurrent_actions raises the given exception."""
        with self.assertRaises(signals.TestFailure):
            utils.test_concurrent_actions(
                lambda: self.function_raises_passed_in_exception_type(KeyError
                                                                      ),
                failure_exceptions=KeyError)


class SuppressLogOutputTest(unittest.TestCase):
    """Tests SuppressLogOutput"""

    def test_suppress_log_output(self):
        """Tests that the SuppressLogOutput context manager removes handlers
        of the specified levels upon entry and re-adds handlers upon exit.
        """
        handlers = [
            logging.NullHandler(level=lvl)
            for lvl in (logging.DEBUG, logging.INFO, logging.ERROR)
        ]
        log = logging.getLogger('test_log')
        for handler in handlers:
            log.addHandler(handler)
        with utils.SuppressLogOutput(log, [logging.INFO, logging.ERROR]):
            self.assertTrue(
                any(handler.level == logging.DEBUG
                    for handler in log.handlers))
            self.assertFalse(
                any(handler.level in (logging.INFO, logging.ERROR)
                    for handler in log.handlers))
        self.assertCountEqual(handlers, log.handlers)


class IpAddressUtilTest(unittest.TestCase):
    def test_positive_ipv4_normal_address(self):
        ip_address = "192.168.1.123"
        self.assertTrue(utils.is_valid_ipv4_address(ip_address))

    def test_positive_ipv4_any_address(self):
        ip_address = "0.0.0.0"
        self.assertTrue(utils.is_valid_ipv4_address(ip_address))

    def test_positive_ipv4_broadcast(self):
        ip_address = "255.255.255.0"
        self.assertTrue(utils.is_valid_ipv4_address(ip_address))

    def test_negative_ipv4_with_ipv6_address(self):
        ip_address = "fe80::f693:9fff:fef4:1ac"
        self.assertFalse(utils.is_valid_ipv4_address(ip_address))

    def test_negative_ipv4_with_invalid_string(self):
        ip_address = "fdsafdsafdsafdsf"
        self.assertFalse(utils.is_valid_ipv4_address(ip_address))

    def test_negative_ipv4_with_invalid_number(self):
        ip_address = "192.168.500.123"
        self.assertFalse(utils.is_valid_ipv4_address(ip_address))

    def test_positive_ipv6(self):
        ip_address = 'fe80::f693:9fff:fef4:1ac'
        self.assertTrue(utils.is_valid_ipv6_address(ip_address))

    def test_positive_ipv6_link_local(self):
        ip_address = 'fe80::'
        self.assertTrue(utils.is_valid_ipv6_address(ip_address))

    def test_negative_ipv6_with_ipv4_address(self):
        ip_address = '192.168.1.123'
        self.assertFalse(utils.is_valid_ipv6_address(ip_address))

    def test_negative_ipv6_invalid_characters(self):
        ip_address = 'fe80:jkyr:f693:9fff:fef4:1ac'
        self.assertFalse(utils.is_valid_ipv6_address(ip_address))

    def test_negative_ipv6_invalid_string(self):
        ip_address = 'fdsafdsafdsafdsf'
        self.assertFalse(utils.is_valid_ipv6_address(ip_address))

    @mock.patch('acts.libs.proc.job.run')
    def test_local_get_interface_ip_addresses_full(self, job_mock):
        job_mock.side_effect = [
            job.Result(stdout=bytes(MOCK_IP_ADDRESSES, 'utf-8'),
                       encoding='utf-8'),
            job.Result(stdout=bytes(MOCK_IFCONFIG_OUTPUT, 'utf-8'),
                       encoding='utf-8')
        ]
        self.assertEqual(utils.get_interface_ip_addresses(job, 'eno1'),
                         CORRECT_FULL_IP_LIST)

    @mock.patch('acts.libs.proc.job.run')
    def test_local_get_interface_ip_addresses_empty(self, job_mock):
        job_mock.side_effect = [
            job.Result(stdout=bytes(MOCK_IP_ADDRESSES, 'utf-8'),
                       encoding='utf-8'),
            job.Result(stdout=bytes(MOCK_IFCONFIG_OUTPUT, 'utf-8'),
                       encoding='utf-8')
        ]
        self.assertEqual(utils.get_interface_ip_addresses(job, 'wlan1'),
                         CORRECT_EMPTY_IP_LIST)

    @mock.patch('acts.controllers.utils_lib.ssh.connection.SshConnection.run')
    def test_ssh_get_interface_ip_addresses_full(self, ssh_mock):
        ssh_mock.side_effect = [
            job.Result(stdout=bytes(MOCK_IP_ADDRESSES, 'utf-8'),
                       encoding='utf-8'),
            job.Result(stdout=bytes(MOCK_IFCONFIG_OUTPUT, 'utf-8'),
                       encoding='utf-8')
        ]
        self.assertEqual(
            utils.get_interface_ip_addresses(SshConnection('mock_settings'),
                                             'eno1'), CORRECT_FULL_IP_LIST)

    @mock.patch('acts.controllers.utils_lib.ssh.connection.SshConnection.run')
    def test_ssh_get_interface_ip_addresses_empty(self, ssh_mock):
        ssh_mock.side_effect = [
            job.Result(stdout=bytes(MOCK_IP_ADDRESSES, 'utf-8'),
                       encoding='utf-8'),
            job.Result(stdout=bytes(MOCK_IFCONFIG_OUTPUT, 'utf-8'),
                       encoding='utf-8')
        ]
        self.assertEqual(
            utils.get_interface_ip_addresses(SshConnection('mock_settings'),
                                             'wlan1'), CORRECT_EMPTY_IP_LIST)

    @mock.patch('acts.controllers.adb.AdbProxy')
    @mock.patch.object(AndroidDevice, 'is_bootloader', return_value=True)
    def test_android_get_interface_ip_addresses_full(self, is_bootloader,
                                                     adb_mock):
        adb_mock().shell.side_effect = [
            MOCK_IP_ADDRESSES, MOCK_IFCONFIG_OUTPUT
        ]
        self.assertEqual(
            utils.get_interface_ip_addresses(AndroidDevice(), 'eno1'),
            CORRECT_FULL_IP_LIST)

    @mock.patch('acts.controllers.adb.AdbProxy')
    @mock.patch.object(AndroidDevice, 'is_bootloader', return_value=True)
    def test_android_get_interface_ip_addresses_empty(self, is_bootloader,
                                                      adb_mock):
        adb_mock().shell.side_effect = [
            MOCK_IP_ADDRESSES, MOCK_IFCONFIG_OUTPUT
        ]
        self.assertEqual(
            utils.get_interface_ip_addresses(AndroidDevice(), 'wlan1'),
            CORRECT_EMPTY_IP_LIST)

    @mock.patch(FUCHSIA_INIT_SERVER)
    @mock.patch(FUCHSIA_INIT_FFX)
    @mock.patch(FUCHSIA_SET_CONTROL_PATH_CONFIG)
    @mock.patch(FUCHSIA_START_SERVICES)
    @mock.patch(FUCHSIA_NETSTACK_LIST_INTERFACES)
    @mock.patch(FUCHSIA_INIT_NETSTACK)
    def test_fuchsia_get_interface_ip_addresses_full(
            self, init_mock, list_interfaces_mock, start_services_mock,
            control_path_mock, ffx_mock, fuchsia_device_mock):
        # Will never actually be created/used.
        logging.log_path = '/tmp/unit_test_garbage'

        init_mock.return_value = None
        list_interfaces_mock.return_value = FUCHSIA_INTERFACES
        fuchsia_device_mock.return_value = None
        self.assertEqual(
            utils.get_interface_ip_addresses(
                FuchsiaDevice({'ip': '192.168.1.1'}), 'eno1'),
            CORRECT_FULL_IP_LIST)

    @mock.patch(FUCHSIA_INIT_SERVER)
    @mock.patch(FUCHSIA_INIT_FFX)
    @mock.patch(FUCHSIA_SET_CONTROL_PATH_CONFIG)
    @mock.patch(FUCHSIA_START_SERVICES)
    @mock.patch(FUCHSIA_NETSTACK_LIST_INTERFACES)
    @mock.patch(FUCHSIA_INIT_NETSTACK)
    def test_fuchsia_get_interface_ip_addresses_empty(
            self, init_mock, list_interfaces_mock, start_services_mock,
            control_path_mock, ffx_mock, fuchsia_device_mock):
        # Will never actually be created/used.
        logging.log_path = '/tmp/unit_test_garbage'

        init_mock.return_value = None
        list_interfaces_mock.return_value = FUCHSIA_INTERFACES
        fuchsia_device_mock.return_value = None
        self.assertEqual(
            utils.get_interface_ip_addresses(
                FuchsiaDevice({'ip': '192.168.1.1'}), 'wlan1'),
            CORRECT_EMPTY_IP_LIST)


class GetDeviceTest(unittest.TestCase):
    class TestDevice:
        def __init__(self, id, device_type=None) -> None:
            self.id = id
            if device_type:
                self.device_type = device_type

    def test_get_device_none(self):
        devices = []
        self.assertRaises(ValueError, utils.get_device, devices, 'DUT')

    def test_get_device_default_one(self):
        devices = [self.TestDevice(0)]
        self.assertEqual(utils.get_device(devices, 'DUT').id, 0)

    def test_get_device_default_many(self):
        devices = [self.TestDevice(0), self.TestDevice(1)]
        self.assertEqual(utils.get_device(devices, 'DUT').id, 0)

    def test_get_device_specified_one(self):
        devices = [self.TestDevice(0), self.TestDevice(1, 'DUT')]
        self.assertEqual(utils.get_device(devices, 'DUT').id, 1)

    def test_get_device_specified_many(self):
        devices = [self.TestDevice(0, 'DUT'), self.TestDevice(1, 'DUT')]
        self.assertRaises(ValueError, utils.get_device, devices, 'DUT')


if __name__ == '__main__':
    unittest.main()
