Skip to content

Merge pull request #12 from JakubAndrysek/wokwi-python-client #24

Merge pull request #12 from JakubAndrysek/wokwi-python-client

Merge pull request #12 from JakubAndrysek/wokwi-python-client #24

GitHub Actions / Test Results failed Sep 12, 2025 in 0s

1 errors, 37 pass in 16m 27s

 76 files   76 suites   16m 27s ⏱️
 38 tests  37 ✅ 0 💤 0 ❌ 1 🔥
241 runs  240 ✅ 0 💤 0 ❌ 1 🔥

Results for commit 9b94d28.

Annotations

Check failure on line 0 in validation.hello_world.test_hello_world

See this annotation in the file changed.

@github-actions github-actions / Test Results

1 out of 7 runs with error: test_hello_world (validation.hello_world.test_hello_world)

./artifacts/test-results-wokwi-esp32-validation/validation/hello_world/esp32/hello_world.xml [took 1s]
Raw output
failed on setup with "websockets.exceptions.ConnectionClosedError: no close frame received or sent"
self = <websockets.legacy.client.WebSocketClientProtocol object at 0x7f00889656a0>

    async def transfer_data(self) -> None:
        """
        Read incoming messages and put them in a queue.
    
        This coroutine runs in a task until the closing handshake is started.
    
        """
        try:
            while True:
>               message = await self.read_message()
                          ^^^^^^^^^^^^^^^^^^^^^^^^^

