1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
14:
15: namespace Avisota\Test;
16:
17: use Avisota\Event\PostTransportMessageEvent;
18: use Avisota\Event\PreTransportMessageEvent;
19: use Avisota\Queue\EventEmittingQueueInterface;
20: use Avisota\Queue\ExecutionConfig;
21: use Avisota\Queue\LoggingQueueInterface;
22: use Avisota\Test\Imap\ImapMailboxChecker;
23: use Avisota\Test\Message\TestMessage;
24: use Avisota\Test\Queue\TestQueueExecutionDecider;
25: use Avisota\Test\Transport\NoOpTransport;
26: use Doctrine\DBAL\Configuration;
27: use Doctrine\DBAL\DriverManager;
28: use Doctrine\DBAL\Schema\Column;
29: use Doctrine\DBAL\Statement;
30: use Monolog\Handler\TestHandler;
31: use Monolog\Logger;
32: use Symfony\Component\EventDispatcher\Event;
33: use Symfony\Component\EventDispatcher\EventDispatcher;
34:
35: abstract class AbstractQueueTest extends \PHPUnit_Framework_TestCase
36: {
37: 38: 39:
40: protected $transportProvider = null;
41:
42: 43: 44:
45: protected $imapConnectionProvider = null;
46:
47: abstract protected function createQueue();
48:
49: 50: 51: 52:
53: protected function checkMessagesInMailbox($imapConnection, array $messages)
54: {
55: $imapMailboxChecker = new ImapMailboxChecker();
56: return $imapMailboxChecker->checkMessages($imapConnection, $messages);
57: }
58:
59: public function testSingleEnqueue()
60: {
61: $queue = $this->createQueue();
62:
63: $message = new TestMessage();
64: $queue->enqueue($message);
65:
66: $this->assertEquals(1, $queue->length());
67: $this->assertEquals(array($message), $queue->getMessages());
68: }
69:
70: public function testMultipleEnqueue()
71: {
72: $queue = $this->createQueue();
73:
74: $count = mt_rand(5, 10);
75: $messages = array();
76:
77: for ($i = 0; $i < $count; $i++) {
78: $message = new TestMessage();
79: $messages[] = $message;
80: $queue->enqueue($message);
81: }
82:
83: $this->assertEquals(
84: $count,
85: $queue->length()
86: );
87: $this->assertEquals(
88: $messages,
89: $queue->getMessages()
90: );
91: }
92:
93: public function testSingleTransport()
94: {
95: $queue = $this->createQueue();
96: $transport = $this->transportProvider->createTransport();
97: $imapConnection = $this->imapConnectionProvider->createImapConnection();
98:
99: if (!$transport) {
100: $this->markTestSkipped('Transport unavailable!');
101: return;
102: }
103:
104: $message = new TestMessage();
105: $queue->enqueue($message);
106:
107: $queue->execute($transport);
108:
109: $this->assertEquals(0, $queue->length());
110:
111: if (!$imapConnection) {
112: $this->markTestIncomplete('Cannot check send messages, because imap connection is not available.');
113: return;
114: }
115:
116: $this->assertEquals(1, $this->checkMessagesInMailbox($imapConnection, array($message)));
117: }
118:
119: public function testMultipleTransport()
120: {
121: $queue = $this->createQueue();
122: $transport = $this->transportProvider->createTransport();
123: $imapConnection = $this->imapConnectionProvider->createImapConnection();
124:
125: if (!$transport) {
126: $this->markTestSkipped('Transport unavailable!');
127: return;
128: }
129:
130: $count = mt_rand(5, 10);
131: $messages = array();
132:
133: for ($i = 0; $i < $count; $i++) {
134: $message = new TestMessage();
135: $messages[] = $message;
136: $queue->enqueue($message);
137: }
138:
139: $queue->execute($transport);
140:
141: $this->assertEquals(0, $queue->length());
142:
143: if (!$imapConnection) {
144: $this->markTestIncomplete('Cannot check send messages, because imap connection is not available.');
145: return;
146: }
147:
148: $this->assertEquals($count, $this->checkMessagesInMailbox($imapConnection, $messages));
149: }
150:
151: public function testSingleTransportDeciderDeny()
152: {
153: $queue = $this->createQueue();
154: $transport = $this->transportProvider->createTransport();
155: $imapConnection = $this->imapConnectionProvider->createImapConnection();
156:
157: if (!$transport) {
158: $this->markTestSkipped('Transport unavailable!');
159: return;
160: }
161:
162: $message = new TestMessage();
163: $queue->enqueue($message);
164:
165: $decider = new TestQueueExecutionDecider(false);
166: $config = new ExecutionConfig();
167: $config->setDecider($decider);
168:
169: $queue->execute($transport, $config);
170:
171: $this->assertEquals(
172: 1,
173: $queue->length()
174: );
175: $this->assertEquals(
176: 1,
177: $decider->getHits()
178: );
179:
180: if (!$imapConnection) {
181: $this->markTestIncomplete('Cannot check send messages, because imap connection is not available.');
182: return;
183: }
184:
185: $this->assertEquals(0, $this->checkMessagesInMailbox($imapConnection, array($message)));
186: }
187:
188: public function testSingleTransportDeciderAllow()
189: {
190: $queue = $this->createQueue();
191: $transport = $this->transportProvider->createTransport();
192: $imapConnection = $this->imapConnectionProvider->createImapConnection();
193:
194: if (!$transport) {
195: $this->markTestSkipped('Transport unavailable!');
196: return;
197: }
198:
199: $message = new TestMessage();
200: $queue->enqueue($message);
201:
202: $decider = new TestQueueExecutionDecider(true);
203: $config = new ExecutionConfig();
204: $config->setDecider($decider);
205:
206: $queue->execute($transport, $config);
207:
208: $this->assertEquals(
209: 0,
210: $queue->length()
211: );
212: $this->assertEquals(
213: 1,
214: $decider->getHits()
215: );
216:
217: if (!$imapConnection) {
218: $this->markTestIncomplete('Cannot check send messages, because imap connection is not available.');
219: return;
220: }
221:
222: $this->assertEquals(1, $this->checkMessagesInMailbox($imapConnection, array($message)));
223: }
224:
225: public function testLoggingSucceed()
226: {
227: $queue = $this->createQueue();
228:
229: if (!$queue instanceof LoggingQueueInterface) {
230: $this->markTestSkipped('Queue of type ' . get_class($queue) . ' does not log actions.');
231: return;
232: }
233:
234: $transport = new NoOpTransport(NoOpTransport::SUCCEED);
235:
236: $handler = new TestHandler();
237: $logger = new Logger('test', array($handler));
238: $queue->setLogger($logger);
239:
240: $message = new TestMessage();
241: $queue->enqueue($message);
242: $queue->execute($transport);
243:
244: $records = $handler->getRecords();
245:
246:
247: $this->assertTrue(count($records) > 0);
248:
249:
250: $this->assertTrue(
251: array_reduce(
252: $records,
253: function (&$result, $record) {
254: return $result || $record['level'] == Logger::DEBUG;
255: },
256: false
257: )
258: );
259: }
260:
261: public function testLoggingSucceedPartial()
262: {
263: $queue = $this->createQueue();
264:
265: if (!$queue instanceof LoggingQueueInterface) {
266: $this->markTestSkipped('Queue of type ' . get_class($queue) . ' does not log actions.');
267: return;
268: }
269:
270: $transport = new NoOpTransport(NoOpTransport::SUCCEED_PARTIAL);
271:
272: $handler = new TestHandler();
273: $logger = new Logger('test', array($handler));
274: $queue->setLogger($logger);
275:
276: $message = new TestMessage();
277: $queue->enqueue($message);
278: $queue->execute($transport);
279:
280: $records = $handler->getRecords();
281:
282:
283: $this->assertTrue(count($records) > 0);
284:
285:
286: $this->assertTrue(
287: array_reduce(
288: $records,
289: function (&$result, $record) {
290: return $result || $record['level'] == Logger::WARNING;
291: },
292: false
293: )
294: );
295: }
296:
297: public function testLoggingFailed()
298: {
299: $queue = $this->createQueue();
300:
301: if (!$queue instanceof LoggingQueueInterface) {
302: $this->markTestSkipped('Queue of type ' . get_class($queue) . ' does not log actions.');
303: return;
304: }
305:
306: $transport = new NoOpTransport(NoOpTransport::FAILED);
307:
308: $handler = new TestHandler();
309: $logger = new Logger('test', array($handler));
310: $queue->setLogger($logger);
311:
312: $message = new TestMessage();
313: $queue->enqueue($message);
314: $queue->execute($transport);
315:
316: $records = $handler->getRecords();
317:
318:
319: $this->assertTrue(count($records) > 0);
320:
321:
322: $this->assertTrue(
323: array_reduce(
324: $records,
325: function (&$result, $record) {
326: return $result || $record['level'] == Logger::ERROR;
327: },
328: false
329: )
330: );
331: }
332:
333: public function testEventDispatcher()
334: {
335: $queue = $this->createQueue();
336:
337: if (!$queue instanceof EventEmittingQueueInterface) {
338: $this->markTestSkipped('Queue of type ' . get_class($queue) . ' does not emit events.');
339: return;
340: }
341:
342: $transport = new NoOpTransport(NoOpTransport::FAILED);
343: $self = $this;
344: $hits = 0;
345:
346: $eventDispatcher = new EventDispatcher();
347: $eventDispatcher->addListener(
348: 'avisota_queue_execution_pre_transport',
349: function(Event $event) use ($self, &$hits) {
350: $self->assertTrue($event instanceof PreTransportMessageEvent);
351: $hits ++;
352: }
353: );
354: $eventDispatcher->addListener(
355: 'avisota_queue_execution_post_transport',
356: function(Event $event) use ($self, &$hits) {
357: $self->assertTrue($event instanceof PostTransportMessageEvent);
358: $hits ++;
359: }
360: );
361: $queue->setEventDispatcher($eventDispatcher);
362:
363: $message = new TestMessage();
364: $queue->enqueue($message);
365: $queue->execute($transport);
366:
367: $this->assertEquals(2, $hits);
368: }
369: }
370: