4@brief Unit tests for the quic module.
12from unittest.mock
import Mock, patch, MagicMock
15sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__),
'..')))
17from quic
import QuicConnection
18from stream
import Stream
19from frame
import FrameStream
20from packet
import Packet
21from constants
import Constants
26 @brief Test cases for the QuicConnection class.
30 with patch(
'socket.socket'):
37 """Test initialization of QuicConnection"""
44 self.assertEqual(self.
quic_connection._sent_packets_counter, Constants.ZERO)
45 self.assertEqual(self.
quic_connection._received_packets_counter, Constants.ZERO)
50 """Test getting a new stream"""
51 initiated_by = Constants.CONNECTION_ID_SENDER
52 direction = Constants.BIDI
54 mock_stream_instance = Mock()
57 with patch.object(self.
quic_connection,
'_stream_id_generator', return_value=stream_id):
59 with patch.object(self.
quic_connection,
'_get_stream_by_id', return_value=mock_stream_instance):
64 self.assertEqual(result, mock_stream_instance)
68 """Test adding a stream"""
69 mock_stream_instance = Mock()
70 mock_stream.return_value = mock_stream_instance
76 with patch(
'quic.QuicConnection._add_stream_to_stats_dict')
as mock_add_stats:
83 mock_add_stats.assert_called_once_with(stream_id)
89 """Test stream ID generation"""
92 stream_id = self.
quic_connection._stream_id_generator(Constants.CONNECTION_ID_SENDER, Constants.BIDI)
93 self.assertEqual(stream_id, 4)
97 stream_id = self.
quic_connection._stream_id_generator(Constants.CONNECTION_ID_SENDER, Constants.UNIDI)
98 self.assertEqual(stream_id, 10)
102 stream_id = self.
quic_connection._stream_id_generator(Constants.CONNECTION_ID_RECEIVER, Constants.BIDI)
103 self.assertEqual(stream_id, 13)
106 """Test adding a stream to the stats dictionary"""
109 with patch(
'time.time', return_value=12345):
113 self.assertEqual(self.
quic_connection._stats_dict[stream_id][
'total_bytes'], Constants.ZERO)
114 self.assertEqual(self.
quic_connection._stats_dict[stream_id][
'total_time'], 12345)
115 self.assertEqual(self.
quic_connection._stats_dict[stream_id][
'total_packets'], set())
117 @patch('quic.Stream')
119 """Test getting an existing stream by ID"""
121 mock_stream_instance = Mock()
125 self.assertEqual(result, mock_stream_instance)
128 """Test getting a new stream by ID"""
130 mock_stream_instance = Mock()
133 with patch(
'quic.QuicConnection._is_stream_id_in_dict', return_value=
False):
135 def mock_add_stream(sid, init, dir):
138 with patch(
'quic.Stream.is_s_init_by_sid', return_value=
True):
139 with patch(
'quic.Stream.is_uni_by_sid', return_value=
False):
140 with patch(
'quic.QuicConnection._add_stream', side_effect=mock_add_stream)
as mock_add:
143 self.assertEqual(result, mock_stream_instance)
144 mock_add.assert_called_once_with(stream_id,
True,
False)
147 """Test removing a stream"""
155 self.assertEqual(result, mock_stream)
159 @patch('builtins.open', new_callable=unittest.mock.mock_open, read_data=b'Test file data')
161 """Test adding a file to a stream"""
163 path =
"test_file.txt"
165 with patch(
'quic.QuicConnection._add_data_to_stream')
as mock_add_data:
168 mock_open.assert_called_once_with(path,
'rb')
169 mock_add_data.assert_called_once_with(stream_id, b
'Test file data')
172 """Test adding data to a stream"""
177 with patch(
'quic.QuicConnection._get_stream_by_id', return_value=mock_stream)
as mock_get:
178 with patch(
'quic.QuicConnection._add_active_stream_id')
as mock_add_active:
181 mock_get.assert_called_once_with(stream_id)
182 mock_stream.add_data_to_stream.assert_called_once_with(data=data)
183 mock_add_active.assert_called_once_with(stream_id)
186 """Test adding an active stream ID"""
196 self.assertEqual(len(self.
quic_connection._active_streams_ids), initial_length)
199 """Test checking if a stream ID is in the dictionary"""
203 self.assertFalse(self.
quic_connection._is_stream_id_in_dict(stream_id))
209 @patch('time.time', return_value=12345)
211 """Test setting the start time for all streams"""
213 1: {
'total_time': 0},
220 self.assertEqual(stream[
'total_time'], 12345)
222 @patch('quic.QuicConnection._send_packet_size')
223 @patch('quic.QuicConnection._create_packet')
224 @patch('quic.QuicConnection._send_packet')
225 @patch('quic.QuicConnection._close_connection')
227 """Test sending packets"""
229 mock_create.return_value = mock_packet
230 mock_packet.pack.return_value = b
'packed packet'
235 def side_effect(*args, **kwargs):
239 mock_send.side_effect = side_effect
241 with patch(
'time.time', return_value=12345):
244 mock_send_size.assert_called_once()
245 mock_create.assert_called_once()
246 mock_send.assert_called_once_with(b
'packed packet')
247 mock_close.assert_called_once()
250 """Test sending the packet size"""
251 with patch(
'quic.PACKET_SIZE', 1500):
252 with patch(
'quic.QuicConnection._send_packet', return_value=
True)
as mock_send:
256 mock_send.assert_called_once_with((1500).to_bytes(Constants.PACKET_SIZE_BYTES,
'big'))
257 self.assertTrue(result)
259 @patch('sys.getsizeof', side_effect=lambda x: 10 if isinstance(x, Packet) else 5)
261 """Test creating a packet"""
264 with patch(
'quic.Packet')
as mock_packet_class:
266 mock_packet_class.return_value = mock_packet
268 with patch(
'quic.QuicConnection._generate_streams_frames'):
269 with patch(
'quic.QuicConnection._get_stream_from_active_streams', return_value=
None):
272 expected_dest_conn_id = 1
273 mock_packet_class.assert_called_once_with(expected_dest_conn_id, Constants.ZERO)
277 """Test generating frames for all active streams"""
278 stream_id1, stream_id2 = 38, 43
281 mock_stream1, mock_stream2 = Mock(), Mock()
283 with patch(
'quic.PACKET_SIZE', 1500):
284 with patch(
'quic.QuicConnection._get_stream_by_id', side_effect=[mock_stream1, mock_stream2])
as mock_get:
287 self.assertEqual(mock_get.call_count, 2)
288 mock_stream1.generate_stream_frames.assert_called_once_with(1500 // Constants.FRAMES_IN_PACKET)
289 mock_stream2.generate_stream_frames.assert_called_once_with(1500 // Constants.FRAMES_IN_PACKET)
292 """Test getting a stream from active streams when empty"""
297 self.assertIsNone(result)
300 @patch('random.choice', return_value=38)
302 """Test getting a stream from active streams"""
310 self.assertEqual(result, mock_stream)
313 """Test sending a packet"""
314 packet = b
'test packet'
321 self.assertTrue(result)
323 @patch('quic.QuicConnection._receive_packet')
325 """Test receiving packets"""
329 def side_effect(*args, **kwargs):
332 mock_receive.side_effect = side_effect
336 self.
quic_connection._socket.settimeout.assert_called_once_with(Constants.TIMEOUT)
337 mock_receive.assert_called_once()
339 @patch('quic.QuicConnection._handle_received_packet_size')
341 """Test receiving a packet size"""
342 packet = b
'size packet'
343 addr = (
'127.0.0.1', 1234)
347 with patch(
'time.time', return_value=12345):
348 with patch(
'quic.QuicConnection._increment_received_packets_counter')
as mock_increment:
351 mock_handle.assert_called_once_with(packet)
352 mock_increment.assert_called_once()
354 @patch('quic.QuicConnection._handle_received_packet')
356 """Test receiving a data packet"""
358 packet = b
'data packet'
359 addr = (
'127.0.0.1', 1234)
363 with patch(
'quic.QuicConnection._increment_received_packets_counter')
as mock_increment:
366 mock_handle.assert_called_once_with(packet)
367 self.assertTrue(mock_increment.called)
370 """Test incrementing the received packets counter"""
371 initial = self.quic_connection._received_packets_counter
373 self.quic_connection._increment_received_packets_counter()
375 self.assertEqual(self.quic_connection._received_packets_counter, initial + 1)
377 def test_handle_received_packet_size(self):
378 """Test handling a received packet size"""
379 packet_size = (1500).to_bytes(Constants.PACKET_SIZE_BYTES, 'big')
381 with patch('builtins.print') as mock_print:
382 self.quic_connection._handle_received_packet_size(packet_size)
384 mock_print.assert_called_once()
385 self.assertEqual(self.quic_connection._packet_size, 1500)
388if __name__ == '__main__':
test_initialization(self)
test_generate_streams_frames(self)
test_add_data_to_stream(self)
test_receive_packets(self, mock_receive)
test_send_packet_size(self)
test_add_active_stream_id(self)
test_get_stream_new(self)
test_receive_packet_size(self, mock_handle)
test_get_stream_by_id_new(self)
test_get_stream_from_active_streams_empty(self)
test_stream_id_generator(self)
test_set_start_time(self, mock_time)
test_receive_packet_data(self, mock_handle)
test_get_stream_by_id_existing(self, mock_stream)
test_get_stream_from_active_streams(self, mock_choice)
test_send_packets(self, mock_close, mock_send, mock_create, mock_send_size)
test_is_stream_id_in_dict(self)
test_create_packet(self, mock_getsizeof)
test_increment_received_packets_counter(self)
test_add_file_to_stream(self, mock_open)
test_add_stream(self, mock_stream)
test_add_stream_to_stats_dict(self)