summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pitt <martinpitt@gnome.org>2013-07-02 10:45:19 +0200
committerMartin Pitt <martinpitt@gnome.org>2013-07-02 10:45:19 +0200
commitd951f39564ea61fdb2be1dece281fab46e1e97ea (patch)
treeb3579a5b2d89c412046c454f72b82d8f23c49812
parent14f82fd299320f28ac11c877c326e254507b402e (diff)
gvfs-test: Add first test for mtp backend
Add umockdev dump and ioctl trace for a Sony Xperia Mini mobile phone (with CyanogenMod), with some small demo files and the ioctls from these commands recorded: gvfs-mount 'mtp://[usb:001,017]' gvfs-ls 'mtp://[usb:001,017]/SD-Karte' gvfs-ls 'mtp://[usb:001,017]/SD-Karte/Music' gvfs-ls 'mtp://[usb:001,017]/SD-Karte/Music/GStreamer - The Test Sine' gvfs-info 'mtp://[usb:001,017]/SD-Karte/Music/GStreamer - The Test Sine' gvfs-info 'mtp://[usb:001,017]/SD-Karte/Music/GStreamer - The Test Sine/sine.ogg' gvfs-cat 'mtp://[usb:001,017]/SD-Karte/Music/GStreamer - The Test Sine/sine.ogg' gvfs-cat 'mtp://[usb:001,017]/SD-Karte/hello.txt' gvfs-info 'mtp://[usb:001,017]/SD-Karte/hello.txt' gvfs-info 'mtp://[usb:001,017]/SD-Karte/DCIM/100CANON/IMG_0001.JPG' gvfs-cat 'mtp://[usb:001,017]/SD-Karte/DCIM/100CANON/IMG_0001.JPG' If umockdev is available, use it to simulate that device and check that we can get the directory and file info, and access the file contents. This bumps the (optional) umockdev dependency to >= 0.2.10.
-rw-r--r--test/files/mtp_xperia.ioctl.xzbin0 -> 8184 bytes
-rw-r--r--test/files/mtp_xperia.umockdev328
-rwxr-xr-xtest/gvfs-test85
3 files changed, 413 insertions, 0 deletions
diff --git a/test/files/mtp_xperia.ioctl.xz b/test/files/mtp_xperia.ioctl.xz
new file mode 100644
index 00000000..f929398f
--- /dev/null
+++ b/test/files/mtp_xperia.ioctl.xz
Binary files differ
diff --git a/test/files/mtp_xperia.umockdev b/test/files/mtp_xperia.umockdev
new file mode 100644
index 00000000..f66209a7
--- /dev/null
+++ b/test/files/mtp_xperia.umockdev
@@ -0,0 +1,328 @@
+P: /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.5/1-1.5.2/1-1.5.2.4
+N: bus/usb/001/017=1201000200000040CE0F660126020203040109022700010100C0FA0904000003FFFF00050705810200020007050202000200070582031C0006
+S: libmtp-1-1.5.2.4
+E: BUSNUM=001
+E: DEVLINKS=/dev/libmtp-1-1.5.2.4
+E: DEVNAME=/dev/bus/usb/001/017
+E: DEVNUM=017
+E: DEVTYPE=usb_device
+E: DRIVER=usb
+E: ID_BUS=usb
+E: ID_FOR_SEAT=usb-pci-0000_00_1a_0-usb-0_1_5_2_4
+E: ID_MEDIA_PLAYER=1
+E: ID_MODEL=MiniPro
+E: ID_MODEL_ENC=MiniPro
+E: ID_MODEL_FROM_DATABASE=Xperia Mini Pro
+E: ID_MODEL_ID=0166
+E: ID_MTP_DEVICE=1
+E: ID_PATH=pci-0000:00:1a.0-usb-0:1.5.2.4
+E: ID_PATH_TAG=pci-0000_00_1a_0-usb-0_1_5_2_4
+E: ID_REVISION=0226
+E: ID_SERIAL=Sony_MiniPro_0123456789ABCDEF
+E: ID_SERIAL_SHORT=0123456789ABCDEF
+E: ID_USB_INTERFACES=:ffff00:
+E: ID_VENDOR=Sony
+E: ID_VENDOR_ENC=Sony
+E: ID_VENDOR_FROM_DATABASE=Sony Ericsson Mobile Communications AB
+E: ID_VENDOR_ID=0fce
+E: MAJOR=189
+E: MINOR=16
+E: PRODUCT=fce/166/226
+E: SUBSYSTEM=usb
+E: TAGS=:seat:uaccess:
+E: TYPE=0/0/0
+A: authorized=1
+A: avoid_reset_quirk=0
+A: bConfigurationValue=1
+A: bDeviceClass=00
+A: bDeviceProtocol=00
+A: bDeviceSubClass=00
+A: bMaxPacketSize0=64
+A: bMaxPower=500mA
+A: bNumConfigurations=1
+A: bNumInterfaces= 1
+A: bcdDevice=0226
+A: bmAttributes=c0
+A: busnum=1
+A: configuration=
+H: descriptors=1201000200000040CE0F660126020203040109022700010100C0FA0904000003FFFF00050705810200020007050202000200070582031C0006
+A: dev=189:16
+A: devnum=17
+A: devpath=1.5.2.4
+A: idProduct=0166
+A: idVendor=0fce
+A: ltm_capable=no
+A: manufacturer=Sony
+A: maxchild=0
+A: product=MiniPro
+A: quirks=0x0
+A: removable=unknown
+A: serial=0123456789ABCDEF
+A: speed=480
+A: urbnum=649
+A: version= 2.00
+
+P: /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.5/1-1.5.2
+N: bus/usb/001/006=12010002090001400904580000010102000109021900010100E0320904000001090000000705810301000C
+E: BUSNUM=001
+E: DEVNAME=/dev/bus/usb/001/006
+E: DEVNUM=006
+E: DEVTYPE=usb_device
+E: DRIVER=usb
+E: ID_BUS=usb
+E: ID_FOR_SEAT=usb-pci-0000_00_1a_0-usb-0_1_5_2
+E: ID_MODEL=USB2.0_Hub_Controller
+E: ID_MODEL_ENC=USB2.0\x20Hub\x20Controller
+E: ID_MODEL_FROM_DATABASE=HighSpeed Hub
+E: ID_MODEL_ID=0058
+E: ID_PATH=pci-0000:00:1a.0-usb-0:1.5.2
+E: ID_PATH_TAG=pci-0000_00_1a_0-usb-0_1_5_2
+E: ID_REVISION=0100
+E: ID_SERIAL=NEC_Corporation_USB2.0_Hub_Controller
+E: ID_USB_INTERFACES=:090000:
+E: ID_VENDOR=NEC_Corporation
+E: ID_VENDOR_ENC=NEC\x20Corporation
+E: ID_VENDOR_FROM_DATABASE=NEC Corp.
+E: ID_VENDOR_ID=0409
+E: MAJOR=189
+E: MINOR=5
+E: PRODUCT=409/58/100
+E: SUBSYSTEM=usb
+E: TAGS=:seat:
+E: TYPE=9/0/1
+A: authorized=1
+A: avoid_reset_quirk=0
+A: bConfigurationValue=1
+A: bDeviceClass=09
+A: bDeviceProtocol=01
+A: bDeviceSubClass=00
+A: bMaxPacketSize0=64
+A: bMaxPower=100mA
+A: bNumConfigurations=1
+A: bNumInterfaces= 1
+A: bcdDevice=0100
+A: bmAttributes=e0
+A: busnum=1
+A: configuration=
+H: descriptors=12010002090001400904580000010102000109021900010100E0320904000001090000000705810301000C
+A: dev=189:5
+A: devnum=6
+A: devpath=1.5.2
+A: idProduct=0058
+A: idVendor=0409
+A: ltm_capable=no
+A: manufacturer=NEC Corporation
+A: maxchild=4
+A: product=USB2.0 Hub Controller
+A: quirks=0x0
+A: removable=unknown
+A: speed=480
+A: urbnum=244
+A: version= 2.00
+
+P: /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.5
+N: bus/usb/001/004=1201000209000240EF17051001000000000109022900010100E0010904000001090001000705810301000C0904000101090002000705810301000C
+E: BUSNUM=001
+E: DEVNAME=/dev/bus/usb/001/004
+E: DEVNUM=004
+E: DEVTYPE=usb_device
+E: DRIVER=usb
+E: ID_BUS=usb
+E: ID_FOR_SEAT=usb-pci-0000_00_1a_0-usb-0_1_5
+E: ID_MODEL=1005
+E: ID_MODEL_ENC=1005
+E: ID_MODEL_ID=1005
+E: ID_PATH=pci-0000:00:1a.0-usb-0:1.5
+E: ID_PATH_TAG=pci-0000_00_1a_0-usb-0_1_5
+E: ID_REVISION=0001
+E: ID_SERIAL=17ef_1005
+E: ID_USB_INTERFACES=:090001:090002:
+E: ID_VENDOR=17ef
+E: ID_VENDOR_ENC=17ef
+E: ID_VENDOR_FROM_DATABASE=Lenovo
+E: ID_VENDOR_ID=17ef
+E: MAJOR=189
+E: MINOR=3
+E: PRODUCT=17ef/1005/1
+E: SUBSYSTEM=usb
+E: TAGS=:seat:
+E: TYPE=9/0/2
+A: authorized=1
+A: avoid_reset_quirk=0
+A: bConfigurationValue=1
+A: bDeviceClass=09
+A: bDeviceProtocol=02
+A: bDeviceSubClass=00
+A: bMaxPacketSize0=64
+A: bMaxPower=2mA
+A: bNumConfigurations=1
+A: bNumInterfaces= 1
+A: bcdDevice=0001
+A: bmAttributes=e0
+A: busnum=1
+A: configuration=
+H: descriptors=1201000209000240EF17051001000000000109022900010100E0010904000001090001000705810301000C0904000101090002000705810301000C
+A: dev=189:3
+A: devnum=4
+A: devpath=1.5
+A: idProduct=1005
+A: idVendor=17ef
+A: ltm_capable=no
+A: maxchild=4
+A: quirks=0x0
+A: removable=removable
+A: speed=480
+A: urbnum=39
+A: version= 2.00
+
+P: /devices/pci0000:00/0000:00:1a.0/usb1/1-1
+N: bus/usb/001/002=12010002090001408780200000000000000109021900010100E0000904000001090000000705810301000C
+E: BUSNUM=001
+E: DEVNAME=/dev/bus/usb/001/002
+E: DEVNUM=002
+E: DEVTYPE=usb_device
+E: DRIVER=usb
+E: ID_BUS=usb
+E: ID_FOR_SEAT=usb-pci-0000_00_1a_0-usb-0_1
+E: ID_MODEL=0020
+E: ID_MODEL_ENC=0020
+E: ID_MODEL_FROM_DATABASE=Integrated Rate Matching Hub
+E: ID_MODEL_ID=0020
+E: ID_PATH=pci-0000:00:1a.0-usb-0:1
+E: ID_PATH_TAG=pci-0000_00_1a_0-usb-0_1
+E: ID_REVISION=0000
+E: ID_SERIAL=8087_0020
+E: ID_USB_INTERFACES=:090000:
+E: ID_VENDOR=8087
+E: ID_VENDOR_ENC=8087
+E: ID_VENDOR_FROM_DATABASE=Intel Corp.
+E: ID_VENDOR_ID=8087
+E: MAJOR=189
+E: MINOR=1
+E: PRODUCT=8087/20/0
+E: SUBSYSTEM=usb
+E: TAGS=:seat:
+E: TYPE=9/0/1
+A: authorized=1
+A: avoid_reset_quirk=0
+A: bConfigurationValue=1
+A: bDeviceClass=09
+A: bDeviceProtocol=01
+A: bDeviceSubClass=00
+A: bMaxPacketSize0=64
+A: bMaxPower=0mA
+A: bNumConfigurations=1
+A: bNumInterfaces= 1
+A: bcdDevice=0000
+A: bmAttributes=e0
+A: busnum=1
+A: configuration=
+H: descriptors=12010002090001408780200000000000000109021900010100E0000904000001090000000705810301000C
+A: dev=189:1
+A: devnum=2
+A: devpath=1
+A: idProduct=0020
+A: idVendor=8087
+A: ltm_capable=no
+A: maxchild=6
+A: quirks=0x0
+A: removable=fixed
+A: speed=480
+A: urbnum=66
+A: version= 2.00
+
+P: /devices/pci0000:00/0000:00:1a.0/usb1
+N: bus/usb/001/001=12010002090000406B1D020010030302010109021900010100E0000904000001090000000705810304000C
+E: BUSNUM=001
+E: DEVNAME=/dev/bus/usb/001/001
+E: DEVNUM=001
+E: DEVTYPE=usb_device
+E: DRIVER=usb
+E: ID_BUS=usb
+E: ID_FOR_SEAT=usb-pci-0000_00_1a_0
+E: ID_MODEL=EHCI_Host_Controller
+E: ID_MODEL_ENC=EHCI\x20Host\x20Controller
+E: ID_MODEL_FROM_DATABASE=2.0 root hub
+E: ID_MODEL_ID=0002
+E: ID_PATH=pci-0000:00:1a.0
+E: ID_PATH_TAG=pci-0000_00_1a_0
+E: ID_REVISION=0310
+E: ID_SERIAL=Linux_3.10.0-0-generic_ehci_hcd_EHCI_Host_Controller_0000:00:1a.0
+E: ID_SERIAL_SHORT=0000:00:1a.0
+E: ID_USB_INTERFACES=:090000:
+E: ID_VENDOR=Linux_3.10.0-0-generic_ehci_hcd
+E: ID_VENDOR_ENC=Linux\x203.10.0-0-generic\x20ehci_hcd
+E: ID_VENDOR_FROM_DATABASE=Linux Foundation
+E: ID_VENDOR_ID=1d6b
+E: MAJOR=189
+E: MINOR=0
+E: PRODUCT=1d6b/2/310
+E: SUBSYSTEM=usb
+E: TAGS=:seat:
+E: TYPE=9/0/0
+A: authorized=1
+A: authorized_default=1
+A: avoid_reset_quirk=0
+A: bConfigurationValue=1
+A: bDeviceClass=09
+A: bDeviceProtocol=00
+A: bDeviceSubClass=00
+A: bMaxPacketSize0=64
+A: bMaxPower=0mA
+A: bNumConfigurations=1
+A: bNumInterfaces= 1
+A: bcdDevice=0310
+A: bmAttributes=e0
+A: busnum=1
+A: configuration=
+H: descriptors=12010002090000406B1D020010030302010109021900010100E0000904000001090000000705810304000C
+A: dev=189:0
+A: devnum=1
+A: devpath=0
+A: idProduct=0002
+A: idVendor=1d6b
+A: ltm_capable=no
+A: manufacturer=Linux 3.10.0-0-generic ehci_hcd
+A: maxchild=3
+A: product=EHCI Host Controller
+A: quirks=0x0
+A: removable=unknown
+A: serial=0000:00:1a.0
+A: speed=480
+A: urbnum=26
+A: version= 2.00
+
+P: /devices/pci0000:00/0000:00:1a.0
+E: DRIVER=ehci-pci
+E: ID_MODEL_FROM_DATABASE=5 Series/3400 Series Chipset USB2 Enhanced Host Controller
+E: ID_PCI_CLASS_FROM_DATABASE=Serial bus controller
+E: ID_PCI_INTERFACE_FROM_DATABASE=EHCI
+E: ID_PCI_SUBCLASS_FROM_DATABASE=USB controller
+E: ID_VENDOR_FROM_DATABASE=Intel Corporation
+E: MODALIAS=pci:v00008086d00003B3Csv000017AAsd00002163bc0Csc03i20
+E: PCI_CLASS=C0320
+E: PCI_ID=8086:3B3C
+E: PCI_SLOT_NAME=0000:00:1a.0
+E: PCI_SUBSYS_ID=17AA:2163
+E: SUBSYSTEM=pci
+A: broken_parity_status=0
+A: class=0x0c0320
+A: companion=
+H: config=86803C3B060190020620030C00000000008072F2000000000000000000000000000000000000000000000000AA1763210000000050000000000000000B040000
+A: consistent_dma_mask_bits=32
+A: d3cold_allowed=1
+A: device=0x3b3c
+A: dma_mask_bits=32
+A: irq=23
+A: local_cpulist=0-3
+A: local_cpus=00000000,00000000,00000000,00000000,00000000,00000000,00000000,0000000f
+A: modalias=pci:v00008086d00003B3Csv000017AAsd00002163bc0Csc03i20
+A: msi_bus=
+A: numa_node=-1
+A: pools=poolinfo - 0.1\nehci_sitd 0 0 96 0\nehci_itd 0 0 192 0\nehci_qh 25 42 96 1\nehci_qtd 36 42 96 1\nbuffer-2048 0 0 2048 0\nbuffer-512 0 0 512 0\nbuffer-128 9 32 128 1\nbuffer-32 1 128 32 1
+A: resource=0x00000000f2728000 0x00000000f27283ff 0x0000000000040200\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000\n0x0000000000000000 0x0000000000000000 0x0000000000000000
+A: subsystem_device=0x2163
+A: subsystem_vendor=0x17aa
+A: uframe_periodic_max=100
+A: vendor=0x8086
+
diff --git a/test/gvfs-test b/test/gvfs-test
index bd8fdbbb..6aab9743 100755
--- a/test/gvfs-test
+++ b/test/gvfs-test
@@ -40,6 +40,8 @@ from gi.repository import GLib, Gio
try:
from gi.repository import UMockdev
have_umockdev = subprocess.call(['which', 'umockdev-wrapper'], stdout=subprocess.PIPE) == 0
+ # needs >= 0.2.10
+ have_umockdev = have_umockdev and hasattr(UMockdev.Testbed, 'add_from_file')
except ImportError:
have_umockdev = False
@@ -1691,6 +1693,89 @@ class GPhoto(GvfsTestCase):
#umockdev_testbed.uevent('/sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.5/1-1.5.2/1-1.5.2.3', 'add');
+@unittest.skipUnless(have_umockdev,
+ 'umockdev not installed; get it from https://launchpad.net/umockdev')
+class Mtp(GvfsTestCase):
+ @classmethod
+ def setUpClass(klass):
+ '''Load Sony Xperia MTP dump into testbed'''
+
+ GvfsTestCase.setUpClass()
+ umockdev_testbed.add_from_file(os.path.join(my_dir, 'files', 'mtp_xperia.umockdev'))
+ umockdev_testbed.load_ioctl('/dev/bus/usb/001/017',
+ os.path.join(my_dir, 'files', 'mtp_xperia.ioctl.xz'))
+
+ def shell(self):
+ subprocess.call(['umockdev-wrapper', 'bash', '-i'])
+
+ def xtest_detect(self):
+ '''mtp:// detection'''
+
+ out = self.program_out_success(['umockdev-wrapper', 'gvfs-mount', '-li'])
+ print(out)
+
+ def test_mount_cli(self):
+ '''mtp:// mount with CLI'''
+
+ uri = 'mtp://[usb:001,017]'
+
+ # this might take a bit until everything is detected
+ timeout = 5
+ while timeout > 0:
+ if subprocess.call(['gvfs-mount', uri], stderr=subprocess.PIPE) == 0:
+ break
+ timeout -= 1
+ time.sleep(0.5)
+ else:
+ self.fail('gvfs-mount %s failed' % uri)
+
+ try:
+ # The top-level name is defined by the mobile firmware
+ self.assertEqual(self.program_out_success(['gvfs-ls', uri]), 'SD-Karte\n')
+ self.assertEqual(self.program_out_success(['gvfs-ls', uri + '/SD-Karte']),
+ 'DCIM\nhello.txt\nLOST.DIR\nMusic\nAndroid\nclockworkmod\n')
+ self.assertEqual(self.program_out_success(['gvfs-ls', uri + '/SD-Karte/Music']),
+ 'GStreamer - The Test Sine\n')
+ self.assertEqual(self.program_out_success(['gvfs-ls', uri + '/SD-Karte/Music/GStreamer - The Test Sine']),
+ 'sine.ogg\n')
+
+ # info for a dir and a music file
+ out = self.program_out_success(['gvfs-info', uri + '/SD-Karte/Music/GStreamer - The Test Sine'])
+ self.assertIn('standard::content-type: inode/directory', out)
+ self.assertIn('access::can-read: TRUE', out)
+ self.assertIn('access::can-write: TRUE', out)
+ self.assertIn('access::can-delete: TRUE', out)
+
+ out = self.program_out_success(['gvfs-info', uri + '/SD-Karte/Music/GStreamer - The Test Sine/sine.ogg'])
+ self.assertIn('standard::content-type: audio/ogg', out)
+ self.assertIn('standard::size: 4400', out)
+ self.assertIn('access::can-read: TRUE', out)
+ self.assertIn('access::can-write: TRUE', out)
+ self.assertIn('access::can-delete: TRUE', out)
+
+ # read ogg file
+ out = subprocess.check_output(['gvfs-cat', uri + '/SD-Karte/Music/GStreamer - The Test Sine/sine.ogg'])
+ self.assertTrue(out.startswith(b'OggS\x00'), out[:20])
+
+ # text file
+ self.assertEqual(self.program_out_success(['gvfs-cat', uri + '/SD-Karte/hello.txt']),
+ 'world\n')
+ out = self.program_out_success(['gvfs-info', uri + '/SD-Karte/hello.txt'])
+ self.assertIn('standard::content-type: text/plain', out)
+ self.assertIn('standard::size: 6', out)
+
+ # photo
+ out = self.program_out_success(['gvfs-info', uri + '/SD-Karte/DCIM/100CANON/IMG_0001.JPG'])
+ self.assertIn('standard::content-type: image/jpeg', out)
+ self.assertIn('standard::size: 8843', out)
+ self.assertIn('preview::icon:', out)
+
+ out = subprocess.check_output(['gvfs-cat', uri + '/SD-Karte/DCIM/100CANON/IMG_0001.JPG'])
+ self.assertIn(b'JFIF', out[:20])
+ finally:
+ self.unmount(uri)
+
+
def start_dbus():
'''Run a local D-BUS daemon under temporary XDG directories