Skip to content

Commit dfdf70b

Browse files
authored
Merge pull request #10767 from maciejbocianski/msd_test_windows_unmount_fix
usb_device-msd test: fix powershell unmount script issue
2 parents 61c4d05 + b4138d1 commit dfdf70b

File tree

3 files changed

+68
-45
lines changed

3 files changed

+68
-45
lines changed

TESTS/host_tests/pyusb_msd.py

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,17 @@ def _callback_unmount(self, key, value, timestamp):
127127
else:
128128
self.report_error("unmount")
129129

130+
def _callback_os_type(self, key, value, timestamp):
131+
system_name = platform.system()
132+
if system_name == "Windows":
133+
self.send_kv("os_type", 1)
134+
elif system_name == "Linux":
135+
self.send_kv("os_type", 2)
136+
elif system_name == "Darwin":
137+
self.send_kv("os_type", 3)
138+
130139
def setup(self):
140+
self.register_callback("get_os_type", self._callback_os_type)
131141
self.register_callback("get_serial_number", self._callback_device_ready)
132142
self.register_callback('check_if_mounted', self._callback_check_if_mounted)
133143
self.register_callback('check_if_not_mounted', self._callback_check_if_not_mounted)
@@ -204,25 +214,16 @@ def _disk_path_mac(serial):
204214
@staticmethod
205215
def _unmount_windows(serial):
206216
disk_path = MSDUtils._disk_path_windows(serial)
207-
tmp_file = tempfile.NamedTemporaryFile(suffix='.ps1', delete=False)
208-
try:
209-
# create unmount script
210-
tmp_file.write('$disk_leter=$args[0]\n')
211-
tmp_file.write('$driveEject = New-Object -comObject Shell.Application\n')
212-
tmp_file.write('$driveEject.Namespace(17).ParseName($disk_leter).InvokeVerb("Eject")\n')
213-
# close to allow open by other process
214-
tmp_file.close()
215-
216-
try_count = 10
217-
while try_count:
218-
p = subprocess.Popen(["powershell.exe", tmp_file.name + " " + disk_path], stdout=sys.stdout)
219-
p.communicate()
220-
try_count -= 1
221-
if MSDUtils._disk_path_windows(serial) is None:
222-
return True
223-
time.sleep(1)
224-
finally:
225-
os.remove(tmp_file.name)
217+
cmd_string = r'(New-Object -comObject Shell.Application).Namespace(17).ParseName("{}").InvokeVerb("Eject")'.format(disk_path)
218+
219+
try_count = 10
220+
while try_count:
221+
p = subprocess.Popen(["powershell.exe", cmd_string], stdout=sys.stdout)
222+
p.communicate()
223+
try_count -= 1
224+
if MSDUtils._disk_path_windows(serial) is None:
225+
return True
226+
time.sleep(1)
226227

227228
return False
228229

TESTS/usb_device/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,14 @@ The FAT32 filesystem cannot be mounted on a device smaller than 64 kB.
136136
137137
The test can be easily extended to use any block device available in Mbed.
138138
139+
### Windows 8/10: Mass storage tests are failing on test file read
140+
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.
141+
142+
To prevent Windows from writing to removable drives on connect drive indexing can be turned off with the following procedure:
143+
- Start the program "gpedit.msc"
144+
- Navigate to "Computer Configuration \ Administrative Templates \ Windows Components \ Search"
145+
- Enable the policy "Do not allow locations on removable drives to be added to libraries."
146+
139147
### Isochronous endpoints are skipped in loopback tests
140148
#### Unresolved
141149

TESTS/usb_device/msd/main.cpp

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,17 @@
3333
#error [NOT_SUPPORTED] USB Device not supported for this target
3434
#endif
3535

