Skip to content

Commit d2204e5

Browse files
cosmo0920edsiper
authored andcommitted
tests: integration: Add an integration test for empty map case on avro
Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
1 parent 54f674a commit d2204e5

2 files changed

Lines changed: 94 additions & 0 deletions

File tree

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
service:
2+
flush: 1
3+
log_level: info
4+
http_server: on
5+
http_port: ${FLUENT_BIT_HTTP_MONITORING_PORT}
6+
7+
pipeline:
8+
inputs:
9+
- name: dummy
10+
tag: out_kafka
11+
dummy: '{"ID":"97789a11215b54828d2c3f50b864afed42543ff8","HTTPHeader":{}}'
12+
samples: 1
13+
14+
outputs:
15+
- name: kafka
16+
match: out_kafka
17+
brokers: 127.0.0.1:${TEST_SUITE_KAFKA_PORT}
18+
topics: test
19+
format: avro
20+
schema_str: '{"type":"record","name":"EmptyMapRecord","fields":[{"name":"ID","type":"string"},{"name":"HTTPHeader","type":{"type":"map","values":"string"}}]}'
21+
schema_id: 42
22+
queue_full_retries: 1
23+
rdkafka.api.version.request: false
24+
rdkafka.broker.version.fallback: 0.8.2.0

tests/integration/scenarios/out_kafka/tests/test_out_kafka_001.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
from utils.test_service import FluentBitTestService
2626

2727

28+
EMPTY_MAP_RECORD_ID = "97789a11215b54828d2c3f50b864afed42543ff8"
29+
30+
2831
class Service:
2932
def __init__(self, config_file, *, use_schema_registry=False):
3033
self.config_file = os.path.abspath(os.path.join(os.path.dirname(__file__), "../config", config_file))
@@ -182,6 +185,42 @@ def _decode_simple_msgpack(data, offset=0):
182185
raise ValueError(f"Unsupported MessagePack type 0x{first:02x}")
183186

184187

188+
def _decode_avro_long(data, offset=0):
189+
encoded = 0
190+
shift = 0
191+
192+
while True:
193+
if offset >= len(data):
194+
raise ValueError("Truncated Avro long")
195+
196+
byte = data[offset]
197+
offset += 1
198+
199+
if shift == 63 and byte & 0x7E:
200+
raise ValueError("Invalid Avro long")
201+
202+
encoded |= (byte & 0x7F) << shift
203+
204+
if byte & 0x80 == 0:
205+
break
206+
207+
shift += 7
208+
if shift >= 64:
209+
raise ValueError("Invalid Avro long")
210+
211+
return (encoded >> 1) ^ -(encoded & 1), offset
212+
213+
214+
def _decode_avro_string(data, offset=0):
215+
size, offset = _decode_avro_long(data, offset)
216+
end = offset + size
217+
218+
if size < 0 or end > len(data):
219+
raise ValueError("Invalid Avro string")
220+
221+
return data[offset:end].decode("utf-8"), end
222+
223+
185224
def _decode_otlp_proto(data, signal_type):
186225
messages = {
187226
"logs": ExportLogsServiceRequest(),
@@ -475,6 +514,8 @@ def _start_or_skip_without_avro_encoder(service):
475514
log_contents = _read_fluent_bit_log(service)
476515
error_message = str(error)
477516
unsupported_markers = [
517+
"unknown configuration property 'schema_str'",
518+
"unknown configuration property 'schema_id'",
478519
"unknown configuration property 'schema_registry_url'",
479520
"unknown configuration property 'schema_registry_subject'",
480521
"unknown configuration property 'schema_registry_version'",
@@ -495,6 +536,13 @@ def _start_or_skip_without_avro_encoder(service):
495536
raise
496537

497538

539+
def test_decode_avro_long_rejects_out_of_range_terminal_bits():
540+
payload = b"\x80" * 9 + b"\x02"
541+
542+
with pytest.raises(ValueError, match="Invalid Avro long"):
543+
_decode_avro_long(payload)
544+
545+
498546
def test_out_kafka_sends_json_payload():
499547
service = Service("out_kafka_basic.yaml")
500548
service.start()
@@ -597,6 +645,28 @@ def test_out_kafka_avro_resolves_schema_registry_subject():
597645
assert "application/vnd.schemaregistry.v1+json" in requests_seen[0]["headers"]["Accept"]
598646

599647

648+
def test_out_kafka_avro_encodes_empty_map():
649+
service = Service("out_kafka_avro_empty_map.yaml")
650+
_start_or_skip_without_avro_encoder(service)
651+
652+
messages = service.wait_for_messages(1)
653+
service.stop()
654+
655+
message = messages[0]
656+
value = message["value"]
657+
658+
assert message["topic"] == "test"
659+
assert value[0] == 0
660+
assert int.from_bytes(value[1:5], "big") == SCHEMA_ID
661+
662+
record_id, offset = _decode_avro_string(value, 5)
663+
map_size, offset = _decode_avro_long(value, offset)
664+
665+
assert record_id == EMPTY_MAP_RECORD_ID
666+
assert map_size == 0
667+
assert offset == len(value)
668+
669+
600670
def test_out_kafka_otlp_json_logs():
601671
service = Service("out_kafka_otlp_json.yaml")
602672
service.start()

0 commit comments

Comments
 (0)