Esempio n. 1
0
    def test_ratelimit_exceeded(self, limiter):
        """Verify that if we're inside our cell, we reduce remaining."""
        rate = helpers.new_quota(
            period=datetime.timedelta(seconds=60), count=50
        )
        mockstore = limiter.store.recording_store
        mockstore.get.side_effect = lambda key: (
            limit_data.LimitData(
                used=49,
                remaining=1,
                created_at=datetime.datetime.now(datetime.timezone.utc),
                time=(
                    datetime.datetime.now(datetime.timezone.utc)
                    + datetime.timedelta(seconds=60)
                ),
            )
        )

        limitresult = limiter.rate_limit(key="key", rate=rate, quantity=1)

        assert limitresult.limited is True
        assert limitresult.remaining == 0
        assert (
            datetime.timedelta(seconds=60)
            <= limitresult.reset_after
            < (2 * datetime.timedelta(seconds=60))
        )
        assert (
            datetime.timedelta(seconds=0)
            < limitresult.retry_after
            <= datetime.timedelta(seconds=3)
        )
Esempio n. 2
0
    def test_copy_with_arguments(self):
        """Verify the behaviour of LimitData.copy_with."""
        ld = limit_data.LimitData(used=5, remaining=5)
        new_ld = ld.copy_with(used=10, remaining=0)

        assert new_ld.remaining == 0
        assert new_ld.used == 10
        assert new_ld.created_at == new_ld.created_at
Esempio n. 3
0
    def test_set_with_time_uses_now(self):
        """Verify we can add data with the current time."""
        store = dictstore.DictionaryStore()
        new_data = limit_data.LimitData(used=9999, remaining=1)

        set_data = store.set_with_time(key="mykey", data=new_data)
        assert isinstance(set_data.time, datetime.datetime)
        assert store.get("mykey") != {}
Esempio n. 4
0
    def test_get_with_time_defaults_to_now(self):
        """Verify we can retrieve data with a default time."""
        data = limit_data.LimitData(used=9999, remaining=1)
        store = dictstore.DictionaryStore(store={"mykey": data})

        dt, retrieved_data = store.get_with_time("mykey")
        assert dt.replace(second=0, microsecond=0) == datetime.datetime.now(
            datetime.timezone.utc).replace(second=0, microsecond=0)
        assert retrieved_data == data.copy_with(time=dt)
Esempio n. 5
0
    def test_rate_limit_reset_after_period(self, limiter):
        """Verify we allow the last request."""
        rate = helpers.new_quota()
        mockstore = limiter.store.recording_store
        now = datetime.datetime.now(datetime.timezone.utc)
        original_created_at = now - datetime.timedelta(seconds=2)
        mockstore.get.return_value = limit_data.LimitData(
            remaining=0, used=5, created_at=original_created_at)
        mockstore.set.return_value = limit_data.LimitData(remaining=4,
                                                          used=1,
                                                          created_at=now)

        limitresult = limiter.rate_limit(key="key", quantity=1, rate=rate)

        assert limitresult.remaining == 4
        assert limitresult.limit == 5
        assert limitresult.limited is False
        mockstore.get.assert_called_once_with("key")
        mockstore.set.assert_called_once_with(key="key", data=mock.ANY)
Esempio n. 6
0
    def test_last_rate_limit_in_period(self, limiter):
        """Verify we allow the last request."""
        rate = helpers.new_quota()
        mockstore = limiter.store.recording_store
        original_created_at = datetime.datetime.now(
            datetime.timezone.utc) - datetime.timedelta(microseconds=1)
        mockstore.get.return_value = limit_data.LimitData(
            remaining=1, used=4, created_at=original_created_at)

        limitresult = limiter.rate_limit(key="key", quantity=1, rate=rate)

        assert limitresult.remaining == 0
        assert limitresult.limit == 5
        assert limitresult.limited is False
        mockstore.get.assert_called_once_with("key")
        mockstore.set.assert_called_once_with(
            key="key",
            data=limit_data.LimitData(used=5,
                                      remaining=0,
                                      created_at=original_created_at),
        )
Esempio n. 7
0
    def test_preexisting_limitdata(self, limiter):
        """Verify we record the limit data appropriately."""
        rate = helpers.new_quota()
        mockstore = limiter.store.recording_store
        original_created_at = datetime.datetime.now(
            datetime.timezone.utc) - datetime.timedelta(microseconds=1)
        mockstore.get.return_value = limit_data.LimitData(
            remaining=4, used=1, created_at=original_created_at)

        limitresult = limiter.rate_limit(key="key", quantity=1, rate=rate)

        assert limitresult.remaining == 3
        assert limitresult.limit == 5
        assert limitresult.limited is False
        mockstore.get.assert_called_once_with("key")
        mockstore.set.assert_called_once_with(
            key="key",
            data=limit_data.LimitData(used=2,
                                      remaining=3,
                                      created_at=original_created_at),
        )
