def test_pop_ready(self):
        k = ready_key('test')

        req1 = {
            'owner_id': '1234',
            'timestamp': 5,
            'attempts': 0,
            'intervals': [10],
            'request': {'foo': 23}
        }

        req2 = {
            'owner_id': '1234',
            'timestamp': 10,
            'attempts': 0,
            'intervals': [10],
            'request': {'bar': 42}
        }

        yield add_ready(self.redis, 'test', [req1, req2])
        self.assertEqual((yield lvalues(self.redis, k)), [req1, req2])

        result = yield pop_ready(self.redis, 'test')
        self.assertEqual(result, req1)
        self.assertEqual((yield lvalues(self.redis, k)), [req2])

        result = yield pop_ready(self.redis, 'test')
        self.assertEqual(result, req2)
        self.assertEqual((yield lvalues(self.redis, k)), [])

        result = yield pop_ready(self.redis, 'test')
        self.assertEqual(result, None)
        self.assertEqual((yield lvalues(self.redis, k)), [])
    def test_add_ready(self):
        k = ready_key('test')

        req1 = {
            'owner_id': '1234',
            'timestamp': 5,
            'attempts': 0,
            'intervals': [10],
            'request': {'foo': 23}
        }

        req2 = {
            'owner_id': '1234',
            'timestamp': 10,
            'attempts': 0,
            'intervals': [10],
            'request': {'bar': 42}
        }

        req3 = {
            'owner_id': '1234',
            'timestamp': 15,
            'attempts': 0,
            'intervals': [10],
            'request': {'baz': 21}
        }

        self.assertEqual((yield lvalues(self.redis, k)), [])

        yield add_ready(self.redis, 'test', [])

        self.assertEqual((yield lvalues(self.redis, k)), [])

        yield add_ready(self.redis, 'test', [req1])

        self.assertEqual((yield lvalues(self.redis, k)), [req1])

        yield add_ready(self.redis, 'test', [req2, req3])

        self.assertEqual((yield lvalues(self.redis, k)), [req1, req2, req3])
    def test_add_ready_no_serialize(self):
        k = ready_key('test')

        req1 = {
            'owner_id': '1234',
            'timestamp': 5,
            'attempts': 0,
            'intervals': [10],
            'request': {'foo': 23}
        }

        req2 = {
            'owner_id': '1234',
            'timestamp': 10,
            'attempts': 0,
            'intervals': [10],
            'request': {'bar': 42}
        }

        yield add_ready(
            self.redis, 'test', [json.dumps(req1), json.dumps(req2)],
            serialize=False)

        self.assertEqual((yield lvalues(self.redis, k)), [req1, req2])
    def test_loop(self):
        k = ready_key('test')
        msgs = self.patch_log()
        retries = self.patch_retry()
        worker = yield self.mk_worker({'frequency': 5})

        reqs = [{
            'owner_id': '1234',
            'timestamp': t,
            'attempts': 0,
            'intervals': [10],
            'request': {'foo': t}
        } for t in range(5, 30, 5)]

        yield add_ready(worker.redis, 'test', reqs)

        self.assertEqual(pop_all(msgs), [
            ('Polling for requests to retry',),
            ('Retrieving next request from ready set',),
            ('Ready set is empty, rechecking on next poll',),
        ])

        worker.clock.advance(5)
        req = yield retries.get()
        self.assertEqual(req, reqs[0])
        self.assertEqual((yield lvalues(worker.redis, k)), reqs[1:])

        self.assertEqual(pop_all(msgs), [
            ('Polling for requests to retry',),
            ('Retrieving next request from ready set',),
            ('Scheduling request for retrying', reqs[0]),
            ('Retrieving next request from ready set',),
        ])

        req = yield retries.get()
        self.assertEqual(req, reqs[1])
        self.assertEqual((yield lvalues(worker.redis, k)), reqs[2:])

        self.assertEqual(pop_all(msgs), [
            ('Scheduling request for retrying', reqs[1]),
            ('Retrieving next request from ready set',),
        ])

        req = yield retries.get()
        self.assertEqual(req, reqs[2])
        self.assertEqual((yield lvalues(worker.redis, k)), reqs[3:])

        self.assertEqual(pop_all(msgs), [
            ('Scheduling request for retrying', reqs[2]),
            ('Retrieving next request from ready set',),
        ])

        req = yield retries.get()
        self.assertEqual(req, reqs[3])
        self.assertEqual((yield lvalues(worker.redis, k)), reqs[4:])

        self.assertEqual(pop_all(msgs), [
            ('Scheduling request for retrying', reqs[3]),
            ('Retrieving next request from ready set',),
        ])

        req = yield retries.get()
        self.assertEqual(req, reqs[4])
        self.assertEqual((yield lvalues(worker.redis, k)), [])

        self.assertEqual(pop_all(msgs), [
            ('Scheduling request for retrying', reqs[4]),
            ('Retrieving next request from ready set',),
        ])

        worker.clock.advance(10)

        reqs = [{
            'owner_id': '1234',
            'timestamp': t,
            'attempts': 0,
            'intervals': [10],
            'request': {'foo': t}
        } for t in range(5, 15, 5)]

        yield add_ready(worker.redis, 'test', reqs)

        self.assertEqual(pop_all(msgs), [
            ('Ready set is empty, rechecking on next poll',),
        ])

        worker.clock.advance(5)
        req = yield retries.get()
        self.assertEqual(req, reqs[0])
        self.assertEqual((yield lvalues(worker.redis, k)), reqs[1:])

        self.assertEqual(pop_all(msgs), [
            ('Polling for requests to retry',),
            ('Retrieving next request from ready set',),
            ('Scheduling request for retrying', reqs[0]),
            ('Retrieving next request from ready set',),
        ])

        worker.clock.advance(5)
        req = yield retries.get()
        self.assertEqual(req, reqs[1])
        self.assertEqual((yield lvalues(worker.redis, k)), [])

        self.assertEqual(pop_all(msgs), [
            ('Scheduling request for retrying', reqs[1]),
            ('Retrieving next request from ready set',),
        ])