示例#1
0
def query_json(json_content, query, delimiter='.'):
    """ Do an xpath-like query with json_content.
    @param (json_content) json_content
        json_content = {
            "ids": [1, 2, 3, 4],
            "person": {
                "name": {
                    "first_name": "Leo",
                    "last_name": "Lee",
                },
                "age": 29,
                "cities": ["Guangzhou", "Shenzhen"]
            }
        }
    @param (str) query
        "person.name.first_name"  =>  "Leo"
        "person.cities.0"         =>  "Guangzhou"
    @return queried result
    """
    if json_content == "":
        raise exception.ResponseError("response content is empty!")

    try:
        for key in query.split(delimiter):
            if isinstance(json_content, list):
                json_content = json_content[int(key)]
            elif isinstance(json_content, (dict, CaseInsensitiveDict)):
                json_content = json_content[key]
            else:
                raise exception.ParseResponseError(
                    "response content is in text format! failed to query key {}!".format(key))
    except (KeyError, ValueError, IndexError):
        raise exception.ParseResponseError("failed to query json when extracting response!")

    return json_content
示例#2
0
    def validate(self, validators, variables_mapping):
        """ Bind named validators to value within the context.
        @param (list) validators
            [
                {"check": "status_code", "comparator": "eq", "expect": 201},
                {"check": "resp_body_success", "comparator": "eq", "expect": True}
            ]
        @param (dict) variables_mapping
            {
                "resp_body_success": True
            }
        @return (list) content differences
            [
                {
                    "check": "status_code",
                    "comparator": "eq", "expect": 201, "value": 200
                }
            ]
        """
        for validator_dict in validators:

            check_item = validator_dict.get("check")
            if not check_item:
                raise exception.ParamsError(
                    "check item invalid: {}".format(check_item))

            if "expect" in validator_dict:
                expect_value = validator_dict.get("expect")
            elif "expected" in validator_dict:
                expect_value = validator_dict.get("expected")
            else:
                raise exception.ParamsError(
                    "expected value missed in testcase validator!")

            comparator = validator_dict.get("comparator", "eq")

            if check_item in variables_mapping:
                validator_dict["actual_value"] = variables_mapping[check_item]
            else:
                try:
                    validator_dict["actual_value"] = self.extract_field(
                        check_item)
                except exception.ParseResponseError:
                    raise exception.ParseResponseError(
                        "failed to extract check item in response!")

            utils.match_expected(validator_dict["actual_value"], expect_value,
                                 comparator, check_item)

        return True
