Ejemplo n.º 1
0
def test_multiple_classes_with_same_name_for_handler():
    class ChargerA(cp):
        @on(Action.Heartbeat)
        def heartbeat(self, **kwargs):
            pass

    class ChargerB(cp):
        @on(Action.Heartbeat)
        def heartbeat(self, **kwargs):
            pass

    A = ChargerA("A", None)
    B = ChargerB("B", None)
    route_mapA = create_route_map(A)
    route_mapB = create_route_map(B)
    assert route_mapA["Heartbeat"] != route_mapB["Heartbeat"]
Ejemplo n.º 2
0
def test_create_route_map():
    """
    This test validates that route map is created correctly and holds all
    functions decorated with the @on() and @after decorators.

    """
    class ChargePoint:
        @on(Action.Heartbeat)
        def on_heartbeat(self):
            pass

        @after(Action.Heartbeat)
        def after_heartbeat(self):
            pass

        @on(Action.MeterValues)
        def meter_values(self):
            pass

        def undecorated(self):
            pass

    cp = ChargePoint()
    route_map = create_route_map(cp)

    assert route_map == {
        Action.Heartbeat: {
            '_on_action': cp.on_heartbeat,
            '_after_action': cp.after_heartbeat,
        },
        Action.MeterValues: {
            '_on_action': cp.meter_values,
        },
    }
Ejemplo n.º 3
0
    def __init__(self, id, connection, response_timeout=30):
        """

        Args:
            charger_id (str): ID of the charger.
            connection: Connection to CP.
            response_timeout (int): When no response on a request is received
                within this interval, a asyncio.TimeoutError is raised.

        """
        self.id = id

        # The maximum time in seconds it may take for a CP to respond to a
        # CALL. An asyncio.TimeoutError will be raised if this limit has been
        # exceeded.
        self._response_timeout = response_timeout

        # A connection to the client. Currently this is an instance of gh
        self._connection = connection

        # A dictionary that hooks for Actions. So if the CS receives a it will
        # look up the Action into this map and execute the corresponding hooks
        # if exists.
        self.route_map = create_route_map(self)

        self._call_lock = asyncio.Lock()

        # A queue used to pass CallResults and CallErrors from
        # the self.serve() task to the self.call() task.
        self._response_queue = asyncio.Queue()

        # Function used to generate unique ids for CALLs. By default
        # uuid.uuid4() is used, but it can be changed. This is meant primarily
        # for testing purposes to have predictable unique ids.
        self._unique_id_generator = uuid.uuid4
Ejemplo n.º 4
0
async def test_route_message_with_existing_route(base_central_system,
                                                 boot_notification_call):
    """ Test if the correct handler is called when routing a message.
    Also test if payload of request is injected correctly in handler.

    """
    @on(Action.BootNotification)
    def on_boot_notification(charge_point_model, charge_point_vendor,
                             **kwargs):  # noqa
        assert charge_point_vendor == "Alfen BV"
        assert charge_point_model == "ICU Eve Mini"
        assert kwargs['firmware_version'] == "#1:3.4.0-2990#N:217H;1.0-223"

        return call_result.BootNotificationPayload(
            current_time='2018-05-29T17:37:05.495259',
            interval=350,
            status='Accepted',
        )

    setattr(base_central_system, 'on_boot_notification', on_boot_notification)
    base_central_system.route_map = create_route_map(base_central_system)

    await base_central_system.route_message(boot_notification_call)
    base_central_system._connection.send.assert_called_once_with(
        json.dumps([
            3, "1", {
                'currentTime': '2018-05-29T17:37:05.495259',
                'interval': 350,
                'status': 'Accepted',
            }
        ]))
Ejemplo n.º 5
0
async def test_route_message_with_existing_route(base_central_system,
                                                 boot_notification_call):
    """ Test if the correct handler is called when routing a message.
    Also test if payload of request is injected correctly in handler.

    """
    @on("BootNotification")
    def on_boot_notification(reason, charging_station, **kwargs):
        assert reason == 'PowerUp'
        assert charging_station == {
            'vendor_name': 'ICU Eve Mini',
            'firmware_version': "#1:3.4.0-2990#N:217H;1.0-223",
            'model': 'ICU Eve Mini',
        }

        return call_result.BootNotificationPayload(
            current_time='2018-05-29T17:37:05.495259',
            interval=350,
            status='Accepted',
        )

    @after("BootNotification")
    def after_boot_notification(reason, charging_station, **kwargs):
        assert reason == 'PowerUp'
        assert charging_station == {
            'vendor_name': 'ICU Eve Mini',
            'firmware_version': "#1:3.4.0-2990#N:217H;1.0-223",
            'model': 'ICU Eve Mini',
        }

    setattr(base_central_system, 'on_boot_notification', on_boot_notification)
    setattr(base_central_system, 'after_boot_notification',
            after_boot_notification)
    base_central_system.route_map = create_route_map(base_central_system)

    await base_central_system.route_message(boot_notification_call)
    base_central_system._connection.send.assert_called_once_with(
        json.dumps([
            3,
            "1",
            {
                'currentTime': '2018-05-29T17:37:05.495259',
                'interval': 350,
                'status': 'Accepted',
            }
        ],
            separators=(',', ':')
        )
    )
Ejemplo n.º 6
0
async def test_route_message_without_validation(base_central_system):
    @on(Action.BootNotification, skip_schema_validation=True)
    def on_boot_notification(**kwargs):  # noqa
        assert kwargs['firmware_version'] == "#1:3.4.0-2990#N:217H;1.0-223"

        return call_result.BootNotificationPayload(
            current_time='2018-05-29T17:37:05.495259',
            interval=350,
            # 'Yolo' is not a valid value for for field status.
            status='Yolo',
        )

    setattr(base_central_system, 'on_boot_notification', on_boot_notification)
    base_central_system.route_map = create_route_map(base_central_system)

    await base_central_system.route_message(
        json.dumps(
            [
                2,
                1,
                "BootNotification",
                {
                    # The payload is missing the required fields 'chargepointVendor'
                    # and 'chargePointModel'.
                    "firmwareVersion": "#1:3.4.0-2990#N:217H;1.0-223"
                }
            ],
            separators=(',', ':')))

    base_central_system._connection.send.call_args == \
        mock.call(json.dumps([
            3,
            "1",
            {
                'currentTime': '2018-05-29T17:37:05.495259',
                'interval': 350,
                'status': 'Yolo',
            }
        ],
            separators=(',', ':')
        ))