Пример #1
0
async def test_parking_request_message(ws_url, user_id, mocker, engine):
    user_location = Location(0.0, 1.0)
    lot_location = Location(0.001, 1.0)
    lot_allocation = ParkingLotAllocation(100,
                                          "test_lot",
                                          0,
                                          lot_location,
                                          1,
                                          distance=50.0,
                                          availability=20)
    parking_request = ParkingRequestMessage(user_location)

    mocker.patch.object(engine, 'handle_allocation_request')
    engine.handle_allocation_request.return_value = return_async_value(
        lot_allocation)

    conn: WebSocketClientConnection = await tornado.websocket.websocket_connect(
        ws_url + user_id)
    await conn.write_message(serialize_model(parking_request))
    msg = deserialize_ws_message(await conn.read_message())

    engine.handle_allocation_request.assert_called_once_with(
        user_id, parking_request)
    assert isinstance(msg, ParkingAllocationMessage)
    assert msg.lot == lot_allocation
Пример #2
0
async def test_no_parking_lots_retry(http_client, base_url):
    car_id = str(uuid4())
    car_cli = await CarWebsocket.create(
        base_url=base_url.replace('http', 'ws') + "/ws", user_id=car_id)
    logger.debug("car websocket client connected")
    response = await car_cli.send_parking_request(Location(0.0, 1.0), {})
    logger.debug(f'requested allocation: {response}')
    allocated = await car_cli.receive(wsmodels.ErrorMessage)
    logger.debug(f'allocation failed: {allocated}')

    assert allocated.error.msg == 'No parking lot available.'

    cli = ParkingLotRest(base_url, http_client)
    lot = ParkingLot(10, 'a', 1.0, Location(0.0, 1.0))

    response = await cli.create_lot(lot)
    lot.id = response
    logger.debug(f'created lot {response}')

    response = await car_cli.send_parking_request(Location(0.0, 1.0), {})
    logger.debug(f'requested allocation: {response}')
    allocated = await car_cli.receive(wsmodels.ParkingAllocationMessage)
    logger.debug(f'allocation recieved: {allocated}')

    assert allocated.lot.id == lot.id
Пример #3
0
async def test_create_parking_lot_confirm(caplog, http_client, base_url):
    caplog.set_level(logging.INFO)

    # create parking lot...
    cli = ParkingLotRest(base_url, http_client)
    lot = ParkingLot(10, 'a', 1.0, Location(0.0, 1.0))

    response = await cli.create_lot(lot)
    lot.id = response

    await asyncio.sleep(1)

    # create car
    car_id = str(uuid4())
    car_cli = await CarWebsocket.create(
        base_url=base_url.replace('http', 'ws') + "/ws", user_id=car_id)
    response = await car_cli.send_parking_request(Location(0.0, 1.0), {})

    # ask for allocation
    allocated = await car_cli.receive(wsmodels.ParkingAllocationMessage)
    assert allocated.lot.id == lot.id

    # accept allocation
    await car_cli.send_parking_acceptance(allocated.lot.id)

    # wait for confirmation
    await car_cli.receive(wsmodels.ConfirmationMessage)
Пример #4
0
async def test_recalculate_allocations():
    user_ids = [uuid4(), uuid4(), uuid4()]
    locations = [
        Location(0.0, 0.0),
        Location(0.0001, 0.0002),
        Location(0.2, 0.0)
    ]
    PARK_ID = 1
    removed = []

    async def fake_get_parking_lot(park_id):
        return {
            'id': PARK_ID,
            'name': 'test_lot_1',
            'capacity': 10,
            'lat': 0.0,
            'long': 0.0001,
            'price': 2,
            'num_available': 1,
            'num_allocated': 3
        }

    async def fake_get_parking_lot_allocations(park_id):
        return [{
            'user_id': user_ids[0],
            'park_id': PARK_ID
        }, {
            'user_id': user_ids[1],
            'park_id': PARK_ID
        }, {
            'user_id': user_ids[2],
            'park_id': PARK_ID
        }]

    async def fake_delete_allocation(user_id):
        removed.append(user_id)

    db = DbAccess()
    db.get_parking_lot = fake_get_parking_lot
    db.get_parking_lot_allocations = fake_get_parking_lot_allocations
    db.delete_allocation = fake_delete_allocation

    us = UserSessions()
    us.deallocate = lambda user_id: print(user_id)
    for user_id, loc in zip(user_ids, locations):
        us.add_user(user_id, None)
        us.update_user_location(user_id, loc)

    engine = AllocationEngine(db, us)

    await engine.recalculate_allocations(PARK_ID)
    assert len(removed) == 2
