Umockdev
Mock hardware devices for creating unit tests and bug reporting
Install / Use
/learn @martinpitt/UmockdevREADME
umockdev
umockdev mocks Linux devices for creating integration tests for hardware related libraries and programs. It also provides tools to record the properties and behaviour of particular devices, and to run a program or test suite under a test bed with the previously recorded devices loaded. This allows developers of software like gphoto or libmtp to receive these records in bug reports and recreate the problem on their system without having access to the affected hardware.
The UMockdevTestbed class builds a temporary sandbox for mock devices.
You can add a number of devices including arbitrary sysfs attributes and udev
properties, and then run your software in that test bed that is independent of
the actual hardware it is running on. With this you can simulate particular
hardware in virtual environments up to some degree, without needing any
particular privileges or disturbing the whole system.
You can use this from the command line, and a wide range of programming languages (C, Vala, and everything which supports gobject-introspection, such as JavaScript or Python).
Right now umockdev supports the following features:
-
Emulation of arbitrary sysfs devices, attributes, and udev properties.
-
Synthesis of arbitrary uevents.
-
Emulation of /dev device nodes; they look just like the original real device (i. e. stat() delivers a block/char device with appropriate major/minor), but are backed by a PTY (for terminal devices) or a plain file (for everything else) by default. You can manually create other kinds of fake devices in your tests, too.
-
Recording and replay of read()s/recv()s and write()s/send()s from/to a character device (e. g. for emulating modems) or an Unix socket (e. g. for Android's /dev/socket/rild). These records are called "scripts". Replay can optionally use a configurable fuzz factor in case the expected (previously recorded) script data doesn't perfectly match what is actually being sent from the tested application.
-
Replay of usbdevfs (e. g. for PtP/MTP devices). Two methods are available for flexible and pure in-order replay. The
--ioctlbased replay may allow interactive emulation while thepcap/usbmonbased replay is purely in-order and supports control transfer replay. -
Recording and replay of evdev (touch pads, Wacom tablets, etc.) ioctls.
-
Recording and replay of spidev ioctls and read/write commands using
--ioctlfor bothumockdev-recordandumockdev-run. This is an in-order record/replay of all SPI transfers. Similar to scripts with the difference that full duplex transfers via ioctl are supported. Timinges/errors are currently not recorded. -
Recording and replay of evdev input events using the evemu events format. Unlike recorded evdev scripts these are architecture independent and human readable.
-
Mocking of files and directories in /proc
Other aspects and functionality will be added in the future as use cases arise.
Component overview
umockdev consists of the following parts:
-
The
umockdev-recordprogram generates text dumps (conventionally called*.umockdev) of some specified, or all of the system's devices and their sysfs attributes and udev properties. It can also record ioctls and reads/writes that a particular program sends and receives to/from a device, and store them into a text file (conventionally called*.ioctlfor ioctl records, and*.scriptfor read/write records). -
The libumockdev library provides the
UMockdevTestbedGObject class which builds sysfs and /dev testbeds, provides API to generate devices, attributes, properties, and uevents on the fly, and can load*.umockdevand*.ioctlrecords into them. It provides VAPI and GI bindings, so you can use it from C, Vala, and any programming language that supports introspection. This is the API that you should use for writing regression tests. You can find the API documentation in docs/reference/. -
The libumockdev-preload library intercepts access to /sys, /dev/, /proc/, the kernel's netlink socket (for uevents) and ioctl() and re-routes them into the sandbox built by libumockdev. You don't interface with this library directly, instead you need to run your test suite or other program that uses libumockdev through the
umockdev-wrapperprogram. -
The
umockdev-runprogram builds a sandbox using libumockdev, can load*.umockdev,*.ioctl, and*.scriptfiles into it, and run a program in that sandbox. I. e. it is a CLI interface to libumockdev, which is useful in the "debug a failure with a particular device" use case if you get the text dumps from a bug report. This automatically takes care of using the preload library, i. e. you don't needumockdev-wrapperwith this. You cannot use this program if you need to simulate uevents or change attributes/properties on the fly; for those you need to use libumockdev directly.
Mocking /proc and /dev
When enabled, the preload library diverts access to /proc and /dev to
the corresponding directories in $UMOCKDEV_DIR, aka.
umockdev_testbed_get_root(). However, if a path does not exist there, it
falls through the real /proc and /dev. Thus you can easily replace
files like /proc/cpuinfo or add new ones without losing standard files such
as /dev/null or /proc/pid/*. Currently there is no way to
"remove" files from the real directories or fully control them. You can get the
effect of removing a file by creating a broken symlink in the umockdev
directory though.
In contrast, an UMockdevTestbed fully controls the visible /sys
directory; for a program there is no (regular) way to see the real /sys,
unless it circumvents the libc API.
Examples
API: Create a fake battery
Batteries, and power supplies in general, are simple devices in the sense that
userspace programs such as upower only communicate with them through sysfs and
uevents. No /dev nor ioctls are necessary. docs/examples/ has two example
programs how to use libumockdev to create a fake battery device, change it to
low charge, sending an uevent, and running upower on a local test system D-BUS
in the testbed, with watching what happens with upower --monitor-detail.
battery.c shows how to do that with plain GObject in C, battery.py is
the equivalent program in Python that uses the GI binding.
Command line: Record and replay PtP/MTP USB devices (unordered)
With this method of record and replay a tree of dependent USB URBs is generated and replayed. The advantage is that discontinuities may occur during replay, as the replayer will always try to find the appropriate response, possibly changing the order of replay.
If you need completely in-order replay or USB control commands, then the pcap based replayer will be more appropriate.
-
Connect your digital camera, mobile phone, or other device which supports PtP or MTP, and locate it in lsusb. For example
Bus 001 Device 012: ID 0fce:0166 Sony Ericsson Xperia Mini Pro -
Dump the sysfs device and udev properties:
umockdev-record /dev/bus/usb/001/012 > mobile.umockdev -
Now record the dynamic behaviour (i. e. usbfs ioctls) of various operations. You can store multiple different operations in the same file, which will share the common communication between them. For example:
umockdev-record --ioctl /dev/bus/usb/001/012=mobile.ioctl mtp-detect umockdev-record --ioctl /dev/bus/usb/001/012=mobile.ioctl mtp-emptyfolders -
Now you can disconnect your device, and run the same operations in a mocked testbed. Please note that
/dev/bus/usb/001/012merely echoes what is inmobile.umockdevand it is independent of what is actually in the real /dev directory. You can rename that device in the generated*.umockdevfiles and on the command line.umockdev-run --device mobile.umockdev --ioctl /dev/bus/usb/001/012=mobile.ioctl mtp-detect umockdev-run --device mobile.umockdev --ioctl /dev/bus/usb/001/012=mobile.ioctl mtp-emptyfolders
Note that if your *.ioctl files get too large for some purpose, you can
xz-compress them.
Command line: Record and replay USB devices using usbmon pcap captures
This method of USB replay is a pure in-order replay. This has the advantage that
timeouts will be correctly emulated rather than causing discontinuities in the
replayer and possibly incorrect device state emulation. pcap currently also
has the advantage of correctly replaying USB control transfers.
-
Connect your device and locate it in lsusb. For example
Bus 001 Device 004: ID 06cb:00bd Synaptics, Inc. Prometheus MIS Touch Fingerprint Reader -
Dump the sysfs device and udev properties:
umockdev-record /dev/bus/usb/001/004 > fingerprint.umockdev -
Use
wiresharkto record the bus in question (bus 001,usbmon1). By default this will record all devices. To minimize the size of the capture, you may use a filter to only record/save communication to the device in question.After starting the capture, run the command to capture the required interactions. For example the
synaptics/custom.pytest script from libfprint. -
Now you can disconnect your device, and run the same operations in a mocked testbed. To do so, load the sysfs device and udev properties. Then specify the
--pcapoption with the corresponding sysfs path of the device. Doing so will create the appropriateusbdevfsdevice node.Note that you need to specify the sysfs path from the device description.
umockdev-run --device fingerprint.umockdev --pcap /sys/de
Related Skills
node-connect
341.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
84.4kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
341.0kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
84.4kCommit, push, and open a PR
