Fix missing custom payload handling (#788)
Closes #787 restler_custom_payload is not correctly plugged into examples Also fix incorrectly passed 'quoted' parameters - this was caught by manually inspecting the logs and seeing incorrect quoting for several primitives when using the generated schema only. Updated test baselines for invalidvalue after the bug fix. Testing: - confirmed the manual repro from #787 now works correctly
This commit is contained in:
Родитель
9750bf91d5
Коммит
a3abcb60b8
|
@ -91,11 +91,11 @@
|
|||
"--fuzzing_mode",
|
||||
"directed-smoke-test",
|
||||
"--restler_grammar",
|
||||
"d:\\demo\\restler_working_dir\\Compile\\grammar.py",
|
||||
"d:\\test\\demo_server\\Compile\\grammar.py",
|
||||
"--custom_mutations",
|
||||
"d:\\demo\\restler_working_dir\\Compile\\dict.json",
|
||||
"d:\\test\\demo_server\\Compile\\dict.json",
|
||||
"--settings",
|
||||
"d:\\demo\\restler_working_dir\\Compile\\engine_settings.json",
|
||||
"d:\\test\\demo_server\\Compile\\engine_settings.json",
|
||||
"--no_ssl",
|
||||
"--host",
|
||||
"localhost",
|
||||
|
|
|
@ -87,7 +87,7 @@ def get_test_values(max_values: int, req: Request, static_dict=None,
|
|||
quoted = request_block[2]
|
||||
examples = request_block[3]
|
||||
|
||||
fuzzable_string = primitives.restler_fuzzable_string("fuzzstring", is_quoted=quoted, examples=examples)
|
||||
fuzzable_string = primitives.restler_fuzzable_string("fuzzstring", quoted=quoted, examples=examples)
|
||||
vgen_fuzzable_values, _, _ = req.init_fuzzable_values([fuzzable_string],
|
||||
vg_pool,
|
||||
log_dict_err_to_main=False)
|
||||
|
|
|
@ -172,12 +172,14 @@ class HeaderParam(KeyValueParamBase):
|
|||
|
||||
class ParamBase:
|
||||
""" Base class for all body parameters """
|
||||
def __init__(self, param_properties=None, dynamic_object=None, param_name=None, content_type=None, is_quoted=False):
|
||||
def __init__(self, param_properties=None, dynamic_object=None, param_name=None, content_type=None, is_quoted=False,
|
||||
custom_payload_type=None):
|
||||
self._fuzzable = False
|
||||
self._example_values = []
|
||||
self._tag = ''
|
||||
self._param_properties = param_properties
|
||||
self._dynamic_object = dynamic_object
|
||||
self._custom_payload_type = custom_payload_type
|
||||
self._param_name = param_name
|
||||
self._content_type = content_type
|
||||
self._is_quoted = is_quoted
|
||||
|
@ -293,6 +295,47 @@ class ParamBase:
|
|||
self._is_quoted = src.is_quoted
|
||||
self._param_name = src._param_name
|
||||
|
||||
def get_custom_payload(self):
|
||||
if self._custom_payload_type is None:
|
||||
return None
|
||||
|
||||
if self._custom_payload_type == "String":
|
||||
return [primitives.restler_custom_payload(self._content, quoted=self.is_quoted,
|
||||
param_name=self.param_name,
|
||||
writer=self.dynamic_object_writer_variable)]
|
||||
elif self._custom_payload_type == "Header":
|
||||
return [primitives.restler_custom_payload_header(self._content, quoted=self.is_quoted,
|
||||
param_name=self.param_name,
|
||||
writer=self.dynamic_object_writer_variable)]
|
||||
elif self._custom_payload_type == "Query":
|
||||
return [primitives.restler_custom_payload_query(self._content, quoted=self.is_quoted,
|
||||
param_name=self.param_name,
|
||||
writer=self.dynamic_object_writer_variable)]
|
||||
elif self._custom_payload_type == "UuidSuffix":
|
||||
return [primitives.restler_custom_payload_uuid4_suffix(self._content, quoted=self.is_quoted,
|
||||
param_name=self.param_name,
|
||||
writer=self.dynamic_object_writer_variable)]
|
||||
else:
|
||||
raise Exception(f"Unexpected custom payload type: {self._custom_payload_type}")
|
||||
|
||||
def get_dynamic_object(self):
|
||||
if self.is_dynamic_object_reader:
|
||||
content = dependencies.RDELIM + self._content + dependencies.RDELIM
|
||||
return [primitives.restler_static_string(content, quoted=self.is_quoted)]
|
||||
return None
|
||||
|
||||
def get_blocks(self):
|
||||
"""Returns the blocks for this payload if it defines either a custom payload or dynamic object.
|
||||
Otherwise, returns None"""
|
||||
custom_payload_blocks = self.get_custom_payload()
|
||||
if custom_payload_blocks is not None:
|
||||
return custom_payload_blocks
|
||||
|
||||
dynamic_object_blocks = self.get_dynamic_object()
|
||||
if dynamic_object_blocks is not None:
|
||||
return dynamic_object_blocks
|
||||
return None
|
||||
|
||||
def set_fuzzable(self, is_fuzzable):
|
||||
""" Sets param as fuzzable
|
||||
|
||||
|
@ -379,9 +422,9 @@ class ParamValue(ParamBase):
|
|||
@rtype: None
|
||||
|
||||
"""
|
||||
ParamBase.__init__(self, param_properties=param_properties, dynamic_object=dynamic_object, is_quoted=is_quoted)
|
||||
ParamBase.__init__(self, param_properties=param_properties, dynamic_object=dynamic_object, is_quoted=is_quoted,
|
||||
custom_payload_type=custom_payload_type)
|
||||
self._content = None
|
||||
self._custom_payload_type = custom_payload_type
|
||||
|
||||
def __eq__(self, other):
|
||||
""" Operator equals
|
||||
|
@ -447,24 +490,11 @@ class ParamValue(ParamBase):
|
|||
@rtype : List[str]
|
||||
|
||||
"""
|
||||
if self._custom_payload_type is not None:
|
||||
# TODO: support 'writer' variable in the schema parser and request parameters below
|
||||
if self._custom_payload_type == "String":
|
||||
return [primitives.restler_custom_payload(self._content)]
|
||||
elif self._custom_payload_type == "Query":
|
||||
return [primitives.restler_custom_payload(self._content)]
|
||||
elif self._custom_payload_type == "Header":
|
||||
return [primitives.restler_custom_payload_header(self._content)]
|
||||
elif self._custom_payload_type == "UuidSuffix":
|
||||
return [primitives.restler_custom_payload_uuid4_suffix(self._content)]
|
||||
else:
|
||||
raise Exception(f"Unknown custom payload type: {self._custom_payload_type}")
|
||||
base_blocks = ParamBase.get_blocks(self)
|
||||
if base_blocks is not None:
|
||||
return base_blocks
|
||||
|
||||
content = self._content
|
||||
if self.is_dynamic_object_reader:
|
||||
content = dependencies.RDELIM + self._content + dependencies.RDELIM
|
||||
|
||||
return [primitives.restler_static_string(content)]
|
||||
return [primitives.restler_static_string(self._content)]
|
||||
|
||||
def get_fuzzing_blocks(self, visitor):
|
||||
""" Gets the fuzzing blocks for this param """
|
||||
|
@ -912,9 +942,9 @@ class ParamString(ParamValue):
|
|||
@rtype: None
|
||||
|
||||
"""
|
||||
ParamValue.__init__(self, param_properties=param_properties, dynamic_object=dynamic_object, is_quoted=is_quoted)
|
||||
ParamValue.__init__(self, param_properties=param_properties, dynamic_object=dynamic_object, is_quoted=is_quoted,
|
||||
custom_payload_type=custom_payload_type)
|
||||
|
||||
self._custom_payload_type=custom_payload_type
|
||||
self._content_type = content_type
|
||||
self._unknown = False
|
||||
|
||||
|
@ -936,20 +966,11 @@ class ParamString(ParamValue):
|
|||
@rtype : List[str]
|
||||
|
||||
"""
|
||||
if self._custom_payload_type is not None:
|
||||
if self._custom_payload_type == "String":
|
||||
return [primitives.restler_custom_payload(self._content, quoted=self.is_quoted)]
|
||||
elif self._custom_payload_type == "Header":
|
||||
return [primitives.restler_custom_payload_header(self._content, quoted=self.is_quoted)]
|
||||
elif self._custom_payload_type == "Query":
|
||||
return [primitives.restler_custom_payload_query(self._content, quoted=self.is_quoted)]
|
||||
else:
|
||||
raise Exception(f"Unexpected custom payload type: {self._custom_payload_type}")
|
||||
if self.is_dynamic_object_reader:
|
||||
content = dependencies.RDELIM + self._content + dependencies.RDELIM
|
||||
else:
|
||||
content = self._content
|
||||
return [primitives.restler_static_string(content, quoted=self.is_quoted)]
|
||||
base_blocks = ParamBase.get_blocks(self)
|
||||
if base_blocks is not None:
|
||||
return base_blocks
|
||||
|
||||
return [primitives.restler_static_string(self._content, quoted=self.is_quoted)]
|
||||
|
||||
def get_original_blocks(self, config=None):
|
||||
""" Gets the original request blocks for the String Parameters.
|
||||
|
@ -958,25 +979,11 @@ class ParamString(ParamValue):
|
|||
@rtype : List[str]
|
||||
|
||||
"""
|
||||
if self._custom_payload_type is not None:
|
||||
if self._custom_payload_type == "String":
|
||||
return [primitives.restler_custom_payload(self._content, quoted=self.is_quoted,
|
||||
param_name=self.param_name,
|
||||
writer=self.dynamic_object_writer_variable)]
|
||||
elif self._custom_payload_type == "Header":
|
||||
return [primitives.restler_custom_payload_header(self._content, quoted=self.is_quoted,
|
||||
param_name=self.param_name,
|
||||
writer=self.dynamic_object_writer_variable)]
|
||||
elif self._custom_payload_type == "Query":
|
||||
return [primitives.restler_custom_payload_query(self._content, quoted=self.is_quoted,
|
||||
param_name=self.param_name,
|
||||
writer=self.dynamic_object_writer_variable)]
|
||||
else:
|
||||
raise Exception(f"Unexpected custom payload type: {self._custom_payload_type}")
|
||||
if self.is_dynamic_object_reader:
|
||||
content = dependencies.RDELIM + self._content + dependencies.RDELIM
|
||||
else:
|
||||
content = self._content
|
||||
base_blocks = ParamBase.get_blocks(self)
|
||||
if base_blocks is not None:
|
||||
return base_blocks
|
||||
|
||||
content = self._content
|
||||
|
||||
if self.is_fuzzable:
|
||||
if self._content_type == "String":
|
||||
|
@ -1122,7 +1129,7 @@ class DynamicObject:
|
|||
|
||||
class ParamNumber(ParamValue):
|
||||
""" Class for number type parameters """
|
||||
def __init__(self, param_properties=None, dynamic_object=None, is_quoted=False, number_type="Int"):
|
||||
def __init__(self, param_properties=None, custom_payload_type=None, dynamic_object=None, is_quoted=False, number_type="Int"):
|
||||
""" Initialize a number type parameter
|
||||
|
||||
@param custom: Whether or not this is a custom payload
|
||||
|
@ -1132,7 +1139,8 @@ class ParamNumber(ParamValue):
|
|||
@rtype: None
|
||||
|
||||
"""
|
||||
ParamValue.__init__(self, param_properties=param_properties, dynamic_object=dynamic_object, is_quoted=is_quoted)
|
||||
ParamValue.__init__(self, param_properties=param_properties, dynamic_object=dynamic_object, is_quoted=is_quoted,
|
||||
custom_payload_type=custom_payload_type)
|
||||
self._number_type = number_type
|
||||
|
||||
@property
|
||||
|
@ -1150,9 +1158,9 @@ class ParamNumber(ParamValue):
|
|||
@rtype : List[str]
|
||||
|
||||
"""
|
||||
if self.is_dynamic_object_reader:
|
||||
content = dependencies.RDELIM + self._content + dependencies.RDELIM
|
||||
return [primitives.restler_static_string(content)]
|
||||
base_blocks = ParamBase.get_blocks(self)
|
||||
if base_blocks is not None:
|
||||
return base_blocks
|
||||
|
||||
content = self._content
|
||||
if self._number_type == "Int":
|
||||
|
@ -1216,6 +1224,12 @@ class ParamNumber(ParamValue):
|
|||
return fuzzer._fuzz_number(self)
|
||||
|
||||
class ParamBoolean(ParamValue):
|
||||
def __init__(self, param_properties=None, custom_payload_type=None, dynamic_object=None, is_quoted=False):
|
||||
""" Initialize a boolean type parameter
|
||||
"""
|
||||
ParamValue.__init__(self, param_properties=param_properties, dynamic_object=dynamic_object, is_quoted=is_quoted,
|
||||
custom_payload_type=custom_payload_type)
|
||||
|
||||
""" Class for Boolean type parameters """
|
||||
@property
|
||||
def type(self):
|
||||
|
@ -1232,9 +1246,9 @@ class ParamBoolean(ParamValue):
|
|||
@rtype : List[str]
|
||||
|
||||
"""
|
||||
if self.is_dynamic_object_reader:
|
||||
content = dependencies.RDELIM + self._content + dependencies.RDELIM
|
||||
return [primitives.restler_static_string(content)]
|
||||
base_blocks = ParamBase.get_blocks(self)
|
||||
if base_blocks is not None:
|
||||
return base_blocks
|
||||
|
||||
return [primitives.restler_fuzzable_bool(self._content, quoted=self.is_quoted, examples=self.example_values,
|
||||
param_name=self.param_name,
|
||||
|
@ -1292,6 +1306,13 @@ class ParamBoolean(ParamValue):
|
|||
|
||||
class ParamObjectLeaf(ParamValue):
|
||||
""" Class for leaf object type parameters """
|
||||
def __init__(self, param_properties=None, custom_payload_type=None, dynamic_object=None, is_quoted=False):
|
||||
""" Initialize an object leaf type parameter
|
||||
"""
|
||||
ParamValue.__init__(self, param_properties=param_properties, dynamic_object=dynamic_object, is_quoted=is_quoted,
|
||||
custom_payload_type=custom_payload_type)
|
||||
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
return dict
|
||||
|
@ -1327,9 +1348,9 @@ class ParamObjectLeaf(ParamValue):
|
|||
@rtype : List[str]
|
||||
|
||||
"""
|
||||
if self.is_dynamic_object_reader:
|
||||
content = dependencies.RDELIM + self._content + dependencies.RDELIM
|
||||
return [primitives.restler_static_string(content)]
|
||||
base_blocks = ParamBase.get_blocks(self)
|
||||
if base_blocks is not None:
|
||||
return base_blocks
|
||||
|
||||
# This check is present to support older grammars, and can be removed in the future.
|
||||
if self._content is None:
|
||||
|
@ -1413,10 +1434,9 @@ class ParamObjectLeaf(ParamValue):
|
|||
|
||||
class ParamEnum(ParamValue):
|
||||
""" Class for Enum type parameters """
|
||||
|
||||
def __init__(self, contents, content_type, is_quoted=False,
|
||||
param_properties=None, body_param=True,
|
||||
enum_name=FUZZABLE_GROUP_TAG):
|
||||
def __init__(self, contents, content_type,
|
||||
enum_name=FUZZABLE_GROUP_TAG,
|
||||
param_properties=None, custom_payload_type=None, dynamic_object=None, is_quoted=False):
|
||||
""" Initialize an Enum type parameter
|
||||
|
||||
@param contents: A list of enum contents
|
||||
|
@ -1428,8 +1448,8 @@ class ParamEnum(ParamValue):
|
|||
@rtype: None
|
||||
|
||||
"""
|
||||
ParamBase.__init__(self, param_properties)
|
||||
|
||||
ParamValue.__init__(self, param_properties=param_properties, dynamic_object=dynamic_object, is_quoted=is_quoted,
|
||||
custom_payload_type=custom_payload_type)
|
||||
self._contents = contents
|
||||
self._type = content_type
|
||||
self._is_quoted = is_quoted
|
||||
|
@ -1486,6 +1506,10 @@ class ParamEnum(ParamValue):
|
|||
@rtype : List[str]
|
||||
|
||||
"""
|
||||
base_blocks = ParamBase.get_blocks(self)
|
||||
if base_blocks is not None:
|
||||
return base_blocks
|
||||
|
||||
return [primitives.restler_fuzzable_group(self._enum_name,
|
||||
self._contents,
|
||||
quoted=self.is_quoted, examples=self.example_values,
|
||||
|
|
|
@ -258,13 +258,23 @@ def des_param_payload(param_payload_json, tag='', body_param=True):
|
|||
dynamic_object=dynamic_object, is_quoted=is_quoted, content_type=content_type)
|
||||
|
||||
elif content_type == 'Int':
|
||||
value = ParamNumber(param_properties=param_properties, dynamic_object=dynamic_object, number_type=content_type)
|
||||
value = ParamNumber(custom_payload_type=custom_payload_type,
|
||||
param_properties=param_properties,
|
||||
dynamic_object=dynamic_object,
|
||||
number_type=content_type)
|
||||
elif content_type == 'Number':
|
||||
value = ParamNumber(param_properties=param_properties, dynamic_object=dynamic_object, number_type=content_type)
|
||||
value = ParamNumber(custom_payload_type=custom_payload_type,
|
||||
param_properties=param_properties,
|
||||
dynamic_object=dynamic_object,
|
||||
number_type=content_type)
|
||||
elif content_type == 'Bool':
|
||||
value = ParamBoolean(param_properties=param_properties, dynamic_object=dynamic_object)
|
||||
value = ParamBoolean(custom_payload_type=custom_payload_type,
|
||||
param_properties=param_properties,
|
||||
dynamic_object=dynamic_object)
|
||||
elif content_type == 'Object':
|
||||
value = ParamObjectLeaf(param_properties=param_properties, dynamic_object=dynamic_object)
|
||||
value = ParamObjectLeaf(custom_payload_type=custom_payload_type,
|
||||
param_properties=param_properties,
|
||||
dynamic_object=dynamic_object)
|
||||
elif 'Enum' in content_type:
|
||||
# unique case for Enums, as they are defined as
|
||||
# "fuzzable" types in the schema, but are not fuzzable
|
||||
|
@ -290,7 +300,8 @@ def des_param_payload(param_payload_json, tag='', body_param=True):
|
|||
else:
|
||||
is_quoted = False
|
||||
value = ParamEnum(contents, enum_content_type, is_quoted=is_quoted,
|
||||
param_properties=param_properties, body_param=body_param, enum_name=enum_name)
|
||||
custom_payload_type=custom_payload_type,
|
||||
param_properties=param_properties, enum_name=enum_name)
|
||||
else:
|
||||
logger.write_to_main(f'Unexpected enum schema {name}')
|
||||
else:
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -45,7 +45,7 @@ class CandidateValuesTest(unittest.TestCase):
|
|||
current_file_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
checkers_file_dir = os.path.join(current_file_dir, "..", "checkers")
|
||||
file_path = os.path.join(checkers_file_dir, "invalid_value_checker_value_gen.py")
|
||||
fuzzable_string = primitives.restler_fuzzable_string("fuzzstring", is_quoted=False, examples=[])
|
||||
fuzzable_string = primitives.restler_fuzzable_string("fuzzstring", quoted=False, examples=[])
|
||||
req_definition = [fuzzable_string]
|
||||
temp_req = Request(req_definition)
|
||||
|
||||
|
@ -77,7 +77,7 @@ class CandidateValuesTest(unittest.TestCase):
|
|||
|
||||
# Default generators with 'int' in request block, which is not present there.
|
||||
# Expected: the string generator should be used.
|
||||
fuzzable_int = primitives.restler_fuzzable_int("20", is_quoted=False, examples=[])
|
||||
fuzzable_int = primitives.restler_fuzzable_int("20", quoted=False, examples=[])
|
||||
override_value_gen["restler_fuzzable_int"] = None
|
||||
req_definition = [fuzzable_int]
|
||||
temp_req = Request(req_definition)
|
||||
|
|
Загрузка…
Ссылка в новой задаче