Support examples and writer variables in the schema parser (#603)

- Added the primitives to 'get_original_blocks'.

- Added test.

Note: get_blocks was not modified - payload body checker support
will need to be addressed separately.  This fix only addresses 'get_original_blocks',
which is used in the main algorithm to generate payloads.

- Fixed compiler inconsistency - handle restler_custom_payload_uuid4_suffix
in the same way as other primitives for quoting.
- Fixed example handling in main algorithm
- fixed several quoting bugs
This commit is contained in:
marina-p 2022-08-12 15:40:47 -07:00 коммит произвёл GitHub
Родитель 3fac57bfff
Коммит acfcc16f75
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
33 изменённых файлов: 5068 добавлений и 135 удалений

9
.vscode/launch.json поставляемый
Просмотреть файл

@ -11,6 +11,15 @@
"program": "${file}"
},
{
"name": "Python: test quick start",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}\\restler\\end_to_end_tests\\test_quick_start.py",
"args" :[
"d:\\restlerdrop\\main",
]
},
{
"name": "Python: Payload body checker",
"type": "python",
"request": "launch",

Просмотреть файл

@ -12,6 +12,7 @@ from engine.core.requests import FailureInformation
from engine.core.sequences import Sequence
from engine.fuzzing_parameters.parameter_schema import HeaderList
import engine.primitives as primitives
from engine.fuzzing_parameters.fuzzing_config import FuzzingConfig
class ExamplesChecker(CheckerBase):
""" Checker for payload body fuzzing. """
@ -81,10 +82,11 @@ class ExamplesChecker(CheckerBase):
BugBuckets.Instance().update_bug_buckets(seq, code, origin=self.__class__.__name__, hash_full_request=True)
status_codes = {}
fuzzing_config = FuzzingConfig()
# Send new request for each body example
for example in filter(lambda x : x is not None, request.examples.body_examples):
blocks = example.get_blocks()
blocks = example.get_original_blocks(fuzzing_config)
new_request = request.substitute_body(blocks)
if new_request:
_send_request(new_request)
@ -96,7 +98,7 @@ class ExamplesChecker(CheckerBase):
for example in filter(lambda x : x is not None, request.examples.query_examples):
q_blocks = []
for idx, query in enumerate(example.param_list):
q_blocks += query.get_blocks()
q_blocks += query.get_original_blocks(fuzzing_config)
if idx < len(example) - 1:
# Add the query separator
q_blocks.append(primitives.restler_static_string('&'))
@ -111,7 +113,7 @@ class ExamplesChecker(CheckerBase):
# There will soon be IDs associated with the examples, so they can be matched.
for example in filter(lambda x : x is not None, request.examples.header_examples):
headers_schema = HeaderList(param=example.param_list)
h_blocks = headers_schema.get_blocks()
h_blocks = headers_schema.get_original_blocks(fuzzing_config)
new_request = request.substitute_headers(h_blocks)
if new_request:
_send_request(new_request)

Просмотреть файл

@ -701,7 +701,7 @@ class Request(object):
return i + 1
return -1
def get_schema_combinations(self, use_grammar_py_schema=True):
def get_schema_combinations(self, use_grammar_py_schema=False):
""" A generator that lazily iterates over a pool of schema combinations
for this request, determined the specified settings.
@ -1016,7 +1016,9 @@ class Request(object):
# constructed, since not all of them may be needed, e.g. during smoke test mode.
next_combination = 0
schema_idx = -1
schema_combinations = itertools.islice(self.get_schema_combinations(), Settings().max_schema_combinations)
schema_combinations = itertools.islice(self.get_schema_combinations(
use_grammar_py_schema=Settings().allow_grammar_py_user_update),
Settings().max_schema_combinations)
remaining_combinations_count = Settings().max_combinations - skip
for (req, is_example) in schema_combinations:
@ -1372,6 +1374,8 @@ class Request(object):
check_example_schema_is_valid(num_query_payloads, max_example_payloads, "query")
check_example_schema_is_valid(num_body_payloads, max_example_payloads, "body")
fuzzing_config = FuzzingConfig()
for payload_idx in range(max_example_payloads):
body_example = None
query_example = None
@ -1395,16 +1399,16 @@ class Request(object):
query_blocks = None
header_blocks = None
if body_example:
body_blocks = body_example.get_blocks()
body_blocks = body_example.get_original_blocks(fuzzing_config)
# Only substitute the body if there is a body.
if body_blocks:
new_request = new_request.substitute_body(body_blocks)
if query_example:
query_blocks = query_example.get_blocks()
query_blocks = query_example.get_original_blocks(fuzzing_config)
new_request = new_request.substitute_query(query_blocks)
if header_example:
header_blocks = header_example.get_blocks()
header_blocks = header_example.get_original_blocks(fuzzing_config)
new_request = new_request.substitute_headers(header_blocks)
if new_request:

Просмотреть файл

@ -54,7 +54,7 @@ class BodySchema():
except Exception as err:
msg = f'Fail deserializing request schema body parameters: {err!s}'
logger.write_to_main(msg, print_to_console=True)
raise Exception(msg)
raise
self._node_count = self._schema.count_nodes(self._config)

Просмотреть файл

@ -150,12 +150,13 @@ class HeaderParam(KeyValueParamBase):
class ParamBase():
""" Base class for all body parameters """
def __init__(self, is_required=True, is_dynamic_object=False, content_type=None, is_quoted=False):
def __init__(self, is_required=True, dynamic_object=None, param_name=None, content_type=None, is_quoted=False):
self._fuzzable = False
self._example_values = []
self._tag = ''
self._is_required = is_required
self._is_dynamic_object = is_dynamic_object
self._dynamic_object = dynamic_object
self._param_name = param_name
self._content_type = content_type
self._is_quoted=is_quoted
@ -199,6 +200,16 @@ class ParamBase():
"""
return self._example_values
@property
def param_name(self):
""" Return the param name
@return: The parameter name
@rtype : list[Str]
"""
return self._param_name
@property
def is_quoted(self):
""" Returns whether the param is quoted
@ -210,13 +221,24 @@ class ParamBase():
return self._is_quoted
@property
def is_dynamic_object(self):
""" Returns whether the param is a dynamic object
def dynamic_object_writer_variable(self):
""" Returns whether the param is a dynamic object writer variable
@return: True if the parameter is a writer variable
@rtype: Bool
"""
if self._dynamic_object is None:
return None
return self._dynamic_object._variable_name
@property
def is_dynamic_object_reader(self):
""" Returns whether the param is a dynamic object reader
@return: True if the parameter is a dynamic object
@rtype: Bool
"""
return self._is_dynamic_object
return self._dynamic_object is not None and (not self._dynamic_object._is_writer)
def meta_copy(self, src):
""" Copy meta data of a ParamValue
@ -232,10 +254,10 @@ class ParamBase():
self._example_values = src._example_values
self._tag = src._tag
self._is_required = src._is_required
self._is_dynamic_object = src._is_dynamic_object
self._dynamic_object = src._dynamic_object
self._content_type = src.content_type
self._is_quoted = src.is_quoted
self._param_name = src._param_name
def set_fuzzable(self, is_fuzzable):
""" Sets param as fuzzable
@ -261,6 +283,28 @@ class ParamBase():
"""
self._example_values = example_values
def set_dynamic_object(self, dynamic_object):
""" Sets dynamic object
@param is_fuzzable: True if fuzzable
@type is_fuzzable: Bool
@return: None
@rtype : None
"""
self._dynamic_object = dynamic_object
def set_param_name(self, param_name):
""" Sets the parameter name for this parameter
@return: None
@rtype : None
"""
self._param_name = param_name
def set_content_type(self, content_type):
""" Sets the content type of the parameter
@ -294,14 +338,14 @@ class ParamValue(ParamBase):
""" Base class for value type parameters. Value can be Object, Array,
String, Number, Boolean, ObjectLeaf, and Enum.
"""
def __init__(self, custom_payload_type=None, is_required=True, is_dynamic_object=False, is_quoted=False):
def __init__(self, custom_payload_type=None, is_required=True, dynamic_object=None, is_quoted=False):
""" Initialize a ParamValue.
@return: None
@rtype: None
"""
ParamBase.__init__(self, is_required=is_required, is_dynamic_object=is_dynamic_object, is_quoted=is_quoted)
ParamBase.__init__(self, is_required=is_required, dynamic_object=dynamic_object, is_quoted=is_quoted)
self._content = None
self._custom_payload_type = custom_payload_type
@ -383,7 +427,7 @@ class ParamValue(ParamBase):
raise Exception(f"Unknown custom payload type: {self._custom_payload_type}")
content = self._content
if self.is_dynamic_object:
if self.is_dynamic_object_reader:
content = dependencies.RDELIM + self._content + dependencies.RDELIM
return [primitives.restler_static_string(content)]
@ -820,7 +864,8 @@ class ParamArray(ParamBase):
class ParamString(ParamValue):
""" Class for string type parameters """
def __init__(self, custom_payload_type=None, is_required=True, is_dynamic_object=False, is_quoted=True, content_type="String"):
def __init__(self, custom_payload_type=None, is_required=True, dynamic_object=None, is_quoted=True,
content_type="String"):
""" Initialize a string type parameter
@param custom: Whether or not this is a custom payload
@ -830,7 +875,7 @@ class ParamString(ParamValue):
@rtype: None
"""
ParamValue.__init__(self, is_required=is_required, is_dynamic_object=is_dynamic_object, is_quoted=is_quoted)
ParamValue.__init__(self, is_required=is_required, dynamic_object=dynamic_object, is_quoted=is_quoted)
self._custom_payload_type=custom_payload_type
self._content_type = content_type
@ -861,11 +906,9 @@ class ParamString(ParamValue):
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)]
elif self._custom_payload_type == "UuidSuffix":
return [primitives.restler_custom_payload_uuid4_suffix(self._content)]
else:
raise Exception(f"Unexpected custom payload type: {self._custom_payload_type}")
if self.is_dynamic_object:
if self.is_dynamic_object_reader:
content = dependencies.RDELIM + self._content + dependencies.RDELIM
else:
content = self._content
@ -880,29 +923,42 @@ class ParamString(ParamValue):
"""
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)]
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)]
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)]
elif self._custom_payload_type == "UuidSuffix":
return [primitives.restler_custom_payload_uuid4_suffix(self._content)]
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:
if self.is_dynamic_object_reader:
content = dependencies.RDELIM + self._content + dependencies.RDELIM
else:
content = self._content
if self.is_fuzzable:
if self._content_type == "String":
return [primitives.restler_fuzzable_string(content, quoted=self.is_quoted, examples=self.example_values)]
return [primitives.restler_fuzzable_string(content, quoted=self.is_quoted, examples=self.example_values,
param_name=self.param_name,
writer=self.dynamic_object_writer_variable)]
elif self._content_type == "Uuid":
return [primitives.restler_fuzzable_uuid4(content, quoted=self.is_quoted, examples=self.example_values)]
return [primitives.restler_fuzzable_uuid4(content, quoted=self.is_quoted, examples=self.example_values,
param_name=self.param_name,
writer=self.dynamic_object_writer_variable)]
elif self._content_type == "DateTime":
return [primitives.restler_fuzzable_datetime(content, quoted=self.is_quoted, examples=self.example_values)]
return [primitives.restler_fuzzable_datetime(content, quoted=self.is_quoted,
examples=self.example_values,
param_name=self.param_name,
writer=self.dynamic_object_writer_variable)]
elif self._content_type == "Date":
return [primitives.restler_fuzzable_date(content, quoted=self.is_quoted, examples=self.example_values)]
return [primitives.restler_fuzzable_date(content, quoted=self.is_quoted, examples=self.example_values,
param_name=self.param_name,
writer=self.dynamic_object_writer_variable)]
else:
raise Exception(f"Unexpected content type: {self._content_type}")
@ -951,7 +1007,7 @@ class ParamString(ParamValue):
return [primitives.restler_static_string(default_value, quoted=False)]
if not self.is_fuzzable:
if self.is_dynamic_object:
if self.is_dynamic_object_reader:
content = dependencies.RDELIM + self._content + dependencies.RDELIM
return [primitives.restler_static_string(content, quoted=self.is_quoted)]
return [primitives.restler_static_string(default_value, quoted=self.is_quoted)]
@ -999,7 +1055,10 @@ class ParamUuidSuffix(ParamString):
@rtype : List[str]
"""
return [primitives.restler_custom_payload_uuid4_suffix(self._content)]
return [primitives.restler_custom_payload_uuid4_suffix(self._content,
quoted=self.is_quoted,
param_name=self.param_name,
writer=self.dynamic_object_writer_variable)]
def get_blocks(self, config=None):
""" Gets request blocks for Uuid Suffix Parameters.
@ -1011,9 +1070,21 @@ class ParamUuidSuffix(ParamString):
return self.get_original_blocks(config)
class DynamicObject:
""" Class for dynamic object variables """
def __init__(self, primitive_type, variable_name, is_writer):
self._primitive_type = primitive_type
self._variable_name = variable_name
self._is_writer = is_writer
@property
def is_writer(self):
return self._is_writer
class ParamNumber(ParamValue):
""" Class for number type parameters """
def __init__(self, is_required=True, is_dynamic_object=False, is_quoted=False, number_type="Int"):
def __init__(self, is_required=True, dynamic_object=None, is_quoted=False, number_type="Int"):
""" Initialize a number type parameter
@param custom: Whether or not this is a custom payload
@ -1023,7 +1094,7 @@ class ParamNumber(ParamValue):
@rtype: None
"""
ParamValue.__init__(self, is_required=is_required, is_dynamic_object=is_dynamic_object, is_quoted=is_quoted)
ParamValue.__init__(self, is_required=is_required, dynamic_object=dynamic_object, is_quoted=is_quoted)
self._number_type = number_type
@property
@ -1041,15 +1112,20 @@ class ParamNumber(ParamValue):
@rtype : List[str]
"""
if self.is_dynamic_object:
if self.is_dynamic_object_reader:
content = dependencies.RDELIM + self._content + dependencies.RDELIM
return [primitives.restler_static_string(content)]
content = self._content
if self._number_type == "Int":
return [primitives.restler_fuzzable_int(content, quoted=self.is_quoted, examples=self.example_values)]
return [primitives.restler_fuzzable_int(content, quoted=self.is_quoted,
examples=self.example_values,
param_name=self.param_name,
writer=self.dynamic_object_writer_variable)]
else:
return [primitives.restler_fuzzable_number(content, quoted=self.is_quoted, examples=self.example_values)]
return [primitives.restler_fuzzable_number(content, quoted=self.is_quoted, examples=self.example_values,
param_name=self.param_name,
writer=self.dynamic_object_writer_variable)]
def get_fuzzing_blocks(self, config):
@ -1066,7 +1142,7 @@ class ParamNumber(ParamValue):
default_value = str(default_value)
if not self.is_fuzzable:
if self.is_dynamic_object:
if self.is_dynamic_object_reader:
default_value = dependencies.RDELIM + default_value + dependencies.RDELIM
return [primitives.restler_static_string(default_value)]
@ -1118,12 +1194,13 @@ class ParamBoolean(ParamValue):
@rtype : List[str]
"""
if self.is_dynamic_object:
if self.is_dynamic_object_reader:
content = dependencies.RDELIM + self._content + dependencies.RDELIM
return [primitives.restler_static_string(content)]
return [primitives.restler_fuzzable_bool(self._content, quoted=self.is_quoted, examples=self.example_values)]
return [primitives.restler_fuzzable_bool(self._content, quoted=self.is_quoted, examples=self.example_values,
param_name=self.param_name,
writer=self.dynamic_object_writer_variable)]
def get_fuzzing_blocks(self, config):
""" Returns the fuzzing request blocks per the config
@ -1138,7 +1215,7 @@ class ParamBoolean(ParamValue):
)
if not self.is_fuzzable:
if self.is_dynamic_object:
if self.is_dynamic_object_reader:
default_value = dependencies.RDELIM + default_value + dependencies.RDELIM
else:
default_value = str(default_value).lower()
@ -1192,7 +1269,7 @@ class ParamObjectLeaf(ParamValue):
@rtype : List[str]
"""
if self.is_dynamic_object:
if self.is_dynamic_object_reader:
content = dependencies.RDELIM + self._content + dependencies.RDELIM
return [primitives.restler_static_string(content)]
@ -1212,14 +1289,21 @@ class ParamObjectLeaf(ParamValue):
@rtype : List[str]
"""
if self.is_dynamic_object:
if self.is_dynamic_object_reader:
content = dependencies.RDELIM + self._content + dependencies.RDELIM
return [primitives.restler_static_string(content)]
formalized_content = self._content.replace("'", '"')
formalized_content = formalized_content.replace('u"', '"')
# This check is present to support older grammars, and can be removed in the future.
if self._content is None:
formalized_content = "null"
else:
formalized_content = self._content.replace("'", '"')
formalized_content = formalized_content.replace('u"', '"')
return [primitives.restler_fuzzable_object(formalized_content, quoted=self.is_quoted, examples=self.example_values)]
return [primitives.restler_fuzzable_object(formalized_content, quoted=self.is_quoted,
examples=self.example_values,
param_name=self.param_name,
writer=self.dynamic_object_writer_variable)]
def get_fuzzing_blocks(self, config):
""" Returns the fuzzing request blocks per the config
@ -1249,7 +1333,7 @@ class ParamObjectLeaf(ParamValue):
# not fuzzalbe --> constant
if not self.is_fuzzable:
if self.is_dynamic_object:
if self.is_dynamic_object_reader:
default_value = dependencies.RDELIM + default_value + dependencies.RDELIM
else:
default_value = formalize_object_value(default_value)
@ -1291,7 +1375,8 @@ class ParamObjectLeaf(ParamValue):
class ParamEnum(ParamValue):
""" Class for Enum type parameters """
def __init__(self, contents, content_type, is_required=True, body_param=True, is_dynamic_object=False,
def __init__(self, contents, content_type, is_quoted=False,
is_required=True, body_param=True, is_dynamic_object=False,
enum_name=FUZZABLE_GROUP_TAG):
""" Initialize an Enum type parameter
@ -1308,7 +1393,7 @@ class ParamEnum(ParamValue):
self._contents = contents
self._type = content_type
self._is_quoted = body_param
self._is_quoted = is_quoted
self._enum_name = enum_name
@property
@ -1362,8 +1447,11 @@ class ParamEnum(ParamValue):
@rtype : List[str]
"""
return [primitives.restler_fuzzable_group(self._enum_name, self._get_fuzzable_group_values(),
quoted=self.is_quoted, examples=self.example_values)]
return [primitives.restler_fuzzable_group(self._enum_name,
self._contents,
quoted=self.is_quoted, examples=self.example_values,
param_name=self.param_name,
writer=self.dynamic_object_writer_variable)]
def get_blocks(self, config=None):
""" Gets request blocks for the Enum Parameters
@ -1372,7 +1460,8 @@ class ParamEnum(ParamValue):
@rtype : List[str]
"""
return [primitives.restler_fuzzable_group(FUZZABLE_GROUP_TAG, self._get_fuzzable_group_values(),
return [primitives.restler_fuzzable_group(FUZZABLE_GROUP_TAG,
self._get_fuzzable_group_values(),
quoted=self.is_quoted, examples=self.example_values)]
def get_fuzzing_pool(self, fuzzer, config):

Просмотреть файл

@ -87,6 +87,14 @@ def des_request_param_payload(request_param_payload_json):
return [KeyPayload(None, None)]
def des_dynamic_object(dynobj_json_grammar):
"""Parses dynamic object variable information from the grammar json"""
primitive_type = dynobj_json_grammar['primitiveType']
variable_name = dynobj_json_grammar['variableName']
is_writer = dynobj_json_grammar['isWriter']
return DynamicObject(primitive_type, variable_name, is_writer)
def des_param_payload(param_payload_json, tag='', body_param=True):
""" Deserialize ParameterPayload type object.
@ -102,6 +110,7 @@ def des_param_payload(param_payload_json, tag='', body_param=True):
"""
param = None
STRING_CONTENT_TYPES = ['String', 'Uuid', 'DateTime', 'Date']
if 'InternalNode' in param_payload_json:
internal_node = param_payload_json['InternalNode']
@ -176,39 +185,43 @@ def des_param_payload(param_payload_json, tag='', body_param=True):
content_type = 'Unknown'
content_value = 'Unknown'
param_name = None
example_values = []
custom_payload_type = None
fuzzable = False
is_dynamic_object = False
dynamic_object = None
if 'Fuzzable' in payload:
content_type = payload['Fuzzable']['primitiveType']
content_value = payload['Fuzzable']['defaultValue']
if 'exampleValue' in payload['Fuzzable']:
example_values = [payload['Fuzzable']['exampleValue']]
# Workaround for the way null values are serialized to the example
example_value = payload['Fuzzable']['exampleValue']
if 'Some' in example_value and example_value['Some'] == None:
example_value = None
example_values = [example_value]
if 'dynamicObject' in payload['Fuzzable']:
dynamic_object = des_dynamic_object(payload['Fuzzable']['dynamicObject'])
if 'parameterName' in payload['Fuzzable']:
param_name = payload['Fuzzable']['parameterName']
fuzzable = True
elif 'Constant' in payload:
content_type = payload['Constant'][0]
content_value = payload['Constant'][1]
elif 'DynamicObject' in payload:
content_type = payload['DynamicObject']['primitiveType']
content_value = payload['DynamicObject']['variableName']
is_dynamic_object = True
dynamic_object = des_dynamic_object(payload['DynamicObject'])
content_type = dynamic_object._primitive_type
content_value = dynamic_object._variable_name
elif 'Custom' in payload:
content_type = payload['Custom']['primitiveType']
content_value = payload['Custom']['payloadValue']
custom_payload_type = payload['Custom']['payloadType']
# TODO: these dynamic objects are not yet supported in the schema.
# This dictionary is currently not used, and will be used once
# dynamic objects are added to the schema types below (ParamValue, etc.).
dynamic_object_input_variable=None
if 'dynamicObject' in payload['Custom']:
dynamic_object_input_variable={}
dynamic_object_input_variable['content_type'] = payload['Custom']['dynamicObject']['primitiveType']
dynamic_object_input_variable['content_value'] = payload['Custom']['dynamicObject']['variableName']
dynamic_object = des_dynamic_object(payload['Custom']['dynamicObject'])
elif 'PayloadParts' in payload:
# Note: 'PayloadParts' is no longer supported in the compiler.
# This code is present to support old grammars, and should be
# removed with an exception to recompile in the future.
definition = payload['PayloadParts'][-1]
if 'Custom' in definition:
content_type = definition['Custom']['primitiveType']
@ -217,24 +230,28 @@ def des_param_payload(param_payload_json, tag='', body_param=True):
# create value w.r.t. the type
value = None
if content_type in ['String', 'Uuid', 'DateTime', 'Date']:
if content_type in STRING_CONTENT_TYPES:
# Query or header parameter values should not be quoted
is_quoted = body_param
value = ParamString(custom_payload_type=custom_payload_type, is_required=is_required,
is_dynamic_object=is_dynamic_object, is_quoted=is_quoted, content_type=content_type)
if custom_payload_type == "UuidSuffix":
# Set as unknown for payload body fuzzing purposes.
# This will be fuzzed as a string.
value = ParamUuidSuffix(is_required=is_required, dynamic_object=dynamic_object,
is_quoted=is_quoted,
content_type=content_type)
value.set_unknown()
else:
value = ParamString(custom_payload_type=custom_payload_type, is_required=is_required,
dynamic_object=dynamic_object, is_quoted=is_quoted, content_type=content_type)
elif content_type == 'Int':
value = ParamNumber(is_required=is_required, is_dynamic_object=is_dynamic_object, number_type=content_type)
value = ParamNumber(is_required=is_required, dynamic_object=dynamic_object, number_type=content_type)
elif content_type == 'Number':
value = ParamNumber(is_required=is_required, is_dynamic_object=is_dynamic_object, number_type=content_type)
value = ParamNumber(is_required=is_required, dynamic_object=dynamic_object, number_type=content_type)
elif content_type == 'Bool':
value = ParamBoolean(is_required=is_required, is_dynamic_object=is_dynamic_object)
value = ParamBoolean(is_required=is_required, dynamic_object=dynamic_object)
elif content_type == 'Object':
value = ParamObjectLeaf(is_required=is_required, is_dynamic_object=is_dynamic_object)
elif custom_payload_type is not None and custom_payload_type == 'UuidSuffix':
value = ParamUuidSuffix(is_required=is_required)
# Set as unknown for payload body fuzzing purposes.
# This will be fuzzed as a string.
value.set_unknown()
value = ParamObjectLeaf(is_required=is_required, 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
@ -254,15 +271,23 @@ def des_param_payload(param_payload_json, tag='', body_param=True):
enum_name = enum_definition[0]
enum_content_type = enum_definition[1]
contents = enum_definition[2]
value = ParamEnum(contents, enum_content_type, is_required=is_required, body_param=body_param, enum_name=enum_name)
# Get quoting depending on the type
if enum_content_type in STRING_CONTENT_TYPES:
is_quoted = body_param
else:
is_quoted = False
value = ParamEnum(contents, enum_content_type, is_quoted=is_quoted,
is_required=is_required, body_param=body_param, enum_name=enum_name)
else:
logger.write_to_main(f'Unexpected enum schema {name}')
else:
value = ParamString(False, is_required=is_required, is_dynamic_object=is_dynamic_object)
value = ParamString()
value.set_unknown()
value.set_fuzzable(fuzzable)
value.set_example_values(example_values)
value.set_param_name(param_name)
value.set_dynamic_object(dynamic_object)
value.set_content_type(content_type)
value.content = content_value

Просмотреть файл

@ -470,6 +470,8 @@ class RestlerSettings(object):
self._disable_logging = SettingsArg('disable_logging', bool, False, user_args)
## Add current dates in addition to the ones specified in the dictionary
self._add_fuzzable_dates = SettingsArg('add_fuzzable_dates', bool, False, user_args)
## Indicates whether the user is allowed to modify the grammar.py that was automatically generated by RESTler.
self._allow_grammar_py_user_update = SettingsArg('allow_grammar_py_user_update', bool, True, user_args)
## The command to execute in order to refresh the authentication token
self._token_refresh_cmd = SettingsArg('token_refresh_cmd', str, None, user_args)
## Interval to periodically refresh the authentication token (seconds)
@ -679,6 +681,10 @@ class RestlerSettings(object):
def add_fuzzable_dates(self):
return self._add_fuzzable_dates.val
@property
def allow_grammar_py_user_update(self):
return self._allow_grammar_py_user_update.val
@property
def token_refresh_cmd(self):
return self._token_refresh_cmd.val

Просмотреть файл

@ -0,0 +1,662 @@
{
"Requests": [
{
"id": {
"endpoint": "/api/blog/posts",
"method": "Get"
},
"method": "Get",
"basePath": "",
"path": [
{
"Constant": [
"String",
"api"
]
},
{
"Constant": [
"String",
"blog"
]
},
{
"Constant": [
"String",
"posts"
]
}
],
"queryParameters": [
[
"Schema",
{
"ParameterList": [
{
"name": "page",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1"
}
},
"isRequired": false,
"isReadOnly": false
}
}
},
{
"name": "per_page",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1"
}
},
"isRequired": false,
"isReadOnly": false
}
}
}
]
}
]
],
"bodyParameters": [
[
"Schema",
{
"ParameterList": []
}
]
],
"headerParameters": [
[
"Schema",
{
"ParameterList": []
}
],
[
"DictionaryCustomPayload",
{
"ParameterList": []
}
]
],
"token": "Refreshable",
"headers": [
[
"Accept",
"application/json"
],
[
"Host",
"localhost:8888"
]
],
"httpVersion": "1.1",
"requestMetadata": {
"isLongRunningOperation": false
}
},
{
"id": {
"endpoint": "/api/blog/posts",
"method": "Post"
},
"method": "Post",
"basePath": "",
"path": [
{
"Constant": [
"String",
"api"
]
},
{
"Constant": [
"String",
"blog"
]
},
{
"Constant": [
"String",
"posts"
]
}
],
"queryParameters": [
[
"Schema",
{
"ParameterList": []
}
]
],
"bodyParameters": [
[
"Schema",
{
"ParameterList": [
{
"name": "__body__",
"payload": {
"InternalNode": [
{
"name": "",
"propertyType": "Object",
"isRequired": true,
"isReadOnly": false
},
[
{
"LeafNode": {
"name": "id",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1",
"exampleValue": "99"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "body",
"payload": {
"Fuzzable": {
"primitiveType": "String",
"defaultValue": "fuzzstring",
"exampleValue": "my first blog post"
}
},
"isRequired": true,
"isReadOnly": false
}
}
]
]
}
}
]
}
]
],
"headerParameters": [
[
"Schema",
{
"ParameterList": []
}
],
[
"DictionaryCustomPayload",
{
"ParameterList": [
{
"name": "Content-Type",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Constant": [
"String",
"application/json"
]
},
"isRequired": true,
"isReadOnly": false
}
}
}
]
}
]
],
"token": "Refreshable",
"headers": [
[
"Accept",
"application/json"
],
[
"Host",
"localhost:8888"
]
],
"httpVersion": "1.1",
"dependencyData": {
"responseParser": {
"writerVariables": [
{
"requestId": {
"endpoint": "/api/blog/posts",
"method": "Post"
},
"accessPathParts": {
"path": [
"body"
]
},
"primitiveType": "String",
"kind": "BodyResponseProperty"
},
{
"requestId": {
"endpoint": "/api/blog/posts",
"method": "Post"
},
"accessPathParts": {
"path": [
"id"
]
},
"primitiveType": "Int",
"kind": "BodyResponseProperty"
}
],
"headerWriterVariables": []
},
"inputWriterVariables": [],
"orderingConstraintWriterVariables": [],
"orderingConstraintReaderVariables": []
},
"requestMetadata": {
"isLongRunningOperation": false
}
},
{
"id": {
"endpoint": "/api/blog/posts/{postId}",
"method": "Get"
},
"method": "Get",
"basePath": "",
"path": [
{
"Constant": [
"String",
"api"
]
},
{
"Constant": [
"String",
"blog"
]
},
{
"Constant": [
"String",
"posts"
]
},
{
"DynamicObject": {
"primitiveType": "Int",
"variableName": "_api_blog_posts_post_id",
"isWriter": false
}
}
],
"queryParameters": [
[
"Schema",
{
"ParameterList": []
}
]
],
"bodyParameters": [
[
"Schema",
{
"ParameterList": []
}
]
],
"headerParameters": [
[
"Schema",
{
"ParameterList": []
}
],
[
"DictionaryCustomPayload",
{
"ParameterList": []
}
]
],
"token": "Refreshable",
"headers": [
[
"Accept",
"application/json"
],
[
"Host",
"localhost:8888"
]
],
"httpVersion": "1.1",
"requestMetadata": {
"isLongRunningOperation": false
}
},
{
"id": {
"endpoint": "/api/blog/posts/{postId}",
"method": "Put"
},
"method": "Put",
"basePath": "",
"path": [
{
"Constant": [
"String",
"api"
]
},
{
"Constant": [
"String",
"blog"
]
},
{
"Constant": [
"String",
"posts"
]
},
{
"DynamicObject": {
"primitiveType": "Int",
"variableName": "_api_blog_posts_post_id",
"isWriter": false
}
}
],
"queryParameters": [
[
"Schema",
{
"ParameterList": []
}
]
],
"bodyParameters": [
[
"Schema",
{
"ParameterList": [
{
"name": "__body__",
"payload": {
"InternalNode": [
{
"name": "",
"propertyType": "Object",
"isRequired": true,
"isReadOnly": false
},
[
{
"LeafNode": {
"name": "id",
"payload": {
"DynamicObject": {
"primitiveType": "Int",
"variableName": "_api_blog_posts_post_id",
"isWriter": false
}
},
"isRequired": false,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "body",
"payload": {
"DynamicObject": {
"primitiveType": "String",
"variableName": "_api_blog_posts_post_body",
"isWriter": false
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "checksum",
"payload": {
"Fuzzable": {
"primitiveType": "String",
"defaultValue": "fuzzstring",
"exampleValue": "abcde"
}
},
"isRequired": false,
"isReadOnly": false
}
}
]
]
}
}
]
}
]
],
"headerParameters": [
[
"Schema",
{
"ParameterList": []
}
],
[
"DictionaryCustomPayload",
{
"ParameterList": [
{
"name": "Content-Type",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Constant": [
"String",
"application/json"
]
},
"isRequired": true,
"isReadOnly": false
}
}
}
]
}
]
],
"token": "Refreshable",
"headers": [
[
"Accept",
"application/json"
],
[
"Host",
"localhost:8888"
]
],
"httpVersion": "1.1",
"requestMetadata": {
"isLongRunningOperation": false
}
},
{
"id": {
"endpoint": "/api/blog/posts/{postId}",
"method": "Delete"
},
"method": "Delete",
"basePath": "",
"path": [
{
"Constant": [
"String",
"api"
]
},
{
"Constant": [
"String",
"blog"
]
},
{
"Constant": [
"String",
"posts"
]
},
{
"DynamicObject": {
"primitiveType": "Int",
"variableName": "_api_blog_posts_post_id",
"isWriter": false
}
}
],
"queryParameters": [
[
"Schema",
{
"ParameterList": []
}
]
],
"bodyParameters": [
[
"Schema",
{
"ParameterList": []
}
]
],
"headerParameters": [
[
"Schema",
{
"ParameterList": []
}
],
[
"DictionaryCustomPayload",
{
"ParameterList": []
}
]
],
"token": "Refreshable",
"headers": [
[
"Accept",
"application/json"
],
[
"Host",
"localhost:8888"
]
],
"httpVersion": "1.1",
"requestMetadata": {
"isLongRunningOperation": false
}
},
{
"id": {
"endpoint": "/api/doc",
"method": "Get"
},
"method": "Get",
"basePath": "",
"path": [
{
"Constant": [
"String",
"api"
]
},
{
"Constant": [
"String",
"doc"
]
}
],
"queryParameters": [
[
"Schema",
{
"ParameterList": []
}
]
],
"bodyParameters": [
[
"Schema",
{
"ParameterList": []
}
]
],
"headerParameters": [
[
"Schema",
{
"ParameterList": []
}
],
[
"DictionaryCustomPayload",
{
"ParameterList": []
}
]
],
"token": "Refreshable",
"headers": [
[
"Accept",
"application/json"
],
[
"Host",
"localhost:8888"
]
],
"httpVersion": "1.1",
"requestMetadata": {
"isLongRunningOperation": false
}
}
]
}

Просмотреть файл

@ -0,0 +1,237 @@
""" THIS IS AN AUTOMATICALLY GENERATED FILE!"""
from __future__ import print_function
import json
from engine import primitives
from engine.core import requests
from engine.errors import ResponseParsingException
from engine import dependencies
_api_blog_posts_post_body = dependencies.DynamicVariable("_api_blog_posts_post_body")
_api_blog_posts_post_id = dependencies.DynamicVariable("_api_blog_posts_post_id")
def parse_apiblogpostspost(data, **kwargs):
""" Automatically generated response parser """
# Declare response variables
temp_7262 = None
temp_8173 = None
if 'headers' in kwargs:
headers = kwargs['headers']
# Parse body if needed
if data:
try:
data = json.loads(data)
except Exception as error:
raise ResponseParsingException("Exception parsing response, data was not valid json: {}".format(error))
pass
# Try to extract each dynamic object
try:
temp_7262 = str(data["body"])
except Exception as error:
# This is not an error, since some properties are not always returned
pass
try:
temp_8173 = str(data["id"])
except Exception as error:
# This is not an error, since some properties are not always returned
pass
# If no dynamic objects were extracted, throw.
if not (temp_7262 or temp_8173):
raise ResponseParsingException("Error: all of the expected dynamic objects were not present in the response.")
# Set dynamic variables
if temp_7262:
dependencies.set_variable("_api_blog_posts_post_body", temp_7262)
if temp_8173:
dependencies.set_variable("_api_blog_posts_post_id", temp_8173)
req_collection = requests.RequestCollection([])
# Endpoint: /api/blog/posts, method: Get
request = requests.Request([
primitives.restler_static_string("GET "),
primitives.restler_basepath(""),
primitives.restler_static_string("/"),
primitives.restler_static_string("api"),
primitives.restler_static_string("/"),
primitives.restler_static_string("blog"),
primitives.restler_static_string("/"),
primitives.restler_static_string("posts"),
primitives.restler_static_string("?"),
primitives.restler_static_string("page="),
primitives.restler_fuzzable_int("1"),
primitives.restler_static_string("&"),
primitives.restler_static_string("per_page="),
primitives.restler_fuzzable_int("1"),
primitives.restler_static_string(" HTTP/1.1\r\n"),
primitives.restler_static_string("Accept: application/json\r\n"),
primitives.restler_static_string("Host: localhost:8888\r\n"),
primitives.restler_refreshable_authentication_token("authentication_token_tag"),
primitives.restler_static_string("\r\n"),
],
requestId="/api/blog/posts"
)
req_collection.add_request(request)
# Endpoint: /api/blog/posts, method: Post
request = requests.Request([
primitives.restler_static_string("POST "),
primitives.restler_basepath(""),
primitives.restler_static_string("/"),
primitives.restler_static_string("api"),
primitives.restler_static_string("/"),
primitives.restler_static_string("blog"),
primitives.restler_static_string("/"),
primitives.restler_static_string("posts"),
primitives.restler_static_string(" HTTP/1.1\r\n"),
primitives.restler_static_string("Accept: application/json\r\n"),
primitives.restler_static_string("Host: localhost:8888\r\n"),
primitives.restler_static_string("Content-Type: "),
primitives.restler_static_string("application/json"),
primitives.restler_static_string("\r\n"),
primitives.restler_refreshable_authentication_token("authentication_token_tag"),
primitives.restler_static_string("\r\n"),
primitives.restler_static_string("{"),
primitives.restler_static_string("""
"id":"""),
primitives.restler_fuzzable_int("1", examples=["99"]),
primitives.restler_static_string(""",
"body":"""),
primitives.restler_fuzzable_string("fuzzstring", quoted=True, examples=["my first blog post"]),
primitives.restler_static_string("}"),
primitives.restler_static_string("\r\n"),
{
'post_send':
{
'parser': parse_apiblogpostspost,
'dependencies':
[
_api_blog_posts_post_body.writer(),
_api_blog_posts_post_id.writer()
]
}
},
],
requestId="/api/blog/posts"
)
req_collection.add_request(request)
# Endpoint: /api/blog/posts/{postId}, method: Get
request = requests.Request([
primitives.restler_static_string("GET "),
primitives.restler_basepath(""),
primitives.restler_static_string("/"),
primitives.restler_static_string("api"),
primitives.restler_static_string("/"),
primitives.restler_static_string("blog"),
primitives.restler_static_string("/"),
primitives.restler_static_string("posts"),
primitives.restler_static_string("/"),
primitives.restler_static_string(_api_blog_posts_post_id.reader(), quoted=False),
primitives.restler_static_string(" HTTP/1.1\r\n"),
primitives.restler_static_string("Accept: application/json\r\n"),
primitives.restler_static_string("Host: localhost:8888\r\n"),
primitives.restler_refreshable_authentication_token("authentication_token_tag"),
primitives.restler_static_string("\r\n"),
],
requestId="/api/blog/posts/{postId}"
)
req_collection.add_request(request)
# Endpoint: /api/blog/posts/{postId}, method: Put
request = requests.Request([
primitives.restler_static_string("PUT "),
primitives.restler_basepath(""),
primitives.restler_static_string("/"),
primitives.restler_static_string("api"),
primitives.restler_static_string("/"),
primitives.restler_static_string("blog"),
primitives.restler_static_string("/"),
primitives.restler_static_string("posts"),
primitives.restler_static_string("/"),
primitives.restler_static_string(_api_blog_posts_post_id.reader(), quoted=False),
primitives.restler_static_string(" HTTP/1.1\r\n"),
primitives.restler_static_string("Accept: application/json\r\n"),
primitives.restler_static_string("Host: localhost:8888\r\n"),
primitives.restler_static_string("Content-Type: "),
primitives.restler_static_string("application/json"),
primitives.restler_static_string("\r\n"),
primitives.restler_refreshable_authentication_token("authentication_token_tag"),
primitives.restler_static_string("\r\n"),
primitives.restler_static_string("{"),
primitives.restler_static_string("""
"id":"""),
primitives.restler_static_string(_api_blog_posts_post_id.reader(), quoted=False),
primitives.restler_static_string(""",
"body":"""),
primitives.restler_static_string(_api_blog_posts_post_body.reader(), quoted=True),
primitives.restler_static_string(""",
"checksum":"""),
primitives.restler_fuzzable_string("fuzzstring", quoted=True, examples=["abcde"]),
primitives.restler_static_string("}"),
primitives.restler_static_string("\r\n"),
],
requestId="/api/blog/posts/{postId}"
)
req_collection.add_request(request)
# Endpoint: /api/blog/posts/{postId}, method: Delete
request = requests.Request([
primitives.restler_static_string("DELETE "),
primitives.restler_basepath(""),
primitives.restler_static_string("/"),
primitives.restler_static_string("api"),
primitives.restler_static_string("/"),
primitives.restler_static_string("blog"),
primitives.restler_static_string("/"),
primitives.restler_static_string("posts"),
primitives.restler_static_string("/"),
primitives.restler_static_string(_api_blog_posts_post_id.reader(), quoted=False),
primitives.restler_static_string(" HTTP/1.1\r\n"),
primitives.restler_static_string("Accept: application/json\r\n"),
primitives.restler_static_string("Host: localhost:8888\r\n"),
primitives.restler_refreshable_authentication_token("authentication_token_tag"),
primitives.restler_static_string("\r\n"),
],
requestId="/api/blog/posts/{postId}"
)
req_collection.add_request(request)
# Endpoint: /api/doc, method: Get
request = requests.Request([
primitives.restler_static_string("GET "),
primitives.restler_basepath(""),
primitives.restler_static_string("/"),
primitives.restler_static_string("api"),
primitives.restler_static_string("/"),
primitives.restler_static_string("doc"),
primitives.restler_static_string(" HTTP/1.1\r\n"),
primitives.restler_static_string("Accept: application/json\r\n"),
primitives.restler_static_string("Host: localhost:8888\r\n"),
primitives.restler_refreshable_authentication_token("authentication_token_tag"),
primitives.restler_static_string("\r\n"),
],
requestId="/api/doc"
)
req_collection.add_request(request)

Просмотреть файл

@ -26,10 +26,11 @@
"LeafNode": {
"name": "",
"payload": {
"Constant": [
"String",
"zzz"
]
"Fuzzable": {
"primitiveType": "String",
"defaultValue": "fuzzstring",
"exampleValue": "zzz"
}
},
"isRequired": true,
"isReadOnly": false
@ -83,10 +84,11 @@
"LeafNode": {
"name": "id",
"payload": {
"Constant": [
"String",
"zzz"
]
"Fuzzable": {
"primitiveType": "String",
"defaultValue": "fuzzstring",
"exampleValue": "zzz"
}
},
"isRequired": false,
"isReadOnly": false
@ -114,10 +116,11 @@
"LeafNode": {
"name": "name",
"payload": {
"Constant": [
"String",
"zzz"
]
"Fuzzable": {
"primitiveType": "String",
"defaultValue": "fuzzstring",
"exampleValue": "zzz"
}
},
"isRequired": true,
"isReadOnly": false
@ -127,10 +130,13 @@
"LeafNode": {
"name": "address",
"payload": {
"Constant": [
"Object",
null
]
"Fuzzable": {
"primitiveType": "Object",
"defaultValue": "{ \"fuzz\": false }",
"exampleValue": {
"Some": null
}
}
},
"isRequired": true,
"isReadOnly": false
@ -246,10 +252,11 @@
"LeafNode": {
"name": "",
"payload": {
"Constant": [
"String",
"zzz"
]
"Fuzzable": {
"primitiveType": "String",
"defaultValue": "fuzzstring",
"exampleValue": "zzz"
}
},
"isRequired": false,
"isReadOnly": false

Просмотреть файл

@ -54,12 +54,12 @@ request = requests.Request([
primitives.restler_static_string("customer"),
primitives.restler_static_string("?"),
primitives.restler_static_string("api-version="),
primitives.restler_static_string("zzz"),
primitives.restler_fuzzable_string("fuzzstring", quoted=False, examples=["zzz"]),
primitives.restler_static_string(" HTTP/1.1\r\n"),
primitives.restler_static_string("Accept: application/json\r\n"),
primitives.restler_static_string("Host: \r\n"),
primitives.restler_static_string("schema-version: "),
primitives.restler_static_string("zzz"),
primitives.restler_fuzzable_string("fuzzstring", quoted=False, examples=["zzz"]),
primitives.restler_static_string("\r\n"),
primitives.restler_static_string("Content-Type: "),
primitives.restler_static_string("application/json"),
@ -68,11 +68,17 @@ request = requests.Request([
primitives.restler_static_string("\r\n"),
primitives.restler_static_string("{"),
primitives.restler_static_string("""
"id":"zzz",
"id":"""),
primitives.restler_fuzzable_string("fuzzstring", quoted=True, examples=["zzz"]),
primitives.restler_static_string(""",
"Person":
{
"name":"zzz",
"address":null
"name":"""),
primitives.restler_fuzzable_string("fuzzstring", quoted=True, examples=["zzz"]),
primitives.restler_static_string(""",
"address":"""),
primitives.restler_fuzzable_object("{ \"fuzz\": false }", examples=[None]),
primitives.restler_static_string("""
}
}"""),
primitives.restler_static_string("\r\n"),

Просмотреть файл

@ -0,0 +1,263 @@
{
"swagger": "2.0",
"info": {
"title": "Simple Swagger with all parameter data types",
"version": "1",
"description": "Covers parameter types x data types x dependency types (with annotation file)"
},
"paths": {
"/customer": {
"post": {
"operationId": "post_customer",
"parameters": [
{
"$ref": "#/parameters/StringQueryParameter"
},
{
"$ref": "#/parameters/StringDateQueryParameter"
},
{
"$ref": "#/parameters/StringDateTimeQueryParameter"
},
{
"$ref": "#/parameters/StringPasswordQueryParameter"
},
{
"$ref": "#/parameters/StringByteQueryParameter"
},
{
"$ref": "#/parameters/StringBinaryQueryParameter"
},
{
"$ref": "#/parameters/ObjectQueryParameter"
},
{
"$ref": "#/parameters/IntQueryParameter"
},
{
"$ref": "#/parameters/Int32QueryParameter"
},
{
"$ref": "#/parameters/Int64QueryParameter"
},
{
"$ref": "#/parameters/FloatNumberQueryParameter"
},
{
"$ref": "#/parameters/DoubleNumberQueryParameter"
},
{
"$ref": "#/parameters/BooleanQueryParameter"
},
{
"name": "body",
"required": true,
"in": "body",
"schema": {
"$ref": "#/definitions/Customer"
}
}
],
"responses": {
"201": {
"description": "Success",
"schema": {
"$ref": "#/definitions/Customer"
}
}
}
}
},
"/customer/{customerId}": {
"get": {
"operationId": "post_customer",
"parameters": [
{
"name": "customerId",
"type": "string",
"in": "path",
"required": true
},
{
"name": "string-enum-header-param",
"type": "string",
"enum": [
"enum_header_val_1",
"enum_header_val_2"
],
"in": "header",
"required": true
}
],
"responses": {
"201": {
"description": "Success",
"schema": {
"$ref": "#/definitions/Customer"
}
}
}
}
}
},
"definitions": {
"Customer": {
"properties": {
"id": {
"type": "string"
},
"Person": {
"$ref": "#/definitions/ParameterTests"
}
},
"required": [
"id",
"Person"
]
},
"ParameterTests": {
"properties": {
"int32-body-param": {
"type": "integer",
"format": "int32"
},
"int64-body-param": {
"type": "integer",
"format": "int64"
},
"int-body-param": {
"type": "integer"
},
"obj-body-param": {
"type": "object"
},
"string-enum-body-param": {
"type": ["string"],
"enum": [
"enum_body_val_1",
"enum_body_val_2"
]
},
"int-enum-body-param": {
"type": "integer",
"enum": [
1024,
512
]
},
"string-enum-null-body-param": {
"type": "string",
"enum": [
"A",
"B"
]
}
},
"required": [
"string-enum-body-param",
"int-enum-body-param",
"string-enum-null-body-param",
"int-body-param",
"int32-body-param",
"int64-body-param",
"obj-body-param"
]
}
},
"parameters": {
"StringQueryParameter": {
"name": "string-query-param",
"in": "query",
"type": "string",
"required": true
},
"StringDateQueryParameter": {
"name": "string-date-query-param",
"in": "query",
"type": "string",
"format": "date",
"required": true
},
"StringDateTimeQueryParameter": {
"name": "string-date-time-query-param",
"in": "query",
"type": "string",
"format": "date-time",
"required": true
},
"StringPasswordQueryParameter": {
"name": "string-password-query-param",
"in": "query",
"type": "string",
"format": "password",
"required": true
},
"StringByteQueryParameter": {
"name": "string-password-query-param",
"in": "query",
"type": "string",
"format": "byte",
"required": true
},
"StringBinaryQueryParameter": {
"name": "string-password-query-param",
"in": "query",
"type": "string",
"format": "binary",
"required": true
},
"ObjectQueryParameter": {
"name": "string-password-query-param",
"in": "query",
"type": "object",
"required": true
},
"IntQueryParameter": {
"name": "string-password-query-param",
"in": "query",
"type": "integer",
"required": true
},
"Int32QueryParameter": {
"name": "string-password-query-param",
"in": "query",
"type": "integer",
"format": "int32",
"required": true
},
"Int64QueryParameter": {
"name": "string-password-query-param",
"in": "query",
"type": "integer",
"format": "int64",
"required": true
},
"NumberQueryParameter": {
"name": "number-query-param",
"in": "query",
"type": "number",
"required": true
},
"FloatNumberQueryParameter": {
"name": "float-number-query-param",
"in": "query",
"type": "number",
"format": "float",
"required": true
},
"DoubleNumberQueryParameter": {
"name": "double-number-query-param",
"in": "query",
"type": "number",
"format": "double",
"required": true
},
"BooleanQueryParameter": {
"name": "boolean-query-param",
"in": "query",
"type": "boolean",
"required": true
}
}
}

Просмотреть файл

@ -0,0 +1,487 @@
{
"Requests": [
{
"id": {
"endpoint": "/customer",
"method": "Post"
},
"method": "Post",
"basePath": "",
"path": [
{
"Constant": [
"String",
"customer"
]
}
],
"queryParameters": [
[
"Schema",
{
"ParameterList": [
{
"name": "string-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "String",
"defaultValue": "fuzzstring"
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "string-date-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "Date",
"defaultValue": "2019-06-26"
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "string-date-time-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "DateTime",
"defaultValue": "2019-06-26T20:20:39+00:00"
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "string-password-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "String",
"defaultValue": "fuzzstring"
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "float-number-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "Number",
"defaultValue": "1.23"
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "double-number-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "Number",
"defaultValue": "1.23"
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "boolean-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "Bool",
"defaultValue": "true"
}
},
"isRequired": true,
"isReadOnly": false
}
}
}
]
}
]
],
"bodyParameters": [
[
"Schema",
{
"ParameterList": [
{
"name": "body",
"payload": {
"InternalNode": [
{
"name": "",
"propertyType": "Object",
"isRequired": true,
"isReadOnly": false
},
[
{
"LeafNode": {
"name": "id",
"payload": {
"Fuzzable": {
"primitiveType": "String",
"defaultValue": "fuzzstring"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"InternalNode": [
{
"name": "Person",
"propertyType": "Property",
"isRequired": true,
"isReadOnly": false
},
[
{
"InternalNode": [
{
"name": "",
"propertyType": "Object",
"isRequired": true,
"isReadOnly": false
},
[
{
"LeafNode": {
"name": "int32-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "int64-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "int-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "obj-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Object",
"defaultValue": "{ \"fuzz\": false }"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "string-enum-body-param",
"payload": {
"Fuzzable": {
"primitiveType": {
"Enum": [
"string-enum-body-param",
"String",
[
"enum_body_val_1",
"enum_body_val_2"
],
null
]
},
"defaultValue": "enum_body_val_1"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "int-enum-body-param",
"payload": {
"Fuzzable": {
"primitiveType": {
"Enum": [
"int-enum-body-param",
"Int",
[
"1024",
"512"
],
null
]
},
"defaultValue": "1024"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "string-enum-null-body-param",
"payload": {
"Fuzzable": {
"primitiveType": {
"Enum": [
"string-enum-null-body-param",
"String",
[
"A",
"B"
],
null
]
},
"defaultValue": "A"
}
},
"isRequired": true,
"isReadOnly": false
}
}
]
]
}
]
]
}
]
]
}
}
]
}
]
],
"headerParameters": [
[
"Schema",
{
"ParameterList": []
}
],
[
"DictionaryCustomPayload",
{
"ParameterList": [
{
"name": "Content-Type",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Constant": [
"String",
"application/json"
]
},
"isRequired": true,
"isReadOnly": false
}
}
}
]
}
]
],
"token": "Refreshable",
"headers": [
[
"Accept",
"application/json"
],
[
"Host",
null
]
],
"httpVersion": "1.1",
"dependencyData": {
"responseParser": {
"writerVariables": [
{
"requestId": {
"endpoint": "/customer",
"method": "Post"
},
"accessPathParts": {
"path": [
"id"
]
},
"primitiveType": "String",
"kind": "BodyResponseProperty"
}
],
"headerWriterVariables": []
},
"inputWriterVariables": [],
"orderingConstraintWriterVariables": [],
"orderingConstraintReaderVariables": []
},
"requestMetadata": {
"isLongRunningOperation": false
}
},
{
"id": {
"endpoint": "/customer/{customerId}",
"method": "Get"
},
"method": "Get",
"basePath": "",
"path": [
{
"Constant": [
"String",
"customer"
]
},
{
"DynamicObject": {
"primitiveType": "String",
"variableName": "_customer_post_id",
"isWriter": false
}
}
],
"queryParameters": [
[
"Schema",
{
"ParameterList": []
}
]
],
"bodyParameters": [
[
"Schema",
{
"ParameterList": []
}
]
],
"headerParameters": [
[
"Schema",
{
"ParameterList": [
{
"name": "string-enum-header-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": {
"Enum": [
"string-enum-header-param",
"String",
[
"enum_header_val_1",
"enum_header_val_2"
],
null
]
},
"defaultValue": "enum_header_val_1"
}
},
"isRequired": true,
"isReadOnly": false
}
}
}
]
}
],
[
"DictionaryCustomPayload",
{
"ParameterList": []
}
]
],
"token": "Refreshable",
"headers": [
[
"Accept",
"application/json"
],
[
"Host",
null
]
],
"httpVersion": "1.1",
"requestMetadata": {
"isLongRunningOperation": false
}
}
]
}

Просмотреть файл

@ -0,0 +1,154 @@
""" THIS IS AN AUTOMATICALLY GENERATED FILE!"""
from __future__ import print_function
import json
from engine import primitives
from engine.core import requests
from engine.errors import ResponseParsingException
from engine import dependencies
_customer_post_id = dependencies.DynamicVariable("_customer_post_id")
def parse_customerpost(data, **kwargs):
""" Automatically generated response parser """
# Declare response variables
temp_7262 = None
if 'headers' in kwargs:
headers = kwargs['headers']
# Parse body if needed
if data:
try:
data = json.loads(data)
except Exception as error:
raise ResponseParsingException("Exception parsing response, data was not valid json: {}".format(error))
pass
# Try to extract each dynamic object
try:
temp_7262 = str(data["id"])
except Exception as error:
# This is not an error, since some properties are not always returned
pass
# If no dynamic objects were extracted, throw.
if not (temp_7262):
raise ResponseParsingException("Error: all of the expected dynamic objects were not present in the response.")
# Set dynamic variables
if temp_7262:
dependencies.set_variable("_customer_post_id", temp_7262)
req_collection = requests.RequestCollection([])
# Endpoint: /customer, method: Post
request = requests.Request([
primitives.restler_static_string("POST "),
primitives.restler_basepath(""),
primitives.restler_static_string("/"),
primitives.restler_static_string("customer"),
primitives.restler_static_string("?"),
primitives.restler_static_string("string-query-param="),
primitives.restler_fuzzable_string("fuzzstring", quoted=False),
primitives.restler_static_string("&"),
primitives.restler_static_string("string-date-query-param="),
primitives.restler_fuzzable_date("2019-06-26", quoted=False),
primitives.restler_static_string("&"),
primitives.restler_static_string("string-date-time-query-param="),
primitives.restler_fuzzable_datetime("2019-06-26T20:20:39+00:00", quoted=False),
primitives.restler_static_string("&"),
primitives.restler_static_string("string-password-query-param="),
primitives.restler_fuzzable_string("fuzzstring", quoted=False),
primitives.restler_static_string("&"),
primitives.restler_static_string("float-number-query-param="),
primitives.restler_fuzzable_number("1.23"),
primitives.restler_static_string("&"),
primitives.restler_static_string("double-number-query-param="),
primitives.restler_fuzzable_number("1.23"),
primitives.restler_static_string("&"),
primitives.restler_static_string("boolean-query-param="),
primitives.restler_fuzzable_bool("true"),
primitives.restler_static_string(" HTTP/1.1\r\n"),
primitives.restler_static_string("Accept: application/json\r\n"),
primitives.restler_static_string("Host: \r\n"),
primitives.restler_static_string("Content-Type: "),
primitives.restler_static_string("application/json"),
primitives.restler_static_string("\r\n"),
primitives.restler_refreshable_authentication_token("authentication_token_tag"),
primitives.restler_static_string("\r\n"),
primitives.restler_static_string("{"),
primitives.restler_static_string("""
"id":"""),
primitives.restler_fuzzable_string("fuzzstring", quoted=True),
primitives.restler_static_string(""",
"Person":
{
"int32-body-param":"""),
primitives.restler_fuzzable_int("1"),
primitives.restler_static_string(""",
"int64-body-param":"""),
primitives.restler_fuzzable_int("1"),
primitives.restler_static_string(""",
"int-body-param":"""),
primitives.restler_fuzzable_int("1"),
primitives.restler_static_string(""",
"obj-body-param":"""),
primitives.restler_fuzzable_object("{ \"fuzz\": false }"),
primitives.restler_static_string(""",
"string-enum-body-param":"""),
primitives.restler_fuzzable_group("string-enum-body-param", ['enum_body_val_1','enum_body_val_2'] ,quoted=True),
primitives.restler_static_string(""",
"int-enum-body-param":"""),
primitives.restler_fuzzable_group("int-enum-body-param", ['1024','512'] ,quoted=False),
primitives.restler_static_string(""",
"string-enum-null-body-param":"""),
primitives.restler_fuzzable_group("string-enum-null-body-param", ['A','B'] ,quoted=True),
primitives.restler_static_string("""
}
}"""),
primitives.restler_static_string("\r\n"),
{
'post_send':
{
'parser': parse_customerpost,
'dependencies':
[
_customer_post_id.writer()
]
}
},
],
requestId="/customer"
)
req_collection.add_request(request)
# Endpoint: /customer/{customerId}, method: Get
request = requests.Request([
primitives.restler_static_string("GET "),
primitives.restler_basepath(""),
primitives.restler_static_string("/"),
primitives.restler_static_string("customer"),
primitives.restler_static_string("/"),
primitives.restler_static_string(_customer_post_id.reader(), quoted=False),
primitives.restler_static_string(" HTTP/1.1\r\n"),
primitives.restler_static_string("Accept: application/json\r\n"),
primitives.restler_static_string("Host: \r\n"),
primitives.restler_static_string("string-enum-header-param: "),
primitives.restler_fuzzable_group("string-enum-header-param", ['enum_header_val_1','enum_header_val_2'] ,quoted=False),
primitives.restler_static_string("\r\n"),
primitives.restler_refreshable_authentication_token("authentication_token_tag"),
primitives.restler_static_string("\r\n"),
],
requestId="/customer/{customerId}"
)
req_collection.add_request(request)

Просмотреть файл

@ -0,0 +1,385 @@
{
"openapi": "3.0.1",
"info": {
"title": "Simple Swagger with all parameter data types",
"description": "Covers parameter types x data types x dependency types (with annotation file)",
"version": "1"
},
"servers": [
{
"url": "/"
}
],
"paths": {
"/customer": {
"post": {
"operationId": "post_customer",
"parameters": [
{
"name": "string-query-param",
"in": "query",
"required": true,
"schema": {
"type": "string"
},
"example": "the quick brown fox"
},
{
"name": "string-date-query-param",
"in": "query",
"required": true,
"schema": {
"type": "string",
"format": "date"
},
"example": "2020-12-10"
},
{
"name": "string-date-time-query-param",
"in": "query",
"required": true,
"schema": {
"type": "string",
"format": "date-time"
},
"example": "2022-12-12"
},
{
"name": "string-password-query-param",
"in": "query",
"required": true,
"schema": {
"type": "integer",
"format": "int64",
"example": 2987
}
},
{
"name": "float-number-query-param",
"in": "query",
"required": true,
"schema": {
"type": "number",
"format": "float",
"example": 2.32
}
},
{
"name": "double-number-query-param",
"in": "query",
"required": true,
"schema": {
"type": "number",
"format": "double",
"example": 4.56
},
"example": 9.999
},
{
"name": "boolean-query-param",
"in": "query",
"required": true,
"schema": {
"type": "boolean",
"example": false
}
}
],
"requestBody": {
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/Customer"
}
}
},
"required": true
},
"responses": {
"201": {
"description": "Success",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/Customer"
}
}
}
}
},
"x-codegen-request-body-name": "body"
}
},
"/customer/{customerId}": {
"get": {
"operationId": "post_customer",
"parameters": [
{
"name": "customerId",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "string-enum-header-param",
"in": "header",
"required": true,
"schema": {
"type": "string",
"enum": [
"enum_val_1",
"enum_val_2"
]
}
}
],
"responses": {
"201": {
"description": "Success",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/Customer"
}
}
}
}
}
}
},
"/product": {
"post": {
"parameters": [
{
"name": "query-producer-param",
"in": "query",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/Product"
}
}
},
"required": true
},
"responses": {}
}
},
"/product/{productId}": {
"get": {
"parameters": [
{
"name": "productId",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {}
}
}
},
"components": {
"schemas": {
"Customer": {
"required": [
"Person",
"id"
],
"type": "object",
"properties": {
"id": {
"type": "string"
},
"Person": {
"$ref": "#/components/schemas/ParameterTests"
}
}
},
"Product": {
"required": [
"info",
"id"
],
"type": "object",
"properties": {
"id": {
"type": "string"
},
"info": {
"$ref": "#/components/schemas/ParameterTests"
}
}
},
"ParameterTests": {
"required": [
"int-body-param",
"int32-body-param",
"int64-body-param",
"obj-body-param"
],
"type": "object",
"properties": {
"int32-body-param": {
"type": "integer",
"format": "int32",
"example": 321
},
"int64-body-param": {
"type": "integer",
"format": "int64",
"example": 200
},
"int-body-param": {
"type": "integer",
"example": -30
},
"obj-body-param": {
"type": "object",
"properties": {},
"example": {
"tags": {"label": "important"}
}
}
}
}
},
"parameters": {
"StringQueryParameter": {
"name": "string-query-param",
"in": "query",
"required": true,
"schema": {
"type": "string"
}
},
"StringDateQueryParameter": {
"name": "string-date-query-param",
"in": "query",
"required": true,
"schema": {
"type": "string",
"format": "date"
}
},
"StringDateTimeQueryParameter": {
"name": "string-date-time-query-param",
"in": "query",
"required": true,
"schema": {
"type": "string",
"format": "date-time"
}
},
"StringPasswordQueryParameter": {
"name": "string-password-query-param",
"in": "query",
"required": true,
"schema": {
"type": "string",
"format": "password"
}
},
"StringByteQueryParameter": {
"name": "string-password-query-param",
"in": "query",
"required": true,
"schema": {
"type": "string",
"format": "byte"
}
},
"StringBinaryQueryParameter": {
"name": "string-password-query-param",
"in": "query",
"required": true,
"schema": {
"type": "string",
"format": "binary"
}
},
"ObjectQueryParameter": {
"name": "string-password-query-param",
"in": "query",
"required": true,
"schema": {
"type": "object"
}
},
"IntQueryParameter": {
"name": "string-password-query-param",
"in": "query",
"required": true,
"schema": {
"type": "integer"
}
},
"Int32QueryParameter": {
"name": "string-password-query-param",
"in": "query",
"required": true,
"schema": {
"type": "integer",
"format": "int32"
}
},
"Int64QueryParameter": {
"name": "string-password-query-param",
"in": "query",
"required": true,
"schema": {
"type": "integer",
"format": "int64"
}
},
"NumberQueryParameter": {
"name": "number-query-param",
"in": "query",
"required": true,
"schema": {
"type": "number"
}
},
"FloatNumberQueryParameter": {
"name": "float-number-query-param",
"in": "query",
"required": true,
"schema": {
"type": "number",
"format": "float"
}
},
"DoubleNumberQueryParameter": {
"name": "double-number-query-param",
"in": "query",
"required": true,
"schema": {
"type": "number",
"format": "double",
"example": "4.56"
},
"example": "9.78"
},
"BooleanQueryParameter": {
"name": "boolean-query-param",
"in": "query",
"required": true,
"schema": {
"type": "boolean"
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,429 @@
{
"Requests": [
{
"id": {
"endpoint": "/customer",
"method": "Post"
},
"method": "Post",
"basePath": "",
"path": [
{
"Constant": [
"String",
"customer"
]
}
],
"queryParameters": [
[
"Schema",
{
"ParameterList": [
{
"name": "string-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "String",
"defaultValue": "fuzzstring",
"exampleValue": "the quick brown fox"
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "string-date-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "Date",
"defaultValue": "2019-06-26",
"exampleValue": "\"2020-12-10\""
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "string-date-time-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "DateTime",
"defaultValue": "2019-06-26T20:20:39+00:00",
"exampleValue": "2022-12-12"
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "string-password-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1",
"exampleValue": "2987"
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "float-number-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "Number",
"defaultValue": "1.23",
"exampleValue": "2.32"
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "double-number-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "Number",
"defaultValue": "1.23",
"exampleValue": "9.999"
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "boolean-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "Bool",
"defaultValue": "true",
"exampleValue": "false"
}
},
"isRequired": true,
"isReadOnly": false
}
}
}
]
}
]
],
"bodyParameters": [
[
"Schema",
{
"ParameterList": [
{
"name": "__body__",
"payload": {
"InternalNode": [
{
"name": "",
"propertyType": "Object",
"isRequired": true,
"isReadOnly": false
},
[
{
"LeafNode": {
"name": "id",
"payload": {
"Fuzzable": {
"primitiveType": "String",
"defaultValue": "fuzzstring"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"InternalNode": [
{
"name": "Person",
"propertyType": "Property",
"isRequired": true,
"isReadOnly": false
},
[
{
"InternalNode": [
{
"name": "",
"propertyType": "Object",
"isRequired": true,
"isReadOnly": false
},
[
{
"LeafNode": {
"name": "int32-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1",
"exampleValue": "321"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "int64-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1",
"exampleValue": "200"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "int-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1",
"exampleValue": "-30"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "obj-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Object",
"defaultValue": "{ \"fuzz\": false }",
"exampleValue": "{\"tags\":{\"label\":\"important\"}}"
}
},
"isRequired": true,
"isReadOnly": false
}
}
]
]
}
]
]
}
]
]
}
}
]
}
]
],
"headerParameters": [
[
"Schema",
{
"ParameterList": []
}
],
[
"DictionaryCustomPayload",
{
"ParameterList": [
{
"name": "Content-Type",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Constant": [
"String",
"application/json"
]
},
"isRequired": true,
"isReadOnly": false
}
}
}
]
}
]
],
"token": "Refreshable",
"headers": [
[
"Accept",
"application/json"
],
[
"Host",
""
]
],
"httpVersion": "1.1",
"dependencyData": {
"responseParser": {
"writerVariables": [
{
"requestId": {
"endpoint": "/customer",
"method": "Post"
},
"accessPathParts": {
"path": [
"id"
]
},
"primitiveType": "String",
"kind": "BodyResponseProperty"
}
],
"headerWriterVariables": []
},
"inputWriterVariables": [],
"orderingConstraintWriterVariables": [],
"orderingConstraintReaderVariables": []
},
"requestMetadata": {
"isLongRunningOperation": false
}
},
{
"id": {
"endpoint": "/customer/{customerId}",
"method": "Get"
},
"method": "Get",
"basePath": "",
"path": [
{
"Constant": [
"String",
"customer"
]
},
{
"DynamicObject": {
"primitiveType": "String",
"variableName": "_customer_post_id",
"isWriter": false
}
}
],
"queryParameters": [
[
"Schema",
{
"ParameterList": []
}
]
],
"bodyParameters": [
[
"Schema",
{
"ParameterList": []
}
]
],
"headerParameters": [
[
"Schema",
{
"ParameterList": [
{
"name": "string-enum-header-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": {
"Enum": [
"string-enum-header-param",
"String",
[
"enum_val_1",
"enum_val_2"
],
null
]
},
"defaultValue": "enum_val_1"
}
},
"isRequired": true,
"isReadOnly": false
}
}
}
]
}
],
[
"DictionaryCustomPayload",
{
"ParameterList": []
}
]
],
"token": "Refreshable",
"headers": [
[
"Accept",
"application/json"
],
[
"Host",
""
]
],
"httpVersion": "1.1",
"requestMetadata": {
"isLongRunningOperation": false
}
}
]
}

Просмотреть файл

@ -0,0 +1,145 @@
""" THIS IS AN AUTOMATICALLY GENERATED FILE!"""
from __future__ import print_function
import json
from engine import primitives
from engine.core import requests
from engine.errors import ResponseParsingException
from engine import dependencies
_customer_post_id = dependencies.DynamicVariable("_customer_post_id")
def parse_customerpost(data, **kwargs):
""" Automatically generated response parser """
# Declare response variables
temp_7262 = None
if 'headers' in kwargs:
headers = kwargs['headers']
# Parse body if needed
if data:
try:
data = json.loads(data)
except Exception as error:
raise ResponseParsingException("Exception parsing response, data was not valid json: {}".format(error))
pass
# Try to extract each dynamic object
try:
temp_7262 = str(data["id"])
except Exception as error:
# This is not an error, since some properties are not always returned
pass
# If no dynamic objects were extracted, throw.
if not (temp_7262):
raise ResponseParsingException("Error: all of the expected dynamic objects were not present in the response.")
# Set dynamic variables
if temp_7262:
dependencies.set_variable("_customer_post_id", temp_7262)
req_collection = requests.RequestCollection([])
# Endpoint: /customer, method: Post
request = requests.Request([
primitives.restler_static_string("POST "),
primitives.restler_basepath(""),
primitives.restler_static_string("/"),
primitives.restler_static_string("customer"),
primitives.restler_static_string("?"),
primitives.restler_static_string("string-query-param="),
primitives.restler_fuzzable_string("fuzzstring", quoted=False, examples=["the quick brown fox"]),
primitives.restler_static_string("&"),
primitives.restler_static_string("string-date-query-param="),
primitives.restler_fuzzable_date("2019-06-26", quoted=False, examples=['"2020-12-10"']),
primitives.restler_static_string("&"),
primitives.restler_static_string("string-date-time-query-param="),
primitives.restler_fuzzable_datetime("2019-06-26T20:20:39+00:00", quoted=False, examples=["2022-12-12"]),
primitives.restler_static_string("&"),
primitives.restler_static_string("string-password-query-param="),
primitives.restler_fuzzable_int("1", examples=["2987"]),
primitives.restler_static_string("&"),
primitives.restler_static_string("float-number-query-param="),
primitives.restler_fuzzable_number("1.23", examples=["2.32"]),
primitives.restler_static_string("&"),
primitives.restler_static_string("double-number-query-param="),
primitives.restler_fuzzable_number("1.23", examples=["9.999"]),
primitives.restler_static_string("&"),
primitives.restler_static_string("boolean-query-param="),
primitives.restler_fuzzable_bool("true", examples=["false"]),
primitives.restler_static_string(" HTTP/1.1\r\n"),
primitives.restler_static_string("Accept: application/json\r\n"),
primitives.restler_static_string("Host: \r\n"),
primitives.restler_static_string("Content-Type: "),
primitives.restler_static_string("application/json"),
primitives.restler_static_string("\r\n"),
primitives.restler_refreshable_authentication_token("authentication_token_tag"),
primitives.restler_static_string("\r\n"),
primitives.restler_static_string("{"),
primitives.restler_static_string("""
"id":"""),
primitives.restler_fuzzable_string("fuzzstring", quoted=True),
primitives.restler_static_string(""",
"Person":
{
"int32-body-param":"""),
primitives.restler_fuzzable_int("1", examples=["321"]),
primitives.restler_static_string(""",
"int64-body-param":"""),
primitives.restler_fuzzable_int("1", examples=["200"]),
primitives.restler_static_string(""",
"int-body-param":"""),
primitives.restler_fuzzable_int("1", examples=["-30"]),
primitives.restler_static_string(""",
"obj-body-param":"""),
primitives.restler_fuzzable_object("{ \"fuzz\": false }", examples=["{\"tags\":{\"label\":\"important\"}}"]),
primitives.restler_static_string("""
}
}"""),
primitives.restler_static_string("\r\n"),
{
'post_send':
{
'parser': parse_customerpost,
'dependencies':
[
_customer_post_id.writer()
]
}
},
],
requestId="/customer"
)
req_collection.add_request(request)
# Endpoint: /customer/{customerId}, method: Get
request = requests.Request([
primitives.restler_static_string("GET "),
primitives.restler_basepath(""),
primitives.restler_static_string("/"),
primitives.restler_static_string("customer"),
primitives.restler_static_string("/"),
primitives.restler_static_string(_customer_post_id.reader(), quoted=False),
primitives.restler_static_string(" HTTP/1.1\r\n"),
primitives.restler_static_string("Accept: application/json\r\n"),
primitives.restler_static_string("Host: \r\n"),
primitives.restler_static_string("string-enum-header-param: "),
primitives.restler_fuzzable_group("string-enum-header-param", ['enum_val_1','enum_val_2'] ,quoted=False),
primitives.restler_static_string("\r\n"),
primitives.restler_refreshable_authentication_token("authentication_token_tag"),
primitives.restler_static_string("\r\n"),
],
requestId="/customer/{customerId}"
)
req_collection.add_request(request)

Просмотреть файл

@ -0,0 +1,11 @@
{
"restler_custom_payload": {
"productId": ["productid"],
"id": ["id"]
},
"restler_custom_payload_uuid4_suffix": {
"productId": "productid",
"id": "id"
},
"restler_custom_payload_unquoted": {}
}

Просмотреть файл

@ -6,6 +6,7 @@
"method": "Post"
},
"method": "Post",
"basePath": "",
"path": [
{
"Constant": [
@ -219,6 +220,7 @@
"method": "Get"
},
"method": "Get",
"basePath": "",
"path": [
{
"Constant": [

Просмотреть файл

@ -0,0 +1,12 @@
{
"x-restler-global-annotations": [
{
"producer_endpoint": "/product",
"producer_method": "POST",
"consumer_endpoint": "/product/{productId}",
"consumer_method": "GET",
"consumer_param": "productId",
"producer_resource_name": "/id"
}
]
}

Просмотреть файл

@ -0,0 +1,731 @@
{
"Requests": [
{
"id": {
"endpoint": "/customer",
"method": "Post"
},
"method": "Post",
"basePath": "",
"path": [
{
"Constant": [
"String",
"customer"
]
}
],
"queryParameters": [
[
"Schema",
{
"ParameterList": [
{
"name": "string-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "String",
"defaultValue": "fuzzstring",
"exampleValue": "the quick brown fox"
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "string-date-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "Date",
"defaultValue": "2019-06-26",
"exampleValue": "\"2020-12-10\""
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "string-date-time-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "DateTime",
"defaultValue": "2019-06-26T20:20:39+00:00",
"exampleValue": "2022-12-12"
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "string-password-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1",
"exampleValue": "2987"
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "float-number-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "Number",
"defaultValue": "1.23",
"exampleValue": "2.32"
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "double-number-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "Number",
"defaultValue": "1.23",
"exampleValue": "9.999"
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "boolean-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "Bool",
"defaultValue": "true",
"exampleValue": "false"
}
},
"isRequired": true,
"isReadOnly": false
}
}
}
]
}
]
],
"bodyParameters": [
[
"Schema",
{
"ParameterList": [
{
"name": "__body__",
"payload": {
"InternalNode": [
{
"name": "",
"propertyType": "Object",
"isRequired": true,
"isReadOnly": false
},
[
{
"LeafNode": {
"name": "id",
"payload": {
"Fuzzable": {
"primitiveType": "String",
"defaultValue": "fuzzstring"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"InternalNode": [
{
"name": "Person",
"propertyType": "Property",
"isRequired": true,
"isReadOnly": false
},
[
{
"InternalNode": [
{
"name": "",
"propertyType": "Object",
"isRequired": true,
"isReadOnly": false
},
[
{
"LeafNode": {
"name": "int32-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1",
"exampleValue": "321"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "int64-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1",
"exampleValue": "200"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "int-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1",
"exampleValue": "-30"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "obj-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Object",
"defaultValue": "{ \"fuzz\": false }",
"exampleValue": "{\"tags\":{\"label\":\"important\"}}"
}
},
"isRequired": true,
"isReadOnly": false
}
}
]
]
}
]
]
}
]
]
}
}
]
}
]
],
"headerParameters": [
[
"Schema",
{
"ParameterList": []
}
],
[
"DictionaryCustomPayload",
{
"ParameterList": [
{
"name": "Content-Type",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Constant": [
"String",
"application/json"
]
},
"isRequired": true,
"isReadOnly": false
}
}
}
]
}
]
],
"token": "Refreshable",
"headers": [
[
"Accept",
"application/json"
],
[
"Host",
""
]
],
"httpVersion": "1.1",
"dependencyData": {
"responseParser": {
"writerVariables": [
{
"requestId": {
"endpoint": "/customer",
"method": "Post"
},
"accessPathParts": {
"path": [
"id"
]
},
"primitiveType": "String",
"kind": "BodyResponseProperty"
}
],
"headerWriterVariables": []
},
"inputWriterVariables": [],
"orderingConstraintWriterVariables": [],
"orderingConstraintReaderVariables": []
},
"requestMetadata": {
"isLongRunningOperation": false
}
},
{
"id": {
"endpoint": "/customer/{customerId}",
"method": "Get"
},
"method": "Get",
"basePath": "",
"path": [
{
"Constant": [
"String",
"customer"
]
},
{
"DynamicObject": {
"primitiveType": "String",
"variableName": "_customer_post_id",
"isWriter": false
}
}
],
"queryParameters": [
[
"Schema",
{
"ParameterList": []
}
]
],
"bodyParameters": [
[
"Schema",
{
"ParameterList": []
}
]
],
"headerParameters": [
[
"Schema",
{
"ParameterList": [
{
"name": "string-enum-header-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": {
"Enum": [
"string-enum-header-param",
"String",
[
"enum_val_1",
"enum_val_2"
],
null
]
},
"defaultValue": "enum_val_1"
}
},
"isRequired": true,
"isReadOnly": false
}
}
}
]
}
],
[
"DictionaryCustomPayload",
{
"ParameterList": []
}
]
],
"token": "Refreshable",
"headers": [
[
"Accept",
"application/json"
],
[
"Host",
""
]
],
"httpVersion": "1.1",
"requestMetadata": {
"isLongRunningOperation": false
}
},
{
"id": {
"endpoint": "/product",
"method": "Post"
},
"method": "Post",
"basePath": "",
"path": [
{
"Constant": [
"String",
"product"
]
}
],
"queryParameters": [
[
"Schema",
{
"ParameterList": [
{
"name": "query-producer-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "String",
"defaultValue": "fuzzstring"
}
},
"isRequired": true,
"isReadOnly": false
}
}
}
]
}
]
],
"bodyParameters": [
[
"Schema",
{
"ParameterList": [
{
"name": "__body__",
"payload": {
"InternalNode": [
{
"name": "",
"propertyType": "Object",
"isRequired": true,
"isReadOnly": false
},
[
{
"LeafNode": {
"name": "id",
"payload": {
"Custom": {
"payloadType": "UuidSuffix",
"primitiveType": "String",
"payloadValue": "id",
"isObject": false,
"dynamicObject": {
"primitiveType": "String",
"variableName": "_product_post_id",
"isWriter": false
}
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"InternalNode": [
{
"name": "info",
"propertyType": "Property",
"isRequired": true,
"isReadOnly": false
},
[
{
"InternalNode": [
{
"name": "",
"propertyType": "Object",
"isRequired": true,
"isReadOnly": false
},
[
{
"LeafNode": {
"name": "int32-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1",
"exampleValue": "321"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "int64-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1",
"exampleValue": "200"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "int-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1",
"exampleValue": "-30"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "obj-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Object",
"defaultValue": "{ \"fuzz\": false }",
"exampleValue": "{\"tags\":{\"label\":\"important\"}}"
}
},
"isRequired": true,
"isReadOnly": false
}
}
]
]
}
]
]
}
]
]
}
}
]
}
]
],
"headerParameters": [
[
"Schema",
{
"ParameterList": []
}
],
[
"DictionaryCustomPayload",
{
"ParameterList": [
{
"name": "Content-Type",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Constant": [
"String",
"application/json"
]
},
"isRequired": true,
"isReadOnly": false
}
}
}
]
}
]
],
"token": "Refreshable",
"headers": [
[
"Accept",
"application/json"
],
[
"Host",
""
]
],
"httpVersion": "1.1",
"dependencyData": {
"responseParser": {
"writerVariables": [],
"headerWriterVariables": []
},
"inputWriterVariables": [
{
"requestId": {
"endpoint": "/product",
"method": "Post"
},
"accessPathParts": {
"path": [
"id"
]
},
"primitiveType": "String",
"kind": "InputParameter"
}
],
"orderingConstraintWriterVariables": [],
"orderingConstraintReaderVariables": []
},
"requestMetadata": {
"isLongRunningOperation": false
}
},
{
"id": {
"endpoint": "/product/{productId}",
"method": "Get"
},
"method": "Get",
"basePath": "",
"path": [
{
"Constant": [
"String",
"product"
]
},
{
"DynamicObject": {
"primitiveType": "String",
"variableName": "_product_post_id",
"isWriter": false
}
}
],
"queryParameters": [
[
"Schema",
{
"ParameterList": []
}
]
],
"bodyParameters": [
[
"Schema",
{
"ParameterList": []
}
]
],
"headerParameters": [
[
"Schema",
{
"ParameterList": []
}
],
[
"DictionaryCustomPayload",
{
"ParameterList": []
}
]
],
"token": "Refreshable",
"headers": [
[
"Accept",
"application/json"
],
[
"Host",
""
]
],
"httpVersion": "1.1",
"requestMetadata": {
"isLongRunningOperation": false
}
}
]
}

Просмотреть файл

@ -0,0 +1,224 @@
""" THIS IS AN AUTOMATICALLY GENERATED FILE!"""
from __future__ import print_function
import json
from engine import primitives
from engine.core import requests
from engine.errors import ResponseParsingException
from engine import dependencies
_customer_post_id = dependencies.DynamicVariable("_customer_post_id")
_product_post_id = dependencies.DynamicVariable("_product_post_id")
def parse_customerpost(data, **kwargs):
""" Automatically generated response parser """
# Declare response variables
temp_7262 = None
if 'headers' in kwargs:
headers = kwargs['headers']
# Parse body if needed
if data:
try:
data = json.loads(data)
except Exception as error:
raise ResponseParsingException("Exception parsing response, data was not valid json: {}".format(error))
pass
# Try to extract each dynamic object
try:
temp_7262 = str(data["id"])
except Exception as error:
# This is not an error, since some properties are not always returned
pass
# If no dynamic objects were extracted, throw.
if not (temp_7262):
raise ResponseParsingException("Error: all of the expected dynamic objects were not present in the response.")
# Set dynamic variables
if temp_7262:
dependencies.set_variable("_customer_post_id", temp_7262)
req_collection = requests.RequestCollection([])
# Endpoint: /customer, method: Post
request = requests.Request([
primitives.restler_static_string("POST "),
primitives.restler_basepath(""),
primitives.restler_static_string("/"),
primitives.restler_static_string("customer"),
primitives.restler_static_string("?"),
primitives.restler_static_string("string-query-param="),
primitives.restler_fuzzable_string("fuzzstring", quoted=False, examples=["the quick brown fox"]),
primitives.restler_static_string("&"),
primitives.restler_static_string("string-date-query-param="),
primitives.restler_fuzzable_date("2019-06-26", quoted=False, examples=['"2020-12-10"']),
primitives.restler_static_string("&"),
primitives.restler_static_string("string-date-time-query-param="),
primitives.restler_fuzzable_datetime("2019-06-26T20:20:39+00:00", quoted=False, examples=["2022-12-12"]),
primitives.restler_static_string("&"),
primitives.restler_static_string("string-password-query-param="),
primitives.restler_fuzzable_int("1", examples=["2987"]),
primitives.restler_static_string("&"),
primitives.restler_static_string("float-number-query-param="),
primitives.restler_fuzzable_number("1.23", examples=["2.32"]),
primitives.restler_static_string("&"),
primitives.restler_static_string("double-number-query-param="),
primitives.restler_fuzzable_number("1.23", examples=["9.999"]),
primitives.restler_static_string("&"),
primitives.restler_static_string("boolean-query-param="),
primitives.restler_fuzzable_bool("true", examples=["false"]),
primitives.restler_static_string(" HTTP/1.1\r\n"),
primitives.restler_static_string("Accept: application/json\r\n"),
primitives.restler_static_string("Host: \r\n"),
primitives.restler_static_string("Content-Type: "),
primitives.restler_static_string("application/json"),
primitives.restler_static_string("\r\n"),
primitives.restler_refreshable_authentication_token("authentication_token_tag"),
primitives.restler_static_string("\r\n"),
primitives.restler_static_string("{"),
primitives.restler_static_string("""
"id":"""),
primitives.restler_fuzzable_string("fuzzstring", quoted=True),
primitives.restler_static_string(""",
"Person":
{
"int32-body-param":"""),
primitives.restler_fuzzable_int("1", examples=["321"]),
primitives.restler_static_string(""",
"int64-body-param":"""),
primitives.restler_fuzzable_int("1", examples=["200"]),
primitives.restler_static_string(""",
"int-body-param":"""),
primitives.restler_fuzzable_int("1", examples=["-30"]),
primitives.restler_static_string(""",
"obj-body-param":"""),
primitives.restler_fuzzable_object("{ \"fuzz\": false }", examples=["{\"tags\":{\"label\":\"important\"}}"]),
primitives.restler_static_string("""
}
}"""),
primitives.restler_static_string("\r\n"),
{
'post_send':
{
'parser': parse_customerpost,
'dependencies':
[
_customer_post_id.writer()
]
}
},
],
requestId="/customer"
)
req_collection.add_request(request)
# Endpoint: /customer/{customerId}, method: Get
request = requests.Request([
primitives.restler_static_string("GET "),
primitives.restler_basepath(""),
primitives.restler_static_string("/"),
primitives.restler_static_string("customer"),
primitives.restler_static_string("/"),
primitives.restler_static_string(_customer_post_id.reader(), quoted=False),
primitives.restler_static_string(" HTTP/1.1\r\n"),
primitives.restler_static_string("Accept: application/json\r\n"),
primitives.restler_static_string("Host: \r\n"),
primitives.restler_static_string("string-enum-header-param: "),
primitives.restler_fuzzable_group("string-enum-header-param", ['enum_val_1','enum_val_2'] ,quoted=False),
primitives.restler_static_string("\r\n"),
primitives.restler_refreshable_authentication_token("authentication_token_tag"),
primitives.restler_static_string("\r\n"),
],
requestId="/customer/{customerId}"
)
req_collection.add_request(request)
# Endpoint: /product, method: Post
request = requests.Request([
primitives.restler_static_string("POST "),
primitives.restler_basepath(""),
primitives.restler_static_string("/"),
primitives.restler_static_string("product"),
primitives.restler_static_string("?"),
primitives.restler_static_string("query-producer-param="),
primitives.restler_fuzzable_string("fuzzstring", quoted=False),
primitives.restler_static_string(" HTTP/1.1\r\n"),
primitives.restler_static_string("Accept: application/json\r\n"),
primitives.restler_static_string("Host: \r\n"),
primitives.restler_static_string("Content-Type: "),
primitives.restler_static_string("application/json"),
primitives.restler_static_string("\r\n"),
primitives.restler_refreshable_authentication_token("authentication_token_tag"),
primitives.restler_static_string("\r\n"),
primitives.restler_static_string("{"),
primitives.restler_static_string("""
"id":"""),
primitives.restler_custom_payload_uuid4_suffix("id", writer=_product_post_id.writer(), quoted=True),
primitives.restler_static_string(""",
"info":
{
"int32-body-param":"""),
primitives.restler_fuzzable_int("1", examples=["321"]),
primitives.restler_static_string(""",
"int64-body-param":"""),
primitives.restler_fuzzable_int("1", examples=["200"]),
primitives.restler_static_string(""",
"int-body-param":"""),
primitives.restler_fuzzable_int("1", examples=["-30"]),
primitives.restler_static_string(""",
"obj-body-param":"""),
primitives.restler_fuzzable_object("{ \"fuzz\": false }", examples=["{\"tags\":{\"label\":\"important\"}}"]),
primitives.restler_static_string("""
}
}"""),
primitives.restler_static_string("\r\n"),
{
'post_send':
{
'dependencies':
[
_product_post_id.writer()
]
}
},
],
requestId="/product"
)
req_collection.add_request(request)
# Endpoint: /product/{productId}, method: Get
request = requests.Request([
primitives.restler_static_string("GET "),
primitives.restler_basepath(""),
primitives.restler_static_string("/"),
primitives.restler_static_string("product"),
primitives.restler_static_string("/"),
primitives.restler_static_string(_product_post_id.reader(), quoted=False),
primitives.restler_static_string(" HTTP/1.1\r\n"),
primitives.restler_static_string("Accept: application/json\r\n"),
primitives.restler_static_string("Host: \r\n"),
primitives.restler_refreshable_authentication_token("authentication_token_tag"),
primitives.restler_static_string("\r\n"),
],
requestId="/product/{productId}"
)
req_collection.add_request(request)

Просмотреть файл

@ -0,0 +1,733 @@
{
"Requests": [
{
"id": {
"endpoint": "/customer",
"method": "Post"
},
"method": "Post",
"basePath": "",
"path": [
{
"Constant": [
"String",
"customer"
]
}
],
"queryParameters": [
[
"Schema",
{
"ParameterList": [
{
"name": "string-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "String",
"defaultValue": "fuzzstring",
"exampleValue": "the quick brown fox"
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "string-date-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "Date",
"defaultValue": "2019-06-26",
"exampleValue": "\"2020-12-10\""
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "string-date-time-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "DateTime",
"defaultValue": "2019-06-26T20:20:39+00:00",
"exampleValue": "2022-12-12"
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "string-password-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1",
"exampleValue": "2987"
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "float-number-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "Number",
"defaultValue": "1.23",
"exampleValue": "2.32"
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "double-number-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "Number",
"defaultValue": "1.23",
"exampleValue": "9.999"
}
},
"isRequired": true,
"isReadOnly": false
}
}
},
{
"name": "boolean-query-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "Bool",
"defaultValue": "true",
"exampleValue": "false"
}
},
"isRequired": true,
"isReadOnly": false
}
}
}
]
}
]
],
"bodyParameters": [
[
"Schema",
{
"ParameterList": [
{
"name": "__body__",
"payload": {
"InternalNode": [
{
"name": "",
"propertyType": "Object",
"isRequired": true,
"isReadOnly": false
},
[
{
"LeafNode": {
"name": "id",
"payload": {
"Custom": {
"payloadType": "String",
"primitiveType": "String",
"payloadValue": "id",
"isObject": false
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"InternalNode": [
{
"name": "Person",
"propertyType": "Property",
"isRequired": true,
"isReadOnly": false
},
[
{
"InternalNode": [
{
"name": "",
"propertyType": "Object",
"isRequired": true,
"isReadOnly": false
},
[
{
"LeafNode": {
"name": "int32-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1",
"exampleValue": "321"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "int64-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1",
"exampleValue": "200"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "int-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1",
"exampleValue": "-30"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "obj-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Object",
"defaultValue": "{ \"fuzz\": false }",
"exampleValue": "{\"tags\":{\"label\":\"important\"}}"
}
},
"isRequired": true,
"isReadOnly": false
}
}
]
]
}
]
]
}
]
]
}
}
]
}
]
],
"headerParameters": [
[
"Schema",
{
"ParameterList": []
}
],
[
"DictionaryCustomPayload",
{
"ParameterList": [
{
"name": "Content-Type",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Constant": [
"String",
"application/json"
]
},
"isRequired": true,
"isReadOnly": false
}
}
}
]
}
]
],
"token": "Refreshable",
"headers": [
[
"Accept",
"application/json"
],
[
"Host",
""
]
],
"httpVersion": "1.1",
"dependencyData": {
"responseParser": {
"writerVariables": [
{
"requestId": {
"endpoint": "/customer",
"method": "Post"
},
"accessPathParts": {
"path": [
"id"
]
},
"primitiveType": "String",
"kind": "BodyResponseProperty"
}
],
"headerWriterVariables": []
},
"inputWriterVariables": [],
"orderingConstraintWriterVariables": [],
"orderingConstraintReaderVariables": []
},
"requestMetadata": {
"isLongRunningOperation": false
}
},
{
"id": {
"endpoint": "/customer/{customerId}",
"method": "Get"
},
"method": "Get",
"basePath": "",
"path": [
{
"Constant": [
"String",
"customer"
]
},
{
"DynamicObject": {
"primitiveType": "String",
"variableName": "_customer_post_id",
"isWriter": false
}
}
],
"queryParameters": [
[
"Schema",
{
"ParameterList": []
}
]
],
"bodyParameters": [
[
"Schema",
{
"ParameterList": []
}
]
],
"headerParameters": [
[
"Schema",
{
"ParameterList": [
{
"name": "string-enum-header-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": {
"Enum": [
"string-enum-header-param",
"String",
[
"enum_val_1",
"enum_val_2"
],
null
]
},
"defaultValue": "enum_val_1"
}
},
"isRequired": true,
"isReadOnly": false
}
}
}
]
}
],
[
"DictionaryCustomPayload",
{
"ParameterList": []
}
]
],
"token": "Refreshable",
"headers": [
[
"Accept",
"application/json"
],
[
"Host",
""
]
],
"httpVersion": "1.1",
"requestMetadata": {
"isLongRunningOperation": false
}
},
{
"id": {
"endpoint": "/product",
"method": "Post"
},
"method": "Post",
"basePath": "",
"path": [
{
"Constant": [
"String",
"product"
]
}
],
"queryParameters": [
[
"Schema",
{
"ParameterList": [
{
"name": "query-producer-param",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Fuzzable": {
"primitiveType": "String",
"defaultValue": "fuzzstring"
}
},
"isRequired": true,
"isReadOnly": false
}
}
}
]
}
]
],
"bodyParameters": [
[
"Schema",
{
"ParameterList": [
{
"name": "__body__",
"payload": {
"InternalNode": [
{
"name": "",
"propertyType": "Object",
"isRequired": true,
"isReadOnly": false
},
[
{
"LeafNode": {
"name": "id",
"payload": {
"Custom": {
"payloadType": "String",
"primitiveType": "String",
"payloadValue": "id",
"isObject": false,
"dynamicObject": {
"primitiveType": "String",
"variableName": "_product_post_id",
"isWriter": false
}
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"InternalNode": [
{
"name": "info",
"propertyType": "Property",
"isRequired": true,
"isReadOnly": false
},
[
{
"InternalNode": [
{
"name": "",
"propertyType": "Object",
"isRequired": true,
"isReadOnly": false
},
[
{
"LeafNode": {
"name": "int32-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1",
"exampleValue": "321"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "int64-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1",
"exampleValue": "200"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "int-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Int",
"defaultValue": "1",
"exampleValue": "-30"
}
},
"isRequired": true,
"isReadOnly": false
}
},
{
"LeafNode": {
"name": "obj-body-param",
"payload": {
"Fuzzable": {
"primitiveType": "Object",
"defaultValue": "{ \"fuzz\": false }",
"exampleValue": "{\"tags\":{\"label\":\"important\"}}"
}
},
"isRequired": true,
"isReadOnly": false
}
}
]
]
}
]
]
}
]
]
}
}
]
}
]
],
"headerParameters": [
[
"Schema",
{
"ParameterList": []
}
],
[
"DictionaryCustomPayload",
{
"ParameterList": [
{
"name": "Content-Type",
"payload": {
"LeafNode": {
"name": "",
"payload": {
"Constant": [
"String",
"application/json"
]
},
"isRequired": true,
"isReadOnly": false
}
}
}
]
}
]
],
"token": "Refreshable",
"headers": [
[
"Accept",
"application/json"
],
[
"Host",
""
]
],
"httpVersion": "1.1",
"dependencyData": {
"responseParser": {
"writerVariables": [],
"headerWriterVariables": []
},
"inputWriterVariables": [
{
"requestId": {
"endpoint": "/product",
"method": "Post"
},
"accessPathParts": {
"path": [
"id"
]
},
"primitiveType": "String",
"kind": "InputParameter"
}
],
"orderingConstraintWriterVariables": [],
"orderingConstraintReaderVariables": []
},
"requestMetadata": {
"isLongRunningOperation": false
}
},
{
"id": {
"endpoint": "/product/{productId}",
"method": "Get"
},
"method": "Get",
"basePath": "",
"path": [
{
"Constant": [
"String",
"product"
]
},
{
"DynamicObject": {
"primitiveType": "String",
"variableName": "_product_post_id",
"isWriter": false
}
}
],
"queryParameters": [
[
"Schema",
{
"ParameterList": []
}
]
],
"bodyParameters": [
[
"Schema",
{
"ParameterList": []
}
]
],
"headerParameters": [
[
"Schema",
{
"ParameterList": []
}
],
[
"DictionaryCustomPayload",
{
"ParameterList": []
}
]
],
"token": "Refreshable",
"headers": [
[
"Accept",
"application/json"
],
[
"Host",
""
]
],
"httpVersion": "1.1",
"requestMetadata": {
"isLongRunningOperation": false
}
}
]
}

Просмотреть файл

@ -0,0 +1,224 @@
""" THIS IS AN AUTOMATICALLY GENERATED FILE!"""
from __future__ import print_function
import json
from engine import primitives
from engine.core import requests
from engine.errors import ResponseParsingException
from engine import dependencies
_customer_post_id = dependencies.DynamicVariable("_customer_post_id")
_product_post_id = dependencies.DynamicVariable("_product_post_id")
def parse_customerpost(data, **kwargs):
""" Automatically generated response parser """
# Declare response variables
temp_7262 = None
if 'headers' in kwargs:
headers = kwargs['headers']
# Parse body if needed
if data:
try:
data = json.loads(data)
except Exception as error:
raise ResponseParsingException("Exception parsing response, data was not valid json: {}".format(error))
pass
# Try to extract each dynamic object
try:
temp_7262 = str(data["id"])
except Exception as error:
# This is not an error, since some properties are not always returned
pass
# If no dynamic objects were extracted, throw.
if not (temp_7262):
raise ResponseParsingException("Error: all of the expected dynamic objects were not present in the response.")
# Set dynamic variables
if temp_7262:
dependencies.set_variable("_customer_post_id", temp_7262)
req_collection = requests.RequestCollection([])
# Endpoint: /customer, method: Post
request = requests.Request([
primitives.restler_static_string("POST "),
primitives.restler_basepath(""),
primitives.restler_static_string("/"),
primitives.restler_static_string("customer"),
primitives.restler_static_string("?"),
primitives.restler_static_string("string-query-param="),
primitives.restler_fuzzable_string("fuzzstring", quoted=False, examples=["the quick brown fox"]),
primitives.restler_static_string("&"),
primitives.restler_static_string("string-date-query-param="),
primitives.restler_fuzzable_date("2019-06-26", quoted=False, examples=['"2020-12-10"']),
primitives.restler_static_string("&"),
primitives.restler_static_string("string-date-time-query-param="),
primitives.restler_fuzzable_datetime("2019-06-26T20:20:39+00:00", quoted=False, examples=["2022-12-12"]),
primitives.restler_static_string("&"),
primitives.restler_static_string("string-password-query-param="),
primitives.restler_fuzzable_int("1", examples=["2987"]),
primitives.restler_static_string("&"),
primitives.restler_static_string("float-number-query-param="),
primitives.restler_fuzzable_number("1.23", examples=["2.32"]),
primitives.restler_static_string("&"),
primitives.restler_static_string("double-number-query-param="),
primitives.restler_fuzzable_number("1.23", examples=["9.999"]),
primitives.restler_static_string("&"),
primitives.restler_static_string("boolean-query-param="),
primitives.restler_fuzzable_bool("true", examples=["false"]),
primitives.restler_static_string(" HTTP/1.1\r\n"),
primitives.restler_static_string("Accept: application/json\r\n"),
primitives.restler_static_string("Host: \r\n"),
primitives.restler_static_string("Content-Type: "),
primitives.restler_static_string("application/json"),
primitives.restler_static_string("\r\n"),
primitives.restler_refreshable_authentication_token("authentication_token_tag"),
primitives.restler_static_string("\r\n"),
primitives.restler_static_string("{"),
primitives.restler_static_string("""
"id":"""),
primitives.restler_custom_payload("id", quoted=True),
primitives.restler_static_string(""",
"Person":
{
"int32-body-param":"""),
primitives.restler_fuzzable_int("1", examples=["321"]),
primitives.restler_static_string(""",
"int64-body-param":"""),
primitives.restler_fuzzable_int("1", examples=["200"]),
primitives.restler_static_string(""",
"int-body-param":"""),
primitives.restler_fuzzable_int("1", examples=["-30"]),
primitives.restler_static_string(""",
"obj-body-param":"""),
primitives.restler_fuzzable_object("{ \"fuzz\": false }", examples=["{\"tags\":{\"label\":\"important\"}}"]),
primitives.restler_static_string("""
}
}"""),
primitives.restler_static_string("\r\n"),
{
'post_send':
{
'parser': parse_customerpost,
'dependencies':
[
_customer_post_id.writer()
]
}
},
],
requestId="/customer"
)
req_collection.add_request(request)
# Endpoint: /customer/{customerId}, method: Get
request = requests.Request([
primitives.restler_static_string("GET "),
primitives.restler_basepath(""),
primitives.restler_static_string("/"),
primitives.restler_static_string("customer"),
primitives.restler_static_string("/"),
primitives.restler_static_string(_customer_post_id.reader(), quoted=False),
primitives.restler_static_string(" HTTP/1.1\r\n"),
primitives.restler_static_string("Accept: application/json\r\n"),
primitives.restler_static_string("Host: \r\n"),
primitives.restler_static_string("string-enum-header-param: "),
primitives.restler_fuzzable_group("string-enum-header-param", ['enum_val_1','enum_val_2'] ,quoted=False),
primitives.restler_static_string("\r\n"),
primitives.restler_refreshable_authentication_token("authentication_token_tag"),
primitives.restler_static_string("\r\n"),
],
requestId="/customer/{customerId}"
)
req_collection.add_request(request)
# Endpoint: /product, method: Post
request = requests.Request([
primitives.restler_static_string("POST "),
primitives.restler_basepath(""),
primitives.restler_static_string("/"),
primitives.restler_static_string("product"),
primitives.restler_static_string("?"),
primitives.restler_static_string("query-producer-param="),
primitives.restler_fuzzable_string("fuzzstring", quoted=False),
primitives.restler_static_string(" HTTP/1.1\r\n"),
primitives.restler_static_string("Accept: application/json\r\n"),
primitives.restler_static_string("Host: \r\n"),
primitives.restler_static_string("Content-Type: "),
primitives.restler_static_string("application/json"),
primitives.restler_static_string("\r\n"),
primitives.restler_refreshable_authentication_token("authentication_token_tag"),
primitives.restler_static_string("\r\n"),
primitives.restler_static_string("{"),
primitives.restler_static_string("""
"id":"""),
primitives.restler_custom_payload("id", quoted=True, writer=_product_post_id.writer()),
primitives.restler_static_string(""",
"info":
{
"int32-body-param":"""),
primitives.restler_fuzzable_int("1", examples=["321"]),
primitives.restler_static_string(""",
"int64-body-param":"""),
primitives.restler_fuzzable_int("1", examples=["200"]),
primitives.restler_static_string(""",
"int-body-param":"""),
primitives.restler_fuzzable_int("1", examples=["-30"]),
primitives.restler_static_string(""",
"obj-body-param":"""),
primitives.restler_fuzzable_object("{ \"fuzz\": false }", examples=["{\"tags\":{\"label\":\"important\"}}"]),
primitives.restler_static_string("""
}
}"""),
primitives.restler_static_string("\r\n"),
{
'post_send':
{
'dependencies':
[
_product_post_id.writer()
]
}
},
],
requestId="/product"
)
req_collection.add_request(request)
# Endpoint: /product/{productId}, method: Get
request = requests.Request([
primitives.restler_static_string("GET "),
primitives.restler_basepath(""),
primitives.restler_static_string("/"),
primitives.restler_static_string("product"),
primitives.restler_static_string("/"),
primitives.restler_static_string(_product_post_id.reader(), quoted=False),
primitives.restler_static_string(" HTTP/1.1\r\n"),
primitives.restler_static_string("Accept: application/json\r\n"),
primitives.restler_static_string("Host: \r\n"),
primitives.restler_refreshable_authentication_token("authentication_token_tag"),
primitives.restler_static_string("\r\n"),
],
requestId="/product/{productId}"
)
req_collection.add_request(request)

Просмотреть файл

@ -46,6 +46,8 @@ def set_grammar_schema(grammar_file_name, request_collection):
class SchemaParserTest(unittest.TestCase):
maxDiff = None
def setup(self):
try:
self.settings = Settings()
@ -85,16 +87,24 @@ class SchemaParserTest(unittest.TestCase):
return new_request
def check_equivalence(self, original_req, generated_req, req_collection, equal=True):
def check_equivalence(self, original_req, generated_req, req_collection, fuzzables_equal=True, custom_payloads_equal=True):
# Fuzzables equal
original_fuzzables=list(filter(lambda x : 'restler_fuzzable' in x[0] , original_req.definition))
generated_fuzzables=list(filter(lambda x : 'restler_fuzzable' in x[0] , generated_req.definition))
original_fuzzables = list(filter(lambda x: 'restler_fuzzable' in x[0], original_req.definition))
generated_fuzzables = list(filter(lambda x: 'restler_fuzzable' in x[0], generated_req.definition))
if equal:
if fuzzables_equal:
self.assertEqual(original_fuzzables, generated_fuzzables)
else:
self.assertNotEqual(original_fuzzables, generated_fuzzables)
# Custom payloads equal
original_custom_payloads = list(filter(lambda x: 'restler_custom_payload' in x[0], original_req.definition))
generated_custom_payloads = list(filter(lambda x: 'restler_custom_payload' in x[0], generated_req.definition))
if custom_payloads_equal:
self.assertEqual(original_custom_payloads, generated_custom_payloads)
else:
self.assertNotEqual(original_custom_payloads, generated_custom_payloads)
# TODO: enums equal
# Payloads equal
@ -109,7 +119,7 @@ class SchemaParserTest(unittest.TestCase):
generated_rendered_data = generated_rendered_data.replace("\n", "")
generated_rendered_data = generated_rendered_data.replace(" ", "")
if equal:
if fuzzables_equal and custom_payloads_equal:
self.assertEqual(original_rendered_data, generated_rendered_data)
else:
self.assertNotEqual(original_rendered_data, generated_rendered_data)
@ -201,7 +211,7 @@ class SchemaParserTest(unittest.TestCase):
req_current = next(req_current.get_body_param_combinations(combination_settings))
required_only_generated_req = req_current
original_rendering, generated_rendering =\
self.check_equivalence(req, required_only_generated_req, request_collection, equal=False)
self.check_equivalence(req, required_only_generated_req, request_collection, fuzzables_equal=False)
# Confirm that none of the optional parameters are present in the generated request.
optional_param_names = {
@ -261,7 +271,6 @@ class SchemaParserTest(unittest.TestCase):
for x, is_example in req_with_body.get_schema_combinations(use_grammar_py_schema=False):
self.assertTrue(len(x.definition) > 0)
def test_schema_with_uuid4_suffix_example(self):
"""Regression test for generating a python grammar from a schema with a uuid4_suffix in the body. """
self.setup()
@ -277,3 +286,74 @@ class SchemaParserTest(unittest.TestCase):
# Just go through and get all schema combinations. This makes sure there are no crashes.
for x, is_example in req_with_body.get_schema_combinations(use_grammar_py_schema=False):
self.assertTrue(len(x.definition) > 0)
def test_schema_with_all_supported_writers_example(self):
"""Regression test for all the ways dynamic objects can appear in the json grammar.
This test does a 'round trip' from the json to the original Python grammar and confirms
the payloads are identical. """
pass
def test_all_data_types_request(self):
def test_grammar(grammar_name, dictionary_file_name=None, all_params_required=False):
schema_json_file_name = f"{grammar_name}.json"
request_collection = get_python_grammar(grammar_name)
set_grammar_schema(schema_json_file_name, request_collection)
if dictionary_file_name is not None:
custom_mutations = json.load(open(dictionary_file_name, encoding='utf-8'))
request_collection.set_custom_mutations(custom_mutations, None, None)
pass
# Check the equivalence of the request in grammar.py (generated by the compiler)
# with the engine-generated request.
for idx, req in enumerate(request_collection):
# 2. Generate the Python grammar from this schema, and confirm it matches
# the expected Python grammar (generated by the RESTler compiler)
# Go through and generate the body, query, and headers
# then, call 'substitute' on the request.
# Then, make sure they match the original request.
# This is a "round trip" test for the request.
generated_req = self.generate_new_request(req, req.headers_schema, req.query_schema, req.body_schema)
# Checking for equality is not going to work because of the compiler
# feature to "merge" the grammars. We will have to validate as follows:
# 1) The same 'fuzzable' and 'custom payload' and 'enum' entries are there
# 2) the generated payload is the same.
self.check_equivalence(req, generated_req, request_collection)
# Now generate the request with required parameters only
combination_settings = {
"max_combinations": 1,
"param_kind": "optional"
}
req_current = req
req_current = next(req_current.get_header_param_combinations(combination_settings))
req_current = next(req_current.get_query_param_combinations(combination_settings))
if req.body_schema:
req_current = next(req_current.get_body_param_combinations(combination_settings))
required_only_generated_req = req_current
if all_params_required:
original_rendering, generated_rendering =\
self.check_equivalence(req, required_only_generated_req, request_collection, fuzzables_equal=True)
self.setup()
grammar_names = [
"simple_swagger_all_param_data_types_grammar",
"simple_swagger_all_param_data_types_local_examples_grammar",
"simple_swagger_with_annotations_grammar",
"demo_server_grammar",
# TODO: enable this after abstracting uuid suffix in the equivalence check
# "simple_swagger_annotations_uuid4_suffix" # todo rename 'grammar'
]
dict_file_name = get_grammar_file_path("simple_swagger_all_param_types_dict.json")
for grammar_name in grammar_names:
test_required = "demo_server" not in grammar_name
test_grammar(grammar_name, dict_file_name, all_params_required=test_required)

Просмотреть файл

@ -336,7 +336,7 @@ module Dependencies =
Restler.Workflow.Constants.DefaultRestlerGrammarFileName)
let grammar = File.ReadAllText(grammarFilePath)
Assert.True(grammar.Contains("""restler_custom_payload_uuid4_suffix("fileId", writer=_file__fileId__post_fileId_path.writer())"""))
Assert.True(grammar.Contains("""restler_custom_payload_uuid4_suffix("fileId", writer=_file__fileId__post_fileId_path.writer(), quoted=False)"""))
Assert.True(grammar.Contains("""restler_static_string(_file__fileId__post_fileId_path.reader(), quoted=False)"""))
// Validate (tag, label) annotation. tag - body producer (jsonpath), label: path parameter.

Просмотреть файл

@ -55,8 +55,13 @@ module Dictionary =
let grammar = File.ReadAllText(grammarFilePath)
// The grammar should contain both of the custom payload uuid suffixes from the dictionary
Assert.True(grammar.Contains("""primitives.restler_custom_payload_uuid4_suffix("resourceId"),"""))
Assert.True(grammar.Contains("""primitives.restler_custom_payload_uuid4_suffix("/resource/id"),"""))
Assert.True(grammar.Contains("""primitives.restler_custom_payload_uuid4_suffix("resourceId", quoted=False)"""))
// TODO: the generated grammar currently contains a known bug - the resoruce ID is an integer and is being
// assigned a uuid suffix, which currently only supports strings. The 'quoted' value is correctly 'False'
// because ID is an integer type, but
// in the future this should be a different primitive, e.g. 'custom_payload_unique_integer'
Assert.True(grammar.Contains("""primitives.restler_custom_payload_uuid4_suffix("/resource/id", quoted=False)"""))
[<Fact>]
/// Test that when a custom payload query (resp. header) is specified in the dictionary, it is injected.

Просмотреть файл

@ -405,10 +405,10 @@ module Examples =
// Make sure the grammar contains expected partial resource IDs (from the example)
Assert.True(grammar.Contains("primitives.restler_static_string(\"/frontendPorts/\")"))
Assert.True(grammar.Contains("primitives.restler_static_string(\"/frontendIPConfigurations/\")"))
Assert.True(grammar.Contains("primitives.restler_custom_payload_uuid4_suffix(\"frontendPorts_name\")"))
Assert.True(grammar.Contains("primitives.restler_custom_payload_uuid4_suffix(\"frontendIPConfigurations_name\")"))
Assert.False(grammar.Contains("primitives.restler_custom_payload_uuid4_suffix(\"frontendPort_name\")"))
Assert.False(grammar.Contains("primitives.restler_custom_payload_uuid4_suffix(\"frontendIPConfiguration_name\")"))
Assert.True(grammar.Contains("primitives.restler_custom_payload_uuid4_suffix(\"frontendPorts_name\", quoted=True)"))
Assert.True(grammar.Contains("primitives.restler_custom_payload_uuid4_suffix(\"frontendIPConfigurations_name\", quoted=True)"))
Assert.False(grammar.Contains("primitives.restler_custom_payload_uuid4_suffix(\"frontendPort_name\", quoted=True)"))
Assert.False(grammar.Contains("primitives.restler_custom_payload_uuid4_suffix(\"frontendIPConfiguration_name\", quoted=True)"))
Assert.True(grammar.Contains("appgwipc")) // This does not have a producer
Assert.False(grammar.Contains("appgwfip"))

Просмотреть файл

@ -85,7 +85,7 @@ module ApiSpecSchema =
Restler.Workflow.generateRestlerGrammar None config
let grammarOutputFilePath = config.GrammarOutputDirectoryPath.Value ++ Restler.Workflow.Constants.DefaultRestlerGrammarFileName
let grammar = File.ReadAllText(grammarOutputFilePath)
Assert.True(grammar.Contains("restler_custom_payload_uuid4_suffix(\"customerId\")"))
Assert.True(grammar.Contains("restler_custom_payload_uuid4_suffix(\"customerId\", quoted=False)"))
[<Fact>]
let ``swagger escape characters is parsed successfully`` () =

Просмотреть файл

@ -55,7 +55,7 @@ request = requests.Request([
primitives.restler_static_string("/"),
primitives.restler_static_string("app"),
primitives.restler_static_string("/"),
primitives.restler_custom_payload_uuid4_suffix("appId"),
primitives.restler_custom_payload_uuid4_suffix("appId", quoted=False),
primitives.restler_static_string(" HTTP/1.1\r\n"),
primitives.restler_static_string("Accept: application/json\r\n"),
primitives.restler_static_string("Host: localhost:8888\r\n"),

Просмотреть файл

@ -57,7 +57,7 @@ request = requests.Request([
primitives.restler_static_string("/"),
primitives.restler_static_string("app"),
primitives.restler_static_string("/"),
primitives.restler_custom_payload_uuid4_suffix("appId", writer=_app__appId__put_appId_path.writer()),
primitives.restler_custom_payload_uuid4_suffix("appId", writer=_app__appId__put_appId_path.writer(), quoted=False),
primitives.restler_static_string(" HTTP/1.1\r\n"),
primitives.restler_static_string("Accept: application/json\r\n"),
primitives.restler_static_string("Host: localhost:8888\r\n"),

Просмотреть файл

@ -36,7 +36,7 @@ request = requests.Request([
primitives.restler_static_string("PUT "),
primitives.restler_basepath(""),
primitives.restler_static_string("/"),
primitives.restler_custom_payload_uuid4_suffix("resourceName", writer=__resourceName__type_folder_put_resourceName_path.writer()),
primitives.restler_custom_payload_uuid4_suffix("resourceName", writer=__resourceName__type_folder_put_resourceName_path.writer(), quoted=False),
primitives.restler_static_string("?"),
primitives.restler_static_string("type=folder"),
primitives.restler_static_string(" HTTP/1.1\r\n"),
@ -74,7 +74,7 @@ request = requests.Request([
primitives.restler_static_string("PUT "),
primitives.restler_basepath(""),
primitives.restler_static_string("/"),
primitives.restler_custom_payload_uuid4_suffix("resourceName", writer=__resourceName__type_file_put_resourceName_path.writer()),
primitives.restler_custom_payload_uuid4_suffix("resourceName", writer=__resourceName__type_file_put_resourceName_path.writer(), quoted=False),
primitives.restler_static_string("?"),
primitives.restler_static_string("type=file"),
primitives.restler_static_string(" HTTP/1.1\r\n"),

Просмотреть файл

@ -51,7 +51,7 @@ module Types =
| Restler_custom_payload_header of string * DynamicObjectWriter option
| Restler_custom_payload_query of string * DynamicObjectWriter option
/// (Payload name, dynamic object writer name)
| Restler_custom_payload_uuid4_suffix of string * DynamicObjectWriter option
| Restler_custom_payload_uuid4_suffix of string * bool * DynamicObjectWriter option
| Restler_refreshable_authentication_token of string
| Restler_basepath of string
| Shadow_values of string
@ -118,7 +118,7 @@ let rec getRestlerPythonPayload (payload:FuzzingPayload) (isQuoted:bool) : Reque
| CustomPayloadType.String ->
Restler_custom_payload ({ defaultValue = c.payloadValue ; isQuoted = isQuoted ; exampleValue = None ; trackedParameterName = None }, dynamicObject)
| CustomPayloadType.UuidSuffix ->
Restler_custom_payload_uuid4_suffix (c.payloadValue, dynamicObject)
Restler_custom_payload_uuid4_suffix (c.payloadValue, isQuoted, dynamicObject)
| CustomPayloadType.Header ->
Restler_custom_payload_header (c.payloadValue, dynamicObject)
| CustomPayloadType.Query ->
@ -350,12 +350,12 @@ let generatePythonParameter includeOptionalParameters parameterSource parameterK
let needQuotes, isFuzzable, isDynamicObject =
match p.payload with
| FuzzingPayload.Custom c ->
let isFuzzable = (c.payloadType = CustomPayloadType.String)
let isFuzzable = true
// 'needQuotes' must be based on the underlying type of the payload.
let needQuotes =
(not c.isObject) &&
(isPrimitiveTypeQuoted c.primitiveType false)
needQuotes, isFuzzable, false
needQuotes, isFuzzable, false
| FuzzingPayload.Constant (PrimitiveType.String, s) ->
// TODO: improve the metadata of FuzzingPayload.Constant to capture whether
// the constant represents an object,
@ -1191,10 +1191,11 @@ let getRequests(requests:Request list) includeOptionalParameters =
p.defaultValue
(if p.isQuoted then "True" else "False")
(formatDynamicObjectVariable dynamicObject)
| Restler_custom_payload_uuid4_suffix (p, dynamicObject) ->
sprintf "primitives.restler_custom_payload_uuid4_suffix(\"%s\"%s)"
| Restler_custom_payload_uuid4_suffix (p, isQuoted, dynamicObject) ->
sprintf "primitives.restler_custom_payload_uuid4_suffix(\"%s\"%s, quoted=%s)"
p
(formatDynamicObjectVariable dynamicObject)
(if isQuoted then "True" else "False")
| Restler_custom_payload_header (p, dynamicObject) ->
sprintf "primitives.restler_custom_payload_header(\"%s\"%s)"
p