def test_enqueue_wait_splitpolicy(self): splitpolicy1 = self.mox.CreateMock(QueuePolicy) splitpolicy2 = self.mox.CreateMock(QueuePolicy) regpolicy = self.mox.CreateMock(QueuePolicy) env1 = Envelope('*****@*****.**', ['*****@*****.**']) env2 = Envelope('*****@*****.**', ['*****@*****.**']) env3 = Envelope('*****@*****.**', ['*****@*****.**']) splitpolicy1.apply(self.env).AndReturn([env1, env2]) regpolicy.apply(env1) splitpolicy2.apply(env1) regpolicy.apply(env2) splitpolicy2.apply(env2).AndReturn([env2, env3]) self.store.write(env1, IsA(float)).AndReturn('1234') self.store.write(env2, IsA(float)).AndReturn('5678') self.store.write(env3, IsA(float)).AndReturn('90AB') self.relay._attempt(env1, 0).InAnyOrder('relay') self.relay._attempt(env2, 0).InAnyOrder('relay') self.relay._attempt(env3, 0).InAnyOrder('relay') self.store.remove('1234').InAnyOrder('relay') self.store.remove('5678').InAnyOrder('relay') self.store.remove('90AB').InAnyOrder('relay') self.mox.ReplayAll() queue = Queue(self.store, self.relay, relay_pool=5) queue.add_policy(splitpolicy1) queue.add_policy(regpolicy) queue.add_policy(splitpolicy2) self.assertEqual([(env1, '1234'), (env2, '5678'), (env3, '90AB')], queue.enqueue(self.env)) queue.relay_pool.join()
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_write(self): self.storage.redis.hsetnx(Func(_is_prefixed_id), 'envelope', IsA(bytes)).AndReturn(0) self.storage.redis.hsetnx(Func(_is_prefixed_id), 'envelope', IsA(bytes)).AndReturn(1) pipe = self.mox.CreateMockAnything() self.storage.redis.pipeline().AndReturn(pipe) def _verify_hmset(val): self.assertEqual(1234567890, val['timestamp']) self.assertEqual(0, val['attempts']) self.assertFalse('envelope' in val) return True pipe.hmset(Func(_is_prefixed_id), Func(_verify_hmset)) def _verify_rpush(val): timestamp, id = cPickle.loads(val) self.assertEqual(1234567890, timestamp) self.assertTrue(_is_id(id)) return True pipe.rpush('test:queue', Func(_verify_rpush)) pipe.execute() self.mox.ReplayAll() env = Envelope('*****@*****.**', ['*****@*****.**']) env.timestamp = 9876543210 self.storage.write(env, 1234567890)
def message_to_envelope(message): generated_message = message.message() envelope = Envelope() envelope.parse(generated_message.as_bytes()) envelope.sender = message.from_email envelope.recipients.append(message.to[0]) return envelope
def test_add_date_header_existing(self): env = Envelope() env.parse('Date: testing\r\n') adh = AddDateHeader() self.assertEqual('testing', env.headers['Date']) adh.apply(env) self.assertEqual('testing', env.headers['Date'])
def test_no_matches(self): env = Envelope('*****@*****.**', ['*****@*****.**']) fwd = Forward() fwd.add_mapping(r'nomatch', 'test') fwd.apply(env) self.assertEqual('*****@*****.**', env.sender) self.assertEqual(['*****@*****.**'], env.recipients)
def as_envelope(self, must_raise=True): envelope = Envelope() headers_filters.process( self.headers, self, settings.TRANSACTIONAL['HEADERS_FILTERS_PARAMS']) headers = "" for key, value in self.headers.items(): if key in ('Subject', ): header = make_header(decode_header(value), header_name=key, maxlinelen=78) value = header.encode(linesep='\r\n') headers += "{}: {}\n".format(key, value) message = "" if self.message: message = self.message.content or "" if self.message is None and must_raise: raise Exception("Can't build this envelope because " "there is no RawMail attached to it.") envelope.parse(headers.encode('utf-8') + message.encode('utf-8')) envelope.sender = self.sender envelope.recipients.append(self.recipient) return envelope
def test_enqueue_wait_partial_relay(self): env = Envelope( '*****@*****.**', ['*****@*****.**', '*****@*****.**', '*****@*****.**']) self.store.write(env, IsA(float)).AndReturn('1234') self.relay._attempt(env, 0).AndReturn({ '*****@*****.**': None, '*****@*****.**': TransientRelayError('transient', Reply('450', 'transient')), '*****@*****.**': PermanentRelayError('permanent', Reply('550', 'permanent')) }) self.store.increment_attempts('1234') self.store.set_timestamp('1234', IsA(float)) self.store.set_recipients_delivered('1234', set([0, 2])) self.mox.ReplayAll() def backoff(envelope, attempts): return 0 def no_bounce(envelope, reply): return None queue = Queue(self.store, self.relay, backoff=backoff, bounce_factory=no_bounce, relay_pool=5) queue.enqueue(env) queue.relay_pool.join()
def test_write(self, l): env = Envelope('*****@*****.**', ['*****@*****.**']) self.log.write('123abc', env) l.check(( 'test', 'DEBUG', 'queue:123abc:write recipients=[\'[email protected]\'] sender=\'[email protected]\'' ))
def test_deliver_multircpt(self): result = self.mox.CreateMock(AsyncResult) env = Envelope( '*****@*****.**', ['*****@*****.**', '*****@*****.**', '*****@*****.**']) env.parse(b'From: [email protected]\r\n\r\ntest test\r\n') self.sock.sendall(b'LHLO 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\nRCPT TO:<*****@*****.**>\r\nRCPT TO:<*****@*****.**>\r\nDATA\r\n' ) self.sock.recv(IsA(int)).AndReturn( b'250 Ok\r\n250 Ok\r\n550 Nope\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\n450 Yikes\r\n') result.set({ '*****@*****.**': None, '*****@*****.**': IsA(PermanentRelayError), '*****@*****.**': IsA(TransientRelayError) }) self.sock.sendall(b'RSET\r\n') self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n') self.mox.ReplayAll() client = LmtpRelayClient('addr', self.queue, socket_creator=self._socket_creator, ehlo_as='test') client._connect() client._ehlo() client._deliver(result, env)
def test_deliver_conversion(self): result = self.mox.CreateMock(AsyncResult) env = Envelope('*****@*****.**', ['*****@*****.**']) env.parse(b'From: [email protected]\r\n\r\ntest test \x81\r\n') self.sock.sendall(b'LHLO 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\nContent-Transfer-Encoding: base64\r\n\r\ndGVzdCB0ZXN0IIENCg==\n\r\n.\r\n' ) self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n') result.set({'*****@*****.**': None}) self.mox.ReplayAll() client = LmtpRelayClient('addr', self.queue, socket_creator=self._socket_creator, ehlo_as='test', binary_encoder=encode_base64) client._connect() client._ehlo() client._deliver(result, env)
def test_write_msg_queue_exception(self): env = Envelope('*****@*****.**', ['*****@*****.**']) self.obj_store.write_message(env, 1234.0).AndReturn('testid') self.msg_queue.queue_message('testid', 1234.0).AndRaise(Exception) self.mox.ReplayAll() storage = CloudStorage(self.obj_store, self.msg_queue) self.assertEqual('testid', storage.write(env, 1234.0))
def setUp(self): super(TestRackspaceCloudFiles, self).setUp() self.auth = self.mox.CreateMock(RackspaceCloudAuth) self.auth.token_id = 'tokenid' self.auth.files_endpoint = 'http://files/v1' self.env = Envelope('*****@*****.**', ['*****@*****.**']) self.pickled_env = cPickle.dumps(self.env, cPickle.HIGHEST_PROTOCOL)
def mk_envelope(self, data, sender=None, recipients=None): env = Envelope(sender=sender) env.parse(data) if not recipients: recipients = ['root@localhost'] env.recipients = recipients return env
def test_recipientsplit_apply(self): env = Envelope('*****@*****.**', ['*****@*****.**', '*****@*****.**']) env.parse("""\ From: [email protected] To: [email protected] To: [email protected] test test\r """) policy = RecipientSplit() env1, env2 = policy.apply(env) assert_equal('*****@*****.**', env1.sender) assert_equal(['*****@*****.**'], env1.recipients) assert_equal('*****@*****.**', env1.headers['from']) assert_equal(['*****@*****.**', '*****@*****.**'], env1.headers.get_all('To')) assert_equal('test test\r\n', env1.message) assert_equal('*****@*****.**', env2.sender) assert_equal(['*****@*****.**'], env2.recipients) assert_equal('*****@*****.**', env2.headers['from']) assert_equal(['*****@*****.**', '*****@*****.**'], env2.headers.get_all('To')) assert_equal('test test\r\n', env2.message)
def test_attempt(self): self.mox.StubOutWithMock(subprocess, 'Popen') env = Envelope('*****@*****.**', ['*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**']) env.parse(b'From: [email protected]\r\n\r\ntest test\r\n') self._mock_popen('*****@*****.**', 0, '') self._mock_popen('*****@*****.**', 1337, 'transient') self._mock_popen('*****@*****.**', 1337, '5.0.0 permanent') subprocess.Popen(['relaytest', '-f', '*****@*****.**', '*****@*****.**'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE).AndRaise(Timeout) self.mox.ReplayAll() m = PipeRelay(['relaytest', '-f', '{sender}', '{recipient}']) results = m.attempt(env, 0) self.assertEqual(4, len(results)) self.assertEqual(None, results['*****@*****.**']) self.assertIsInstance(results['*****@*****.**'], TransientRelayError) self.assertEqual('transient', str(results['*****@*****.**'])) self.assertEqual('450', results['*****@*****.**'].reply.code) self.assertIsInstance(results['*****@*****.**'], PermanentRelayError) self.assertEqual('5.0.0 permanent', str(results['*****@*****.**'])) self.assertEqual('550', results['*****@*****.**'].reply.code) self.assertIsInstance(results['*****@*****.**'], TransientRelayError) self.assertEqual('Delivery timed out', str(results['*****@*****.**'])) self.assertEqual('450', results['*****@*****.**'].reply.code)
def test_enqueue_wait_partial_relay_expired(self): env = Envelope( '*****@*****.**', ['*****@*****.**', '*****@*****.**', '*****@*****.**']) bounce_mock = self.mox.CreateMockAnything() bounce_mock(IsA(Envelope), IsA(Reply)).AndReturn(None) bounce_mock(IsA(Envelope), IsA(Reply)).AndReturn(None) self.store.write(env, IsA(float)).AndReturn('1234') self.relay._attempt(env, 0).AndReturn({ '*****@*****.**': TransientRelayError('transient', Reply('450', 'transient 1')), '*****@*****.**': TransientRelayError('transient', Reply('450', 'transient 1')), '*****@*****.**': TransientRelayError('transient', Reply('450', 'transient 2')) }) self.store.increment_attempts('1234') self.store.remove('1234') self.mox.ReplayAll() queue = Queue(self.store, self.relay, bounce_factory=bounce_mock, relay_pool=5) queue.enqueue(env) queue.relay_pool.join()
def test_attempt(self): env = Envelope() m = PipeRelay(['relaytest']) self.mox.StubOutWithMock(m, '_exec_process') m._exec_process(env).AndReturn((0, '', '')) self.mox.ReplayAll() m.attempt(env, 0)
def test_queueerror(self): self.queue.enqueue(IsA(Envelope)).AndReturn([(Envelope(), QueueError()) ]) self.start_response.__call__('500 Internal Server Error', IsA(list)) self.mox.ReplayAll() w = WsgiEdge(self.queue) self.assertEqual([], w(self.environ, self.start_response))
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_deliver_conversion(self): result = AsyncResult() env = Envelope('*****@*****.**', ['*****@*****.**']) env.parse(b'From: [email protected]\r\n\r\ntest test \x81\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') if pycompat.PY3: self.sock.sendall( b'From: [email protected]\r\nContent-Transfer-Encoding: base64\r\n\r\ndGVzdCB0ZXN0IIEK\r\n.\r\n' ) else: self.sock.sendall( b'From: [email protected]\r\nContent-Transfer-Encoding: base64\r\n\r\ndGVzdCB0ZXN0IIENCg==\r\n.\r\n' ) self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n') self.mox.ReplayAll() client = SmtpRelayClient(('addr', 0), self.queue, socket_creator=self._socket_creator, ehlo_as='there', binary_encoder=encode_base64) client._connect() client._ehlo() client._deliver(result, env) self.assertEqual({'*****@*****.**': Reply('250', 'Ok')}, result.get_nowait())
def as_envelope(self): message = self.as_message() envelope = Envelope() envelope.parse(message.message().as_bytes()) envelope.sender = message.from_email envelope.recipients.append(self.recipient) return envelope
def test_deliver(self): result = AsyncResult() env = Envelope('*****@*****.**', ['*****@*****.**']) env.parse(b'From: [email protected]\r\n\r\ntest test \x81\r\n') self.sock.sendall(b'EHLO there\r\n') self.sock.recv(IsA(int)).AndReturn(b'250-Hello\r\n250 8BITMIME\r\n') self.sock.sendall(b'MAIL FROM:<*****@*****.**>\r\n') self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n') self.sock.sendall(b'RCPT TO:<*****@*****.**>\r\n') self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n') self.sock.sendall(b'DATA\r\n') self.sock.recv(IsA(int)).AndReturn(b'354 Go ahead\r\n') self.sock.sendall( b'From: [email protected]\r\n\r\ntest test \x81\r\n.\r\n') self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n') self.mox.ReplayAll() client = SmtpRelayClient(('addr', 0), self.queue, socket_creator=self._socket_creator, ehlo_as='there') client._connect() client._ehlo() client._deliver(result, env) self.assertEqual({'*****@*****.**': Reply('250', 'Ok')}, result.get_nowait())
def test_deliver_baddata(self): result = AsyncResult() env = Envelope('*****@*****.**', ['*****@*****.**']) env.parse(b'From: [email protected]\r\n\r\ntest test\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'450 Yikes\r\n') self.sock.sendall(b'RSET\r\n') self.sock.recv(IsA(int)).AndReturn(b'250 Ok\r\n') self.mox.ReplayAll() client = SmtpRelayClient(('addr', 0), self.queue, socket_creator=self._socket_creator, ehlo_as='there') client._connect() client._ehlo() client._deliver(result, env) with self.assertRaises(TransientRelayError): result.get_nowait()
def test_add_message_id_header_existing(self): env = Envelope() env.parse(b'Message-Id: testing\r\n') amih = AddMessageIdHeader() self.assertEqual('testing', env.headers['Message-Id']) amih.apply(env) self.assertEqual('testing', env.headers['Message-Id'])
def test_attempt_timeout(self): env = Envelope() m = PipeRelay(['relaytest']) self.mox.StubOutWithMock(m, '_exec_process') m._exec_process(env).AndRaise(Timeout) self.mox.ReplayAll() with self.assertRaises(TransientRelayError): m.attempt(env, 0)
def test_add_date_header(self): env = Envelope() env.parse(b'') env.timestamp = 1234567890 adh = AddDateHeader() self.assertEqual(None, env.headers['Date']) adh.apply(env) self.assertTrue(env.headers['Date'])
def test_add_date_header_existing(self): env = Envelope() epoch = 'Thu, 01 Jan 1970 00:00:00 -0000' env.parse(b'Date: ' + epoch.encode() + b'\r\n') adh = AddDateHeader() self.assertEqual(epoch, env.headers['Date']) adh.apply(env) self.assertEqual(epoch, env.headers['Date'])
def test_attempt_permanentfail(self): env = Envelope() m = PipeRelay(['relaytest']) self.mox.StubOutWithMock(m, '_exec_process') m._exec_process(env).AndReturn((13, '5.0.0 permanent failure', '')) self.mox.ReplayAll() with self.assertRaises(PermanentRelayError): m.attempt(env, 0)