test_supervisord.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  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. 'stderr_logfile': None, 'stderr_capture_maxbytes': 0,
  253. 'stderr_events_enabled': False,
  254. 'stderr_logfile_backups': 0, 'stderr_logfile_maxbytes': 0,
  255. 'redirect_stderr': False,
  256. 'stopsignal': None, 'stopwaitsecs': 10,
  257. 'stopasgroup': False,
  258. 'killasgroup': False,
  259. 'exitcodes': (0,2), 'environment': None, 'serverurl': None }
  260. result.update(params)
  261. return ProcessConfig(options, **result)
  262. def make_gconfig(name, pconfigs):
  263. return ProcessGroupConfig(options, name, 25, pconfigs)
  264. pconfig = make_pconfig('process1', 'process1', uid='new')
  265. group1 = make_gconfig('group1', [pconfig])
  266. pconfig = make_pconfig('process2', 'process2')
  267. group2 = make_gconfig('group2', [pconfig])
  268. new = [group1, group2]
  269. pconfig = make_pconfig('process1', 'process1', uid='old')
  270. group3 = make_gconfig('group1', [pconfig])
  271. pconfig = make_pconfig('process2', 'process2')
  272. group4 = make_gconfig('group2', [pconfig])
  273. supervisord.add_process_group(group3)
  274. supervisord.add_process_group(group4)
  275. added, changed, removed = supervisord.diff_to_active(new)
  276. self.assertEqual([added, removed], [[], []])
  277. self.assertEqual(changed, [group1])
  278. options = DummyOptions()
  279. supervisord = self._makeOne(options)
  280. pconfig1 = make_pconfig('process1', 'process1')
  281. pconfig2 = make_pconfig('process2', 'process2')
  282. group1 = make_gconfig('group1', [pconfig1, pconfig2])
  283. new = [group1]
  284. supervisord.add_process_group(make_gconfig('group1', [pconfig1]))
  285. added, changed, removed = supervisord.diff_to_active(new)
  286. self.assertEqual([added, removed], [[], []])
  287. self.assertEqual(changed, [group1])
  288. def test_add_process_group(self):
  289. options = DummyOptions()
  290. pconfig = DummyPConfig(options, 'foo', 'foo', '/bin/foo')
  291. gconfig = DummyPGroupConfig(options,'foo', pconfigs=[pconfig])
  292. options.process_group_configs = [gconfig]
  293. supervisord = self._makeOne(options)
  294. self.assertEqual(supervisord.process_groups, {})
  295. result = supervisord.add_process_group(gconfig)
  296. self.assertEqual(supervisord.process_groups.keys(), ['foo'])
  297. self.assertTrue(result)
  298. group = supervisord.process_groups['foo']
  299. result = supervisord.add_process_group(gconfig)
  300. self.assertEqual(group, supervisord.process_groups['foo'])
  301. self.assertTrue(not result)
  302. def test_add_process_group_event(self):
  303. from supervisor import events
  304. L = []
  305. def callback(event):
  306. L.append(1)
  307. events.subscribe(events.ProcessGroupAddedEvent, callback)
  308. options = DummyOptions()
  309. pconfig = DummyPConfig(options, 'foo', 'foo', '/bin/foo')
  310. gconfig = DummyPGroupConfig(options,'foo', pconfigs=[pconfig])
  311. options.process_group_configs = [gconfig]
  312. supervisord = self._makeOne(options)
  313. supervisord.add_process_group(gconfig)
  314. options.test = True
  315. supervisord.runforever()
  316. self.assertEqual(L, [1])
  317. def test_remove_process_group(self):
  318. options = DummyOptions()
  319. pconfig = DummyPConfig(options, 'foo', 'foo', '/bin/foo')
  320. gconfig = DummyPGroupConfig(options, 'foo', pconfigs=[pconfig])
  321. supervisord = self._makeOne(options)
  322. self.assertRaises(KeyError, supervisord.remove_process_group, 'asdf')
  323. supervisord.add_process_group(gconfig)
  324. result = supervisord.remove_process_group('foo')
  325. self.assertEqual(supervisord.process_groups, {})
  326. self.assertTrue(result)
  327. supervisord.add_process_group(gconfig)
  328. supervisord.process_groups['foo'].unstopped_processes = [DummyProcess(None)]
  329. result = supervisord.remove_process_group('foo')
  330. self.assertEqual(supervisord.process_groups.keys(), ['foo'])
  331. self.assertTrue(not result)
  332. def test_remove_process_group_event(self):
  333. from supervisor import events
  334. L = []
  335. def callback(event):
  336. L.append(1)
  337. events.subscribe(events.ProcessGroupRemovedEvent, callback)
  338. options = DummyOptions()
  339. pconfig = DummyPConfig(options, 'foo', 'foo', '/bin/foo')
  340. gconfig = DummyPGroupConfig(options,'foo', pconfigs=[pconfig])
  341. options.process_group_configs = [gconfig]
  342. supervisord = self._makeOne(options)
  343. supervisord.add_process_group(gconfig)
  344. supervisord.process_groups['foo'].stopped_processes = [DummyProcess(None)]
  345. supervisord.remove_process_group('foo')
  346. options.test = True
  347. supervisord.runforever()
  348. self.assertEqual(L, [1])
  349. def test_runforever_emits_generic_startup_event(self):
  350. from supervisor import events
  351. L = []
  352. def callback(event):
  353. L.append(1)
  354. events.subscribe(events.SupervisorStateChangeEvent, callback)
  355. options = DummyOptions()
  356. supervisord = self._makeOne(options)
  357. options.test = True
  358. supervisord.runforever()
  359. self.assertEqual(L, [1])
  360. def test_runforever_emits_generic_specific_event(self):
  361. from supervisor import events
  362. L = []
  363. def callback(event):
  364. L.append(2)
  365. events.subscribe(events.SupervisorRunningEvent, callback)
  366. options = DummyOptions()
  367. options.test = True
  368. supervisord = self._makeOne(options)
  369. supervisord.runforever()
  370. self.assertEqual(L, [2])
  371. def test_runforever_calls_tick(self):
  372. options = DummyOptions()
  373. options.test = True
  374. supervisord = self._makeOne(options)
  375. self.assertEqual(len(supervisord.ticks), 0)
  376. supervisord.runforever()
  377. self.assertEqual(len(supervisord.ticks), 3)
  378. def test_runforever_select_eintr(self):
  379. options = DummyOptions()
  380. import errno
  381. options.select_error = errno.EINTR
  382. supervisord = self._makeOne(options)
  383. options.test = True
  384. supervisord.runforever()
  385. self.assertEqual(options.logger.data[0], 'EINTR encountered in select')
  386. def test_runforever_select_uncaught_exception(self):
  387. options = DummyOptions()
  388. import errno
  389. options.select_error = errno.EBADF
  390. supervisord = self._makeOne(options)
  391. import select
  392. options.test = True
  393. self.assertRaises(select.error, supervisord.runforever)
  394. def test_runforever_select_dispatchers(self):
  395. options = DummyOptions()
  396. supervisord = self._makeOne(options)
  397. pconfig = DummyPConfig(options, 'foo', '/bin/foo',)
  398. gconfig = DummyPGroupConfig(options, pconfigs=[pconfig])
  399. pgroup = DummyProcessGroup(gconfig)
  400. readable = DummyDispatcher(readable=True)
  401. writable = DummyDispatcher(writable=True)
  402. error = DummyDispatcher(writable=True, error=OSError)
  403. pgroup.dispatchers = {6:readable, 7:writable, 8:error}
  404. supervisord.process_groups = {'foo': pgroup}
  405. options.select_result = [6], [7, 8], []
  406. options.test = True
  407. supervisord.runforever()
  408. self.assertEqual(pgroup.transitioned, True)
  409. self.assertEqual(readable.read_event_handled, True)
  410. self.assertEqual(writable.write_event_handled, True)
  411. self.assertEqual(error.error_handled, True)
  412. def test_runforever_select_dispatcher_exitnow(self):
  413. options = DummyOptions()
  414. supervisord = self._makeOne(options)
  415. pconfig = DummyPConfig(options, 'foo', '/bin/foo',)
  416. gconfig = DummyPGroupConfig(options, pconfigs=[pconfig])
  417. pgroup = DummyProcessGroup(gconfig)
  418. from supervisor.medusa import asyncore_25 as asyncore
  419. exitnow = DummyDispatcher(readable=True, error=asyncore.ExitNow)
  420. pgroup.dispatchers = {6:exitnow}
  421. supervisord.process_groups = {'foo': pgroup}
  422. options.select_result = [6], [], []
  423. options.test = True
  424. self.assertRaises(asyncore.ExitNow, supervisord.runforever)
  425. def test_runforever_stopping_emits_events(self):
  426. options = DummyOptions()
  427. supervisord = self._makeOne(options)
  428. gconfig = DummyPGroupConfig(options)
  429. pgroup = DummyProcessGroup(gconfig)
  430. supervisord.process_groups = {'foo': pgroup}
  431. supervisord.options.mood = -1
  432. L = []
  433. def callback(event):
  434. L.append(event)
  435. from supervisor import events
  436. events.subscribe(events.SupervisorStateChangeEvent, callback)
  437. from supervisor.medusa import asyncore_25 as asyncore
  438. options.test = True
  439. self.assertRaises(asyncore.ExitNow, supervisord.runforever)
  440. self.assertTrue(pgroup.all_stopped)
  441. self.assertTrue(isinstance(L[0], events.SupervisorRunningEvent))
  442. self.assertTrue(isinstance(L[0], events.SupervisorStateChangeEvent))
  443. self.assertTrue(isinstance(L[1], events.SupervisorStoppingEvent))
  444. self.assertTrue(isinstance(L[1], events.SupervisorStateChangeEvent))
  445. def test_exit(self):
  446. options = DummyOptions()
  447. supervisord = self._makeOne(options)
  448. pconfig = DummyPConfig(options, 'foo', '/bin/foo',)
  449. gconfig = DummyPGroupConfig(options, pconfigs=[pconfig])
  450. pgroup = DummyProcessGroup(gconfig)
  451. L = []
  452. def callback():
  453. L.append(1)
  454. supervisord.process_groups = {'foo': pgroup}
  455. supervisord.options.mood = 0
  456. supervisord.options.test = True
  457. from supervisor.medusa import asyncore_25 as asyncore
  458. self.assertRaises(asyncore.ExitNow, supervisord.runforever)
  459. self.assertEqual(pgroup.all_stopped, True)
  460. def test_exit_delayed(self):
  461. options = DummyOptions()
  462. supervisord = self._makeOne(options)
  463. pconfig = DummyPConfig(options, 'foo', '/bin/foo',)
  464. process = DummyProcess(pconfig)
  465. gconfig = DummyPGroupConfig(options, pconfigs=[pconfig])
  466. pgroup = DummyProcessGroup(gconfig)
  467. pgroup.unstopped_processes = [process]
  468. L = []
  469. def callback():
  470. L.append(1)
  471. supervisord.process_groups = {'foo': pgroup}
  472. supervisord.options.mood = 0
  473. supervisord.options.test = True
  474. supervisord.runforever()
  475. self.assertNotEqual(supervisord.lastshutdownreport, 0)
  476. def test_getSupervisorStateDescription(self):
  477. from supervisor.states import getSupervisorStateDescription
  478. from supervisor.states import SupervisorStates
  479. result = getSupervisorStateDescription(SupervisorStates.RUNNING)
  480. self.assertEqual(result, 'RUNNING')
  481. def test_tick(self):
  482. from supervisor import events
  483. L = []
  484. def callback(event):
  485. L.append(event)
  486. events.subscribe(events.TickEvent, callback)
  487. options = DummyOptions()
  488. supervisord = self._makeOne(options)
  489. supervisord.tick(now=0)
  490. self.assertEqual(supervisord.ticks[5], 0)
  491. self.assertEqual(supervisord.ticks[60], 0)
  492. self.assertEqual(supervisord.ticks[3600], 0)
  493. self.assertEqual(len(L), 0)
  494. supervisord.tick(now=6)
  495. self.assertEqual(supervisord.ticks[5], 5)
  496. self.assertEqual(supervisord.ticks[60], 0)
  497. self.assertEqual(supervisord.ticks[3600], 0)
  498. self.assertEqual(len(L), 1)
  499. self.assertEqual(L[-1].__class__, events.Tick5Event)
  500. supervisord.tick(now=61)
  501. self.assertEqual(supervisord.ticks[5], 60)
  502. self.assertEqual(supervisord.ticks[60], 60)
  503. self.assertEqual(supervisord.ticks[3600], 0)
  504. self.assertEqual(len(L), 3)
  505. self.assertEqual(L[-1].__class__, events.Tick60Event)
  506. supervisord.tick(now=3601)
  507. self.assertEqual(supervisord.ticks[5], 3600)
  508. self.assertEqual(supervisord.ticks[60], 3600)
  509. self.assertEqual(supervisord.ticks[3600], 3600)
  510. self.assertEqual(len(L), 6)
  511. self.assertEqual(L[-1].__class__, events.Tick3600Event)
  512. def test_suite():
  513. return unittest.findTestCases(sys.modules[__name__])
  514. if __name__ == '__main__':
  515. unittest.main(defaultTest='test_suite')