Esempio n. 8
0
    def test_reset(self, limiter):
        """Verify reset works appropriately."""
        rate = helpers.new_quota()
        mockstore = limiter.store.recording_store

        mockstore.set.return_value = limit_data.LimitData(remaining=5, used=0)

        limitresult = limiter.reset(key="key", rate=rate)

        assert limitresult.remaining == 5
        assert limitresult.limit == 5
        assert limitresult.limited is False
        mockstore.set.assert_called_once_with(key="key", data=mock.ANY)
Esempio n. 9
0
 def test_result_from_quota(self, limiter):
     """Verify the behaviour of result_from_quota."""
     quota = mock.Mock(count=5, period=datetime.timedelta(hours=1))
     limitresult = limiter.result_from_quota(
         rate=quota,
         limited=False,
         limitdata=limit_data.LimitData(used=0, remaining=6),
         elapsed_since_period_start=datetime.timedelta(seconds=1),
     )
     assert isinstance(limitresult, result.RateLimitResult)
     assert limitresult.limited is False
     assert limitresult.limit == 5
     assert limitresult.remaining == 6
     assert limitresult.retry_after == datetime.timedelta(seconds=-1)
Esempio n. 10
0
    def test_get_with_time_uses_existing_time(self):
        """Verify we can retrieve data from our datastore with its time."""
        data = limit_data.LimitData(
            used=9999,
            remaining=1,
            time=datetime.datetime(
                year=2018,
                month=12,
                day=4,
                hour=9,
                minute=0,
                second=0,
                tzinfo=datetime.timezone.utc,
            ),
        )
        store = dictstore.DictionaryStore(store={"mykey": data})

        dt, retrieved_data = store.get_with_time("mykey")
        assert dt == data.time
        assert retrieved_data == data
Esempio n. 11
0
    def test_set_with_time_uses_provided_value(self):
        """Verify we can add data with a specific time."""
        store = dictstore.DictionaryStore()
        new_data = limit_data.LimitData(
            used=9999,
            remaining=1,
            time=datetime.datetime(
                year=2018,
                month=12,
                day=4,
                hour=9,
                minute=0,
                second=0,
                tzinfo=datetime.timezone.utc,
            ),
        )

        set_data = store.set_with_time(key="mykey", data=new_data)
        assert set_data == new_data
        assert store.get("mykey") == new_data
Esempio n. 12
0
    def test_asdict_without_time(self):
        """Verify the behaviour of LimitData.asdict."""
        created_at = datetime.datetime(
            year=2018,
            month=12,
            day=11,
            hour=12,
            minute=12,
            second=15,
            microsecond=123_456,
            tzinfo=datetime.timezone.utc,
        )
        ld = limit_data.LimitData(used=0, remaining=5, created_at=created_at)

        assert ld.asdict() == {
            "time": "",
            "created_at": "2018-12-11T12:12:15.123456+0000",
            "used": "0",
            "remaining": "5",
        }
Esempio n. 13
0
    def test_conversion(self):
        """Test attrs conversion just to be safe."""
        kwargs = {
            "time": "",
            "created_at": "2018-12-11T12:12:15.123456+0000",
            "used": "0",
            "remaining": "5",
        }
        created_at = datetime.datetime(
            year=2018,
            month=12,
            day=11,
            hour=12,
            minute=12,
            second=15,
            microsecond=123_456,
            tzinfo=datetime.timezone.utc,
        )
        ld = limit_data.LimitData(**kwargs)

        assert ld.used == 0
        assert ld.remaining == 5
        assert ld.created_at == created_at
        assert ld.time is None
Esempio n. 14
0
    def test_copy_with_no_arguments(self):
        """Verify the behaviour of LimitData.copy_with."""
        ld = limit_data.LimitData(used=5, remaining=5)

        assert ld.copy_with() == ld
Esempio n. 15
0
    def test_get(self):
        """Verify we can retrieve data from our datastore."""
        data = limit_data.LimitData(used=9999, remaining=1)
        store = dictstore.DictionaryStore(store={"mykey": data})

        assert store.get("mykey") == data
Esempio n. 16
0
    def test_set(self):
        """Verify we can add data."""
        store = dictstore.DictionaryStore()
        new_data = limit_data.LimitData(used=9999, remaining=1)

        assert store.set(key="mykey", data=new_data) == new_data
Esempio n. 17
0
    def test_may_begin_life_with_data(self):
        """Verify that we can give it initial data."""
        data = {"a_key": limit_data.LimitData(used=9999, remaining=1)}
        store = dictstore.DictionaryStore(store=data)

        assert store.store == data