UMockdev

UMockdev — Build a test bed for testing software that handles Linux hardware devices.

Synopsis

UMockdevTestbed *   umockdev_testbed_new                (void);
gchar *             umockdev_testbed_add_device         (UMockdevTestbed *self,
                                                         const gchar *subsystem,
                                                         const gchar *name,
                                                         const gchar *parent,
                                                         ...);
gchar *             umockdev_testbed_add_devicev        (UMockdevTestbed *self,
                                                         const gchar *subsystem,
                                                         const gchar *name,
                                                         const gchar *parent,
                                                         gchar **attributes,
                                                         gchar **properties);
gchar *             umockdev_testbed_get_root_dir       (UMockdevTestbed *self);
gchar *             umockdev_testbed_get_sys_dir        (UMockdevTestbed *self);
void                umockdev_testbed_set_attribute      (UMockdevTestbed *self,
                                                         const gchar *devpath,
                                                         const gchar *name,
                                                         const gchar *value);
void                umockdev_testbed_set_attribute_int  (UMockdevTestbed *self,
                                                         const gchar *devpath,
                                                         const gchar *name,
                                                         gint value);
void                umockdev_testbed_set_attribute_hex  (UMockdevTestbed *self,
                                                         const gchar *devpath,
                                                         const gchar *name,
                                                         guint value);
void                umockdev_testbed_set_attribute_binary
                                                        (UMockdevTestbed *self,
                                                         const gchar *devpath,
                                                         const gchar *name,
                                                         guint8 *value,
                                                         int value_length1);
void                umockdev_testbed_set_property       (UMockdevTestbed *self,
                                                         const gchar *devpath,
                                                         const gchar *name,
                                                         const gchar *value);
void                umockdev_testbed_set_property_int   (UMockdevTestbed *self,
                                                         const gchar *devpath,
                                                         const gchar *name,
                                                         gint value);
void                umockdev_testbed_set_property_hex   (UMockdevTestbed *self,
                                                         const gchar *devpath,
                                                         const gchar *name,
                                                         guint value);
void                umockdev_testbed_uevent             (UMockdevTestbed *self,
                                                         const gchar *devpath,
                                                         const gchar *action);
gboolean            umockdev_testbed_add_from_string    (UMockdevTestbed *self,
                                                         const gchar *data,
                                                         GError **error);
gboolean            umockdev_testbed_load_ioctl         (UMockdevTestbed *self,
                                                         const gchar *dev,
                                                         const gchar *recordfile,
                                                         GError **error);
struct              UMockdevTestbed;
struct              UMockdevTestbedClass;

Object Hierarchy

  GObject
   +----UMockdevTestbed

Description

The UMockdevTestbed class builds a temporary sandbox for mock devices. Right now this covers sysfs, uevents, basic support for /dev devices, and recording/mocking usbdevfs (for PtP/MTP devices) and evdev (touch pads, Wacom tablets, etc.) ioctls, but other aspects will be added in the future. 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 either add devices by specifying individual device paths, properties, and attributes, or use the umockdev-record tool to create a human readable/editable record of a real device (and all its parents) and load that into the testbed with umockdev_testbed_add_from_string().

Instantiating a UMockdevTestbed object creates a temporary directory with an empty sysfs tree and sets the $UMOCKDEV_DIR environment variable so that programs subsequently started under umockdev-wrapper will use the test bed instead of the system's real sysfs.

Details

umockdev_testbed_new ()

UMockdevTestbed *   umockdev_testbed_new                (void);

umockdev_testbed_add_device ()

gchar *             umockdev_testbed_add_device         (UMockdevTestbed *self,
                                                         const gchar *subsystem,
                                                         const gchar *name,
                                                         const gchar *parent,
                                                         ...);

Add a new device to the testbed. A Linux kernel device always has a subsystem (such as "usb" or "pci"), and a device name. The test bed only builds a very simple sysfs structure without nested namespaces, so it requires device names to be unique. Some gudev client programs might make assumptions about the name (e. g. a SCSI disk block device should be called sdaN). A device also has an arbitrary number of sysfs attributes and udev properties; usually you should specify them upon creation, but it is also possible to change them later on with umockdev_testbed_set_attribute() and umockdev_testbed_set_property().

Example:

  umockdev_testbed_add_device (testbed, "usb", "dev1", NULL,
                             "idVendor", "0815", "idProduct", "AFFE", NULL,
                             "ID_MODEL", "KoolGadget", NULL);
  

self :

A UMockdevTestbed.

subsystem :

The subsystem name, e. g. "usb"

name :

The device name; arbitrary, but needs to be unique within the testbed

parent :

device path of the parent device. Use NULL for a top-level device. [allow-none]

... :

Arbitrarily many pairs of sysfs attributes (alternating names and values), terminated by NULL, followed by arbitrarily many pairs of udev properties, terminated by another NULL.

Returns :

The sysfs path for the newly created device. Free with g_free().

umockdev_testbed_add_devicev ()

gchar *             umockdev_testbed_add_devicev        (UMockdevTestbed *self,
                                                         const gchar *subsystem,
                                                         const gchar *name,
                                                         const gchar *parent,
                                                         gchar **attributes,
                                                         gchar **properties);

This method is mostly meant for language bindings (where it is named umockdev_testbed_add_device()). For C programs it is usually more convenient to use umockdev_testbed_add_device().

