class FakeRedisTestCase(TestCase): def test_delete(self): self.r_server = FakeRedis() self.r_server.set("delete_me", 1) self.assertEqual(True, self.r_server.delete("delete_me")) self.assertEqual(False, self.r_server.delete("delete_me")) def test_incr(self): self.r_server = FakeRedis() self.r_server.set("inc", 1) self.assertEqual('1', self.r_server.get("inc")) self.assertEqual(2, self.r_server.incr("inc")) self.assertEqual(3, self.r_server.incr("inc")) self.assertEqual('3', self.r_server.get("inc")) def test_incr_with_by_param(self): self.r_server = FakeRedis() self.r_server.set("inc", 1) self.assertEqual('1', self.r_server.get("inc")) self.assertEqual(2, self.r_server.incr("inc", 1)) self.assertEqual(4, self.r_server.incr("inc", 2)) self.assertEqual(7, self.r_server.incr("inc", 3)) self.assertEqual(11, self.r_server.incr("inc", 4)) self.assertEqual(111, self.r_server.incr("inc", 100)) self.assertEqual('111', self.r_server.get("inc")) def test_zrange(self): self.r_server = FakeRedis() self.r_server.zadd('set', one=0.1, two=0.2, three=0.3) self.assertEqual(self.r_server.zrange('set', 0, 0), ['one']) self.assertEqual(self.r_server.zrange('set', 0, 1), ['one', 'two']) self.assertEqual(self.r_server.zrange('set', 0, 2), ['one', 'two', 'three']) self.assertEqual(self.r_server.zrange('set', 0, 3), ['one', 'two', 'three']) self.assertEqual(self.r_server.zrange('set', 0, -1), ['one', 'two', 'three']) self.assertEqual(self.r_server.zrange('set', 0, -1, withscores=True), [(0.1, 'one'), (0.2, 'two'), (0.3, 'three')]) self.assertEqual(self.r_server.zrange('set', 0, -1, desc=True), ['three', 'two', 'one']) self.assertEqual( self.r_server.zrange('set', 0, -1, desc=True, withscores=True), [(0.3, 'three'), (0.2, 'two'), (0.1, 'one')]) def test_hgetall_returns_copy(self): self.r_server = FakeRedis() self.r_server.hset("hash", "foo", "1") data = self.r_server.hgetall("hash") data["foo"] = "2" self.assertEqual(self.r_server.hgetall("hash"), { "foo": "1", }) def test_hincrby(self): self.r_server = FakeRedis() hincrby = self.r_server.hincrby self.assertEqual(hincrby("inc", "field1"), 1) self.assertEqual(hincrby("inc", "field1"), 2) self.assertEqual(hincrby("inc", "field1", 3), 5) self.assertEqual(hincrby("inc", "field1", "2"), 7) self.assertRaises(Exception, hincrby, "inc", "field1", "1.5") self.r_server.hset("inc", "field2", "a") self.assertRaises(Exception, hincrby, "inc", "field2") self.r_server.set("key", "string") self.assertRaises(Exception, self.r_server.hincrby, "key", "field1") def test_sadd(self): self.r_server = FakeRedis() self.r_server.sadd('set', 1) self.r_server.sadd('set', 2, 3, 4) self.assertEqual(self.r_server.smembers('set'), set(['1', '2', '3', '4'])) def test_smove(self): self.r_server = FakeRedis() self.r_server.sadd('set1', 1) self.r_server.sadd('set2', 2) self.assertEqual(self.r_server.smove('set1', 'set2', '1'), True) self.assertEqual(self.r_server.smembers('set1'), set()) self.assertEqual(self.r_server.smembers('set2'), set(['1', '2'])) self.assertEqual(self.r_server.smove('set1', 'set2', '1'), False) self.assertEqual(self.r_server.smove('set2', 'set3', '1'), True) self.assertEqual(self.r_server.smembers('set2'), set(['2'])) self.assertEqual(self.r_server.smembers('set3'), set(['1'])) def test_sunion(self): self.r_server = FakeRedis() self.r_server.sadd('set1', 1) self.r_server.sadd('set2', 2) self.assertEqual(self.r_server.sunion('set1'), set(['1'])) self.assertEqual(self.r_server.sunion('set1', 'set2'), set(['1', '2'])) self.assertEqual(self.r_server.sunion('other'), set())
class Vas2NetsFailureWorkerTestCase(unittest.TestCase): @inlineCallbacks def setUp(self): self.today = datetime.utcnow().date() self.port = 9999 self.path = "/api/v1/sms/vas2nets/receive/" self.config = { "transport_name": "vas2nets", "url": "http://localhost:%s%s" % (self.port, self.path), "username": "******", "password": "******", "owner": "owner", "service": "service", "subservice": "subservice", "web_receive_path": "/receive", "web_receipt_path": "/receipt", "web_port": 9998, } self.fail_config = { "transport_name": "vas2nets", "retry_routing_key": "sms.outbound.%(transport_name)s", "failures_routing_key": "sms.outbound.%(transport_name)s.failures", } self.workers = [] self.broker = FakeAMQPBroker() self.redis = FakeRedis() self.worker = yield self.mk_transport_worker(self.config, self.broker) self.fail_worker = yield self.mk_failure_worker(self.fail_config, self.broker, self.redis) def tearDown(self): for worker in self.workers: worker.stopWorker() @inlineCallbacks def mk_transport_worker(self, config, broker): worker = get_stubbed_worker(Vas2NetsTransport, config, broker) self.workers.append(worker) yield worker.startWorker() returnValue(worker) @inlineCallbacks def mk_failure_worker(self, config, broker, redis): w = get_stubbed_worker(Vas2NetsFailureWorker, config, broker) self.workers.append(w) yield w.startWorker() w.retry_publisher = yield self.worker.publish_to("foo") w.r_server = redis returnValue(w) @inlineCallbacks def mk_resource_worker(self, body, headers=None, code=http.OK): w = get_stubbed_worker(TestResourceWorker, {}, self.broker) self.workers.append(w) w.set_resources([(self.path, BadVas2NetsResource, (body, headers, code))]) yield w.startWorker() returnValue(w) def get_dispatched(self, rkey): return self.broker.get_dispatched("vumi", rkey) def get_retry_keys(self): timestamps = self.redis.zrange(self.fail_worker._retry_timestamps_key, 0, 0) retry_keys = set() for timestamp in timestamps: bucket_key = self.fail_worker.r_key("retry_keys." + timestamp) retry_keys.update(self.redis.smembers(bucket_key)) return retry_keys def mkmsg_out(self, in_reply_to=None): msg = TransportSMS( transport="vas2nets", to_addr="+27761234567", from_addr="9292", message_id="1", in_reply_to=in_reply_to, transport_metadata={"network_id": "network-id"}, message="hello world", ) return msg def assert_dispatched_count(self, count, routing_key): self.assertEqual(count, len(self.get_dispatched(routing_key))) @inlineCallbacks def test_send_sms_success(self): yield self.mk_resource_worker("Result_code: 00, Message OK") yield self.worker.handle_outbound_message(self.mkmsg_out()) self.assert_dispatched_count(1, "sms.ack.vas2nets") self.assert_dispatched_count(0, "sms.failures.vas2nets") @inlineCallbacks def test_send_sms_fail(self): """ A 'No SmsId Header' error should not be retried. """ self.worker.failure_published = FailureCounter(1) self.worker.SUPPRESS_EXCEPTIONS = True yield self.mk_resource_worker("Result_code: 04, Internal system error " "occurred while processing message", {}) yield self.worker.handle_outbound_message(self.mkmsg_out()) yield self.worker.failure_published.deferred self.assert_dispatched_count(0, "sms.ack.vas2nets") self.assert_dispatched_count(1, "sms.outbound.vas2nets.failures") [fmsg] = self.get_dispatched("sms.outbound.vas2nets.failures") fmsg = from_json(fmsg.body) self.assertTrue("Vas2NetsTransportError: No SmsId Header" in fmsg["reason"]) yield self.broker.kick_delivery() [key] = self.fail_worker.get_failure_keys() self.assertEqual(set(), self.get_retry_keys()) @inlineCallbacks def test_send_sms_noconn(self): """ A 'connection refused' error should be retried. """ self.worker.failure_published = FailureCounter(1) self.worker.SUPPRESS_EXCEPTIONS = True msg = self.mkmsg_out() yield self.worker.handle_outbound_message(msg) yield self.worker.failure_published.deferred self.assert_dispatched_count(0, "sms.ack.vas2nets") self.assert_dispatched_count(1, "sms.outbound.vas2nets.failures") [fmsg] = self.get_dispatched("sms.outbound.vas2nets.failures") fmsg = from_json(fmsg.body) self.assertEqual(msg, fmsg["message"]) self.assertEqual("connection refused", fmsg["reason"]) yield self.broker.kick_delivery() [key] = self.fail_worker.get_failure_keys() self.assertEqual(set([key]), self.get_retry_keys())
class Vas2NetsFailureWorkerTestCase(unittest.TestCase): @inlineCallbacks def setUp(self): self.today = datetime.utcnow().date() self.port = 9999 self.path = '/api/v1/sms/vas2nets/receive/' self.config = { 'transport_name': 'vas2nets', 'url': 'http://localhost:%s%s' % (self.port, self.path), 'username': '******', 'password': '******', 'owner': 'owner', 'service': 'service', 'subservice': 'subservice', 'web_receive_path': '/receive', 'web_receipt_path': '/receipt', 'web_port': 9998, } self.fail_config = { 'transport_name': 'vas2nets', 'retry_routing_key': '%(transport_name)s.outbound', 'failures_routing_key': '%(transport_name)s.failures', } self.workers = [] self.broker = FakeAMQPBroker() self.redis = FakeRedis() self.worker = yield self.mk_transport_worker(self.config, self.broker) self.fail_worker = yield self.mk_failure_worker( self.fail_config, self.broker, self.redis) def tearDown(self): for worker in self.workers: worker.stopWorker() @inlineCallbacks def mk_transport_worker(self, config, broker): worker = get_stubbed_worker(Vas2NetsTransport, config, broker) self.workers.append(worker) yield worker.startWorker() returnValue(worker) @inlineCallbacks def mk_failure_worker(self, config, broker, redis): w = get_stubbed_worker(FailureWorker, config, broker) self.workers.append(w) yield w.startWorker() w.retry_publisher = yield self.worker.publish_to("foo") w.r_server = redis returnValue(w) @inlineCallbacks def mk_resource_worker(self, body, headers=None, code=http.OK): w = get_stubbed_worker(TestResourceWorker, {}, self.broker) self.workers.append(w) w.set_resources([(self.path, BadVas2NetsResource, (body, headers, code))]) yield w.startWorker() returnValue(w) def get_dispatched(self, rkey): return self.broker.get_dispatched('vumi', rkey) def get_retry_keys(self): timestamps = self.redis.zrange( self.fail_worker._retry_timestamps_key, 0, 0) retry_keys = set() for timestamp in timestamps: bucket_key = self.fail_worker.r_key("retry_keys." + timestamp) retry_keys.update(self.redis.smembers(bucket_key)) return retry_keys def mkmsg_out(self, in_reply_to=None): return TransportUserMessage( to_addr='+41791234567', from_addr='9292', message_id='1', transport_name='vas2nets', transport_type='sms', transport_metadata={ 'network_id': 'network-id', }, content='hello world', in_reply_to=in_reply_to, ) def assert_dispatched_count(self, count, routing_key): self.assertEqual(count, len(self.get_dispatched(routing_key))) @inlineCallbacks def test_send_sms_success(self): yield self.mk_resource_worker("Result_code: 00, Message OK") yield self.worker._process_message(self.mkmsg_out()) self.assert_dispatched_count(1, 'vas2nets.event') self.assert_dispatched_count(0, 'vas2nets.failures') @inlineCallbacks def test_send_sms_fail(self): """ A 'No SmsId Header' error should not be retried. """ self.worker.failure_published = FailureCounter(1) yield self.mk_resource_worker("Result_code: 04, Internal system error " "occurred while processing message", {}) yield self.worker._process_message(self.mkmsg_out()) yield self.worker.failure_published.deferred yield self.broker.kick_delivery() self.assert_dispatched_count(0, 'vas2nets.event') self.assert_dispatched_count(1, 'vas2nets.failures') [fmsg] = self.get_dispatched('vas2nets.failures') fmsg = from_json(fmsg.body) self.assertTrue( "Vas2NetsTransportError: No SmsId Header" in fmsg['reason']) yield self.broker.kick_delivery() [key] = self.fail_worker.get_failure_keys() self.assertEqual(set(), self.get_retry_keys()) @inlineCallbacks def test_send_sms_noconn(self): """ A 'connection refused' error should be retried. """ self.worker.failure_published = FailureCounter(1) msg = self.mkmsg_out() yield self.worker._process_message(msg) yield self.worker.failure_published.deferred self.assert_dispatched_count(0, 'vas2nets.event') self.assert_dispatched_count(1, 'vas2nets.failures') [fmsg] = self.get_dispatched('vas2nets.failures') fmsg = from_json(fmsg.body) self.assertEqual(msg.payload, fmsg['message']) self.assertEqual(FailureMessage.FC_TEMPORARY, fmsg['failure_code']) self.assertTrue(fmsg['reason'].strip().endswith("connection refused")) yield self.broker.kick_delivery() [key] = self.fail_worker.get_failure_keys() self.assertEqual(set([key]), self.get_retry_keys())
class Vas2NetsFailureWorkerTestCase(unittest.TestCase): @inlineCallbacks def setUp(self): self.today = datetime.utcnow().date() self.port = 9999 self.path = '/api/v1/sms/vas2nets/receive/' self.config = { 'transport_name': 'vas2nets', 'url': 'http://localhost:%s%s' % (self.port, self.path), 'username': '******', 'password': '******', 'owner': 'owner', 'service': 'service', 'subservice': 'subservice', 'web_receive_path': '/receive', 'web_receipt_path': '/receipt', 'web_port': 9998, } self.fail_config = { 'transport_name': 'vas2nets', 'retry_routing_key': '%(transport_name)s.outbound', 'failures_routing_key': '%(transport_name)s.failures', } self.workers = [] self.broker = FakeAMQPBroker() self.redis = FakeRedis() self.worker = yield self.mk_transport_worker(self.config, self.broker) self.fail_worker = yield self.mk_failure_worker( self.fail_config, self.broker, self.redis) def tearDown(self): for worker in self.workers: worker.stopWorker() @inlineCallbacks def mk_transport_worker(self, config, broker): worker = get_stubbed_worker(Vas2NetsTransport, config, broker) self.workers.append(worker) yield worker.startWorker() returnValue(worker) @inlineCallbacks def mk_failure_worker(self, config, broker, redis): w = get_stubbed_worker(FailureWorker, config, broker) self.workers.append(w) w.retry_publisher = yield self.worker.publish_to("foo") w.r_server = redis yield w.startWorker() returnValue(w) @inlineCallbacks def mk_resource_worker(self, body, headers=None, code=http.OK): w = get_stubbed_worker(TestResourceWorker, {}, self.broker) self.workers.append(w) w.set_resources([(self.path, BadVas2NetsResource, (body, headers, code))]) yield w.startWorker() returnValue(w) def get_dispatched(self, rkey): return self.broker.get_dispatched('vumi', rkey) def get_retry_keys(self): timestamps = self.redis.zrange( self.fail_worker._retry_timestamps_key, 0, 0) retry_keys = set() for timestamp in timestamps: bucket_key = self.fail_worker.r_key("retry_keys." + timestamp) retry_keys.update(self.redis.smembers(bucket_key)) return retry_keys def mkmsg_out(self, in_reply_to=None): return TransportUserMessage( to_addr='+41791234567', from_addr='9292', message_id='1', transport_name='vas2nets', transport_type='sms', transport_metadata={ 'network_id': 'network-id', }, content='hello world', in_reply_to=in_reply_to, ) def assert_dispatched_count(self, count, routing_key): self.assertEqual(count, len(self.get_dispatched(routing_key))) @inlineCallbacks def test_send_sms_success(self): yield self.mk_resource_worker("Result_code: 00, Message OK") yield self.worker._process_message(self.mkmsg_out()) self.assert_dispatched_count(1, 'vas2nets.event') self.assert_dispatched_count(0, 'vas2nets.failures') @inlineCallbacks def test_send_sms_fail(self): """ A 'No SmsId Header' error should not be retried. """ self.worker.failure_published = FailureCounter(1) yield self.mk_resource_worker("Result_code: 04, Internal system error " "occurred while processing message", {}) yield self.worker._process_message(self.mkmsg_out()) yield self.worker.failure_published.deferred yield self.broker.kick_delivery() self.assert_dispatched_count(0, 'vas2nets.event') self.assert_dispatched_count(1, 'vas2nets.failures') [twisted_failure] = self.flushLoggedErrors(Vas2NetsTransportError) failure = twisted_failure.value self.assertTrue("No SmsId Header" in str(failure)) [fmsg] = self.get_dispatched('vas2nets.failures') fmsg = from_json(fmsg.body) self.assertTrue( "Vas2NetsTransportError: No SmsId Header" in fmsg['reason']) yield self.broker.kick_delivery() [key] = self.fail_worker.get_failure_keys() self.assertEqual(set(), self.get_retry_keys()) @inlineCallbacks def test_send_sms_noconn(self): """ A 'connection refused' error should be retried. """ self.worker.failure_published = FailureCounter(1) msg = self.mkmsg_out() yield self.worker._process_message(msg) yield self.worker.failure_published.deferred self.assert_dispatched_count(0, 'vas2nets.event') self.assert_dispatched_count(1, 'vas2nets.failures') [twisted_failure] = self.flushLoggedErrors(TemporaryFailure) failure = twisted_failure.value self.assertTrue("connection refused" in str(failure)) [fmsg] = self.get_dispatched('vas2nets.failures') fmsg = from_json(fmsg.body) self.assertEqual(msg.payload, fmsg['message']) self.assertEqual(FailureMessage.FC_TEMPORARY, fmsg['failure_code']) self.assertTrue(fmsg['reason'].strip().endswith("connection refused")) yield self.broker.kick_delivery() [key] = self.fail_worker.get_failure_keys() self.assertEqual(set([key]), self.get_retry_keys())
class SchedulerTestCase(TestCase): def setUp(self): self.r_server = FakeRedis() self.scheduler = Scheduler(self.r_server, self._scheduler_callback) self._delivery_history = [] def tearDown(self): if self.scheduler.is_running: self.scheduler.stop() def _scheduler_callback(self, scheduled_at, message): self._delivery_history.append((scheduled_at, message)) return (scheduled_at, message) def assertDelivered(self, message): delivered_messages = [ TransportUserMessage(**payload) for _, payload in self._delivery_history ] self.assertIn( message['message_id'], [message['message_id'] for message in delivered_messages]) def assertNumDelivered(self, number): self.assertEqual(number, len(self._delivery_history)) def get_pending_messages(self): scheduled_timestamps = self.scheduler.r_key('scheduled_timestamps') return self.r_server.zrange(scheduled_timestamps, 0, -1) def mkmsg_in(self, content='hello world', message_id='abc', to_addr='9292', from_addr='+41791234567', session_event=None, transport_type='sms', transport_name='test_transport', helper_metadata={}, transport_metadata={}): return TransportUserMessage( from_addr=from_addr, to_addr=to_addr, message_id=message_id, transport_name=transport_name, transport_type=transport_type, transport_metadata=transport_metadata, helper_metadata=helper_metadata, content=content, session_event=session_event, timestamp=datetime.now(), ) def test_scheduling(self): msg = self.mkmsg_in() now = time.mktime(datetime(2012, 1, 1).timetuple()) delta = 10 # seconds from now key, bucket_key = self.scheduler.schedule(delta, msg.payload, now) self.assertEqual( bucket_key, '%s#%s.%s' % (self.scheduler.r_prefix, 'scheduled_keys', self.scheduler.get_next_write_timestamp(delta, now))) scheduled_key = self.scheduler.get_scheduled_key(now) self.assertEqual(scheduled_key, None) scheduled_time = now + delta scheduled_key = self.scheduler.get_scheduled_key(scheduled_time) self.assertTrue(scheduled_key) self.assertEqual(set([scheduled_key]), self.scheduler.get_all_scheduled_keys()) @inlineCallbacks def test_delivery_loop(self): msg = self.mkmsg_in() now = time.mktime(datetime(2012, 1, 1).timetuple()) delta = 16 # seconds from now self.scheduler.schedule(delta, msg.payload, now) scheduled_time = now + delta + self.scheduler.granularity yield self.scheduler.deliver_scheduled(scheduled_time) self.assertDelivered(msg) @inlineCallbacks def test_deliver_loop_future(self): now = time.mktime(datetime(2012, 1, 1).timetuple()) for i in range(0, 3): msg = self.mkmsg_in(message_id='message_%s' % (i, )) delta = i * 10 key, _ = self.scheduler.schedule(delta, msg.payload, now) scheduled_time = now + delta + self.scheduler.granularity self.assertEqual(set([key]), self.scheduler.get_all_scheduled_keys()) yield self.scheduler.deliver_scheduled(scheduled_time) self.assertNumDelivered(i + 1) self.assertEqual(set(), self.scheduler.get_all_scheduled_keys()) @inlineCallbacks def test_deliver_ancient_messages(self): # something stuck in the queue since 1912 or scheduler hasn't # been running since 1912 msg = self.mkmsg_in() way_back = time.mktime(datetime(1912, 1, 1).timetuple()) scheduled_key, _ = self.scheduler.schedule(0, msg.payload, way_back) self.assertTrue(scheduled_key) now = time.mktime(datetime.now().timetuple()) yield self.scheduler.deliver_scheduled(now) self.assertEqual(set([scheduled_key]), self.scheduler.get_all_scheduled_keys()) self.assertEqual(len(self.get_pending_messages()), 1) yield self.scheduler.deliver_scheduled(way_back + self.scheduler.granularity) self.assertDelivered(msg) self.assertEqual(self.get_pending_messages(), []) self.assertEqual(set(), self.scheduler.get_all_scheduled_keys()) @inlineCallbacks def test_clear_scheduled_messages(self): msg = self.mkmsg_in() now = time.mktime(datetime.now().timetuple()) scheduled_time = now + self.scheduler.granularity key, bucket = self.scheduler.schedule(0, msg.payload, scheduled_time) self.assertEqual(len(self.get_pending_messages()), 1) self.assertEqual(set([key]), self.scheduler.get_all_scheduled_keys()) self.scheduler.clear_scheduled(key) yield self.scheduler.deliver_scheduled() self.assertEqual(self.r_server.hgetall(key), {}) self.assertEqual(self.r_server.smembers(bucket), set()) self.assertNumDelivered(0)
class SchedulerTestCase(TestCase): def setUp(self): self.r_server = FakeRedis() self.scheduler = Scheduler(self.r_server, self._scheduler_callback) self._delivery_history = [] def tearDown(self): if self.scheduler.is_running: self.scheduler.stop() def _scheduler_callback(self, scheduled_at, message): self._delivery_history.append((scheduled_at, message)) return (scheduled_at, message) def assertDelivered(self, message): delivered_messages = [TransportUserMessage(**payload) for _, payload in self._delivery_history] self.assertIn(message['message_id'], [message['message_id'] for message in delivered_messages]) def assertNumDelivered(self, number): self.assertEqual(number, len(self._delivery_history)) def get_pending_messages(self): scheduled_timestamps = self.scheduler.r_key('scheduled_timestamps') return self.r_server.zrange(scheduled_timestamps, 0, -1) def mkmsg_in(self, content='hello world', message_id='abc', to_addr='9292', from_addr='+41791234567', session_event=None, transport_type='sms', transport_name='test_transport', helper_metadata={}, transport_metadata={}): return TransportUserMessage( from_addr=from_addr, to_addr=to_addr, message_id=message_id, transport_name=transport_name, transport_type=transport_type, transport_metadata=transport_metadata, helper_metadata=helper_metadata, content=content, session_event=session_event, timestamp=datetime.now(), ) def test_scheduling(self): msg = self.mkmsg_in() now = time.mktime(datetime(2012, 1, 1).timetuple()) delta = 10 # seconds from now key, bucket_key = self.scheduler.schedule(delta, msg.payload, now) self.assertEqual(bucket_key, '%s#%s.%s' % ( self.scheduler.r_prefix, 'scheduled_keys', self.scheduler.get_next_write_timestamp(delta, now) )) scheduled_key = self.scheduler.get_scheduled_key(now) self.assertEqual(scheduled_key, None) scheduled_time = now + delta scheduled_key = self.scheduler.get_scheduled_key(scheduled_time) self.assertTrue(scheduled_key) self.assertEqual(set([scheduled_key]), self.scheduler.get_all_scheduled_keys()) @inlineCallbacks def test_delivery_loop(self): msg = self.mkmsg_in() now = time.mktime(datetime(2012, 1, 1).timetuple()) delta = 16 # seconds from now self.scheduler.schedule(delta, msg.payload, now) scheduled_time = now + delta + self.scheduler.granularity yield self.scheduler.deliver_scheduled(scheduled_time) self.assertDelivered(msg) @inlineCallbacks def test_deliver_loop_future(self): now = time.mktime(datetime(2012, 1, 1).timetuple()) for i in range(0, 3): msg = self.mkmsg_in(message_id='message_%s' % (i,)) delta = i * 10 key, _ = self.scheduler.schedule(delta, msg.payload, now) scheduled_time = now + delta + self.scheduler.granularity self.assertEqual(set([key]), self.scheduler.get_all_scheduled_keys()) yield self.scheduler.deliver_scheduled(scheduled_time) self.assertNumDelivered(i + 1) self.assertEqual(set(), self.scheduler.get_all_scheduled_keys()) @inlineCallbacks def test_deliver_ancient_messages(self): # something stuck in the queue since 1912 or scheduler hasn't # been running since 1912 msg = self.mkmsg_in() way_back = time.mktime(datetime(1912, 1, 1).timetuple()) scheduled_key, _ = self.scheduler.schedule(0, msg.payload, way_back) self.assertTrue(scheduled_key) now = time.mktime(datetime.now().timetuple()) yield self.scheduler.deliver_scheduled(now) self.assertEqual(set([scheduled_key]), self.scheduler.get_all_scheduled_keys()) self.assertEqual(len(self.get_pending_messages()), 1) yield self.scheduler.deliver_scheduled( way_back + self.scheduler.granularity) self.assertDelivered(msg) self.assertEqual(self.get_pending_messages(), []) self.assertEqual(set(), self.scheduler.get_all_scheduled_keys()) @inlineCallbacks def test_clear_scheduled_messages(self): msg = self.mkmsg_in() now = time.mktime(datetime.now().timetuple()) scheduled_time = now + self.scheduler.granularity key, bucket = self.scheduler.schedule(0, msg.payload, scheduled_time) self.assertEqual(len(self.get_pending_messages()), 1) self.assertEqual(set([key]), self.scheduler.get_all_scheduled_keys()) self.scheduler.clear_scheduled(key) yield self.scheduler.deliver_scheduled() self.assertEqual(self.r_server.hgetall(key), {}) self.assertEqual(self.r_server.smembers(bucket), set()) self.assertNumDelivered(0)
class FakeRedisTestCase(TestCase): def test_delete(self): self.r_server = FakeRedis() self.r_server.set("delete_me", 1) self.assertEqual(True, self.r_server.delete("delete_me")) self.assertEqual(False, self.r_server.delete("delete_me")) def test_incr(self): self.r_server = FakeRedis() self.r_server.set("inc", 1) self.assertEqual('1', self.r_server.get("inc")) self.assertEqual(2, self.r_server.incr("inc")) self.assertEqual(3, self.r_server.incr("inc")) self.assertEqual('3', self.r_server.get("inc")) def test_incr_with_by_param(self): self.r_server = FakeRedis() self.r_server.set("inc", 1) self.assertEqual('1', self.r_server.get("inc")) self.assertEqual(2, self.r_server.incr("inc", 1)) self.assertEqual(4, self.r_server.incr("inc", 2)) self.assertEqual(7, self.r_server.incr("inc", 3)) self.assertEqual(11, self.r_server.incr("inc", 4)) self.assertEqual(111, self.r_server.incr("inc", 100)) self.assertEqual('111', self.r_server.get("inc")) def test_zrange(self): self.r_server = FakeRedis() self.r_server.zadd('set', one=0.1, two=0.2, three=0.3) self.assertEqual(self.r_server.zrange('set', 0, 0), ['one']) self.assertEqual(self.r_server.zrange('set', 0, 1), ['one', 'two']) self.assertEqual(self.r_server.zrange('set', 0, 2), ['one', 'two', 'three']) self.assertEqual(self.r_server.zrange('set', 0, 3), ['one', 'two', 'three']) self.assertEqual(self.r_server.zrange('set', 0, -1), ['one', 'two', 'three']) self.assertEqual(self.r_server.zrange('set', 0, -1, withscores=True), [(0.1, 'one'), (0.2, 'two'), (0.3, 'three')]) self.assertEqual(self.r_server.zrange('set', 0, -1, desc=True), ['three', 'two', 'one']) self.assertEqual(self.r_server.zrange('set', 0, -1, desc=True, withscores=True), [(0.3, 'three'), (0.2, 'two'), (0.1, 'one')]) def test_hgetall_returns_copy(self): self.r_server = FakeRedis() self.r_server.hset("hash", "foo", "1") data = self.r_server.hgetall("hash") data["foo"] = "2" self.assertEqual(self.r_server.hgetall("hash"), { "foo": "1", }) def test_hincrby(self): self.r_server = FakeRedis() hincrby = self.r_server.hincrby self.assertEqual(hincrby("inc", "field1"), 1) self.assertEqual(hincrby("inc", "field1"), 2) self.assertEqual(hincrby("inc", "field1", 3), 5) self.assertEqual(hincrby("inc", "field1", "2"), 7) self.assertRaises(Exception, hincrby, "inc", "field1", "1.5") self.r_server.hset("inc", "field2", "a") self.assertRaises(Exception, hincrby, "inc", "field2") self.r_server.set("key", "string") self.assertRaises(Exception, self.r_server.hincrby, "key", "field1") def test_sadd(self): self.r_server = FakeRedis() self.r_server.sadd('set', 1) self.r_server.sadd('set', 2, 3, 4) self.assertEqual(self.r_server.smembers('set'), set([ '1', '2', '3', '4'])) def test_smove(self): self.r_server = FakeRedis() self.r_server.sadd('set1', 1) self.r_server.sadd('set2', 2) self.assertEqual(self.r_server.smove('set1', 'set2', '1'), True) self.assertEqual(self.r_server.smembers('set1'), set()) self.assertEqual(self.r_server.smembers('set2'), set(['1', '2'])) self.assertEqual(self.r_server.smove('set1', 'set2', '1'), False) self.assertEqual(self.r_server.smove('set2', 'set3', '1'), True) self.assertEqual(self.r_server.smembers('set2'), set(['2'])) self.assertEqual(self.r_server.smembers('set3'), set(['1'])) def test_sunion(self): self.r_server = FakeRedis() self.r_server.sadd('set1', 1) self.r_server.sadd('set2', 2) self.assertEqual(self.r_server.sunion('set1'), set(['1'])) self.assertEqual(self.r_server.sunion('set1', 'set2'), set(['1', '2'])) self.assertEqual(self.r_server.sunion('other'), set())