Skip to content

Commit 125b9a2

Browse files
committed
Test related events.
1 parent 34bf0a8 commit 125b9a2

File tree

1 file changed

+391
-0
lines changed

1 file changed

+391
-0
lines changed

test/test_related_events.py

+391
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,391 @@
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_nothing(self, frame_factory):
214+
"""
215+
TrailersReceived is normally related to no events.
216+
"""
217+
c = h2.connection.H2Connection()
218+
c.initiate_connection()
219+
c.send_headers(stream_id=1, headers=self.example_request_headers)
220+
221+
f = frame_factory.build_headers_frame(
222+
headers=self.example_response_headers,
223+
)
224+
c.receive_data(f.serialize())
225+
226+
input_frame = frame_factory.build_headers_frame(
227+
headers=self.example_trailers,
228+
)
229+
events = c.receive_data(input_frame.serialize())
230+
231+
assert len(events) == 1
232+
base_event = events[0]
233+
234+
assert base_event.stream_ended is None
235+
assert base_event.priority_updated is None
236+
237+
def test_trailers_received_related_all(self, frame_factory):
238+
"""
239+
TrailersReceived has two possible related events: PriorityUpdated and
240+
StreamEnded, all fired when a single HEADERS frame is received.
241+
"""
242+
c = h2.connection.H2Connection()
243+
c.initiate_connection()
244+
c.send_headers(stream_id=1, headers=self.example_request_headers)
245+
246+
f = frame_factory.build_headers_frame(
247+
headers=self.example_response_headers,
248+
)
249+
c.receive_data(f.serialize())
250+
251+
input_frame = frame_factory.build_headers_frame(
252+
headers=self.example_trailers,
253+
flags=['END_STREAM', 'PRIORITY'],
254+
stream_weight=15,
255+
depends_on=0,
256+
exclusive=False,
257+
)
258+
events = c.receive_data(input_frame.serialize())
259+
260+
assert len(events) == 3
261+
base_event = events[0]
262+
other_events = events[1:]
263+
264+
assert base_event.stream_ended in other_events
265+
assert isinstance(base_event.stream_ended, h2.events.StreamEnded)
266+
assert base_event.priority_updated in other_events
267+
assert isinstance(
268+
base_event.priority_updated, h2.events.PriorityUpdated
269+
)
270+
271+
def test_trailers_received_related_stream_ended(self, frame_factory):
272+
"""
273+
TrailersReceived can be related to StreamEnded by itself.
274+
"""
275+
c = h2.connection.H2Connection()
276+
c.initiate_connection()
277+
c.send_headers(stream_id=1, headers=self.example_request_headers)
278+
279+
f = frame_factory.build_headers_frame(
280+
headers=self.example_response_headers,
281+
)
282+
c.receive_data(f.serialize())
283+
284+
input_frame = frame_factory.build_headers_frame(
285+
headers=self.example_trailers,
286+
flags=['END_STREAM'],
287+
)
288+
events = c.receive_data(input_frame.serialize())
289+
290+
assert len(events) == 2
291+
base_event = events[0]
292+
stream_ended_event = events[1]
293+
294+
assert base_event.stream_ended is stream_ended_event
295+
assert base_event.priority_updated is None
296+
assert isinstance(base_event.stream_ended, h2.events.StreamEnded)
297+
298+
def test_informational_response_related_nothing(self, frame_factory):
299+
"""
300+
InformationalResponseReceived in the standard case is related to
301+
nothing.
302+
"""
303+
c = h2.connection.H2Connection()
304+
c.initiate_connection()
305+
c.send_headers(stream_id=1, headers=self.example_request_headers)
306+
307+
input_frame = frame_factory.build_headers_frame(
308+
headers=self.informational_response_headers,
309+
)
310+
events = c.receive_data(input_frame.serialize())
311+
312+
assert len(events) == 1
313+
base_event = events[0]
314+
315+
assert base_event.priority_updated is None
316+
317+
def test_informational_response_received_related_all(self, frame_factory):
318+
"""
319+
InformationalResponseReceived has one possible related event:
320+
PriorityUpdated, fired when a single HEADERS frame is received.
321+
"""
322+
c = h2.connection.H2Connection()
323+
c.initiate_connection()
324+
c.send_headers(stream_id=1, headers=self.example_request_headers)
325+
326+
input_frame = frame_factory.build_headers_frame(
327+
headers=self.informational_response_headers,
328+
flags=['PRIORITY'],
329+
stream_weight=15,
330+
depends_on=0,
331+
exclusive=False,
332+
)
333+
events = c.receive_data(input_frame.serialize())
334+
335+
assert len(events) == 2
336+
base_event = events[0]
337+
priority_updated_event = events[1]
338+
339+
assert base_event.priority_updated is priority_updated_event
340+
assert isinstance(
341+
base_event.priority_updated, h2.events.PriorityUpdated
342+
)
343+
344+
def test_data_received_normally_relates_to_nothing(self, frame_factory):
345+
"""
346+
A plain DATA frame leads to DataReceieved with no related events.
347+
"""
348+
c = h2.connection.H2Connection()
349+
c.initiate_connection()
350+
c.send_headers(stream_id=1, headers=self.example_request_headers)
351+
352+
f = frame_factory.build_headers_frame(
353+
headers=self.example_response_headers,
354+
)
355+
c.receive_data(f.serialize())
356+
357+
input_frame = frame_factory.build_data_frame(
358+
data=b'some data',
359+
)
360+
events = c.receive_data(input_frame.serialize())
361+
362+
assert len(events) == 1
363+
base_event = events[0]
364+
365+
assert base_event.stream_ended is None
366+
367+
def test_data_received_related_stream_ended(self, frame_factory):
368+
"""
369+
DataReceived can be related to StreamEnded by itself.
370+
"""
371+
c = h2.connection.H2Connection()
372+
c.initiate_connection()
373+
c.send_headers(stream_id=1, headers=self.example_request_headers)
374+
375+
f = frame_factory.build_headers_frame(
376+
headers=self.example_response_headers,
377+
)
378+
c.receive_data(f.serialize())
379+
380+
input_frame = frame_factory.build_data_frame(
381+
data=b'some data',
382+
flags=['END_STREAM'],
383+
)
384+
events = c.receive_data(input_frame.serialize())
385+
386+
assert len(events) == 2
387+
base_event = events[0]
388+
stream_ended_event = events[1]
389+
390+
assert base_event.stream_ended is stream_ended_event
391+
assert isinstance(base_event.stream_ended, h2.events.StreamEnded)

0 commit comments

Comments
 (0)