def search_conf_item(start_path, item_type, item_name): """ search expected function or variable recursive upward @param start_path: search start path item_type: "function" or "variable" item_name: function name or variable name """ dir_path = os.path.dirname(os.path.abspath(start_path)) target_file = os.path.join(dir_path, "debugtalk.py") if os.path.isfile(target_file): imported_module = get_imported_module_from_file(target_file) items_dict = filter_module(imported_module, item_type) if item_name in items_dict: return items_dict[item_name] else: return search_conf_item(dir_path, item_type, item_name) if dir_path == start_path: # system root path err_msg = "{} not found in recursive upward path!".format(item_name) if item_type == "function": raise exceptions.FunctionNotFound(err_msg) else: raise exceptions.VariableNotFound(err_msg) return search_conf_item(dir_path, item_type, item_name)
def parse_function(content): """ parse function name and args from string content. @param (str) content @return (dict) function name and args e.g. func() => {'func_name': 'func', 'args': [], 'kwargs': {}} func(5) => {'func_name': 'func', 'args': [5], 'kwargs': {}} func(1, 2) => {'func_name': 'func', 'args': [1, 2], 'kwargs': {}} func(a=1, b=2) => {'func_name': 'func', 'args': [], 'kwargs': {'a': 1, 'b': 2}} func(1, 2, a=3, b=4) => {'func_name': 'func', 'args': [1, 2], 'kwargs': {'a':3, 'b':4}} """ matched = function_regexp_compile.match(content) if not matched: raise exceptions.FunctionNotFound("{} not found!".format(content)) function_meta = {"func_name": matched.group(1), "args": [], "kwargs": {}} args_str = matched.group(2).strip() if args_str == "": return function_meta args_list = args_str.split(',') for arg in args_list: arg = arg.strip() if '=' in arg: key, value = arg.split('=') function_meta["kwargs"][key.strip()] = parse_string_value( value.strip()) else: function_meta["args"].append(parse_string_value(arg)) return function_meta
def get_module_item(module_mapping, item_type, item_name): """ get expected function or variable from module mapping. Args: module_mapping(dict): module mapping with variables and functions. { "variables": {}, "functions": {} } item_type(str): "functions" or "variables" item_name(str): function name or variable name Returns: object: specified variable or function object. Raises: exceptions.FunctionNotFound: If specified function not found in module mapping exceptions.VariableNotFound: If specified variable not found in module mapping """ try: return module_mapping[item_type][item_name] except KeyError: err_msg = "{} not found in debugtalk.py module!\n".format(item_name) err_msg += "module mapping: {}".format(module_mapping) if item_type == "functions": raise exceptions.FunctionNotFound(err_msg) else: raise exceptions.VariableNotFound(err_msg)
def get_mapping_function(function_name, functions_mapping): """ get function from functions_mapping, if not found, then try to check if builtin function. Args: variable_name (str): variable name variables_mapping (dict): variables mapping Returns: mapping function object. Raises: exceptions.FunctionNotFound: function is neither defined in debugtalk.py nor builtin. """ if function_name in functions_mapping: return functions_mapping[function_name] try: return get_builtin_item("functions", function_name) except exceptions.FunctionNotFound: pass try: # check if builtin functions item_func = eval(function_name) if callable(item_func): # is builtin function return item_func except (NameError, TypeError): # is not builtin function raise exceptions.FunctionNotFound("{} is not found.".format(function_name))
def get_mapping_function(function_name, functions_mapping): """ get function from functions_mapping, if not found, then try to check if builtin function. Args: variable_name (str): variable name variables_mapping (dict): variables mapping Returns: mapping function object. Raises: exceptions.FunctionNotFound: function is neither defined in debugtalk.py nor builtin. """ if function_name in functions_mapping: return functions_mapping[function_name] try: # check if HttpRunner builtin functions from httprunner import loader built_in_functions = loader.load_builtin_functions() return built_in_functions[function_name] except KeyError: pass try: # check if Python builtin functions item_func = eval(function_name) if callable(item_func): # is builtin function return item_func except (NameError, TypeError): # is not builtin function raise exceptions.FunctionNotFound("{} is not found.".format(function_name))
def get_builtin_item(item_type, item_name): """ Args: item_type (enum): "variables" or "functions" item_name (str): variable name or function name Returns: variable or function with the name of item_name """ # override built_in module with debugtalk.py module from httprunner import loader built_in_module = loader.load_builtin_module() if item_type == "variables": try: return built_in_module["variables"][item_name] except KeyError: raise exceptions.VariableNotFound("{} is not found.".format(item_name)) else: # item_type == "functions": try: return built_in_module["functions"][item_name] except KeyError: raise exceptions.FunctionNotFound("{} is not found.".format(item_name))
def get_module_item(module_mapping, item_type, item_name): ''' get excepted function or variable from module mapping. Args: module_mapping (dict): module mapping with variables and functions. { 'variables':{}, 'functions':{} } item_type (str): 'functions' or 'variables' item_name (str): specified function name or variable name Returns: object: specified variable or function object. Raises: exceptions.FunctionNotFound: If specified function not found in module mapping. exceptions.VariableNotFound: If specified variable not found in module mapping. ''' try: return module_mapping[item_type][item_name] except KeyError: err_msg = f'{item_name} not found in confcustom.py module!' logger.log_error(err_msg) if item_type == 'functions': raise exceptions.FunctionNotFound(err_msg) else: raise exceptions.VariableNotFound(err_msg)
def _do_validation(self, validator_dict): """ validate with functions Args: validator_dict (dict): validator dict { "check": "status_code", "check_value": 200, "expect": 201, "comparator": "eq" } """ # TODO: move comparator uniform to init_test_suites comparator = utils.get_uniform_comparator(validator_dict["comparator"]) validate_func = self.TESTCASE_SHARED_FUNCTIONS_MAPPING.get(comparator) if not validate_func: raise exceptions.FunctionNotFound( "comparator not found: {}".format(comparator)) check_item = validator_dict["check"] check_value = validator_dict["check_value"] expect_value = validator_dict["expect"] if (check_value is None or expect_value is None) \ and comparator not in ["is", "eq", "equals", "=="]: raise exceptions.ParamsError( "Null value can only be compared with comparator: eq/equals/==" ) validate_msg = "validate: {} {} {}({})".format( check_item, comparator, expect_value, type(expect_value).__name__) try: validator_dict["check_result"] = "pass" validate_func(check_value, expect_value) validate_msg += "\t==> pass" logger.log_debug(validate_msg) except (AssertionError, TypeError): validate_msg += "\t==> fail" validate_msg += "\n{}({}) {} {}({})".format( check_value, type(check_value).__name__, comparator, expect_value, type(expect_value).__name__) logger.log_error(validate_msg) validator_dict["check_result"] = "fail" raise exceptions.ValidationFailure(validate_msg)
def _do_validation(self, validator_dict): ''' validator with functions Args: validator_dict (dict): validator dict { 'check':'status_code', 'check_value':200, 'expect':201, 'comparator':'eq' } ''' comparator = utils.get_uniform_comparator(validator_dict['comparator']) validate_func = self.TESTCASE_SHARED_FUNCTIONS_MAPPING.get(comparator) if not validate_func: raise exceptions.FunctionNotFound( f'comparator not found: {comparator}') check_item = validator_dict['check'] check_value = validator_dict['check_value'] expect_value = validator_dict['expect'] if (check_value is None or expect_value is None) \ and comparator not in ['equals']: raise exceptions.ParamError( 'Null value can only be comparated with comparator: eq/equals/==/is' ) validate_msg = 'validator: {} {} {} {}'.format( check_item, comparator, expect_value, type(expect_value).__name__) try: validator_dict['check_result'] = 'pass' validate_func(check_value, expect_value) validate_msg += '\t==> pass' logger.log_debug(validate_msg) except (AssertionError, TypeError): validate_msg += '\t==> fail' validate_msg += '\n{}({}) {} {}({})'.format( check_value, type(check_value).__name__, comparator, expect_value, type(expect_value).__name__) logger.log_error(validate_msg) validator_dict['check_result'] = 'fail' raise exceptions.VaildationFailure(validate_msg)
def get_mapping_function( function_name: Text, functions_mapping: FunctionsMapping ) -> Callable: """ get function from functions_mapping, if not found, then try to check if builtin function. Args: function_name (str): function name functions_mapping (dict): functions mapping Returns: mapping function object. Raises: exceptions.FunctionNotFound: function is neither defined in debugtalk.py nor builtin. """ if function_name in functions_mapping: return functions_mapping[function_name] elif function_name in ["parameterize", "P"]: return loader.load_csv_file elif function_name in ["environ", "ENV"]: return utils.get_os_environ elif function_name in ["multipart_encoder", "multipart_content_type"]: # extension for upload test from httprunner.ext import uploader return getattr(uploader, function_name) try: # check if HttpRunner builtin functions built_in_functions = loader.load_builtin_functions() return built_in_functions[function_name] except KeyError: pass try: # check if Python builtin functions return getattr(builtins, function_name) except AttributeError: pass raise exceptions.FunctionNotFound(f"{function_name} is not found.")
def parse_function(content): ''' parse function name and args from string expression Args: content (str): string content Returns: dict: function meta dict { "func_name":"xxx", "args":[], "kwargs":{} } Examples: >>> parse_function("func()") {'func_name': 'func','args': [],'kwargs': {}} >>> parse_function("func(5)") {'func_name': 'func','args': [5],'kwargs': {}} >>> parse_function("func(1, 2)") {'func_name': 'func','args': [1, 2],'kwargs': {}} >>> parse_function("func(a=1, b=2)") {'func_name': 'func','args': [],'kwargs': {'a': 1, 'b': 2}} >>> parse_function("func(1, 2, a=3, b=4)") {'func_name': 'func','args': [1, 2],'kwargs': {'a': 3, 'b': 4}} ''' matched = funciton_regexp_compile.match(content) if not matched: raise exceptions.FunctionNotFound(f'{content} not found!') function_meta = {"func_name": matched.group(1), "args": [], "kwargs": {}} args_str = matched.group(2).strip() if args_str == "": return function_meta args_list = args_str.split(',') for arg in args_list: arg = arg.strip() if "=" in arg: key, value = arg.split("=") function_meta["kwargs"][key.strip()] = parse_string_value( value.strip()) else: function_meta["args"].append(parse_string_value(arg)) return function_meta
def get_mapping_function(function_name, functions_mapping): """ get function from functions_mapping, if not found, then try to check if builtin function. Args: variable_name (str): variable name variables_mapping (dict): variables mapping Returns: mapping function object. Raises: exceptions.FunctionNotFound: function is neither defined in debugtalk.py nor builtin. """ if function_name in functions_mapping: return functions_mapping[function_name] elif function_name in ["parameterize", "P"]: from httprunner import loader return loader.load_csv_file elif function_name in ["environ", "ENV"]: return utils.get_os_environ try: # check if HttpRunner builtin functions from httprunner import loader built_in_functions = loader.load_builtin_functions() return built_in_functions[function_name] except KeyError: pass try: # check if Python builtin functions return getattr(builtins, function_name) except AttributeError: # is not builtin function raise exceptions.FunctionNotFound( "{} is not found.".format(function_name))
def get_mapping_funciton(function_name, functions_mapping): ''' get function from functions_mapping, if not found, then try to check if builtin function. Args: function_name (str): specified function name functions_mapping (dict): functions mapping Returns: mapping function object Raises: exceptions.FunctionNotFound: function is neither defined in confcustom.py nor builtin. ''' if function_name in functions_mapping: return functions_mapping[function_name] try: # check if built-in functions item_func = eval(function_name) if callable(item_func): return item_func except (NameError, TypeError): raise exceptions.FunctionNotFound(f'{function_name} is not found.')
def parse_function(content): """ parse function name and args from string content. @param (str) content @return (dict) function name and args e.g. func() => {'func_name': 'func', 'args': [], 'kwargs': {}} func(5) => {'func_name': 'func', 'args': [5], 'kwargs': {}} func(1, 2) => {'func_name': 'func', 'args': [1, 2], 'kwargs': {}} func(a=1, b=2) => {'func_name': 'func', 'args': [], 'kwargs': {'a': 1, 'b': 2}} func(1, 2, a=3, b=4) => {'func_name': 'func', 'args': [1, 2], 'kwargs': {'a':3, 'b':4}} """ matched = function_regexp_compile.match(content) if not matched: raise exceptions.FunctionNotFound("{} not found!".format(content)) function_meta = {"func_name": matched.group(1), "args": [], "kwargs": {}} args_str = matched.group(2).strip() if args_str == "": return function_meta # args_list = args_str.split(',') # for arg in args_list: # arg = arg.strip() # if '=' in arg: # key, value = arg.split('=') # function_meta["kwargs"][key.strip()] = parse_string_value(value.strip()) # else: # function_meta["args"].append(parse_string_value(arg)) # return function_meta # 函数入参列表提取正则表达式,太长,分开写 # 第一段是提取《key=》,0/1个,等号前后可以带空白符号,只提取出key。 # 例子(1,a=2),提取出来后第一个key为空,第二个key为a r = r"""(?:(\w+?)\s*?=\s*?)?(?#可带key=,允许等号前后有空白符号,分组但不提取,只提取key)""" # 第二段是提取《value》,可以匹配python各种数据类型:整数、浮点数、列表、元组、字典、布尔值、字串(单双引号)、日期格式,以及httprunner变量$name这种情况 # 例子:($name, 1,2,[1,2],(1,), a=(1,), b=True, c=[1,2], d={'a':1,'b':2}) r = r + r"""(\w+\.\w+|\".*?\"|\'.*?\'|\{.*?\}|\(.*?\)|\[.*?\]|-?\d+\.?\d+|-?\d|\w+|\$\w+)""" # s = """$name, 1, 1.1, 'abc', False, [1,2], (1,), {'a':1,'b':2}, tu=(1,2), li=[1,2], dic={'a':1,'b':2}, st='abcd', fmt='%Y%m%d'""" # r=r"""(?:(\w+?)\s*?=\s*?)?(\'.*?\'|\{.*?\}|\(.*?\)|\[.*?\]|\d+\.?\d+|\d|\w+|\$\w+)""" # lis = re.findall(r, s) # for x in lis: # print(x) # 提取结果: # ('', '$name') # ('', '1') # ('', '1.1') # ('', "'abc'") # ('', 'False') # ('', '[1,2]') # ('', '(1,)') # ('', "{'a':1,'b':2}") # ('tu', '(1,2)') # ('li', '[1,2]') # ('dic', "{'a':1,'b':2}") # ('st', "'abcd'") # ('fmt', "'%Y%m%d'") args_list = re.findall(r, args_str) for key, value in args_list: if key: function_meta["kwargs"][key.strip()] = parse_string_value( value.strip()) else: function_meta["args"].append(parse_string_value(value)) return function_meta