Skip to content

Commit bb0871e

Browse files
Kriechipgjones
authored andcommitted
1 parent 51113e7 commit bb0871e

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "test/http2-frame-test-case"]
2+
path = test/http2-frame-test-case
3+
url = https://github.com/http2jp/http2-frame-test-case.git

test/test_external_collection.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# https://github.com/http2jp/http2-frame-test-case
2+
3+
import os
4+
import json
5+
import pytest
6+
from hyperframe.frame import Frame
7+
8+
tc_filepaths = []
9+
root = os.path.dirname(__file__)
10+
path = os.walk(os.path.join(root, "http2-frame-test-case"))
11+
for dirpath, dirnames, filenames in path:
12+
for filename in filenames:
13+
if os.path.splitext(filename)[1] != ".json":
14+
continue
15+
tc_filepaths.append(
16+
os.path.relpath(os.path.join(dirpath, filename), root)
17+
)
18+
19+
20+
def check_valid_frame(tc, data): # noqa: C901
21+
new_frame, length = Frame.parse_frame_header(data[:9], strict=True)
22+
new_frame.parse_body(memoryview(data[9:9 + length]))
23+
24+
assert tc["frame"]["length"] == length
25+
assert tc["frame"]["stream_identifier"] == new_frame.stream_id
26+
assert tc["frame"]["type"] == new_frame.type
27+
28+
flags = 0
29+
for flag, flag_bit in new_frame.defined_flags:
30+
if flag in new_frame.flags:
31+
flags |= flag_bit
32+
assert tc["frame"]["flags"] == flags
33+
34+
p = tc["frame"]["frame_payload"]
35+
if "header_block_fragment" in p:
36+
assert p["header_block_fragment"] == new_frame.data.decode()
37+
if "data" in p:
38+
assert p["data"] == new_frame.data.decode()
39+
if "padding" in p:
40+
# the padding data itself is not retained by hyperframe after parsing
41+
pass
42+
if "padding_length" in p and p["padding_length"]:
43+
assert p["padding_length"] == new_frame.pad_length
44+
if "error_code" in p:
45+
assert p["error_code"] == new_frame.error_code
46+
if "additional_debug_data" in p:
47+
assert p["additional_debug_data"].encode() == new_frame.additional_data
48+
if "last_stream_id" in p:
49+
assert p["last_stream_id"] == new_frame.last_stream_id
50+
if "stream_dependency" in p:
51+
assert p["stream_dependency"] or 0 == new_frame.depends_on
52+
if "weight" in p and p["weight"]:
53+
assert p["weight"] - 1 == new_frame.stream_weight
54+
if "exclusive" in p:
55+
assert (p["exclusive"] or False) == new_frame.exclusive
56+
if "opaque_data" in p:
57+
assert p["opaque_data"].encode() == new_frame.opaque_data
58+
if "promised_stream_id" in p:
59+
assert p["promised_stream_id"] == new_frame.promised_stream_id
60+
if "settings" in p:
61+
assert dict(p["settings"]) == new_frame.settings
62+
if "window_size_increment" in p:
63+
assert p["window_size_increment"] == new_frame.window_increment
64+
65+
66+
class TestExternalCollection:
67+
@pytest.mark.parametrize('tc_filepath', tc_filepaths)
68+
def test(self, tc_filepath):
69+
with open(os.path.join(root, tc_filepath)) as f:
70+
tc = json.load(f)
71+
72+
data = bytes.fromhex(tc["wire"])
73+
74+
if tc["error"] is None and tc["frame"]:
75+
check_valid_frame(tc, data)
76+
elif tc["error"] and tc["frame"] is None:
77+
with pytest.raises(Exception):
78+
new_frame, length = Frame.parse_frame_header(
79+
data[:9],
80+
strict=True
81+
)
82+
new_frame.parse_body(memoryview(data[9:9 + length]))
83+
assert length == new_frame.body_len
84+
else:
85+
pytest.fail("unexpected test case: {} {}".format(tc_filepath, tc))

0 commit comments

Comments
 (0)