示例#3
0
    def eval_check_item(self, validator, resp_obj):
        """ evaluate check item in validator
        @param (dict) validator
            {"check": "status_code", "comparator": "eq", "expect": 201}
            {"check": "$resp_body_success", "comparator": "eq", "expect": True}
        @param (object) resp_obj
        @return (dict) validator info
            {
                "check": "status_code",
                "check_value": 200,
                "expect": 201,
                "comparator": "eq"
            }
        """
        check_item = validator["check"]
        # check_item should only be the following 5 formats:
        # 1, variable reference, e.g. $token
        # 2, function reference, e.g. ${is_status_code_200($status_code)}
        # 3, dict or list, maybe containing variable/function reference, e.g. {"var": "$abc"}
        # 4, string joined by delimiter. e.g. "status_code", "headers.content-type"
        # 5, regex string, e.g. "LB[\d]*(.*)RB[\d]*"

        if isinstance(check_item, (dict, list)) \
            or testcase.extract_variables(check_item) \
            or testcase.extract_functions(check_item):
            # format 1/2/3
            check_value = self.eval_content(check_item)
        else:
            try:
                # format 4/5
                check_value = resp_obj.extract_field(check_item)
            except exception.ParseResponseError:
                msg = "failed to extract check item from response!\n"
                msg += "response content: {}".format(resp_obj.content)
                raise exception.ParseResponseError(msg)

        validator["check_value"] = check_value

        # expect_value should only be in 2 types:
        # 1, variable reference, e.g. $expect_status_code
        # 2, actual value, e.g. 200
        expect_value = self.eval_content(validator["expect"])
        validator["expect"] = expect_value
        validator["check_result"] = "unchecked"
        return validator
    def eval_check_item(self, validator, resp_obj):
        """ evaluate check item in validator
        @param (dict) validator
            {"check": "status_code", "comparator": "eq", "expect": 201}
            {"check": "$resp_body_success", "comparator": "eq", "expect": True}
        @param (object) resp_obj
        @return (dict) validator info
            {
                "check": "status_code",
                "check_value": 200,
                "expect": 201,
                "comparator": "eq"
            }
        """
        check_item = validator["check"]
        # check_item should only be in 3 types:
        # 1, variable reference, e.g. $token
        # 2, string joined by delimiter. e.g. "status_code", "headers.content-type"
        # 3, regex string, e.g. "LB[\d]*(.*)RB[\d]*"
        if testcase.extract_variables(check_item):
            # type 1
            check_value = self.testcase_parser.eval_content_variables(
                check_item)
        else:
            try:
                # type 2 or type 3
                check_value = resp_obj.extract_field(check_item)
            except exception.ParseResponseError:
                raise exception.ParseResponseError(
                    "failed to extract check item in response!")

        validator["check_value"] = check_value

        # expect_value should only be in 2 types:
        # 1, variable reference, e.g. $expect_status_code
        # 2, actual value, e.g. 200
        expect_value = self.testcase_parser.eval_content_variables(
            validator["expect"])
        validator["expect"] = expect_value
        return validator
示例#5
0
    def parse_validator(self, validator, resp_obj):
        """ parse validator, validator maybe in two format
        @param (dict) validator
            format1: this is kept for compatiblity with the previous versions.
                {"check": "status_code", "comparator": "eq", "expect": 201}
                {"check": "$resp_body_success", "comparator": "eq", "expect": True}
            format2: recommended new version
                {'eq': ['status_code', 201]}
                {'eq': ['$resp_body_success', True]}
        @param (object) resp_obj
        @return (dict) validator info
            {
                "check_item": check_item,
                "check_value": check_value,
                "expect_value": expect_value,
                "comparator": comparator
            }
        """
        if not isinstance(validator, dict):
            raise exception.ParamsError(
                "invalid validator: {}".format(validator))

        if "check" in validator and len(validator) > 1:
            # format1
            check_item = validator.get("check")

            if "expect" in validator:
                expect_value = validator.get("expect")
            elif "expected" in validator:
                expect_value = validator.get("expected")
            else:
                raise exception.ParamsError(
                    "invalid validator: {}".format(validator))

            comparator = validator.get("comparator", "eq")

        elif len(validator) == 1:
            # format2
            comparator = list(validator.keys())[0]
            compare_values = validator[comparator]

            if not isinstance(compare_values,
                              list) or len(compare_values) != 2:
                raise exception.ParamsError(
                    "invalid validator: {}".format(validator))

            check_item, expect_value = compare_values

        else:
            raise exception.ParamsError(
                "invalid validator: {}".format(validator))

        # check_item should only be in 3 type:
        # 1, variable reference, e.g. $token
        # 2, string joined by delimiter. e.g. "status_code", "headers.content-type"
        # 3, regex string, e.g. "LB[\d]*(.*)RB[\d]*"
        if testcase.extract_variables(check_item):
            # type 1
            check_value = self.testcase_parser.eval_content_variables(
                check_item)
        else:
            try:
                # type 2 or type 3
                check_value = resp_obj.extract_field(check_item)
            except exception.ParseResponseError:
                raise exception.ParseResponseError(
                    "failed to extract check item in response!")

        expect_value = self.testcase_parser.eval_content_variables(
            expect_value)

        validator_dict = {
            "check_item": check_item,
            "check_value": check_value,
            "expect_value": expect_value,
            "comparator": comparator
        }
        return validator_dict