def parse(self, testcase_dict): testcase_dict = Parser.flatten_lowercase_keys_dict(testcase_dict) for keyword in TestCase.KEYWORD_DICT.keys(): value = testcase_dict.get(keyword) if value is None: continue if keyword == TestCaseKeywords.auth_username: self.auth_username = value elif keyword == TestCaseKeywords.auth_password: self.auth_password = value elif keyword == TestCaseKeywords.method: self.http_method = value elif keyword == TestCaseKeywords.delay: self.__delay = int(value) elif keyword == TestCaseKeywords.group: self.__group = value elif keyword == TestCaseKeywords.name: self.__name = value elif keyword == TestCaseKeywords.url: self.url = value elif keyword == TestCaseKeywords.extract_binds: self.extract_binds = value elif keyword == TestCaseKeywords.validators: self.validators = value elif keyword == TestCaseKeywords.headers: self.headers = value elif keyword == TestCaseKeywords.variable_binds: self.__variable_binds_dict = Parser.flatten_dictionaries(value) elif keyword == TestCaseKeywords.generator_binds: self.__generator_binds_dict = { str(k): str(v) for k, v in Parser.flatten_dictionaries(value) } elif keyword == TestCaseKeywords.options: raise NotImplementedError("Yet to Support") elif keyword == TestCaseKeywords.body: self.body = value elif keyword == TestCaseKeywords.absolute_urls: self.__abs_url = Parser.safe_to_bool(value) expected_status = testcase_dict.get(TestCaseKeywords.expected_status, []) if expected_status: self.expected_http_status_code_list = expected_status else: if self.http_method in ["POST", "PUT", "DELETE"]: self.expected_http_status_code_list = [200, 201, 204]
def parse_generator(configuration): """ Parses a configuration built from yaml and returns a generator Configuration should be a map """ from py3resttest.utils import Parser configuration = Parser.lowercase_keys(Parser.flatten_dictionaries(configuration)) gen_type = str(configuration.get(u'type')).lower() if gen_type not in GENERATOR_TYPES: raise ValueError( 'Generator type given {0} is not valid '.format(gen_type)) # Do the easy parsing, delegate more complex logic to parsing functions if gen_type == 'env_variable': return factory_env_variable(configuration['variable_name'])() elif gen_type == 'env_string': return factory_env_string(configuration['string'])() elif gen_type == 'number_sequence': start = int(configuration.get('start', 1)) increment = int(configuration.get('increment', 1)) return factory_generate_ids(start, increment)() elif gen_type == 'random_int': return generator_random_int32() elif gen_type == 'random_text': return parse_random_text_generator(configuration) elif gen_type in GENERATOR_TYPES: return GENERATOR_PARSING[gen_type](configuration) raise Exception("Unknown generator type: {0}".format('gen_type'))
def headers(self, headers): config_value = Parser.flatten_dictionaries(headers) if isinstance(config_value, dict): for key, value in config_value.items(): if isinstance(value, dict): if value.get('template'): self.set_template("headers", value.get('template')) self.__header_dict.update(config_value) else: raise ValidatorError( "Illegal header type: headers must be a dictionary or list of dictionary keys" )
def parse(config): from py3resttest.utils import Parser output = ExtractTestValidator() config = Parser.lowercase_keys(Parser.flatten_dictionaries(config)) output.config = config extractor = _get_extractor(config) output.extractor = extractor test_name = config['test'] output.test_name = test_name test_fn = VALIDATOR_TESTS[test_name] output.test_fn = test_fn return output
def extract_binds(self, bind_dict): bind_dict = Parser.flatten_dictionaries(bind_dict) for variable_name, extractor in bind_dict.items(): if not isinstance(extractor, dict) or len(extractor) == 0: raise BindError( "Extractors must be defined as maps of extractorType:{configs} with 1 entry" ) if len(extractor) > 1: raise BindError( "Cannot define multiple extractors for given variable name" ) for extractor_type, extractor_config in extractor.items(): self.__extract_binds_dict[variable_name] = parse_extractor( extractor_type, extractor_config)
def test_flatten_dictionaries(self): input_dict = {"x": 1, "y": 2} result_dict = Parser.flatten_dictionaries(input_dict) self.assertEqual(input_dict, result_dict) input_dict.update({"y": {"a": 1}}) result_dict = Parser.flatten_dictionaries(input_dict) self.assertEqual(input_dict, result_dict) result_dict = Parser.flatten_dictionaries( [input_dict, input_dict, input_dict]) self.assertEqual(input_dict, result_dict) result_dict = Parser.flatten_dictionaries([input_dict]) self.assertEqual(input_dict, result_dict) result_dict = Parser.flatten_dictionaries([{'x': 1}, input_dict]) self.assertEqual(input_dict, result_dict) result_dict = Parser.flatten_dictionaries([input_dict, {'x': 2}]) self.assertNotEqual(input_dict, result_dict) result_dict = Parser.flatten_dictionaries([{'x': 2}, input_dict]) self.assertEqual(input_dict, result_dict)
def parse(self, config_node): node = Parser.flatten_lowercase_keys_dict(config_node) for key, value in node.items(): if key == 'timeout': self.timeout = int(value) elif key == u'print_bodies': self.print_bodies = Parser.safe_to_bool(value) elif key == 'retries': self.retries = int(value) elif key == 'variable_binds': self.variable_binds = value elif key == u'generators': if not isinstance(value, list): raise TypeError( "generators in config should defined as list(array).") flat = Parser.flatten_dictionaries(value) gen_dict = {} for generator_name, generator_config in flat.items(): gen = parse_generator(generator_config) gen_dict[str(generator_name)] = gen self.generators = gen_dict
def variable_binds(self, variable_dict): """Variable binding """ if isinstance(variable_dict, dict): self.__variable_binds_dict.update( Parser.flatten_dictionaries(variable_dict))
def generator_binds(self, value: Dict): binds_dict = Parser.flatten_dictionaries(value) __binds_dict = {str(k): str(v) for k, v in binds_dict.items()} self.__generator_binds_dict.update(__binds_dict)
def parse(config): """ Create a validator that does an extract from body and applies a comparator, Then does comparison vs expected value Syntax sample: { jsonpath_mini: 'node.child', operator: 'eq', expected: 'myValue' } """ from py3resttest.utils import Parser output = ComparatorValidator() config = Parser.lowercase_keys(Parser.flatten_dictionaries(config)) output.config = config output.extractor = _get_extractor(config) if output.extractor is None: raise ValueError( "Extract function for comparison is not valid or not found!") if 'comparator' not in config: # Equals comparator if unspecified output.comparator_name = 'eq' else: output.comparator_name = config['comparator'].lower() try: output.comparator = COMPARATORS[output.comparator_name] except KeyError: raise ValueError("Invalid comparator given! %s " "available options are %s" % (output.comparator_name, COMPARATORS.keys())) if not output.comparator: raise ValueError("Invalid comparator given!") try: expected = config['expected'] except KeyError: raise ValueError( "No expected value found in comparator validator config, one must be!" ) # Expected value can be another extractor query, or a single value, or # a templated value if isinstance(expected, str) or isinstance(expected, (int, float, complex)): output.expected = expected elif isinstance(expected, dict): expected = Parser.lowercase_keys(expected) template = expected.get('template') if template: # Templated string if not isinstance(template, str): raise ValueError( "Can't template a comparator-validator unless template value is a string" ) output.is_template_expected = True output.expected = template else: # Extractor to compare against output.expected = _get_extractor(expected) if not output.expected: raise ValueError( "Can't supply a non-template, non-extract dictionary to comparator-validator" ) return output
def parse_content(node): """ Parse content from input node and returns ContentHandler object it'll look like: - template: - file: - temple: path or something """ # Tread carefully, this one is a bit narly because of nesting output = ContentHandler() is_template_path = False is_template_content = False is_file = False is_done = False while node and not is_done: # Dive through the configuration tree # Finally we've found the value! if isinstance(node, str): output.content = node output.setup(node, is_file=is_file, is_template_path=is_template_path, is_template_content=is_template_content) return output elif not isinstance(node, dict) and not isinstance(node, list): raise TypeError( "Content must be a string, dictionary, or list of dictionaries") is_done = True # Dictionary or list of dictionaries flat = Parser.lowercase_keys(Parser.flatten_dictionaries(node)) for key, value in flat.items(): if key == 'template': if isinstance(value, str): if is_file: value = os.path.abspath(value) output.content = value is_template_content = is_template_content or not is_file output.is_template_content = is_template_content output.is_template_path = is_file output.is_file = is_file return output else: is_template_content = True node = value is_done = False break elif key == 'file': if isinstance(value, str): output.content = os.path.abspath(value) output.is_file = True output.is_template_content = is_template_content return output else: is_file = True node = value is_done = False break raise Exception("Invalid configuration for content.")