Exemplo n.º 1
0
    async def _feed_protocol_handlers(self, protocol: ProtocolAPI) -> None:
        # do not start consuming from the protocol stream until
        # `start_protocol_streams` has been called and the multiplexer is
        # active.
        try:
            await asyncio.wait_for(asyncio.gather(self._handlers_ready.wait()),
                                   timeout=10)
        except asyncio.TimeoutError as err:
            self.logger.info('Timedout waiting for handler ready signal')
            raise asyncio.TimeoutError(
                "The handlers ready event was never set.  Ensure that "
                "`Connection.start_protocol_streams()` is being called"
            ) from err

        # we don't need to use wait_iter here because the multiplexer does it
        # for us.
        async for cmd in self._multiplexer.stream_protocol_messages(protocol):
            self.logger.debug2('Handling command: %s', type(cmd))
            # local copy to prevent multation while iterating
            protocol_handlers = set(self._protocol_handlers[type(protocol)])
            for proto_handler_fn in protocol_handlers:
                self.logger.debug2(
                    'Running protocol handler %s for protocol=%s command=%s',
                    proto_handler_fn,
                    protocol,
                    type(cmd),
                )
                self.run_task(proto_handler_fn(self, cmd))
            command_handlers = set(self._command_handlers[type(cmd)])
            for cmd_handler_fn in command_handlers:
                self.logger.debug2(
                    'Running command handler %s for protocol=%s command=%s',
                    cmd_handler_fn,
                    protocol,
                    type(cmd),
                )
                self.run_task(cmd_handler_fn(self, cmd))
Exemplo n.º 2
0
    def create(cls, serial_id):
        """ Create a new asynchronous Linkbot object.

        :param serial_id: The robot to connect to
        :type serial_id: str
        :returns: AsyncLinkbot() object.
        """
        try:
            self = cls()
            self._proxy = yield from asyncio.wait_for(
                _AsyncLinkbot.create(serial_id), util.DEFAULT_TIMEOUT)
            self.rb_add_broadcast_handler = self._proxy.rb_add_broadcast_handler
            self.close = self._proxy.close
            self.enableButtonEvent = self._proxy.enableButtonEvent
            self._accelerometer = yield from peripherals.Accelerometer.create(
                self)
            self._battery = yield from peripherals.Battery.create(self)
            self._button = yield from peripherals.Button.create(self)
            self._buzzer = yield from peripherals.Buzzer.create(self)
            self._eeprom_obj = yield from peripherals.Eeprom.create(self)
            self._led = yield from peripherals.Led.create(self)
            self._motors = yield from peripherals.Motors.create(self)
            self._twi = yield from peripherals.Twi.create(self)
            self._serial_id = serial_id

            # Enable joint events
            yield from self._proxy.enableJointEvent(enable=True)
            self._proxy.rb_add_broadcast_handler('jointEvent',
                                                 self.__joint_event)
            self._proxy.rb_add_broadcast_handler('debugMessageEvent',
                                                 self.__debug_message_event)
            return self
        except asyncio.TimeoutError:
            raise asyncio.TimeoutError(
                'Timed out trying to connect to remote robot. Please ensure '
                'that the remote robot is on and not currently connected to '
                'another computer.')
Exemplo n.º 3
0
    async def on_response_message(self, message: IncomingMessage):
        """ Process a response.

        This method is used to process standard responses as well as requests
        that expired and were sent to the dead letter exchange to which the
        response queue is also linked to.
        """
        await message.ack()

        if message.correlation_id is None:
            logger.warning(f"Message had no correlation_id: {message}")
            return

        f = self.futures.pop(
            message.correlation_id, None
        )  # type: Optional[asyncio.Future]

        if f is None:
            logger.warning(
                f"Unrecognized correlation_id: {message.correlation_id}: {message}"
            )
            return

        if "x-death" in message.headers:
            # The presence of the 'x-death' header indicates the return of an
            # unprocessed request.
            f.set_exception(asyncio.TimeoutError("Message timed-out"))
            return

        try:
            payload = utils.decode_message(message)
        except Exception as e:
            logger.error(f"Failed to deserialize response on message: {message}")
            f.set_exception(e)
            return

        f.set_result(payload)
