-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Expand file tree
/
Copy pathtest_new_api_versions.py
More file actions
144 lines (114 loc) · 14.4 KB
/
test_new_api_versions.py
File metadata and controls
144 lines (114 loc) · 14.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import io
import pytest
from kafka.protocol.new.api_header import ResponseHeader
from kafka.protocol.new.metadata import ApiVersionsRequest, ApiVersionsResponse
TEST_CASES = [
(
ApiVersionsRequest[0](),
b'\x00\x00\x00\x1f\x00\x12\x00\x00\x00\x00\x00\x01\x00\x15_internal_client_kYVL',
),
(
ApiVersionsRequest[1](),
b'\x00\x00\x00\x1f\x00\x12\x00\x01\x00\x00\x00\x01\x00\x15_internal_client_kYVL',
),
(
ApiVersionsRequest[2](),
b'\x00\x00\x00\x1f\x00\x12\x00\x02\x00\x00\x00\x01\x00\x15_internal_client_kYVL',
),
(
ApiVersionsRequest[3](client_software_name='kafka-python', client_software_version='3.0.0'),
b'\x00\x00\x004\x00\x12\x00\x03\x00\x00\x00\x01\x00\x15_internal_client_kYVL\x00\rkafka-python\x063.0.0\x00',
),
(
ApiVersionsRequest[4](client_software_name='kafka-python', client_software_version='3.0.0'),
b'\x00\x00\x004\x00\x12\x00\x04\x00\x00\x00\x01\x00\x15_internal_client_kYVL\x00\rkafka-python\x063.0.0\x00',
),
(
ApiVersionsResponse[0](error_code=35, api_keys=[(18, 0, 3)]),
b'\x00\x00\x00\x10\x00\x00\x00\x01\x00#\x00\x00\x00\x01\x00\x12\x00\x00\x00\x03',
),
(
ApiVersionsResponse[0](error_code=0, api_keys=[(0, 0, 8), (1, 0, 11), (2, 0, 5), (3, 0, 9), (4, 0, 4), (5, 0, 3), (6, 0, 6), (7, 0, 3), (8, 0, 8), (9, 0, 7), (10, 0, 3), (11, 0, 7), (12, 0, 4), (13, 0, 4), (14, 0, 5), (15, 0, 5), (16, 0, 4), (17, 0, 1), (18, 0, 3), (19, 0, 5), (20, 0, 4), (21, 0, 2), (22, 0, 3), (23, 0, 3), (24, 0, 1), (25, 0, 1), (26, 0, 1), (27, 0, 0), (28, 0, 3), (29, 0, 2), (30, 0, 2), (31, 0, 2), (32, 0, 3), (33, 0, 1), (34, 0, 1), (35, 0, 2), (36, 0, 2), (37, 0, 2), (38, 0, 2), (39, 0, 2), (40, 0, 2), (41, 0, 2), (42, 0, 2), (43, 0, 2), (44, 0, 1), (45, 0, 0), (46, 0, 0), (47, 0, 0), (48, 0, 0), (49, 0, 0)]),
b'\x00\x00\x016\x00\x00\x00\x01\x00\x00\x00\x00\x002\x00\x00\x00\x00\x00\x08\x00\x01\x00\x00\x00\x0b\x00\x02\x00\x00\x00\x05\x00\x03\x00\x00\x00\t\x00\x04\x00\x00\x00\x04\x00\x05\x00\x00\x00\x03\x00\x06\x00\x00\x00\x06\x00\x07\x00\x00\x00\x03\x00\x08\x00\x00\x00\x08\x00\t\x00\x00\x00\x07\x00\n\x00\x00\x00\x03\x00\x0b\x00\x00\x00\x07\x00\x0c\x00\x00\x00\x04\x00\r\x00\x00\x00\x04\x00\x0e\x00\x00\x00\x05\x00\x0f\x00\x00\x00\x05\x00\x10\x00\x00\x00\x04\x00\x11\x00\x00\x00\x01\x00\x12\x00\x00\x00\x03\x00\x13\x00\x00\x00\x05\x00\x14\x00\x00\x00\x04\x00\x15\x00\x00\x00\x02\x00\x16\x00\x00\x00\x03\x00\x17\x00\x00\x00\x03\x00\x18\x00\x00\x00\x01\x00\x19\x00\x00\x00\x01\x00\x1a\x00\x00\x00\x01\x00\x1b\x00\x00\x00\x00\x00\x1c\x00\x00\x00\x03\x00\x1d\x00\x00\x00\x02\x00\x1e\x00\x00\x00\x02\x00\x1f\x00\x00\x00\x02\x00 \x00\x00\x00\x03\x00!\x00\x00\x00\x01\x00"\x00\x00\x00\x01\x00#\x00\x00\x00\x02\x00$\x00\x00\x00\x02\x00%\x00\x00\x00\x02\x00&\x00\x00\x00\x02\x00\'\x00\x00\x00\x02\x00(\x00\x00\x00\x02\x00)\x00\x00\x00\x02\x00*\x00\x00\x00\x02\x00+\x00\x00\x00\x02\x00,\x00\x00\x00\x01\x00-\x00\x00\x00\x00\x00.\x00\x00\x00\x00\x00/\x00\x00\x00\x00\x000\x00\x00\x00\x00\x001\x00\x00\x00\x00',
),
(
ApiVersionsResponse[1](error_code=0, api_keys=[(0, 0, 8), (1, 0, 11), (2, 0, 5), (3, 0, 9), (4, 0, 4), (5, 0, 3), (6, 0, 6), (7, 0, 3), (8, 0, 8), (9, 0, 7), (10, 0, 3), (11, 0, 7), (12, 0, 4), (13, 0, 4), (14, 0, 5), (15, 0, 5), (16, 0, 4), (17, 0, 1), (18, 0, 3), (19, 0, 5), (20, 0, 4), (21, 0, 2), (22, 0, 3), (23, 0, 3), (24, 0, 1), (25, 0, 1), (26, 0, 1), (27, 0, 0), (28, 0, 3), (29, 0, 2), (30, 0, 2), (31, 0, 2), (32, 0, 3), (33, 0, 1), (34, 0, 1), (35, 0, 2), (36, 0, 2), (37, 0, 2), (38, 0, 2), (39, 0, 2), (40, 0, 2), (41, 0, 2), (42, 0, 2), (43, 0, 2), (44, 0, 1), (45, 0, 0), (46, 0, 0), (47, 0, 0), (48, 0, 0), (49, 0, 0)], throttle_time_ms=1),
b'\x00\x00\x01:\x00\x00\x00\x01\x00\x00\x00\x00\x002\x00\x00\x00\x00\x00\x08\x00\x01\x00\x00\x00\x0b\x00\x02\x00\x00\x00\x05\x00\x03\x00\x00\x00\t\x00\x04\x00\x00\x00\x04\x00\x05\x00\x00\x00\x03\x00\x06\x00\x00\x00\x06\x00\x07\x00\x00\x00\x03\x00\x08\x00\x00\x00\x08\x00\t\x00\x00\x00\x07\x00\n\x00\x00\x00\x03\x00\x0b\x00\x00\x00\x07\x00\x0c\x00\x00\x00\x04\x00\r\x00\x00\x00\x04\x00\x0e\x00\x00\x00\x05\x00\x0f\x00\x00\x00\x05\x00\x10\x00\x00\x00\x04\x00\x11\x00\x00\x00\x01\x00\x12\x00\x00\x00\x03\x00\x13\x00\x00\x00\x05\x00\x14\x00\x00\x00\x04\x00\x15\x00\x00\x00\x02\x00\x16\x00\x00\x00\x03\x00\x17\x00\x00\x00\x03\x00\x18\x00\x00\x00\x01\x00\x19\x00\x00\x00\x01\x00\x1a\x00\x00\x00\x01\x00\x1b\x00\x00\x00\x00\x00\x1c\x00\x00\x00\x03\x00\x1d\x00\x00\x00\x02\x00\x1e\x00\x00\x00\x02\x00\x1f\x00\x00\x00\x02\x00 \x00\x00\x00\x03\x00!\x00\x00\x00\x01\x00"\x00\x00\x00\x01\x00#\x00\x00\x00\x02\x00$\x00\x00\x00\x02\x00%\x00\x00\x00\x02\x00&\x00\x00\x00\x02\x00\'\x00\x00\x00\x02\x00(\x00\x00\x00\x02\x00)\x00\x00\x00\x02\x00*\x00\x00\x00\x02\x00+\x00\x00\x00\x02\x00,\x00\x00\x00\x01\x00-\x00\x00\x00\x00\x00.\x00\x00\x00\x00\x00/\x00\x00\x00\x00\x000\x00\x00\x00\x00\x001\x00\x00\x00\x00\x00\x00\x00\x01',
),
(
ApiVersionsResponse[2](error_code=0, api_keys=[(0, 0, 8), (1, 0, 11), (2, 0, 5), (3, 0, 9), (4, 0, 4), (5, 0, 3), (6, 0, 6), (7, 0, 3), (8, 0, 8), (9, 0, 7), (10, 0, 3), (11, 0, 7), (12, 0, 4), (13, 0, 4), (14, 0, 5), (15, 0, 5), (16, 0, 4), (17, 0, 1), (18, 0, 3), (19, 0, 5), (20, 0, 4), (21, 0, 2), (22, 0, 3), (23, 0, 3), (24, 0, 1), (25, 0, 1), (26, 0, 1), (27, 0, 0), (28, 0, 3), (29, 0, 2), (30, 0, 2), (31, 0, 2), (32, 0, 3), (33, 0, 1), (34, 0, 1), (35, 0, 2), (36, 0, 2), (37, 0, 2), (38, 0, 2), (39, 0, 2), (40, 0, 2), (41, 0, 2), (42, 0, 2), (43, 0, 2), (44, 0, 1), (45, 0, 0), (46, 0, 0), (47, 0, 0), (48, 0, 0), (49, 0, 0)], throttle_time_ms=1),
b'\x00\x00\x01:\x00\x00\x00\x01\x00\x00\x00\x00\x002\x00\x00\x00\x00\x00\x08\x00\x01\x00\x00\x00\x0b\x00\x02\x00\x00\x00\x05\x00\x03\x00\x00\x00\t\x00\x04\x00\x00\x00\x04\x00\x05\x00\x00\x00\x03\x00\x06\x00\x00\x00\x06\x00\x07\x00\x00\x00\x03\x00\x08\x00\x00\x00\x08\x00\t\x00\x00\x00\x07\x00\n\x00\x00\x00\x03\x00\x0b\x00\x00\x00\x07\x00\x0c\x00\x00\x00\x04\x00\r\x00\x00\x00\x04\x00\x0e\x00\x00\x00\x05\x00\x0f\x00\x00\x00\x05\x00\x10\x00\x00\x00\x04\x00\x11\x00\x00\x00\x01\x00\x12\x00\x00\x00\x03\x00\x13\x00\x00\x00\x05\x00\x14\x00\x00\x00\x04\x00\x15\x00\x00\x00\x02\x00\x16\x00\x00\x00\x03\x00\x17\x00\x00\x00\x03\x00\x18\x00\x00\x00\x01\x00\x19\x00\x00\x00\x01\x00\x1a\x00\x00\x00\x01\x00\x1b\x00\x00\x00\x00\x00\x1c\x00\x00\x00\x03\x00\x1d\x00\x00\x00\x02\x00\x1e\x00\x00\x00\x02\x00\x1f\x00\x00\x00\x02\x00 \x00\x00\x00\x03\x00!\x00\x00\x00\x01\x00"\x00\x00\x00\x01\x00#\x00\x00\x00\x02\x00$\x00\x00\x00\x02\x00%\x00\x00\x00\x02\x00&\x00\x00\x00\x02\x00\'\x00\x00\x00\x02\x00(\x00\x00\x00\x02\x00)\x00\x00\x00\x02\x00*\x00\x00\x00\x02\x00+\x00\x00\x00\x02\x00,\x00\x00\x00\x01\x00-\x00\x00\x00\x00\x00.\x00\x00\x00\x00\x00/\x00\x00\x00\x00\x000\x00\x00\x00\x00\x001\x00\x00\x00\x00\x00\x00\x00\x01',
),
(
ApiVersionsResponse[3](error_code=0, api_keys=[(0, 0, 8, {}), (1, 0, 11, {}), (2, 0, 5, {}), (3, 0, 9, {}), (4, 0, 4, {}), (5, 0, 3, {}), (6, 0, 6, {}), (7, 0, 3, {}), (8, 0, 8, {}), (9, 0, 7, {}), (10, 0, 3, {}), (11, 0, 7, {}), (12, 0, 4, {}), (13, 0, 4, {}), (14, 0, 5, {}), (15, 0, 5, {}), (16, 0, 4, {}), (17, 0, 1, {}), (18, 0, 3, {}), (19, 0, 5, {}), (20, 0, 4, {}), (21, 0, 2, {}), (22, 0, 3, {}), (23, 0, 3, {}), (24, 0, 1, {}), (25, 0, 1, {}), (26, 0, 1, {}), (27, 0, 0, {}), (28, 0, 3, {}), (29, 0, 2, {}), (30, 0, 2, {}), (31, 0, 2, {}), (32, 0, 3, {}), (33, 0, 1, {}), (34, 0, 1, {}), (35, 0, 2, {}), (36, 0, 2, {}), (37, 0, 2, {}), (38, 0, 2, {}), (39, 0, 2, {}), (40, 0, 2, {}), (41, 0, 2, {}), (42, 0, 2, {}), (43, 0, 2, {}), (44, 0, 1, {}), (45, 0, 0, {}), (46, 0, 0, {}), (47, 0, 0, {}), (48, 0, 0, {}), (49, 0, 0, {})], throttle_time_ms=0),
b'\x00\x00\x01j\x00\x00\x00\x01\x00\x003\x00\x00\x00\x00\x00\x08\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x02\x00\x00\x00\x05\x00\x00\x03\x00\x00\x00\t\x00\x00\x04\x00\x00\x00\x04\x00\x00\x05\x00\x00\x00\x03\x00\x00\x06\x00\x00\x00\x06\x00\x00\x07\x00\x00\x00\x03\x00\x00\x08\x00\x00\x00\x08\x00\x00\t\x00\x00\x00\x07\x00\x00\n\x00\x00\x00\x03\x00\x00\x0b\x00\x00\x00\x07\x00\x00\x0c\x00\x00\x00\x04\x00\x00\r\x00\x00\x00\x04\x00\x00\x0e\x00\x00\x00\x05\x00\x00\x0f\x00\x00\x00\x05\x00\x00\x10\x00\x00\x00\x04\x00\x00\x11\x00\x00\x00\x01\x00\x00\x12\x00\x00\x00\x03\x00\x00\x13\x00\x00\x00\x05\x00\x00\x14\x00\x00\x00\x04\x00\x00\x15\x00\x00\x00\x02\x00\x00\x16\x00\x00\x00\x03\x00\x00\x17\x00\x00\x00\x03\x00\x00\x18\x00\x00\x00\x01\x00\x00\x19\x00\x00\x00\x01\x00\x00\x1a\x00\x00\x00\x01\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x1c\x00\x00\x00\x03\x00\x00\x1d\x00\x00\x00\x02\x00\x00\x1e\x00\x00\x00\x02\x00\x00\x1f\x00\x00\x00\x02\x00\x00 \x00\x00\x00\x03\x00\x00!\x00\x00\x00\x01\x00\x00"\x00\x00\x00\x01\x00\x00#\x00\x00\x00\x02\x00\x00$\x00\x00\x00\x02\x00\x00%\x00\x00\x00\x02\x00\x00&\x00\x00\x00\x02\x00\x00\'\x00\x00\x00\x02\x00\x00(\x00\x00\x00\x02\x00\x00)\x00\x00\x00\x02\x00\x00*\x00\x00\x00\x02\x00\x00+\x00\x00\x00\x02\x00\x00,\x00\x00\x00\x01\x00\x00-\x00\x00\x00\x00\x00\x00.\x00\x00\x00\x00\x00\x00/\x00\x00\x00\x00\x00\x000\x00\x00\x00\x00\x00\x001\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
),
]
@pytest.mark.parametrize('msg, encoded', TEST_CASES)
def test_parse(msg, encoded):
msg.with_header(correlation_id=1, client_id='_internal_client_kYVL')
assert msg.encode(header=True, framed=True) == encoded
assert msg.__class__.decode(encoded, version=msg.version, header=True, framed=True) == msg
@pytest.mark.parametrize('version', [0, 1, 2, 3, 4])
def test_parse_flexible_error(version):
# An unsupported request version returns v0 response. Make sure this works with all versions!
msg = ApiVersionsResponse[0](error_code=35, api_keys=[(18, 0, 3)])
msg.with_header(correlation_id=1)
encoded = b'\x00\x00\x00\x10\x00\x00\x00\x01\x00#\x00\x00\x00\x01\x00\x12\x00\x00\x00\x03'
assert ApiVersionsResponse[version].decode(encoded, header=True, framed=True) == msg
@pytest.mark.parametrize("version", range(ApiVersionsRequest.min_version, ApiVersionsRequest.max_version + 1))
def test_api_versions_request_roundtrip(version):
request = ApiVersionsRequest(
client_software_name='foo' if version >= 3 else '',
client_software_version='123' if version >= 3 else '',
)
encoded = request.encode(version=version)
decoded = ApiVersionsRequest.decode(encoded, version=version)
assert decoded == request
@pytest.mark.parametrize("version", range(ApiVersionsResponse.min_version, ApiVersionsResponse.max_version + 1))
def test_api_versions_response_roundtrip(version):
ApiVersion = ApiVersionsResponse.ApiVersion
SupportedFeatureKey = ApiVersionsResponse.SupportedFeatureKey
FinalizedFeatureKey = ApiVersionsResponse.FinalizedFeatureKey
response = ApiVersionsResponse(
error_code=0,
api_keys=[
ApiVersion(api_key=1, min_version=0, max_version=10),
ApiVersion(3, 2, 5),
],
throttle_time_ms=123 if version >= 1 else 0,
supported_features=[
SupportedFeatureKey(
name='foo',
min_version=1,
max_version=3,
),
] if version >= 3 else [],
finalized_features_epoch=5555 if version >= 3 else -1,
finalized_features=[
FinalizedFeatureKey(
name='bar',
max_version_level=3,
min_version_level=2,
),
] if version >= 3 else [],
zk_migration_ready=True if version >= 3 else False,
)
encoded = response.encode(version=version)
decoded = ApiVersionsResponse.decode(encoded, version=version)
assert decoded == response
def test_supported_features():
encoded = b'\x00\x00\x00\x01\x00\x00>\x00\x00\x00\x00\x00\x0c\x00\x00\x01\x00\x04\x00\x11\x00\x00\x02\x00\x01\x00\n\x00\x00\x03\x00\x00\x00\r\x00\x00\x08\x00\x02\x00\t\x00\x00\t\x00\x01\x00\t\x00\x00\n\x00\x00\x00\x06\x00\x00\x0b\x00\x02\x00\t\x00\x00\x0c\x00\x00\x00\x04\x00\x00\r\x00\x00\x00\x05\x00\x00\x0e\x00\x00\x00\x05\x00\x00\x0f\x00\x00\x00\x06\x00\x00\x10\x00\x00\x00\x05\x00\x00\x11\x00\x00\x00\x01\x00\x00\x12\x00\x00\x00\x04\x00\x00\x13\x00\x02\x00\x07\x00\x00\x14\x00\x01\x00\x06\x00\x00\x15\x00\x00\x00\x02\x00\x00\x16\x00\x00\x00\x05\x00\x00\x17\x00\x02\x00\x04\x00\x00\x18\x00\x00\x00\x05\x00\x00\x19\x00\x00\x00\x04\x00\x00\x1a\x00\x00\x00\x05\x00\x00\x1b\x00\x01\x00\x01\x00\x00\x1c\x00\x00\x00\x05\x00\x00\x1d\x00\x01\x00\x03\x00\x00\x1e\x00\x01\x00\x03\x00\x00\x1f\x00\x01\x00\x03\x00\x00 \x00\x01\x00\x04\x00\x00!\x00\x00\x00\x02\x00\x00"\x00\x01\x00\x02\x00\x00#\x00\x01\x00\x04\x00\x00$\x00\x00\x00\x02\x00\x00%\x00\x00\x00\x03\x00\x00&\x00\x01\x00\x03\x00\x00\'\x00\x01\x00\x02\x00\x00(\x00\x01\x00\x02\x00\x00)\x00\x01\x00\x03\x00\x00*\x00\x00\x00\x02\x00\x00+\x00\x00\x00\x02\x00\x00,\x00\x00\x00\x01\x00\x00-\x00\x00\x00\x00\x00\x00.\x00\x00\x00\x00\x00\x00/\x00\x00\x00\x00\x00\x000\x00\x00\x00\x01\x00\x001\x00\x00\x00\x01\x00\x002\x00\x00\x00\x00\x00\x003\x00\x00\x00\x00\x00\x007\x00\x00\x00\x02\x00\x009\x00\x00\x00\x02\x00\x00<\x00\x00\x00\x02\x00\x00=\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00A\x00\x00\x00\x00\x00\x00B\x00\x00\x00\x01\x00\x00D\x00\x00\x00\x01\x00\x00E\x00\x00\x00\x01\x00\x00J\x00\x00\x00\x00\x00\x00K\x00\x00\x00\x00\x00\x00P\x00\x00\x00\x00\x00\x00Q\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00|\x06\x0egroup.version\x00\x00\x00\x01\x00\x0ekraft.version\x00\x00\x00\x01\x00\x11metadata.version\x00\x07\x00\x19\x00\x14transaction.version\x00\x00\x00\x02\x00!eligible.leader.replicas.version\x00\x00\x00\x01\x00\x01\x08\x00\x00\x00\x00\x00\x00\x00\n\x02V\x05\x0egroup.version\x00\x01\x00\x01\x00\x14transaction.version\x00\x02\x00\x02\x00\x0ekraft.version\x00\x01\x00\x01\x00\x11metadata.version\x00\x19\x00\x19\x00'
supported_features = b'\x06\x0egroup.version\x00\x00\x00\x01\x00\x0ekraft.version\x00\x00\x00\x01\x00\x11metadata.version\x00\x07\x00\x19\x00\x14transaction.version\x00\x00\x00\x02\x00!eligible.leader.replicas.version\x00\x00\x00\x01\x00'
data = io.BytesIO(supported_features)
features = ApiVersionsResponse.fields['supported_features'].decode(data, version=4, compact=True, tagged=None)
assert len(features) == 5
data = io.BytesIO(encoded)
ApiVersionsResponse[4].parse_header(data)
decoded = ApiVersionsResponse.decode(data, version=4)
assert decoded.version == 4
assert len(decoded.supported_features) == 5
assert set([feature.name for feature in decoded.supported_features]) == set([
'group.version', 'kraft.version', 'metadata.version',
'transaction.version', 'eligible.leader.replicas.version',
])