/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/site-packages/websockets/legacy/protocol.py:963: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/site-packages/websockets/legacy/protocol.py:1033: in read_message
    frame = await self.read_data_frame(max_size=self.max_size)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/site-packages/websockets/legacy/protocol.py:1108: in read_data_frame
    frame = await self.read_frame(max_size)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/site-packages/websockets/legacy/protocol.py:1165: in read_frame
    frame = await Frame.read(
/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/site-packages/websockets/legacy/framing.py:68: in read
    data = await reader(2)
           ^^^^^^^^^^^^^^^
/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/asyncio/streams.py:769: in readexactly
    await self._wait_for_data('readexactly')
/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/asyncio/streams.py:539: in _wait_for_data
    await self._waiter
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <_SelectorSocketTransport closed fd=20>
data = b'\x17\x03\x03@\x11I\xef\xbd\x94\xces\xbd\x89\x8c\xf2V0\x03\x18i\xf7Q8\x0bf\x12\xd3\x04\xbb%\x81\x99\xfa1\x0cH\xd5\x05...e\xa7\x95"\xb0TD\xc6\xd07\x1cS\xa8\x00\xc2\nW\x9c\x91W\x95\x83M\n\xb1\x95o\x8a\xac\xf9f\xea\xa1\xb8\x83^\xb2\x80\x1e3C'

    def write(self, data):
        if not isinstance(data, (bytes, bytearray, memoryview)):
            raise TypeError(f'data argument must be a bytes-like object, '
                            f'not {type(data).__name__!r}')
        if self._eof:
            raise RuntimeError('Cannot call write() after write_eof()')
        if self._empty_waiter is not None:
            raise RuntimeError('unable to write; sendfile is in progress')
        if not data:
            return
    
        if self._conn_lost:
            if self._conn_lost >= constants.LOG_THRESHOLD_FOR_CONNLOST_WRITES:
                logger.warning('socket.send() raised exception.')
            self._conn_lost += 1
            return
    
        if not self._buffer:
            # Optimization: try to send now.
            try:
>               n = self._sock.send(data)
                    ^^^^^^^^^^^^^^^^^^^^^
E               ConnectionResetError: [Errno 104] Connection reset by peer

/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/asyncio/selector_events.py:1067: ConnectionResetError

The above exception was the direct cause of the following exception:

args = ()
kwargs = {'_fixture_classes_and_options': ClassCliOptions(classes={'app': <class 'pytest_embedded_arduino.app.ArduinoApp'>, 'wo...logfile_extension='.log'), 'wokwi': None}})), 'app': <pytest_embedded_arduino.app.ArduinoApp object at 0x7f0088ae9fd0>}
_close_or_terminate = <function multi_dut_generator_fixture.<locals>.wrapper.<locals>._close_or_terminate at 0x7f008891dee0>
res = None

    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        def _close_or_terminate(obj):
            if obj is None:
                del obj
                return
    
            try:
                if isinstance(obj, (subprocess.Popen, multiprocessing.process.BaseProcess)):
                    obj.terminate()
                    obj.kill()
                elif isinstance(obj, io.IOBase):
                    try:
                        obj.close()
                    except Exception as e:
                        logging.debug('file %s closed failed with error: %s', obj, str(e))
                else:
                    try:
                        obj.close()
                    except AttributeError:
                        try:
                            obj.terminate()
                        except AttributeError:
                            pass
                    except Exception as e:
                        logging.debug('Not properly caught object %s: %s', obj, str(e))
            except Exception as e:
                logging.debug('%s: %s', obj, str(e))
                return  # swallow up all error
            finally:
                referrers = gc.get_referrers(obj)
                for _referrer in referrers:
                    if isinstance(_referrer, list):
                        for _i, val in enumerate(_referrer):
                            if val is obj:
                                _referrer[_i] = None
                    elif isinstance(_referrer, dict):
                        for key, value in _referrer.items():
                            if value is obj:
                                _referrer[key] = None
                del obj
    
        if _COUNT == 1:
            res = None
            try:
>               res = func(*args, **kwargs)
                      ^^^^^^^^^^^^^^^^^^^^^

/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/site-packages/pytest_embedded/plugin.py:504: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/site-packages/pytest_embedded/plugin.py:1141: in wokwi
    return wokwi_gn(**locals())
           ^^^^^^^^^^^^^^^^^^^^
/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/site-packages/pytest_embedded/dut_factory.py:502: in wokwi_gn
    return cls(**_drop_none_kwargs(kwargs))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/site-packages/pytest_embedded_wokwi/wokwi.py:84: in __init__
    raise e
/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/site-packages/wokwi_client/client_sync.py:113: in disconnect
    fut.result(timeout=2.0)
/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/concurrent/futures/_base.py:456: in result
    return self.__get_result()
           ^^^^^^^^^^^^^^^^^^^
/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/concurrent/futures/_base.py:401: in __get_result
    raise self._exception
/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/site-packages/wokwi_client/client.py:72: in disconnect
    await self._transport.close()
/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/site-packages/wokwi_client/transport.py:61: in close
    await self._recv_task
/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/site-packages/wokwi_client/transport.py:115: in _background_recv
    msg: IncomingMessage = await self._recv()
                           ^^^^^^^^^^^^^^^^^^
/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/site-packages/wokwi_client/transport.py:160: in _recv
    raw_message = await self._ws.recv()
                  ^^^^^^^^^^^^^^^^^^^^^
/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/site-packages/websockets/legacy/protocol.py:568: in recv
    await self.ensure_open()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <websockets.legacy.client.WebSocketClientProtocol object at 0x7f00889656a0>

    async def ensure_open(self) -> None:
        """
        Check that the WebSocket connection is open.
    
        Raise :exc:`~websockets.exceptions.ConnectionClosed` if it isn't.
    
        """
        # Handle cases from most common to least common for performance.
        if self.state is State.OPEN:
            # If self.transfer_data_task exited without a closing handshake,
            # self.close_connection_task may be closing the connection, going
            # straight from OPEN to CLOSED.
            if self.transfer_data_task.done():
                await asyncio.shield(self.close_connection_task)
                raise self.connection_closed_exc()
            else:
                return
    
        if self.state is State.CLOSED:
>           raise self.connection_closed_exc()
E           websockets.exceptions.ConnectionClosedError: no close frame received or sent

/opt/hostedtoolcache/Python/3.13.7/x64/lib/python3.13/site-packages/websockets/legacy/protocol.py:939: ConnectionClosedError

Check notice on line 0 in .github

See this annotation in the file changed.

@github-actions github-actions / Test Results

38 tests found

There are 38 tests, see "Raw output" for the full list of tests.
Raw output
auto_baudrate_test
basic_transmission_test
begin_when_running_test
change_baudrate_test
change_clock
change_cpu_frequency_test
change_pins_test
disabled_uart_calls_test
enabled_uart_calls_test
end_when_stopped_test
periman_test
psram_found
resize_buffers_test
rtc_run_clock
rtc_set_time
scan_bus
scan_bus_with_wifi
swap_pins
test_api
test_calloc_success
test_fail
test_malloc_fail
test_malloc_success
test_memcpy
test_memset_all_ones
test_memset_all_zeroes
test_memset_alternating
test_memset_random
test_pass
test_realloc_success
timer_clock_select_test
timer_divider_test
timer_interrupt_test
timer_read_test
validation.gpio.test_gpio ‑ test_gpio
validation.hello_world.test_hello_world ‑ test_hello_world
validation.nvs.test_nvs ‑ test_nvs
validation.wifi.test_wifi ‑ test_wifi