Exemplo n.º 4
0
    def send_packet_and_watch(self, request_packet, retries=0, timeout=DEFAULT_RESPONSE_TIMEOUT):
        """
        Send request packet to the server with timeout and trying to resend it some times

        Params:
            request_packet(aioradius.protocol.Packet) - packet for sending
            retries(int) - number of resend attempts
            timeout(int) - delay between resend attempts

        Return:
            response from server
        """
        trying_idx = 0
        response = None
        if retries > 0:
            retries -= 1

        while trying_idx <= retries:
            try:
                response = yield from asyncio.wait_for(self.send_packet_once(request_packet), timeout)
            except asyncio.TimeoutError:
                trying_idx += 1
                logger.warning("Timeout for {} ({} sec)".format(request_packet, timeout))
                continue
            except packet.PacketError:
                trying_idx += 1
                logger.warning("Validation error for {}".format(request_packet))
                continue
            else:
                break
        if response is not None:
            return response
        else:
            raise asyncio.TimeoutError("All {} retries to sent {} are timed out".format(
                retries + 1,
                request_packet
            ))
Exemplo n.º 5
0
 async def _request(self,
                    unit: int,
                    function_code: int,
                    address: int,
                    *values: int,
                    decode_packing: str,
                    packet_length: int,
                    timeout: float = 0.1):
     if unit is None:
         unit = self.default_unit_id
     async with self.transaction:
         try:
             await asyncio.wait_for(self.connected.wait(), 2)
         except asyncio.TimeoutError as e:
             raise asyncio.TimeoutError(
                 "Failed modbus request as client is not connected") from e
         packet = self._encode_packet(unit, function_code, address, *values)
         self.protocol.buffer.clear()
         self.transport.write(packet)
         unit_id, func_code, *values, crc = await self.protocol.decode(
             packet_length, decode_packing, timeout=timeout)
         assert unit_id == unit
         assert function_code == func_code
         return values
Exemplo n.º 6
0
async def test_exception_handling():
    """Test handling of exceptions."""
    send_messages = []
    user = MockUser()
    refresh_token = Mock()
    conn = websocket_api.ActiveConnection(logging.getLogger(__name__), None,
                                          send_messages.append, user,
                                          refresh_token)

    for (exc, code, err) in (
        (exceptions.Unauthorized(), websocket_api.ERR_UNAUTHORIZED,
         "Unauthorized"),
        (
            vol.Invalid("Invalid something"),
            websocket_api.ERR_INVALID_FORMAT,
            "Invalid something. Got {'id': 5}",
        ),
        (asyncio.TimeoutError(), websocket_api.ERR_TIMEOUT, "Timeout"),
        (
            exceptions.HomeAssistantError("Failed to do X"),
            websocket_api.ERR_UNKNOWN_ERROR,
            "Failed to do X",
        ),
        (ValueError("Really bad"), websocket_api.ERR_UNKNOWN_ERROR,
         "Unknown error"),
        (
            exceptions.HomeAssistantError(),
            websocket_api.ERR_UNKNOWN_ERROR,
            "Unknown error",
        ),
    ):
        send_messages.clear()
        conn.async_handle_exception({"id": 5}, exc)
        assert len(send_messages) == 1
        assert send_messages[0]["error"]["code"] == code
        assert send_messages[0]["error"]["message"] == err
Exemplo n.º 7
0
    async def simulate_and_collect_stats(self, testname, spec):
        pools = [connpool.Pool, connpool._NaivePool]

        js_data = []
        for pool_cls in pools:
            try:
                data = await asyncio.wait_for(
                    self.simulate_once(
                        spec, pool_cls, collect_stats=True),
                    spec.timeout
                )
            except asyncio.TimeoutError:
                raise asyncio.TimeoutError(f'timeout with {pool_cls!r}')
            js_data.append(data)

        js_data = {
            'desc': textwrap.dedent(spec.desc) if spec.desc else None,
            'test_name': testname,
            'now': str(datetime.datetime.now()),
            'spec': dataclasses.asdict(spec),
            'runs': js_data
        }

        return js_data
