diff options
author | Tom Rini <trini@konsulko.com> | 2024-01-29 10:56:56 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2024-01-29 12:50:34 -0500 |
commit | ce54325c42a97ac38cc60891be713e7000e32e04 (patch) | |
tree | 0a3312f144666e31fafa52f1ac60b09264931f55 /test/py/tests/test_mmc.py | |
parent | 526a865fe4fea59fb2638726c26e39557eb97fdd (diff) | |
parent | e24e5405d266f16b95fd7c1c3a2eec753c01f112 (diff) |
Merge branch '2024-01-29-pytest-enhancements'
- Update pygit2 version and add a number of additional hardware pytests
Diffstat (limited to 'test/py/tests/test_mmc.py')
-rw-r--r-- | test/py/tests/test_mmc.py | 671 |
1 files changed, 671 insertions, 0 deletions
diff --git a/test/py/tests/test_mmc.py b/test/py/tests/test_mmc.py new file mode 100644 index 00000000000..a96c4e8fd89 --- /dev/null +++ b/test/py/tests/test_mmc.py @@ -0,0 +1,671 @@ +# SPDX-License-Identifier: GPL-2.0 +# (C) Copyright 2023, Advanced Micro Devices, Inc. + +import pytest +import random +import re +import u_boot_utils + +""" +Note: This test doesn't rely on boardenv_* configuration values but it can +change the test behavior. To test MMC file system cases (fat32, ext2, ext4), +MMC device should be formatted and valid partitions should be created for +different file system, otherwise it may leads to failure. This test will be +skipped if the MMC device is not detected. + +For example: + +# Setup env__mmc_device_test_skip to not skipping the test. By default, its +# value is set to True. Set it to False to run all tests for MMC device. +env__mmc_device_test_skip = False +""" + +mmc_set_up = False +controllers = 0 +devices = {} + +def setup_mmc(u_boot_console): + if u_boot_console.config.env.get('env__mmc_device_test_skip', True): + pytest.skip('MMC device test is not enabled') + +@pytest.mark.buildconfigspec('cmd_mmc') +def test_mmc_list(u_boot_console): + setup_mmc(u_boot_console) + output = u_boot_console.run_command('mmc list') + if 'No MMC device available' in output: + pytest.skip('No SD/MMC/eMMC controller available') + + if 'Card did not respond to voltage select' in output: + pytest.skip('No SD/MMC card present') + + array = output.split() + global devices + global controllers + controllers = int(len(array) / 2) + for x in range(0, controllers): + y = x * 2 + devices[x] = {} + devices[x]['name'] = array[y] + + global mmc_set_up + mmc_set_up = True + +@pytest.mark.buildconfigspec('cmd_mmc') +def test_mmc_dev(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + fail = 0 + for x in range(0, controllers): + devices[x]['detected'] = 'yes' + output = u_boot_console.run_command('mmc dev %d' % x) + + # Some sort of switch here + if 'Card did not respond to voltage select' in output: + fail = 1 + devices[x]['detected'] = 'no' + + if 'no mmc device at slot' in output: + devices[x]['detected'] = 'no' + + if 'MMC: no card present' in output: + devices[x]['detected'] = 'no' + + if fail: + pytest.fail('Card not present') + +@pytest.mark.buildconfigspec('cmd_mmc') +def test_mmcinfo(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + output = u_boot_console.run_command('mmcinfo') + if 'busy timeout' in output: + pytest.skip('No SD/MMC/eMMC device present') + + obj = re.search(r'Capacity: (\d+|\d+[\.]?\d)', output) + try: + capacity = float(obj.groups()[0]) + print(capacity) + devices[x]['capacity'] = capacity + print('Capacity of dev %d is: %g GiB' % (x, capacity)) + except ValueError: + pytest.fail('MMC capacity not recognized') + +@pytest.mark.buildconfigspec('cmd_mmc') +def test_mmc_info(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + + output = u_boot_console.run_command('mmc info') + + obj = re.search(r'Capacity: (\d+|\d+[\.]?\d)', output) + try: + capacity = float(obj.groups()[0]) + print(capacity) + if devices[x]['capacity'] != capacity: + pytest.fail("MMC capacity doesn't match mmcinfo") + + except ValueError: + pytest.fail('MMC capacity not recognized') + +@pytest.mark.buildconfigspec('cmd_mmc') +def test_mmc_rescan(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + output = u_boot_console.run_command('mmc rescan') + if output: + pytest.fail('mmc rescan has something to check') + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + +@pytest.mark.buildconfigspec('cmd_mmc') +def test_mmc_part(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + output = u_boot_console.run_command('mmc part') + + lines = output.split('\n') + part_fat = [] + part_ext = [] + for line in lines: + obj = re.search( + r'(\d)\s+\d+\s+\d+\s+\w+\d+\w+-\d+\s+(\d+\w+)', line) + if obj: + part_id = int(obj.groups()[0]) + part_type = obj.groups()[1] + print('part_id:%d, part_type:%s' % (part_id, part_type)) + + if part_type in ['0c', '0b', '0e']: + print('Fat detected') + part_fat.append(part_id) + elif part_type == '83': + print('ext detected') + part_ext.append(part_id) + else: + pytest.fail('Unsupported Filesystem on device %d' % x) + devices[x]['ext4'] = part_ext + devices[x]['ext2'] = part_ext + devices[x]['fat'] = part_fat + + if not part_ext and not part_fat: + pytest.fail('No partition detected on device %d' % x) + +@pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.buildconfigspec('cmd_fat') +def test_mmc_fatls_fatinfo(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + fs = 'fat' + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + output = u_boot_console.run_command( + 'fatls mmc %d:%s' % (x, part)) + if 'Unrecognized filesystem type' in output: + partitions.remove(part) + pytest.fail('Unrecognized filesystem') + + if not re.search(r'\d file\(s\), \d dir\(s\)', output): + pytest.fail('%s read failed on device %d' % (fs.upper, x)) + output = u_boot_console.run_command( + 'fatinfo mmc %d:%s' % (x, part)) + string = 'Filesystem: %s' % fs.upper + if re.search(string, output): + pytest.fail('%s FS failed on device %d' % (fs.upper(), x)) + part_detect = 1 + + if not part_detect: + pytest.skip('No %s partition detected' % fs.upper()) + + +@pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.buildconfigspec('cmd_fat') +@pytest.mark.buildconfigspec('cmd_memory') +def test_mmc_fatload_fatwrite(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + fs = 'fat' + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + addr = u_boot_utils.find_ram_base(u_boot_console) + devices[x]['addr_%d' % part] = addr + size = random.randint(4, 1 * 1024 * 1024) + devices[x]['size_%d' % part] = size + # count CRC32 + output = u_boot_console.run_command('crc32 %x %x' % (addr, size)) + m = re.search('==> (.+?)', output) + if not m: + pytest.fail('CRC32 failed') + expected_crc32 = m.group(1) + devices[x]['expected_crc32_%d' % part] = expected_crc32 + # do write + file = '%s_%d' % ('uboot_test', size) + devices[x]['file_%d' % part] = file + output = u_boot_console.run_command( + '%swrite mmc %d:%s %x %s %x' % (fs, x, part, addr, file, size) + ) + assert 'Unable to write' not in output + assert 'Error' not in output + assert 'overflow' not in output + expected_text = '%d bytes written' % size + assert expected_text in output + + alignment = int( + u_boot_console.config.buildconfig.get( + 'config_sys_cacheline_size', 128 + ) + ) + offset = random.randrange(alignment, 1024, alignment) + output = u_boot_console.run_command( + '%sload mmc %d:%s %x %s' % (fs, x, part, addr + offset, file) + ) + assert 'Invalid FAT entry' not in output + assert 'Unable to read file' not in output + assert 'Misaligned buffer address' not in output + expected_text = '%d bytes read' % size + assert expected_text in output + + output = u_boot_console.run_command( + 'crc32 %x $filesize' % (addr + offset) + ) + assert expected_crc32 in output + + if not part_detect: + pytest.skip('No %s partition detected' % fs.upper()) + +@pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.buildconfigspec('cmd_ext4') +def test_mmc_ext4ls(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + fs = 'ext4' + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + u_boot_console.run_command('mmc dev %d' % x) + for part in partitions: + output = u_boot_console.run_command('%sls mmc %d:%s' % (fs, x, part)) + if 'Unrecognized filesystem type' in output: + partitions.remove(part) + pytest.fail('Unrecognized filesystem') + part_detect = 1 + + if not part_detect: + pytest.skip('No %s partition detected' % fs.upper()) + +@pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.buildconfigspec('cmd_ext4') +@pytest.mark.buildconfigspec('ext4_write') +@pytest.mark.buildconfigspec('cmd_memory') +def test_mmc_ext4load_ext4write(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + fs = 'ext4' + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + addr = u_boot_utils.find_ram_base(u_boot_console) + devices[x]['addr_%d' % part] = addr + size = random.randint(4, 1 * 1024 * 1024) + devices[x]['size_%d' % part] = size + # count CRC32 + output = u_boot_console.run_command('crc32 %x %x' % (addr, size)) + m = re.search('==> (.+?)', output) + if not m: + pytest.fail('CRC32 failed') + expected_crc32 = m.group(1) + devices[x]['expected_crc32_%d' % part] = expected_crc32 + # do write + + file = '%s_%d' % ('uboot_test', size) + devices[x]['file_%d' % part] = file + output = u_boot_console.run_command( + '%swrite mmc %d:%s %x /%s %x' % (fs, x, part, addr, file, size) + ) + assert 'Unable to write' not in output + assert 'Error' not in output + assert 'overflow' not in output + expected_text = '%d bytes written' % size + assert expected_text in output + + offset = random.randrange(128, 1024, 128) + output = u_boot_console.run_command( + '%sload mmc %d:%s %x /%s' % (fs, x, part, addr + offset, file) + ) + expected_text = '%d bytes read' % size + assert expected_text in output + + output = u_boot_console.run_command( + 'crc32 %x $filesize' % (addr + offset) + ) + assert expected_crc32 in output + + if not part_detect: + pytest.skip('No %s partition detected' % fs.upper()) + +@pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.buildconfigspec('cmd_ext2') +def test_mmc_ext2ls(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + fs = 'ext2' + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + output = u_boot_console.run_command('%sls mmc %d:%s' % (fs, x, part)) + if 'Unrecognized filesystem type' in output: + partitions.remove(part) + pytest.fail('Unrecognized filesystem') + part_detect = 1 + + if not part_detect: + pytest.skip('No %s partition detected' % fs.upper()) + +@pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.buildconfigspec('cmd_ext2') +@pytest.mark.buildconfigspec('cmd_ext4') +@pytest.mark.buildconfigspec('ext4_write') +@pytest.mark.buildconfigspec('cmd_memory') +def test_mmc_ext2load(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + fs = 'ext2' + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + addr = devices[x]['addr_%d' % part] + size = devices[x]['size_%d' % part] + expected_crc32 = devices[x]['expected_crc32_%d' % part] + file = devices[x]['file_%d' % part] + + offset = random.randrange(128, 1024, 128) + output = u_boot_console.run_command( + '%sload mmc %d:%s %x /%s' % (fs, x, part, addr + offset, file) + ) + expected_text = '%d bytes read' % size + assert expected_text in output + + output = u_boot_console.run_command( + 'crc32 %x $filesize' % (addr + offset) + ) + assert expected_crc32 in output + + if not part_detect: + pytest.skip('No %s partition detected' % fs.upper()) + +@pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.buildconfigspec('cmd_fs_generic') +def test_mmc_ls(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + for fs in ['fat', 'ext4']: + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + output = u_boot_console.run_command('ls mmc %d:%s' % (x, part)) + if re.search(r'No \w+ table on this device', output): + pytest.fail( + '%s: Partition table not found %d' % (fs.upper(), x) + ) + + if not part_detect: + pytest.skip('No partition detected') + +@pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.buildconfigspec('cmd_fs_generic') +def test_mmc_load(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + for fs in ['fat', 'ext4']: + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + addr = devices[x]['addr_%d' % part] + size = devices[x]['size_%d' % part] + expected_crc32 = devices[x]['expected_crc32_%d' % part] + file = devices[x]['file_%d' % part] + + offset = random.randrange(128, 1024, 128) + output = u_boot_console.run_command( + 'load mmc %d:%s %x /%s' % (x, part, addr + offset, file) + ) + expected_text = '%d bytes read' % size + assert expected_text in output + + output = u_boot_console.run_command( + 'crc32 %x $filesize' % (addr + offset) + ) + assert expected_crc32 in output + + if not part_detect: + pytest.skip('No partition detected') + +@pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.buildconfigspec('cmd_fs_generic') +def test_mmc_save(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + for fs in ['fat', 'ext4']: + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + addr = devices[x]['addr_%d' % part] + size = 0 + file = devices[x]['file_%d' % part] + + offset = random.randrange(128, 1024, 128) + output = u_boot_console.run_command( + 'save mmc %d:%s %x /%s %d' + % (x, part, addr + offset, file, size) + ) + expected_text = '%d bytes written' % size + assert expected_text in output + + if not part_detect: + pytest.skip('No partition detected') + +@pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.buildconfigspec('cmd_fat') +@pytest.mark.buildconfigspec('cmd_memory') +def test_mmc_fat_read_write_files(u_boot_console): + test_mmc_list(u_boot_console) + test_mmc_dev(u_boot_console) + test_mmcinfo(u_boot_console) + test_mmc_part(u_boot_console) + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + fs = 'fat' + + # Number of files to be written/read in MMC card + num_files = 100 + + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + addr = u_boot_utils.find_ram_base(u_boot_console) + count_f = 0 + addr_l = [] + size_l = [] + file_l = [] + crc32_l = [] + offset_l = [] + addr_l.append(addr) + + while count_f < num_files: + size_l.append(random.randint(4, 1 * 1024 * 1024)) + + # CRC32 count + output = u_boot_console.run_command( + 'crc32 %x %x' % (addr_l[count_f], size_l[count_f]) + ) + m = re.search('==> (.+?)', output) + if not m: + pytest.fail('CRC32 failed') + crc32_l.append(m.group(1)) + + # Write operation + file_l.append('%s_%d_%d' % ('uboot_test', count_f, size_l[count_f])) + output = u_boot_console.run_command( + '%swrite mmc %d:%s %x %s %x' + % ( + fs, + x, + part, + addr_l[count_f], + file_l[count_f], + size_l[count_f], + ) + ) + assert 'Unable to write' not in output + assert 'Error' not in output + assert 'overflow' not in output + expected_text = '%d bytes written' % size_l[count_f] + assert expected_text in output + + addr_l.append(addr_l[count_f] + size_l[count_f] + 1048576) + count_f += 1 + + count_f = 0 + while count_f < num_files: + alignment = int( + u_boot_console.config.buildconfig.get( + 'config_sys_cacheline_size', 128 + ) + ) + offset_l.append(random.randrange(alignment, 1024, alignment)) + + # Read operation + output = u_boot_console.run_command( + '%sload mmc %d:%s %x %s' + % ( + fs, + x, + part, + addr_l[count_f] + offset_l[count_f], + file_l[count_f], + ) + ) + assert 'Invalid FAT entry' not in output + assert 'Unable to read file' not in output + assert 'Misaligned buffer address' not in output + expected_text = '%d bytes read' % size_l[count_f] + assert expected_text in output + + output = u_boot_console.run_command( + 'crc32 %x $filesize' % (addr_l[count_f] + offset_l[count_f]) + ) + assert crc32_l[count_f] in output + + count_f += 1 + + if not part_detect: + pytest.skip('No %s partition detected' % fs.upper()) |