tests.cc 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905
  1. #include <iostream>
  2. #include <cerrno>
  3. #include <cassert>
  4. #include "service.h"
  5. #include "test_service.h"
  6. #include "baseproc-sys.h"
  7. constexpr static auto REG = dependency_type::REGULAR;
  8. constexpr static auto WAITS = dependency_type::WAITS_FOR;
  9. constexpr static auto MS = dependency_type::MILESTONE;
  10. constexpr static auto BEFORE = dependency_type::BEFORE;
  11. constexpr static auto AFTER = dependency_type::AFTER;
  12. class test_listener : public service_listener
  13. {
  14. public:
  15. bool got_started = false;
  16. bool got_stopped = false;
  17. bool start_cancelled = false;
  18. bool stop_cancelled = false;
  19. void service_event(service_record * service, service_event_t event) noexcept override
  20. {
  21. switch (event) {
  22. case service_event_t::STARTED:
  23. got_started = true;
  24. break;
  25. case service_event_t::STOPPED:
  26. got_stopped = true;
  27. break;
  28. case service_event_t::STARTCANCELLED:
  29. start_cancelled = true;
  30. break;
  31. case service_event_t::STOPCANCELLED:
  32. stop_cancelled = true;
  33. break;
  34. case service_event_t::FAILEDSTART:
  35. break;
  36. }
  37. }
  38. };
  39. // Starting a service starts dependencies; stopping the service releases and
  40. // stops dependencies.
  41. void basic_test1()
  42. {
  43. service_set sset;
  44. service_record *s1 = new service_record(&sset, "test-service-1", service_type_t::INTERNAL, {});
  45. service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, REG}});
  46. service_record *s3 = new service_record(&sset, "test-service-3", service_type_t::INTERNAL, {{s2, REG}});
  47. sset.add_service(s1);
  48. sset.add_service(s2);
  49. sset.add_service(s3);
  50. assert(sset.find_service("test-service-1") == s1);
  51. assert(sset.find_service("test-service-2") == s2);
  52. assert(sset.find_service("test-service-3") == s3);
  53. // s3 depends on s2, which depends on s1. So starting s3 should start all three services:
  54. sset.start_service(s3);
  55. assert(s1->get_state() == service_state_t::STARTED);
  56. assert(s2->get_state() == service_state_t::STARTED);
  57. assert(s3->get_state() == service_state_t::STARTED);
  58. // stopping s3 should release the other two services:
  59. sset.stop_service(s3);
  60. assert(s3->get_state() == service_state_t::STOPPED);
  61. assert(s2->get_state() == service_state_t::STOPPED);
  62. assert(s1->get_state() == service_state_t::STOPPED);
  63. assert(sset.count_active_services() == 0);
  64. }
  65. // Multiple dependents will hold a dependency active if one of the dependents is
  66. // stopped/released.
  67. void basic_test2()
  68. {
  69. service_set sset;
  70. service_record *s1 = new service_record(&sset, "test-service-1", service_type_t::INTERNAL, {});
  71. service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, REG}});
  72. service_record *s3 = new service_record(&sset, "test-service-3", service_type_t::INTERNAL, {{s2, REG}});
  73. service_record *s4 = new service_record(&sset, "test-service-4", service_type_t::INTERNAL, {{s2, REG}});
  74. sset.add_service(s1);
  75. sset.add_service(s2);
  76. sset.add_service(s3);
  77. sset.add_service(s4);
  78. // s3 depends on s2, which depends on s1. Similarly with s4. After starting both, all services
  79. // should be started:
  80. sset.start_service(s3);
  81. sset.start_service(s4);
  82. assert(s1->get_state() == service_state_t::STARTED);
  83. assert(s2->get_state() == service_state_t::STARTED);
  84. assert(s3->get_state() == service_state_t::STARTED);
  85. assert(s4->get_state() == service_state_t::STARTED);
  86. // after stopping s3, s4 should hold the other two services:
  87. sset.stop_service(s3);
  88. assert(s4->get_state() == service_state_t::STARTED);
  89. assert(s3->get_state() == service_state_t::STOPPED);
  90. assert(s2->get_state() == service_state_t::STARTED);
  91. assert(s1->get_state() == service_state_t::STARTED);
  92. // Now if we stop s4, s2 and s1 should also be released:
  93. sset.stop_service(s4);
  94. assert(s4->get_state() == service_state_t::STOPPED);
  95. assert(s3->get_state() == service_state_t::STOPPED);
  96. assert(s2->get_state() == service_state_t::STOPPED);
  97. assert(s1->get_state() == service_state_t::STOPPED);
  98. assert(sset.count_active_services() == 0);
  99. }
  100. // Stopping a dependency causes its dependents to stop.
  101. void basic_test3()
  102. {
  103. service_set sset;
  104. service_record *s1 = new service_record(&sset, "test-service-1", service_type_t::INTERNAL, {});
  105. service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, REG}});
  106. service_record *s3 = new service_record(&sset, "test-service-3", service_type_t::INTERNAL, {{s2, REG}});
  107. sset.add_service(s1);
  108. sset.add_service(s2);
  109. sset.add_service(s3);
  110. assert(sset.find_service("test-service-1") == s1);
  111. assert(sset.find_service("test-service-2") == s2);
  112. assert(sset.find_service("test-service-3") == s3);
  113. // Start all three services:
  114. sset.start_service(s3);
  115. // Now stop s1, which should also force s2 and s3 to stop:
  116. sset.stop_service(s1);
  117. assert(s3->get_state() == service_state_t::STOPPED);
  118. assert(s2->get_state() == service_state_t::STOPPED);
  119. assert(s1->get_state() == service_state_t::STOPPED);
  120. assert(sset.count_active_services() == 0);
  121. }
  122. // An explicitly activated service with automatic restart will restart if it
  123. // stops due to a dependency stopping, therefore also causing the dependency to restart.
  124. void basic_test4()
  125. {
  126. service_set sset;
  127. test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
  128. service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, REG}});
  129. service_record *s3 = new service_record(&sset, "test-service-3", service_type_t::INTERNAL, {{s2, REG}});
  130. s2->set_auto_restart(true);
  131. sset.add_service(s1);
  132. sset.add_service(s2);
  133. sset.add_service(s3);
  134. assert(sset.find_service("test-service-1") == s1);
  135. assert(sset.find_service("test-service-2") == s2);
  136. assert(sset.find_service("test-service-3") == s3);
  137. // Start all three services:
  138. sset.start_service(s3);
  139. // Also explicitly activate s2:
  140. sset.start_service(s2);
  141. s1->started();
  142. sset.process_queues();
  143. assert(s3->get_state() == service_state_t::STARTED);
  144. assert(s2->get_state() == service_state_t::STARTED);
  145. assert(s1->get_state() == service_state_t::STARTED);
  146. // Now stop s1, which should also force s2 and s3 to stop.
  147. // s2 (and therefore s1) should restart:
  148. s1->forced_stop();
  149. sset.process_queues();
  150. assert(s3->get_state() == service_state_t::STOPPED);
  151. assert(s2->get_state() == service_state_t::STARTING);
  152. assert(s1->get_state() == service_state_t::STARTING);
  153. s1->started();
  154. sset.process_queues();
  155. assert(s3->get_state() == service_state_t::STOPPED);
  156. assert(s2->get_state() == service_state_t::STARTED);
  157. assert(s1->get_state() == service_state_t::STARTED);
  158. assert(sset.count_active_services() == 2);
  159. }
  160. // Test that services which do not start immediately correctly chain start of
  161. // dependent services.
  162. void basic_test5()
  163. {
  164. service_set sset;
  165. test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
  166. test_service *s2 = new test_service(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, REG}});
  167. test_service *s3 = new test_service(&sset, "test-service-3", service_type_t::INTERNAL, {{s2, REG}});
  168. sset.add_service(s1);
  169. sset.add_service(s2);
  170. sset.add_service(s3);
  171. sset.start_service(s3);
  172. // All three should transition to STARTING state:
  173. assert(s3->get_state() == service_state_t::STARTING);
  174. assert(s2->get_state() == service_state_t::STARTING);
  175. assert(s1->get_state() == service_state_t::STARTING);
  176. s1->started();
  177. sset.process_queues();
  178. assert(s3->get_state() == service_state_t::STARTING);
  179. assert(s2->get_state() == service_state_t::STARTING);
  180. assert(s1->get_state() == service_state_t::STARTED);
  181. s2->started();
  182. sset.process_queues();
  183. assert(s3->get_state() == service_state_t::STARTING);
  184. assert(s2->get_state() == service_state_t::STARTED);
  185. assert(s1->get_state() == service_state_t::STARTED);
  186. s3->started();
  187. sset.process_queues();
  188. assert(s3->get_state() == service_state_t::STARTED);
  189. assert(s2->get_state() == service_state_t::STARTED);
  190. assert(s1->get_state() == service_state_t::STARTED);
  191. assert(sset.count_active_services() == 3);
  192. }
  193. // Test that issuing a stop-without-bring-down to a service that is held up by a dependent does not
  194. // cause the service to stop.
  195. void basic_test6()
  196. {
  197. service_set sset;
  198. test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
  199. test_service *s2 = new test_service(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, REG}});
  200. test_service *s3 = new test_service(&sset, "test-service-3", service_type_t::INTERNAL, {{s2, REG}});
  201. sset.add_service(s1);
  202. sset.add_service(s2);
  203. sset.add_service(s3);
  204. sset.start_service(s3);
  205. // All three should transition to STARTING state:
  206. assert(s3->get_state() == service_state_t::STARTING);
  207. s1->started();
  208. sset.process_queues();
  209. assert(s2->get_state() == service_state_t::STARTING);
  210. s2->started();
  211. sset.process_queues();
  212. assert(s3->get_state() == service_state_t::STARTING);
  213. s3->started();
  214. sset.process_queues();
  215. assert(s3->get_state() == service_state_t::STARTED);
  216. assert(s2->get_state() == service_state_t::STARTED);
  217. assert(s1->get_state() == service_state_t::STARTED);
  218. assert(s3->get_target_state() == service_state_t::STARTED);
  219. assert(s2->get_target_state() == service_state_t::STARTED);
  220. assert(s1->get_target_state() == service_state_t::STARTED);
  221. // Mark s2 active (it's already started):
  222. s2->start();
  223. sset.process_queues();
  224. // Issue stop, *without* bring-down, to s1 and s2.
  225. s1->stop(false);
  226. sset.process_queues();
  227. assert(s1->get_state() == service_state_t::STARTED);
  228. s2->stop(false);
  229. sset.process_queues();
  230. assert(s2->get_state() == service_state_t::STARTED);
  231. assert(s3->get_target_state() == service_state_t::STARTED);
  232. assert(s2->get_target_state() == service_state_t::STARTED);
  233. assert(s1->get_target_state() == service_state_t::STARTED);
  234. assert(s3->get_state() == service_state_t::STARTED);
  235. assert(s2->get_state() == service_state_t::STARTED);
  236. assert(s1->get_state() == service_state_t::STARTED);
  237. assert(sset.count_active_services() == 3);
  238. }
  239. // An explicitly activated service with automatic restart will not restart if it
  240. // stops due to a dependency stopping from a manual stop (which inhibits restart).
  241. void basic_test7()
  242. {
  243. service_set sset;
  244. service_record *s1 = new service_record(&sset, "test-service-1", service_type_t::INTERNAL, {});
  245. service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, REG}});
  246. service_record *s3 = new service_record(&sset, "test-service-3", service_type_t::INTERNAL, {{s2, REG}});
  247. s2->set_auto_restart(true);
  248. sset.add_service(s1);
  249. sset.add_service(s2);
  250. sset.add_service(s3);
  251. assert(sset.find_service("test-service-1") == s1);
  252. assert(sset.find_service("test-service-2") == s2);
  253. assert(sset.find_service("test-service-3") == s3);
  254. // Start all three services:
  255. sset.start_service(s3);
  256. // Also explicitly activate s2:
  257. sset.start_service(s2);
  258. assert(s3->get_state() == service_state_t::STARTED);
  259. assert(s2->get_state() == service_state_t::STARTED);
  260. assert(s1->get_state() == service_state_t::STARTED);
  261. // Now stop s1, which should also force s2 and s3 to stop.
  262. // s2 should not restart, since this was an explicit forced stop which
  263. // inhibits restart, and so s1 should also remain stopped.
  264. sset.stop_service(s1);
  265. assert(s3->get_state() == service_state_t::STOPPED);
  266. assert(s2->get_state() == service_state_t::STOPPED);
  267. assert(s1->get_state() == service_state_t::STOPPED);
  268. assert(sset.count_active_services() == 0);
  269. }
  270. // A dependent service which stops due to a dependency should have target state STOPPED
  271. // if it won't restart.
  272. void basic_test8()
  273. {
  274. service_set sset;
  275. test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
  276. test_service *s2 = new test_service(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, REG}});
  277. test_service *s3 = new test_service(&sset, "test-service-3", service_type_t::INTERNAL, {{s2, REG}});
  278. s2->auto_stop = false;
  279. s3->auto_stop = false;
  280. sset.add_service(s1);
  281. sset.add_service(s2);
  282. sset.add_service(s3);
  283. assert(sset.find_service("test-service-1") == s1);
  284. assert(sset.find_service("test-service-2") == s2);
  285. assert(sset.find_service("test-service-3") == s3);
  286. // Start all three services:
  287. sset.start_service(s3);
  288. // Also explicitly activate s2:
  289. sset.start_service(s2);
  290. s1->started();
  291. sset.process_queues();
  292. s2->started();
  293. sset.process_queues();
  294. s3->started();
  295. sset.process_queues();
  296. assert(s3->get_state() == service_state_t::STARTED);
  297. assert(s2->get_state() == service_state_t::STARTED);
  298. assert(s1->get_state() == service_state_t::STARTED);
  299. // Now stop s1, which should also force s2 and s3 to stop.
  300. // s2 (and therefore s1) should restart:
  301. s1->forced_stop();
  302. sset.process_queues();
  303. assert(s3->get_state() == service_state_t::STOPPING);
  304. assert(s2->get_state() == service_state_t::STOPPING);
  305. assert(s1->get_state() == service_state_t::STOPPING);
  306. assert(s3->get_target_state() == service_state_t::STOPPED);
  307. assert(s2->get_target_state() == service_state_t::STOPPED);
  308. s3->stopped();
  309. sset.process_queues();
  310. s2->stopped();
  311. sset.process_queues();
  312. assert(s3->get_state() == service_state_t::STOPPED);
  313. assert(s2->get_state() == service_state_t::STOPPED);
  314. assert(s1->get_state() == service_state_t::STOPPED);
  315. assert(sset.count_active_services() == 0);
  316. }
  317. // A hard dependent service which restarts due to a requested dependency restart should restart,
  318. // a soft dependent service should be left untouched.
  319. void basic_test9()
  320. {
  321. service_set sset;
  322. test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
  323. test_service *s2 = new test_service(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, REG}});
  324. test_service *s3 = new test_service(&sset, "test-service-3", service_type_t::INTERNAL, {{s2, REG}});
  325. test_service *s4 = new test_service(&sset, "test-service-4", service_type_t::INTERNAL, {{s1, MS}});
  326. sset.add_service(s1);
  327. sset.add_service(s2);
  328. sset.add_service(s3);
  329. sset.add_service(s4);
  330. assert(sset.find_service("test-service-1") == s1);
  331. assert(sset.find_service("test-service-2") == s2);
  332. assert(sset.find_service("test-service-3") == s3);
  333. assert(sset.find_service("test-service-4") == s4);
  334. // Start all four services:
  335. sset.start_service(s3);
  336. sset.start_service(s4);
  337. s1->started();
  338. sset.process_queues();
  339. s2->started();
  340. sset.process_queues();
  341. s3->started();
  342. sset.process_queues();
  343. s4->started();
  344. sset.process_queues();
  345. assert(s4->get_state() == service_state_t::STARTED);
  346. assert(s3->get_state() == service_state_t::STARTED);
  347. assert(s2->get_state() == service_state_t::STARTED);
  348. assert(s1->get_state() == service_state_t::STARTED);
  349. // Now restart s1, which should also force s2 and s3 to restart.
  350. // s2 (and therefore s1) should restart:
  351. s1->restart();
  352. sset.process_queues();
  353. // s4 only has a milestone dependency, and should be left untouched.
  354. assert(s4->get_state() == service_state_t::STARTED);
  355. assert(s3->get_state() == service_state_t::STARTING);
  356. assert(s2->get_state() == service_state_t::STARTING);
  357. assert(s1->get_state() == service_state_t::STARTING);
  358. assert(s4->get_target_state() == service_state_t::STARTED);
  359. assert(s3->get_target_state() == service_state_t::STARTED);
  360. assert(s2->get_target_state() == service_state_t::STARTED);
  361. assert(s1->get_target_state() == service_state_t::STARTED);
  362. s1->started();
  363. sset.process_queues();
  364. s2->started();
  365. sset.process_queues();
  366. s3->started();
  367. sset.process_queues();
  368. assert(s4->get_state() == service_state_t::STARTED);
  369. assert(s3->get_state() == service_state_t::STARTED);
  370. assert(s2->get_state() == service_state_t::STARTED);
  371. assert(s1->get_state() == service_state_t::STARTED);
  372. assert(sset.count_active_services() == 4);
  373. }
  374. // Test services stop in reverse dependency order
  375. void basic_test10()
  376. {
  377. service_set sset;
  378. test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
  379. test_service *s2 = new test_service(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, REG}});
  380. s2->auto_stop = false;
  381. sset.add_service(s1);
  382. sset.add_service(s2);
  383. assert(sset.find_service("test-service-1") == s1);
  384. assert(sset.find_service("test-service-2") == s2);
  385. // Start two services:
  386. sset.start_service(s2);
  387. s1->started();
  388. sset.process_queues();
  389. s2->started();
  390. sset.process_queues();
  391. assert(s2->get_state() == service_state_t::STARTED);
  392. assert(s1->get_state() == service_state_t::STARTED);
  393. // Issue stop (without forced bring down) to both s1 and s2:
  394. s1->stop(false);
  395. s2->stop(false);
  396. sset.process_queues();
  397. assert(s1->get_state() == service_state_t::STOPPING);
  398. assert(s2->get_state() == service_state_t::STOPPING);
  399. s2->stopped();
  400. sset.process_queues();
  401. assert(s1->get_state() == service_state_t::STOPPED);
  402. assert(s2->get_state() == service_state_t::STOPPED);
  403. assert(sset.count_active_services() == 0);
  404. }
  405. // Test that service pinned in start state is not stopped when its dependency stops.
  406. void test_pin1()
  407. {
  408. service_set sset;
  409. service_record *s1 = new service_record(&sset, "test-service-1", service_type_t::INTERNAL, {});
  410. service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, REG}});
  411. service_record *s3 = new service_record(&sset, "test-service-3", service_type_t::INTERNAL, {{s2, REG}});
  412. s2->set_auto_restart(true);
  413. sset.add_service(s1);
  414. sset.add_service(s2);
  415. sset.add_service(s3);
  416. // Pin s3:
  417. s3->pin_start();
  418. // Start all three services:
  419. sset.start_service(s3);
  420. assert(s3->get_state() == service_state_t::STARTED);
  421. assert(s2->get_state() == service_state_t::STARTED);
  422. assert(s1->get_state() == service_state_t::STARTED);
  423. // Stop s2:
  424. s2->forced_stop();
  425. s2->stop(true);
  426. sset.process_queues();
  427. // s3 should remain started due to pin:
  428. assert(s3->get_state() == service_state_t::STARTED);
  429. assert(s2->get_state() == service_state_t::STARTED);
  430. assert(s1->get_state() == service_state_t::STARTED);
  431. // If we now unpin, s3 should stop:
  432. s3->unpin();
  433. sset.process_queues();
  434. assert(s3->get_state() == service_state_t::STOPPED);
  435. assert(s2->get_state() == service_state_t::STOPPED);
  436. assert(s1->get_state() == service_state_t::STOPPED);
  437. assert(sset.count_active_services() == 0);
  438. }
  439. // Test that issuing a stop to a pinned-started service does not stop the service or its dependencies.
  440. void test_pin2()
  441. {
  442. service_set sset;
  443. service_record *s1 = new service_record(&sset, "test-service-1", service_type_t::INTERNAL, {});
  444. service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, REG}});
  445. service_record *s3 = new service_record(&sset, "test-service-3", service_type_t::INTERNAL, {{s2, REG}});
  446. s2->set_auto_restart(true);
  447. sset.add_service(s1);
  448. sset.add_service(s2);
  449. sset.add_service(s3);
  450. // Pin s3:
  451. s3->pin_start();
  452. // Start all three services:
  453. sset.start_service(s3);
  454. assert(s3->get_state() == service_state_t::STARTED);
  455. assert(s2->get_state() == service_state_t::STARTED);
  456. assert(s1->get_state() == service_state_t::STARTED);
  457. // Issue stop to s3:
  458. s3->stop(true);
  459. sset.process_queues();
  460. // s3 should remain started due to pin, s1 and s2 not released:
  461. assert(s3->get_state() == service_state_t::STARTED);
  462. assert(s2->get_state() == service_state_t::STARTED);
  463. assert(s1->get_state() == service_state_t::STARTED);
  464. assert(sset.count_active_services() == 3);
  465. }
  466. // Test that a STOPPING dependency of a pinned service stops when pin is released, even if pinned
  467. // service is activated:
  468. void test_pin3()
  469. {
  470. service_set sset;
  471. service_record *s1 = new service_record(&sset, "test-service-1", service_type_t::INTERNAL, {});
  472. service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, REG}});
  473. service_record *s3 = new service_record(&sset, "test-service-3", service_type_t::INTERNAL, {{s2, REG}});
  474. s2->set_auto_restart(true);
  475. sset.add_service(s1);
  476. sset.add_service(s2);
  477. sset.add_service(s3);
  478. // Pin s3:
  479. s3->pin_start();
  480. // Start all three services:
  481. sset.start_service(s3);
  482. assert(s3->get_state() == service_state_t::STARTED);
  483. assert(s2->get_state() == service_state_t::STARTED);
  484. assert(s1->get_state() == service_state_t::STARTED);
  485. // Issue force stop to s2:
  486. s2->stop(true);
  487. s2->forced_stop();
  488. sset.process_queues();
  489. // s3 should remain started due to pin, but s2 should now be STOPPING:
  490. assert(s3->get_state() == service_state_t::STARTED);
  491. assert(s2->get_state() == service_state_t::STARTED);
  492. assert(s1->get_state() == service_state_t::STARTED);
  493. // If we now issue start, s2 still needs to stop (due to force stop); this shouldn't happen until
  494. // it's unpinned.
  495. s3->start();
  496. sset.process_queues();
  497. assert(s3->get_state() == service_state_t::STARTED);
  498. assert(s2->get_state() == service_state_t::STARTED);
  499. assert(s1->get_state() == service_state_t::STARTED);
  500. // When we unpin, s2 should STOP; s3 must stop as a result; s1 is released and so also stops:
  501. s3->unpin();
  502. sset.process_queues();
  503. assert(s3->get_state() == service_state_t::STOPPED);
  504. assert(s2->get_state() == service_state_t::STOPPED);
  505. assert(s1->get_state() == service_state_t::STOPPED);
  506. assert(sset.count_active_services() == 0);
  507. }
  508. // Test that service pinned started is released when stop issued and stops when unpinned
  509. void test_pin4()
  510. {
  511. service_set sset;
  512. service_record *s1 = new service_record(&sset, "test-service-1", service_type_t::INTERNAL, {});
  513. sset.add_service(s1);
  514. // Pin s1:
  515. s1->pin_start();
  516. // Start the service:
  517. sset.start_service(s1);
  518. assert(s1->get_state() == service_state_t::STARTED);
  519. // Issue forced stop:
  520. s1->stop(true);
  521. s1->forced_stop();
  522. sset.process_queues();
  523. // s1 should remain started:
  524. assert(s1->get_state() == service_state_t::STARTED);
  525. // If we now unpin, s1 should stop:
  526. s1->unpin();
  527. sset.process_queues();
  528. assert(s1->get_state() == service_state_t::STOPPED);
  529. assert(sset.count_active_services() == 0);
  530. }
  531. // Test that a pinned-started service doesn't stop when released by a dependent
  532. void test_pin5()
  533. {
  534. service_set sset;
  535. service_record *s1 = new service_record(&sset, "test-service-1", service_type_t::INTERNAL, {});
  536. service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, REG}});
  537. service_record *s3 = new service_record(&sset, "test-service-3", service_type_t::INTERNAL, {{s2, REG}});
  538. sset.add_service(s1);
  539. sset.add_service(s2);
  540. sset.add_service(s3);
  541. // Pin s2:
  542. s2->pin_start();
  543. // Start all three services:
  544. sset.start_service(s3);
  545. assert(s3->get_state() == service_state_t::STARTED);
  546. assert(s2->get_state() == service_state_t::STARTED);
  547. assert(s1->get_state() == service_state_t::STARTED);
  548. // Issue stop to s3:
  549. s3->stop(true);
  550. sset.process_queues();
  551. // s2 should remain started due to pin (and s1 via dependency), s3 should stop
  552. assert(s3->get_state() == service_state_t::STOPPED);
  553. assert(s2->get_state() == service_state_t::STARTED);
  554. assert(s1->get_state() == service_state_t::STARTED);
  555. // If we unpin s2, it should stop:
  556. s2->unpin();
  557. sset.process_queues();
  558. assert(s3->get_state() == service_state_t::STOPPED);
  559. assert(s2->get_state() == service_state_t::STOPPED);
  560. assert(s1->get_state() == service_state_t::STOPPED);
  561. assert(sset.count_active_services() == 0);
  562. }
  563. // Test that unpinning a service has no effect on soft dependencies
  564. void test_pin6()
  565. {
  566. service_set sset;
  567. service_record *s1 = new service_record(&sset, "test-service-1", service_type_t::INTERNAL, {});
  568. service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, WAITS}});
  569. sset.add_service(s1);
  570. sset.add_service(s2);
  571. // Pin s2:
  572. s2->pin_start();
  573. // Start both three services:
  574. sset.start_service(s2);
  575. assert(s2->get_state() == service_state_t::STARTED);
  576. assert(s1->get_state() == service_state_t::STARTED);
  577. // Unpin:
  578. s2->unpin();
  579. assert(s2->get_state() == service_state_t::STARTED);
  580. assert(s1->get_state() == service_state_t::STARTED);
  581. assert(sset.count_active_services() == 2);
  582. }
  583. // Test that service pinned stopped does not start when unpinned (does not get marked active)
  584. void test_pin7()
  585. {
  586. service_set sset;
  587. service_record *s1 = new service_record(&sset, "test-service-1", service_type_t::INTERNAL, {});
  588. sset.add_service(s1);
  589. // Pin stopped:
  590. s1->pin_stop();
  591. // Request service start:
  592. sset.start_service(s1);
  593. assert(s1->get_state() == service_state_t::STOPPED);
  594. // Unpin:
  595. s1->unpin();
  596. // Service should remain stopped
  597. assert(s1->get_state() == service_state_t::STOPPED);
  598. assert(sset.count_active_services() == 0);
  599. }
  600. // Test that dependents of a pinned-started service are unaffected by a transitive stop issued to the
  601. // pinned service
  602. void test_pin8()
  603. {
  604. service_set sset;
  605. service_record *s1 = new service_record(&sset, "test-service-1", service_type_t::INTERNAL, {});
  606. service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, REG}});
  607. service_record *s3 = new service_record(&sset, "test-service-3", service_type_t::INTERNAL, {{s2, REG}});
  608. sset.add_service(s1);
  609. sset.add_service(s2);
  610. sset.add_service(s3);
  611. // Pin s3:
  612. s2->pin_start();
  613. // Start all three services:
  614. sset.start_service(s3);
  615. assert(s3->get_state() == service_state_t::STARTED);
  616. assert(s2->get_state() == service_state_t::STARTED);
  617. assert(s1->get_state() == service_state_t::STARTED);
  618. // Issue stop to s1, will be ignored
  619. s1->stop(true);
  620. sset.process_queues();
  621. // s2 should remain started due to pin, s1 stopping, s3 remains started:
  622. assert(s3->get_state() == service_state_t::STARTED);
  623. assert(s2->get_state() == service_state_t::STARTED);
  624. assert(s1->get_state() == service_state_t::STARTED);
  625. assert(sset.count_active_services() == 3);
  626. }
  627. // test that a pinned-stopped service is not started via a soft dependency once unpinned
  628. void test_pin9()
  629. {
  630. service_set sset;
  631. service_record *s1 = new service_record(&sset, "test-service-1", service_type_t::INTERNAL, {});
  632. service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, WAITS}});
  633. sset.add_service(s1);
  634. sset.add_service(s2);
  635. // Pin s1:
  636. s1->pin_stop();
  637. // Start s2:
  638. sset.start_service(s2);
  639. assert(s2->get_state() == service_state_t::STARTED);
  640. assert(s1->get_state() == service_state_t::STOPPED);
  641. // release pin, service should not start:
  642. s1->unpin();
  643. // s2 should remain started, s1 should remain stopped:
  644. assert(s2->get_state() == service_state_t::STARTED);
  645. assert(s1->get_state() == service_state_t::STOPPED);
  646. assert(sset.count_active_services() == 1);
  647. }
  648. // test that starting a service with a stop-pinned dependency fails
  649. void test_pin10()
  650. {
  651. service_set sset;
  652. service_record *s1 = new service_record(&sset, "test-service-1", service_type_t::INTERNAL, {});
  653. service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, REG}});
  654. service_record *s3 = new service_record(&sset, "test-service-3", service_type_t::INTERNAL, {{s2, REG}});
  655. s2->set_auto_restart(true);
  656. sset.add_service(s1);
  657. sset.add_service(s2);
  658. sset.add_service(s3);
  659. // Pin-stop s2:
  660. s2->pin_stop();
  661. // Try to start all three services:
  662. sset.start_service(s3);
  663. // Start of s3 should fail due to s2
  664. assert(s3->get_state() == service_state_t::STOPPED);
  665. assert(s2->get_state() == service_state_t::STOPPED);
  666. assert(s1->get_state() == service_state_t::STOPPED);
  667. assert(sset.count_active_services() == 0);
  668. }
  669. // Stopping a soft dependency doesn't cause the dependent to stop.
  670. void test_softdep1()
  671. {
  672. service_set sset;
  673. service_record *s1 = new service_record(&sset, "test-service-1", service_type_t::INTERNAL, {});
  674. service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, REG}});
  675. service_record *s3 = new service_record(&sset, "test-service-3", service_type_t::INTERNAL, {{s2, WAITS}});
  676. sset.add_service(s1);
  677. sset.add_service(s2);
  678. sset.add_service(s3);
  679. assert(sset.find_service("test-service-1") == s1);
  680. assert(sset.find_service("test-service-2") == s2);
  681. assert(sset.find_service("test-service-3") == s3);
  682. // Start all three services:
  683. sset.start_service(s3);
  684. // Now stop s1, which should also force s2 but not s3 to stop:
  685. sset.stop_service(s1);
  686. assert(s3->get_state() == service_state_t::STARTED);
  687. assert(s2->get_state() == service_state_t::STOPPED);
  688. assert(s1->get_state() == service_state_t::STOPPED);
  689. assert(sset.count_active_services() == 1);
  690. }
  691. // Stopping a milestone dependency doesn't cause the dependent to stop
  692. void test_softdep2()
  693. {
  694. service_set sset;
  695. service_record *s1 = new service_record(&sset, "test-service-1", service_type_t::INTERNAL, {});
  696. service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, MS}});
  697. sset.add_service(s1);
  698. sset.add_service(s2);
  699. assert(sset.find_service("test-service-1") == s1);
  700. assert(sset.find_service("test-service-2") == s2);
  701. // Start the services:
  702. sset.start_service(s2);
  703. assert(s2->get_state() == service_state_t::STARTED);
  704. assert(s1->get_state() == service_state_t::STARTED);
  705. // Now stop s1, which should not stop s2:
  706. sset.stop_service(s1);
  707. assert(s2->get_state() == service_state_t::STARTED);
  708. assert(s1->get_state() == service_state_t::STOPPED);
  709. assert(sset.count_active_services() == 1);
  710. }
  711. // A failing milestone dependency causes the dependent to fail
  712. void test_softdep3()
  713. {
  714. service_set sset;
  715. test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
  716. test_service *s2 = new test_service(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, MS}});
  717. sset.add_service(s1);
  718. sset.add_service(s2);
  719. assert(sset.find_service("test-service-1") == s1);
  720. assert(sset.find_service("test-service-2") == s2);
  721. // Start the services, but fail s1:
  722. sset.start_service(s2);
  723. assert(s1->get_state() == service_state_t::STARTING);
  724. s1->failed_to_start();
  725. sset.process_queues();
  726. assert(s1->get_state() == service_state_t::STOPPED);
  727. assert(s2->get_state() == service_state_t::STOPPED);
  728. assert(sset.count_active_services() == 0);
  729. }
  730. // If a milestone dependency start is cancelled, dependent doesn't start.
  731. void test_softdep4()
  732. {
  733. service_set sset;
  734. test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
  735. service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, MS}});
  736. sset.add_service(s1);
  737. sset.add_service(s2);
  738. assert(sset.find_service("test-service-1") == s1);
  739. assert(sset.find_service("test-service-2") == s2);
  740. // Request start of the s2 service:
  741. sset.start_service(s2);
  742. sset.process_queues();
  743. assert(s1->get_state() == service_state_t::STARTING);
  744. assert(s2->get_state() == service_state_t::STARTING);
  745. s1->stop();
  746. sset.process_queues();
  747. s1->bring_down();
  748. sset.process_queues();
  749. assert(s1->get_state() == service_state_t::STOPPED);
  750. assert(s2->get_state() == service_state_t::STOPPED);
  751. assert(sset.count_active_services() == 0);
  752. }
  753. // Test that soft dependents of a service reattach when service starts
  754. void test_softdep5()
  755. {
  756. service_set sset;
  757. service_record *s1 = new service_record(&sset, "test-service-1", service_type_t::INTERNAL, {});
  758. service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, WAITS}});
  759. sset.add_service(s1);
  760. sset.add_service(s2);
  761. assert(sset.find_service("test-service-1") == s1);
  762. assert(sset.find_service("test-service-2") == s2);
  763. // Start both services:
  764. sset.start_service(s2);
  765. // Stop s1:
  766. sset.stop_service(s1);
  767. assert(s1->get_state() == service_state_t::STOPPED);
  768. assert(s2->get_state() == service_state_t::STARTED);
  769. // Start s1:
  770. sset.start_service(s1);
  771. assert(s1->get_state() == service_state_t::STARTED);
  772. assert(s2->get_state() == service_state_t::STARTED);
  773. // De-activate but don't force bring down of s1
  774. // It should remain running, as the dependency from s2 should be reattached
  775. s1->stop(false);
  776. sset.process_queues();
  777. assert(s1->get_state() == service_state_t::STARTED);
  778. assert(s2->get_state() == service_state_t::STARTED);
  779. assert(sset.count_active_services() == 2);
  780. }
  781. // Test that already-started dependencies are correctly attached when starting
  782. void test_softdep6()
  783. {
  784. service_set sset;
  785. service_record *s1 = new service_record(&sset, "test-service-1", service_type_t::INTERNAL, {});
  786. service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, WAITS}});
  787. service_record *s3 = new service_record(&sset, "test-service-3", service_type_t::INTERNAL, {{s1, WAITS}});
  788. sset.add_service(s1);
  789. sset.add_service(s2);
  790. sset.add_service(s3);
  791. assert(sset.find_service("test-service-1") == s1);
  792. assert(sset.find_service("test-service-2") == s2);
  793. assert(sset.find_service("test-service-3") == s3);
  794. // Start s1+s2 services:
  795. sset.start_service(s2);
  796. // Start s3:
  797. sset.start_service(s3);
  798. // Stop s2:
  799. sset.stop_service(s2);
  800. // s1 should remain started, due to dependency from s3.
  801. assert(s1->get_state() == service_state_t::STARTED);
  802. assert(s2->get_state() == service_state_t::STOPPED);
  803. assert(s3->get_state() == service_state_t::STARTED);
  804. // Stop s3, all should stop:
  805. sset.stop_service(s3);
  806. assert(s1->get_state() == service_state_t::STOPPED);
  807. assert(s2->get_state() == service_state_t::STOPPED);
  808. assert(s3->get_state() == service_state_t::STOPPED);
  809. assert(sset.count_active_services() == 0);
  810. }
  811. // Test that a soft dependency restarts if set to auto-restart and dependent still running
  812. void test_softdep7()
  813. {
  814. service_set sset;
  815. test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
  816. service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, WAITS}});
  817. s1->set_auto_restart(true);
  818. sset.add_service(s1);
  819. sset.add_service(s2);
  820. assert(sset.find_service("test-service-1") == s1);
  821. assert(sset.find_service("test-service-2") == s2);
  822. // Start both services:
  823. sset.start_service(s2);
  824. assert(s1->get_target_state() == service_state_t::STARTED);
  825. s1->started();
  826. sset.process_queues();
  827. assert(s1->get_state() == service_state_t::STARTED);
  828. assert(s2->get_state() == service_state_t::STARTED);
  829. // Unexpected stop:
  830. s1->forced_stop();
  831. sset.process_queues();
  832. // since s1 will restart, target state should be STARTED:
  833. assert(s1->get_target_state() == service_state_t::STARTED);
  834. s1->stopped();
  835. sset.process_queues();
  836. // We should see s1 restarting:
  837. assert(s1->get_state() == service_state_t::STARTING);
  838. s1->started();
  839. sset.process_queues();
  840. assert(s1->get_state() == service_state_t::STARTED);
  841. assert(s2->get_state() == service_state_t::STARTED);
  842. assert(sset.count_active_services() == 2);
  843. }
  844. // Test that a soft dependency doesn't restart if not set to auto-restart and dependent still running
  845. void test_softdep8()
  846. {
  847. service_set sset;
  848. test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
  849. s1->auto_stop = false;
  850. service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, WAITS}});
  851. sset.add_service(s1);
  852. sset.add_service(s2);
  853. assert(sset.find_service("test-service-1") == s1);
  854. assert(sset.find_service("test-service-2") == s2);
  855. // Start both services:
  856. sset.start_service(s2);
  857. assert(s1->get_target_state() == service_state_t::STARTED);
  858. s1->started();
  859. sset.process_queues();
  860. assert(s1->get_state() == service_state_t::STARTED);
  861. assert(s2->get_state() == service_state_t::STARTED);
  862. assert(sset.count_active_services() == 2);
  863. // Unexpected stop:
  864. s1->forced_stop();
  865. sset.process_queues();
  866. // since s1 will not restart, target state should be STOPPED:
  867. assert(s1->get_target_state() == service_state_t::STOPPED);
  868. s1->stopped();
  869. sset.process_queues();
  870. // We should see s1 remain stopped:
  871. assert(s1->get_state() == service_state_t::STOPPED);
  872. assert(s2->get_state() == service_state_t::STARTED);
  873. assert(sset.count_active_services() == 1);
  874. }
  875. // If start cancelled, service is removed from console queue
  876. void test_other1()
  877. {
  878. service_set sset;
  879. // Create s1 and s2. s2 depends on s1, and starts on the console.
  880. test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
  881. test_service *s2 = new test_service(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, REG}});
  882. service_flags_t s2_flags;
  883. s2_flags.starts_on_console = true;
  884. s2->set_flags(s2_flags);
  885. sset.add_service(s1);
  886. sset.add_service(s2);
  887. // Create s3, which starts and runs on console:
  888. test_service *s3 = new test_service(&sset, "test-service-3", service_type_t::INTERNAL, {});
  889. service_flags_t s3_flags;
  890. s3_flags.starts_on_console = true;
  891. s3_flags.runs_on_console = true;
  892. sset.add_service(s3);
  893. assert(sset.find_service("test-service-1") == s1);
  894. assert(sset.find_service("test-service-2") == s2);
  895. assert(sset.find_service("test-service-3") == s3);
  896. // Start the s3 service, so it gets console:
  897. sset.start_service(s3);
  898. sset.process_queues();
  899. s3->started();
  900. sset.process_queues();
  901. assert(! sset.is_queued_for_console(s3)); // should not be queued, because already has acquired
  902. assert(sset.is_console_queue_empty());
  903. // Start s2, which starts s1 as a dependency:
  904. sset.start_service(s2);
  905. sset.process_queues();
  906. assert(s1->get_state() == service_state_t::STARTING);
  907. assert(s2->get_state() == service_state_t::STARTING);
  908. s1->started();
  909. sset.process_queues();
  910. // s2 should now be waiting for console:
  911. assert(s1->get_state() == service_state_t::STARTED);
  912. assert(s2->get_state() == service_state_t::STARTING);
  913. assert(sset.is_queued_for_console(s2));
  914. // stop s1, should stop s2, s2 should unqueue:
  915. s1->stop();
  916. sset.process_queues();
  917. assert(s1->get_state() == service_state_t::STOPPED);
  918. assert(s2->get_state() == service_state_t::STOPPED);
  919. assert(! sset.is_queued_for_console(s2));
  920. assert(sset.count_active_services() == 1); // s3 is still started
  921. }
  922. // Test that active service count reaches 0 when stopping a service with different types of dependency
  923. void test_other2()
  924. {
  925. service_set sset;
  926. service_record *s4 = new service_record(&sset, "test-service-4", service_type_t::INTERNAL, {});
  927. service_record *s3 = new service_record(&sset, "test-service-3", service_type_t::INTERNAL, {});
  928. service_record *s2 = new service_record(&sset, "test-service-2", service_type_t::INTERNAL, {});
  929. service_record *s1 = new service_record(&sset, "test-service-1", service_type_t::INTERNAL,
  930. {{s2, WAITS}, {s3, REG}, {s4, MS}});
  931. sset.add_service(s4);
  932. sset.add_service(s3);
  933. sset.add_service(s2);
  934. sset.add_service(s1);
  935. assert(sset.find_service("test-service-1") == s1);
  936. assert(sset.find_service("test-service-2") == s2);
  937. assert(sset.find_service("test-service-3") == s3);
  938. assert(sset.find_service("test-service-4") == s4);
  939. // Request start of the s2 service, should also start s1:
  940. sset.start_service(s1);
  941. sset.process_queues();
  942. assert(s1->get_state() == service_state_t::STARTED);
  943. assert(s2->get_state() == service_state_t::STARTED);
  944. assert(s3->get_state() == service_state_t::STARTED);
  945. assert(s4->get_state() == service_state_t::STARTED);
  946. s1->stop();
  947. sset.process_queues();
  948. assert(s1->get_state() == service_state_t::STOPPED);
  949. assert(s2->get_state() == service_state_t::STOPPED);
  950. assert(s3->get_state() == service_state_t::STOPPED);
  951. assert(s4->get_state() == service_state_t::STOPPED);
  952. assert(sset.count_active_services() == 0);
  953. }
  954. // Tests for "restart" functionality.
  955. void test_other3()
  956. {
  957. service_set sset;
  958. test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
  959. test_service *s2 = new test_service(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, WAITS}});
  960. test_service *s3 = new test_service(&sset, "test-service-3", service_type_t::INTERNAL, {{s2, REG}});
  961. sset.add_service(s1);
  962. sset.add_service(s2);
  963. sset.add_service(s3);
  964. // Start all services via s3
  965. sset.start_service(s3);
  966. s1->started();
  967. sset.process_queues();
  968. s2->started();
  969. sset.process_queues();
  970. s3->started();
  971. sset.process_queues();
  972. assert(s3->get_state() == service_state_t::STARTED);
  973. assert(s2->get_state() == service_state_t::STARTED);
  974. assert(s1->get_state() == service_state_t::STARTED);
  975. test_listener tl;
  976. s1->add_listener(&tl);
  977. s1->restart();
  978. sset.process_queues();
  979. assert(s3->get_state() == service_state_t::STARTED);
  980. assert(s2->get_state() == service_state_t::STARTED);
  981. assert(s1->get_state() == service_state_t::STARTING);
  982. assert(! tl.got_started);
  983. s1->started();
  984. sset.process_queues();
  985. assert(s3->get_state() == service_state_t::STARTED);
  986. assert(s2->get_state() == service_state_t::STARTED);
  987. assert(s1->get_state() == service_state_t::STARTED);
  988. assert(tl.got_started);
  989. }
  990. // Make sure a service only restarts once (i.e. restart flag doesn't get stuck)
  991. void test_other4()
  992. {
  993. service_set sset;
  994. test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
  995. test_service *s2 = new test_service(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, WAITS}});
  996. sset.add_service(s1);
  997. sset.add_service(s2);
  998. // Start all services via s2
  999. sset.start_service(s2);
  1000. s1->started();
  1001. sset.process_queues();
  1002. s2->started();
  1003. sset.process_queues();
  1004. assert(s2->get_state() == service_state_t::STARTED);
  1005. assert(s1->get_state() == service_state_t::STARTED);
  1006. s1->restart();
  1007. sset.process_queues();
  1008. assert(s2->get_state() == service_state_t::STARTED);
  1009. assert(s1->get_state() == service_state_t::STARTING);
  1010. s1->started();
  1011. sset.process_queues();
  1012. assert(s2->get_state() == service_state_t::STARTED);
  1013. assert(s1->get_state() == service_state_t::STARTED);
  1014. // Ok, we restarted s1. Now stop it:
  1015. s1->stop(true);
  1016. sset.process_queues();
  1017. assert(s2->get_state() == service_state_t::STARTED);
  1018. assert(s1->get_state() == service_state_t::STOPPED); // didn't restart
  1019. }
  1020. // Test that restart can be cancelled if dependents stop
  1021. void test_other5()
  1022. {
  1023. service_set sset;
  1024. test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
  1025. test_service *s2 = new test_service(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, WAITS}});
  1026. sset.add_service(s1);
  1027. sset.add_service(s2);
  1028. // Start all services via s2
  1029. sset.start_service(s2);
  1030. s1->started();
  1031. sset.process_queues();
  1032. s2->started();
  1033. sset.process_queues();
  1034. assert(s2->get_state() == service_state_t::STARTED);
  1035. assert(s1->get_state() == service_state_t::STARTED);
  1036. test_listener tl;
  1037. s1->add_listener(&tl);
  1038. s1->auto_stop = false;
  1039. s1->restart();
  1040. sset.process_queues();
  1041. assert(s1->get_state() == service_state_t::STOPPING);
  1042. assert(s1->get_target_state() == service_state_t::STARTED);
  1043. // Stop s2, s1 will be released and will therefore not restart
  1044. s2->stop();
  1045. sset.process_queues();
  1046. assert(s1->get_target_state() == service_state_t::STOPPED);
  1047. assert(tl.start_cancelled);
  1048. s1->stopped();
  1049. sset.process_queues();
  1050. assert(s2->get_state() == service_state_t::STOPPED);
  1051. assert(s1->get_state() == service_state_t::STOPPED);
  1052. assert(! tl.got_started);
  1053. }
  1054. // Test interrupted startup.
  1055. void test_other6()
  1056. {
  1057. service_set sset;
  1058. test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
  1059. test_service *s2 = new test_service(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, WAITS}});
  1060. test_service *s3 = new test_service(&sset, "test-service-3", service_type_t::INTERNAL, {{s2, MS}});
  1061. sset.add_service(s1);
  1062. sset.add_service(s2);
  1063. sset.add_service(s3);
  1064. // Begin to start all services via s3
  1065. sset.start_service(s3);
  1066. assert(s1->get_state() == service_state_t::STARTING);
  1067. assert(s2->get_state() == service_state_t::STARTING);
  1068. assert(s3->get_state() == service_state_t::STARTING);
  1069. // Stop s2, s3 should stop, s1 is no longer required but still STARTING
  1070. // Note s2 is waiting for dependencies (s1) so start should be interruptible.
  1071. s2->stop();
  1072. sset.process_queues();
  1073. assert(s1->get_state() == service_state_t::STARTING);
  1074. assert(s2->get_state() == service_state_t::STOPPED);
  1075. assert(s3->get_state() == service_state_t::STOPPED);
  1076. // Once s1 starts, it is no longer required and so should stop.
  1077. s1->started();
  1078. sset.process_queues();
  1079. assert(s1->get_state() == service_state_t::STOPPED);
  1080. assert(s2->get_state() == service_state_t::STOPPED);
  1081. assert(s3->get_state() == service_state_t::STOPPED);
  1082. assert(sset.count_active_services() == 0);
  1083. }
  1084. static void flush_log(int fd)
  1085. {
  1086. while (! is_log_flushed()) {
  1087. event_loop.send_fd_event(fd, dasynq::OUT_EVENTS);
  1088. event_loop.send_fd_event(STDOUT_FILENO, dasynq::OUT_EVENTS);
  1089. }
  1090. std::vector<char> wdata;
  1091. bp_sys::extract_written_data(fd, wdata);
  1092. bp_sys::extract_written_data(0, wdata);
  1093. }
  1094. void test_log1()
  1095. {
  1096. // Basic test that output to log is written to log file
  1097. service_set sset;
  1098. init_log(true /* syslog format */);
  1099. setup_log_console_handoff(&sset);
  1100. int logfd = bp_sys::allocfd();
  1101. setup_main_log(logfd);
  1102. flush_log(logfd);
  1103. log(loglevel_t::ERROR, "test one");
  1104. // flush
  1105. //event_loop.
  1106. event_loop.send_fd_event(logfd, dasynq::OUT_EVENTS);
  1107. std::vector<char> wdata;
  1108. bp_sys::extract_written_data(logfd, wdata);
  1109. std::string wstr {wdata.begin(), wdata.end()};
  1110. assert(wstr == "<27>dinit: test one\n");
  1111. close_log();
  1112. }
  1113. void test_log2()
  1114. {
  1115. // test that log is closed on write failure.
  1116. service_set sset;
  1117. init_log(true /* syslog format */);
  1118. setup_log_console_handoff(&sset);
  1119. bool was_closed = false;
  1120. class fail_writer : public bp_sys::write_handler {
  1121. public:
  1122. bool *was_closed = nullptr;
  1123. ssize_t write(int fd, const void *buf, size_t count) override
  1124. {
  1125. errno = ENOSPC;
  1126. return -1;
  1127. }
  1128. ~fail_writer() override
  1129. {
  1130. *was_closed = true;
  1131. }
  1132. };
  1133. fail_writer *fw = new fail_writer();
  1134. fw->was_closed = &was_closed;
  1135. int logfd = bp_sys::allocfd(fw);
  1136. setup_main_log(logfd);
  1137. event_loop.send_fd_event(logfd, dasynq::OUT_EVENTS);
  1138. event_loop.send_fd_event(STDOUT_FILENO, dasynq::OUT_EVENTS);
  1139. log(loglevel_t::ERROR, "test two");
  1140. // flush
  1141. //event_loop.
  1142. event_loop.send_fd_event(logfd, dasynq::OUT_EVENTS);
  1143. assert(was_closed);
  1144. close_log();
  1145. }
  1146. // Test ordering is honoured (when services would start anyway)
  1147. void test_order1()
  1148. {
  1149. service_set sset;
  1150. test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
  1151. test_service *s2 = new test_service(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, BEFORE}});
  1152. test_service *s3 = new test_service(&sset, "test-service-3", service_type_t::INTERNAL, {{s2, REG}, {s1, REG}});
  1153. s1->auto_stop = false;
  1154. s2->auto_stop = false;
  1155. s3->auto_stop = false;
  1156. sset.add_service(s1);
  1157. sset.add_service(s2);
  1158. sset.add_service(s3);
  1159. assert(sset.find_service("test-service-1") == s1);
  1160. assert(sset.find_service("test-service-2") == s2);
  1161. assert(sset.find_service("test-service-3") == s3);
  1162. // Start all three services:
  1163. sset.start_service(s3);
  1164. assert(s1->bring_up_reqd == true);
  1165. assert(s2->bring_up_reqd == false);
  1166. assert(s3->bring_up_reqd == false);
  1167. s1->started();
  1168. sset.process_queues();
  1169. assert(s2->bring_up_reqd == true);
  1170. assert(s3->bring_up_reqd == false);
  1171. s2->started();
  1172. sset.process_queues();
  1173. assert(s3->bring_up_reqd == true);
  1174. s3->started();
  1175. sset.process_queues();
  1176. assert(s3->get_state() == service_state_t::STARTED);
  1177. assert(s2->get_state() == service_state_t::STARTED);
  1178. assert(s1->get_state() == service_state_t::STARTED);
  1179. // Now stop s3, which should also cause s1 and s2 to stop.
  1180. s3->stop();
  1181. sset.process_queues();
  1182. assert(s3->get_state() == service_state_t::STOPPING);
  1183. assert(s2->get_state() == service_state_t::STOPPING);
  1184. assert(s1->get_state() == service_state_t::STOPPING);
  1185. assert(s3->get_target_state() == service_state_t::STOPPED);
  1186. assert(s2->get_target_state() == service_state_t::STOPPED);
  1187. assert(s1->get_target_state() == service_state_t::STOPPED);
  1188. s3->stopped();
  1189. sset.process_queues();
  1190. s2->stopped();
  1191. sset.process_queues();
  1192. s1->stopped();
  1193. sset.process_queues();
  1194. assert(s3->get_state() == service_state_t::STOPPED);
  1195. assert(s2->get_state() == service_state_t::STOPPED);
  1196. assert(s1->get_state() == service_state_t::STOPPED);
  1197. assert(sset.count_active_services() == 0);
  1198. }
  1199. // Test "before" ordering does not by itself imply bring-up requirement
  1200. void test_order2()
  1201. {
  1202. service_set sset;
  1203. test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
  1204. test_service *s2 = new test_service(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, BEFORE}});
  1205. test_service *s3 = new test_service(&sset, "test-service-3", service_type_t::INTERNAL, {{s2, REG}});
  1206. s1->auto_stop = false;
  1207. s2->auto_stop = false;
  1208. s3->auto_stop = false;
  1209. sset.add_service(s1);
  1210. sset.add_service(s2);
  1211. sset.add_service(s3);
  1212. assert(sset.find_service("test-service-1") == s1);
  1213. assert(sset.find_service("test-service-2") == s2);
  1214. assert(sset.find_service("test-service-3") == s3);
  1215. // Start s3 and s2; s1 should not be started
  1216. sset.start_service(s3);
  1217. assert(s1->bring_up_reqd == false);
  1218. assert(s2->bring_up_reqd == true);
  1219. assert(s3->bring_up_reqd == false);
  1220. s2->started();
  1221. sset.process_queues();
  1222. s3->started();
  1223. sset.process_queues();
  1224. assert(s3->get_state() == service_state_t::STARTED);
  1225. assert(s2->get_state() == service_state_t::STARTED);
  1226. assert(s1->get_state() == service_state_t::STOPPED);
  1227. // Now stop s3, which should also cause ss2 to stop.
  1228. s3->stop();
  1229. sset.process_queues();
  1230. assert(s3->get_state() == service_state_t::STOPPING);
  1231. assert(s2->get_state() == service_state_t::STOPPING);
  1232. assert(s1->get_state() == service_state_t::STOPPED);
  1233. assert(s3->get_target_state() == service_state_t::STOPPED);
  1234. assert(s2->get_target_state() == service_state_t::STOPPED);
  1235. assert(s1->get_target_state() == service_state_t::STOPPED);
  1236. s3->stopped();
  1237. sset.process_queues();
  1238. s2->stopped();
  1239. sset.process_queues();
  1240. assert(s3->get_state() == service_state_t::STOPPED);
  1241. assert(s2->get_state() == service_state_t::STOPPED);
  1242. assert(s1->get_state() == service_state_t::STOPPED);
  1243. assert(sset.count_active_services() == 0);
  1244. }
  1245. // Test "after" ordering does not by itself imply bring-up requirement
  1246. void test_order3()
  1247. {
  1248. service_set sset;
  1249. test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
  1250. test_service *s2 = new test_service(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, AFTER}});
  1251. test_service *s3 = new test_service(&sset, "test-service-3", service_type_t::INTERNAL, {{s2, REG}});
  1252. s1->auto_stop = false;
  1253. s2->auto_stop = false;
  1254. s3->auto_stop = false;
  1255. sset.add_service(s1);
  1256. sset.add_service(s2);
  1257. sset.add_service(s3);
  1258. assert(sset.find_service("test-service-1") == s1);
  1259. assert(sset.find_service("test-service-2") == s2);
  1260. assert(sset.find_service("test-service-3") == s3);
  1261. // Start s3 and s2; s1 should not be started
  1262. sset.start_service(s3);
  1263. assert(s1->bring_up_reqd == false);
  1264. assert(s2->bring_up_reqd == true);
  1265. assert(s3->bring_up_reqd == false);
  1266. s2->started();
  1267. sset.process_queues();
  1268. s3->started();
  1269. sset.process_queues();
  1270. assert(s3->get_state() == service_state_t::STARTED);
  1271. assert(s2->get_state() == service_state_t::STARTED);
  1272. assert(s1->get_state() == service_state_t::STOPPED);
  1273. // Now stop s3, which should also cause ss2 to stop.
  1274. s3->stop();
  1275. sset.process_queues();
  1276. assert(s3->get_state() == service_state_t::STOPPING);
  1277. assert(s2->get_state() == service_state_t::STOPPING);
  1278. assert(s1->get_state() == service_state_t::STOPPED);
  1279. assert(s3->get_target_state() == service_state_t::STOPPED);
  1280. assert(s2->get_target_state() == service_state_t::STOPPED);
  1281. assert(s1->get_target_state() == service_state_t::STOPPED);
  1282. s3->stopped();
  1283. sset.process_queues();
  1284. s2->stopped();
  1285. sset.process_queues();
  1286. assert(s3->get_state() == service_state_t::STOPPED);
  1287. assert(s2->get_state() == service_state_t::STOPPED);
  1288. assert(s1->get_state() == service_state_t::STOPPED);
  1289. assert(sset.count_active_services() == 0);
  1290. }
  1291. // Stopping a restarting service, which is in the stopping phase, should prevent restart
  1292. void test_restart_stop1()
  1293. {
  1294. service_set sset;
  1295. test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
  1296. s1->auto_stop = false;
  1297. sset.add_service(s1);
  1298. assert(sset.find_service("test-service-1") == s1);
  1299. // start s1
  1300. sset.start_service(s1);
  1301. assert(s1->bring_up_reqd == true);
  1302. s1->started();
  1303. sset.process_queues();
  1304. assert(s1->get_state() == service_state_t::STARTED);
  1305. // issue restart
  1306. s1->restart();
  1307. sset.process_queues();
  1308. assert(s1->get_state() == service_state_t::STOPPING);
  1309. // now issue stop, while still in stopping phase of restart: the restart should be cancelled
  1310. s1->stop();
  1311. sset.process_queues();
  1312. assert(s1->get_state() == service_state_t::STOPPING);
  1313. // once stopped, the service should not restart
  1314. s1->stopped();
  1315. assert(s1->get_state() == service_state_t::STOPPED);
  1316. }
  1317. // Stopping a restarting service, which is in the stopping phase, should prevent restart
  1318. // (this time with a dependent)
  1319. void test_restart_stop2()
  1320. {
  1321. service_set sset;
  1322. test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
  1323. test_service *s2 = new test_service(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, REG}});
  1324. s1->auto_stop = false;
  1325. s2->auto_stop = false;
  1326. sset.add_service(s1);
  1327. sset.add_service(s2);
  1328. assert(sset.find_service("test-service-1") == s1);
  1329. assert(sset.find_service("test-service-2") == s2);
  1330. // start s2, which also starts s1
  1331. sset.start_service(s2);
  1332. assert(s1->bring_up_reqd == true);
  1333. assert(s2->bring_up_reqd == false);
  1334. s1->started();
  1335. sset.process_queues();
  1336. assert(s1->get_state() == service_state_t::STARTED);
  1337. assert(s2->bring_up_reqd == true);
  1338. s2->started();
  1339. sset.process_queues();
  1340. assert(s2->get_state() == service_state_t::STARTED);
  1341. // issue restart
  1342. s1->restart();
  1343. sset.process_queues();
  1344. assert(s1->get_state() == service_state_t::STOPPING);
  1345. assert(s2->get_state() == service_state_t::STOPPING);
  1346. // now issue stop, while still in stopping phase of restart: the restart should be cancelled
  1347. s1->stop();
  1348. sset.process_queues();
  1349. assert(s1->get_state() == service_state_t::STOPPING);
  1350. assert(s2->get_state() == service_state_t::STOPPING);
  1351. // once stopped, the service should not restart
  1352. s2->stopped();
  1353. assert(s2->get_state() == service_state_t::STOPPED);
  1354. s1->stopped();
  1355. assert(s1->get_state() == service_state_t::STOPPED);
  1356. }
  1357. // Stopping a restarting service, which is in the stopping phase, should prevent restart,
  1358. // and prevent restart of a dependency which is not otherwise active
  1359. void test_restart_stop3()
  1360. {
  1361. service_set sset;
  1362. test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
  1363. test_service *s2 = new test_service(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, REG}});
  1364. s1->auto_stop = false;
  1365. s2->auto_stop = false;
  1366. sset.add_service(s1);
  1367. sset.add_service(s2);
  1368. assert(sset.find_service("test-service-1") == s1);
  1369. assert(sset.find_service("test-service-2") == s2);
  1370. // start s2, which also starts s1
  1371. sset.start_service(s2);
  1372. assert(s1->bring_up_reqd == true);
  1373. assert(s2->bring_up_reqd == false);
  1374. s1->started();
  1375. sset.process_queues();
  1376. assert(s1->get_state() == service_state_t::STARTED);
  1377. assert(s2->bring_up_reqd == true);
  1378. s2->started();
  1379. sset.process_queues();
  1380. assert(s2->get_state() == service_state_t::STARTED);
  1381. // issue restart on s1 (and s2 transitively)
  1382. s1->restart();
  1383. sset.process_queues();
  1384. assert(s1->get_state() == service_state_t::STOPPING);
  1385. assert(s2->get_state() == service_state_t::STOPPING);
  1386. // now issue stop on s2, while still in stopping phase of restart: the restart should be cancelled
  1387. // s1's restart should also be cancelled due to lack of any active dependent
  1388. s2->stop();
  1389. sset.process_queues();
  1390. assert(s1->get_state() == service_state_t::STOPPING);
  1391. assert(s2->get_state() == service_state_t::STOPPING);
  1392. // once stopped, the services should not restart
  1393. s2->stopped();
  1394. assert(s2->get_state() == service_state_t::STOPPED);
  1395. s1->stopped();
  1396. assert(s1->get_state() == service_state_t::STOPPED);
  1397. }
  1398. // Stopping a restarting service, which is in the stopping phase, should prevent restart,
  1399. // but not prevent restart of a dependency which is otherwise active
  1400. void test_restart_stop4()
  1401. {
  1402. service_set sset;
  1403. test_service *s1 = new test_service(&sset, "test-service-1", service_type_t::INTERNAL, {});
  1404. test_service *s2 = new test_service(&sset, "test-service-2", service_type_t::INTERNAL, {{s1, REG}});
  1405. s1->auto_stop = false;
  1406. s2->auto_stop = false;
  1407. sset.add_service(s1);
  1408. sset.add_service(s2);
  1409. assert(sset.find_service("test-service-1") == s1);
  1410. assert(sset.find_service("test-service-2") == s2);
  1411. // start s2, which also starts s1
  1412. sset.start_service(s2);
  1413. assert(s1->bring_up_reqd == true);
  1414. assert(s2->bring_up_reqd == false);
  1415. s1->started();
  1416. sset.process_queues();
  1417. assert(s1->get_state() == service_state_t::STARTED);
  1418. assert(s2->bring_up_reqd == true);
  1419. s2->started();
  1420. sset.process_queues();
  1421. assert(s2->get_state() == service_state_t::STARTED);
  1422. // also explicitly activate s1
  1423. s1->start();
  1424. // issue restart on s1 (and s2 transitively)
  1425. s1->restart();
  1426. sset.process_queues();
  1427. assert(s1->get_state() == service_state_t::STOPPING);
  1428. assert(s2->get_state() == service_state_t::STOPPING);
  1429. // now issue stop on s2, while still in stopping phase of restart: the restart should be cancelled
  1430. // s1's restart should not be cancelled
  1431. s2->stop();
  1432. sset.process_queues();
  1433. assert(s1->get_state() == service_state_t::STOPPING);
  1434. assert(s2->get_state() == service_state_t::STOPPING);
  1435. // once stopped, the s2 should not restart
  1436. s2->stopped();
  1437. assert(s2->get_state() == service_state_t::STOPPED);
  1438. // When s1 stops, it should restart
  1439. s1->stopped();
  1440. assert(s1->get_state() == service_state_t::STARTING);
  1441. s1->started();
  1442. assert(s1->get_state() == service_state_t::STARTED);
  1443. s1->stop();
  1444. sset.process_queues();
  1445. s1->stopped();
  1446. }
  1447. #define RUN_TEST(name, spacing) \
  1448. std::cout << #name "..." spacing << std::flush; \
  1449. name(); \
  1450. std::cout << "PASSED" << std::endl;
  1451. int main(int argc, char **argv)
  1452. {
  1453. bp_sys::init_bpsys();
  1454. RUN_TEST(basic_test1, " ");
  1455. RUN_TEST(basic_test2, " ");
  1456. RUN_TEST(basic_test3, " ");
  1457. RUN_TEST(basic_test4, " ");
  1458. RUN_TEST(basic_test5, " ");
  1459. RUN_TEST(basic_test6, " ");
  1460. RUN_TEST(basic_test7, " ");
  1461. RUN_TEST(basic_test8, " ");
  1462. RUN_TEST(basic_test9, " ");
  1463. RUN_TEST(basic_test10, " ");
  1464. RUN_TEST(test_pin1, " ");
  1465. RUN_TEST(test_pin2, " ");
  1466. RUN_TEST(test_pin3, " ");
  1467. RUN_TEST(test_pin4, " ");
  1468. RUN_TEST(test_pin5, " ");
  1469. RUN_TEST(test_pin6, " ");
  1470. RUN_TEST(test_pin7, " ");
  1471. RUN_TEST(test_pin8, " ");
  1472. RUN_TEST(test_pin9, " ");
  1473. RUN_TEST(test_pin10, " ");
  1474. RUN_TEST(test_softdep1, " ");
  1475. RUN_TEST(test_softdep2, " ");
  1476. RUN_TEST(test_softdep3, " ");
  1477. RUN_TEST(test_softdep4, " ");
  1478. RUN_TEST(test_softdep5, " ");
  1479. RUN_TEST(test_softdep6, " ");
  1480. RUN_TEST(test_softdep7, " ");
  1481. RUN_TEST(test_softdep8, " ");
  1482. RUN_TEST(test_other1, " ");
  1483. RUN_TEST(test_other2, " ");
  1484. RUN_TEST(test_other3, " ");
  1485. RUN_TEST(test_other4, " ");
  1486. RUN_TEST(test_other5, " ");
  1487. RUN_TEST(test_other6, " ");
  1488. RUN_TEST(test_log1, " ");
  1489. RUN_TEST(test_log2, " ");
  1490. RUN_TEST(test_order1, " ");
  1491. RUN_TEST(test_order2, " ");
  1492. RUN_TEST(test_order3, " ");
  1493. RUN_TEST(test_restart_stop1, " ");
  1494. RUN_TEST(test_restart_stop2, " ");
  1495. RUN_TEST(test_restart_stop3, " ");
  1496. RUN_TEST(test_restart_stop4, " ");
  1497. }