Exemplo n.º 8
0
    async def result(
            self, timeout: Optional[float] = None,
            *, pole_delay: float = 0.5,
    ) -> Any:
        """
        Get the result of the job, including waiting if it's not yet available.
        If the job raised an exception, it will be raised here.

        :param timeout: maximum time to wait for the job result before raising
                        ``TimeoutError``, will wait forever
        :param pole_delay: how often to poll redis for the job result
        """
        async for delay in poll(pole_delay):
            info = await self.result_info()
            if info:
                result = info.result
                if info.success:
                    return result
                elif isinstance(result, Exception):
                    raise result
                else:
                    raise SerializationError(result)
            if timeout is not None and delay > timeout:
                raise asyncio.TimeoutError()
Exemplo n.º 9
0
    def test_setup_platform_timeout_loginpage(self, mock_error,
                                              aioclient_mock):
        """Setup a platform with timeout on loginpage."""
        aioclient_mock.get(
            "http://{}/common_page/login.html".format(self.host),
            exc=asyncio.TimeoutError()
        )
        aioclient_mock.post(
            "http://{}/xml/getter.xml".format(self.host),
            content=b'successful',
        )

        with assert_setup_component(1):
            assert setup_component(
                self.hass, DOMAIN, {DOMAIN: {
                    CONF_PLATFORM: 'upc_connect',
                    CONF_HOST: self.host,
                    CONF_PASSWORD: '******'
                }})

        assert len(aioclient_mock.mock_calls) == 1

        assert 'Error setting up platform' in \
            str(mock_error.call_args_list[-1])
Exemplo n.º 10
0
    async def start(self, **kwargs):
        await super().start(**kwargs)

        while (await self.describe_pod()).status.phase == "Pending":
            await asyncio.sleep(0.1)

        while self.address is None:
            logs = await self.logs()
            for line in logs.splitlines():
                if "Scheduler at:" in line:
                    self.address = line.split("Scheduler at:")[1].strip()
            await asyncio.sleep(0.1)

        self.service = await self._create_service()
        self.address = "tcp://{name}.{namespace}:{port}".format(
            name=self.service.metadata.name,
            namespace=self.namespace,
            port=SCHEDULER_PORT,
        )
        if self.service.spec.type == "LoadBalancer":
            # Wait for load balancer to be assigned
            start = time.time()
            while self.service.status.load_balancer.ingress is None:
                if (self._service_wait_timeout_s > 0 and
                        time.time() > start + self._service_wait_timeout_s):
                    raise asyncio.TimeoutError(
                        "Timed out waiting for Load Balancer to be provisioned."
                    )
                self.service = await self.core_api.read_namespaced_service(
                    self.cluster_name, self.namespace)
                await asyncio.sleep(0.2)

            [loadbalancer_ingress] = self.service.status.load_balancer.ingress
            loadbalancer_host = loadbalancer_ingress.hostname or loadbalancer_ingress.ip
            self.external_address = "tcp://{host}:{port}".format(
                host=loadbalancer_host, port=SCHEDULER_PORT)
Exemplo n.º 11
0
    async def _fetch(self, url):
        try:
            # Set a timeout of 30 seconds
            async with timeout(30.0):
                headers = await self.get_headers()

                # Fetch the url
                async with self.session.get(url, headers=headers) as resp:
                    # If the get request failed in some way, return None
                    if resp.status != 200:
                        return None

                    # Convert the data to json format
                    data = await resp.json()

        # If the request times out, raise a better error
        except asyncio.TimeoutError:
            raise asyncio.TimeoutError(f"Timed out while fetching '{url}'")

        # This is probably useless, but just in case
        if self.error_detector(data):
            return None

        return data
Exemplo n.º 12
0
 async def wait_till_subscriptions_active(self, subscriptions):
     """:param subcriptions: [subscription, ...] or {subcription: timeout, ...}"""
     timeouts_by_sub = subscriptions
     if not isinstance(subscriptions, dict):
         timeouts_by_sub = dict.fromkeys(subscriptions, None)
     timeouts_by_sub = {
         self.get_subscription(x): timeout
         for x, timeout in timeouts_by_sub.items()
     }
     started = time.time()
     while True:
         not_active = [s for s in timeouts_by_sub if not s.state]
         if not not_active:
             break
         elapsed = time.time() - started
         exceeded = [
             s for s in not_active if timeouts_by_sub[s] is not None
             and elapsed > timeouts_by_sub[s]
         ]
         if exceeded:
             raise asyncio.TimeoutError(
                 'Subcription(s) {} have exceeded their timeout'.format(
                     exceeded))
         await asyncio.sleep(0.05)
