Testing removable USB devices

Tracker Miner FS has code to index removable devices, and test coverage is around 0%. I would like to improve that by adding some testcases that connect and disconnect fake removable media, and I want to check if there’s an easy way to do it.

The test must work inside a container on Gitlab CI and must not require root. The test needs to trigger GVolumeMonitor events on device added/removed. And I want to integrate it with existing testing infrastructure written in Python.

So… I tried to implement a TestVolumeMonitor class in Python and register it using Gio.ExtensionPoint.implement(), as follows:

from gi.repository import Gio

import os

# From GLib: gio/gvolumemonitor.h
G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME = "gio-native-volume-monitor"


class TestNativeVolumeMonitor(Gio.NativeVolumeMonitor):
    __gtype_name__ = 'TestNativeVolumeMonitor'

    def do_is_supported(self):
        return True


def main():
    # Trigger _g_io_modules_ensure_extension_points_registered()
    vfs = Gio.Vfs.get_local()

    Gio.IOExtensionPoint.implement(G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME, TestNativeVolumeMonitor.__gtype__, 'MyTest', 1)

    os.environ['GIO_USE_VOLUME_MONITOR'] = 'MyTest'

    vm = Gio.VolumeMonitor.get()


main()

This almost works, but do_is_selected() doesn’t get hooked up to the TestNativeVolumeMonitor vtable, leading to a crash in giomodule.c - try_class(). PyGI only hooks up vfuncs which have a corresponding virtual-method introspection annotation, and I guess is_selected is considered private.

The fallback approach seems to be creating a TestVolumeMonitor class in a C library, which can be imported into Python and used from there. I hope to get some time to develop this approach further.

In the meantime, has anyone implemented something like this before? I would love to avoid writing such a thing from scratch… :slight_smile:

I had a look at implementing this using umockdev, which would be at a lower level and test more components. We can create a fake USB storage device that way, but the catch is that we can’t mount it - we need to run our own udisks2 daemon so that it picks up the fake devices, and as we won’t run it with root privileges it wouldn’t be able to actually do the mount. There’s no support in umockdev for faking contents of fstab or mtab.

In the end I have implemented this a GIO module written in C. Currently it will live in the tracker-miners tree, if its useful somewhere else then we can think about a shared location. See tracker-miners!350 and the mockvolumemonitor module.

Hope this is useful!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.