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 |
---|