From: Davin McCall Date: Fri, 16 Nov 2018 18:30:41 +0000 (+0000) Subject: Tests: add test for readiness notification via pipe. X-Git-Tag: v0.5.0~24 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=29102a6ffafbfc90e7994f04bb99bb27ddf85227;p=oweals%2Fdinit.git Tests: add test for readiness notification via pipe. --- diff --git a/src/tests/proctests.cc b/src/tests/proctests.cc index 1f61cf2..c3d245c 100644 --- a/src/tests/proctests.cc +++ b/src/tests/proctests.cc @@ -44,6 +44,11 @@ class base_process_service_test bsp->pid = -1; bsp->handle_exit_status(bp_sys::exit_status(false, true, signo)); } + + static int get_notification_fd(base_process_service *bsp) + { + return bsp->notification_fd; + } }; namespace bp_sys { @@ -89,6 +94,49 @@ void test_proc_service_start() sset.remove_service(&p); } +// Test start with readiness notification +void test_proc_notify_start() +{ + using namespace std; + + service_set sset; + + string command = "test-command"; + list> command_offsets; + command_offsets.emplace_back(0, command.length()); + std::list depends; + + process_service p {&sset, "testproc", std::move(command), command_offsets, depends}; + init_service_defaults(p); + p.set_notification_fd(3); + sset.add_service(&p); + + p.start(true); + sset.process_queues(); + + assert(p.get_state() == service_state_t::STARTING); + + base_process_service_test::exec_succeeded(&p); + sset.process_queues(); + + assert(p.get_state() == service_state_t::STARTING); + + int nfd = base_process_service_test::get_notification_fd(&p); + assert(nfd > 0); + + char notifystr[] = "ok started\n"; + std::vector rnotifystr; + rnotifystr.insert(rnotifystr.end(), notifystr, notifystr + sizeof(notifystr)); + bp_sys::supply_read_data(nfd, std::move(rnotifystr)); + + event_loop.regd_fd_watchers[nfd]->fd_event(event_loop, nfd, dasynq::IN_EVENTS); + + assert(p.get_state() == service_state_t::STARTED); + assert(event_loop.active_timers.size() == 0); + + sset.remove_service(&p); +} + // Unexpected termination void test_proc_unexpected_term() { @@ -267,7 +315,8 @@ void test_proc_start_timeout2() init_service_defaults(p); sset.add_service(&p); - service_record ts {&sset, "test-service-1", service_type_t::INTERNAL, {{&p, dependency_type::WAITS_FOR}} }; + service_record ts {&sset, "test-service-1", service_type_t::INTERNAL, + {{&p, dependency_type::WAITS_FOR}} }; ts.start(true); sset.process_queues(); @@ -322,7 +371,6 @@ void test_proc_start_execfail() sset.remove_service(&p); } - // Test stop timeout void test_proc_stop_timeout() { @@ -535,7 +583,8 @@ void test_scripted_start_fail() sset.add_service(&p); service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{&p, REG}}); - service_record *s3 = new service_record(&sset, "test-service-3", service_type_t::INTERNAL, {{&p, REG}, {s2, REG}}); + service_record *s3 = new service_record(&sset, "test-service-3", + service_type_t::INTERNAL, {{&p, REG}, {s2, REG}}); sset.add_service(s2); sset.add_service(s3); @@ -581,8 +630,10 @@ void test_scripted_stop_fail() sset.add_service(&p); service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {}); - service_record *s3 = new service_record(&sset, "test-service-3", service_type_t::INTERNAL, {{s2, REG}, {&p, REG}}); - service_record *s4 = new service_record(&sset, "test-service-4", service_type_t::INTERNAL, {{&p, REG}, {s3, REG}}); + service_record *s3 = new service_record(&sset, "test-service-3", service_type_t::INTERNAL, + {{s2, REG}, {&p, REG}}); + service_record *s4 = new service_record(&sset, "test-service-4", service_type_t::INTERNAL, + {{&p, REG}, {s3, REG}}); sset.add_service(s2); sset.add_service(s3); sset.add_service(s4); @@ -795,6 +846,7 @@ void test_waitsfor_restart() int main(int argc, char **argv) { RUN_TEST(test_proc_service_start, " "); + RUN_TEST(test_proc_notify_start, " "); RUN_TEST(test_proc_unexpected_term, " "); RUN_TEST(test_term_via_stop, " "); RUN_TEST(test_term_via_stop2, " "); diff --git a/src/tests/test-includes/dinit.h b/src/tests/test-includes/dinit.h index 55bda59..14c1ee9 100644 --- a/src/tests/test-includes/dinit.h +++ b/src/tests/test-includes/dinit.h @@ -67,7 +67,12 @@ class eventloop_t public: void add_watch(eventloop_t &loop, int fd, int events, bool enable = true) { + if (loop.regd_fd_watchers.find(fd) != loop.regd_fd_watchers.end() + || loop.regd_bidi_watchers.find(fd) != loop.regd_bidi_watchers.end()) { + throw std::string("must not add_watch when already active"); + } watched_fd = fd; + loop.regd_fd_watchers[fd] = this; } int get_watched_fd() noexcept @@ -82,8 +87,11 @@ class eventloop_t void deregister(eventloop_t &loop) noexcept { - + loop.regd_fd_watchers.erase(watched_fd); + watched_fd = -1; } + + virtual rearm fd_event(eventloop_t & loop, int fd, int flags) = 0; }; template class fd_watcher_impl : public fd_watcher @@ -163,6 +171,7 @@ class eventloop_t std::unordered_set active_timers; std::map regd_bidi_watchers; + std::map regd_fd_watchers; }; inline void open_control_socket(bool report_ro_failure = true) noexcept