From a9cded655bc9b28a0d9947d883f8951c10417769 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 10 Apr 2025 13:34:52 +0200 Subject: [PATCH 1/2] test-sd-device: dedeplicate common setup fragment --- src/libsystemd/sd-device/test-sd-device.c | 30 ++++++++++------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/libsystemd/sd-device/test-sd-device.c b/src/libsystemd/sd-device/test-sd-device.c index 86926ec4846..d08e5914a29 100644 --- a/src/libsystemd/sd-device/test-sd-device.c +++ b/src/libsystemd/sd-device/test-sd-device.c @@ -221,11 +221,7 @@ static void test_sd_device_one(sd_device *d) { } } -TEST(sd_device_enumerator_devices) { - _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; - - ASSERT_OK(sd_device_enumerator_new(&e)); - ASSERT_OK(sd_device_enumerator_allow_uninitialized(e)); +static void exclude_problematic_devices(sd_device_enumerator *e) { /* On some CI environments, it seems some loop block devices and corresponding bdi devices sometimes * disappear during running this test. Let's exclude them here for stability. */ ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "bdi", false)); @@ -233,6 +229,15 @@ TEST(sd_device_enumerator_devices) { /* On CentOS CI, systemd-networkd-tests.py may be running when this test is invoked. The networkd * test creates and removes many network interfaces, and may interfere with this test. */ ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "net", false)); +} + +TEST(sd_device_enumerator_devices) { + _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; + + ASSERT_OK(sd_device_enumerator_new(&e)); + ASSERT_OK(sd_device_enumerator_allow_uninitialized(e)); + exclude_problematic_devices(e); + FOREACH_DEVICE(e, d) test_sd_device_one(d); } @@ -300,10 +305,7 @@ static bool test_sd_device_enumerator_filter_subsystem_trial(void) { ASSERT_NOT_NULL((subsystems = hashmap_new(&string_hash_ops))); ASSERT_OK(sd_device_enumerator_new(&e)); - /* See comments in TEST(sd_device_enumerator_devices). */ - ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "bdi", false)); - ASSERT_OK(sd_device_enumerator_add_nomatch_sysname(e, "loop*")); - ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "net", false)); + exclude_problematic_devices(e); FOREACH_DEVICE(e, d) { const char *syspath, *subsystem; @@ -482,10 +484,7 @@ TEST(sd_device_enumerator_add_match_parent) { ASSERT_OK(sd_device_enumerator_new(&e)); ASSERT_OK(sd_device_enumerator_allow_uninitialized(e)); - /* See comments in TEST(sd_device_enumerator_devices). */ - ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "bdi", false)); - ASSERT_OK(sd_device_enumerator_add_nomatch_sysname(e, "loop*")); - ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "net", false)); + exclude_problematic_devices(e); if (!slow_tests_enabled()) ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "block", true)); @@ -564,10 +563,7 @@ TEST(sd_device_get_child) { ASSERT_OK(sd_device_enumerator_new(&e)); ASSERT_OK(sd_device_enumerator_allow_uninitialized(e)); - /* See comments in TEST(sd_device_enumerator_devices). */ - ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "bdi", false)); - ASSERT_OK(sd_device_enumerator_add_nomatch_sysname(e, "loop*")); - ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "net", false)); + exclude_problematic_devices(e); if (!slow_tests_enabled()) ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "block", true)); From 74cb65e45fbf3468cf6b522e4b4fa568d95f12c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 10 Apr 2025 13:51:21 +0200 Subject: [PATCH 2/2] test-sd-device: limit the number of iterations when testing device parent/child functions The test "hangs" and times out on some arm64 machines. It actually works as expected, but the machine has 2016 children under /sys/devices/system/memory/, and the tests do a double loop over this, which is slow enough to hit the 120 s limit. Add a limit on the number of iterations. Another option would be to exclude "memory" subsystem. But we may have other subsystems which have the same problem in the future, so I think it'll be more robust to not try to limit the fix to a specific subsystem. --- src/libsystemd/sd-device/test-sd-device.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libsystemd/sd-device/test-sd-device.c b/src/libsystemd/sd-device/test-sd-device.c index d08e5914a29..85c3beb04fb 100644 --- a/src/libsystemd/sd-device/test-sd-device.c +++ b/src/libsystemd/sd-device/test-sd-device.c @@ -480,12 +480,16 @@ static void check_parent_match(sd_device_enumerator *e, sd_device *dev) { TEST(sd_device_enumerator_add_match_parent) { _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; + /* Some devices have thousands of children. Avoid spending too much time in the double loop below. */ + unsigned iterations = 200; int r; ASSERT_OK(sd_device_enumerator_new(&e)); ASSERT_OK(sd_device_enumerator_allow_uninitialized(e)); exclude_problematic_devices(e); + ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "memory", false)); + if (!slow_tests_enabled()) ASSERT_OK(sd_device_enumerator_add_match_subsystem(e, "block", true)); @@ -494,6 +498,9 @@ TEST(sd_device_enumerator_add_match_parent) { const char *syspath; sd_device *parent; + if (iterations-- == 0) + break; + ASSERT_OK(sd_device_get_syspath(dev, &syspath)); r = sd_device_get_parent(dev, &parent); @@ -559,6 +566,8 @@ TEST(sd_device_enumerator_add_all_parents) { TEST(sd_device_get_child) { _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; + /* Some devices have thousands of children. Avoid spending too much time in the double loop below. */ + unsigned iterations = 3000; int r; ASSERT_OK(sd_device_enumerator_new(&e)); @@ -589,6 +598,9 @@ TEST(sd_device_get_child) { FOREACH_DEVICE_CHILD_WITH_SUFFIX(parent, child, suffix) { const char *s; + if (iterations-- == 0) + return; + ASSERT_NOT_NULL(child); ASSERT_NOT_NULL(suffix);