diff --git a/TESTS/host_tests/pyusb_msd.py b/TESTS/host_tests/pyusb_msd.py index 0fbd9cecf2..4ab7529657 100644 --- a/TESTS/host_tests/pyusb_msd.py +++ b/TESTS/host_tests/pyusb_msd.py @@ -127,7 +127,17 @@ class PyusbMSDTest(BaseHostTest): else: self.report_error("unmount") + def _callback_os_type(self, key, value, timestamp): + system_name = platform.system() + if system_name == "Windows": + self.send_kv("os_type", 1) + elif system_name == "Linux": + self.send_kv("os_type", 2) + elif system_name == "Darwin": + self.send_kv("os_type", 3) + def setup(self): + self.register_callback("get_os_type", self._callback_os_type) self.register_callback("get_serial_number", self._callback_device_ready) self.register_callback('check_if_mounted', self._callback_check_if_mounted) self.register_callback('check_if_not_mounted', self._callback_check_if_not_mounted) @@ -204,25 +214,16 @@ class MSDUtils(object): @staticmethod def _unmount_windows(serial): disk_path = MSDUtils._disk_path_windows(serial) - tmp_file = tempfile.NamedTemporaryFile(suffix='.ps1', delete=False) - try: - # create unmount script - tmp_file.write('$disk_leter=$args[0]\n') - tmp_file.write('$driveEject = New-Object -comObject Shell.Application\n') - tmp_file.write('$driveEject.Namespace(17).ParseName($disk_leter).InvokeVerb("Eject")\n') - # close to allow open by other process - tmp_file.close() + cmd_string = r'(New-Object -comObject Shell.Application).Namespace(17).ParseName("{}").InvokeVerb("Eject")'.format(disk_path) - try_count = 10 - while try_count: - p = subprocess.Popen(["powershell.exe", tmp_file.name + " " + disk_path], stdout=sys.stdout) - p.communicate() - try_count -= 1 - if MSDUtils._disk_path_windows(serial) is None: - return True - time.sleep(1) - finally: - os.remove(tmp_file.name) + try_count = 10 + while try_count: + p = subprocess.Popen(["powershell.exe", cmd_string], stdout=sys.stdout) + p.communicate() + try_count -= 1 + if MSDUtils._disk_path_windows(serial) is None: + return True + time.sleep(1) return False diff --git a/TESTS/usb_device/README.md b/TESTS/usb_device/README.md index 7931b082b0..f1d3bc8c90 100644 --- a/TESTS/usb_device/README.md +++ b/TESTS/usb_device/README.md @@ -136,6 +136,14 @@ The FAT32 filesystem cannot be mounted on a device smaller than 64 kB. The test can be easily extended to use any block device available in Mbed. +### Windows 8/10: Mass storage tests are failing on test file read +By default Windows 8 and 10 access and write to removable drives shortly after they are connected. It's caused by drive indexing mechanisms. Because disk used in test has only 64kB its content can be easily corrupted by writing large files, what actually was encountered during test runs. + +To prevent Windows from writing to removable drives on connect drive indexing can be turned off with the following procedure: +- Start the program "gpedit.msc" +- Navigate to "Computer Configuration \ Administrative Templates \ Windows Components \ Search" +- Enable the policy "Do not allow locations on removable drives to be added to libraries." + ### Isochronous endpoints are skipped in loopback tests #### Unresolved diff --git a/TESTS/usb_device/msd/main.cpp b/TESTS/usb_device/msd/main.cpp index 1666afefc7..a634958802 100644 --- a/TESTS/usb_device/msd/main.cpp +++ b/TESTS/usb_device/msd/main.cpp @@ -33,6 +33,17 @@ #error [NOT_SUPPORTED] USB Device not supported for this target #endif + +#define OS_WINDOWS 1 +#define OS_LINUX 2 +#define OS_MAC 3 + +// Host side unmount was disabled for windows machines. +// PowerShell execution policies/restrictions cause that +// on some windows machines unmount is failing +// To re-enable it comment out below line. +#define DISABLE_HOST_SIDE_UMOUNT + #ifdef MIN #undef MIN #endif @@ -250,13 +261,10 @@ void msd_process(USBMSD *msd) */ void storage_init() { - if (mbed_heap_size >= MIN_HEAP_SIZE) { - FATFileSystem::format(get_heap_block_device()); - bool result = prepare_storage(get_heap_block_device(), &heap_fs); - TEST_ASSERT_MESSAGE(result, "heap storage initialisation failed"); - } else { - utest_printf("Not enough heap memory for HeapBlockDevice creation. Heap block device init skipped!!!\n"); - } + TEST_ASSERT_MESSAGE(mbed_heap_size >= MIN_HEAP_SIZE, "Not enough heap memory for HeapBlockDevice creation"); + FATFileSystem::format(get_heap_block_device()); + bool result = prepare_storage(get_heap_block_device(), &heap_fs); + TEST_ASSERT_MESSAGE(result, "heap storage initialisation failed"); } /** Test mass storage device mount and unmount @@ -316,19 +324,31 @@ void mount_unmount_test(BlockDevice *bd, FileSystem *fs) uint64_t ret_size = atoll(_key); TEST_ASSERT_EQUAL_UINT64(get_fs_mount_size(fs), ret_size); - // unmount msd device on host side - greentea_send_kv("unmount", 0); +#ifdef DISABLE_HOST_SIDE_UMOUNT + greentea_send_kv("get_os_type", 0); greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value)); - TEST_ASSERT_EQUAL_STRING_LOOP("passed", _key, i); + int32_t os_type = atoi(_value); + if (os_type != OS_WINDOWS) { +#endif + // unmount msd device on host side + greentea_send_kv("unmount", 0); + greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value)); + TEST_ASSERT_EQUAL_STRING_LOOP("passed", _key, i); - // wait for unmount event (set 10s timeout) - media_remove_event.wait(10000); - if (!usb.media_removed()) { - TEST_ASSERT_EQUAL_LOOP(true, usb.media_removed(), i); + // wait for unmount event (set 10s timeout) + media_remove_event.wait(10000); + if (!usb.media_removed()) { + TEST_ASSERT_EQUAL_LOOP(true, usb.media_removed(), i); + } + + // unmount since media_removed doesn't disconnects device side + usb.disconnect(); +#ifdef DISABLE_HOST_SIDE_UMOUNT + } else { + // unmount + usb.disconnect(); } - // unmount since media_removed doesn't disconnects device side - usb.disconnect(); - +#endif // check if device is detached on host side greentea_send_kv("check_if_not_mounted", 0); greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value)); @@ -428,19 +448,13 @@ void mount_unmount_and_data_test(BlockDevice *bd, FileSystem *fs) void heap_block_device_mount_unmount_test() { - if (mbed_heap_size < MIN_HEAP_SIZE) { - TEST_SKIP_MESSAGE("Not enough heap memory for HeapBlockDevice creation"); - return; - } + TEST_ASSERT_MESSAGE(mbed_heap_size >= MIN_HEAP_SIZE, "Not enough heap memory for HeapBlockDevice creation"); mount_unmount_test<3>(get_heap_block_device(), &heap_fs); } void heap_block_device_mount_unmount_and_data_test() { - if (mbed_heap_size < MIN_HEAP_SIZE) { - TEST_SKIP_MESSAGE("Not enough heap memory for HeapBlockDevice creation"); - return; - } + TEST_ASSERT_MESSAGE(mbed_heap_size >= MIN_HEAP_SIZE, "Not enough heap memory for HeapBlockDevice creation"); mount_unmount_and_data_test(get_heap_block_device(), &heap_fs); }