36+
37+
#define OS_WINDOWS 1
38+
#define OS_LINUX 2
39+
#define OS_MAC 3
40+
41+
// Host side unmount was disabled for windows machines.
42+
// PowerShell execution policies/restrictions cause that
43+
// on some windows machines unmount is failing
44+
// To re-enable it comment out below line.
45+
#define DISABLE_HOST_SIDE_UMOUNT
46+
3647
#ifdef MIN
3748
#undef MIN
3849
#endif
@@ -250,13 +261,10 @@ void msd_process(USBMSD *msd)
250261
*/
251262
void storage_init()
252263
{
253-
if (mbed_heap_size >= MIN_HEAP_SIZE) {
254-
FATFileSystem::format(get_heap_block_device());
255-
bool result = prepare_storage(get_heap_block_device(), &heap_fs);
256-
TEST_ASSERT_MESSAGE(result, "heap storage initialisation failed");
257-
} else {
258-
utest_printf("Not enough heap memory for HeapBlockDevice creation. Heap block device init skipped!!!\n");
259-
}
264+
TEST_ASSERT_MESSAGE(mbed_heap_size >= MIN_HEAP_SIZE, "Not enough heap memory for HeapBlockDevice creation");
265+
FATFileSystem::format(get_heap_block_device());
266+
bool result = prepare_storage(get_heap_block_device(), &heap_fs);
267+
TEST_ASSERT_MESSAGE(result, "heap storage initialisation failed");
260268
}
261269

262270
/** Test mass storage device mount and unmount
@@ -316,19 +324,31 @@ void mount_unmount_test(BlockDevice *bd, FileSystem *fs)
316324
uint64_t ret_size = atoll(_key);
317325
TEST_ASSERT_EQUAL_UINT64(get_fs_mount_size(fs), ret_size);
318326

319-
// unmount msd device on host side
320-
greentea_send_kv("unmount", 0);
327+
#ifdef DISABLE_HOST_SIDE_UMOUNT
328+
greentea_send_kv("get_os_type", 0);
321329
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
322-
TEST_ASSERT_EQUAL_STRING_LOOP("passed", _key, i);
323-
324-
// wait for unmount event (set 10s timeout)
325-
media_remove_event.wait(10000);
326-
if (!usb.media_removed()) {
327-
TEST_ASSERT_EQUAL_LOOP(true, usb.media_removed(), i);
330+
int32_t os_type = atoi(_value);
331+
if (os_type != OS_WINDOWS) {
332+
#endif
333+
// unmount msd device on host side
334+
greentea_send_kv("unmount", 0);
335+
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
336+
TEST_ASSERT_EQUAL_STRING_LOOP("passed", _key, i);
337+
338+
// wait for unmount event (set 10s timeout)
339+
media_remove_event.wait(10000);
340+
if (!usb.media_removed()) {
341+
TEST_ASSERT_EQUAL_LOOP(true, usb.media_removed(), i);
342+
}
343+
344+
// unmount since media_removed doesn't disconnects device side
345+
usb.disconnect();
346+
#ifdef DISABLE_HOST_SIDE_UMOUNT
347+
} else {
348+
// unmount
349+
usb.disconnect();
328350
}
329-
// unmount since media_removed doesn't disconnects device side
330-
usb.disconnect();
331-
351+
#endif
332352
// check if device is detached on host side
333353
greentea_send_kv("check_if_not_mounted", 0);
334354
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
@@ -428,19 +448,13 @@ void mount_unmount_and_data_test(BlockDevice *bd, FileSystem *fs)
428448

429449
void heap_block_device_mount_unmount_test()
430450
{
431-
if (mbed_heap_size < MIN_HEAP_SIZE) {
432-
TEST_SKIP_MESSAGE("Not enough heap memory for HeapBlockDevice creation");
433-
return;
434-
}
451+
TEST_ASSERT_MESSAGE(mbed_heap_size >= MIN_HEAP_SIZE, "Not enough heap memory for HeapBlockDevice creation");
435452
mount_unmount_test<3>(get_heap_block_device(), &heap_fs);
436453
}
437454

438455
void heap_block_device_mount_unmount_and_data_test()
439456
{
440-
if (mbed_heap_size < MIN_HEAP_SIZE) {
441-
TEST_SKIP_MESSAGE("Not enough heap memory for HeapBlockDevice creation");
442-
return;
443-
}
457+
TEST_ASSERT_MESSAGE(mbed_heap_size >= MIN_HEAP_SIZE, "Not enough heap memory for HeapBlockDevice creation");
444458
mount_unmount_and_data_test(get_heap_block_device(), &heap_fs);
445459
}
446460

0 commit comments

Comments
 (0)