Skip to content

Commit

Permalink
Testbed: Create "bus" and "class" dirs at init (#145)
Browse files Browse the repository at this point in the history
libudev expects the "bus" and "class" directories to exist when calling
udev_enumerate_scan_devices(). When this was called on an empty Testbed,
it would return -ENOENT since these directories did not exist.

This fixes the issue by creating the "/sys/bus" and "/sys/class" at the
same time that "/sys" is created in the Testbed.

num_udev_devices() is modified to call udev_enumerate_scan_devices()
directly instead of using GUdev, which ignores the return value of
udev_enumerate_scan_devices(). This makes t_testbed_empty() a valid
test for the bug we are fixing.

Some vala tests also had to be modified to account for the change.

Fixes #144
  • Loading branch information
dlech authored Sep 11, 2021
1 parent 8a949b9 commit 5e82960
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 19 deletions.
6 changes: 6 additions & 0 deletions src/umockdev.vala
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ public class Testbed: GLib.Object {
this.sys_dir = Path.build_filename(this.root_dir, "sys");
DirUtils.create(this.sys_dir, 0755);

/* Create "bus" and "class" directories to make libudev happy */
string bus_path = Path.build_filename(this.sys_dir, "bus");
DirUtils.create(bus_path, 0755);
string class_path = Path.build_filename(this.sys_dir, "class");
DirUtils.create(class_path, 0755);

this.dev_fd = new HashTable<string, int> (str_hash, str_equal);
this.dev_script_runner = new HashTable<string, ScriptRunner> (str_hash, str_equal);
this.custom_handlers = new HashTable<string, IoctlBase> (str_hash, str_equal);
Expand Down
11 changes: 4 additions & 7 deletions tests/test-umockdev-vala.vala
Original file line number Diff line number Diff line change
Expand Up @@ -159,37 +159,34 @@ t_testbed_fs_ops ()
assert_cmpstr (syspath, CompareOperator.EQ, "/sys/devices/dev1");

// absolute paths
assert_listdir ("/sys", {"bus", "devices"});
assert_listdir ("/sys", {"bus", "class", "devices"});
assert_listdir ("/sys/devices", {"dev1"});
assert_listdir ("/sys/bus", {"pci"});
assert_listdir ("/sys/devices/dev1", {"a", "subsystem", "uevent"});

// change directory into trapped /sys
assert_cmpint (Posix.chdir ("/sys"), CompareOperator.EQ, 0);
assert_listdir (".", {"bus", "devices"});
assert_listdir (".", {"bus", "class", "devices"});
assert_listdir ("bus", {"pci"});
assert_cmpstr (Environment.get_current_dir (), CompareOperator.EQ, "/sys");

assert_cmpint (Posix.chdir ("/sys/devices/dev1"), CompareOperator.EQ, 0);
assert_listdir (".", {"a", "subsystem", "uevent"});
assert_cmpstr (Environment.get_current_dir (), CompareOperator.EQ, "/sys/devices/dev1");

assert_cmpint (Posix.chdir ("/sys/class"), CompareOperator.EQ, -1);
assert_cmpint (Posix.errno, CompareOperator.EQ, Posix.ENOENT);

// relative paths into trapped /sys; this only works if the real /sys exists, as otherwise realpath() fails in trap_path()
if (!have_real_sys) {
stdout.printf ("[SKIP relative paths: environment has no real /sys]\n");
return;
}

assert_cmpint (Posix.chdir ("/"), CompareOperator.EQ, 0);
assert_listdir ("sys", {"bus", "devices"});
assert_listdir ("sys", {"bus", "class", "devices"});
assert_listdir ("sys/devices", {"dev1"});
assert_listdir ("sys/bus", {"pci"});

assert_cmpint (Posix.chdir ("/etc"), CompareOperator.EQ, 0);
assert_listdir ("../sys", {"bus", "devices"});
assert_listdir ("../sys", {"bus", "class", "devices"});
assert_listdir ("../sys/devices", {"dev1"});
assert_listdir ("../sys/bus", {"pci"});

Expand Down
34 changes: 22 additions & 12 deletions tests/test-umockdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,20 +107,30 @@ t_testbed_read_buf_delay(ulong delay, int fd, char* buf, ssize_t length)
static guint
num_udev_devices(void)
{
GUdevEnumerator *enumerator;
GList *result;
guint num;

g_autoptr (GUdevClient) client = g_udev_client_new(NULL);
g_assert(client);
struct udev *udev;
struct udev_enumerate *enumerate;
struct udev_list_entry *entry;
int err;
guint num = 0;

enumerator = g_udev_enumerator_new(client);
g_assert(enumerator);
result = g_udev_enumerator_execute(enumerator);
num = g_list_length(result);
udev = udev_new();
g_assert(udev);

enumerate = udev_enumerate_new(udev);
g_assert(enumerate);

// NB: using libudev here instead of GUdev so that we can check the return
// value of udev_enumerate_scan_devices().
// https://github.com/martinpitt/umockdev/issues/144
err = udev_enumerate_scan_devices(enumerate);
g_assert_cmpint(err, >=, 0);

udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(enumerate)) {
num++;
}

g_list_free_full(result, g_object_unref);
g_object_unref(enumerator);
udev_enumerate_unref(enumerate);
udev_unref(udev);

return num;
}
Expand Down

0 comments on commit 5e82960

Please sign in to comment.