I believe that a non-blocking UDP socket can raise a BlockingIOError on sendto. I would like to force this situation to test how my program behaves in this case.
sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
sock.setblocking(False)
sock.bind(('', 7777))
...
# Even if repeating in a loop, doesn't seem to raise a BlockingIOError
sock.sendto(b'abcde', ('1.2.3.4', 61908))
I have tried setting the outgoing buffer small by
buffer_size = 5
sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, buffer_size)
But it either seems to have no impact, or results in OSError: [Errno 40] Message too long
if the buffer is smaller than the data.
Is my belief wrong: can it never raise a BlockingIOError? Or if it can, how can I force it?
My aim here is to have an integration-style test: I want to actually have a real socket and make actual network calls. Mocking the socket for a unit-style test in this case would not be ideal.
The socket will only be used from a single-threaded Python asyncio program.
From TCP/IP Sockets in C: Practical Guide for Programmers, Michael J. Donahoo, Kenneth L. Calvert
For UDP sockets, there are no send buffers, so
send()
andsendto()
never returnEWOULDBLOCK
And from https://linux.die.net/man/2/sendto there is a hint as to why...
Packets are just silently dropped when a device queue overflows.
So in Python terms, BlockingIOError
cannot be raised, at least on Linux.