Пример #5
0
async def test_allocate_parking_lot_to_user_already_allocated_fail(event_loop):
    with Postgresql() as postgresql:
        db = await DbAccess.create(postgresql.url(),
                                   event_loop,
                                   reset_tables=True)

        parking_lot1 = ParkingLot(100, 'test_name1', 0.0, Location(0.0, 1.0))
        parking_lot2 = ParkingLot(100, 'test_name2', 0.0, Location(0.0, 1.0))
        await db.insert_parking_lot(parking_lot1)
        await db.insert_parking_lot(parking_lot2)

        assert await db.allocate_parking_lot("test_user", 1) is True
        assert await db.allocate_parking_lot("test_user", 2) is False
Пример #6
0
async def test_create_parking_lot(http_client, base_url):
    lot = ParkingLot(100, 'test', 1.0, Location(0.0, 1.0))
    response = await http_client.fetch(base_url + '/spaces',
                                       method='POST',
                                       headers=HEADERS,
                                       body=serialize_model(lot))
    assert ParkingLotCreationResponse(**json.loads(response.body)).id == 1
async def test_update_parking_lot_availability(plr):
    lot = ParkingLot(100, 'test', 1.0, Location(0.0, 1.0))
    lot_id = await plr.create_lot(lot)
    assert lot_id == 1

    # TODO: Check that the ParkingLot availability has actually been updated using a GET # request.
    await plr.update_available(lot_id, 2)
async def test_delete_parking_lot(plr):
    lot = ParkingLot(100, 'test', 1.0, Location(0.0, 1.0))
    lot_id = await plr.create_lot(lot)
    assert lot_id == 1

    # TODO: Check that the ParkingLot has actually been deleted using a GET # request.
    await plr.delete_lot(lot_id)
Пример #9
0
async def test_handle_allocation_request():
    async def fake_get_available_parking_lot(loc, dist, rej):
        lots = [{
            'id': 1,
            'name': 'test_lot_1',
            'capacity': 10,
            'lat': 0.0,
            'long': 0.0001,
            'price': 2,
            'num_available': 10,
            'num_allocated': 0
        }, {
            'id': 2,
            'name': 'test_lot_2',
            'capacity': 10,
            'lat': 0.0,
            'long': 0.0001,
            'price': 2,
            'num_available': 10,
            'num_allocated': 0
        }]
        return lots

    db = DbAccess()
    db.get_available_parking_lots = fake_get_available_parking_lot
    us = UserSessions()
    user_id = uuid4()
    us.add_user(user_id, None)
    engine = AllocationEngine(db, us)
    req = ParkingRequestMessage(location=Location(0.0, 0.0001), preferences={})

    lot = await engine.handle_allocation_request(user_id, req)
    assert lot.id == 1
Пример #10
0
async def test_allocate_parking_lot_to_user(event_loop):
    with Postgresql() as postgresql:
        db = await DbAccess.create(postgresql.url(),
                                   event_loop,
                                   reset_tables=True)

        parking_lot = ParkingLot(100, 'test_name', 0.0, Location(0.0, 1.0))
        await db.insert_parking_lot(parking_lot)
        assert await db.allocate_parking_lot("test_user", 1) is True
