# 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 = (
    {
        "fixture_id": "micro_b",
        "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
    {
        "fixture_id": "emmc",
        "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
    {
        "fixture_id": "sd",
        "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)
