def test_run_multiple(self): result1 = self.mox.CreateMock(AsyncResult) result2 = self.mox.CreateMock(AsyncResult) env1 = Envelope('*****@*****.**', ['*****@*****.**']) env1.parse('From: [email protected]\r\n\r\ntest test\r\n') env2 = Envelope('*****@*****.**', ['*****@*****.**']) env2.parse('From: [email protected]\r\n\r\ntest test\r\n') queue = BlockingDeque() queue.append((result1, env1)) queue.append((result2, env2)) self.sock.recv(IsA(int)).AndReturn('220 Welcome\r\n') self.sock.sendall('EHLO test\r\n') self.sock.recv(IsA(int)).AndReturn('250-Hello\r\n250 PIPELINING\r\n') self.sock.sendall('MAIL FROM:<*****@*****.**>\r\nRCPT TO:<*****@*****.**>\r\nDATA\r\n') self.sock.recv(IsA(int)).AndReturn('250 Ok\r\n250 Ok\r\n354 Go ahead\r\n') self.sock.sendall('From: [email protected]\r\n\r\ntest test\r\n.\r\n') self.sock.recv(IsA(int)).AndReturn('250 Ok\r\n') result1.set([None]) self.sock.sendall('MAIL FROM:<*****@*****.**>\r\nRCPT TO:<*****@*****.**>\r\nDATA\r\n') self.sock.recv(IsA(int)).AndReturn('250 Ok\r\n250 Ok\r\n354 Go ahead\r\n') self.sock.sendall('From: [email protected]\r\n\r\ntest test\r\n.\r\n') self.sock.recv(IsA(int)).AndReturn('250 Ok\r\n') result2.set([None]) self.sock.sendall('QUIT\r\n') self.sock.recv(IsA(int)).AndReturn('221 Goodbye\r\n') self.sock.close() self.mox.ReplayAll() client = SmtpRelayClient(None, queue, socket_creator=self._socket_creator, ehlo_as='test', idle_timeout=0.0) client._run()
def test_run(self): result = self.mox.CreateMock(AsyncResult) env = Envelope('*****@*****.**', ['*****@*****.**']) env.parse('From: [email protected]\r\n\r\ntest test\r\n') queue = BlockingDeque() queue.append((result, env)) self.sock.recv(IsA(int)).AndReturn('220 Welcome\r\n') self.sock.sendall('EHLO test\r\n') self.sock.recv(IsA(int)).AndReturn('250-Hello\r\n250 PIPELINING\r\n') self.sock.sendall( 'MAIL FROM:<*****@*****.**>\r\nRCPT TO:<*****@*****.**>\r\nDATA\r\n' ) self.sock.recv( IsA(int)).AndReturn('250 Ok\r\n250 Ok\r\n354 Go ahead\r\n') self.sock.sendall('From: [email protected]\r\n\r\ntest test\r\n.\r\n') self.sock.recv(IsA(int)).AndReturn('250 Ok\r\n') result.set(True) self.sock.sendall('QUIT\r\n') self.sock.recv(IsA(int)).AndReturn('221 Goodbye\r\n') self.sock.close() self.mox.ReplayAll() client = SmtpRelayClient(None, queue, socket_creator=self._socket_creator, ehlo_as='test') client._run()
def test_run(self): result = AsyncResult() env = Envelope('*****@*****.**', ['*****@*****.**']) env.parse(b'From: [email protected]\r\n\r\ntest test\r\n') queue = BlockingDeque() queue.append((result, env)) self.sock.recv(IsA(int)).AndReturn(b'220 Welcome\r\n') self.sock.sendall(b'EHLO there\r\n') self.sock.recv(IsA(int)).AndReturn(b'250-Hello\r\n250 PIPELINING\r\n') self.sock.sendall( b'MAIL FROM:<*****@*****.**>\r\nRCPT TO:<*****@*****.**>\r\nDATA\r\n' ) self.sock.recv( IsA(int)).AndReturn(b'250 Ok\r\n250 Ok\r\n354 Go ahead\r\n') self.sock.sendall( b'From: [email protected]\r\n\r\ntest test\r\n.\r\n') self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n') self.sock.sendall(b'QUIT\r\n') self.sock.recv(IsA(int)).AndReturn(b'221 Goodbye\r\n') self.sock.close() self.mox.ReplayAll() client = SmtpRelayClient(('addr', 0), queue, socket_creator=self._socket_creator, ehlo_as='there') client._run() self.assertEqual({'*****@*****.**': Reply('250', 'Ok')}, result.get_nowait())
def test_run_multiple(self): result1 = AsyncResult() result2 = AsyncResult() env1 = Envelope('*****@*****.**', ['*****@*****.**']) env1.parse(b'From: [email protected]\r\n\r\ntest test\r\n') env2 = Envelope('*****@*****.**', ['*****@*****.**']) env2.parse(b'From: [email protected]\r\n\r\ntest test\r\n') queue = BlockingDeque() queue.append((result1, env1)) queue.append((result2, env2)) self.sock.recv(IsA(int)).AndReturn(b'220 Welcome\r\n') self.sock.sendall(b'EHLO test\r\n') self.sock.recv(IsA(int)).AndReturn(b'250-Hello\r\n250 PIPELINING\r\n') self.sock.sendall(b'MAIL FROM:<*****@*****.**>\r\nRCPT TO:<*****@*****.**>\r\nDATA\r\n') self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n250 Ok\r\n354 Go ahead\r\n') self.sock.sendall(b'From: [email protected]\r\n\r\ntest test\r\n.\r\n') self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n') self.sock.sendall(b'MAIL FROM:<*****@*****.**>\r\nRCPT TO:<*****@*****.**>\r\nDATA\r\n') self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n250 Ok\r\n354 Go ahead\r\n') self.sock.sendall(b'From: [email protected]\r\n\r\ntest test\r\n.\r\n') self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n') self.sock.sendall(b'QUIT\r\n') self.sock.recv(IsA(int)).AndReturn(b'221 Goodbye\r\n') self.sock.close() self.mox.ReplayAll() client = SmtpRelayClient('addr', queue, socket_creator=self._socket_creator, ehlo_as='test', idle_timeout=0.0) client._run() self.assertEqual({'*****@*****.**': Reply('250', 'Ok')}, result1.get_nowait()) self.assertEqual({'*****@*****.**': Reply('250', 'Ok')}, result2.get_nowait())
class RelayPool(Relay): """Base class that inherits |Relay| to add the ability to create bounded, cached pools of outbound clients. It maintains a queue of messages to be delivered such that idle clients in the pool pick them up. :param pool_size: At most this many simultaneous connections will be open to a destination. If this limit is reached and no connections are idle, new attempts will block. """ def __init__(self, pool_size=None): super(RelayPool, self).__init__() self.pool = set() self.pool_size = pool_size #: This attribute holds the queue object for providing delivery #: requests to idle clients in the pool. self.queue = BlockingDeque() def kill(self): for client in self.pool: client.kill() def _remove_client(self, client): self.pool.remove(client) if len(self.queue) > 0 and not self.pool: self._add_client() def _add_client(self): client = self.add_client() client.queue = self.queue client.start() client.link(self._remove_client) self.pool.add(client) def _check_idle(self): for client in self.pool: if client.idle: return if not self.pool_size or len(self.pool) < self.pool_size: self._add_client() def add_client(self): """Sub-classes must override this method to create and return a new :class:`RelayPoolClient` object that will poll for delivery requests. :rtype: :class:`RelayPoolClient` """ raise NotImplementedError() def attempt(self, envelope, attempts): self._check_idle() result = AsyncResult() self.queue.append((result, envelope)) return result.get()
def test_run_banner_failure(self): result = self.mox.CreateMock(AsyncResult) env = Envelope('*****@*****.**', ['*****@*****.**']) env.parse('From: [email protected]\r\n\r\ntest test\r\n') queue = BlockingDeque() queue.append((result, env)) self.sock.recv(IsA(int)).AndReturn('520 Not Welcome\r\n') result.set_exception(IsA(PermanentRelayError)) self.sock.sendall('QUIT\r\n') self.sock.recv(IsA(int)).AndReturn('221 Goodbye\r\n') self.sock.close() self.mox.ReplayAll() client = SmtpRelayClient(None, queue, socket_creator=self._socket_creator, ehlo_as='test') client._run()
def test_run_banner_failure(self): result = AsyncResult() env = Envelope('*****@*****.**', ['*****@*****.**']) env.parse(b'From: [email protected]\r\n\r\ntest test\r\n') queue = BlockingDeque() queue.append((result, env)) self.sock.recv(IsA(int)).AndReturn(b'520 Not Welcome\r\n') self.sock.sendall(b'QUIT\r\n') self.sock.recv(IsA(int)).AndReturn(b'221 Goodbye\r\n') self.sock.close() self.mox.ReplayAll() client = SmtpRelayClient('addr', queue, socket_creator=self._socket_creator, ehlo_as='test') client._run() with self.assertRaises(PermanentRelayError): result.get_nowait()
def test_run_timeout(self): result = self.mox.CreateMock(AsyncResult) env = Envelope('*****@*****.**', ['*****@*****.**']) env.parse('From: [email protected]\r\n\r\ntest test\r\n') queue = BlockingDeque() queue.append((result, env)) self.sock.recv(IsA(int)).AndRaise(Timeout(0.0)) result.ready().AndReturn(False) result.set_exception(IsA(TransientRelayError)) self.sock.sendall('QUIT\r\n') self.sock.recv(IsA(int)).AndReturn('221 Goodbye\r\n') self.sock.close() self.mox.ReplayAll() client = SmtpRelayClient(None, queue, socket_creator=self._socket_creator, ehlo_as='test') client._run()
def test_run_smtperror(self): result = self.mox.CreateMock(AsyncResult) env = Envelope("*****@*****.**", ["*****@*****.**"]) env.parse("From: [email protected]\r\n\r\ntest test\r\n") queue = BlockingDeque() queue.append((result, env)) self.sock.recv(IsA(int)).AndRaise(SmtpError("test error")) result.ready().AndReturn(False) result.set_exception(IsA(TransientRelayError)) self.sock.sendall("QUIT\r\n") self.sock.recv(IsA(int)).AndReturn("221 Goodbye\r\n") self.sock.close() self.mox.ReplayAll() client = SmtpRelayClient(None, queue, socket_creator=self._socket_creator, ehlo_as="test") client._run()
def test_run_random_exception(self): result = AsyncResult() env = Envelope('*****@*****.**', ['*****@*****.**']) env.parse(b'From: [email protected]\r\n\r\ntest test\r\n') queue = BlockingDeque() queue.append((result, env)) self.sock.recv(IsA(int)).AndRaise(ValueError('test error')) self.sock.sendall(b'QUIT\r\n') self.sock.recv(IsA(int)).AndReturn(b'221 Goodbye\r\n') self.sock.close() self.mox.ReplayAll() client = SmtpRelayClient('addr', queue, socket_creator=self._socket_creator, ehlo_as='test') with self.assertRaises(ValueError): client._run() with self.assertRaises(ValueError): result.get_nowait()
def test_run_banner_failure(self): result = AsyncResult() env = Envelope('*****@*****.**', ['*****@*****.**']) env.parse(b'From: [email protected]\r\n\r\ntest test\r\n') queue = BlockingDeque() queue.append((result, env)) self.sock.recv(IsA(int)).AndReturn(b'520 Not Welcome\r\n') self.sock.sendall(b'QUIT\r\n') self.sock.recv(IsA(int)).AndReturn(b'221 Goodbye\r\n') self.sock.close() self.mox.ReplayAll() client = SmtpRelayClient(('addr', 0), queue, socket_creator=self._socket_creator, ehlo_as='there') client._run() with self.assertRaises(PermanentRelayError): result.get_nowait()
def test_run_smtperror(self): result = AsyncResult() env = Envelope('*****@*****.**', ['*****@*****.**']) env.parse(b'From: [email protected]\r\n\r\ntest test\r\n') queue = BlockingDeque() queue.append((result, env)) self.sock.recv(IsA(int)).AndRaise(SmtpError('test error')) self.sock.sendall(b'QUIT\r\n') self.sock.recv(IsA(int)).AndReturn(b'221 Goodbye\r\n') self.sock.close() self.mox.ReplayAll() client = SmtpRelayClient('addr', queue, socket_creator=self._socket_creator, ehlo_as='test') client._run() with self.assertRaises(TransientRelayError): result.get_nowait()
def test_run_multiple(self): result1 = AsyncResult() result2 = AsyncResult() env1 = Envelope('*****@*****.**', ['*****@*****.**']) env1.parse(b'From: [email protected]\r\n\r\ntest test\r\n') env2 = Envelope('*****@*****.**', ['*****@*****.**']) env2.parse(b'From: [email protected]\r\n\r\ntest test\r\n') queue = BlockingDeque() queue.append((result1, env1)) queue.append((result2, env2)) self.sock.recv(IsA(int)).AndReturn(b'220 Welcome\r\n') self.sock.sendall(b'EHLO test\r\n') self.sock.recv(IsA(int)).AndReturn(b'250-Hello\r\n250 PIPELINING\r\n') self.sock.sendall( b'MAIL FROM:<*****@*****.**>\r\nRCPT TO:<*****@*****.**>\r\nDATA\r\n' ) self.sock.recv( IsA(int)).AndReturn(b'250 Ok\r\n250 Ok\r\n354 Go ahead\r\n') self.sock.sendall( b'From: [email protected]\r\n\r\ntest test\r\n.\r\n') self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n') self.sock.sendall( b'MAIL FROM:<*****@*****.**>\r\nRCPT TO:<*****@*****.**>\r\nDATA\r\n' ) self.sock.recv( IsA(int)).AndReturn(b'250 Ok\r\n250 Ok\r\n354 Go ahead\r\n') self.sock.sendall( b'From: [email protected]\r\n\r\ntest test\r\n.\r\n') self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n') self.sock.sendall(b'QUIT\r\n') self.sock.recv(IsA(int)).AndReturn(b'221 Goodbye\r\n') self.sock.close() self.mox.ReplayAll() client = SmtpRelayClient('addr', queue, socket_creator=self._socket_creator, ehlo_as='test', idle_timeout=0.0) client._run() self.assertEqual({'*****@*****.**': Reply('250', 'Ok')}, result1.get_nowait()) self.assertEqual({'*****@*****.**': Reply('250', 'Ok')}, result2.get_nowait())
def test_run(self): result = AsyncResult() env = Envelope('*****@*****.**', ['*****@*****.**']) env.parse(b'From: [email protected]\r\n\r\ntest test\r\n') queue = BlockingDeque() queue.append((result, env)) self.sock.recv(IsA(int)).AndReturn(b'220 Welcome\r\n') self.sock.sendall(b'EHLO there\r\n') self.sock.recv(IsA(int)).AndReturn(b'250-Hello\r\n250 PIPELINING\r\n') self.sock.sendall(b'MAIL FROM:<*****@*****.**>\r\nRCPT TO:<*****@*****.**>\r\nDATA\r\n') self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n250 Ok\r\n354 Go ahead\r\n') self.sock.sendall(b'From: [email protected]\r\n\r\ntest test\r\n.\r\n') self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n') self.sock.sendall(b'QUIT\r\n') self.sock.recv(IsA(int)).AndReturn(b'221 Goodbye\r\n') self.sock.close() self.mox.ReplayAll() client = SmtpRelayClient(('addr', 0), queue, socket_creator=self._socket_creator, ehlo_as='there') client._run() self.assertEqual({'*****@*****.**': Reply('250', 'Ok')}, result.get_nowait())
def test_run(self): result = self.mox.CreateMock(AsyncResult) env = Envelope('*****@*****.**', ['*****@*****.**']) env.parse('From: [email protected]\r\n\r\ntest test\r\n') queue = BlockingDeque() queue.append((result, env)) self.sock.recv(IsA(int)).AndReturn('220 Welcome\r\n') self.sock.sendall('EHLO test\r\n') self.sock.recv(IsA(int)).AndReturn('250-Hello\r\n250 PIPELINING\r\n') self.sock.sendall('MAIL FROM:<*****@*****.**>\r\nRCPT TO:<*****@*****.**>\r\nDATA\r\n') self.sock.recv(IsA(int)).AndReturn('250 Ok\r\n250 Ok\r\n354 Go ahead\r\n') self.sock.sendall('From: [email protected]\r\n\r\ntest test\r\n.\r\n') self.sock.recv(IsA(int)).AndReturn('250 Ok\r\n') result.set(True) self.sock.sendall('QUIT\r\n') self.sock.recv(IsA(int)).AndReturn('221 Goodbye\r\n') self.sock.close() self.mox.ReplayAll() client = SmtpRelayClient(None, queue, socket_creator=self._socket_creator, ehlo_as='test') client._run()
class TestBlockingDeque(MoxTestBase, unittest.TestCase): def setUp(self): super(TestBlockingDeque, self).setUp() self.deque = BlockingDeque() self.deque.sema = self.mox.CreateMockAnything() def test_append(self): self.deque.sema.release() self.mox.ReplayAll() self.deque.append(True) def test_appendleft(self): self.deque.sema.release() self.mox.ReplayAll() self.deque.appendleft(True) def test_clear(self): for i in range(3): self.deque.sema.release() for i in range(3): self.deque.sema.locked().AndReturn(False) self.deque.sema.acquire(blocking=False) self.deque.sema.locked().AndReturn(True) self.mox.ReplayAll() self.deque.append(True) self.deque.append(True) self.deque.append(True) self.deque.clear() def test_extend(self): self.deque.sema.release() self.deque.sema.release() self.deque.sema.release() self.mox.ReplayAll() self.deque.extend([1, 2, 3]) def test_extendleft(self): self.deque.sema.release() self.deque.sema.release() self.deque.sema.release() self.mox.ReplayAll() self.deque.extendleft([1, 2, 3]) def test_pop(self): self.deque.sema.release() self.deque.sema.release() self.deque.sema.acquire() self.mox.ReplayAll() self.deque.append(4) self.deque.append(5) self.assertEqual(5, self.deque.pop()) def test_popleft(self): self.deque.sema.release() self.deque.sema.release() self.deque.sema.acquire() self.mox.ReplayAll() self.deque.append(4) self.deque.append(5) self.assertEqual(4, self.deque.popleft()) def test_remove(self): self.deque.sema.release() self.deque.sema.release() self.deque.sema.acquire() self.mox.ReplayAll() self.deque.append(4) self.deque.append(5) self.deque.remove(4) def test_remove_notfound(self): self.deque.sema.release() self.deque.sema.release() self.mox.ReplayAll() self.deque.append(4) self.deque.append(5) with self.assertRaises(ValueError): self.deque.remove(6)