|
| 1 | +from __future__ import annotations |
| 2 | + |
| 3 | +from tigrcorn.config.model import WebSocketConfig, WebTransportConfig |
| 4 | +from tigrcorn.sessions.limits import SessionLimits |
| 5 | +from tigrcorn_protocols.client_session_coverage import ( |
| 6 | + ClientTopology, |
| 7 | + CoverageDisposition, |
| 8 | + ProtocolCarrier, |
| 9 | + build_matrix_row, |
| 10 | +) |
| 11 | + |
| 12 | + |
| 13 | +def test_session_limits_bound_concurrent_stream_pressure() -> None: |
| 14 | + limits = SessionLimits(max_streams=2) |
| 15 | + |
| 16 | + assert limits.allow_stream(0) is True |
| 17 | + assert limits.allow_stream(1) is True |
| 18 | + assert limits.allow_stream(2) is False |
| 19 | + |
| 20 | + row = build_matrix_row( |
| 21 | + protocol_carrier=ProtocolCarrier.HTTP2, |
| 22 | + client_topology=ClientTopology.CONCURRENT_CLIENTS, |
| 23 | + disposition=CoverageDisposition.FAIL_CLOSED, |
| 24 | + lifecycle_behavior=CoverageDisposition.COVERED, |
| 25 | + identity_isolation=CoverageDisposition.COVERED, |
| 26 | + ordering_behavior=CoverageDisposition.COVERED, |
| 27 | + pressure_mode=CoverageDisposition.COVERED, |
| 28 | + fault_mode=CoverageDisposition.REQUIRED, |
| 29 | + client_id="client-a", |
| 30 | + connection_id="h2-conn", |
| 31 | + stream_id=3, |
| 32 | + error_kind="max_streams_exceeded", |
| 33 | + ) |
| 34 | + assert row["pressure_mode"] == "covered" |
| 35 | + assert row["error_kind"] == "max_streams_exceeded" |
| 36 | + |
| 37 | + |
| 38 | +def test_websocket_queue_and_message_pressure_have_configured_bounds() -> None: |
| 39 | + config = WebSocketConfig(max_message_size=4, max_queue=2) |
| 40 | + accepted = [b"one", b"two"] |
| 41 | + rejected_payload = b"three" |
| 42 | + |
| 43 | + assert len(accepted) == config.max_queue |
| 44 | + assert len(rejected_payload) > config.max_message_size |
| 45 | + |
| 46 | + row = build_matrix_row( |
| 47 | + protocol_carrier=ProtocolCarrier.WEBSOCKET_H1, |
| 48 | + client_topology=ClientTopology.CONCURRENT_CLIENTS, |
| 49 | + disposition=CoverageDisposition.FAIL_CLOSED, |
| 50 | + lifecycle_behavior=CoverageDisposition.COVERED, |
| 51 | + identity_isolation=CoverageDisposition.COVERED, |
| 52 | + ordering_behavior=CoverageDisposition.COVERED, |
| 53 | + pressure_mode=CoverageDisposition.COVERED, |
| 54 | + fault_mode=CoverageDisposition.COVERED, |
| 55 | + client_id="client-a", |
| 56 | + connection_id="ws-conn", |
| 57 | + error_kind="websocket_pressure_budget_exceeded", |
| 58 | + ) |
| 59 | + assert row["session_scope"] == "websocket_connection_scoped" |
| 60 | + |
| 61 | + |
| 62 | +def test_webtransport_session_stream_and_datagram_pressure_are_bounded() -> None: |
| 63 | + config = WebTransportConfig(max_sessions=1, max_streams=1, max_datagram_size=4) |
| 64 | + |
| 65 | + assert config.max_sessions == 1 |
| 66 | + assert config.max_streams == 1 |
| 67 | + assert len(b"toolong") > config.max_datagram_size |
| 68 | + |
| 69 | + row = build_matrix_row( |
| 70 | + protocol_carrier=ProtocolCarrier.WEBTRANSPORT_H3_QUIC, |
| 71 | + client_topology=ClientTopology.CONCURRENT_CLIENTS, |
| 72 | + disposition=CoverageDisposition.FAIL_CLOSED, |
| 73 | + lifecycle_behavior=CoverageDisposition.COVERED, |
| 74 | + identity_isolation=CoverageDisposition.COVERED, |
| 75 | + ordering_behavior=CoverageDisposition.COVERED, |
| 76 | + pressure_mode=CoverageDisposition.COVERED, |
| 77 | + fault_mode=CoverageDisposition.COVERED, |
| 78 | + client_id="client-a", |
| 79 | + connection_id="wt-conn", |
| 80 | + session_id="wt-session", |
| 81 | + datagram_id="d-too-large", |
| 82 | + error_kind="webtransport_pressure_budget_exceeded", |
| 83 | + ) |
| 84 | + assert row["datagram_id"] == "d-too-large" |
0 commit comments