1 /* SPDX-License-Identifier: LGPL-2.1+ */
10 #include "test-helper.h"
14 int main(int argc
, char *argv
[]) {
15 _cleanup_(rm_rf_physical_and_freep
) char *runtime_dir
= NULL
;
16 _cleanup_(sd_bus_error_free
) sd_bus_error err
= SD_BUS_ERROR_NULL
;
17 _cleanup_(manager_freep
) Manager
*m
= NULL
;
18 Unit
*a
= NULL
, *b
= NULL
, *c
= NULL
, *d
= NULL
, *e
= NULL
, *g
= NULL
,
19 *h
= NULL
, *i
= NULL
, *a_conj
= NULL
, *unit_with_multiple_dashes
= NULL
;
23 test_setup_logging(LOG_DEBUG
);
25 r
= enter_cgroup_subroot();
27 return log_tests_skipped("cgroupfs not available");
29 /* prepare the test */
30 assert_se(set_unit_path(get_testdata_dir()) >= 0);
31 assert_se(runtime_dir
= setup_fake_runtime_dir());
32 r
= manager_new(UNIT_FILE_USER
, MANAGER_TEST_RUN_BASIC
, &m
);
33 if (MANAGER_SKIP_TEST(r
))
34 return log_tests_skipped_errno(r
, "manager_new");
36 assert_se(manager_startup(m
, NULL
, NULL
) >= 0);
39 assert_se(manager_load_startable_unit_or_warn(m
, "a.service", NULL
, &a
) >= 0);
40 assert_se(manager_load_startable_unit_or_warn(m
, "b.service", NULL
, &b
) >= 0);
41 assert_se(manager_load_startable_unit_or_warn(m
, "c.service", NULL
, &c
) >= 0);
42 manager_dump_units(m
, stdout
, "\t");
44 printf("Test1: (Trivial)\n");
45 r
= manager_add_job(m
, JOB_START
, c
, JOB_REPLACE
, NULL
, &err
, &j
);
46 if (sd_bus_error_is_set(&err
))
47 log_error("error: %s: %s", err
.name
, err
.message
);
49 manager_dump_jobs(m
, stdout
, "\t");
52 manager_clear_jobs(m
);
53 assert_se(manager_load_startable_unit_or_warn(m
, "d.service", NULL
, &d
) >= 0);
54 assert_se(manager_load_startable_unit_or_warn(m
, "e.service", NULL
, &e
) >= 0);
55 manager_dump_units(m
, stdout
, "\t");
57 printf("Test2: (Cyclic Order, Unfixable)\n");
58 assert_se(manager_add_job(m
, JOB_START
, d
, JOB_REPLACE
, NULL
, NULL
, &j
) == -EDEADLK
);
59 manager_dump_jobs(m
, stdout
, "\t");
61 printf("Test3: (Cyclic Order, Fixable, Garbage Collector)\n");
62 assert_se(manager_add_job(m
, JOB_START
, e
, JOB_REPLACE
, NULL
, NULL
, &j
) == 0);
63 manager_dump_jobs(m
, stdout
, "\t");
65 printf("Test4: (Identical transaction)\n");
66 assert_se(manager_add_job(m
, JOB_START
, e
, JOB_FAIL
, NULL
, NULL
, &j
) == 0);
67 manager_dump_jobs(m
, stdout
, "\t");
70 assert_se(manager_load_startable_unit_or_warn(m
, "g.service", NULL
, &g
) >= 0);
71 manager_dump_units(m
, stdout
, "\t");
73 printf("Test5: (Colliding transaction, fail)\n");
74 assert_se(manager_add_job(m
, JOB_START
, g
, JOB_FAIL
, NULL
, NULL
, &j
) == -EDEADLK
);
76 printf("Test6: (Colliding transaction, replace)\n");
77 assert_se(manager_add_job(m
, JOB_START
, g
, JOB_REPLACE
, NULL
, NULL
, &j
) == 0);
78 manager_dump_jobs(m
, stdout
, "\t");
80 printf("Test7: (Unmergeable job type, fail)\n");
81 assert_se(manager_add_job(m
, JOB_STOP
, g
, JOB_FAIL
, NULL
, NULL
, &j
) == -EDEADLK
);
83 printf("Test8: (Mergeable job type, fail)\n");
84 assert_se(manager_add_job(m
, JOB_RESTART
, g
, JOB_FAIL
, NULL
, NULL
, &j
) == 0);
85 manager_dump_jobs(m
, stdout
, "\t");
87 printf("Test9: (Unmergeable job type, replace)\n");
88 assert_se(manager_add_job(m
, JOB_STOP
, g
, JOB_REPLACE
, NULL
, NULL
, &j
) == 0);
89 manager_dump_jobs(m
, stdout
, "\t");
92 assert_se(manager_load_startable_unit_or_warn(m
, "h.service", NULL
, &h
) >= 0);
93 manager_dump_units(m
, stdout
, "\t");
95 printf("Test10: (Unmergeable job type of auxiliary job, fail)\n");
96 assert_se(manager_add_job(m
, JOB_START
, h
, JOB_FAIL
, NULL
, NULL
, &j
) == 0);
97 manager_dump_jobs(m
, stdout
, "\t");
100 manager_clear_jobs(m
);
101 assert_se(manager_load_startable_unit_or_warn(m
, "i.service", NULL
, &i
) >= 0);
102 SERVICE(a
)->state
= SERVICE_RUNNING
;
103 SERVICE(d
)->state
= SERVICE_RUNNING
;
104 manager_dump_units(m
, stdout
, "\t");
106 printf("Test11: (Start/stop job ordering, execution cycle)\n");
107 assert_se(manager_add_job(m
, JOB_START
, i
, JOB_FAIL
, NULL
, NULL
, &j
) == 0);
108 assert_se(unit_has_job_type(a
, JOB_STOP
));
109 assert_se(unit_has_job_type(d
, JOB_STOP
));
110 assert_se(unit_has_job_type(b
, JOB_START
));
111 manager_dump_jobs(m
, stdout
, "\t");
114 manager_clear_jobs(m
);
115 assert_se(manager_load_startable_unit_or_warn(m
, "a-conj.service", NULL
, &a_conj
) >= 0);
116 SERVICE(a
)->state
= SERVICE_DEAD
;
117 manager_dump_units(m
, stdout
, "\t");
119 printf("Test12: (Trivial cycle, Unfixable)\n");
120 assert_se(manager_add_job(m
, JOB_START
, a_conj
, JOB_REPLACE
, NULL
, NULL
, &j
) == -EDEADLK
);
121 manager_dump_jobs(m
, stdout
, "\t");
123 assert_se(!hashmap_get(a
->dependencies
[UNIT_PROPAGATES_RELOAD_TO
], b
));
124 assert_se(!hashmap_get(b
->dependencies
[UNIT_RELOAD_PROPAGATED_FROM
], a
));
125 assert_se(!hashmap_get(a
->dependencies
[UNIT_PROPAGATES_RELOAD_TO
], c
));
126 assert_se(!hashmap_get(c
->dependencies
[UNIT_RELOAD_PROPAGATED_FROM
], a
));
128 assert_se(unit_add_dependency(a
, UNIT_PROPAGATES_RELOAD_TO
, b
, true, UNIT_DEPENDENCY_UDEV
) == 0);
129 assert_se(unit_add_dependency(a
, UNIT_PROPAGATES_RELOAD_TO
, c
, true, UNIT_DEPENDENCY_PROC_SWAP
) == 0);
131 assert_se(hashmap_get(a
->dependencies
[UNIT_PROPAGATES_RELOAD_TO
], b
));
132 assert_se(hashmap_get(b
->dependencies
[UNIT_RELOAD_PROPAGATED_FROM
], a
));
133 assert_se(hashmap_get(a
->dependencies
[UNIT_PROPAGATES_RELOAD_TO
], c
));
134 assert_se(hashmap_get(c
->dependencies
[UNIT_RELOAD_PROPAGATED_FROM
], a
));
136 unit_remove_dependencies(a
, UNIT_DEPENDENCY_UDEV
);
138 assert_se(!hashmap_get(a
->dependencies
[UNIT_PROPAGATES_RELOAD_TO
], b
));
139 assert_se(!hashmap_get(b
->dependencies
[UNIT_RELOAD_PROPAGATED_FROM
], a
));
140 assert_se(hashmap_get(a
->dependencies
[UNIT_PROPAGATES_RELOAD_TO
], c
));
141 assert_se(hashmap_get(c
->dependencies
[UNIT_RELOAD_PROPAGATED_FROM
], a
));
143 unit_remove_dependencies(a
, UNIT_DEPENDENCY_PROC_SWAP
);
145 assert_se(!hashmap_get(a
->dependencies
[UNIT_PROPAGATES_RELOAD_TO
], b
));
146 assert_se(!hashmap_get(b
->dependencies
[UNIT_RELOAD_PROPAGATED_FROM
], a
));
147 assert_se(!hashmap_get(a
->dependencies
[UNIT_PROPAGATES_RELOAD_TO
], c
));
148 assert_se(!hashmap_get(c
->dependencies
[UNIT_RELOAD_PROPAGATED_FROM
], a
));
150 assert_se(manager_load_unit(m
, "unit-with-multiple-dashes.service", NULL
, NULL
, &unit_with_multiple_dashes
) >= 0);
152 assert_se(strv_equal(unit_with_multiple_dashes
->documentation
, STRV_MAKE("man:test", "man:override2", "man:override3")));
153 assert_se(streq_ptr(unit_with_multiple_dashes
->description
, "override4"));