예제 #1
0
def test_add() -> None:
    now = datetime.now()
    stats.add(
        amount=Decimal(10),
        ts=now,
    )
    expected_stats = {
        'avg': Decimal(10),
        'count': 1,
        'max': Decimal(10),
        'min': Decimal(10),
        'sum': Decimal(10),
    }
    assert stats.get() == expected_stats

    stats.add(
        amount=Decimal(-5),
        ts=now,
    )
    expected_stats = {
        'avg': Decimal(2.5),
        'count': 2,
        'max': Decimal(10),
        'min': Decimal(-5),
        'sum': Decimal(5),
    }
    assert stats.get() == expected_stats
예제 #2
0
async def post(request: web.Request) -> web.Response:
    data = await request.json()
    try:
        amount = data['amount']
        timestamp = data['timestamp']
    except KeyError:
        return web.Response(status=400)
    try:
        amount = Decimal(amount)
    except InvalidOperation:
        return web.Response(status=400)
    try:
        ts = datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S.%fZ')
    except ValueError:
        return web.Response(status=400)

    try:
        stats.add(amount, ts)
    except StatTooOld:
        status = 204
        logger.warning('Ignored old stat')
    except StatInTheFuture:
        status = 422
        logger.warning('Ignored stat in the future')
    else:
        status = 201
        await stats.sweep_at(ts + timedelta(seconds=61))
        logger.info('Received transaction')
    return web.Response(status=status)
예제 #3
0
async def test_get_rounding(
    client: _TestClient,
    amount: Decimal,
    expected_avg: str,
) -> None:
    stats.add(
        amount=amount,
        ts=datetime.now(),
    )
    response = await client.get('/statistics')
    assert response.status == 200
    data = await response.json()
    assert data['avg'] == expected_avg
예제 #4
0
async def test_get_simple(
    client: _TestClient,
    stats_api_empty: Dict,
) -> None:
    response = await client.get('/statistics')
    assert response.status == 200
    data = await response.json()
    assert data == stats_api_empty

    stats.add(
        amount=Decimal(1),
        ts=datetime.now(),
    )
    response = await client.get('/statistics')
    assert response.status == 200
    data = await response.json()
    assert data == {
        'avg': '1.00',
        'count': 1,
        'max': '1.00',
        'min': '1.00',
        'sum': '1.00',
    }
예제 #5
0
def test_sweep() -> None:
    initial_datetime = datetime(
        year=2018,
        month=10,
        day=17,
        hour=0,
        minute=0,
        second=0,
    )
    with freeze_time(initial_datetime) as frozen_datetime:
        # [
        #     (10, t0),
        # ]
        stats.add(
            amount=Decimal(10),
            ts=datetime.now(),
        )
        expected_stats = {
            'avg': Decimal(10),
            'count': 1,
            'max': Decimal(10),
            'min': Decimal(10),
            'sum': Decimal(10),
        }
        assert stats.get() == expected_stats

        # [
        #     (10, t0),
        #     (5, t0 + 21),
        # ]
        frozen_datetime.tick(delta=timedelta(seconds=21))
        stats.sweep()
        stats.add(
            amount=Decimal(5),
            ts=datetime.now(),
        )
        expected_stats = {
            'avg': Decimal(7.5),
            'count': 2,
            'max': Decimal(10),
            'min': Decimal(5),
            'sum': Decimal(15),
        }
        assert stats.get() == expected_stats

        # [
        #     (10, t0),
        #     (5, t0 + 21),
        #     (-3, t0 + 42),
        # ]
        frozen_datetime.tick(delta=timedelta(seconds=21))
        stats.sweep()
        stats.add(
            amount=Decimal(-3),
            ts=datetime.now(),
        )
        expected_stats = {
            'avg': Decimal(4),
            'count': 3,
            'max': Decimal(10),
            'min': Decimal(-3),
            'sum': Decimal(12),
        }
        assert stats.get() == expected_stats

        # [
        #     (10, t0),  expired
        #     (5, t0 + 21)
        #     (-3, t0 + 42)
        #     (1, t0 + 63)
        # ]
        frozen_datetime.tick(delta=timedelta(seconds=21))
        stats.sweep()
        stats.add(
            amount=Decimal(1),
            ts=datetime.now(),
        )
        expected_stats = {
            'avg': Decimal(1),
            'count': 3,
            'max': Decimal(5),
            'min': Decimal(-3),
            'sum': Decimal(3),
        }
        assert stats.get() == expected_stats
예제 #6
0
def test_stat_in_the_future() -> None:
    with pytest.raises(StatInTheFuture):
        stats.add(amount=Decimal(10), ts=datetime.now() + timedelta(seconds=1))
예제 #7
0
def test_stat_too_old() -> None:
    stats.add(amount=Decimal(10), ts=datetime.now() - timedelta(seconds=59))
    with pytest.raises(StatTooOld):
        stats.add(amount=Decimal(10),
                  ts=datetime.now() - timedelta(seconds=60))