Пример #11
0
async def test_location_update_message(ws_url, user_id, mocker, usessions):
    conn: WebSocketClientConnection = await tornado.websocket.websocket_connect(
        ws_url + user_id)

    mocker.spy(usessions, 'update_user_location')

    location = Location(0.0, 1.0)
    await conn.write_message(serialize_model(LocationUpdateMessage(location)))
    await sleep(0.01)
    usessions.update_user_location.assert_called_once_with(user_id, location)
Пример #12
0
async def test_location_message_callback(http_client, ws_url):
    f = asyncio.Future()
    car_ws = await clients.CarWebsocket.create(
        ws_url, {
            wsm.LocationUpdateMessage: f.set_result,
        })
    location = Location(0.0, 1.0)
    await car_ws.send_location(location)
    response = await f
    assert response.location == location
Пример #13
0
async def test_no_parking_lots(http_client, base_url):
    car_id = str(uuid4())
    car_cli = await CarWebsocket.create(
        base_url=base_url.replace('http', 'ws') + "/ws", user_id=car_id)
    logger.debug("car websocket client connected")
    response = await car_cli.send_parking_request(Location(0.0, 1.0), {})
    logger.debug(f'requested allocation: {response}')
    allocated = await car_cli.receive(wsmodels.ErrorMessage)
    logger.debug(f'allocation failed: {allocated}')

    assert allocated.error.msg == 'No parking lot available.'
Пример #14
0
async def test_delete_parking_lot(http_client, base_url):
    lot = ParkingLot(100, 'test', 1.0, Location(0.0, 1.0))
    response = await http_client.fetch(base_url + '/spaces',
                                       method='POST',
                                       headers=HEADERS,
                                       body=serialize_model(lot))
    assert ParkingLotCreationResponse(**json.loads(response.body)).id == 1

    # TODO: Check that the ParkingLot has actually been deleted using a GET # request.
    response = await http_client.fetch(base_url + '/spaces/1', method='DELETE')
    assert response.code == 200
Пример #15
0
async def test_get_parking_lot(event_loop):
    with Postgresql() as postgresql:
        db = await DbAccess.create(postgresql.url(),
                                   event_loop,
                                   reset_tables=True)
        parking_lot = ParkingLot(100, 'test_name', 0.0, Location(0.0, 1.0089))

        park_id = await db.insert_parking_lot(parking_lot)

        lot = await db.get_parking_lot(park_id)
        assert lot['name'] == parking_lot.name
Пример #16
0
async def test_insert_parking_lot(event_loop):
    with Postgresql() as postgresql:
        db = await DbAccess.create(postgresql.url(),
                                   event_loop,
                                   reset_tables=True)

        parking_lot = ParkingLot(100, 'test_name', 0.0, Location(0.0, 1.0))
        park_id = await db.insert_parking_lot(parking_lot)
        assert park_id == 1

        async with db.pool.acquire() as conn:
            lst: List[Record] = await conn.fetch('SELECT * from ParkingLots;')
            assert len(lst) == 1
Пример #17
0
async def test_create_multiple_parking_lot(http_client, base_url):
    cli = ParkingLotRest(base_url, http_client)

    lot = ParkingLot(10, 'a', 1.0, Location(0.0, 1.0))
    response = await cli.create_lot(lot)
    lot.id = response
    logger.debug(f'[test_create_parking_lot] created lot {lot.id}')

    lot2 = ParkingLot(10, 'b', 1.0, Location(2.0, 2.0))
    response = await cli.create_lot(lot2)
    lot2.id = response
    logger.debug(f'[test_create_parking_lot] created lot2 {lot2.id}')

    car_id = str(uuid4())
    car_cli = await CarWebsocket.create(
        base_url=base_url.replace('http', 'ws') + "/ws", user_id=car_id)
    logger.debug("car websocket client connected")
    response = await car_cli.send_parking_request(Location(0.0, 1.0), {})
    logger.debug(f'requested allocation: {response}')
    allocated = await car_cli.receive(wsmodels.ParkingAllocationMessage)
    logger.debug(f'allocation recieved: {allocated}')

    assert allocated.lot.id == lot.id
