Skip to content

Commit 71054bf

Browse files
committed
Test related events.
1 parent 34bf0a8 commit 71054bf

File tree

1 file changed

+367
-0
lines changed

1 file changed

+367
-0
lines changed

test/test_related_events.py

+367
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,367 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
test_related_events.py
4+
~~~~~~~~~~~~~~~~~~~~~~
5+
6+
Specific tests to validate the "related events" logic used by certain events
7+
inside hyper-h2.
8+
"""
9+
import h2.connection
10+
import h2.events
11+
12+
13+
class TestRelatedEvents(object):
14+
"""
15+
Related events correlate all those events that happen on a single frame.
16+
"""
17+
example_request_headers = [
18+
(':authority', 'example.com'),
19+
(':path', '/'),
20+
(':scheme', 'https'),
21+
(':method', 'GET'),
22+
]
23+
24+
example_response_headers = [
25+
(':status', '200'),
26+
('server', 'fake-serv/0.1.0')
27+
]
28+
29+
informational_response_headers = [
30+
(':status', '100'),
31+
('server', 'fake-serv/0.1.0')
32+
]
33+
34+
example_trailers = [
35+
('another', 'field'),
36+
]
37+
38+
def test_request_received_related_all(self, frame_factory):
39+
"""
40+
RequestReceived has two possible related events: PriorityUpdated and
41+
StreamEnded, all fired when a single HEADERS frame is received.
42+
"""
43+
c = h2.connection.H2Connection(client_side=False)
44+
c.initiate_connection()
45+
c.receive_data(frame_factory.preamble())
46+
47+
input_frame = frame_factory.build_headers_frame(
48+
headers=self.example_request_headers,
49+
flags=['END_STREAM', 'PRIORITY'],
50+
stream_weight=15,
51+
depends_on=0,
52+
exclusive=False,
53+
)
54+
events = c.receive_data(input_frame.serialize())
55+
56+
assert len(events) == 3
57+
base_event = events[0]
58+
other_events = events[1:]
59+
60+
assert base_event.stream_ended in other_events
61+
assert isinstance(base_event.stream_ended, h2.events.StreamEnded)
62+
assert base_event.priority_updated in other_events
63+
assert isinstance(
64+
base_event.priority_updated, h2.events.PriorityUpdated
65+
)
66+
67+
def test_request_received_related_priority(self, frame_factory):
68+
"""
69+
RequestReceived can be related to PriorityUpdated.
70+
"""
71+
c = h2.connection.H2Connection(client_side=False)
72+
c.initiate_connection()
73+
c.receive_data(frame_factory.preamble())
74+
75+
input_frame = frame_factory.build_headers_frame(
76+
headers=self.example_request_headers,
77+
flags=['PRIORITY'],
78+
stream_weight=15,
79+
depends_on=0,
80+
exclusive=False,
81+
)
82+
events = c.receive_data(input_frame.serialize())
83+
84+
assert len(events) == 2
85+
base_event = events[0]
86+
priority_updated_event = events[1]
87+
88+
assert base_event.priority_updated is priority_updated_event
89+
assert base_event.stream_ended is None
90+
assert isinstance(
91+
base_event.priority_updated, h2.events.PriorityUpdated
92+
)
93+
94+
def test_request_received_related_stream_ended(self, frame_factory):
95+
"""
96+
RequestReceived can be related to StreamEnded.
97+
"""
98+
c = h2.connection.H2Connection(client_side=False)
99+
c.initiate_connection()
100+
c.receive_data(frame_factory.preamble())
101+
102+
input_frame = frame_factory.build_headers_frame(
103+
headers=self.example_request_headers,
104+
flags=['END_STREAM'],
105+
)
106+
events = c.receive_data(input_frame.serialize())
107+
108+
assert len(events) == 2
109+
base_event = events[0]
110+
stream_ended_event = events[1]
111+
112+
assert base_event.stream_ended is stream_ended_event
113+
assert base_event.priority_updated is None
114+
assert isinstance(base_event.stream_ended, h2.events.StreamEnded)
115+
116+
def test_response_received_related_nothing(self, frame_factory):
117+
"""
118+
ResponseReceived is ordinarily related to no events.
119+
"""
120+
c = h2.connection.H2Connection()
121+
c.initiate_connection()
122+
c.send_headers(stream_id=1, headers=self.example_request_headers)
123+
124+
input_frame = frame_factory.build_headers_frame(
125+
headers=self.example_response_headers,
126+
)
127+
events = c.receive_data(input_frame.serialize())
128+
129+
assert len(events) == 1
130+
base_event = events[0]
131+
132+
assert base_event.stream_ended is None
133+
assert base_event.priority_updated is None
134+
135+
def test_response_received_related_all(self, frame_factory):
136+
"""
137+
ResponseReceived has two possible related events: PriorityUpdated and
138+
StreamEnded, all fired when a single HEADERS frame is received.
139+
"""
140+
c = h2.connection.H2Connection()
141+
c.initiate_connection()
142+
c.send_headers(stream_id=1, headers=self.example_request_headers)
143+
144+
input_frame = frame_factory.build_headers_frame(
145+
headers=self.example_response_headers,
146+
flags=['END_STREAM', 'PRIORITY'],
147+
stream_weight=15,
148+
depends_on=0,
149+
exclusive=False,
150+
)
151+
events = c.receive_data(input_frame.serialize())
152+
153+
assert len(events) == 3
154+
base_event = events[0]
155+
other_events = events[1:]
156+
157+
assert base_event.stream_ended in other_events
158+
assert isinstance(base_event.stream_ended, h2.events.StreamEnded)
159+
assert base_event.priority_updated in other_events
160+
assert isinstance(
161+
base_event.priority_updated, h2.events.PriorityUpdated
162+
)
163+
164+
def test_response_received_related_priority(self, frame_factory):
165+
"""
166+
ResponseReceived can be related to PriorityUpdated.
167+
"""
168+
c = h2.connection.H2Connection()
169+
c.initiate_connection()
170+
c.send_headers(stream_id=1, headers=self.example_request_headers)
171+
172+
input_frame = frame_factory.build_headers_frame(
173+
headers=self.example_response_headers,
174+
flags=['PRIORITY'],
175+
stream_weight=15,
176+
depends_on=0,
177+
exclusive=False,
178+
)
179+
events = c.receive_data(input_frame.serialize())
180+
181+
assert len(events) == 2
182+
base_event = events[0]
183+
priority_updated_event = events[1]
184+
185+
assert base_event.priority_updated is priority_updated_event
186+
assert base_event.stream_ended is None
187+
assert isinstance(
188+
base_event.priority_updated, h2.events.PriorityUpdated
189+
)
190+
191+
def test_response_received_related_stream_ended(self, frame_factory):
192+
"""
193+
ResponseReceived can be related to StreamEnded.
194+
"""
195+
c = h2.connection.H2Connection()
196+
c.initiate_connection()
197+
c.send_headers(stream_id=1, headers=self.example_request_headers)
198+
199+
input_frame = frame_factory.build_headers_frame(
200+
headers=self.example_response_headers,
201+
flags=['END_STREAM'],
202+
)
203+
events = c.receive_data(input_frame.serialize())
204+
205+
assert len(events) == 2
206+
base_event = events[0]
207+
stream_ended_event = events[1]
208+
209+
assert base_event.stream_ended is stream_ended_event
210+
assert base_event.priority_updated is None
211+
assert isinstance(base_event.stream_ended, h2.events.StreamEnded)
212+
213+
def test_trailers_received_related_all(self, frame_factory):
214+
"""
215+
TrailersReceived has two possible related events: PriorityUpdated and
216+
StreamEnded, all fired when a single HEADERS frame is received.
217+
"""
218+
c = h2.connection.H2Connection()
219+
c.initiate_connection()
220+
c.send_headers(stream_id=1, headers=self.example_request_headers)
221+
222+
f = frame_factory.build_headers_frame(
223+
headers=self.example_response_headers,
224+
)
225+
c.receive_data(f.serialize())
226+
227+
input_frame = frame_factory.build_headers_frame(
228+
headers=self.example_trailers,
229+
flags=['END_STREAM', 'PRIORITY'],
230+
stream_weight=15,
231+
depends_on=0,
232+
exclusive=False,
233+
)
234+
events = c.receive_data(input_frame.serialize())
235+
236+
assert len(events) == 3
237+
base_event = events[0]
238+
other_events = events[1:]
239+
240+
assert base_event.stream_ended in other_events
241+
assert isinstance(base_event.stream_ended, h2.events.StreamEnded)
242+
assert base_event.priority_updated in other_events
243+
assert isinstance(
244+
base_event.priority_updated, h2.events.PriorityUpdated
245+
)
246+
247+
def test_trailers_received_related_stream_ended(self, frame_factory):
248+
"""
249+
TrailersReceived can be related to StreamEnded by itself.
250+
"""
251+
c = h2.connection.H2Connection()
252+
c.initiate_connection()
253+
c.send_headers(stream_id=1, headers=self.example_request_headers)
254+
255+
f = frame_factory.build_headers_frame(
256+
headers=self.example_response_headers,
257+
)
258+
c.receive_data(f.serialize())
259+
260+
input_frame = frame_factory.build_headers_frame(
261+
headers=self.example_trailers,
262+
flags=['END_STREAM'],
263+
)
264+
events = c.receive_data(input_frame.serialize())
265+
266+
assert len(events) == 2
267+
base_event = events[0]
268+
stream_ended_event = events[1]
269+
270+
assert base_event.stream_ended is stream_ended_event
271+
assert base_event.priority_updated is None
272+
assert isinstance(base_event.stream_ended, h2.events.StreamEnded)
273+
274+
def test_informational_response_related_nothing(self, frame_factory):
275+
"""
276+
InformationalResponseReceived in the standard case is related to
277+
nothing.
278+
"""
279+
c = h2.connection.H2Connection()
280+
c.initiate_connection()
281+
c.send_headers(stream_id=1, headers=self.example_request_headers)
282+
283+
input_frame = frame_factory.build_headers_frame(
284+
headers=self.informational_response_headers,
285+
)
286+
events = c.receive_data(input_frame.serialize())
287+
288+
assert len(events) == 1
289+
base_event = events[0]
290+
291+
assert base_event.priority_updated is None
292+
293+
def test_informational_response_received_related_all(self, frame_factory):
294+
"""
295+
InformationalResponseReceived has one possible related event:
296+
PriorityUpdated, fired when a single HEADERS frame is received.
297+
"""
298+
c = h2.connection.H2Connection()
299+
c.initiate_connection()
300+
c.send_headers(stream_id=1, headers=self.example_request_headers)
301+
302+
input_frame = frame_factory.build_headers_frame(
303+
headers=self.informational_response_headers,
304+
flags=['PRIORITY'],
305+
stream_weight=15,
306+
depends_on=0,
307+
exclusive=False,
308+
)
309+
events = c.receive_data(input_frame.serialize())
310+
311+
assert len(events) == 2
312+
base_event = events[0]
313+
priority_updated_event = events[1]
314+
315+
assert base_event.priority_updated is priority_updated_event
316+
assert isinstance(
317+
base_event.priority_updated, h2.events.PriorityUpdated
318+
)
319+
320+
def test_data_received_normally_relates_to_nothing(self, frame_factory):
321+
"""
322+
A plain DATA frame leads to DataReceieved with no related events.
323+
"""
324+
c = h2.connection.H2Connection()
325+
c.initiate_connection()
326+
c.send_headers(stream_id=1, headers=self.example_request_headers)
327+
328+
f = frame_factory.build_headers_frame(
329+
headers=self.example_response_headers,
330+
)
331+
c.receive_data(f.serialize())
332+
333+
input_frame = frame_factory.build_data_frame(
334+
data=b'some data',
335+
)
336+
events = c.receive_data(input_frame.serialize())
337+
338+
assert len(events) == 1
339+
base_event = events[0]
340+
341+
assert base_event.stream_ended is None
342+
343+
def test_data_received_related_stream_ended(self, frame_factory):
344+
"""
345+
DataReceived can be related to StreamEnded by itself.
346+
"""
347+
c = h2.connection.H2Connection()
348+
c.initiate_connection()
349+
c.send_headers(stream_id=1, headers=self.example_request_headers)
350+
351+
f = frame_factory.build_headers_frame(
352+
headers=self.example_response_headers,
353+
)
354+
c.receive_data(f.serialize())
355+
356+
input_frame = frame_factory.build_data_frame(
357+
data=b'some data',
358+
flags=['END_STREAM'],
359+
)
360+
events = c.receive_data(input_frame.serialize())
361+
362+
assert len(events) == 2
363+
base_event = events[0]
364+
stream_ended_event = events[1]
365+
366+
assert base_event.stream_ended is stream_ended_event
367+
assert isinstance(base_event.stream_ended, h2.events.StreamEnded)

0 commit comments

Comments
 (0)