Exemplo n.º 13
0
    async def wait_for_serial(self, serial, timeout=DEFAULT_MAX_WAIT):
        '''Wait for a device with the specified serial number to attach.

        Args:
            serial (string): Serial number of the device to wait for.
            timeout (float): The maximum amount of time in seconds to wait for a
                matching device to be connected.
                Set to None to wait indefinitely, or -1 to only check currently
                connected devices.
        Returns:
            int: The device id of the connected device
        Raises:
            asyncio.TimeoutError if the device with the specified serial number doesn't appear.
        '''
        timeout = Timeout(timeout)
        with self.attach_watcher(include_existing=True) as watcher:
            while not timeout.expired:
                action, device_id, info = await watcher.wait_for_next(timeout.remaining)
                if action != ACTION_ATTACHED:
                    continue
                if info['SerialNumber'].lower() == serial.lower():
                    return device_id

        raise asyncio.TimeoutError("No devices matching serial number found")
Exemplo n.º 14
0
async def test_execute__with_attempt_timeout__idempotent(mocker):
    cl = Cluster(["addr1"], max_attempts=3)

    mocked_pooler = mocker.patch.object(cl, "_pooler", new=get_pooler_mock())
    pool = mocked_pooler._pool
    pool.execute.side_effect = asyncio.TimeoutError()

    mocked_manager = mocker.patch.object(cl,
                                         "_manager",
                                         new=get_manager_mock())
    state = mocked_manager.get_state.return_value
    state.slot_master.return_value.addr = Address("1.2.3.4", 9999)
    state.random_node.return_value.addr = Address("6.6.6.6", 9999)

    mocked_execute_retry_slowdown = mocker.patch.object(
        cl, "_execute_retry_slowdown", new=create_async_mock())

    with pytest.raises(asyncio.TimeoutError):
        await cl.execute("get", "key")

    assert mocked_manager.get_state.call_count == 3
    assert mocked_pooler.ensure_pool.call_count == 3
    assert mocked_manager.require_reload_state.call_count == 3
    assert mocked_execute_retry_slowdown.call_count == 2
Exemplo n.º 15
0
async def test_async_step_bluetooth_valid_device_but_missing_payload(hass):
    """Test discovery via bluetooth with a valid device but missing payload."""
    with patch(
        "homeassistant.components.xiaomi_ble.config_flow.async_process_advertisements",
        side_effect=asyncio.TimeoutError(),
    ):
        result = await hass.config_entries.flow.async_init(
            DOMAIN,
            context={"source": config_entries.SOURCE_BLUETOOTH},
            data=MISSING_PAYLOAD_ENCRYPTED,
        )
    assert result["type"] == FlowResultType.FORM
    assert result["step_id"] == "confirm_slow"

    with patch(
        "homeassistant.components.xiaomi_ble.async_setup_entry", return_value=True
    ):
        result2 = await hass.config_entries.flow.async_configure(
            result["flow_id"], user_input={}
        )
    assert result2["type"] == FlowResultType.CREATE_ENTRY
    assert result2["title"] == "Temperature/Humidity Sensor 565384 (LYWSD03MMC)"
    assert result2["data"] == {}
    assert result2["result"].unique_id == "A4:C1:38:56:53:84"
Exemplo n.º 16
0
async def test_simple_inspector_exception(aioresponses):
    aioresponses.get(
        "http://getstatuscode.com/timeout",
        exception=asyncio.TimeoutError("test error"),
    )
    aioresponses.get(
        "http://getstatuscode.com/error",
        exception=aiohttp.ClientError("test error"),
    )
    client = HttpMonitor()
    async with aiohttp.ClientSession() as session:
        resp = await client.check(session,
                                  url="http://getstatuscode.com/error")
        assert resp.url == "http://getstatuscode.com/error"
        assert resp.status_code == -1
        assert resp.error == "test error"
        assert not resp.ok

        resp = await client.check(session,
                                  url="http://getstatuscode.com/timeout")
        assert resp.url == "http://getstatuscode.com/timeout"
        assert resp.status_code == -1
        assert resp.error == "host does not respond (timeout)"
        assert not resp.ok
