[b5d87e0] | 1 | import pytest |
---|
| 2 | from unittest.mock import patch, Mock |
---|
| 3 | |
---|
| 4 | from ow.tasks.mail import queue_processor |
---|
| 5 | |
---|
| 6 | |
---|
| 7 | class TestQueueProcessor(object): |
---|
| 8 | |
---|
| 9 | @pytest.fixture |
---|
| 10 | def settings(self): |
---|
| 11 | settings = { |
---|
| 12 | 'qp.host': 'hostname', |
---|
| 13 | 'qp.username': 'username', |
---|
| 14 | 'qp.password': 'xxxxxxxx', |
---|
| 15 | 'mail.queue_path': '/some/path', |
---|
| 16 | 'mail.queue_processor_lock': '/tmp/queue-processor.lock'} |
---|
| 17 | return settings |
---|
| 18 | |
---|
| 19 | @pytest.fixture |
---|
| 20 | def alt_settings(self): |
---|
| 21 | alt_settings = { |
---|
| 22 | 'mail.host': 'mail-hostname', |
---|
| 23 | 'mail.username': 'mail-username', |
---|
| 24 | 'mail.password': 'yyyyyyyyyyyyy', |
---|
| 25 | 'mail.queue_path': '/some/path', |
---|
| 26 | 'mail.queue_processor_lock': '/tmp/queue-processor.lock'} |
---|
| 27 | return alt_settings |
---|
| 28 | |
---|
| 29 | def wrap_settings(self, settings): |
---|
| 30 | registry = Mock(settings=settings) |
---|
| 31 | return {'registry': registry} |
---|
| 32 | |
---|
| 33 | def params(self, settings): |
---|
| 34 | """ |
---|
| 35 | Return a list of arguments that ressembles what should be passed |
---|
| 36 | to the ConsoleApp queue processor in the "real" code |
---|
| 37 | """ |
---|
| 38 | args = ['qp', |
---|
| 39 | '--hostname', settings.get('qp.host', |
---|
| 40 | settings.get('mail.host')), |
---|
| 41 | '--username', settings.get('qp.username', |
---|
| 42 | settings.get('mail.username')), |
---|
| 43 | '--password', settings.get('qp.password', |
---|
| 44 | settings.get('mail.password')), |
---|
| 45 | settings.get('mail.queue_path')] |
---|
| 46 | return args |
---|
| 47 | |
---|
| 48 | @patch('fcntl.lockf') |
---|
| 49 | @patch('ow.tasks.mail.ConsoleApp') |
---|
| 50 | def test_queue_processor_settings(self, ca, lockf, settings): |
---|
| 51 | queue_processor(self.wrap_settings(settings)) |
---|
| 52 | ca.assert_called_with(self.params(settings)) |
---|
| 53 | # the lockf was called, to set the lock on the lock file |
---|
| 54 | assert lockf.called |
---|
| 55 | |
---|
| 56 | @patch('fcntl.lockf') |
---|
| 57 | @patch('ow.tasks.mail.ConsoleApp') |
---|
| 58 | def test_queue_processor_alt_settings(self, ca, lockf, alt_settings): |
---|
| 59 | queue_processor(self.wrap_settings(alt_settings)) |
---|
| 60 | ca.assert_called_with(self.params(alt_settings)) |
---|
| 61 | # the lockf was called, to set the lock on the lock file |
---|
| 62 | assert lockf.called |
---|
| 63 | |
---|
| 64 | @patch('fcntl.lockf') |
---|
| 65 | @patch('ow.tasks.mail.log') |
---|
| 66 | @patch('ow.tasks.mail.ConsoleApp') |
---|
| 67 | def test_queue_processor_lock_ioerror(self, ca, log, lockf, settings): |
---|
| 68 | """ |
---|
| 69 | A second call to the queue processor while a previous run is still |
---|
| 70 | running will find a lock on the lock file, which means this call cannot |
---|
| 71 | continue, so it is aborted and a warning message is logged to the |
---|
| 72 | logging facilities |
---|
| 73 | """ |
---|
| 74 | # Make lock raise an IOError, mimicing what happens when the lock has |
---|
| 75 | # been acquired by another process |
---|
| 76 | e = IOError('could not lock file!') |
---|
| 77 | lockf.side_effect = e |
---|
| 78 | |
---|
| 79 | ret = queue_processor(self.wrap_settings(settings)) |
---|
| 80 | # Exception raised, False returned |
---|
| 81 | assert ret is False |
---|
| 82 | |
---|
| 83 | # Calls: fcntl.lock has been called, then the IOError was raised |
---|
| 84 | # and no more calls to the api have been made |
---|
| 85 | assert lockf.called |
---|
| 86 | assert not ca.called |
---|
| 87 | |
---|
| 88 | # except for the log call, which was a warning |
---|
| 89 | assert log.warning.called |
---|