LCOV - code coverage report
Current view: top level - test - test-path.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 140 145 96.6 %
Date: 2019-08-23 13:36:53 Functions: 11 11 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 77 144 53.5 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <stdbool.h>
       4                 :            : #include <stdio.h>
       5                 :            : #include <sys/stat.h>
       6                 :            : #include <sys/types.h>
       7                 :            : 
       8                 :            : #include "alloc-util.h"
       9                 :            : #include "all-units.h"
      10                 :            : #include "fd-util.h"
      11                 :            : #include "fs-util.h"
      12                 :            : #include "macro.h"
      13                 :            : #include "manager.h"
      14                 :            : #include "mkdir.h"
      15                 :            : #include "path-util.h"
      16                 :            : #include "rm-rf.h"
      17                 :            : #include "string-util.h"
      18                 :            : #include "strv.h"
      19                 :            : #include "test-helper.h"
      20                 :            : #include "tests.h"
      21                 :            : #include "unit.h"
      22                 :            : #include "util.h"
      23                 :            : 
      24                 :            : typedef void (*test_function_t)(Manager *m);
      25                 :            : 
      26                 :         28 : static int setup_test(Manager **m) {
      27                 :         28 :         char **tests_path = STRV_MAKE("exists", "existsglobFOOBAR", "changed", "modified", "unit",
      28                 :            :                                       "directorynotempty", "makedirectory");
      29                 :            :         char **test_path;
      30                 :         28 :         Manager *tmp = NULL;
      31                 :            :         int r;
      32                 :            : 
      33         [ -  + ]:         28 :         assert_se(m);
      34                 :            : 
      35                 :         28 :         r = enter_cgroup_subroot();
      36         [ -  + ]:         28 :         if (r == -ENOMEDIUM)
      37                 :          0 :                 return log_tests_skipped("cgroupfs not available");
      38                 :            : 
      39                 :         28 :         r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &tmp);
      40   [ -  +  -  + ]:         28 :         if (MANAGER_SKIP_TEST(r))
      41                 :          0 :                 return log_tests_skipped_errno(r, "manager_new");
      42         [ -  + ]:         28 :         assert_se(r >= 0);
      43         [ -  + ]:         28 :         assert_se(manager_startup(tmp, NULL, NULL) >= 0);
      44                 :            : 
      45   [ +  -  +  + ]:        224 :         STRV_FOREACH(test_path, tests_path) {
      46                 :        196 :                 _cleanup_free_ char *p = NULL;
      47                 :            : 
      48                 :        196 :                 p = strjoin("/tmp/test-path_", *test_path);
      49         [ -  + ]:        196 :                 assert_se(p);
      50                 :            : 
      51                 :        196 :                 (void) rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL);
      52                 :            :         }
      53                 :            : 
      54                 :         28 :         *m = tmp;
      55                 :            : 
      56                 :         28 :         return 0;
      57                 :            : }
      58                 :            : 
      59                 :         28 : static void shutdown_test(Manager *m) {
      60         [ -  + ]:         28 :         assert_se(m);
      61                 :            : 
      62                 :         28 :         manager_free(m);
      63                 :         28 : }
      64                 :            : 
      65                 :         24 : static void check_stop_unlink(Manager *m, Unit *unit, const char *test_path, const char *service_name) {
      66                 :         24 :         _cleanup_free_ char *tmp = NULL;
      67                 :         24 :         Unit *service_unit = NULL;
      68                 :         24 :         Service *service = NULL;
      69                 :            :         usec_t ts;
      70                 :         24 :         usec_t timeout = 2 * USEC_PER_SEC;
      71                 :            : 
      72         [ -  + ]:         24 :         assert_se(m);
      73         [ -  + ]:         24 :         assert_se(unit);
      74         [ -  + ]:         24 :         assert_se(test_path);
      75                 :            : 
      76         [ +  + ]:         24 :         if (!service_name) {
      77         [ -  + ]:         20 :                 assert_se(tmp = strreplace(unit->id, ".path", ".service"));
      78                 :         20 :                 service_unit = manager_get_unit(m, tmp);
      79                 :            :         } else
      80                 :          4 :                 service_unit = manager_get_unit(m, service_name);
      81         [ -  + ]:         24 :         assert_se(service_unit);
      82                 :         24 :         service = SERVICE(service_unit);
      83                 :            : 
      84                 :         24 :         ts = now(CLOCK_MONOTONIC);
      85                 :            :         /* We process events until the service related to the path has been successfully started */
      86   [ -  +  +  + ]:        179 :         while (service->result != SERVICE_SUCCESS || service->state != SERVICE_START) {
      87                 :            :                 usec_t n;
      88                 :            :                 int r;
      89                 :            : 
      90                 :        155 :                 r = sd_event_run(m->event, 100 * USEC_PER_MSEC);
      91         [ -  + ]:        155 :                 assert_se(r >= 0);
      92                 :            : 
      93                 :        155 :                 printf("%s: state = %s; result = %s \n",
      94                 :            :                                 service_unit->id,
      95                 :            :                                 service_state_to_string(service->state),
      96                 :            :                                 service_result_to_string(service->result));
      97                 :            : 
      98                 :            :                 /* But we timeout if the service has not been started in the allocated time */
      99                 :        155 :                 n = now(CLOCK_MONOTONIC);
     100         [ -  + ]:        155 :                 if (ts + timeout < n) {
     101         [ #  # ]:          0 :                         log_error("Test timeout when testing %s", unit->id);
     102                 :          0 :                         exit(EXIT_FAILURE);
     103                 :            :                 }
     104                 :            :         }
     105                 :            : 
     106         [ -  + ]:         24 :         assert_se(unit_stop(unit) >= 0);
     107                 :         24 :         (void) rm_rf(test_path, REMOVE_ROOT|REMOVE_PHYSICAL);
     108                 :         24 : }
     109                 :            : 
     110                 :          4 : static void test_path_exists(Manager *m) {
     111                 :          4 :         const char *test_path = "/tmp/test-path_exists";
     112                 :          4 :         Unit *unit = NULL;
     113                 :            : 
     114         [ -  + ]:          4 :         assert_se(m);
     115                 :            : 
     116         [ -  + ]:          4 :         assert_se(manager_load_startable_unit_or_warn(m, "path-exists.path", NULL, &unit) >= 0);
     117         [ -  + ]:          4 :         assert_se(unit_start(unit) >= 0);
     118                 :            : 
     119         [ -  + ]:          4 :         assert_se(touch(test_path) >= 0);
     120                 :            : 
     121                 :          4 :         check_stop_unlink(m, unit, test_path, NULL);
     122                 :          4 : }
     123                 :            : 
     124                 :          4 : static void test_path_existsglob(Manager *m) {
     125                 :          4 :         const char *test_path = "/tmp/test-path_existsglobFOOBAR";
     126                 :          4 :         Unit *unit = NULL;
     127                 :            : 
     128         [ -  + ]:          4 :         assert_se(m);
     129         [ -  + ]:          4 :         assert_se(manager_load_startable_unit_or_warn(m, "path-existsglob.path", NULL, &unit) >= 0);
     130         [ -  + ]:          4 :         assert_se(unit_start(unit) >= 0);
     131                 :            : 
     132         [ -  + ]:          4 :         assert_se(touch(test_path) >= 0);
     133                 :            : 
     134                 :          4 :         check_stop_unlink(m, unit, test_path, NULL);
     135                 :          4 : }
     136                 :            : 
     137                 :          4 : static void test_path_changed(Manager *m) {
     138                 :          4 :         const char *test_path = "/tmp/test-path_changed";
     139                 :            :         FILE *f;
     140                 :          4 :         Unit *unit = NULL;
     141                 :            : 
     142         [ -  + ]:          4 :         assert_se(m);
     143                 :            : 
     144         [ -  + ]:          4 :         assert_se(touch(test_path) >= 0);
     145                 :            : 
     146         [ -  + ]:          4 :         assert_se(manager_load_startable_unit_or_warn(m, "path-changed.path", NULL, &unit) >= 0);
     147         [ -  + ]:          4 :         assert_se(unit_start(unit) >= 0);
     148                 :            : 
     149                 :          4 :         f = fopen(test_path, "w");
     150         [ -  + ]:          4 :         assert_se(f);
     151                 :          4 :         fclose(f);
     152                 :            : 
     153                 :          4 :         check_stop_unlink(m, unit, test_path, NULL);
     154                 :          4 : }
     155                 :            : 
     156                 :          4 : static void test_path_modified(Manager *m) {
     157                 :          4 :         _cleanup_fclose_ FILE *f = NULL;
     158                 :          4 :         const char *test_path = "/tmp/test-path_modified";
     159                 :          4 :         Unit *unit = NULL;
     160                 :            : 
     161         [ -  + ]:          4 :         assert_se(m);
     162                 :            : 
     163         [ -  + ]:          4 :         assert_se(touch(test_path) >= 0);
     164                 :            : 
     165         [ -  + ]:          4 :         assert_se(manager_load_startable_unit_or_warn(m, "path-modified.path", NULL, &unit) >= 0);
     166         [ -  + ]:          4 :         assert_se(unit_start(unit) >= 0);
     167                 :            : 
     168                 :          4 :         f = fopen(test_path, "w");
     169         [ -  + ]:          4 :         assert_se(f);
     170                 :          4 :         fputs("test", f);
     171                 :            : 
     172                 :          4 :         check_stop_unlink(m, unit, test_path, NULL);
     173                 :          4 : }
     174                 :            : 
     175                 :          4 : static void test_path_unit(Manager *m) {
     176                 :          4 :         const char *test_path = "/tmp/test-path_unit";
     177                 :          4 :         Unit *unit = NULL;
     178                 :            : 
     179         [ -  + ]:          4 :         assert_se(m);
     180                 :            : 
     181         [ -  + ]:          4 :         assert_se(manager_load_startable_unit_or_warn(m, "path-unit.path", NULL, &unit) >= 0);
     182         [ -  + ]:          4 :         assert_se(unit_start(unit) >= 0);
     183                 :            : 
     184         [ -  + ]:          4 :         assert_se(touch(test_path) >= 0);
     185                 :            : 
     186                 :          4 :         check_stop_unlink(m, unit, test_path, "path-mycustomunit.service");
     187                 :          4 : }
     188                 :            : 
     189                 :          4 : static void test_path_directorynotempty(Manager *m) {
     190                 :          4 :         const char *test_path = "/tmp/test-path_directorynotempty/";
     191                 :          4 :         Unit *unit = NULL;
     192                 :            : 
     193         [ -  + ]:          4 :         assert_se(m);
     194                 :            : 
     195         [ -  + ]:          4 :         assert_se(access(test_path, F_OK) < 0);
     196                 :            : 
     197         [ -  + ]:          4 :         assert_se(manager_load_startable_unit_or_warn(m, "path-directorynotempty.path", NULL, &unit) >= 0);
     198         [ -  + ]:          4 :         assert_se(unit_start(unit) >= 0);
     199                 :            : 
     200                 :            :         /* MakeDirectory default to no */
     201         [ -  + ]:          4 :         assert_se(access(test_path, F_OK) < 0);
     202                 :            : 
     203         [ -  + ]:          4 :         assert_se(mkdir_p(test_path, 0755) >= 0);
     204   [ +  +  +  -  :         20 :         assert_se(touch(strjoina(test_path, "test_file")) >= 0);
          -  +  -  +  +  
             +  +  -  -  
                      + ]
     205                 :            : 
     206                 :          4 :         check_stop_unlink(m, unit, test_path, NULL);
     207                 :          4 : }
     208                 :            : 
     209                 :          4 : static void test_path_makedirectory_directorymode(Manager *m) {
     210                 :          4 :         const char *test_path = "/tmp/test-path_makedirectory/";
     211                 :          4 :         Unit *unit = NULL;
     212                 :            :         struct stat s;
     213                 :            : 
     214         [ -  + ]:          4 :         assert_se(m);
     215                 :            : 
     216         [ -  + ]:          4 :         assert_se(access(test_path, F_OK) < 0);
     217                 :            : 
     218         [ -  + ]:          4 :         assert_se(manager_load_startable_unit_or_warn(m, "path-makedirectory.path", NULL, &unit) >= 0);
     219         [ -  + ]:          4 :         assert_se(unit_start(unit) >= 0);
     220                 :            : 
     221                 :            :         /* Check if the directory has been created */
     222         [ -  + ]:          4 :         assert_se(access(test_path, F_OK) >= 0);
     223                 :            : 
     224                 :            :         /* Check the mode we specified with DirectoryMode=0744 */
     225         [ -  + ]:          4 :         assert_se(stat(test_path, &s) >= 0);
     226         [ -  + ]:          4 :         assert_se((s.st_mode & S_IRWXU) == 0700);
     227         [ -  + ]:          4 :         assert_se((s.st_mode & S_IRWXG) == 0040);
     228         [ -  + ]:          4 :         assert_se((s.st_mode & S_IRWXO) == 0004);
     229                 :            : 
     230         [ -  + ]:          4 :         assert_se(unit_stop(unit) >= 0);
     231                 :          4 :         (void) rm_rf(test_path, REMOVE_ROOT|REMOVE_PHYSICAL);
     232                 :          4 : }
     233                 :            : 
     234                 :          4 : int main(int argc, char *argv[]) {
     235                 :            :         static const test_function_t tests[] = {
     236                 :            :                 test_path_exists,
     237                 :            :                 test_path_existsglob,
     238                 :            :                 test_path_changed,
     239                 :            :                 test_path_modified,
     240                 :            :                 test_path_unit,
     241                 :            :                 test_path_directorynotempty,
     242                 :            :                 test_path_makedirectory_directorymode,
     243                 :            :                 NULL,
     244                 :            :         };
     245                 :            : 
     246                 :          4 :         _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
     247                 :          4 :         _cleanup_free_ char *test_path = NULL;
     248                 :          4 :         const test_function_t *test = NULL;
     249                 :          4 :         Manager *m = NULL;
     250                 :            : 
     251                 :          4 :         umask(022);
     252                 :            : 
     253                 :          4 :         test_setup_logging(LOG_INFO);
     254                 :            : 
     255                 :          4 :         test_path = path_join(get_testdata_dir(), "test-path");
     256         [ -  + ]:          4 :         assert_se(set_unit_path(test_path) >= 0);
     257         [ -  + ]:          4 :         assert_se(runtime_dir = setup_fake_runtime_dir());
     258                 :            : 
     259   [ +  -  +  + ]:         32 :         for (test = tests; test && *test; test++) {
     260                 :            :                 int r;
     261                 :            : 
     262                 :            :                 /* We create a clean environment for each test */
     263                 :         28 :                 r = setup_test(&m);
     264         [ -  + ]:         28 :                 if (r != 0)
     265                 :          0 :                         return r;
     266                 :            : 
     267                 :         28 :                 (*test)(m);
     268                 :            : 
     269                 :         28 :                 shutdown_test(m);
     270                 :            :         }
     271                 :            : 
     272                 :          4 :         return 0;
     273                 :            : }

Generated by: LCOV version 1.14