Exemplo n.º 17
0
 def _execute(self, method, path, params=None, timeout=None, loop=None):
     if loop is None:
         loop = self.loop
     if timeout is None:
         timeout = self.read_timeout
     failed = False
     # TODO: whatif self._machines_cache is empty ?
     for idx, uri in enumerate(self._machines_cache):
         try:
             resp = yield from asyncio.wait_for(
                 aiohttp.request(
                     method, uri + path, params=params, loop=loop
                 ),
                 timeout, loop=loop
             )
             if failed:
                 self._machine_cache = self._machine_cache[idx:]
                 if not self._cache_update_scheduled:
                     self._cache_update_scheduled = True
                     self.loop.create_task(self._update_machine_cache())
             return resp
         except asyncio.TimeoutError:
             failed = True
     raise asyncio.TimeoutError()
Exemplo n.º 18
0
    def first(futures: [asyncio.Future],
              loop,
              timeout=None,
              cancel_others=True):
        """Return first future and cancel others."""
        # wait for first
        try:
            done, pending = yield from asyncio.wait(
                iter(futures),
                loop=loop,
                timeout=timeout,
                return_when=asyncio.FIRST_COMPLETED)
        except asyncio.CancelledError:
            Util.cancel_futures(futures)
            raise

        if cancel_others:
            # cancel all other futures
            for future in pending:
                future.cancel()

        if not done:
            raise asyncio.TimeoutError()
        return next(iter(done))
Exemplo n.º 19
0
 async def wait(self,
                tx: basetransaction.BaseTransaction,
                height=-1,
                timeout=None):
     addresses = set()
     for txi in tx.inputs:
         if txi.txo_ref.txo is not None:
             addresses.add(
                 self.hash160_to_address(
                     txi.txo_ref.txo.script.values['pubkey_hash']))
     for txo in tx.outputs:
         addresses.add(
             self.hash160_to_address(txo.script.values['pubkey_hash']))
     records = await self.db.get_addresses(address__in=addresses)
     _, pending = await asyncio.wait([
         self.on_transaction.where(
             partial(
                 lambda a, e: a == e.address and e.tx.height >= height and e
                 .tx.id == tx.id, address_record['address']))
         for address_record in records
     ],
                                     timeout=timeout)
     if pending:
         raise asyncio.TimeoutError('Timed out waiting for transaction.')
Exemplo n.º 20
0
    def test_service_say_timeout(self, aioclient_mock):
        """Test service call say."""
        calls = mock_service(self.hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)

        aioclient_mock.get(
            self.url, params=self.url_param, status=200,
            exc=asyncio.TimeoutError())

        config = {
            tts.DOMAIN: {
                'platform': 'marytts',
            }
        }

        with assert_setup_component(1, tts.DOMAIN):
            setup_component(self.hass, tts.DOMAIN, config)

        self.hass.services.call(tts.DOMAIN, 'marytts_say', {
            tts.ATTR_MESSAGE: "HomeAssistant",
        })
        self.hass.block_till_done()

        assert len(calls) == 0
        assert len(aioclient_mock.mock_calls) == 1
