summaryrefslogtreecommitdiffstats
path: root/test/py/tests/test_ums.py
blob: a137221c7a5b04d27a5c87f14795ee1177492306 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
#
# SPDX-License-Identifier: GPL-2.0

# Test U-Boot's "ums" command. At present, this test only ensures that a UMS
# device can be enumerated by the host/test machine. In the future, this test
# should be enhanced to validate disk IO.

import os
import pytest
import time

'''
Note: This test relies on:

a) boardenv_* to contain configuration values to define which USB ports are
available for testing. Without this, this test will be automatically skipped.
For example:

env__usb_dev_ports = (
    {'tgt_usb_ctlr': '0', 'host_ums_dev_node': '/dev/disk/by-path/pci-0000:00:14.0-usb-0:13:1.0-scsi-0:0:0:0'},
)

env__block_devs = (
    {'type': 'mmc', 'id': '0'}, # eMMC; always present
    {'type': 'mmc', 'id': '1'}, # SD card; present since I plugged one in
)

b) udev rules to set permissions on devices nodes, so that sudo is not
required. For example:

ACTION=="add", SUBSYSTEM=="block", SUBSYSTEMS=="usb", KERNELS=="3-13", MODE:="666"

(You may wish to change the group ID instead of setting the permissions wide
open. All that matters is that the user ID running the test can access the
device.)
'''

def open_ums_device(host_ums_dev_node):
    '''Attempt to open a device node, returning either the opened file handle,
    or None on any error.'''

    try:
        return open(host_ums_dev_node, 'rb')
    except:
        return None

def wait_for_ums_device(host_ums_dev_node):
    '''Continually attempt to open the device node exported by the "ums"
    command, and either return the opened file handle, or raise an exception
    after a timeout.'''

    for i in xrange(100):
        fh = open_ums_device(host_ums_dev_node)
        if fh:
            return fh
        time.sleep(0.1)
    raise Exception('UMS device did not appear')

def wait_for_ums_device_gone(host_ums_dev_node):
    '''Continually attempt to open the device node exported by the "ums"
    command, and either return once the device has disappeared, or raise an
    exception if it does not before a timeout occurs.'''

    for i in xrange(100):
        fh = open_ums_device(host_ums_dev_node)
        if not fh:
            return
        fh.close()
        time.sleep(0.1)
    raise Exception('UMS device did not disappear')

@pytest.mark.buildconfigspec('cmd_usb_mass_storage')
def test_ums(u_boot_console, env__usb_dev_port, env__block_devs):
    '''Test the "ums" command; the host system must be able to enumerate a UMS
    device when "ums" is running, and this device must disappear when "ums" is
    aborted.'''

    tgt_usb_ctlr = env__usb_dev_port['tgt_usb_ctlr']
    host_ums_dev_node = env__usb_dev_port['host_ums_dev_node']

    # We're interested in testing USB device mode on each port, not the cross-
    # product of that with each device. So, just pick the first entry in the
    # device list here. We'll test each block device somewhere else.
    tgt_dev_type = env__block_devs[0]['type']
    tgt_dev_id = env__block_devs[0]['id']

    cmd = 'ums %s %s %s' % (tgt_usb_ctlr, tgt_dev_type, tgt_dev_id)
    u_boot_console.run_command('ums 0 mmc 0', wait_for_prompt=False)
    fh = wait_for_ums_device(host_ums_dev_node)
    fh.read(4096)
    fh.close()
    u_boot_console.ctrlc()
    wait_for_ums_device_gone(host_ums_dev_node)
OpenPOWER on IntegriCloud