Add a new device to the testbed. A Linux kernel device always has a subsystem (such as "usb" or "pci"), and a device name. The test bed only builds a very simple sysfs structure without nested namespaces, so it requires device names to be unique. Some gudev client programs might make assumptions about the name (e. g. a SCSI disk block device should be called sdaN). A device also has an arbitrary number of sysfs attributes and udev properties; usually you should specify them upon creation, but it is also possible to change them later on with umockdev_testbed_set_attribute() and umockdev_testbed_set_property().

self :

A UMockdevTestbed.

subsystem :

The subsystem name, e. g. "usb"

name :

The device name; arbitrary, but needs to be unique within the testbed

parent :

device path of the parent device. Use NULL for a top-level device. [allow-none]

attributes :

A list of device sysfs attributes, alternating names and values, terminated with NULL: { "key1", "value1", "key2", "value2", ..., NULL }. [array zero-terminated=1]

properties :

A list of device udev properties; same format as attributes. [array zero-terminated=1]

Returns :

The sysfs path for the newly created device. Free with g_free(). Rename to: umockdev_testbed_add_device

umockdev_testbed_get_root_dir ()

gchar *             umockdev_testbed_get_root_dir       (UMockdevTestbed *self);

Get the root directory for the testbed.

self :

A UMockdevTestbed.

Returns :

The testbed's root directory.

umockdev_testbed_get_sys_dir ()

gchar *             umockdev_testbed_get_sys_dir        (UMockdevTestbed *self);

Get the sysfs directory for the testbed.

self :

A UMockdevTestbed.

Returns :

The testbed's sysfs directory.

umockdev_testbed_set_attribute ()

void                umockdev_testbed_set_attribute      (UMockdevTestbed *self,
                                                         const gchar *devpath,
                                                         const gchar *name,
                                                         const gchar *value);

umockdev_testbed_set_attribute_int ()

void                umockdev_testbed_set_attribute_int  (UMockdevTestbed *self,
                                                         const gchar *devpath,
                                                         const gchar *name,
                                                         gint value);

umockdev_testbed_set_attribute_hex ()

void                umockdev_testbed_set_attribute_hex  (UMockdevTestbed *self,
                                                         const gchar *devpath,
                                                         const gchar *name,
                                                         guint value);

umockdev_testbed_set_attribute_binary ()

void                umockdev_testbed_set_attribute_binary
                                                        (UMockdevTestbed *self,
                                                         const gchar *devpath,
                                                         const gchar *name,
                                                         guint8 *value,
                                                         int value_length1);

umockdev_testbed_set_property ()

void                umockdev_testbed_set_property       (UMockdevTestbed *self,
                                                         const gchar *devpath,
                                                         const gchar *name,
                                                         const gchar *value);

umockdev_testbed_set_property_int ()

void                umockdev_testbed_set_property_int   (UMockdevTestbed *self,
                                                         const gchar *devpath,
                                                         const gchar *name,
                                                         gint value);

umockdev_testbed_set_property_hex ()

void                umockdev_testbed_set_property_hex   (UMockdevTestbed *self,
                                                         const gchar *devpath,
                                                         const gchar *name,
                                                         guint value);

umockdev_testbed_uevent ()

void                umockdev_testbed_uevent             (UMockdevTestbed *self,
                                                         const gchar *devpath,
                                                         const gchar *action);

Generate an uevent for a device.

self :

A UMockdevTestbed.

devpath :

The full device path, as returned by #umockdev_testbed_add_device()

action :

"add", "remove", or "change"

umockdev_testbed_add_from_string ()

gboolean            umockdev_testbed_add_from_string    (UMockdevTestbed *self,
                                                         const gchar *data,
                                                         GError **error);

Add a set of devices to the testbed from a textual description. This reads the format generated by the umockdev-record tool.

Each paragraph defines one device. A line starts with a type tag (like 'E'), followed by a colon, followed by either a value or a "key=value" assignment, depending on the type tag. A device description must start with a 'P:' line. Available type tags are:

  • P:path: device path in sysfs, starting with /devices/; must occur exactly once at the start of device definition
  • E:key=value: udev property
  • A:key=value: ASCII sysfs attribute, with backslash-style escaping of \ (\\) and newlines (\n)
  • H:key=value: binary sysfs attribute, with the value being written as continuous hex string (e. g. 0081FE0A..)
  • N:devname[=contents]: device node name (without the /dev/ prefix); if contents is given (encoded in a continuous hex string), it creates a /dev/devname in the mock environment with the given contents, otherwise the created dev file will be empty.
  • S:linkname: device node symlink (without the /dev/ prefix); ignored right now.

self :

A UMockdevTestbed.

data :

Description of the device(s) as generated with umockdev-record

error :

return location for a GError, or NULL

Returns :

TRUE on success, FALSE if the data is invalid and an error occurred.

umockdev_testbed_load_ioctl ()

gboolean            umockdev_testbed_load_ioctl         (UMockdevTestbed *self,
                                                         const gchar *dev,
                                                         const gchar *recordfile,
                                                         GError **error);

Load an ioctl record file for a particular device into the testbed. ioctl records can be created with umockdev-record --ioctl. They can optionally be xz compressed to save space (but then are required to have an .xz file name suffix).

self :

A UMockdevTestbed.

dev :

Device path (/dev/...) for which to load the ioctl record.

recordfile :

Path of the ioctl record file.

error :

return location for a GError, or NULL

Returns :

TRUE on success, FALSE if the data is invalid and an error occurred.

struct UMockdevTestbed

struct UMockdevTestbed;

struct UMockdevTestbedClass

struct UMockdevTestbedClass {
	GObjectClass parent_class;
};