Merge lp:~sylvain-pineau/checkbox/story597_removable_test_for_SD into lp:checkbox

Proposed by Sylvain Pineau
Status: Merged
Merged at revision: 1631
Proposed branch: lp:~sylvain-pineau/checkbox/story597_removable_test_for_SD
Merge into: lp:checkbox
Diff against target: 313 lines (+99/-26)
4 files modified
debian/changelog (+3/-0)
jobs/mediacard.txt.in (+11/-0)
scripts/removable_storage_test (+57/-21)
scripts/removable_storage_watcher (+28/-5)
To merge this branch: bzr merge lp:~sylvain-pineau/checkbox/story597_removable_test_for_SD
Reviewer Review Type Date Requested Status
Jeff Lane  Approve
Review via email: mp+121770@code.launchpad.net

Description of the change

This MR tries to offer a way to properly identify memory cards plugged in the system under test.
Udisks correctly manages this type of devices but only shows detailed information if they are available on the sdio interface.

Memory cards plugged in a usb card reader are just seen as usb devices an we can't get the media type.

I've started to look into the ouput of the following commands, but the SCSI spec (2 or 3) doesn't provide enough information
to clearly identify such devices (My sd card is mounted as /dev/sdb):

sudo sg_scan -i (see http://pastebin.ubuntu.com/1173366/)
sudo sg_inq /dev/sdb (see http://pastebin.ubuntu.com/1173368/)

But we can see the reader model name in the sg_scan ouput and this data is also available
to udev and part of the ancestors path:

udevadm info -a -p /sys/block/sdb (see http://pastebin.ubuntu.com/1173369/)

Finally udisks can access the model name because it's part of the unique id name given to the device and can be retrieved with the DeviceFileById property (http://hal.freedesktop.org/docs/udisks/Device.html#Device:DeviceFileById)

udisks --show-info /dev/sdb (see http://pastebin.ubuntu.com/1173370/)

This is an extract of /dev/disk/by-id/

/dev/disk/by-id/ata-HL-DT-ST_DVD+_-RW_GS20N_KZ5A1S70602 -> ../../sr0
/dev/disk/by-id/mmc-SD08G_0x074e5fa1 -> ../../mmcblk0
/dev/disk/by-id/mmc-SD08G_0x074e5fa1-part1 -> ../../mmcblk0p1
/dev/disk/by-id/mmc-SD08G_0x074e5fa1-part2 -> ../../mmcblk0p2
/dev/disk/by-id/usb-Generic_Ultra_HS-SD_MMC_000000264001-0:0 -> ../../sdb
/dev/disk/by-id/usb-JetFlash_Transcend_4GB_16DLP0JADLM1F6WM-0:0 -> ../../sdc
/dev/disk/by-id/usb-JetFlash_Transcend_4GB_16DLP0JADLM1F6WM-0:0-part1 -> ../../sdc1

So the proposal is an attempt to guess the media type by looking into the parent model/name and using the following pattern: 'SD|MMC|CF|MS|SM|xD|Card' to match a memory card reader.

Both removable_storage_watcher and removable_storage_test offer a new parameter (--memorycard) to help the identification but only removable_storage_test is used for the preinserted SD test.
I've also left other manual test definition as they were for the moment, keeping this experimental guess for SRU.

To post a comment you must log in.
1621. By Sylvain Pineau

Update search pattern with in removable_storage scripts (+Generic)

Revision history for this message
Jeff Lane  (bladernr) wrote :

Nice! Great enhancement! Here's the before and after testing I just did:

bladernr@klaatu:~/development/sylvain-mmc-test-enhancement$ ./scripts/removable_storage_test -l sdio usb scsi
--------------------
Removable devices currently mounted:
/dev/mmcblk0p1 : /media/8765-4321
/dev/sdb1 : /media/1AE8-8249
Removable devices currently not mounted:
None
--------------------
bladernr@klaatu:~/development/sylvain-mmc-test-enhancement$ ./scripts/removable_storage_test --memorycard -l sdio usb scsi
--------------------
Removable devices currently mounted:
/dev/mmcblk0p1 : /media/8765-4321
Removable devices currently not mounted:
None
--------------------

Note that sdb on my machine is a usb key... and it properly ignores the usb key!

Approve

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2012-08-29 20:52:33 +0000
3+++ debian/changelog 2012-08-30 09:35:22 +0000
4@@ -7,6 +7,9 @@
5 properly with KVM.
6 * jobs/suspend.txt.in, scripts/gpu_test: Update the job description and the
7 script docstrings from Flash to HTML5 video playback.
8+ * [FEATURE] scripts/removable_storage_test, scripts/removable_storage_watcher,
9+ jobs/mediacard.txt.in: Added memory cards detection (on bus other than sdio)
10+ and a new automated (based on usb/storage-pre-inserted) for SD cards.
11
12 [Jeff Marcom]
13 * scripts/accelerometer_test, jobs/input.txt.in: Improved ability to detect
14
15=== modified file 'jobs/mediacard.txt.in'
16--- jobs/mediacard.txt.in 2012-07-11 17:28:09 +0000
17+++ jobs/mediacard.txt.in 2012-08-30 09:35:22 +0000
18@@ -176,6 +176,17 @@
19 The verification of this test is automated. Do not change the
20 automatically selected result.
21
22+plugin: shell
23+name: mediacard/sd-preinserted
24+user: root
25+requires:
26+ package.name == 'udisks'
27+command: removable_storage_test --memorycard -l sdio usb scsi && removable_storage_test --memorycard sdio usb scsi
28+_description:
29+ This is a fully automated version of mediacard/sd-automated and assumes that the
30+ system under test has a memory card device plugged in prior to checkbox execution.
31+ It is intended for SRU automated testing.
32+
33 plugin: manual
34 name: mediacard/sdhc-insert
35 requires:
36
37=== modified file 'scripts/removable_storage_test'
38--- scripts/removable_storage_test 2012-08-21 19:44:07 +0000
39+++ scripts/removable_storage_test 2012-08-30 09:35:22 +0000
40@@ -4,6 +4,7 @@
41 import sys
42 import random
43 import os
44+import re
45 import tempfile
46 import hashlib
47 import argparse
48@@ -64,7 +65,7 @@
49
50
51 class DiskTest():
52- ''' Class to contain various methods for testing USB disks '''
53+ ''' Class to contain various methods for testing removable disks '''
54 def __init__(self):
55 self.process = None
56 self.cmd = None
57@@ -130,7 +131,7 @@
58 print("ERROR: Unable to remove tempfile %s" % target,
59 file=sys.stderr)
60
61- def get_disk_info(self, device):
62+ def get_disk_info(self, args):
63 ''' Probes dbus to find any attached/mounted devices'''
64 bus = dbus.SystemBus()
65 ud_manager_obj = bus.get_object("org.freedesktop.UDisks",
66@@ -139,23 +140,36 @@
67 self.rem_disks = {}
68 self.rem_disks_speed = {}
69 self.rem_disks_nm = {}
70+ self.rem_disks_memory_cards = {}
71+ self.rem_disks_memory_cards_nm = {}
72 for dev in ud_manager.EnumerateDevices():
73 device_obj = bus.get_object("org.freedesktop.UDisks", dev)
74 device_props = dbus.Interface(device_obj, dbus.PROPERTIES_IFACE)
75 udisks = 'org.freedesktop.UDisks.Device'
76 if not device_props.Get(udisks, "DeviceIsDrive"):
77- if device_props.Get(udisks,
78- "DriveConnectionInterface") in device:
79+ dev_bus = device_props.Get(udisks, "DriveConnectionInterface")
80+ if dev_bus in args.device:
81+ if args.memorycard and dev_bus != 'sdio':
82+ device_file_by_id = device_props.Get(udisks,
83+ "DeviceFileById")[0]
84+ if not re.search('SD|MMC|CF|MS|SM|xD|Card|Generic',
85+ device_file_by_id, re.I):
86+ continue
87+ else:
88+ self.rem_disks_memory_cards = {}
89 dev_file = str(device_props.Get(udisks, "DeviceFile"))
90- dev_speed = str(device_props.Get(udisks,
91+ dev_speed = str(device_props.Get(udisks,
92 "DriveConnectionSpeed"))
93 self.rem_disks_speed[dev_file] = dev_speed
94 if len(device_props.Get(udisks, "DeviceMountPaths")) > 0:
95 devPath = str(device_props.Get(udisks,
96 "DeviceMountPaths")[0])
97 self.rem_disks[dev_file] = devPath
98+ self.rem_disks_memory_cards[dev_file] = devPath
99 else:
100 self.rem_disks_nm[dev_file] = None
101+ self.rem_disks_memory_cards_nm[dev_file] = None
102+
103
104 def mount(self):
105 passed_mount = {}
106@@ -193,6 +207,8 @@
107
108 for disk in self.rem_disks_nm:
109 result = False
110+ if not self.rem_disks_nm[disk]:
111+ continue
112 try:
113 result = self.make_thread(self._umount(disk))
114 except:
115@@ -213,6 +229,8 @@
116
117 def clean_tmp_dir(self):
118 for disk in self.rem_disks_nm:
119+ if not self.rem_disks_nm[disk]:
120+ continue
121 if not os.path.ismount(self.rem_disks_nm[disk]):
122 os.rmdir(self.rem_disks_nm[disk])
123
124@@ -281,12 +299,16 @@
125 default=False,
126 help=("skip the removable devices "
127 "which haven't been mounted before the test."))
128+ parser.add_argument('--memorycard', action="store_true",
129+ help=("Memory cards devices on bus other than sdio "
130+ "require this parameter to identify "
131+ "them as such"))
132
133 args = parser.parse_args()
134
135 test = DiskTest()
136
137- test.get_disk_info(args.device)
138+ test.get_disk_info(args)
139
140 errors = 0
141 # If we do have removable drives attached and mounted
142@@ -294,24 +316,38 @@
143 if args.list: # Simply output a list of drives detected
144 print('-' * 20)
145 print("Removable devices currently mounted:")
146- if len(test.rem_disks) > 0:
147- for disk, mount_point in test.rem_disks.items():
148- print("%s : %s" % (disk, mount_point))
149- else:
150- print("None")
151-
152- print("Removable devices currently not mounted:")
153- if len(test.rem_disks_nm) > 0:
154- for disk, dummy in test.rem_disks_nm.items():
155- print(disk)
156- else:
157- print("None")
158+ if args.memorycard:
159+ if len(test.rem_disks_memory_cards) > 0:
160+ for disk, mnt_point in test.rem_disks_memory_cards.items():
161+ print("%s : %s" % (disk, mnt_point))
162+ else:
163+ print("None")
164+
165+ print("Removable devices currently not mounted:")
166+ if len(test.rem_disks_memory_cards_nm) > 0:
167+ for disk, dummy in test.rem_disks_memory_cards_nm.items():
168+ print(disk)
169+ else:
170+ print("None")
171+ else:
172+ if len(test.rem_disks) > 0:
173+ for disk, mnt_point in test.rem_disks.items():
174+ print("%s : %s" % (disk, mnt_point))
175+ else:
176+ print("None")
177+
178+ print("Removable devices currently not mounted:")
179+ if len(test.rem_disks_nm) > 0:
180+ for disk, dummy in test.rem_disks_nm.items():
181+ print(disk)
182+ else:
183+ print("None")
184
185 print('-' * 20)
186
187 return 0
188
189- else: # Create a file, copy to USB and compare hashes
190+ else: # Create a file, copy to disk and compare hashes
191 if args.skip_not_mount:
192 disks_all = test.rem_disks
193 else:
194@@ -332,7 +368,7 @@
195
196 for disk, mount_point in disks_all.items():
197 supported_speed = test.rem_disks_speed[disk]
198- print(" %s : %s : %s bits/s" %
199+ print(" %s : %s : %s bits/s" %
200 (disk, mount_point, supported_speed),
201 end="")
202 if (args.min_speed and int(args.min_speed) > int(supported_speed)):
203@@ -426,7 +462,7 @@
204 "but there were errors" % args.count)
205 return 1
206 elif len(disks_eligible) == 0:
207- print("ERROR: No %s disks with speed higher than %s bits/s" %
208+ print("ERROR: No %s disks with speed higher than %s bits/s" %
209 (args.device, args.min_speed), file=sys.stderr)
210 return 1
211
212
213=== modified file 'scripts/removable_storage_watcher'
214--- scripts/removable_storage_watcher 2012-08-21 19:30:10 +0000
215+++ scripts/removable_storage_watcher 2012-08-30 09:35:22 +0000
216@@ -1,5 +1,6 @@
217 #!/usr/bin/env python3
218
219+import re
220 import sys
221 import dbus
222 import argparse
223@@ -10,13 +11,15 @@
224
225 class StorageDeviceListener:
226
227- def __init__(self, action, devices, minimum_speed ):
228+ def __init__(self, action, devices, minimum_speed, memorycard ):
229 self._action = action
230 self._devices = devices
231 self._minimum_speed = minimum_speed
232+ self._memorycard = memorycard
233 self._bus = dbus.SystemBus(mainloop=DBusGMainLoop())
234 self._loop = GObject.MainLoop()
235 self._error = False
236+ self._change_cache = []
237
238 def check(self, timeout):
239 udisks = 'org.freedesktop.UDisks'
240@@ -46,7 +49,13 @@
241 desired_bus_devices = [device for device in changed_devices \
242 if device[1] in self._devices]
243 for dev in desired_bus_devices:
244- print(message % {'bus':dev[1], 'file': dev[0]})
245+ if self._memorycard and dev[1] != 'sdio':
246+ if not re.search('SD|MMC|CF|MS|SM|xD|Card|Generic',
247+ dev[3], re.I):
248+ return
249+ print(message % {'bus':'memory card', 'file': dev[0]})
250+ else:
251+ print(message % {'bus':dev[1], 'file': dev[0]})
252 if self._minimum_speed:
253 if dev[2] >= self._minimum_speed:
254 print("with speed of %(speed)s bits/s "
255@@ -63,12 +72,16 @@
256 job_num_tasks, job_cur_task_id,
257 job_cur_task_percentage):
258 if job_id == "FilesystemMount":
259+ if devices in self._change_cache:
260+ return
261+ self._change_cache.append(devices)
262 inserted_devices = list(set(self.get_existing_devices()) -
263 set(self._starting_devices))
264 self.verify_device_change(inserted_devices,
265 message="Expected %(bus)s device %(file)s inserted")
266
267 def add_detected(self, added_path):
268+ self._change_cache = []
269 self._bus.add_signal_receiver(self.job_change_detected,
270 signal_name='DeviceJobChanged',
271 dbus_interface='org.freedesktop.UDisks')
272@@ -93,12 +106,18 @@
273 udisks = 'org.freedesktop.UDisks.Device'
274 _device_file = device_props.Get(udisks,
275 "DeviceFile")
276+ _device_file_by_id = device_props.Get(udisks,
277+ "DeviceFileById")[0]
278 _device = device_props.Get(udisks,
279 "DriveConnectionInterface")
280 _speed = device_props.Get(udisks,
281 "DriveConnectionSpeed")
282 if not device_props.Get(udisks, "DeviceIsDrive"):
283- device=(str(_device_file),str(_device), int(_speed))
284+ device=(
285+ str(_device_file),
286+ str(_device),
287+ int(_speed),
288+ str(_device_file_by_id))
289 existing_devices.append(device)
290
291 except dbus.DBusException:
292@@ -115,6 +134,10 @@
293 choices=['usb', 'sdio', 'firewire',
294 'scsi', 'ata_serial_esata'],
295 nargs=argparse.REMAINDER)
296+ memorycard_help = ("Memory cards devices on bus other than sdio require "
297+ "this parameter to identify them as such")
298+ parser.add_argument('--memorycard', action="store_true",
299+ help=memorycard_help)
300 parser.add_argument('--timeout', type=int, default=20)
301 min_speed_help = ("Will only accept a device if its connection speed "
302 "attribute is higher than this value "
303@@ -122,8 +145,8 @@
304 parser.add_argument('--minimum_speed', '-m', help=min_speed_help,
305 type=int, default=0)
306 args = parser.parse_args()
307- listener = StorageDeviceListener(args.action, args.device,
308- args.minimum_speed)
309+ listener = StorageDeviceListener(args.action, args.device,
310+ args.minimum_speed, args.memorycard)
311 return(listener.check(args.timeout))
312
313 if __name__ == "__main__":

Subscribers

People subscribed via source and target branches