LCOV - code coverage report
Current view: top level - test - test-libudev.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 322 397 81.1 %
Date: 2019-08-23 13:36:53 Functions: 18 19 94.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 139 304 45.7 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <errno.h>
       4                 :            : #include <getopt.h>
       5                 :            : #include <stdio.h>
       6                 :            : #include <sys/epoll.h>
       7                 :            : #include <unistd.h>
       8                 :            : 
       9                 :            : #include "alloc-util.h"
      10                 :            : #include "build.h"
      11                 :            : #include "fd-util.h"
      12                 :            : #include "libudev-list-internal.h"
      13                 :            : #include "libudev-util.h"
      14                 :            : #include "log.h"
      15                 :            : #include "main-func.h"
      16                 :            : #include "stdio-util.h"
      17                 :            : #include "string-util.h"
      18                 :            : #include "tests.h"
      19                 :            : 
      20                 :            : static bool arg_monitor = false;
      21                 :            : 
      22                 :         32 : static void print_device(struct udev_device *device) {
      23                 :            :         const char *str;
      24                 :            :         dev_t devnum;
      25                 :            :         int count;
      26                 :            :         struct udev_list_entry *list_entry;
      27                 :            : 
      28         [ +  - ]:         32 :         log_info("*** device: %p ***", device);
      29                 :         32 :         str = udev_device_get_action(device);
      30         [ -  + ]:         32 :         if (str)
      31         [ #  # ]:          0 :                 log_info("action:    '%s'", str);
      32                 :            : 
      33                 :         32 :         str = udev_device_get_syspath(device);
      34         [ +  - ]:         32 :         log_info("syspath:   '%s'", str);
      35                 :            : 
      36                 :         32 :         str = udev_device_get_sysname(device);
      37         [ +  - ]:         32 :         log_info("sysname:   '%s'", str);
      38                 :            : 
      39                 :         32 :         str = udev_device_get_sysnum(device);
      40         [ -  + ]:         32 :         if (str)
      41         [ #  # ]:          0 :                 log_info("sysnum:    '%s'", str);
      42                 :            : 
      43                 :         32 :         str = udev_device_get_devpath(device);
      44         [ +  - ]:         32 :         log_info("devpath:   '%s'", str);
      45                 :            : 
      46                 :         32 :         str = udev_device_get_subsystem(device);
      47         [ +  - ]:         32 :         if (str)
      48         [ +  - ]:         32 :                 log_info("subsystem: '%s'", str);
      49                 :            : 
      50                 :         32 :         str = udev_device_get_devtype(device);
      51         [ +  + ]:         32 :         if (str)
      52         [ +  - ]:          4 :                 log_info("devtype:   '%s'", str);
      53                 :            : 
      54                 :         32 :         str = udev_device_get_driver(device);
      55         [ -  + ]:         32 :         if (str)
      56         [ #  # ]:          0 :                 log_info("driver:    '%s'", str);
      57                 :            : 
      58                 :         32 :         str = udev_device_get_devnode(device);
      59         [ +  + ]:         32 :         if (str)
      60         [ +  - ]:         20 :                 log_info("devname:   '%s'", str);
      61                 :            : 
      62                 :         32 :         devnum = udev_device_get_devnum(device);
      63         [ +  + ]:         32 :         if (major(devnum) > 0)
      64         [ +  - ]:         20 :                 log_info("devnum:    %u:%u", major(devnum), minor(devnum));
      65                 :            : 
      66                 :         32 :         count = 0;
      67         [ +  + ]:         44 :         udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device)) {
      68         [ +  - ]:         12 :                 log_info("link:      '%s'", udev_list_entry_get_name(list_entry));
      69                 :         12 :                 count++;
      70                 :            :         }
      71         [ +  + ]:         32 :         if (count > 0)
      72         [ +  - ]:          4 :                 log_info("found %i links", count);
      73                 :            : 
      74                 :         32 :         count = 0;
      75         [ +  + ]:        336 :         udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device)) {
      76         [ +  - ]:        304 :                 log_info("property:  '%s=%s'",
      77                 :            :                        udev_list_entry_get_name(list_entry),
      78                 :            :                        udev_list_entry_get_value(list_entry));
      79                 :        304 :                 count++;
      80                 :            :         }
      81         [ +  - ]:         32 :         if (count > 0)
      82         [ +  - ]:         32 :                 log_info("found %i properties", count);
      83                 :            : 
      84                 :         32 :         str = udev_device_get_property_value(device, "MAJOR");
      85         [ +  + ]:         32 :         if (str)
      86         [ +  - ]:         20 :                 log_info("MAJOR: '%s'", str);
      87                 :            : 
      88                 :         32 :         str = udev_device_get_sysattr_value(device, "dev");
      89         [ +  + ]:         32 :         if (str)
      90         [ +  - ]:         20 :                 log_info("attr{dev}: '%s'", str);
      91                 :         32 : }
      92                 :            : 
      93                 :          4 : static void test_device(struct udev *udev, const char *syspath) {
      94                 :          4 :         _cleanup_(udev_device_unrefp) struct udev_device *device;
      95                 :            : 
      96         [ +  - ]:          4 :         log_info("/* %s, device %s */", __func__, syspath);
      97                 :          4 :         device = udev_device_new_from_syspath(udev, syspath);
      98         [ +  - ]:          4 :         if (device)
      99                 :          4 :                 print_device(device);
     100                 :            :         else
     101         [ #  # ]:          0 :                 log_warning_errno(errno, "udev_device_new_from_syspath: %m");
     102                 :          4 : }
     103                 :            : 
     104                 :          4 : static void test_device_parents(struct udev *udev, const char *syspath) {
     105         [ +  - ]:          4 :         _cleanup_(udev_device_unrefp) struct udev_device *device;
     106                 :            :         struct udev_device *device_parent;
     107                 :            : 
     108         [ +  - ]:          4 :         log_info("/* %s, device %s */", __func__, syspath);
     109                 :          4 :         device = udev_device_new_from_syspath(udev, syspath);
     110         [ -  + ]:          4 :         if (device == NULL)
     111                 :          0 :                 return;
     112                 :            : 
     113         [ +  - ]:          4 :         log_info("looking at parents");
     114                 :          4 :         device_parent = device;
     115                 :            :         do {
     116                 :          4 :                 print_device(device_parent);
     117                 :          4 :                 device_parent = udev_device_get_parent(device_parent);
     118         [ -  + ]:          4 :         } while (device_parent != NULL);
     119                 :            : 
     120         [ +  - ]:          4 :         log_info("looking at parents again");
     121                 :          4 :         device_parent = device;
     122                 :            :         do {
     123                 :          4 :                 print_device(device_parent);
     124                 :          4 :                 device_parent = udev_device_get_parent(device_parent);
     125         [ -  + ]:          4 :         } while (device_parent != NULL);
     126                 :            : }
     127                 :            : 
     128                 :          4 : static void test_device_devnum(struct udev *udev) {
     129                 :          4 :         dev_t devnum = makedev(1, 3);
     130                 :          4 :         _cleanup_(udev_device_unrefp) struct udev_device *device;
     131                 :            : 
     132         [ +  - ]:          4 :         log_info("/* %s, device %d:%d */", __func__, major(devnum), minor(devnum));
     133                 :            : 
     134                 :          4 :         device = udev_device_new_from_devnum(udev, 'c', devnum);
     135         [ +  - ]:          4 :         if (device)
     136                 :          4 :                 print_device(device);
     137                 :            :         else
     138         [ #  # ]:          0 :                 log_warning_errno(errno, "udev_device_new_from_devnum: %m");
     139                 :          4 : }
     140                 :            : 
     141                 :         16 : static void test_device_subsys_name(struct udev *udev, const char *subsys, const char *dev) {
     142                 :         16 :         _cleanup_(udev_device_unrefp) struct udev_device *device;
     143                 :            : 
     144         [ +  - ]:         16 :         log_info("looking up device: '%s:%s'", subsys, dev);
     145                 :         16 :         device = udev_device_new_from_subsystem_sysname(udev, subsys, dev);
     146         [ -  + ]:         16 :         if (device == NULL)
     147         [ #  # ]:          0 :                 log_warning_errno(errno, "udev_device_new_from_subsystem_sysname: %m");
     148                 :            :         else
     149                 :         16 :                 print_device(device);
     150                 :         16 : }
     151                 :            : 
     152                 :         28 : static int enumerate_print_list(struct udev_enumerate *enumerate) {
     153                 :            :         struct udev_list_entry *list_entry;
     154                 :         28 :         int count = 0;
     155                 :            : 
     156         [ +  + ]:       7540 :         udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
     157                 :            :                 struct udev_device *device;
     158                 :            : 
     159                 :       7512 :                 device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate),
     160                 :            :                                                       udev_list_entry_get_name(list_entry));
     161         [ +  - ]:       7512 :                 if (device) {
     162         [ +  - ]:       7512 :                         log_info("device: '%s' (%s)",
     163                 :            :                                  udev_device_get_syspath(device),
     164                 :            :                                  udev_device_get_subsystem(device));
     165                 :       7512 :                         udev_device_unref(device);
     166                 :       7512 :                         count++;
     167                 :            :                 }
     168                 :            :         }
     169         [ +  - ]:         28 :         log_info("found %i devices", count);
     170                 :         28 :         return count;
     171                 :            : }
     172                 :            : 
     173                 :          0 : static void test_monitor(struct udev *udev) {
     174                 :          0 :         _cleanup_(udev_monitor_unrefp) struct udev_monitor *udev_monitor;
     175                 :          0 :         _cleanup_close_ int fd_ep;
     176                 :            :         int fd_udev;
     177                 :          0 :         struct epoll_event ep_udev = {
     178                 :            :                 .events = EPOLLIN,
     179                 :          0 :         }, ep_stdin = {
     180                 :            :                 .events = EPOLLIN,
     181                 :            :                 .data.fd = STDIN_FILENO,
     182                 :            :         };
     183                 :            : 
     184         [ #  # ]:          0 :         log_info("/* %s */", __func__);
     185                 :            : 
     186                 :          0 :         fd_ep = epoll_create1(EPOLL_CLOEXEC);
     187         [ #  # ]:          0 :         assert_se(fd_ep >= 0);
     188                 :            : 
     189                 :          0 :         udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
     190         [ #  # ]:          0 :         assert_se(udev_monitor != NULL);
     191                 :            : 
     192                 :          0 :         fd_udev = udev_monitor_get_fd(udev_monitor);
     193                 :          0 :         ep_udev.data.fd = fd_udev;
     194                 :            : 
     195         [ #  # ]:          0 :         assert_se(udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "block", NULL) >= 0);
     196         [ #  # ]:          0 :         assert_se(udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "tty", NULL) >= 0);
     197         [ #  # ]:          0 :         assert_se(udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb", "usb_device") >= 0);
     198                 :            : 
     199         [ #  # ]:          0 :         assert_se(udev_monitor_enable_receiving(udev_monitor) >= 0);
     200                 :            : 
     201         [ #  # ]:          0 :         assert_se(epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_udev, &ep_udev) >= 0);
     202         [ #  # ]:          0 :         assert_se(epoll_ctl(fd_ep, EPOLL_CTL_ADD, STDIN_FILENO, &ep_stdin) >= 0);
     203                 :            : 
     204                 :          0 :         for (;;) {
     205                 :            :                 int fdcount;
     206                 :            :                 struct epoll_event ev[4];
     207                 :            :                 struct udev_device *device;
     208                 :            :                 int i;
     209                 :            : 
     210                 :          0 :                 printf("waiting for events from udev, press ENTER to exit\n");
     211                 :          0 :                 fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), -1);
     212                 :          0 :                 printf("epoll fd count: %i\n", fdcount);
     213                 :            : 
     214         [ #  # ]:          0 :                 for (i = 0; i < fdcount; i++) {
     215   [ #  #  #  # ]:          0 :                         if (ev[i].data.fd == fd_udev && ev[i].events & EPOLLIN) {
     216                 :          0 :                                 device = udev_monitor_receive_device(udev_monitor);
     217         [ #  # ]:          0 :                                 if (device == NULL) {
     218                 :          0 :                                         printf("no device from socket\n");
     219                 :          0 :                                         continue;
     220                 :            :                                 }
     221                 :          0 :                                 print_device(device);
     222                 :          0 :                                 udev_device_unref(device);
     223   [ #  #  #  # ]:          0 :                         } else if (ev[i].data.fd == STDIN_FILENO && ev[i].events & EPOLLIN) {
     224                 :          0 :                                 printf("exiting loop\n");
     225                 :          0 :                                 return;
     226                 :            :                         }
     227                 :            :                 }
     228                 :            :         }
     229                 :            : }
     230                 :            : 
     231                 :          4 : static void test_queue(struct udev *udev) {
     232                 :            :         struct udev_queue *udev_queue;
     233                 :            :         bool empty;
     234                 :            : 
     235         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     236                 :            : 
     237         [ -  + ]:          4 :         assert_se(udev_queue = udev_queue_new(udev));
     238                 :            : 
     239                 :          4 :         empty = udev_queue_get_queue_is_empty(udev_queue);
     240   [ +  -  +  - ]:          4 :         log_info("queue is %s", empty ? "empty" : "not empty");
     241                 :          4 :         udev_queue_unref(udev_queue);
     242                 :          4 : }
     243                 :            : 
     244                 :          4 : static int test_enumerate(struct udev *udev, const char *subsystem) {
     245                 :            :         struct udev_enumerate *udev_enumerate;
     246                 :            :         int r;
     247                 :            : 
     248         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     249                 :            : 
     250   [ +  -  -  + ]:          4 :         log_info("enumerate '%s'", subsystem == NULL ? "<all>" : subsystem);
     251                 :          4 :         udev_enumerate = udev_enumerate_new(udev);
     252         [ -  + ]:          4 :         if (!udev_enumerate)
     253                 :          0 :                 return -1;
     254                 :          4 :         udev_enumerate_add_match_subsystem(udev_enumerate, subsystem);
     255                 :          4 :         udev_enumerate_scan_devices(udev_enumerate);
     256                 :          4 :         enumerate_print_list(udev_enumerate);
     257                 :          4 :         udev_enumerate_unref(udev_enumerate);
     258                 :            : 
     259         [ +  - ]:          4 :         log_info("enumerate 'net' + duplicated scan + null + zero");
     260                 :          4 :         udev_enumerate = udev_enumerate_new(udev);
     261         [ -  + ]:          4 :         if (!udev_enumerate)
     262                 :          0 :                 return -1;
     263                 :          4 :         udev_enumerate_add_match_subsystem(udev_enumerate, "net");
     264                 :          4 :         udev_enumerate_scan_devices(udev_enumerate);
     265                 :          4 :         udev_enumerate_scan_devices(udev_enumerate);
     266                 :          4 :         udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
     267                 :          4 :         udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
     268                 :          4 :         udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
     269                 :          4 :         udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
     270                 :          4 :         udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
     271                 :          4 :         udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
     272                 :          4 :         udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/null");
     273                 :          4 :         udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
     274                 :          4 :         udev_enumerate_add_syspath(udev_enumerate, "/sys/class/mem/zero");
     275                 :          4 :         udev_enumerate_scan_devices(udev_enumerate);
     276                 :          4 :         enumerate_print_list(udev_enumerate);
     277                 :          4 :         udev_enumerate_unref(udev_enumerate);
     278                 :            : 
     279         [ +  - ]:          4 :         log_info("enumerate 'block'");
     280                 :          4 :         udev_enumerate = udev_enumerate_new(udev);
     281         [ -  + ]:          4 :         if (!udev_enumerate)
     282                 :          0 :                 return -1;
     283                 :          4 :         udev_enumerate_add_match_subsystem(udev_enumerate,"block");
     284                 :          4 :         r = udev_enumerate_add_match_is_initialized(udev_enumerate);
     285         [ -  + ]:          4 :         if (r < 0) {
     286                 :          0 :                 udev_enumerate_unref(udev_enumerate);
     287                 :          0 :                 return r;
     288                 :            :         }
     289                 :          4 :         udev_enumerate_scan_devices(udev_enumerate);
     290                 :          4 :         enumerate_print_list(udev_enumerate);
     291                 :          4 :         udev_enumerate_unref(udev_enumerate);
     292                 :            : 
     293         [ +  - ]:          4 :         log_info("enumerate 'not block'");
     294                 :          4 :         udev_enumerate = udev_enumerate_new(udev);
     295         [ -  + ]:          4 :         if (!udev_enumerate)
     296                 :          0 :                 return -1;
     297                 :          4 :         udev_enumerate_add_nomatch_subsystem(udev_enumerate, "block");
     298                 :          4 :         udev_enumerate_scan_devices(udev_enumerate);
     299                 :          4 :         enumerate_print_list(udev_enumerate);
     300                 :          4 :         udev_enumerate_unref(udev_enumerate);
     301                 :            : 
     302         [ +  - ]:          4 :         log_info("enumerate 'pci, mem, vc'");
     303                 :          4 :         udev_enumerate = udev_enumerate_new(udev);
     304         [ -  + ]:          4 :         if (!udev_enumerate)
     305                 :          0 :                 return -1;
     306                 :          4 :         udev_enumerate_add_match_subsystem(udev_enumerate, "pci");
     307                 :          4 :         udev_enumerate_add_match_subsystem(udev_enumerate, "mem");
     308                 :          4 :         udev_enumerate_add_match_subsystem(udev_enumerate, "vc");
     309                 :          4 :         udev_enumerate_scan_devices(udev_enumerate);
     310                 :          4 :         enumerate_print_list(udev_enumerate);
     311                 :          4 :         udev_enumerate_unref(udev_enumerate);
     312                 :            : 
     313         [ +  - ]:          4 :         log_info("enumerate 'subsystem'");
     314                 :          4 :         udev_enumerate = udev_enumerate_new(udev);
     315         [ -  + ]:          4 :         if (!udev_enumerate)
     316                 :          0 :                 return -1;
     317                 :          4 :         udev_enumerate_scan_subsystems(udev_enumerate);
     318                 :          4 :         enumerate_print_list(udev_enumerate);
     319                 :          4 :         udev_enumerate_unref(udev_enumerate);
     320                 :            : 
     321         [ +  - ]:          4 :         log_info("enumerate 'property IF_FS_*=filesystem'");
     322                 :          4 :         udev_enumerate = udev_enumerate_new(udev);
     323         [ -  + ]:          4 :         if (!udev_enumerate)
     324                 :          0 :                 return -1;
     325                 :          4 :         udev_enumerate_add_match_property(udev_enumerate, "ID_FS*", "filesystem");
     326                 :          4 :         udev_enumerate_scan_devices(udev_enumerate);
     327                 :          4 :         enumerate_print_list(udev_enumerate);
     328                 :          4 :         udev_enumerate_unref(udev_enumerate);
     329                 :          4 :         return 0;
     330                 :            : }
     331                 :            : 
     332                 :          4 : static void test_hwdb(struct udev *udev, const char *modalias) {
     333                 :            :         struct udev_hwdb *hwdb;
     334                 :            :         struct udev_list_entry *entry;
     335                 :            : 
     336         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     337                 :            : 
     338                 :          4 :         hwdb = udev_hwdb_new(udev);
     339         [ -  + ]:          4 :         if (!hwdb)
     340         [ #  # ]:          0 :                 log_warning_errno(errno, "Failed to open hwdb: %m");
     341                 :            : 
     342         [ +  + ]:         12 :         udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(hwdb, modalias, 0))
     343         [ +  - ]:          8 :                 log_info("'%s'='%s'", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry));
     344                 :            : 
     345                 :          4 :         hwdb = udev_hwdb_unref(hwdb);
     346         [ -  + ]:          4 :         assert_se(hwdb == NULL);
     347                 :          4 : }
     348                 :            : 
     349                 :        128 : static void test_util_replace_whitespace_one_len(const char *str, size_t len, const char *expected) {
     350                 :        128 :         _cleanup_free_ char *result = NULL;
     351                 :            :         int r;
     352                 :            : 
     353                 :        128 :         result = new(char, len + 1);
     354         [ -  + ]:        128 :         assert_se(result);
     355                 :        128 :         r = util_replace_whitespace(str, result, len);
     356         [ -  + ]:        128 :         assert_se((size_t) r == strlen(expected));
     357         [ -  + ]:        128 :         assert_se(streq(result, expected));
     358                 :        128 : }
     359                 :            : 
     360                 :         20 : static void test_util_replace_whitespace_one(const char *str, const char *expected) {
     361                 :         20 :         test_util_replace_whitespace_one_len(str, strlen(str), expected);
     362                 :         20 : }
     363                 :            : 
     364                 :          4 : static void test_util_replace_whitespace(void) {
     365         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     366                 :            : 
     367                 :          4 :         test_util_replace_whitespace_one("hogehoge", "hogehoge");
     368                 :          4 :         test_util_replace_whitespace_one("hoge  hoge", "hoge_hoge");
     369                 :          4 :         test_util_replace_whitespace_one("  hoge  hoge  ", "hoge_hoge");
     370                 :          4 :         test_util_replace_whitespace_one("     ", "");
     371                 :          4 :         test_util_replace_whitespace_one("hoge ", "hoge");
     372                 :            : 
     373                 :          4 :         test_util_replace_whitespace_one_len("hoge hoge    ", 9, "hoge_hoge");
     374                 :          4 :         test_util_replace_whitespace_one_len("hoge hoge    ", 8, "hoge_hog");
     375                 :          4 :         test_util_replace_whitespace_one_len("hoge hoge    ", 7, "hoge_ho");
     376                 :          4 :         test_util_replace_whitespace_one_len("hoge hoge    ", 6, "hoge_h");
     377                 :          4 :         test_util_replace_whitespace_one_len("hoge hoge    ", 5, "hoge");
     378                 :          4 :         test_util_replace_whitespace_one_len("hoge hoge    ", 4, "hoge");
     379                 :          4 :         test_util_replace_whitespace_one_len("hoge hoge    ", 3, "hog");
     380                 :          4 :         test_util_replace_whitespace_one_len("hoge hoge    ", 2, "ho");
     381                 :          4 :         test_util_replace_whitespace_one_len("hoge hoge    ", 1, "h");
     382                 :          4 :         test_util_replace_whitespace_one_len("hoge hoge    ", 0, "");
     383                 :            : 
     384                 :          4 :         test_util_replace_whitespace_one_len("    hoge   hoge    ", 16, "hoge_hoge");
     385                 :          4 :         test_util_replace_whitespace_one_len("    hoge   hoge    ", 15, "hoge_hoge");
     386                 :          4 :         test_util_replace_whitespace_one_len("    hoge   hoge    ", 14, "hoge_hog");
     387                 :          4 :         test_util_replace_whitespace_one_len("    hoge   hoge    ", 13, "hoge_ho");
     388                 :          4 :         test_util_replace_whitespace_one_len("    hoge   hoge    ", 12, "hoge_h");
     389                 :          4 :         test_util_replace_whitespace_one_len("    hoge   hoge    ", 11, "hoge");
     390                 :          4 :         test_util_replace_whitespace_one_len("    hoge   hoge    ", 10, "hoge");
     391                 :          4 :         test_util_replace_whitespace_one_len("    hoge   hoge    ", 9, "hoge");
     392                 :          4 :         test_util_replace_whitespace_one_len("    hoge   hoge    ", 8, "hoge");
     393                 :          4 :         test_util_replace_whitespace_one_len("    hoge   hoge    ", 7, "hog");
     394                 :          4 :         test_util_replace_whitespace_one_len("    hoge   hoge    ", 6, "ho");
     395                 :          4 :         test_util_replace_whitespace_one_len("    hoge   hoge    ", 5, "h");
     396                 :          4 :         test_util_replace_whitespace_one_len("    hoge   hoge    ", 4, "");
     397                 :          4 :         test_util_replace_whitespace_one_len("    hoge   hoge    ", 3, "");
     398                 :          4 :         test_util_replace_whitespace_one_len("    hoge   hoge    ", 2, "");
     399                 :          4 :         test_util_replace_whitespace_one_len("    hoge   hoge    ", 1, "");
     400                 :          4 :         test_util_replace_whitespace_one_len("    hoge   hoge    ", 0, "");
     401                 :          4 : }
     402                 :            : 
     403                 :         56 : static void test_util_resolve_subsys_kernel_one(const char *str, bool read_value, int retval, const char *expected) {
     404                 :         56 :         char result[UTIL_PATH_SIZE] = "";
     405                 :            :         int r;
     406                 :            : 
     407                 :         56 :         r = util_resolve_subsys_kernel(str, result, sizeof(result), read_value);
     408         [ +  - ]:         56 :         log_info("\"%s\" → expect: \"%s\", %d, actual: \"%s\", %d", str, strnull(expected), retval, result, r);
     409         [ -  + ]:         56 :         assert_se(r == retval);
     410         [ +  + ]:         56 :         if (r >= 0)
     411         [ -  + ]:         32 :                 assert_se(streq(result, expected));
     412                 :         56 : }
     413                 :            : 
     414                 :          4 : static void test_util_resolve_subsys_kernel(void) {
     415         [ +  - ]:          4 :         log_info("/* %s */", __func__);
     416                 :            : 
     417                 :          4 :         test_util_resolve_subsys_kernel_one("hoge", false, -EINVAL, NULL);
     418                 :          4 :         test_util_resolve_subsys_kernel_one("[hoge", false, -EINVAL, NULL);
     419                 :          4 :         test_util_resolve_subsys_kernel_one("[hoge/foo", false, -EINVAL, NULL);
     420                 :          4 :         test_util_resolve_subsys_kernel_one("[hoge/]", false, -ENODEV, NULL);
     421                 :            : 
     422                 :          4 :         test_util_resolve_subsys_kernel_one("[net/lo]", false, 0, "/sys/devices/virtual/net/lo");
     423                 :          4 :         test_util_resolve_subsys_kernel_one("[net/lo]/", false, 0, "/sys/devices/virtual/net/lo");
     424                 :          4 :         test_util_resolve_subsys_kernel_one("[net/lo]hoge", false, 0, "/sys/devices/virtual/net/lo/hoge");
     425                 :          4 :         test_util_resolve_subsys_kernel_one("[net/lo]/hoge", false, 0, "/sys/devices/virtual/net/lo/hoge");
     426                 :            : 
     427                 :          4 :         test_util_resolve_subsys_kernel_one("[net/lo]", true, -EINVAL, NULL);
     428                 :          4 :         test_util_resolve_subsys_kernel_one("[net/lo]/", true, -EINVAL, NULL);
     429                 :          4 :         test_util_resolve_subsys_kernel_one("[net/lo]hoge", true, 0, "");
     430                 :          4 :         test_util_resolve_subsys_kernel_one("[net/lo]/hoge", true, 0, "");
     431                 :          4 :         test_util_resolve_subsys_kernel_one("[net/lo]address", true, 0, "00:00:00:00:00:00");
     432                 :          4 :         test_util_resolve_subsys_kernel_one("[net/lo]/address", true, 0, "00:00:00:00:00:00");
     433                 :          4 : }
     434                 :            : 
     435                 :          4 : static void test_list(void) {
     436                 :          4 :         _cleanup_(udev_list_freep) struct udev_list *list = NULL;
     437                 :            :         struct udev_list_entry *e;
     438                 :            : 
     439                 :            :         /* empty list */
     440         [ -  + ]:          4 :         assert_se(list = udev_list_new(false));
     441         [ -  + ]:          4 :         assert_se(!udev_list_get_entry(list));
     442                 :          4 :         list = udev_list_free(list);
     443                 :            : 
     444                 :            :         /* unique == false */
     445         [ -  + ]:          4 :         assert_se(list = udev_list_new(false));
     446         [ -  + ]:          4 :         assert_se(udev_list_entry_add(list, "aaa", "hoge"));
     447         [ -  + ]:          4 :         assert_se(udev_list_entry_add(list, "aaa", "hogehoge"));
     448         [ -  + ]:          4 :         assert_se(udev_list_entry_add(list, "bbb", "foo"));
     449                 :          4 :         e = udev_list_get_entry(list);
     450         [ -  + ]:          4 :         assert_se(e);
     451         [ -  + ]:          4 :         assert_se(streq_ptr(udev_list_entry_get_name(e), "aaa"));
     452         [ -  + ]:          4 :         assert_se(streq_ptr(udev_list_entry_get_value(e), "hoge"));
     453                 :          4 :         e = udev_list_entry_get_next(e);
     454         [ -  + ]:          4 :         assert_se(e);
     455         [ -  + ]:          4 :         assert_se(streq_ptr(udev_list_entry_get_name(e), "aaa"));
     456         [ -  + ]:          4 :         assert_se(streq_ptr(udev_list_entry_get_value(e), "hogehoge"));
     457                 :          4 :         e = udev_list_entry_get_next(e);
     458         [ -  + ]:          4 :         assert_se(e);
     459         [ -  + ]:          4 :         assert_se(streq_ptr(udev_list_entry_get_name(e), "bbb"));
     460         [ -  + ]:          4 :         assert_se(streq_ptr(udev_list_entry_get_value(e), "foo"));
     461         [ -  + ]:          4 :         assert_se(!udev_list_entry_get_next(e));
     462                 :            : 
     463         [ -  + ]:          4 :         assert_se(!udev_list_entry_get_by_name(e, "aaa"));
     464         [ -  + ]:          4 :         assert_se(!udev_list_entry_get_by_name(e, "bbb"));
     465         [ -  + ]:          4 :         assert_se(!udev_list_entry_get_by_name(e, "ccc"));
     466                 :          4 :         list = udev_list_free(list);
     467                 :            : 
     468                 :            :         /* unique == true */
     469         [ -  + ]:          4 :         assert_se(list = udev_list_new(true));
     470         [ -  + ]:          4 :         assert_se(udev_list_entry_add(list, "aaa", "hoge"));
     471         [ -  + ]:          4 :         assert_se(udev_list_entry_add(list, "aaa", "hogehoge"));
     472         [ -  + ]:          4 :         assert_se(udev_list_entry_add(list, "bbb", "foo"));
     473                 :          4 :         e = udev_list_get_entry(list);
     474         [ -  + ]:          4 :         assert_se(e);
     475         [ -  + ]:          4 :         assert_se(streq_ptr(udev_list_entry_get_name(e), "aaa"));
     476         [ -  + ]:          4 :         assert_se(streq_ptr(udev_list_entry_get_value(e), "hogehoge"));
     477                 :          4 :         e = udev_list_entry_get_next(e);
     478         [ -  + ]:          4 :         assert_se(streq_ptr(udev_list_entry_get_name(e), "bbb"));
     479         [ -  + ]:          4 :         assert_se(streq_ptr(udev_list_entry_get_value(e), "foo"));
     480         [ -  + ]:          4 :         assert_se(!udev_list_entry_get_next(e));
     481                 :            : 
     482                 :          4 :         e = udev_list_entry_get_by_name(e, "bbb");
     483         [ -  + ]:          4 :         assert_se(e);
     484         [ -  + ]:          4 :         assert_se(streq_ptr(udev_list_entry_get_name(e), "bbb"));
     485         [ -  + ]:          4 :         assert_se(streq_ptr(udev_list_entry_get_value(e), "foo"));
     486                 :          4 :         e = udev_list_entry_get_by_name(e, "aaa");
     487         [ -  + ]:          4 :         assert_se(e);
     488         [ -  + ]:          4 :         assert_se(streq_ptr(udev_list_entry_get_name(e), "aaa"));
     489         [ -  + ]:          4 :         assert_se(streq_ptr(udev_list_entry_get_value(e), "hogehoge"));
     490         [ -  + ]:          4 :         assert_se(!udev_list_entry_get_by_name(e, "ccc"));
     491                 :          4 : }
     492                 :            : 
     493                 :          4 : static int parse_args(int argc, char *argv[], const char **syspath, const char **subsystem) {
     494                 :            :         static const struct option options[] = {
     495                 :            :                 { "syspath",   required_argument, NULL, 'p' },
     496                 :            :                 { "subsystem", required_argument, NULL, 's' },
     497                 :            :                 { "debug",     no_argument,       NULL, 'd' },
     498                 :            :                 { "help",      no_argument,       NULL, 'h' },
     499                 :            :                 { "version",   no_argument,       NULL, 'V' },
     500                 :            :                 { "monitor",   no_argument,       NULL, 'm' },
     501                 :            :                 {}
     502                 :            :         };
     503                 :            :         int c;
     504                 :            : 
     505         [ -  + ]:          4 :         while ((c = getopt_long(argc, argv, "p:s:dhVm", options, NULL)) >= 0)
     506   [ #  #  #  #  :          0 :                 switch (c) {
             #  #  #  # ]
     507                 :          0 :                 case 'p':
     508                 :          0 :                         *syspath = optarg;
     509                 :          0 :                         break;
     510                 :            : 
     511                 :          0 :                 case 's':
     512                 :          0 :                         *subsystem = optarg;
     513                 :          0 :                         break;
     514                 :            : 
     515                 :          0 :                 case 'd':
     516                 :          0 :                         log_set_max_level(LOG_DEBUG);
     517                 :          0 :                         break;
     518                 :            : 
     519                 :          0 :                 case 'h':
     520                 :          0 :                         printf("--debug --syspath= --subsystem= --help\n");
     521                 :          0 :                         return 0;
     522                 :            : 
     523                 :          0 :                 case 'V':
     524                 :          0 :                         printf("%s\n", GIT_VERSION);
     525                 :          0 :                         return 0;
     526                 :            : 
     527                 :          0 :                 case 'm':
     528                 :          0 :                         arg_monitor = true;
     529                 :          0 :                         break;
     530                 :            : 
     531                 :          0 :                 case '?':
     532                 :          0 :                         return -EINVAL;
     533                 :            : 
     534                 :          0 :                 default:
     535                 :          0 :                         assert_not_reached("Unhandled option code.");
     536                 :            :                 }
     537                 :            : 
     538                 :          4 :         return 1;
     539                 :            : }
     540                 :            : 
     541                 :          4 : static int run(int argc, char *argv[]) {
     542                 :          4 :         _cleanup_(udev_unrefp) struct udev *udev = NULL;
     543                 :            : 
     544                 :          4 :         const char *syspath = "/devices/virtual/mem/null";
     545                 :          4 :         const char *subsystem = NULL;
     546                 :            :         int r;
     547                 :            : 
     548                 :          4 :         test_setup_logging(LOG_INFO);
     549                 :            : 
     550                 :          4 :         r = parse_args(argc, argv, &syspath, &subsystem);
     551         [ -  + ]:          4 :         if (r <= 0)
     552                 :          0 :                 return r;
     553                 :            : 
     554         [ -  + ]:          4 :         assert_se(udev = udev_new());
     555                 :            : 
     556                 :            :         /* add sys path if needed */
     557         [ +  - ]:          4 :         if (!startswith(syspath, "/sys"))
     558   [ +  +  +  -  :         20 :                 syspath = strjoina("/sys/", syspath);
          -  +  -  +  +  
                +  +  - ]
     559                 :            : 
     560                 :          4 :         test_device(udev, syspath);
     561                 :          4 :         test_device_devnum(udev);
     562                 :          4 :         test_device_subsys_name(udev, "block", "sda");
     563                 :          4 :         test_device_subsys_name(udev, "subsystem", "pci");
     564                 :          4 :         test_device_subsys_name(udev, "drivers", "scsi:sd");
     565                 :          4 :         test_device_subsys_name(udev, "module", "printk");
     566                 :          4 :         test_device_parents(udev, syspath);
     567                 :            : 
     568                 :          4 :         test_enumerate(udev, subsystem);
     569                 :            : 
     570                 :          4 :         test_queue(udev);
     571                 :            : 
     572                 :          4 :         test_hwdb(udev, "usb:v0D50p0011*");
     573                 :            : 
     574         [ -  + ]:          4 :         if (arg_monitor)
     575                 :          0 :                 test_monitor(udev);
     576                 :            : 
     577                 :          4 :         test_util_replace_whitespace();
     578                 :          4 :         test_util_resolve_subsys_kernel();
     579                 :            : 
     580                 :          4 :         test_list();
     581                 :            : 
     582                 :          4 :         return 0;
     583                 :            : }
     584                 :            : 
     585                 :          4 : DEFINE_MAIN_FUNCTION(run);

Generated by: LCOV version 1.14