8 #include "proc-service.h"
10 // Tests of process-service related functionality.
12 // These tests work mostly by completely mocking out the base_process_service class. The mock
13 // implementations can be found in test-baseproc.cc.
15 // Friend interface to access base_process_service private/protected members.
16 class base_process_service_test
19 static void exec_succeeded(base_process_service *bsp)
21 bsp->waiting_for_execstat = false;
22 bsp->exec_succeeded();
25 static void handle_exit(base_process_service *bsp, int exit_status)
28 bsp->handle_exit_status(exit_status);
34 extern int last_sig_sent;
35 extern pid_t last_forked_pid;
38 // Regular service start
39 void test_proc_service_start()
45 string command = "test-command";
46 list<pair<unsigned,unsigned>> command_offsets;
47 command_offsets.emplace_back(0, command.length());
48 std::list<prelim_dep> depends;
50 process_service p = process_service(&sset, "testproc", std::move(command), command_offsets, depends);
52 sset.process_queues();
54 assert(p.get_state() == service_state_t::STARTING);
56 base_process_service_test::exec_succeeded(&p);
57 sset.process_queues();
59 assert(p.get_state() == service_state_t::STARTED);
62 // Unexpected termination
63 void test_proc_unexpected_term()
69 string command = "test-command";
70 list<pair<unsigned,unsigned>> command_offsets;
71 command_offsets.emplace_back(0, command.length());
72 std::list<prelim_dep> depends;
74 process_service p = process_service(&sset, "testproc", std::move(command), command_offsets, depends);
76 sset.process_queues();
78 base_process_service_test::exec_succeeded(&p);
79 sset.process_queues();
81 assert(p.get_state() == service_state_t::STARTED);
83 base_process_service_test::handle_exit(&p, 0);
84 sset.process_queues();
86 assert(p.get_state() == service_state_t::STOPPED);
89 // Termination via stop request
90 void test_term_via_stop()
96 string command = "test-command";
97 list<pair<unsigned,unsigned>> command_offsets;
98 command_offsets.emplace_back(0, command.length());
99 std::list<prelim_dep> depends;
101 process_service p = process_service(&sset, "testproc", std::move(command), command_offsets, depends);
103 sset.process_queues();
105 base_process_service_test::exec_succeeded(&p);
106 sset.process_queues();
108 assert(p.get_state() == service_state_t::STARTED);
111 sset.process_queues();
113 assert(p.get_state() == service_state_t::STOPPING);
115 base_process_service_test::handle_exit(&p, 0);
116 sset.process_queues();
118 assert(p.get_state() == service_state_t::STOPPED);
121 // Time-out during start
122 void test_proc_start_timeout()
128 string command = "test-command";
129 list<pair<unsigned,unsigned>> command_offsets;
130 command_offsets.emplace_back(0, command.length());
131 std::list<prelim_dep> depends;
133 process_service p = process_service(&sset, "testproc", std::move(command), command_offsets, depends);
135 sset.process_queues();
137 assert(p.get_state() == service_state_t::STARTING);
140 sset.process_queues();
142 assert(p.get_state() == service_state_t::STOPPING);
144 base_process_service_test::handle_exit(&p, 0);
145 sset.process_queues();
147 assert(p.get_state() == service_state_t::STOPPED);
151 void test_proc_stop_timeout()
157 string command = "test-command";
158 list<pair<unsigned,unsigned>> command_offsets;
159 command_offsets.emplace_back(0, command.length());
160 std::list<prelim_dep> depends;
162 process_service p = process_service(&sset, "testproc", std::move(command), command_offsets, depends);
164 sset.process_queues();
166 assert(p.get_state() == service_state_t::STARTING);
168 base_process_service_test::exec_succeeded(&p);
169 sset.process_queues();
171 assert(p.get_state() == service_state_t::STARTED);
174 sset.process_queues();
176 assert(p.get_state() == service_state_t::STOPPING);
177 assert(bp_sys::last_sig_sent == SIGTERM);
180 sset.process_queues();
182 // kill signal (SIGKILL) should have been sent; process not dead until it's dead, however
183 assert(p.get_state() == service_state_t::STOPPING);
184 assert(bp_sys::last_sig_sent == SIGKILL);
186 base_process_service_test::handle_exit(&p, 0);
187 sset.process_queues();
189 assert(p.get_state() == service_state_t::STOPPED);
193 void test_proc_smooth_recovery1()
199 string command = "test-command";
200 list<pair<unsigned,unsigned>> command_offsets;
201 command_offsets.emplace_back(0, command.length());
202 std::list<prelim_dep> depends;
204 process_service p = process_service(&sset, "testproc", std::move(command), command_offsets, depends);
205 p.set_smooth_recovery(true);
208 sset.process_queues();
210 base_process_service_test::exec_succeeded(&p);
211 sset.process_queues();
213 pid_t first_instance = bp_sys::last_forked_pid;
215 assert(p.get_state() == service_state_t::STARTED);
217 base_process_service_test::handle_exit(&p, 0);
218 sset.process_queues();
220 // since time hasn't been changed, we expect that the process has not yet been re-launched:
221 assert(first_instance == bp_sys::last_forked_pid);
222 assert(p.get_state() == service_state_t::STARTED);
225 sset.process_queues();
227 // Now a new process should've been launched:
228 assert(first_instance + 1 == bp_sys::last_forked_pid);
229 assert(p.get_state() == service_state_t::STARTED);
232 void test_proc_smooth_recovery2()
238 string command = "test-command";
239 list<pair<unsigned,unsigned>> command_offsets;
240 command_offsets.emplace_back(0, command.length());
241 std::list<prelim_dep> depends;
243 process_service p = process_service(&sset, "testproc", std::move(command), command_offsets, depends);
244 p.set_smooth_recovery(true);
245 p.set_restart_delay(time_val(0, 0));
248 sset.process_queues();
250 base_process_service_test::exec_succeeded(&p);
251 sset.process_queues();
253 pid_t first_instance = bp_sys::last_forked_pid;
255 assert(p.get_state() == service_state_t::STARTED);
257 base_process_service_test::handle_exit(&p, 0);
258 sset.process_queues();
260 // no restart delay, process should restart immediately:
261 assert(first_instance + 1 == bp_sys::last_forked_pid);
262 assert(p.get_state() == service_state_t::STARTED);
265 #define RUN_TEST(name, spacing) \
266 std::cout << #name "..." spacing; \
268 std::cout << "PASSED" << std::endl;
270 int main(int argc, char **argv)
272 RUN_TEST(test_proc_service_start, " ");
273 RUN_TEST(test_proc_unexpected_term, " ");
274 RUN_TEST(test_term_via_stop, " ");
275 RUN_TEST(test_proc_start_timeout, " ");
276 RUN_TEST(test_proc_stop_timeout, " ");
277 RUN_TEST(test_proc_smooth_recovery1, "");
278 RUN_TEST(test_proc_smooth_recovery2, "");