Fix: stop milestone dependency before started.
authorDavin McCall <davmac@davmac.org>
Wed, 28 Feb 2018 12:08:37 +0000 (12:08 +0000)
committerDavin McCall <davmac@davmac.org>
Wed, 28 Feb 2018 12:09:31 +0000 (12:09 +0000)
Stopping a milestone dependency before its dependent has started must
also stop the dependent (the "milestone" hasn't been reached).

Add a test.

src/service.cc
src/tests/tests.cc

index 1abe899f9068a66414bb557e992136197640f961..5195c56599c8248d0db07f695a36cc839c54a2af 100644 (file)
@@ -517,7 +517,9 @@ bool service_record::stop_dependents() noexcept
 {
     bool all_deps_stopped = true;
     for (auto dept : dependents) {
-        if (dept->dep_type == dependency_type::REGULAR) {
+        if (dept->dep_type == dependency_type::REGULAR ||
+                (dept->dep_type == dependency_type::MILESTONE &&
+                dept->get_from()->service_state != service_state_t::STARTED)) {
             if (! dept->get_from()->is_stopped()) {
                 // Note we check *first* since if the dependent service is not stopped,
                 // 1. We will issue a stop to it shortly and
index 8e7cbfcc025ea131ace9449f667b23a77afe4c5d..115535def434ce48b73220818cc09f165ca99f20 100644 (file)
@@ -479,6 +479,37 @@ void test10()
     assert(! sset.is_queued_for_console(s2));
 }
 
+// Test 11: if a milestone dependency doesn't start, dependent doesn't start.
+void test11()
+{
+    service_set sset;
+
+    test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
+    service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, MS}});
+
+    sset.add_service(s1);
+    sset.add_service(s2);
+
+    assert(sset.find_service("test-service-1") == s1);
+    assert(sset.find_service("test-service-2") == s2);
+
+    // Request start of the s2 service:
+    sset.start_service(s2);
+    sset.process_queues();
+
+    assert(s1->get_state() == service_state_t::STARTING);
+    assert(s2->get_state() == service_state_t::STARTING);
+
+    s1->stop();
+    sset.process_queues();
+    s1->bring_down();
+    sset.process_queues();
+
+    assert(s1->get_state() == service_state_t::STOPPED);
+    assert(s2->get_state() == service_state_t::STOPPED);
+}
+
+
 #define RUN_TEST(name) \
     std::cout << #name "... "; \
     name(); \
@@ -499,4 +530,5 @@ int main(int argc, char **argv)
     RUN_TEST(test8);
     RUN_TEST(test9);
     RUN_TEST(test10);
+    RUN_TEST(test11);
 }