test_supervisord.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. import unittest
  2. import time
  3. import signal
  4. import sys
  5. import os
  6. import tempfile
  7. import shutil
  8. from supervisor.tests.base import DummyOptions
  9. from supervisor.tests.base import DummyPConfig
  10. from supervisor.tests.base import DummyPGroupConfig
  11. from supervisor.tests.base import DummyProcess
  12. from supervisor.tests.base import DummyProcessGroup
  13. from supervisor.tests.base import DummyDispatcher
  14. class EntryPointTests(unittest.TestCase):
  15. def test_main_noprofile(self):
  16. from supervisor.supervisord import main
  17. conf = os.path.join(
  18. os.path.abspath(os.path.dirname(__file__)), 'fixtures',
  19. 'donothing.conf')
  20. import StringIO
  21. new_stdout = StringIO.StringIO()
  22. old_stdout = sys.stdout
  23. try:
  24. tempdir = tempfile.mkdtemp()
  25. log = os.path.join(tempdir, 'log')
  26. pid = os.path.join(tempdir, 'pid')
  27. sys.stdout = new_stdout
  28. main(args=['-c', conf, '-l', log, '-j', pid, '-n'],
  29. test=True)
  30. finally:
  31. sys.stdout = old_stdout
  32. shutil.rmtree(tempdir)
  33. output = new_stdout.getvalue()
  34. self.assertTrue(output.find('supervisord started') != 1, output)
  35. if sys.version_info[:2] >= (2, 4):
  36. def test_main_profile(self):
  37. from supervisor.supervisord import main
  38. conf = os.path.join(
  39. os.path.abspath(os.path.dirname(__file__)), 'fixtures',
  40. 'donothing.conf')
  41. import StringIO
  42. new_stdout = StringIO.StringIO()
  43. old_stdout = sys.stdout
  44. try:
  45. tempdir = tempfile.mkdtemp()
  46. log = os.path.join(tempdir, 'log')
  47. pid = os.path.join(tempdir, 'pid')
  48. sys.stdout = new_stdout
  49. main(args=['-c', conf, '-l', log, '-j', pid, '-n',
  50. '--profile_options=cumulative,calls'], test=True)
  51. finally:
  52. sys.stdout = old_stdout
  53. shutil.rmtree(tempdir)
  54. output = new_stdout.getvalue()
  55. self.assertTrue(output.find('cumulative time, call count') != -1,
  56. output)
  57. class SupervisordTests(unittest.TestCase):
  58. def tearDown(self):
  59. from supervisor.events import clear
  60. clear()
  61. def _getTargetClass(self):
  62. from supervisor.supervisord import Supervisor
  63. return Supervisor
  64. def _makeOne(self, options):
  65. return self._getTargetClass()(options)
  66. def test_main_first(self):
  67. options = DummyOptions()
  68. pconfig = DummyPConfig(options, 'foo', 'foo', '/bin/foo')
  69. gconfigs = [DummyPGroupConfig(options,'foo', pconfigs=[pconfig])]
  70. options.process_group_configs = gconfigs
  71. options.test = True
  72. options.first = True
  73. supervisord = self._makeOne(options)
  74. supervisord.main()
  75. self.assertEqual(options.environment_processed, True)
  76. self.assertEqual(options.fds_cleaned_up, False)
  77. self.assertEqual(options.rlimits_set, True)
  78. self.assertEqual(options.make_logger_messages,
  79. (['setuid_called'], [], ['rlimits_set']))
  80. self.assertEqual(options.autochildlogdir_cleared, True)
  81. self.assertEqual(len(supervisord.process_groups), 1)
  82. self.assertEqual(supervisord.process_groups['foo'].config.options,
  83. options)
  84. self.assertEqual(options.environment_processed, True)
  85. self.assertEqual(options.httpservers_opened, True)
  86. self.assertEqual(options.signals_set, True)
  87. self.assertEqual(options.daemonized, True)
  88. self.assertEqual(options.pidfile_written, True)
  89. self.assertEqual(options.cleaned_up, True)
  90. def test_main_notfirst(self):
  91. options = DummyOptions()
  92. pconfig = DummyPConfig(options, 'foo', 'foo', '/bin/foo')
  93. gconfigs = [DummyPGroupConfig(options,'foo', pconfigs=[pconfig])]
  94. options.process_group_configs = gconfigs
  95. options.test = True
  96. options.first = False
  97. supervisord = self._makeOne(options)
  98. supervisord.main()
  99. self.assertEqual(options.environment_processed, True)
  100. self.assertEqual(options.fds_cleaned_up, True)
  101. self.assertFalse(hasattr(options, 'rlimits_set'))
  102. self.assertEqual(options.make_logger_messages,
  103. (['setuid_called'], [], []))
  104. self.assertEqual(options.autochildlogdir_cleared, True)
  105. self.assertEqual(len(supervisord.process_groups), 1)
  106. self.assertEqual(supervisord.process_groups['foo'].config.options,
  107. options)
  108. self.assertEqual(options.environment_processed, True)
  109. self.assertEqual(options.httpservers_opened, True)
  110. self.assertEqual(options.signals_set, True)
  111. self.assertEqual(options.daemonized, False)
  112. self.assertEqual(options.pidfile_written, True)
  113. self.assertEqual(options.cleaned_up, True)
  114. def test_reap(self):
  115. options = DummyOptions()
  116. options.waitpid_return = 1, 1
  117. pconfig = DummyPConfig(options, 'process', 'process', '/bin/process1')
  118. process = DummyProcess(pconfig)
  119. process.drained = False
  120. process.killing = 1
  121. process.laststop = None
  122. process.waitstatus = None, None
  123. options.pidhistory = {1:process}
  124. supervisord = self._makeOne(options)
  125. supervisord.reap(once=True)
  126. self.assertEqual(process.finished, (1,1))
  127. def test_reap_unknown_pid(self):
  128. options = DummyOptions()
  129. options.waitpid_return = 2, 0 # pid, status
  130. pconfig = DummyPConfig(options, 'process', 'process', '/bin/process1')
  131. process = DummyProcess(pconfig)
  132. process.drained = False
  133. process.killing = True
  134. process.laststop = None
  135. process.waitstatus = None, None
  136. options.pidhistory = {1: process}
  137. supervisord = self._makeOne(options)
  138. supervisord.reap(once=True)
  139. self.assertEqual(process.finished, None)
  140. self.assertEqual(options.logger.data[0],
  141. 'reaped unknown pid 2')
  142. def test_handle_sigterm(self):
  143. options = DummyOptions()
  144. options._signal = signal.SIGTERM
  145. supervisord = self._makeOne(options)
  146. supervisord.handle_signal()
  147. self.assertEqual(supervisord.options.mood, -1)
  148. self.assertEqual(options.logger.data[0],
  149. 'received SIGTERM indicating exit request')
  150. def test_handle_sigint(self):
  151. options = DummyOptions()
  152. options._signal = signal.SIGINT
  153. supervisord = self._makeOne(options)
  154. supervisord.handle_signal()
  155. self.assertEqual(supervisord.options.mood, -1)
  156. self.assertEqual(options.logger.data[0],
  157. 'received SIGINT indicating exit request')
  158. def test_handle_sigquit(self):
  159. options = DummyOptions()
  160. options._signal = signal.SIGQUIT
  161. supervisord = self._makeOne(options)
  162. supervisord.handle_signal()
  163. self.assertEqual(supervisord.options.mood, -1)
  164. self.assertEqual(options.logger.data[0],
  165. 'received SIGQUIT indicating exit request')
  166. def test_handle_sighup(self):
  167. options = DummyOptions()
  168. options._signal = signal.SIGHUP
  169. supervisord = self._makeOne(options)
  170. supervisord.handle_signal()
  171. self.assertEqual(supervisord.options.mood, 0)
  172. self.assertEqual(options.logger.data[0],
  173. 'received SIGHUP indicating restart request')
  174. def test_handle_sigchld(self):
  175. options = DummyOptions()
  176. options._signal = signal.SIGCHLD
  177. supervisord = self._makeOne(options)
  178. supervisord.handle_signal()
  179. self.assertEqual(supervisord.options.mood, 1)
  180. # supervisor.options.signame(signal.SIGCHLD) may return "SIGCLD"
  181. # on linux or other systems where SIGCHLD = SIGCLD.
  182. msgs = ('received SIGCHLD indicating a child quit',
  183. 'received SIGCLD indicating a child quit')
  184. self.assertTrue(options.logger.data[0] in msgs)
  185. def test_handle_sigusr2(self):
  186. options = DummyOptions()
  187. options._signal = signal.SIGUSR2
  188. pconfig1 = DummyPConfig(options, 'process1', 'process1','/bin/process1')
  189. from supervisor.process import ProcessStates
  190. process1 = DummyProcess(pconfig1, state=ProcessStates.STOPPING)
  191. process1.delay = time.time() - 1
  192. supervisord = self._makeOne(options)
  193. pconfigs = [DummyPConfig(options, 'foo', 'foo', '/bin/foo')]
  194. options.process_group_configs = DummyPGroupConfig(
  195. options, 'foo',
  196. pconfigs=pconfigs)
  197. supervisord.handle_signal()
  198. self.assertEqual(supervisord.options.mood, 1)
  199. self.assertEqual(options.logs_reopened, True)
  200. self.assertEqual(options.logger.data[0],
  201. 'received SIGUSR2 indicating log reopen request')
  202. def test_handle_unknown_signal(self):
  203. options = DummyOptions()
  204. options._signal = signal.SIGUSR1
  205. supervisord = self._makeOne(options)
  206. supervisord.handle_signal()
  207. self.assertEqual(supervisord.options.mood, 1)
  208. self.assertEqual(options.logger.data[0],
  209. 'received SIGUSR1 indicating nothing')
  210. def test_diff_add_remove(self):
  211. options = DummyOptions()
  212. supervisord = self._makeOne(options)
  213. pconfig = DummyPConfig(options, 'process1', 'process1')
  214. group1 = DummyPGroupConfig(options, 'group1', pconfigs=[pconfig])
  215. pconfig = DummyPConfig(options, 'process2', 'process2')
  216. group2 = DummyPGroupConfig(options, 'group2', pconfigs=[pconfig])
  217. new = [group1, group2]
  218. added, changed, removed = supervisord.diff_to_active()
  219. self.assertEqual(added, [])
  220. self.assertEqual(changed, [])
  221. self.assertEqual(removed, [])
  222. added, changed, removed = supervisord.diff_to_active(new)
  223. self.assertEqual(added, new)
  224. self.assertEqual(changed, [])
  225. self.assertEqual(removed, [])
  226. supervisord.options.process_group_configs = new
  227. added, changed, removed = supervisord.diff_to_active()
  228. self.assertEqual(added, new)
  229. supervisord.add_process_group(group1)
  230. supervisord.add_process_group(group2)
  231. pconfig = DummyPConfig(options, 'process3', 'process3')
  232. new_group1 = DummyPGroupConfig(options, pconfigs=[pconfig])
  233. pconfig = DummyPConfig(options, 'process4', 'process4')
  234. new_group2 = DummyPGroupConfig(options, pconfigs=[pconfig])
  235. new = [group2, new_group1, new_group2]
  236. added, changed, removed = supervisord.diff_to_active(new)
  237. self.assertEqual(added, [new_group1, new_group2])
  238. self.assertEqual(changed, [])
  239. self.assertEqual(removed, [group1])
  240. def test_diff_changed(self):
  241. from supervisor.options import ProcessConfig, ProcessGroupConfig
  242. options = DummyOptions()
  243. supervisord = self._makeOne(options)
  244. def make_pconfig(name, command, **params):
  245. result = {
  246. 'name': name, 'command': command,
  247. 'directory': None, 'umask': None, 'priority': 999, 'autostart': True,
  248. 'autorestart': True, 'startsecs': 10, 'startretries': 999,
  249. 'uid': None, 'stdout_logfile': None, 'stdout_capture_maxbytes': 0,
  250. 'stdout_events_enabled': False,
  251. 'stdout_logfile_backups': 0, 'stdout_logfile_maxbytes': 0,
  252. 'stdout_syslog': False,
  253. 'stderr_logfile': None, 'stderr_capture_maxbytes': 0,
  254. 'stderr_events_enabled': False,
  255. 'stderr_logfile_backups': 0, 'stderr_logfile_maxbytes': 0,
  256. 'stderr_syslog': False,
  257. 'redirect_stderr': False,
  258. 'stopsignal': None, 'stopwaitsecs': 10,
  259. 'stopasgroup': False,
  260. 'killasgroup': False,
  261. 'exitcodes': (0,2), 'environment': None, 'serverurl': None,
  262. }
  263. result.update(params)
  264. return ProcessConfig(options, **result)
  265. def make_gconfig(name, pconfigs):
  266. return ProcessGroupConfig(options, name, 25, pconfigs)
  267. pconfig = make_pconfig('process1', 'process1', uid='new')
  268. group1 = make_gconfig('group1', [pconfig])
  269. pconfig = make_pconfig('process2', 'process2')
  270. group2 = make_gconfig('group2', [pconfig])
  271. new = [group1, group2]
  272. pconfig = make_pconfig('process1', 'process1', uid='old')
  273. group3 = make_gconfig('group1', [pconfig])
  274. pconfig = make_pconfig('process2', 'process2')
  275. group4 = make_gconfig('group2', [pconfig])
  276. supervisord.add_process_group(group3)
  277. supervisord.add_process_group(group4)
  278. added, changed, removed = supervisord.diff_to_active(new)
  279. self.assertEqual([added, removed], [[], []])
  280. self.assertEqual(changed, [group1])
  281. options = DummyOptions()
  282. supervisord = self._makeOne(options)
  283. pconfig1 = make_pconfig('process1', 'process1')
  284. pconfig2 = make_pconfig('process2', 'process2')
  285. group1 = make_gconfig('group1', [pconfig1, pconfig2])
  286. new = [group1]
  287. supervisord.add_process_group(make_gconfig('group1', [pconfig1]))
  288. added, changed, removed = supervisord.diff_to_active(new)
  289. self.assertEqual([added, removed], [[], []])
  290. self.assertEqual(changed, [group1])
  291. def test_add_process_group(self):
  292. options = DummyOptions()
  293. pconfig = DummyPConfig(options, 'foo', 'foo', '/bin/foo')
  294. gconfig = DummyPGroupConfig(options,'foo', pconfigs=[pconfig])
  295. options.process_group_configs = [gconfig]
  296. supervisord = self._makeOne(options)
  297. self.assertEqual(supervisord.process_groups, {})
  298. result = supervisord.add_process_group(gconfig)
  299. self.assertEqual(supervisord.process_groups.keys(), ['foo'])
  300. self.assertTrue(result)
  301. group = supervisord.process_groups['foo']
  302. result = supervisord.add_process_group(gconfig)
  303. self.assertEqual(group, supervisord.process_groups['foo'])
  304. self.assertTrue(not result)
  305. def test_add_process_group_event(self):
  306. from supervisor import events
  307. L = []
  308. def callback(event):
  309. L.append(1)
  310. events.subscribe(events.ProcessGroupAddedEvent, callback)
  311. options = DummyOptions()
  312. pconfig = DummyPConfig(options, 'foo', 'foo', '/bin/foo')
  313. gconfig = DummyPGroupConfig(options,'foo', pconfigs=[pconfig])
  314. options.process_group_configs = [gconfig]
  315. supervisord = self._makeOne(options)
  316. supervisord.add_process_group(gconfig)
  317. options.test = True
  318. supervisord.runforever()
  319. self.assertEqual(L, [1])
  320. def test_remove_process_group(self):
  321. options = DummyOptions()
  322. pconfig = DummyPConfig(options, 'foo', 'foo', '/bin/foo')
  323. gconfig = DummyPGroupConfig(options, 'foo', pconfigs=[pconfig])
  324. supervisord = self._makeOne(options)
  325. self.assertRaises(KeyError, supervisord.remove_process_group, 'asdf')
  326. supervisord.add_process_group(gconfig)
  327. result = supervisord.remove_process_group('foo')
  328. self.assertEqual(supervisord.process_groups, {})
  329. self.assertTrue(result)
  330. supervisord.add_process_group(gconfig)
  331. supervisord.process_groups['foo'].unstopped_processes = [DummyProcess(None)]
  332. result = supervisord.remove_process_group('foo')
  333. self.assertEqual(supervisord.process_groups.keys(), ['foo'])
  334. self.assertTrue(not result)
  335. def test_remove_process_group_event(self):
  336. from supervisor import events
  337. L = []
  338. def callback(event):
  339. L.append(1)
  340. events.subscribe(events.ProcessGroupRemovedEvent, callback)
  341. options = DummyOptions()
  342. pconfig = DummyPConfig(options, 'foo', 'foo', '/bin/foo')
  343. gconfig = DummyPGroupConfig(options,'foo', pconfigs=[pconfig])
  344. options.process_group_configs = [gconfig]
  345. supervisord = self._makeOne(options)
  346. supervisord.add_process_group(gconfig)
  347. supervisord.process_groups['foo'].stopped_processes = [DummyProcess(None)]
  348. supervisord.remove_process_group('foo')
  349. options.test = True
  350. supervisord.runforever()
  351. self.assertEqual(L, [1])
  352. def test_runforever_emits_generic_startup_event(self):
  353. from supervisor import events
  354. L = []
  355. def callback(event):
  356. L.append(1)
  357. events.subscribe(events.SupervisorStateChangeEvent, callback)
  358. options = DummyOptions()
  359. supervisord = self._makeOne(options)
  360. options.test = True
  361. supervisord.runforever()
  362. self.assertEqual(L, [1])
  363. def test_runforever_emits_generic_specific_event(self):
  364. from supervisor import events
  365. L = []
  366. def callback(event):
  367. L.append(2)
  368. events.subscribe(events.SupervisorRunningEvent, callback)
  369. options = DummyOptions()
  370. options.test = True
  371. supervisord = self._makeOne(options)
  372. supervisord.runforever()
  373. self.assertEqual(L, [2])
  374. def test_runforever_calls_tick(self):
  375. options = DummyOptions()
  376. options.test = True
  377. supervisord = self._makeOne(options)
  378. self.assertEqual(len(supervisord.ticks), 0)
  379. supervisord.runforever()
  380. self.assertEqual(len(supervisord.ticks), 3)
  381. def test_runforever_select_eintr(self):
  382. options = DummyOptions()
  383. import errno
  384. options.select_error = errno.EINTR
  385. supervisord = self._makeOne(options)
  386. options.test = True
  387. supervisord.runforever()
  388. self.assertEqual(options.logger.data[0], 'EINTR encountered in select')
  389. def test_runforever_select_uncaught_exception(self):
  390. options = DummyOptions()
  391. import errno
  392. options.select_error = errno.EBADF
  393. supervisord = self._makeOne(options)
  394. import select
  395. options.test = True
  396. self.assertRaises(select.error, supervisord.runforever)
  397. def test_runforever_select_dispatchers(self):
  398. options = DummyOptions()
  399. supervisord = self._makeOne(options)
  400. pconfig = DummyPConfig(options, 'foo', '/bin/foo',)
  401. gconfig = DummyPGroupConfig(options, pconfigs=[pconfig])
  402. pgroup = DummyProcessGroup(gconfig)
  403. readable = DummyDispatcher(readable=True)
  404. writable = DummyDispatcher(writable=True)
  405. error = DummyDispatcher(writable=True, error=OSError)
  406. pgroup.dispatchers = {6:readable, 7:writable, 8:error}
  407. supervisord.process_groups = {'foo': pgroup}
  408. options.select_result = [6], [7, 8], []
  409. options.test = True
  410. supervisord.runforever()
  411. self.assertEqual(pgroup.transitioned, True)
  412. self.assertEqual(readable.read_event_handled, True)
  413. self.assertEqual(writable.write_event_handled, True)
  414. self.assertEqual(error.error_handled, True)
  415. def test_runforever_select_dispatcher_exitnow(self):
  416. options = DummyOptions()
  417. supervisord = self._makeOne(options)
  418. pconfig = DummyPConfig(options, 'foo', '/bin/foo',)
  419. gconfig = DummyPGroupConfig(options, pconfigs=[pconfig])
  420. pgroup = DummyProcessGroup(gconfig)
  421. from supervisor.medusa import asyncore_25 as asyncore
  422. exitnow = DummyDispatcher(readable=True, error=asyncore.ExitNow)
  423. pgroup.dispatchers = {6:exitnow}
  424. supervisord.process_groups = {'foo': pgroup}
  425. options.select_result = [6], [], []
  426. options.test = True
  427. self.assertRaises(asyncore.ExitNow, supervisord.runforever)
  428. def test_runforever_stopping_emits_events(self):
  429. options = DummyOptions()
  430. supervisord = self._makeOne(options)
  431. gconfig = DummyPGroupConfig(options)
  432. pgroup = DummyProcessGroup(gconfig)
  433. supervisord.process_groups = {'foo': pgroup}
  434. supervisord.options.mood = -1
  435. L = []
  436. def callback(event):
  437. L.append(event)
  438. from supervisor import events
  439. events.subscribe(events.SupervisorStateChangeEvent, callback)
  440. from supervisor.medusa import asyncore_25 as asyncore
  441. options.test = True
  442. self.assertRaises(asyncore.ExitNow, supervisord.runforever)
  443. self.assertTrue(pgroup.all_stopped)
  444. self.assertTrue(isinstance(L[0], events.SupervisorRunningEvent))
  445. self.assertTrue(isinstance(L[0], events.SupervisorStateChangeEvent))
  446. self.assertTrue(isinstance(L[1], events.SupervisorStoppingEvent))
  447. self.assertTrue(isinstance(L[1], events.SupervisorStateChangeEvent))
  448. def test_exit(self):
  449. options = DummyOptions()
  450. supervisord = self._makeOne(options)
  451. pconfig = DummyPConfig(options, 'foo', '/bin/foo',)
  452. gconfig = DummyPGroupConfig(options, pconfigs=[pconfig])
  453. pgroup = DummyProcessGroup(gconfig)
  454. L = []
  455. def callback():
  456. L.append(1)
  457. supervisord.process_groups = {'foo': pgroup}
  458. supervisord.options.mood = 0
  459. supervisord.options.test = True
  460. from supervisor.medusa import asyncore_25 as asyncore
  461. self.assertRaises(asyncore.ExitNow, supervisord.runforever)
  462. self.assertEqual(pgroup.all_stopped, True)
  463. def test_exit_delayed(self):
  464. options = DummyOptions()
  465. supervisord = self._makeOne(options)
  466. pconfig = DummyPConfig(options, 'foo', '/bin/foo',)
  467. process = DummyProcess(pconfig)
  468. gconfig = DummyPGroupConfig(options, pconfigs=[pconfig])
  469. pgroup = DummyProcessGroup(gconfig)
  470. pgroup.unstopped_processes = [process]
  471. L = []
  472. def callback():
  473. L.append(1)
  474. supervisord.process_groups = {'foo': pgroup}
  475. supervisord.options.mood = 0
  476. supervisord.options.test = True
  477. supervisord.runforever()
  478. self.assertNotEqual(supervisord.lastshutdownreport, 0)
  479. def test_getSupervisorStateDescription(self):
  480. from supervisor.states import getSupervisorStateDescription
  481. from supervisor.states import SupervisorStates
  482. result = getSupervisorStateDescription(SupervisorStates.RUNNING)
  483. self.assertEqual(result, 'RUNNING')
  484. def test_tick(self):
  485. from supervisor import events
  486. L = []
  487. def callback(event):
  488. L.append(event)
  489. events.subscribe(events.TickEvent, callback)
  490. options = DummyOptions()
  491. supervisord = self._makeOne(options)
  492. supervisord.tick(now=0)
  493. self.assertEqual(supervisord.ticks[5], 0)
  494. self.assertEqual(supervisord.ticks[60], 0)
  495. self.assertEqual(supervisord.ticks[3600], 0)
  496. self.assertEqual(len(L), 0)
  497. supervisord.tick(now=6)
  498. self.assertEqual(supervisord.ticks[5], 5)
  499. self.assertEqual(supervisord.ticks[60], 0)
  500. self.assertEqual(supervisord.ticks[3600], 0)
  501. self.assertEqual(len(L), 1)
  502. self.assertEqual(L[-1].__class__, events.Tick5Event)
  503. supervisord.tick(now=61)
  504. self.assertEqual(supervisord.ticks[5], 60)
  505. self.assertEqual(supervisord.ticks[60], 60)
  506. self.assertEqual(supervisord.ticks[3600], 0)
  507. self.assertEqual(len(L), 3)
  508. self.assertEqual(L[-1].__class__, events.Tick60Event)
  509. supervisord.tick(now=3601)
  510. self.assertEqual(supervisord.ticks[5], 3600)
  511. self.assertEqual(supervisord.ticks[60], 3600)
  512. self.assertEqual(supervisord.ticks[3600], 3600)
  513. self.assertEqual(len(L), 6)
  514. self.assertEqual(L[-1].__class__, events.Tick3600Event)
  515. def test_suite():
  516. return unittest.findTestCases(sys.modules[__name__])
  517. if __name__ == '__main__':
  518. unittest.main(defaultTest='test_suite')