namuan/fuzzy-swagger

View on GitHub
src/fuzzy_swagger/fuzz_generator.py

Summary

Maintainability
A
0 mins
Test Coverage
import os
from random import getrandbits, randint, uniform
from typing import Any, Dict, List

with open(os.path.dirname(os.path.realpath(__file__)) + "/blns.txt") as f:
    string_data = [line.rstrip() for line in f if not line.strip().startswith("#")]


def rand_int(upper_limit: int, lower_limit: int = 0) -> int:
    return randint(lower_limit, upper_limit)


def fuzz_boolean(_: Any) -> bool:
    return bool(getrandbits(1))


def fuzz_date_time() -> str:
    year = rand_int(3000, 1900)
    month = rand_int(12, 1)
    day = rand_int(30, 1)
    hour = rand_int(24, 1)
    minute = rand_int(60, 1)
    second = rand_int(60, 1)

    return "%s-%02d-%02dT%02d:%02d:%02d.000+00:00" % (
        year,
        month,
        day,
        hour,
        minute,
        second,
    )


def fuzz_string(string_schema: Any) -> Any:
    is_enum = string_schema.get("enum")
    string_format = string_schema.get("format")
    if is_enum:
        # get a random item from list
        return is_enum[rand_int(len(is_enum) - 1)]

    if string_format == "date-time":
        return fuzz_date_time()

    random_index = rand_int(len(string_data) - 1)
    return string_data[random_index]


def fuzz_int(int_schema: Any) -> int:
    return int(uniform(-1 * 1000000000, 1 * 1000000000))


def fuzz_file(file_schema: Any) -> str:
    return ""


def fuzz_array_length() -> int:
    return 10


def fuzz_array(arr_schema: Any, arr_length: int = fuzz_array_length()) -> List:
    items = arr_schema["items"]
    arr_items_type = items["type"]
    fuzz_func = type_mapper_func(arr_items_type)
    if arr_items_type == "object":
        return [
            fuzz_object(arr_schema["items"]["properties"]) for o in range(arr_length)
        ]
    else:
        return [fuzz_func(items) for i in range(arr_length)]


def fuzz_object(root_properties: Dict) -> object:
    obj_root = {}
    for k, v in root_properties.items():
        prop_type = v["type"]
        if prop_type != "object":
            fuzz_func = type_mapper_func(prop_type)
            obj_root[k] = fuzz_func(v)
        else:
            obj_root[k] = fuzz_object(v["properties"])

    return obj_root


__type_mapping = {
    "integer": fuzz_int,
    "boolean": fuzz_boolean,
    "string": fuzz_string,
    "array": fuzz_array,
    "file": fuzz_file,
}


def type_mapper_func(type_name: str) -> Any:
    return __type_mapping[type_name]