Exemplo n.º 21
0
    def test_value_reader_read_timeout(self, logger_warning_mock):
        """Test value reader: read timeout."""
        xknx = XKNX()
        value_reader = ValueReader(xknx, GroupAddress("0/0/0"))
        value_reader.response_received_or_timeout.wait = MagicMock(
            side_effect=asyncio.TimeoutError()
        )

        timed_out_read = self.loop.run_until_complete(value_reader.read())

        # GroupValueRead telegram is still in the queue because we are not actually processing it
        self.assertEqual(xknx.telegrams.qsize(), 1)
        # Warning was logged
        logger_warning_mock.assert_called_once_with(
            "Error: KNX bus did not respond in time (%s secs) to GroupValueRead request for: %s",
            2.0,
            GroupAddress("0/0/0"),
        )
        # Callback was removed again
        self.assertEqual(xknx.telegram_queue.telegram_received_cbs, [])
        # No telegram was received
        self.assertIsNone(value_reader.received_telegram)
        # Unsuccessfull read() returns None
        self.assertIsNone(timed_out_read)
    async def test_watch_timeout(self):
        fake_resp = CoroutineMock()
        fake_resp.content.readline = CoroutineMock()
        fake_resp.release = Mock()

        mock_event = {
            "type": "ADDED",
            "object": {
                "metadata": {
                    "name": "test1555",
                    "resourceVersion": "1555"
                },
                "spec": {},
                "status": {}
            }
        }

        fake_resp.content.readline.side_effect = [
            json.dumps(mock_event).encode('utf8'),
            asyncio.TimeoutError(), b""
        ]

        fake_api = Mock()
        fake_api.get_namespaces = CoroutineMock(return_value=fake_resp)
        fake_api.get_namespaces.__doc__ = ':return: V1NamespaceList'

        watch = kubernetes_asyncio.watch.Watch()
        async with watch.stream(fake_api.get_namespaces) as stream:
            async for e in stream:  # noqa
                pass

        fake_api.get_namespaces.assert_has_calls([
            call(_preload_content=False, watch=True),
            call(_preload_content=False, watch=True, resource_version='1555')
        ])
        fake_resp.release.assert_called_once_with()
Exemplo n.º 23
0
 async def _wait_for_message_by_key(
     self, key: Any, *, timeout: float = None, max_interval: float = 2.0
 ) -> SignalEvent:
     app = self.case.app
     time_start = monotonic()
     remaining = timeout
     # See if the key is already there.
     try:
         return self._get_current_value(key)
     except KeyError:
         pass
     # If not, wait for it to arrive.
     while not app.should_stop:
         if remaining is not None:
             remaining = remaining - (monotonic() - time_start)
         try:
             if remaining is not None and remaining <= 0.0:
                 try:
                     return self._get_current_value(key)
                 except KeyError:
                     raise asyncio.TimeoutError() from None
             max_wait = None
             if remaining is not None:
                 max_wait = min(remaining, max_interval)
             await self._wait_for_resolved(timeout=max_wait)
         except asyncio.TimeoutError:
             msg = f"Timed out waiting for signal {self.name} ({timeout})"
             raise LiveCheckTestTimeout(msg) from None
         if app.should_stop:
             break
         try:
             val = self._get_current_value(key)
             return val
         except KeyError:
             pass
     raise asyncio.CancelledError()
Exemplo n.º 24
0
    async def receive_vrfyres(self, timeout: float) -> Optional[Segment]:
        """Variant of BaseTest.receive that allows checksum errors."""
        while timeout > 0:
            start = time.monotonic()
            data = await asyncio.wait_for(self.recv_queue.get(),
                                          timeout,
                                          loop=self._loop)
            timeout -= (time.monotonic() - start)

            try:
                seg = Segment.from_bytes(self.dst.ip.packed,
                                         self.src.ip.packed, data)
            except ChecksumError:
                return None
            except ValueError:
                # Discard invalid segments silently and retry
                pass
            else:
                if seg.flags & 0x02:
                    # Collect ISNs for ISN predictability meta-test
                    self._isns.append((time.monotonic(), seg.seq))
                return seg

        raise asyncio.TimeoutError()
Exemplo n.º 25
0
    assert result["data"] == {
        "url": "ws://host1:3001",
        "usb_path": "/test",
        "network_key": "abc123",
        "use_addon": True,
        "integration_created_addon": False,
    }
    assert len(mock_setup.mock_calls) == 1
    assert len(mock_setup_entry.mock_calls) == 1


@pytest.mark.parametrize(
    "discovery_info, server_version_side_effect",
    [({
        "config": ADDON_DISCOVERY_INFO
    }, asyncio.TimeoutError())],
)
async def test_supervisor_discovery_cannot_connect(opp, supervisor,
                                                   get_addon_discovery_info):
    """Test Supervisor discovery and cannot connect."""
    await setup.async_setup_component(opp, "persistent_notification", {})

    result = await opp.config_entries.flow.async_init(
        DOMAIN,
        context={"source": config_entries.SOURCE_OPPIO},
        data=ADDON_DISCOVERY_INFO,
    )

    assert result["type"] == "abort"
    assert result["reason"] == "cannot_connect"