Пример #18
0
async def test_add_allocation(event_loop):
    with Postgresql() as postgresql:
        db = await DbAccess.create(postgresql.url(),
                                   event_loop,
                                   reset_tables=True)
        parking_lot = ParkingLot(100, 'test_name', 0.0, Location(0.0, 1.0089))
        user_id = str(uuid4())

        park_id = await db.insert_parking_lot(parking_lot)
        result = await db.allocate_parking_lot(user_id, park_id)
        assert result

        allocations = await db.get_parking_lot_allocations(park_id)
        assert allocations[0]['park_id'] == park_id
        assert allocations[0]['user_id'] == user_id
Пример #19
0
async def test_get_available_parking_lots(event_loop):
    with Postgresql() as postgresql:
        db = await DbAccess.create(postgresql.url(),
                                   event_loop,
                                   reset_tables=True)
        parking_lot1 = ParkingLot(100, 'test_name1', 0.0,
                                  Location(0.0, 1.0089))
        parking_lot2 = ParkingLot(100, 'test_name2', 0.0, Location(0.0, 1.01))
        parking_lot3 = ParkingLot(100, 'test_name2', 0.0, Location(0.0, 1.0))

        await db.insert_parking_lot(parking_lot1)
        await db.update_parking_lot_availability(1, 50)
        await db.insert_parking_lot(parking_lot2)
        await db.update_parking_lot_availability(2, 50)
        await db.insert_parking_lot(parking_lot3)
        await db.update_parking_lot_availability(3, 50)

        records = await db.get_available_parking_lots(location=Location(
            0.0, 1.0),
                                                      dist_meters=1000,
                                                      exclusions=[])

        assert len(records) == 2
        assert records[0]['id'] == 3
        assert records[0]['distance'] == 0
        assert records[1]['id'] == 1
        assert round(records[1]['distance']) == 991

        records2 = await db.get_available_parking_lots(location=Location(
            0.0, 1.0),
                                                       dist_meters=1000,
                                                       exclusions=[3])

        assert len(records2) == 1
        assert records2[0]['id'] == 1
        assert round(records2[0]['distance']) == 991
Пример #20
0
async def test_update_parking_lot_price_and_availability_unsuccessful(
        event_loop):
    new_availability = 10
    new_price = 5

    with Postgresql() as postgresql:
        db = await DbAccess.create(postgresql.url(),
                                   event_loop,
                                   reset_tables=True)

        parking_lot = ParkingLot(100, 'test_name', 0.0, Location(0.0, 1.0))
        await db.insert_parking_lot(parking_lot)
        park_id = await db.update_parking_lot_availability(2, new_availability)
        assert park_id is None
        park_id = await db.update_parking_lot_price(2, new_price)
        assert park_id is None
Пример #21
0
async def test_no_parking_lots_retry_waiting(http_client, base_url):
    car_id = str(uuid4())
    car_cli = await CarWebsocket.create(
        base_url=base_url.replace('http', 'ws') + "/ws", user_id=car_id)
    logger.debug("car websocket client connected")
    response = await car_cli.send_parking_request(Location(0.0, 1.0), {})
    logger.debug(f'requested allocation: {response}')
    futs = [
        car_cli.receive(wsmodels.ParkingAllocationMessage),
        car_cli.receive(wsmodels.ErrorMessage)
    ]
    (fut, ), *_ = await asyncio.wait(futs, return_when=asyncio.FIRST_COMPLETED)
    space = fut.result()

    assert isinstance(space, wsmodels.ErrorMessage)
    assert space.error.msg == 'No parking lot available.'
