[gvfs] gvfs-test: Add first test for mtp backend



commit d951f39564ea61fdb2be1dece281fab46e1e97ea
Author: Martin Pitt <martinpitt gnome org>
Date:   Tue Jul 2 10:45:19 2013 +0200

    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.

 test/files/mtp_xperia.ioctl.xz |  Bin 0 -> 8184 bytes
 test/files/mtp_xperia.umockdev |  328 ++++++++++++++++++++++++++++++++++++++++
 test/gvfs-test                 |   85 +++++++++++
 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 0000000..f929398
Binary files /dev/null and b/test/files/mtp_xperia.ioctl.xz differ
diff --git a/test/files/mtp_xperia.umockdev b/test/files/mtp_xperia.umockdev
new file mode 100644
index 0000000..f66209a
--- /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 bd8fdbb..6aab974 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
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]