Exemplo n.º 26
0
 def watchdog_cb(fut: Awaitable) -> None:
     self._raise_error(asyncio.TimeoutError(
         'Navigation Timeout Exceeded: {} ms exceeded'.format(
             self._timeout)
     ))
Exemplo n.º 27
0
 def _pong_not_received(self) -> None:
     if self._req is not None and self._req.transport is not None:
         self._closed = True
         self._close_code = WSCloseCode.ABNORMAL_CLOSURE
         self._exception = asyncio.TimeoutError()
         self._req.transport.close()

@pytest.mark.asyncio
async def test_servers_cache_failure(client, protocol_client, backend_client,
                                     servers_cache):
    servers_cache.get.return_value = async_raise(AccessDenied())
    await client.run()
    servers_cache.get.assert_called_once_with()
    backend_client.get_authentication_data.assert_not_called()
    protocol_client.authenticate.assert_not_called()
    protocol_client.run.assert_not_called()


@pytest.mark.asyncio
@pytest.mark.parametrize("exception", [
    asyncio.TimeoutError(),
    IOError(),
    websockets.InvalidURI("wss://websocket_1"),
    websockets.InvalidHandshake()
])
async def test_connect_error(client, backend_client, protocol_client,
                             servers_cache, mocker, exception):
    servers_cache.get.side_effect = [
        async_return_value(["wss://websocket_1", "wss://websocket_2"]),
    ]
    connect = mocker.patch(
        "protocol.websocket_client.websockets.connect",
        side_effect=[async_raise(exception),
                     async_return_value(MagicMock())])
    backend_client.get_authentication_data.return_value = STEAM_ID, ACCOUNT_NAME, TOKEN
    protocol_client.authenticate.return_value = async_return_value(None)
    async def call(self, payload, suppress=True):
        """
        Send Call message to client and return payload of response.

        The given payload is transformed into a Call object by looking at the
        type of the payload. A payload of type BootNotificationPayload will
        turn in a Call with Action BootNotification, a HeartbeatPayload will
        result in a Call with Action Heartbeat etc.

        A timeout is raised when no response has arrived before expiring of
        the configured timeout.

        When waiting for a response no other Call message can be send. So this
        function will wait before response arrives or response timeout has
        expired. This is in line the OCPP specification

        Suppress is used to maintain backwards compatibility. When set to True,
        if response is a CallError, then this call will be suppressed. When
        set to False, an exception will be raised for users to handle this
        CallError.

        """
        camel_case_payload = snake_to_camel_case(asdict(payload))

        call = Call(
            unique_id=str(self._unique_id_generator()),
            action=payload.__class__.__name__[:-7],
            payload=remove_nones(camel_case_payload)
        )

        validate_payload(call, self._ocpp_version)

        # Use a lock to prevent make sure that only 1 message can be send at a
        # a time.
        async with self._call_lock:
            await self._send(call.to_json())
            try:
                response = \
                    await self._get_specific_response(call.unique_id,
                                                      self._response_timeout)
            except asyncio.TimeoutError:
                raise asyncio.TimeoutError(
                    f"Waited {self._response_timeout}s for response on "
                    f"{call.to_json()}."
                )

        if response.message_type_id == MessageType.CallError:
            LOGGER.warning("Received a CALLError: %s'", response)
            if suppress:
                return
            raise response.to_exception()
        else:
            response.action = call.action
            validate_payload(response, self._ocpp_version)

        snake_case_payload = camel_to_snake_case(response.payload)
        # Create the correct Payload instance based on the received payload. If
        # this method is called with a call.BootNotificationPayload, then it
        # will create a call_result.BootNotificationPayload. If this method is
        # called with a call.HeartbeatPayload, then it will create a
        # call_result.HeartbeatPayload etc.
        cls = getattr(self._call_result, payload.__class__.__name__)  # noqa
        return cls(**snake_case_payload)
Exemplo n.º 30
0
 async def on_wait_for(*args, **kwargs):
     if wait_for.call_count >= 2:
         sup._stopped.set()
     raise asyncio.TimeoutError()