# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
#
# SPDX-License-Identifier: GPL-2.0

# Test U-Boot's "ums" command. The test starts UMS in U-Boot, waits for USB
# device enumeration on the host, reads a small block of data from the UMS
# block device, optionally mounts a partition and performs filesystem-based
# read/write tests, and finally aborts the "ums" command in U-Boot.

import os
import os.path
import pytest
import re
import time
import u_boot_utils

'''
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:

# Leave this list empty if you have no block_devs below with writable
# partitions defined.
env__mount_points = (
    "/mnt/ubtest-mnt-p2371-2180-na",
)

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 = (
    # eMMC; always present
    {
        "type": "mmc",
        "id": "0",
        # The following two properties are optional.
        # If present, the partition will be mounted and a file written-to and
        # read-from it. If missing, only a simple block read test will be
        # performed.
        "writable_fs_partition": 1,
        "writable_fs_subdir": "tmp/",
    },
    # SD card; present since I plugged one in
    {
        "type": "mmc",
        "id": "1"
    },
)

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.)

c) /etc/fstab entries to allow the block device to be mounted without requiring
root permissions. For example:

/dev/disk/by-path/pci-0000:00:14.0-usb-0:13:1.0-scsi-0:0:0:0-part1 /mnt/ubtest-mnt-p2371-2180-na ext4 noauto,user,nosuid,nodev

This entry is only needed if any block_devs above contain a
writable_fs_partition value.
'''

@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, block and optionally file I/O are tested,
    and this device must disappear when "ums" is aborted.

    Args:
        u_boot_console: A U-Boot console connection.
        env__usb_dev_port: The single USB device-mode port specification on
            which to run the test. See the file-level comment above for
            details of the format.
        env__block_devs: The list of block devices that the target U-Boot
            device has attached. See the file-level comment above for details
            of the format.

    Returns:
        Nothing.
    '''

    have_writable_fs_partition = 'writable_fs_partition' in env__block_devs[0]
    if not have_writable_fs_partition:
        # If 'writable_fs_subdir' is missing, we'll skip all parts of the
        # testing which mount filesystems.
        u_boot_console.log.warning(
            'boardenv missing "writable_fs_partition"; ' +
            'UMS testing will be limited.')

    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']
    if have_writable_fs_partition:
        mount_point = u_boot_console.config.env['env__mount_points'][0]
        mount_subdir = env__block_devs[0]['writable_fs_subdir']
        part_num = env__block_devs[0]['writable_fs_partition']
        host_ums_part_node = '%s-part%d' % (host_ums_dev_node, part_num)
    else:
        host_ums_part_node = host_ums_dev_node

    test_f = u_boot_utils.PersistentRandomFile(u_boot_console, 'ums.bin',
        1024 * 1024);
    if have_writable_fs_partition:
        mounted_test_fn = mount_point + '/' + mount_subdir + test_f.fn

    def start_ums():
        '''Start U-Boot's ums shell command.

        This also waits for the host-side USB enumeration process to complete.

        Args:
            None.

        Returns:
            Nothing.
        '''

        u_boot_console.log.action(
            'Starting long-running U-Boot ums shell command')
        cmd = 'ums %s %s %s' % (tgt_usb_ctlr, tgt_dev_type, tgt_dev_id)
        u_boot_console.run_command(cmd, wait_for_prompt=False)
        u_boot_console.wait_for(re.compile('UMS: LUN.*[\r\n]'))
        fh = u_boot_utils.wait_until_open_succeeds(host_ums_part_node)
        u_boot_console.log.action('Reading raw data from UMS device')
        fh.read(4096)
        fh.close()

    def mount():
        '''Mount the block device that U-Boot exports.

        Args:
            None.

        Returns:
            Nothing.
        '''

        u_boot_console.log.action('Mounting exported UMS device')
        cmd = ('/bin/mount', host_ums_part_node)
        u_boot_utils.run_and_log(u_boot_console, cmd)

    def umount(ignore_errors):
        '''Unmount the block device that U-Boot exports.

        Args:
            ignore_errors: Ignore any errors. This is useful if an error has
                already been detected, and the code is performing best-effort
                cleanup. In this case, we do not want to mask the original
                error by "honoring" any new errors.

        Returns:
            Nothing.
        '''

        u_boot_console.log.action('Unmounting UMS device')
        cmd = ('/bin/umount', host_ums_part_node)
        u_boot_utils.run_and_log(u_boot_console, cmd, ignore_errors)

    def stop_ums(ignore_errors):
        '''Stop U-Boot's ums shell command from executing.

        This also waits for the host-side USB de-enumeration process to
        complete.

        Args:
            ignore_errors: Ignore any errors. This is useful if an error has
                already been detected, and the code is performing best-effort
                cleanup. In this case, we do not want to mask the original
                error by "honoring" any new errors.

        Returns:
            Nothing.
        '''

        u_boot_console.log.action(
            'Stopping long-running U-Boot ums shell command')
        u_boot_console.ctrlc()
        u_boot_utils.wait_until_file_open_fails(host_ums_part_node,
            ignore_errors)

    ignore_cleanup_errors = True
    try:
        start_ums()
        if not have_writable_fs_partition:
            # Skip filesystem-based testing if not configured
            return
        try:
            mount()
            u_boot_console.log.action('Writing test file via UMS')
            cmd = ('rm', '-f', mounted_test_fn)
            u_boot_utils.run_and_log(u_boot_console, cmd)
            if os.path.exists(mounted_test_fn):
                raise Exception('Could not rm target UMS test file')
            cmd = ('cp', test_f.abs_fn, mounted_test_fn)
            u_boot_utils.run_and_log(u_boot_console, cmd)
            ignore_cleanup_errors = False
        finally:
            umount(ignore_errors=ignore_cleanup_errors)
    finally:
        stop_ums(ignore_errors=ignore_cleanup_errors)

    ignore_cleanup_errors = True
    try:
        start_ums()
        try:
            mount()
            u_boot_console.log.action('Reading test file back via UMS')
            read_back_hash = u_boot_utils.md5sum_file(mounted_test_fn)
            cmd = ('rm', '-f', mounted_test_fn)
            u_boot_utils.run_and_log(u_boot_console, cmd)
            ignore_cleanup_errors = False
        finally:
            umount(ignore_errors=ignore_cleanup_errors)
    finally:
        stop_ums(ignore_errors=ignore_cleanup_errors)

    written_hash = test_f.content_hash
    assert(written_hash == read_back_hash)