Пример #22
0
async def test_parking_request_message_no_parking_lot(ws_url, user_id, mocker,
                                                      engine):
    user_location = Location(0.0, 1.0)
    parking_request = ParkingRequestMessage(user_location)

    mocker.patch.object(engine, 'handle_allocation_request')
    engine.handle_allocation_request.return_value = return_async_value(None)

    conn: WebSocketClientConnection = await tornado.websocket.websocket_connect(
        ws_url + user_id)
    await conn.write_message(serialize_model(parking_request))
    msg = deserialize_ws_message(await conn.read_message())

    engine.handle_allocation_request.assert_called_once_with(
        user_id, parking_request)
    assert WebSocketErrorType(
        msg.error) == WebSocketErrorType.NO_AVAILABLE_PARKING_LOT
Пример #23
0
    async def handle_allocation_request(self, user_id: str,
                                        request: ParkingRequestMessage) -> Optional[ParkingLotAllocation]:
        user_rejections = self.user_sessions.get_user(user_id).rejections
        if 'distance' in request.preferences:
            max_distance = request.preferences['distance']
        else:
            max_distance = MAX_DISTANCE
        lots = await self.dba.get_available_parking_lots(request.location, max_distance, user_rejections)

        # Just take the first lot for now...
        if lots:
            lot = lots[0]
            lot_loc = (lot['lat'], lot['long'])
            req_loc = (request.location.latitude, request.location.longitude)
            dist = distance(lot_loc, req_loc).meters

            return ParkingLotAllocation(lot['capacity'], lot['name'], lot['price'],
                                        Location(lot['lat'], lot['long']), lot['id'],
                                        dist, lot['num_available'])
        else:
            return None
Пример #24
0
async def test_update_parking_lot_price_and_availability(event_loop):
    new_availability = 10
    new_price = 5

    with Postgresql() as postgresql:
        db = await DbAccess.create(postgresql.url(),
                                   event_loop,
                                   reset_tables=True)

        parking_lot = ParkingLot(100, 'test_name', 0.0, Location(0.0, 1.0))
        park_id = await db.insert_parking_lot(parking_lot)
        park_id = await db.update_parking_lot_availability(
            park_id, new_availability)
        assert park_id == 1
        park_id = await db.update_parking_lot_price(park_id, new_price)
        assert park_id == 1

        async with db.pool.acquire() as conn:
            p_record: Record = await conn.fetchrow('SELECT * from ParkingLots;'
                                                   )

        assert p_record['num_available'] == new_availability
        assert p_record['price'] == new_price
Пример #25
0
def test_location_missing_arg():
    with pytest.raises(TypeError):
        Location(0.0)
Пример #26
0
def test_location_cons():
    loc = Location(0.0, 0.0)
    assert isinstance(loc, Location)
Пример #27
0
def test_location_incorrect_arg_type():
    with pytest.raises(TypeError):
        Location(0.0, 'a')
Пример #28
0
def test_message_type():
    msg = LocationUpdateMessage(Location(0.0, 1.0))
    assert msg._type == WebSocketMessageType.LOCATION_UPDATE
async def test_create_parking_lot_new(plr):
    lot = ParkingLot(100, 'test', 1.0, Location(0.0, 1.0))
    lot_id = await plr.create_lot(lot)
    assert lot_id == 1
Пример #30
0
import attr
import pytest
from parking.shared.location import Location
from parking.shared.rest_models import (ParkingLot, ParkingLotCreationResponse,
                                        SpaceAvailableMessage, SpacePriceMessage)

loc = Location(0.0, 1.0)


def test_correct_parkinglot_cons():
    assert isinstance(ParkingLot(100, 'test_name', 0.0, loc), ParkingLot)


def test_missing_parkinglot_arg():
    with pytest.raises(TypeError):
        ParkingLot(100, 'test_name', 0)


def test_incorrect_parkinglot_arg_type():
    with pytest.raises(TypeError):
        ParkingLot(100, 0, 0.0, loc)


def test_incorrect_parkinglot_arg():
    with pytest.raises(ValueError):
        ParkingLot(-100, 'test_name', 0.0, loc)


def test_zero_capacity_parkinglot():
    with pytest.raises(ValueError):
        ParkingLot(0, 'test_name', 0.0, loc)