--- /dev/null
+#include "service.h"
+
+class test_service : public service_record
+{
+ public:
+ test_service(service_set *set, std::string name, service_type type_p, sr_list &&pdepends_on,
+ const sr_list &pdepends_soft)
+ : service_record(set, name, type_p, std::move(pdepends_on), pdepends_soft)
+ {
+
+ }
+
+ // Do any post-dependency startup; return false on failure
+ virtual bool start_ps_process() noexcept override
+ {
+ // return service_record::start_ps_process();
+ return true;
+ }
+
+ // All dependents have stopped.
+ virtual void all_deps_stopped() noexcept override
+ {
+ return service_record::all_deps_stopped();
+ }
+
+ // Whether a STARTING service can immediately transition to STOPPED (as opposed to
+ // having to wait for it reach STARTED and then go through STOPPING).
+ virtual bool can_interrupt_start() noexcept override
+ {
+ return waiting_for_deps;
+ }
+
+ virtual void interrupt_start() noexcept override
+ {
+
+ }
+
+ void started() noexcept
+ {
+ service_record::started();
+ }
+};
#include <iostream>
#include "service.h"
+#include "test_service.h"
// Test 1: starting a service starts dependencies; stopping the service releases and
// stops dependencies.
assert(s1->get_state() == service_state_t::STARTED);
}
+// Test 5: test that services which do not start immediately correctly chain start of
+// dependent services.
+void test5()
+{
+ service_set sset;
+
+ test_service *s1 = new test_service(&sset, "test-service-1", service_type::INTERNAL, {}, {});
+ test_service *s2 = new test_service(&sset, "test-service-2", service_type::INTERNAL, {s1}, {});
+ test_service *s3 = new test_service(&sset, "test-service-3", service_type::INTERNAL, {s2}, {});
+
+ sset.add_service(s1);
+ sset.add_service(s2);
+ sset.add_service(s3);
+
+ sset.start_service(s3);
+
+ // All three should transition to STARTING state:
+ assert(s3->get_state() == service_state_t::STARTING);
+ assert(s2->get_state() == service_state_t::STARTING);
+ assert(s1->get_state() == service_state_t::STARTING);
+
+ s1->started();
+ sset.process_queues();
+ assert(s3->get_state() == service_state_t::STARTING);
+ assert(s2->get_state() == service_state_t::STARTING);
+ assert(s1->get_state() == service_state_t::STARTED);
+
+ s2->started();
+ sset.process_queues();
+ assert(s3->get_state() == service_state_t::STARTING);
+ assert(s2->get_state() == service_state_t::STARTED);
+ assert(s1->get_state() == service_state_t::STARTED);
+
+ s3->started();
+ sset.process_queues();
+ assert(s3->get_state() == service_state_t::STARTED);
+ assert(s2->get_state() == service_state_t::STARTED);
+ assert(s1->get_state() == service_state_t::STARTED);
+}
+
int main(int argc, char **argv)
{
std::cout << "test1... ";
std::cout << "test4... ";
test4();
std::cout << "PASSED" << std::endl;
+
+ std::cout << "test5... ";
+ test5();
+ std::cout << "PASSED" << std::endl;
}