test_celery.py 9.1 KB

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