S1005403_RisCC/tests/utils/test_network.py

121 lines
3.2 KiB
Python

import socket
import types
import pytest
from target_simulator.utils import network
class DummySocket:
def __init__(self, fail_on_bind=False, rcvbuf=4096):
self._closed = False
self._fail_on_bind = fail_on_bind
self._rcvbuf = rcvbuf
self._timeout = None
def getsockopt(self, level, optname):
return self._rcvbuf
def setsockopt(self, level, optname, value):
# Simulate refusal if value is absurd (for edge test)
if value > 10 * 1024 * 1024:
raise OSError("too large")
def bind(self, addr):
if self._fail_on_bind:
raise socket.error("bind failed")
def recvfrom(self, bufsize):
if self._timeout:
raise socket.timeout()
return b"data", ("127.0.0.1", 1234)
def fileno(self):
return -1 if self._closed else 3
def close(self):
if self._closed:
raise socket.error("already closed")
self._closed = True
def test_create_udp_socket_success(monkeypatch):
dummy = DummySocket()
def fake_socket(family, type_):
return dummy
monkeypatch.setattr(network.socket, "socket", fake_socket)
s = network.create_udp_socket("127.0.0.1", 0)
# Should return our dummy socket object
assert s is dummy
def test_create_udp_socket_bind_failure(monkeypatch):
dummy = DummySocket(fail_on_bind=True)
def fake_socket(family, type_):
return dummy
monkeypatch.setattr(network.socket, "socket", fake_socket)
s = network.create_udp_socket("127.0.0.1", 0)
# On bind failure implementation returns None
assert s is None
def test_create_udp_socket_buf_set_failure(monkeypatch):
# Simulate setsockopt raising OSError when trying to set very large buffer
dummy = DummySocket()
def fake_socket(family, type_):
return dummy
# Also patch dummy.setsockopt to raise
def bad_setsockopt(level, optname, value):
raise OSError("no permission")
dummy.setsockopt = bad_setsockopt
monkeypatch.setattr(network.socket, "socket", fake_socket)
# Should still return the socket even if buffer set fails
s = network.create_udp_socket("127.0.0.1", 0)
assert s is dummy
def test_receive_udp_packet_success_and_timeout(monkeypatch):
dummy = DummySocket()
# Normal receive
data, addr = network.receive_udp_packet(dummy)
assert data == b"data"
assert addr == ("127.0.0.1", 1234)
# Simulate timeout
dummy._timeout = True
data, addr = network.receive_udp_packet(dummy)
assert data is None and addr is None
def test_receive_udp_packet_error(monkeypatch):
class ErrSock(DummySocket):
def recvfrom(self, bufsize):
raise socket.error("recv failed")
err = ErrSock()
data, addr = network.receive_udp_packet(err)
assert data is None and addr is None
def test_close_udp_socket_open_and_closed(monkeypatch):
dummy = DummySocket()
# Open socket: fileno != -1 -> will call close
dummy._closed = False
network.close_udp_socket(dummy)
assert dummy._closed is True
# Now calling close on an already-closed socket should hit the debug branch
# and not raise
network.close_udp_socket(dummy) # should be no-op and not raise