# Created by AG on 22-12-2025 from __future__ import annotations import random from typing import Any, Dict from src.payload_generation_utils import _generate_random_string, _generate_wrong_data_type from src.utils import _probabilistic_choice, identify_logical_type, _fields_enum, _field_names, _field_names_required from src.payload_generation_utils import _union_contains_string, _rand_email_gen, _choose_union_branching from src.payload_generation_utils import _is_email_field_valid, _is_string_valid_contract, _rand_fixed_bytes_to_b64 AvroContract = Dict[str, Any] def _generate_record_field_value( field_name: str, field_contract: Any, field_default_value: Any | None, rng: random.Random ) -> Any: from src.generate_payload import generate_valid_payload if field_default_value is not None and _probabilistic_choice(rng, 0.15): return field_default_value if _is_email_field_valid(field_name) and (_is_string_valid_contract(field_contract) or _union_contains_string(field_contract)): return _rand_email_gen(rng) return generate_valid_payload(field_contract, rng=rng) def _generate_record( contract: AvroContract, rng: random.Random ) -> Dict[str, Any]: record: Dict[str, Any] = {} for field in contract.get("fields", []): name = field["name"] field_contract = field["type"] field_default = field.get("default", None) if "default" in field else None record[name] = _generate_record_field_value(name, field_contract, field_default, rng) return record def _generate_array( contract: AvroContract, rng: random.Random ) -> list[Any]: from src.generate_payload import generate_valid_payload items_contract = contract["items"] return [ generate_valid_payload(items_contract, rng) for _ in range(rng.randint(0, 5)) ] def _generate_map( contract: AvroContract, rng: random.Random ) -> Dict[str, Any]: from src.generate_payload import generate_valid_payload values_contract = contract["values"] return { _generate_random_string(rng, 3, 10): generate_valid_payload(values_contract, rng) for _ in range(rng.randint(0, 5)) } def _generate_enum( contract: AvroContract, rng:random.Random ) -> str: return rng.choice(contract["symbols"]) def _generate_union( contract: list[Any], rng: random.Random ) -> Any: from src.generate_payload import generate_valid_payload selected_branch = _choose_union_branching(contract, rng=rng) return generate_valid_payload(selected_branch, rng) def _generate_fixed( contract: AvroContract, rng: random.Random ) -> str: return _rand_fixed_bytes_to_b64(rng, int(contract["size"])) def _generate_dict_contract( contract: AvroContract, rng: random.Random ) -> Any: logical_type = identify_logical_type(contract, rng) if logical_type is not None: return logical_type data_type = contract.get("type") if data_type == "record": return _generate_record(contract, rng) if data_type == "array": return _generate_array(contract, rng) if data_type == "map": return _generate_map(contract, rng) if data_type == "enum": return _generate_enum(contract, rng) if data_type == "fixed": return _generate_fixed(contract, rng) def _generate_invalid_type( inject_invalid: Dict[str, Any], contract: AvroContract, rng: random.Random ) -> Dict[str, Any]: contract_fields = contract.get("fields", []) if not contract_fields: inject_invalid["_is_invalid"] = True return inject_invalid random_field = rng.choice(contract_fields) inject_invalid[random_field["name"]] = _generate_wrong_data_type(random_field["type"], rng) return inject_invalid def _generate_invalid_enum( inject_invalid: Dict[str, Any], contract: AvroContract, rng: random.Random ) -> Dict[str, Any]: contract_enums = _fields_enum(contract) if contract_enums: field = rng.choice(contract_enums) inject_invalid[field["name"]] = "INVALID_SYMBOLS" return inject_invalid contract_fields = _field_names(contract) if contract_fields: inject_invalid[rng.choice(contract_fields)] = { "invalid": "enum_type" } else: inject_invalid["_is_invalid"] = True return inject_invalid def _generate_invalid_required( inject_invalid: Dict[str, Any], contract: AvroContract, rng: random.Random ) -> Dict[str, Any]: required_fields = _field_names_required(contract) if required_fields: inject_invalid[rng.choice(required_fields)] = None return inject_invalid field_names = _field_names(contract) if field_names: inject_invalid[rng.choice(field_names)] = None else: inject_invalid["_is_invalid"] = True return inject_invalid