Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add method limit_param_set to ValuePoolFuzzer class #7

Merged
merged 5 commits into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion custom_components/test/fuzzing/fuzzer_overview.puml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ package "fuzzer_utils" as FUtils <<Folder>> {
--
- __int__(self) : void
+ fuzz(self, param_nr : int, types : list, param_combi : int) : list
+ limit_param_set(self, param_set : list, runs : int) : list
}
class "RandomFuzzer" as RFuzzer << class >>{
--
Expand Down Expand Up @@ -51,6 +50,7 @@ package "fuzzer_utils" as FUtils <<Folder>> {
--
- __int__(self) : void
+ run(self, function : function, param_set : list) : list
+ limit_param_set(self, param_set : list, runs : int) : list
}

class "GeneratorRunner" as GRunner << class >> {
Expand Down
41 changes: 37 additions & 4 deletions custom_components/test/fuzzing/fuzzer_utils/ParamRunner.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import logging
import inspect
import random

from custom_components.test.fuzzing.fuzzer_utils.Runner import Runner


class ParamRunner(Runner):
"""Paramter runner class, inherits from the abstract runner class."""

logger = logging.getLogger(__name__)

def __int__(self):
"""constructor"""
pass
Expand All @@ -23,20 +26,50 @@ def run(self, function, param_set: list) -> list:
:rtype: list
"""

logger = logging.getLogger(__name__)
sig = inspect.signature(function)
num_params = len(sig.parameters)
logger.info("The given functions needs " + str(num_params) + " parameters")
self.logger.info("The given functions needs " + str(num_params) + " parameters")

passed_tests = 0
failed_tests = 0
for param in param_set:
try:
function(*param)
passed_tests += 1
logger.debug(f"Test passed with parameters: {param}")
self.logger.debug(f"Test passed with parameters: {param}")
except Exception as e:
failed_tests += 1
logger.error(f"Test failed with parameters: {param}. Exception: {e}")
self.logger.error(f"Test failed with parameters: {param}. Exception: {e}")

return [passed_tests, failed_tests]

def limit_param_set(self, param_set: list, runs: int) -> list:
"""Generates a specific selection of an individual value pool. A list of lists is returned with a specified number of elements.

:param param_set: The value pool as list of lists.
:type param_nr: list
:param runs: Number of elements selected from the value pool.
:type types: int

:return: A random selection of certain elements from the parameter set.
:rtype: list
"""

# Validate input parameters
if not isinstance(param_set, list):
self.logger.error("Param_set must be of type list.")
raise TypeError("Param_set must be of type list.")
if len(param_set) == 0:
self.logger.error("Length of param_set must be greater then 0.")
raise ValueError("Length of param_set must be greater then 0.")
if not isinstance(runs, int) or runs <= 0:
self.logger.error("Runs must be of type int and greater than 0. Parameter set is returned unchanged.")
return param_set

# Selection of random elements from param_set if the number of runs is smaller than the number of elements in param_set
if runs > len(param_set):
self.logger.info("Length of param_set is smaller than the value of runs. Returned param_set unchanged.")
return param_set
else:
self.logger.info(f"Decresed elements in param_set from {len(param_set)} to {runs}")
return random.sample(param_set, runs)
16 changes: 8 additions & 8 deletions custom_components/test/fuzzing/fuzzer_utils/ValuePoolFuzzer.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from itertools import product
import logging


from custom_components.test.fuzzing.fuzzer_utils.Fuzzer import Fuzzer
from custom_components.test.fuzzing.fuzzer_utils.ValuePool import ValuePool

Expand All @@ -10,6 +9,7 @@ class ValuePoolFuzzer(Fuzzer):
"""Value pool fuzzer class, inherits from the abstract fuzzer class."""

value_pool = ValuePool()
logger = logging.getLogger(__name__)

def __int__(self):
"""constructor"""
Expand All @@ -32,18 +32,18 @@ def fuzz(
:rtype: list
"""

logger = logging.getLogger(__name__)
logger.warning("The var param_combi is not in use!")

self.logger.warning("The var param_combi is not in use!")

# Validate input parameters
if param_nr <= 0:
logger.error("Param Nr smaller or equal 0")
self.logger.error("Param Nr smaller or equal 0")
raise ValueError("param_nr must be a positive integer.")
if len(types) != param_nr:
logger.error("Length of types list must be equal to param_nr.")
self.logger.error("Length of types list must be equal to param_nr.")
raise ValueError("Length of types list must be equal to param_nr.")
if param_combi <= 0 or param_combi > param_nr:
logger.error("param_combi must be between 1 and param_nr.")
self.logger.error("param_combi must be between 1 and param_nr.")
raise ValueError("param_combi must be between 1 and param_nr.")

# Get the value pools for the valid types
Expand All @@ -63,7 +63,7 @@ def fuzz(
# Check whether requested types are valid.
for t in types:
if t not in valid_types:
logger.error("Invalid type " + str(t) + "specified.")
self.logger.error("Invalid type " + str(t) + "specified.")
raise ValueError(f"Invalid type '{t}' specified.")

# Create a list of lists containing the valid values for each type in types_list
Expand All @@ -77,4 +77,4 @@ def fuzz(
result = [list(combination) for combination in combinations]

# print(result)
return result
return result
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@
param_runner = ParamRunner()


@pytest.mark.timeout(300)
def test_map_range():
logger.info("Start of map_range() test.")
param_set = value_pool_fuzzer.fuzz(
5, ["FLOAT", "FLOAT", "FLOAT", "FLOAT", "FLOAT"], 5
)
param_set = param_runner.limit_param_set(param_set, 50000)
result = param_runner.run(map_range, param_set)
logger.info("map_range() test finished.")

Expand Down