Ejemplo n.º 1
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())
Ejemplo n.º 2
0
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())
Ejemplo n.º 3
0
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())
Ejemplo n.º 4
0
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())
Ejemplo n.º 5
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)
Ejemplo n.º 6
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)
Ejemplo n.º 7
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())