LCOV - code coverage report
Current view: top level - test - test-path.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 140 145 96.6 %
Date: 2019-08-22 15:41:25 Functions: 11 11 100.0 %

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

Generated by: LCOV version 1.14