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 extern eventloop_t event_loop;
17 constexpr static auto REG = dependency_type::REGULAR;
18 constexpr static auto WAITS = dependency_type::WAITS_FOR;
20 // Friend interface to access base_process_service private/protected members.
21 class base_process_service_test
24 static void exec_succeeded(base_process_service *bsp)
26 bsp->waiting_for_execstat = false;
27 bsp->exec_succeeded();
30 static void exec_failed(base_process_service *bsp, int errcode)
32 bsp->waiting_for_execstat = false;
33 bsp->exec_failed(errcode);
36 static void handle_exit(base_process_service *bsp, int exit_status)
39 bsp->handle_exit_status(bp_sys::exit_status(true, false, exit_status));
42 static void handle_signal_exit(base_process_service *bsp, int signo)
45 bsp->handle_exit_status(bp_sys::exit_status(false, true, signo));
48 static int get_notification_fd(base_process_service *bsp)
50 return bsp->notification_fd;
56 extern int last_sig_sent;
57 extern pid_t last_forked_pid;
60 static void init_service_defaults(base_process_service &ps)
62 ps.set_restart_interval(time_val(10,0), 3);
63 ps.set_restart_delay(time_val(0, 200000000)); // 200 milliseconds
64 ps.set_stop_timeout(time_val(10,0));
67 // Regular service start
68 void test_proc_service_start()
74 string command = "test-command";
75 list<pair<unsigned,unsigned>> command_offsets;
76 command_offsets.emplace_back(0, command.length());
77 std::list<prelim_dep> depends;
79 process_service p {&sset, "testproc", std::move(command), command_offsets, depends};
80 init_service_defaults(p);
84 sset.process_queues();
86 assert(p.get_state() == service_state_t::STARTING);
88 base_process_service_test::exec_succeeded(&p);
89 sset.process_queues();
91 assert(p.get_state() == service_state_t::STARTED);
92 assert(event_loop.active_timers.size() == 0);
94 sset.remove_service(&p);
97 // Test start with readiness notification
98 void test_proc_notify_start()
104 string command = "test-command";
105 list<pair<unsigned,unsigned>> command_offsets;
106 command_offsets.emplace_back(0, command.length());
107 std::list<prelim_dep> depends;
109 process_service p {&sset, "testproc", std::move(command), command_offsets, depends};
110 init_service_defaults(p);
111 p.set_notification_fd(3);
112 sset.add_service(&p);
115 sset.process_queues();
117 assert(p.get_state() == service_state_t::STARTING);
119 base_process_service_test::exec_succeeded(&p);
120 sset.process_queues();
122 assert(p.get_state() == service_state_t::STARTING);
124 int nfd = base_process_service_test::get_notification_fd(&p);
127 char notifystr[] = "ok started\n";
128 std::vector<char> rnotifystr;
129 rnotifystr.insert(rnotifystr.end(), notifystr, notifystr + sizeof(notifystr));
130 bp_sys::supply_read_data(nfd, std::move(rnotifystr));
132 event_loop.regd_fd_watchers[nfd]->fd_event(event_loop, nfd, dasynq::IN_EVENTS);
134 assert(p.get_state() == service_state_t::STARTED);
135 assert(event_loop.active_timers.size() == 0);
137 sset.remove_service(&p);
140 // Unexpected termination
141 void test_proc_unexpected_term()
147 string command = "test-command";
148 list<pair<unsigned,unsigned>> command_offsets;
149 command_offsets.emplace_back(0, command.length());
150 std::list<prelim_dep> depends;
152 process_service p {&sset, "testproc", std::move(command), command_offsets, depends};
153 init_service_defaults(p);
154 sset.add_service(&p);
157 sset.process_queues();
159 base_process_service_test::exec_succeeded(&p);
160 sset.process_queues();
162 assert(p.get_state() == service_state_t::STARTED);
164 base_process_service_test::handle_exit(&p, 0);
165 sset.process_queues();
167 assert(p.get_state() == service_state_t::STOPPED);
168 assert(p.get_stop_reason() == stopped_reason_t::TERMINATED);
169 assert(event_loop.active_timers.size() == 0);
171 sset.remove_service(&p);
174 // Unexpected termination
175 void test_proc_term_restart()
181 string command = "test-command";
182 list<pair<unsigned,unsigned>> command_offsets;
183 command_offsets.emplace_back(0, command.length());
184 std::list<prelim_dep> depends;
186 process_service p {&sset, "testproc", std::move(command), command_offsets, depends};
187 init_service_defaults(p);
188 p.set_auto_restart(true);
189 sset.add_service(&p);
192 sset.process_queues();
194 base_process_service_test::exec_succeeded(&p);
195 sset.process_queues();
197 assert(p.get_state() == service_state_t::STARTED);
198 assert(event_loop.active_timers.size() == 0);
200 base_process_service_test::handle_exit(&p, 0);
201 sset.process_queues();
203 // Starting, restart timer should be armed:
204 assert(p.get_state() == service_state_t::STARTING);
205 assert(event_loop.active_timers.size() == 1);
207 event_loop.advance_time(time_val(0, 200000000));
208 assert(event_loop.active_timers.size() == 0);
210 sset.process_queues();
211 base_process_service_test::exec_succeeded(&p);
212 sset.process_queues();
214 assert(p.get_state() == service_state_t::STARTED);
215 assert(event_loop.active_timers.size() == 0);
217 sset.remove_service(&p);
220 // Termination via stop request
221 void test_term_via_stop()
227 string command = "test-command";
228 list<pair<unsigned,unsigned>> command_offsets;
229 command_offsets.emplace_back(0, command.length());
230 std::list<prelim_dep> depends;
232 process_service p {&sset, "testproc", std::move(command), command_offsets, depends};
233 init_service_defaults(p);
234 sset.add_service(&p);
237 sset.process_queues();
239 base_process_service_test::exec_succeeded(&p);
240 sset.process_queues();
242 assert(p.get_state() == service_state_t::STARTED);
243 assert(event_loop.active_timers.size() == 0);
246 sset.process_queues();
248 assert(p.get_state() == service_state_t::STOPPING);
249 assert(event_loop.active_timers.size() == 1);
251 base_process_service_test::handle_exit(&p, 0);
252 sset.process_queues();
254 assert(p.get_state() == service_state_t::STOPPED);
255 assert(p.get_stop_reason() == stopped_reason_t::NORMAL);
256 assert(event_loop.active_timers.size() == 0);
258 sset.remove_service(&p);
261 // Termination via stop request, ensure reason is reset:
262 void test_term_via_stop2()
268 string command = "test-command";
269 list<pair<unsigned,unsigned>> command_offsets;
270 command_offsets.emplace_back(0, command.length());
271 std::list<prelim_dep> depends;
273 process_service p {&sset, "testproc", std::move(command), command_offsets, depends};
274 init_service_defaults(p);
275 sset.add_service(&p);
278 sset.process_queues();
280 // first set it up with failure reason:
282 base_process_service_test::exec_failed(&p, ENOENT);
283 sset.process_queues();
285 assert(p.get_state() == service_state_t::STOPPED);
286 assert(p.get_stop_reason() == stopped_reason_t::EXECFAILED);
288 // now restart clean:
291 sset.process_queues();
293 base_process_service_test::exec_succeeded(&p);
294 sset.process_queues();
296 assert(p.get_state() == service_state_t::STARTED);
297 assert(event_loop.active_timers.size() == 0);
300 sset.process_queues();
301 assert(p.get_state() == service_state_t::STOPPING);
303 base_process_service_test::handle_exit(&p, 0);
304 sset.process_queues();
305 assert(p.get_state() == service_state_t::STOPPED);
306 assert(p.get_stop_reason() == stopped_reason_t::NORMAL);
307 assert(event_loop.active_timers.size() == 0);
309 sset.remove_service(&p);
312 // Time-out during start
313 void test_proc_start_timeout()
319 string command = "test-command";
320 list<pair<unsigned,unsigned>> command_offsets;
321 command_offsets.emplace_back(0, command.length());
322 std::list<prelim_dep> depends;
324 scripted_service p {&sset, "testproc", std::move(command), command_offsets, depends};
325 init_service_defaults(p);
326 p.set_start_timeout(time_val(10,0));
327 sset.add_service(&p);
330 sset.process_queues();
332 assert(p.get_state() == service_state_t::STARTING);
334 event_loop.advance_time(time_val(10,0));
335 sset.process_queues();
337 assert(p.get_state() == service_state_t::STOPPING);
339 base_process_service_test::handle_signal_exit(&p, SIGTERM);
340 sset.process_queues();
342 // We set no stop script, so state should now be STOPPED with no timer set
343 assert(p.get_state() == service_state_t::STOPPED);
344 assert(p.get_stop_reason() == stopped_reason_t::TIMEDOUT);
345 assert(event_loop.active_timers.size() == 0);
347 sset.remove_service(&p);
350 // Test that a timeout doesn't stop a "waits for" dependent to fail to start
351 void test_proc_start_timeout2()
357 string command = "test-command";
358 list<pair<unsigned,unsigned>> command_offsets;
359 command_offsets.emplace_back(0, command.length());
360 std::list<prelim_dep> depends;
362 process_service p {&sset, "testproc", std::move(command), command_offsets, depends};
363 init_service_defaults(p);
364 sset.add_service(&p);
366 service_record ts {&sset, "test-service-1", service_type_t::INTERNAL,
367 {{&p, dependency_type::WAITS_FOR}} };
370 sset.process_queues();
372 assert(p.get_state() == service_state_t::STARTING);
373 assert(ts.get_state() == service_state_t::STARTING);
376 sset.process_queues();
378 assert(p.get_state() == service_state_t::STOPPING);
380 base_process_service_test::handle_exit(&p, 0);
381 sset.process_queues();
383 assert(p.get_state() == service_state_t::STOPPED);
384 assert(p.get_stop_reason() == stopped_reason_t::TIMEDOUT);
385 assert(ts.get_state() == service_state_t::STARTED);
386 assert(event_loop.active_timers.size() == 0);
388 sset.remove_service(&p);
391 // Test exec() failure for process service start.
392 void test_proc_start_execfail()
398 string command = "test-command";
399 list<pair<unsigned,unsigned>> command_offsets;
400 command_offsets.emplace_back(0, command.length());
401 std::list<prelim_dep> depends;
403 process_service p {&sset, "testproc", std::move(command), command_offsets, depends};
404 init_service_defaults(p);
405 sset.add_service(&p);
408 sset.process_queues();
410 assert(p.get_state() == service_state_t::STARTING);
412 base_process_service_test::exec_failed(&p, ENOENT);
413 sset.process_queues();
415 assert(p.get_state() == service_state_t::STOPPED);
416 assert(p.get_stop_reason() == stopped_reason_t::EXECFAILED);
417 assert(event_loop.active_timers.size() == 0);
419 sset.remove_service(&p);
422 // Test no ready notification before process terminates
423 void test_proc_notify_fail()
429 string command = "test-command";
430 list<pair<unsigned,unsigned>> command_offsets;
431 command_offsets.emplace_back(0, command.length());
432 std::list<prelim_dep> depends;
434 process_service p {&sset, "testproc", std::move(command), command_offsets, depends};
435 init_service_defaults(p);
436 p.set_notification_fd(3);
437 sset.add_service(&p);
440 sset.process_queues();
442 assert(p.get_state() == service_state_t::STARTING);
444 base_process_service_test::exec_succeeded(&p);
445 sset.process_queues();
447 assert(p.get_state() == service_state_t::STARTING);
449 int nfd = base_process_service_test::get_notification_fd(&p);
452 // Signal EOF on notify fd:
453 event_loop.regd_fd_watchers[nfd]->fd_event(event_loop, nfd, dasynq::IN_EVENTS);
455 assert(p.get_state() == service_state_t::STOPPING);
457 base_process_service_test::handle_exit(&p, 0);
458 sset.process_queues();
460 assert(p.get_state() == service_state_t::STOPPED);
461 assert(event_loop.active_timers.size() == 0);
463 sset.remove_service(&p);
467 void test_proc_stop_timeout()
473 string command = "test-command";
474 list<pair<unsigned,unsigned>> command_offsets;
475 command_offsets.emplace_back(0, command.length());
476 std::list<prelim_dep> depends;
478 process_service p {&sset, "testproc", std::move(command), command_offsets, depends};
479 init_service_defaults(p);
480 sset.add_service(&p);
483 sset.process_queues();
485 assert(p.get_state() == service_state_t::STARTING);
487 base_process_service_test::exec_succeeded(&p);
488 sset.process_queues();
490 assert(p.get_state() == service_state_t::STARTED);
493 sset.process_queues();
495 assert(p.get_state() == service_state_t::STOPPING);
496 assert(bp_sys::last_sig_sent == SIGTERM);
499 sset.process_queues();
501 // kill signal (SIGKILL) should have been sent; process not dead until it's dead, however
502 assert(p.get_state() == service_state_t::STOPPING);
503 assert(bp_sys::last_sig_sent == SIGKILL);
505 base_process_service_test::handle_exit(&p, 0);
506 sset.process_queues();
508 assert(p.get_state() == service_state_t::STOPPED);
509 assert(p.get_stop_reason() == stopped_reason_t::NORMAL);
511 // Note that timer is still active as we faked its expiry above
512 //assert(event_loop.active_timers.size() == 0);
513 event_loop.active_timers.clear();
514 sset.remove_service(&p);
518 void test_proc_smooth_recovery1()
524 string command = "test-command";
525 list<pair<unsigned,unsigned>> command_offsets;
526 command_offsets.emplace_back(0, command.length());
527 std::list<prelim_dep> depends;
529 process_service p {&sset, "testproc", std::move(command), command_offsets, depends};
530 init_service_defaults(p);
531 p.set_smooth_recovery(true);
532 sset.add_service(&p);
535 sset.process_queues();
537 base_process_service_test::exec_succeeded(&p);
538 sset.process_queues();
540 pid_t first_instance = bp_sys::last_forked_pid;
542 assert(p.get_state() == service_state_t::STARTED);
544 base_process_service_test::handle_exit(&p, 0);
545 sset.process_queues();
547 // since time hasn't been changed, we expect that the process has not yet been re-launched:
548 assert(first_instance == bp_sys::last_forked_pid);
549 assert(p.get_state() == service_state_t::STARTED);
552 sset.process_queues();
554 // Now a new process should've been launched:
555 assert(first_instance + 1 == bp_sys::last_forked_pid);
556 assert(p.get_state() == service_state_t::STARTED);
557 event_loop.active_timers.clear();
559 sset.remove_service(&p);
562 // Smooth recovery without restart delay
563 void test_proc_smooth_recovery2()
569 string command = "test-command";
570 list<pair<unsigned,unsigned>> command_offsets;
571 command_offsets.emplace_back(0, command.length());
572 std::list<prelim_dep> depends;
574 process_service p {&sset, "testproc", std::move(command), command_offsets, depends};
575 init_service_defaults(p);
576 p.set_smooth_recovery(true);
577 p.set_restart_delay(time_val(0, 0));
578 sset.add_service(&p);
581 sset.process_queues();
583 base_process_service_test::exec_succeeded(&p);
584 sset.process_queues();
586 pid_t first_instance = bp_sys::last_forked_pid;
588 assert(p.get_state() == service_state_t::STARTED);
589 assert(event_loop.active_timers.size() == 0);
591 base_process_service_test::handle_exit(&p, 0);
592 sset.process_queues();
594 // no restart delay, process should restart immediately:
595 assert(first_instance + 1 == bp_sys::last_forked_pid);
596 assert(p.get_state() == service_state_t::STARTED);
597 assert(event_loop.active_timers.size() == 0);
599 sset.remove_service(&p);
603 void test_scripted_stop_timeout()
609 string command = "test-command";
610 string stopcommand = "stop-command";
611 list<pair<unsigned,unsigned>> command_offsets;
612 command_offsets.emplace_back(0, command.length());
613 std::list<prelim_dep> depends;
615 scripted_service p {&sset, "testscripted", std::move(command), command_offsets, depends};
616 init_service_defaults(p);
617 p.set_stop_command(stopcommand, command_offsets);
618 sset.add_service(&p);
621 sset.process_queues();
623 assert(p.get_state() == service_state_t::STARTING);
625 base_process_service_test::exec_succeeded(&p);
626 sset.process_queues();
627 base_process_service_test::handle_exit(&p, 0);
628 sset.process_queues();
630 assert(p.get_state() == service_state_t::STARTED);
633 sset.process_queues();
635 assert(p.get_state() == service_state_t::STOPPING);
637 base_process_service_test::exec_succeeded(&p);
638 sset.process_queues();
640 // should still be stopping:
641 assert(p.get_state() == service_state_t::STOPPING);
644 sset.process_queues();
646 // kill signal (SIGKILL) should have been sent; process not dead until it's dead, however
647 assert(p.get_state() == service_state_t::STOPPING);
648 assert(bp_sys::last_sig_sent == SIGKILL);
650 base_process_service_test::handle_exit(&p, SIGKILL);
651 sset.process_queues();
653 assert(p.get_state() == service_state_t::STOPPED);
654 assert(p.get_stop_reason() == stopped_reason_t::NORMAL);
656 event_loop.active_timers.clear();
657 sset.remove_service(&p);
660 void test_scripted_start_fail()
666 string command = "test-command";
667 string stopcommand = "stop-command";
668 list<pair<unsigned,unsigned>> command_offsets;
669 command_offsets.emplace_back(0, command.length());
670 std::list<prelim_dep> depends;
672 scripted_service p {&sset, "testscripted", std::move(command), command_offsets, depends};
673 init_service_defaults(p);
674 p.set_stop_command(stopcommand, command_offsets);
675 sset.add_service(&p);
677 service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{&p, REG}});
678 service_record *s3 = new service_record(&sset, "test-service-3",
679 service_type_t::INTERNAL, {{&p, REG}, {s2, REG}});
680 sset.add_service(s2);
681 sset.add_service(s3);
684 sset.process_queues();
686 assert(p.get_state() == service_state_t::STARTING);
688 base_process_service_test::exec_succeeded(&p);
689 sset.process_queues();
690 base_process_service_test::handle_exit(&p, 0x1); // exit fail
691 sset.process_queues();
694 assert(p.get_state() == service_state_t::STOPPED);
695 assert(s2->get_state() == service_state_t::STOPPED);
696 assert(s3->get_state() == service_state_t::STOPPED);
697 assert(p.get_stop_reason() == stopped_reason_t::FAILED);
698 assert(s2->get_stop_reason() == stopped_reason_t::DEPFAILED);
699 assert(s3->get_stop_reason() == stopped_reason_t::DEPFAILED);
701 event_loop.active_timers.clear();
702 sset.remove_service(&p);
704 assert(sset.count_active_services() == 0);
707 void test_scripted_stop_fail()
713 string command = "test-command";
714 string stopcommand = "stop-command";
715 list<pair<unsigned,unsigned>> command_offsets;
716 command_offsets.emplace_back(0, command.length());
717 std::list<prelim_dep> depends;
719 scripted_service p {&sset, "testscripted", std::move(command), command_offsets, depends};
720 init_service_defaults(p);
721 p.set_stop_command(stopcommand, command_offsets);
722 sset.add_service(&p);
724 service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {});
725 service_record *s3 = new service_record(&sset, "test-service-3", service_type_t::INTERNAL,
726 {{s2, REG}, {&p, REG}});
727 service_record *s4 = new service_record(&sset, "test-service-4", service_type_t::INTERNAL,
728 {{&p, REG}, {s3, REG}});
729 sset.add_service(s2);
730 sset.add_service(s3);
731 sset.add_service(s4);
734 sset.process_queues();
736 base_process_service_test::exec_succeeded(&p);
737 sset.process_queues();
738 base_process_service_test::handle_exit(&p, 0x0); // success
739 sset.process_queues();
741 assert(p.get_state() == service_state_t::STARTED);
742 assert(s2->get_state() == service_state_t::STARTED);
743 assert(s3->get_state() == service_state_t::STARTED);
744 assert(s4->get_state() == service_state_t::STARTED);
746 pid_t last_forked = bp_sys::last_forked_pid;
749 sset.process_queues();
751 base_process_service_test::exec_succeeded(&p);
752 sset.process_queues();
753 base_process_service_test::handle_exit(&p, 0x1); // failure
754 sset.process_queues();
756 // The stop command should be executed once:
757 assert((bp_sys::last_forked_pid - last_forked) == 1);
759 assert(p.get_state() == service_state_t::STOPPED);
760 assert(s2->get_state() == service_state_t::STOPPED);
761 assert(s3->get_state() == service_state_t::STOPPED);
762 assert(s4->get_state() == service_state_t::STOPPED);
764 event_loop.active_timers.clear();
765 sset.remove_service(&p);
768 void test_scripted_start_skip()
774 string command = "test-command";
775 list<pair<unsigned,unsigned>> command_offsets;
776 command_offsets.emplace_back(0, command.length());
777 std::list<prelim_dep> depends;
779 scripted_service p {&sset, "testscripted", std::move(command), command_offsets, depends};
780 init_service_defaults(p);
781 service_flags_t sflags;
782 sflags.skippable = true;
784 sset.add_service(&p);
786 service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{&p, REG}});
787 sset.add_service(s2);
790 sset.process_queues();
791 assert(p.get_state() == service_state_t::STARTING);
793 base_process_service_test::exec_succeeded(&p);
794 sset.process_queues();
795 assert(p.get_state() == service_state_t::STARTING);
797 base_process_service_test::handle_signal_exit(&p, SIGINT); // interrupted
798 sset.process_queues();
800 assert(p.get_state() == service_state_t::STARTED);
801 assert(s2->get_state() == service_state_t::STARTED);
802 assert(p.was_start_skipped());
803 assert(! s2->was_start_skipped());
804 assert(sset.count_active_services() == 2);
807 sset.process_queues();
809 assert(p.get_state() == service_state_t::STOPPED);
810 assert(s2->get_state() == service_state_t::STOPPED);
811 assert(p.get_stop_reason() == stopped_reason_t::NORMAL);
812 assert(s2->get_stop_reason() == stopped_reason_t::NORMAL);
813 assert(sset.count_active_services() == 0);
815 event_loop.active_timers.clear();
816 sset.remove_service(&p);
819 // Test interrupting start of a service marked skippable
820 void test_scripted_start_skip2()
826 string command = "test-command";
827 list<pair<unsigned,unsigned>> command_offsets;
828 command_offsets.emplace_back(0, command.length());
829 std::list<prelim_dep> depends;
831 scripted_service p {&sset, "testscripted", std::move(command), command_offsets, depends};
832 init_service_defaults(p);
833 service_flags_t sflags;
834 sflags.skippable = true;
835 sflags.start_interruptible = true;
837 sset.add_service(&p);
839 service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{&p, REG}});
840 sset.add_service(s2);
843 sset.process_queues();
844 assert(p.get_state() == service_state_t::STARTING);
846 base_process_service_test::exec_succeeded(&p);
847 sset.process_queues();
848 assert(p.get_state() == service_state_t::STARTING);
850 s2->stop(true); // abort startup; p should be cancelled
851 sset.process_queues();
853 assert(p.get_state() == service_state_t::STOPPING);
855 base_process_service_test::handle_signal_exit(&p, SIGINT); // interrupted
856 sset.process_queues();
858 assert(p.get_state() == service_state_t::STOPPED);
859 assert(s2->get_state() == service_state_t::STOPPED);
860 assert(p.get_stop_reason() == stopped_reason_t::NORMAL);
861 assert(s2->get_stop_reason() == stopped_reason_t::NORMAL);
862 assert(sset.count_active_services() == 0);
864 event_loop.active_timers.clear();
865 sset.remove_service(&p);
868 // Test that starting a service with a waits-for dependency on another - currently stopping - service,
869 // causes that service to re-start.
870 void test_waitsfor_restart()
876 string command = "test-command";
877 list<pair<unsigned,unsigned>> command_offsets;
878 command_offsets.emplace_back(0, command.length());
879 std::list<prelim_dep> depends;
881 process_service p {&sset, "testproc", std::move(command), command_offsets, depends};
882 init_service_defaults(p);
883 sset.add_service(&p);
885 service_record tp {&sset, "test-service", service_type_t::INTERNAL, {{&p, WAITS}}};
886 sset.add_service(&tp);
891 sset.process_queues();
893 assert(p.get_state() == service_state_t::STARTING);
895 base_process_service_test::exec_succeeded(&p);
896 sset.process_queues();
898 assert(p.get_state() == service_state_t::STARTED);
899 assert(event_loop.active_timers.size() == 0);
904 sset.process_queues();
906 assert(p.get_state() == service_state_t::STOPPING);
908 // start tp (which waits-for p):
911 sset.process_queues();
913 assert(tp.get_state() == service_state_t::STARTING);
914 assert(p.get_state() == service_state_t::STOPPING);
916 base_process_service_test::handle_signal_exit(&p, SIGTERM);
917 sset.process_queues();
919 assert(tp.get_state() == service_state_t::STARTING);
920 assert(p.get_state() == service_state_t::STARTING);
922 base_process_service_test::exec_succeeded(&p);
923 sset.process_queues();
925 assert(tp.get_state() == service_state_t::STARTED);
926 assert(p.get_state() == service_state_t::STARTED);
928 sset.remove_service(&tp);
929 sset.remove_service(&p);
933 #define RUN_TEST(name, spacing) \
934 std::cout << #name "..." spacing << std::flush; \
936 std::cout << "PASSED" << std::endl;
938 int main(int argc, char **argv)
940 RUN_TEST(test_proc_service_start, " ");
941 RUN_TEST(test_proc_notify_start, " ");
942 RUN_TEST(test_proc_unexpected_term, " ");
943 RUN_TEST(test_proc_term_restart, " ");
944 RUN_TEST(test_term_via_stop, " ");
945 RUN_TEST(test_term_via_stop2, " ");
946 RUN_TEST(test_proc_start_timeout, " ");
947 RUN_TEST(test_proc_start_timeout2, " ");
948 RUN_TEST(test_proc_start_execfail, " ");
949 RUN_TEST(test_proc_notify_fail, " ");
950 RUN_TEST(test_proc_stop_timeout, " ");
951 RUN_TEST(test_proc_smooth_recovery1, "");
952 RUN_TEST(test_proc_smooth_recovery2, "");
953 RUN_TEST(test_scripted_stop_timeout, "");
954 RUN_TEST(test_scripted_start_fail, " ");
955 RUN_TEST(test_scripted_stop_fail, " ");
956 RUN_TEST(test_scripted_start_skip, " ");
957 RUN_TEST(test_scripted_start_skip2, " ");
958 RUN_TEST(test_waitsfor_restart, " ");