"Das U-Boot" Source Tree
at master 632 lines 23 kB view raw
1# SPDX-License-Identifier: GPL-2.0 2# (C) Copyright 2023, Advanced Micro Devices, Inc. 3 4import pytest 5import random 6import re 7import u_boot_utils 8 9""" 10Note: This test doesn't rely on boardenv_* configuration values but it can 11change the test behavior. To test USB file system cases (fat32, ext2, ext4), 12USB device should be formatted and valid partitions should be created for 13different file system, otherwise it may leads to failure. This test will be 14skipped if the USB device is not detected. 15 16For example: 17 18# Setup env__usb_device_test_skip to not skipping the test. By default, its 19# value is set to True. Set it to False to run all tests for USB device. 20env__usb_device_test_skip = False 21""" 22 23def setup_usb(u_boot_console): 24 if u_boot_console.config.env.get('env__usb_device_test_skip', True): 25 pytest.skip('USB device test is not enabled') 26 27@pytest.mark.buildconfigspec('cmd_usb') 28def test_usb_start(u_boot_console): 29 setup_usb(u_boot_console) 30 output = u_boot_console.run_command('usb start') 31 32 # if output is empty, usb start may already run as part of preboot command 33 # re-start the usb, in that case 34 if not output: 35 u_boot_console.run_command('usb stop') 36 output = u_boot_console.run_command('usb start') 37 38 if 'No USB device found' in output: 39 pytest.skip('No USB controller available') 40 41 if 'Card did not respond to voltage select' in output: 42 pytest.skip('No USB device present') 43 44 controllers = 0 45 storage_device = 0 46 obj = re.search(r'\d USB Device\(s\) found', output) 47 controllers = int(obj.group()[0]) 48 49 if not controllers: 50 pytest.skip('No USB device present') 51 52 obj = re.search(r'\d Storage Device\(s\) found', output) 53 storage_device = int(obj.group()[0]) 54 55 if not storage_device: 56 pytest.skip('No USB storage device present') 57 58 assert 'USB init failed' not in output 59 assert 'starting USB...' in output 60 61 if 'Starting the controller' in output: 62 assert 'USB XHCI' in output 63 64 output = u_boot_console.run_command('echo $?') 65 assert output.endswith('0') 66 return controllers, storage_device 67 68@pytest.mark.buildconfigspec('cmd_usb') 69def test_usb_stop(u_boot_console): 70 setup_usb(u_boot_console) 71 output = u_boot_console.run_command('usb stop') 72 assert 'stopping USB..' in output 73 74 output = u_boot_console.run_command('echo $?') 75 assert output.endswith('0') 76 77 output = u_boot_console.run_command('usb dev') 78 assert "USB is stopped. Please issue 'usb start' first." in output 79 80@pytest.mark.buildconfigspec('cmd_usb') 81def test_usb_reset(u_boot_console): 82 setup_usb(u_boot_console) 83 output = u_boot_console.run_command('usb reset') 84 85 if 'No USB device found' in output: 86 pytest.skip('No USB controller available') 87 88 if 'Card did not respond to voltage select' in output: 89 pytest.skip('No USB device present') 90 91 obj = re.search(r'\d USB Device\(s\) found', output) 92 usb_dev_num = int(obj.group()[0]) 93 94 if not usb_dev_num: 95 pytest.skip('No USB device present') 96 97 obj = re.search(r'\d Storage Device\(s\) found', output) 98 usb_stor_num = int(obj.group()[0]) 99 100 if not usb_stor_num: 101 pytest.skip('No USB storage device present') 102 103 assert 'BUG' not in output 104 assert 'USB init failed' not in output 105 assert 'resetting USB...' in output 106 107 if 'Starting the controller' in output: 108 assert 'USB XHCI' in output 109 110 output = u_boot_console.run_command('echo $?') 111 assert output.endswith('0') 112 113@pytest.mark.buildconfigspec('cmd_usb') 114def test_usb_info(u_boot_console): 115 controllers, storage_device = test_usb_start(u_boot_console) 116 output = u_boot_console.run_command('usb info') 117 118 num_controller = len(re.findall(': Hub,', output)) 119 num_mass_storage = len(re.findall(': Mass Storage,', output)) 120 121 assert num_controller == controllers - 1 122 assert num_mass_storage == storage_device 123 124 output = u_boot_console.run_command('echo $?') 125 assert output.endswith('0') 126 127 for i in range(0, storage_device + controllers - 1): 128 output = u_boot_console.run_command('usb info %d' % i) 129 num_controller = len(re.findall(': Hub,', output)) 130 num_mass_storage = len(re.findall(': Mass Storage,', output)) 131 assert num_controller + num_mass_storage == 1 132 assert 'No device available' not in output 133 output = u_boot_console.run_command('echo $?') 134 assert output.endswith('0') 135 136@pytest.mark.buildconfigspec('cmd_usb') 137def test_usb_tree(u_boot_console): 138 controllers, storage_device = test_usb_start(u_boot_console) 139 output = u_boot_console.run_command('usb tree') 140 141 num_controller = len(re.findall('Hub', output)) 142 num_mass_storage = len(re.findall('Mass Storage', output)) 143 144 assert num_controller == controllers - 1 145 assert num_mass_storage == storage_device 146 147 output = u_boot_console.run_command('echo $?') 148 assert output.endswith('0') 149 150@pytest.mark.buildconfigspec('cmd_usb') 151@pytest.mark.buildconfigspec('usb_storage') 152def test_usb_storage(u_boot_console): 153 controllers, storage_device = test_usb_start(u_boot_console) 154 output = u_boot_console.run_command('usb storage') 155 156 obj = re.findall(r'Capacity: (\d+|\d+[\.]?\d)', output) 157 devices = {} 158 159 for key in range(int(storage_device)): 160 devices[key] = {} 161 162 for x in range(int(storage_device)): 163 try: 164 capacity = float(obj[x].split()[0]) 165 devices[x]['capacity'] = capacity 166 print('USB storage device %d capacity is: %g MB' % (x, capacity)) 167 except ValueError: 168 pytest.fail('USB storage device capacity not recognized') 169 170 output = u_boot_console.run_command('echo $?') 171 assert output.endswith('0') 172 173@pytest.mark.buildconfigspec('cmd_usb') 174def test_usb_dev(u_boot_console): 175 controllers, storage_device = test_usb_start(u_boot_console) 176 output = u_boot_console.run_command('usb dev') 177 178 assert 'no usb devices available' not in output 179 180 output = u_boot_console.run_command('echo $?') 181 assert output.endswith('0') 182 183 devices = {} 184 185 for key in range(int(storage_device)): 186 devices[key] = {} 187 188 fail = 0 189 for x in range(0, storage_device): 190 devices[x]['detected'] = 'yes' 191 output = u_boot_console.run_command('usb dev %d' % x) 192 193 if 'Card did not respond to voltage select' in output: 194 fail = 1 195 devices[x]['detected'] = 'no' 196 197 if 'No USB device found' in output: 198 devices[x]['detected'] = 'no' 199 200 if 'unknown device' in output: 201 devices[x]['detected'] = 'no' 202 203 assert 'is now current device' in output 204 output = u_boot_console.run_command('echo $?') 205 assert output.endswith('0') 206 207 if fail: 208 pytest.fail('USB device not present') 209 210 return devices, controllers, storage_device 211 212@pytest.mark.buildconfigspec('cmd_usb') 213def test_usb_part(u_boot_console): 214 devices, controllers, storage_device = test_usb_dev(u_boot_console) 215 if not devices: 216 pytest.skip('No devices detected') 217 218 u_boot_console.run_command('usb part') 219 220 output = u_boot_console.run_command('echo $?') 221 assert output.endswith('0') 222 223 for i in range(0, storage_device): 224 if devices[i]['detected'] == 'yes': 225 u_boot_console.run_command('usb dev %d' % i) 226 output = u_boot_console.run_command('usb part') 227 228 lines = output.split('\n') 229 part_fat = [] 230 part_ext2 = [] 231 part_ext4 = [] 232 for line in lines: 233 obj = re.search(r'(\d)\s+\d+\s+\d+\s+\w+\d+\w+-\d+\s+(\d+\w+)', line) 234 if obj: 235 part_id = int(obj.groups()[0]) 236 part_type = obj.groups()[1] 237 print('part_id:%d, part_type:%s' % (part_id, part_type)) 238 239 if part_type == '0c' or part_type == '0b' or part_type == '0e': 240 print('Fat detected') 241 part_fat.append(part_id) 242 elif part_type == '83': 243 print('ext(2/4) detected') 244 output = u_boot_console.run_command( 245 'fstype usb %d:%d' % (i, part_id) 246 ) 247 if 'ext2' in output: 248 part_ext2.append(part_id) 249 elif 'ext4' in output: 250 part_ext4.append(part_id) 251 else: 252 pytest.fail('Unsupported Filesystem on device %d' % i) 253 devices[i]['ext4'] = part_ext4 254 devices[i]['ext2'] = part_ext2 255 devices[i]['fat'] = part_fat 256 257 if not part_ext2 and not part_ext4 and not part_fat: 258 pytest.fail('No partition detected on device %d' % i) 259 260 return devices, controllers, storage_device 261 262@pytest.mark.buildconfigspec('cmd_usb') 263@pytest.mark.buildconfigspec('cmd_fat') 264def test_usb_fatls_fatinfo(u_boot_console): 265 devices, controllers, storage_device = test_usb_part(u_boot_console) 266 if not devices: 267 pytest.skip('No devices detected') 268 269 part_detect = 0 270 fs = 'fat' 271 for x in range(0, int(storage_device)): 272 if devices[x]['detected'] == 'yes': 273 u_boot_console.run_command('usb dev %d' % x) 274 try: 275 partitions = devices[x][fs] 276 except: 277 print('No %s table on this device' % fs.upper()) 278 continue 279 280 for part in partitions: 281 output = u_boot_console.run_command('fatls usb %d:%s' % (x, part)) 282 if 'Unrecognized filesystem type' in output: 283 partitions.remove(part) 284 pytest.fail('Unrecognized filesystem') 285 286 if not re.search(r'\d file\(s\), \d dir\(s\)', output): 287 pytest.fail('%s read failed on device %d' % (fs.upper, x)) 288 289 output = u_boot_console.run_command('fatinfo usb %d:%s' % (x, part)) 290 string = 'Filesystem: %s' % fs.upper 291 if re.search(string, output): 292 pytest.fail('%s FS failed on device %d' % (fs.upper(), x)) 293 part_detect = 1 294 295 if not part_detect: 296 pytest.skip('No %s partition detected' % fs.upper()) 297 298def usb_fatload_fatwrite(u_boot_console, fs, x, part): 299 addr = u_boot_utils.find_ram_base(u_boot_console) 300 size = random.randint(4, 1 * 1024 * 1024) 301 output = u_boot_console.run_command('crc32 %x %x' % (addr, size)) 302 m = re.search('==> (.+?)', output) 303 if not m: 304 pytest.fail('CRC32 failed') 305 expected_crc32 = m.group(1) 306 307 file = '%s_%d' % ('uboot_test', size) 308 output = u_boot_console.run_command( 309 '%swrite usb %d:%s %x %s %x' % (fs, x, part, addr, file, size) 310 ) 311 assert 'Unable to write' not in output 312 assert 'Error' not in output 313 assert 'overflow' not in output 314 expected_text = '%d bytes written' % size 315 assert expected_text in output 316 317 alignment = int( 318 u_boot_console.config.buildconfig.get( 319 'config_sys_cacheline_size', 128 320 ) 321 ) 322 offset = random.randrange(alignment, 1024, alignment) 323 output = u_boot_console.run_command( 324 '%sload usb %d:%s %x %s' % (fs, x, part, addr + offset, file) 325 ) 326 assert 'Invalid FAT entry' not in output 327 assert 'Unable to read file' not in output 328 assert 'Misaligned buffer address' not in output 329 expected_text = '%d bytes read' % size 330 assert expected_text in output 331 332 output = u_boot_console.run_command( 333 'crc32 %x $filesize' % (addr + offset) 334 ) 335 assert expected_crc32 in output 336 337 return file, size, expected_crc32 338 339@pytest.mark.buildconfigspec('cmd_usb') 340@pytest.mark.buildconfigspec('cmd_fat') 341@pytest.mark.buildconfigspec('cmd_memory') 342def test_usb_fatload_fatwrite(u_boot_console): 343 devices, controllers, storage_device = test_usb_part(u_boot_console) 344 if not devices: 345 pytest.skip('No devices detected') 346 347 part_detect = 0 348 fs = 'fat' 349 for x in range(0, int(storage_device)): 350 if devices[x]['detected'] == 'yes': 351 u_boot_console.run_command('usb dev %d' % x) 352 try: 353 partitions = devices[x][fs] 354 except: 355 print('No %s table on this device' % fs.upper()) 356 continue 357 358 for part in partitions: 359 part_detect = 1 360 usb_fatload_fatwrite(u_boot_console, fs, x, part) 361 362 if not part_detect: 363 pytest.skip('No %s partition detected' % fs.upper()) 364 365@pytest.mark.buildconfigspec('cmd_usb') 366@pytest.mark.buildconfigspec('cmd_ext4') 367def test_usb_ext4ls(u_boot_console): 368 devices, controllers, storage_device = test_usb_part(u_boot_console) 369 if not devices: 370 pytest.skip('No devices detected') 371 372 part_detect = 0 373 fs = 'ext4' 374 for x in range(0, int(storage_device)): 375 if devices[x]['detected'] == 'yes': 376 try: 377 partitions = devices[x][fs] 378 except: 379 print('No %s table on this device' % fs.upper()) 380 continue 381 382 u_boot_console.run_command('usb dev %d' % x) 383 for part in partitions: 384 output = u_boot_console.run_command('%sls usb %d:%s' % (fs, x, part)) 385 if 'Unrecognized filesystem type' in output: 386 partitions.remove(part) 387 pytest.fail('Unrecognized filesystem') 388 part_detect = 1 389 390 if not part_detect: 391 pytest.skip('No %s partition detected' % fs.upper()) 392 393def usb_ext4load_ext4write(u_boot_console, fs, x, part): 394 addr = u_boot_utils.find_ram_base(u_boot_console) 395 size = random.randint(4, 1 * 1024 * 1024) 396 output = u_boot_console.run_command('crc32 %x %x' % (addr, size)) 397 m = re.search('==> (.+?)', output) 398 if not m: 399 pytest.fail('CRC32 failed') 400 expected_crc32 = m.group(1) 401 file = '%s_%d' % ('uboot_test', size) 402 403 output = u_boot_console.run_command( 404 '%swrite usb %d:%s %x /%s %x' % (fs, x, part, addr, file, size) 405 ) 406 assert 'Unable to write' not in output 407 assert 'Error' not in output 408 assert 'overflow' not in output 409 expected_text = '%d bytes written' % size 410 assert expected_text in output 411 412 offset = random.randrange(128, 1024, 128) 413 output = u_boot_console.run_command( 414 '%sload usb %d:%s %x /%s' % (fs, x, part, addr + offset, file) 415 ) 416 expected_text = '%d bytes read' % size 417 assert expected_text in output 418 419 output = u_boot_console.run_command( 420 'crc32 %x $filesize' % (addr + offset) 421 ) 422 assert expected_crc32 in output 423 424 return file, size, expected_crc32 425 426@pytest.mark.buildconfigspec('cmd_usb') 427@pytest.mark.buildconfigspec('cmd_ext4') 428@pytest.mark.buildconfigspec('cmd_ext4_write') 429@pytest.mark.buildconfigspec('cmd_memory') 430def test_usb_ext4load_ext4write(u_boot_console): 431 devices, controllers, storage_device = test_usb_part(u_boot_console) 432 if not devices: 433 pytest.skip('No devices detected') 434 435 part_detect = 0 436 fs = 'ext4' 437 for x in range(0, int(storage_device)): 438 if devices[x]['detected'] == 'yes': 439 u_boot_console.run_command('usb dev %d' % x) 440 try: 441 partitions = devices[x][fs] 442 except: 443 print('No %s table on this device' % fs.upper()) 444 continue 445 446 for part in partitions: 447 part_detect = 1 448 usb_ext4load_ext4write(u_boot_console, fs, x, part) 449 450 if not part_detect: 451 pytest.skip('No %s partition detected' % fs.upper()) 452 453@pytest.mark.buildconfigspec('cmd_usb') 454@pytest.mark.buildconfigspec('cmd_ext2') 455def test_usb_ext2ls(u_boot_console): 456 devices, controllers, storage_device = test_usb_part(u_boot_console) 457 if not devices: 458 pytest.skip('No devices detected') 459 460 part_detect = 0 461 fs = 'ext2' 462 for x in range(0, int(storage_device)): 463 if devices[x]['detected'] == 'yes': 464 u_boot_console.run_command('usb dev %d' % x) 465 try: 466 partitions = devices[x][fs] 467 except: 468 print('No %s table on this device' % fs.upper()) 469 continue 470 471 for part in partitions: 472 part_detect = 1 473 output = u_boot_console.run_command('%sls usb %d:%s' % (fs, x, part)) 474 if 'Unrecognized filesystem type' in output: 475 partitions.remove(part) 476 pytest.fail('Unrecognized filesystem') 477 part_detect = 1 478 479 if not part_detect: 480 pytest.skip('No %s partition detected' % fs.upper()) 481 482@pytest.mark.buildconfigspec('cmd_usb') 483@pytest.mark.buildconfigspec('cmd_ext2') 484@pytest.mark.buildconfigspec('cmd_ext4') 485@pytest.mark.buildconfigspec('cmd_ext4_write') 486@pytest.mark.buildconfigspec('cmd_memory') 487def test_usb_ext2load(u_boot_console): 488 devices, controllers, storage_device = test_usb_part(u_boot_console) 489 490 if not devices: 491 pytest.skip('No devices detected') 492 493 part_detect = 0 494 fs = 'ext2' 495 for x in range(0, int(storage_device)): 496 if devices[x]['detected'] == 'yes': 497 u_boot_console.run_command('usb dev %d' % x) 498 try: 499 partitions = devices[x][fs] 500 except: 501 print('No %s table on this device' % fs.upper()) 502 continue 503 504 for part in partitions: 505 part_detect = 1 506 file, size, expected_crc32 = \ 507 usb_ext4load_ext4write(u_boot_console, fs, x, part) 508 addr = u_boot_utils.find_ram_base(u_boot_console) 509 510 offset = random.randrange(128, 1024, 128) 511 output = u_boot_console.run_command( 512 '%sload usb %d:%s %x /%s' % (fs, x, part, addr + offset, file) 513 ) 514 expected_text = '%d bytes read' % size 515 assert expected_text in output 516 517 output = u_boot_console.run_command( 518 'crc32 %x $filesize' % (addr + offset) 519 ) 520 assert expected_crc32 in output 521 522 if not part_detect: 523 pytest.skip('No %s partition detected' % fs.upper()) 524 525@pytest.mark.buildconfigspec('cmd_usb') 526@pytest.mark.buildconfigspec('cmd_fs_generic') 527def test_usb_ls(u_boot_console): 528 devices, controllers, storage_device = test_usb_part(u_boot_console) 529 if not devices: 530 pytest.skip('No devices detected') 531 532 part_detect = 0 533 for x in range(0, int(storage_device)): 534 if devices[x]['detected'] == 'yes': 535 u_boot_console.run_command('usb dev %d' % x) 536 for fs in ['fat', 'ext2', 'ext4']: 537 try: 538 partitions = devices[x][fs] 539 except: 540 print('No %s table on this device' % fs.upper()) 541 continue 542 543 for part in partitions: 544 part_detect = 1 545 output = u_boot_console.run_command('ls usb %d:%s' % (x, part)) 546 if re.search(r'No \w+ table on this device', output): 547 pytest.fail( 548 '%s: Partition table not found %d' % (fs.upper(), x) 549 ) 550 551 if not part_detect: 552 pytest.skip('No partition detected') 553 554@pytest.mark.buildconfigspec('cmd_usb') 555@pytest.mark.buildconfigspec('cmd_ext4_write') 556@pytest.mark.buildconfigspec('cmd_fs_generic') 557def test_usb_load(u_boot_console): 558 devices, controllers, storage_device = test_usb_part(u_boot_console) 559 if not devices: 560 pytest.skip('No devices detected') 561 562 part_detect = 0 563 for x in range(0, int(storage_device)): 564 if devices[x]['detected'] == 'yes': 565 u_boot_console.run_command('usb dev %d' % x) 566 for fs in ['fat', 'ext2', 'ext4']: 567 try: 568 partitions = devices[x][fs] 569 except: 570 print('No %s table on this device' % fs.upper()) 571 continue 572 573 for part in partitions: 574 part_detect = 1 575 addr = u_boot_utils.find_ram_base(u_boot_console) 576 577 if fs == 'fat': 578 file, size, expected_crc32 = \ 579 usb_fatload_fatwrite(u_boot_console, fs, x, part) 580 elif fs in ['ext4', 'ext2']: 581 file, size, expected_crc32 = \ 582 usb_ext4load_ext4write(u_boot_console, fs, x, part) 583 584 offset = random.randrange(128, 1024, 128) 585 output = u_boot_console.run_command( 586 'load usb %d:%s %x /%s' % (x, part, addr + offset, file) 587 ) 588 expected_text = '%d bytes read' % size 589 assert expected_text in output 590 591 output = u_boot_console.run_command( 592 'crc32 %x $filesize' % (addr + offset) 593 ) 594 assert expected_crc32 in output 595 596 if not part_detect: 597 pytest.skip('No partition detected') 598 599@pytest.mark.buildconfigspec('cmd_usb') 600@pytest.mark.buildconfigspec('cmd_fs_generic') 601def test_usb_save(u_boot_console): 602 devices, controllers, storage_device = test_usb_part(u_boot_console) 603 if not devices: 604 pytest.skip('No devices detected') 605 606 part_detect = 0 607 for x in range(0, int(storage_device)): 608 if devices[x]['detected'] == 'yes': 609 u_boot_console.run_command('usb dev %d' % x) 610 for fs in ['fat', 'ext2', 'ext4']: 611 try: 612 partitions = devices[x][fs] 613 except: 614 print('No %s table on this device' % fs.upper()) 615 continue 616 617 for part in partitions: 618 part_detect = 1 619 addr = u_boot_utils.find_ram_base(u_boot_console) 620 size = random.randint(4, 1 * 1024 * 1024) 621 file = '%s_%d' % ('uboot_test', size) 622 623 offset = random.randrange(128, 1024, 128) 624 output = u_boot_console.run_command( 625 'save usb %d:%s %x /%s %x' 626 % (x, part, addr + offset, file, size) 627 ) 628 expected_text = '%d bytes written' % size 629 assert expected_text in output 630 631 if not part_detect: 632 pytest.skip('No partition detected')