test_celery.py 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. from __future__ import absolute_import, unicode_literals
  2. import sys
  3. import pytest
  4. from case import Mock, patch
  5. from celery import __main__
  6. from celery.bin import celery as mod
  7. from celery.bin.base import Error
  8. from celery.bin.celery import main as mainfun
  9. from celery.bin.celery import (CeleryCommand, Command, determine_exit_status,
  10. help, multi, report)
  11. from celery.five import WhateverIO
  12. from celery.platforms import EX_FAILURE, EX_OK, EX_USAGE
  13. class test__main__:
  14. def test_main(self):
  15. with patch('celery.__main__.maybe_patch_concurrency') as mpc:
  16. with patch('celery.bin.celery.main') as main:
  17. __main__.main()
  18. mpc.assert_called_with()
  19. main.assert_called_with()
  20. def test_main__multi(self):
  21. with patch('celery.__main__.maybe_patch_concurrency') as mpc:
  22. with patch('celery.bin.celery.main') as main:
  23. prev, sys.argv = sys.argv, ['foo', 'multi']
  24. try:
  25. __main__.main()
  26. mpc.assert_not_called()
  27. main.assert_called_with()
  28. finally:
  29. sys.argv = prev
  30. class test_Command:
  31. def test_Error_repr(self):
  32. x = Error('something happened')
  33. assert x.status is not None
  34. assert x.reason
  35. assert str(x)
  36. def setup(self):
  37. self.out = WhateverIO()
  38. self.err = WhateverIO()
  39. self.cmd = Command(self.app, stdout=self.out, stderr=self.err)
  40. def test_error(self):
  41. self.cmd.out = Mock()
  42. self.cmd.error('FOO')
  43. self.cmd.out.assert_called()
  44. def test_out(self):
  45. f = Mock()
  46. self.cmd.out('foo', f)
  47. def test_call(self):
  48. def ok_run():
  49. pass
  50. self.cmd.run = ok_run
  51. assert self.cmd() == EX_OK
  52. def error_run():
  53. raise Error('error', EX_FAILURE)
  54. self.cmd.run = error_run
  55. assert self.cmd() == EX_FAILURE
  56. def test_run_from_argv(self):
  57. with pytest.raises(NotImplementedError):
  58. self.cmd.run_from_argv('prog', ['foo', 'bar'])
  59. def test_pretty_list(self):
  60. assert self.cmd.pretty([])[1] == '- empty -'
  61. assert 'bar', self.cmd.pretty(['foo' in 'bar'][1])
  62. def test_pretty_dict(self, text='the quick brown fox'):
  63. assert 'OK' in str(self.cmd.pretty({'ok': text})[0])
  64. assert 'ERROR' in str(self.cmd.pretty({'error': text})[0])
  65. def test_pretty(self):
  66. assert 'OK' in str(self.cmd.pretty('the quick brown'))
  67. assert 'OK' in str(self.cmd.pretty(object()))
  68. assert 'OK' in str(self.cmd.pretty({'foo': 'bar'}))
  69. class test_report:
  70. def test_run(self):
  71. out = WhateverIO()
  72. r = report(app=self.app, stdout=out)
  73. assert r.run() == EX_OK
  74. assert out.getvalue()
  75. class test_help:
  76. def test_run(self):
  77. out = WhateverIO()
  78. h = help(app=self.app, stdout=out)
  79. h.parser = Mock()
  80. assert h.run() == EX_USAGE
  81. assert out.getvalue()
  82. assert h.usage('help')
  83. h.parser.print_help.assert_called_with()
  84. class test_CeleryCommand:
  85. def test_execute_from_commandline(self):
  86. x = CeleryCommand(app=self.app)
  87. x.handle_argv = Mock()
  88. x.handle_argv.return_value = 1
  89. with pytest.raises(SystemExit):
  90. x.execute_from_commandline()
  91. x.handle_argv.return_value = True
  92. with pytest.raises(SystemExit):
  93. x.execute_from_commandline()
  94. x.handle_argv.side_effect = KeyboardInterrupt()
  95. with pytest.raises(SystemExit):
  96. x.execute_from_commandline()
  97. x.respects_app_option = True
  98. with pytest.raises(SystemExit):
  99. x.execute_from_commandline(['celery', 'multi'])
  100. assert not x.respects_app_option
  101. x.respects_app_option = True
  102. with pytest.raises(SystemExit):
  103. x.execute_from_commandline(['manage.py', 'celery', 'multi'])
  104. assert not x.respects_app_option
  105. def test_with_pool_option(self):
  106. x = CeleryCommand(app=self.app)
  107. assert x.with_pool_option(['celery', 'events']) is None
  108. assert x.with_pool_option(['celery', 'worker'])
  109. assert x.with_pool_option(['manage.py', 'celery', 'worker'])
  110. def test_load_extensions_no_commands(self):
  111. with patch('celery.bin.celery.Extensions') as Ext:
  112. ext = Ext.return_value = Mock(name='Extension')
  113. ext.load.return_value = None
  114. x = CeleryCommand(app=self.app)
  115. x.load_extension_commands()
  116. def test_load_extensions_commands(self):
  117. with patch('celery.bin.celery.Extensions') as Ext:
  118. prev, mod.command_classes = list(mod.command_classes), Mock()
  119. try:
  120. ext = Ext.return_value = Mock(name='Extension')
  121. ext.load.return_value = ['foo', 'bar']
  122. x = CeleryCommand(app=self.app)
  123. x.load_extension_commands()
  124. mod.command_classes.append.assert_called_with(
  125. ('Extensions', ['foo', 'bar'], 'magenta'),
  126. )
  127. finally:
  128. mod.command_classes = prev
  129. def test_determine_exit_status(self):
  130. assert determine_exit_status('true') == EX_OK
  131. assert determine_exit_status('') == EX_FAILURE
  132. def test_relocate_args_from_start(self):
  133. x = CeleryCommand(app=self.app)
  134. assert x._relocate_args_from_start(None) == []
  135. relargs1 = x._relocate_args_from_start([
  136. '-l', 'debug', 'worker', '-c', '3', '--foo',
  137. ])
  138. assert relargs1 == ['worker', '-c', '3', '--foo', '-l', 'debug']
  139. relargs2 = x._relocate_args_from_start([
  140. '--pool=gevent', '-l', 'debug', 'worker', '--foo', '-c', '3',
  141. ])
  142. assert relargs2 == [
  143. 'worker', '--foo', '-c', '3',
  144. '--pool=gevent', '-l', 'debug',
  145. ]
  146. assert x._relocate_args_from_start(['foo', '--foo=1']) == [
  147. 'foo', '--foo=1',
  148. ]
  149. def test_register_command(self):
  150. prev, CeleryCommand.commands = dict(CeleryCommand.commands), {}
  151. try:
  152. fun = Mock(name='fun')
  153. CeleryCommand.register_command(fun, name='foo')
  154. assert CeleryCommand.commands['foo'] is fun
  155. finally:
  156. CeleryCommand.commands = prev
  157. def test_handle_argv(self):
  158. x = CeleryCommand(app=self.app)
  159. x.execute = Mock()
  160. x.handle_argv('celery', [])
  161. x.execute.assert_called_with('help', ['help'])
  162. x.handle_argv('celery', ['start', 'foo'])
  163. x.execute.assert_called_with('start', ['start', 'foo'])
  164. def test_execute(self):
  165. x = CeleryCommand(app=self.app)
  166. Help = x.commands['help'] = Mock()
  167. help = Help.return_value = Mock()
  168. x.execute('fooox', ['a'])
  169. help.run_from_argv.assert_called_with(x.prog_name, [], command='help')
  170. help.reset()
  171. x.execute('help', ['help'])
  172. help.run_from_argv.assert_called_with(x.prog_name, [], command='help')
  173. Dummy = x.commands['dummy'] = Mock()
  174. dummy = Dummy.return_value = Mock()
  175. exc = dummy.run_from_argv.side_effect = Error(
  176. 'foo', status='EX_FAILURE',
  177. )
  178. x.on_error = Mock(name='on_error')
  179. help.reset()
  180. x.execute('dummy', ['dummy'])
  181. x.on_error.assert_called_with(exc)
  182. dummy.run_from_argv.assert_called_with(
  183. x.prog_name, [], command='dummy',
  184. )
  185. help.run_from_argv.assert_called_with(
  186. x.prog_name, [], command='help',
  187. )
  188. exc = dummy.run_from_argv.side_effect = x.UsageError('foo')
  189. x.on_usage_error = Mock()
  190. x.execute('dummy', ['dummy'])
  191. x.on_usage_error.assert_called_with(exc)
  192. def test_on_usage_error(self):
  193. x = CeleryCommand(app=self.app)
  194. x.error = Mock()
  195. x.on_usage_error(x.UsageError('foo'), command=None)
  196. x.error.assert_called()
  197. x.on_usage_error(x.UsageError('foo'), command='dummy')
  198. def test_prepare_prog_name(self):
  199. x = CeleryCommand(app=self.app)
  200. main = Mock(name='__main__')
  201. main.__file__ = '/opt/foo.py'
  202. with patch.dict(sys.modules, __main__=main):
  203. assert x.prepare_prog_name('__main__.py') == '/opt/foo.py'
  204. assert x.prepare_prog_name('celery') == 'celery'
  205. class test_multi:
  206. def test_get_options(self):
  207. assert multi(app=self.app).get_options() is None
  208. def test_run_from_argv(self):
  209. with patch('celery.bin.multi.MultiTool') as MultiTool:
  210. m = MultiTool.return_value = Mock()
  211. multi(self.app).run_from_argv('celery', ['arg'], command='multi')
  212. m.execute_from_commandline.assert_called_with(['multi', 'arg'])
  213. class test_main:
  214. @patch('celery.bin.celery.CeleryCommand')
  215. def test_main(self, Command):
  216. cmd = Command.return_value = Mock()
  217. mainfun()
  218. cmd.execute_from_commandline.assert_called_with(None)
  219. @patch('celery.bin.celery.CeleryCommand')
  220. def test_main_KeyboardInterrupt(self, Command):
  221. cmd = Command.return_value = Mock()
  222. cmd.execute_from_commandline.side_effect = KeyboardInterrupt()
  223. mainfun()
  224. cmd.execute_from_commandline.assert_called_with(None)