|
3 | 3 | from azure.eventhub._pyamqp.link import Link |
4 | 4 | from azure.eventhub._pyamqp.receiver import ReceiverLink |
5 | 5 | from azure.eventhub._pyamqp.constants import LinkState |
| 6 | +from azure.eventhub._pyamqp.link import Source, Target |
| 7 | +from unittest.mock import Mock, patch |
| 8 | +from azure.eventhub._pyamqp.constants import LINK_MAX_MESSAGE_SIZE |
6 | 9 | import pytest |
7 | 10 |
|
8 | 11 |
|
@@ -84,6 +87,80 @@ def test_receive_transfer_frame_multiple(): |
84 | 87 | link._incoming_transfer(transfer_frame_two) |
85 | 88 | assert link.current_link_credit == 1 |
86 | 89 |
|
| 90 | +def test_max_message_size_negotiation_with_client_unlimited(): |
| 91 | + """ |
| 92 | + Test AMQP attach frame negotiation where client sends max_message_size=0 ( unlimited ) |
| 93 | + and server responds with its limit (20MB), resulting in final size of 20MB. |
| 94 | + """ |
| 95 | + # Test constants to improve maintainability and reduce duplication |
| 96 | + TEST_LINK_NAME = "test_link" |
| 97 | + TEST_SOURCE_ADDRESS = "test_source" |
| 98 | + TEST_TARGET_ADDRESS = "test_target" |
| 99 | + TEST_HANDLE = 3 |
| 100 | + TEST_SND_SETTLE_MODE = 0 |
| 101 | + TEST_RCV_SETTLE_MODE = 1 |
| 102 | + SERVER_MAX_MESSAGE_SIZE = 20 * 1024 * 1024 |
| 103 | + |
| 104 | + mock_session = Mock() |
| 105 | + mock_connection = Mock() |
| 106 | + mock_session._connection = mock_connection |
| 107 | + |
| 108 | + link = Link( |
| 109 | + mock_session, |
| 110 | + TEST_HANDLE, |
| 111 | + name=TEST_LINK_NAME, |
| 112 | + role=False, # Sender role |
| 113 | + source_address=TEST_SOURCE_ADDRESS, |
| 114 | + target_address=TEST_TARGET_ADDRESS, |
| 115 | + network_trace=False, |
| 116 | + network_trace_params={}, |
| 117 | + max_message_size=LINK_MAX_MESSAGE_SIZE |
| 118 | + ) |
| 119 | + |
| 120 | + # Verifying that client sends 0 (unlimited) in attach frame |
| 121 | + assert link.max_message_size == 0, f"Expected client max_message_size=0, got {link.max_message_size}" |
| 122 | + |
| 123 | + # Simulating server's attach response with 20MB limit, Mock incoming attach frame from server |
| 124 | + mock_attach_frame = [ |
| 125 | + TEST_LINK_NAME, # 0: name |
| 126 | + TEST_HANDLE, # 1: handle |
| 127 | + False, # 2: role |
| 128 | + TEST_SND_SETTLE_MODE, # 3: snd-settle-mode |
| 129 | + TEST_RCV_SETTLE_MODE, # 4: rcv-settle-mode |
| 130 | + Source(address=TEST_SOURCE_ADDRESS), # 5: source |
| 131 | + Target(address=TEST_TARGET_ADDRESS), # 6: target |
| 132 | + None, # 7: unsettled |
| 133 | + False, # 8: incomplete-unsettled |
| 134 | + None, # 9: initial-delivery-count |
| 135 | + SERVER_MAX_MESSAGE_SIZE, # 10: max-message-size |
| 136 | + None, # 11: offered_capabilities |
| 137 | + None, # 12: desired_capabilities |
| 138 | + None, # 13: remote_properties |
| 139 | + ] |
| 140 | + |
| 141 | + # Testing _outgoing_attach() |
| 142 | + with patch.object(link, '_outgoing_attach') as mock_outgoing_attach: |
| 143 | + # Trigger outgoing attach |
| 144 | + link.attach() |
| 145 | + |
| 146 | + # Verifying _outgoing_attach was called |
| 147 | + assert mock_outgoing_attach.called, "_outgoing_attach should have been called during attach()" |
| 148 | + |
| 149 | + # Get the attach frame that would be sent to server |
| 150 | + call_args = mock_outgoing_attach.call_args |
| 151 | + if call_args and call_args[0]: |
| 152 | + attach_frame = call_args[0][0] |
| 153 | + assert attach_frame.max_message_size == 0, f"Expected client to send max_message_size=0, got {attach_frame.max_message_size}" |
| 154 | + |
| 155 | + # Testing _incoming_attach() |
| 156 | + with patch.object(link, '_outgoing_attach') as mock_outgoing_response: |
| 157 | + |
| 158 | + # Calling _incoming_attach to process server's response |
| 159 | + link._incoming_attach(mock_attach_frame) |
| 160 | + |
| 161 | + expected_final_size = SERVER_MAX_MESSAGE_SIZE |
| 162 | + # Verifying remote_max_message_size is set correctly |
| 163 | + assert link.remote_max_message_size == expected_final_size, f"Expected remote_max_message_size={expected_final_size}, got {link.remote_max_message_size}" |
87 | 164 |
|
88 | 165 | def test_receive_transfer_continuation_frame(): |
89 | 166 | session = None |
|
0 commit comments