summaryrefslogtreecommitdiffstats
path: root/src/test/test-devnum-util.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/test/test-devnum-util.c124
1 files changed, 124 insertions, 0 deletions
diff --git a/src/test/test-devnum-util.c b/src/test/test-devnum-util.c
new file mode 100644
index 0000000..66f4ac9
--- /dev/null
+++ b/src/test/test-devnum-util.c
@@ -0,0 +1,124 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <sys/stat.h>
+
+#include "devnum-util.h"
+#include "path-util.h"
+#include "stat-util.h"
+#include "tests.h"
+
+TEST(parse_devnum) {
+ dev_t dev;
+
+ assert_se(parse_devnum("", &dev) == -EINVAL);
+ assert_se(parse_devnum("junk", &dev) == -EINVAL);
+ assert_se(parse_devnum("0", &dev) == -EINVAL);
+ assert_se(parse_devnum("5", &dev) == -EINVAL);
+ assert_se(parse_devnum("5:", &dev) == -EINVAL);
+ assert_se(parse_devnum(":5", &dev) == -EINVAL);
+ assert_se(parse_devnum("-1:-1", &dev) == -EINVAL);
+#if SIZEOF_DEV_T < 8
+ assert_se(parse_devnum("4294967295:4294967295", &dev) == -EINVAL);
+#endif
+ assert_se(parse_devnum("8:11", &dev) >= 0 && major(dev) == 8 && minor(dev) == 11);
+ assert_se(parse_devnum("0:0", &dev) >= 0 && major(dev) == 0 && minor(dev) == 0);
+}
+
+TEST(device_major_minor_valid) {
+ /* on glibc dev_t is 64bit, even though in the kernel it is only 32bit */
+ assert_cc(sizeof(dev_t) == sizeof(uint64_t));
+
+ assert_se(DEVICE_MAJOR_VALID(0U));
+ assert_se(DEVICE_MINOR_VALID(0U));
+
+ assert_se(DEVICE_MAJOR_VALID(1U));
+ assert_se(DEVICE_MINOR_VALID(1U));
+
+ assert_se(!DEVICE_MAJOR_VALID(-1U));
+ assert_se(!DEVICE_MINOR_VALID(-1U));
+
+ assert_se(DEVICE_MAJOR_VALID(1U << 10));
+ assert_se(DEVICE_MINOR_VALID(1U << 10));
+
+ assert_se(DEVICE_MAJOR_VALID((1U << 12) - 1));
+ assert_se(DEVICE_MINOR_VALID((1U << 20) - 1));
+
+ assert_se(!DEVICE_MAJOR_VALID((1U << 12)));
+ assert_se(!DEVICE_MINOR_VALID((1U << 20)));
+
+ assert_se(!DEVICE_MAJOR_VALID(1U << 25));
+ assert_se(!DEVICE_MINOR_VALID(1U << 25));
+
+ assert_se(!DEVICE_MAJOR_VALID(UINT32_MAX));
+ assert_se(!DEVICE_MINOR_VALID(UINT32_MAX));
+
+ assert_se(!DEVICE_MAJOR_VALID(UINT64_MAX));
+ assert_se(!DEVICE_MINOR_VALID(UINT64_MAX));
+
+ assert_se(DEVICE_MAJOR_VALID(major(0)));
+ assert_se(DEVICE_MINOR_VALID(minor(0)));
+}
+
+static void test_device_path_make_canonical_one(const char *path) {
+ _cleanup_free_ char *resolved = NULL, *raw = NULL;
+ struct stat st;
+ dev_t devno;
+ mode_t mode;
+ int r;
+
+ log_debug("> %s", path);
+
+ if (stat(path, &st) < 0) {
+ assert_se(errno == ENOENT);
+ log_notice("Path %s not found, skipping test", path);
+ return;
+ }
+
+ r = device_path_make_canonical(st.st_mode, st.st_rdev, &resolved);
+ if (r == -ENOENT) {
+ /* maybe /dev/char/x:y and /dev/block/x:y are missing in this test environment, because we
+ * run in a container or so? */
+ log_notice("Device %s cannot be resolved, skipping test", path);
+ return;
+ }
+
+ assert_se(r >= 0);
+ assert_se(path_equal(path, resolved));
+
+ assert_se(device_path_make_major_minor(st.st_mode, st.st_rdev, &raw) >= 0);
+ assert_se(device_path_parse_major_minor(raw, &mode, &devno) >= 0);
+
+ assert_se(st.st_rdev == devno);
+ assert_se((st.st_mode & S_IFMT) == (mode & S_IFMT));
+}
+
+TEST(device_path_make_canonical) {
+ test_device_path_make_canonical_one("/dev/null");
+ test_device_path_make_canonical_one("/dev/zero");
+ test_device_path_make_canonical_one("/dev/full");
+ test_device_path_make_canonical_one("/dev/random");
+ test_device_path_make_canonical_one("/dev/urandom");
+ test_device_path_make_canonical_one("/dev/tty");
+
+ if (is_device_node("/run/systemd/inaccessible/blk") > 0) {
+ test_device_path_make_canonical_one("/run/systemd/inaccessible/chr");
+ test_device_path_make_canonical_one("/run/systemd/inaccessible/blk");
+ }
+}
+
+static void test_devnum_format_str_one(dev_t devnum, const char *s) {
+ dev_t x;
+
+ assert_se(streq(FORMAT_DEVNUM(devnum), s));
+ assert_se(parse_devnum(s, &x) >= 0);
+ assert_se(x == devnum);
+}
+
+TEST(devnum_format_str) {
+ test_devnum_format_str_one(makedev(0, 0), "0:0");
+ test_devnum_format_str_one(makedev(1, 2), "1:2");
+ test_devnum_format_str_one(makedev(99, 100), "99:100");
+ test_devnum_format_str_one(makedev(4095, 1048575), "4095:1048575");
+}
+
+DEFINE_TEST_MAIN(LOG_INFO);