Beispiel #1
0
class VariableBindsUnittest(ApiServerUnittest):
    def setUp(self):
        self.context = Context()
        testcase_file_path = os.path.join(os.getcwd(),
                                          'tests/data/demo_binds.yml')
        self.testcases = testcase.load_file(testcase_file_path)

    def test_context_init_functions(self):
        self.assertIn("get_timestamp", self.context.testset_functions_config)
        self.assertIn("gen_random_string",
                      self.context.testset_functions_config)

        variables = [{
            "random": "${gen_random_string(5)}"
        }, {
            "timestamp10": "${get_timestamp(10)}"
        }]
        self.context.bind_variables(variables)
        context_variables = self.context.testcase_variables_mapping

        self.assertEqual(len(context_variables["random"]), 5)
        self.assertEqual(len(context_variables["timestamp10"]), 10)

    def test_context_bind_testset_variables(self):
        # testcase in JSON format
        testcase1 = {
            "variables": [{
                "GLOBAL_TOKEN": "debugtalk"
            }, {
                "token": "$GLOBAL_TOKEN"
            }]
        }
        # testcase in YAML format
        testcase2 = self.testcases["bind_variables"]

        for testcase in [testcase1, testcase2]:
            variables = testcase['variables']
            self.context.bind_variables(variables, level="testset")

            testset_variables = self.context.testset_shared_variables_mapping
            testcase_variables = self.context.testcase_variables_mapping
            self.assertIn("GLOBAL_TOKEN", testset_variables)
            self.assertIn("GLOBAL_TOKEN", testcase_variables)
            self.assertEqual(testset_variables["GLOBAL_TOKEN"], "debugtalk")
            self.assertIn("token", testset_variables)
            self.assertIn("token", testcase_variables)
            self.assertEqual(testset_variables["token"], "debugtalk")

    def test_context_bind_testcase_variables(self):
        testcase1 = {
            "variables": [{
                "GLOBAL_TOKEN": "debugtalk"
            }, {
                "token": "$GLOBAL_TOKEN"
            }]
        }
        testcase2 = self.testcases["bind_variables"]

        for testcase in [testcase1, testcase2]:
            variables = testcase['variables']
            self.context.bind_variables(variables)

            testset_variables = self.context.testset_shared_variables_mapping
            testcase_variables = self.context.testcase_variables_mapping
            self.assertNotIn("GLOBAL_TOKEN", testset_variables)
            self.assertIn("GLOBAL_TOKEN", testcase_variables)
            self.assertEqual(testcase_variables["GLOBAL_TOKEN"], "debugtalk")
            self.assertNotIn("token", testset_variables)
            self.assertIn("token", testcase_variables)
            self.assertEqual(testcase_variables["token"], "debugtalk")

    def test_context_bind_lambda_functions(self):
        testcase1 = {
            "function_binds": {
                "add_one": lambda x: x + 1,
                "add_two_nums": lambda x, y: x + y
            },
            "variables": [{
                "add1": "${add_one(2)}"
            }, {
                "sum2nums": "${add_two_nums(2,3)}"
            }]
        }
        testcase2 = self.testcases["bind_lambda_functions"]

        for testcase in [testcase1, testcase2]:
            function_binds = testcase.get('function_binds', {})
            self.context.bind_functions(function_binds)

            variables = testcase['variables']
            self.context.bind_variables(variables)

            context_variables = self.context.testcase_variables_mapping
            self.assertIn("add1", context_variables)
            self.assertEqual(context_variables["add1"], 3)
            self.assertIn("sum2nums", context_variables)
            self.assertEqual(context_variables["sum2nums"], 5)

    def test_context_bind_lambda_functions_with_import(self):
        testcase1 = {
            "requires": ["random", "string", "hashlib"],
            "function_binds": {
                "gen_random_string":
                "lambda str_len: ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(str_len))",
                "gen_md5":
                "lambda *str_args: hashlib.md5(''.join(str_args).encode('utf-8')).hexdigest()"
            },
            "variables": [{
                "TOKEN": "debugtalk"
            }, {
                "random": "${gen_random_string(5)}"
            }, {
                "data": '{"name": "user", "password": "******"}'
            }, {
                "authorization": "${gen_md5($TOKEN, $data, $random)}"
            }]
        }
        testcase2 = self.testcases["bind_lambda_functions_with_import"]

        for testcase in [testcase1, testcase2]:
            requires = testcase.get('requires', [])
            self.context.import_requires(requires)

            function_binds = testcase.get('function_binds', {})
            self.context.bind_functions(function_binds)

            variables = testcase['variables']
            self.context.bind_variables(variables)
            context_variables = self.context.testcase_variables_mapping

            self.assertIn("TOKEN", context_variables)
            TOKEN = context_variables["TOKEN"]
            self.assertEqual(TOKEN, "debugtalk")
            self.assertIn("random", context_variables)
            self.assertIsInstance(context_variables["random"], str)
            self.assertEqual(len(context_variables["random"]), 5)
            random = context_variables["random"]
            self.assertIn("data", context_variables)
            data = context_variables["data"]
            self.assertIn("authorization", context_variables)
            self.assertEqual(len(context_variables["authorization"]), 32)
            authorization = context_variables["authorization"]
            self.assertEqual(utils.gen_md5(TOKEN, data, random), authorization)

    def test_import_module_items(self):
        testcase1 = {
            "import_module_items": ["tests.data.debugtalk"],
            "variables": [{
                "TOKEN": "debugtalk"
            }, {
                "random": "${gen_random_string(5)}"
            }, {
                "data": '{"name": "user", "password": "******"}'
            }, {
                "authorization": "${gen_md5($TOKEN, $data, $random)}"
            }]
        }
        testcase2 = self.testcases["bind_module_functions"]

        for testcase in [testcase1, testcase2]:
            module_items = testcase.get('import_module_items', [])
            self.context.import_module_items(module_items)

            variables = testcase['variables']
            self.context.bind_variables(variables)
            context_variables = self.context.testcase_variables_mapping

            self.assertIn("TOKEN", context_variables)
            TOKEN = context_variables["TOKEN"]
            self.assertEqual(TOKEN, "debugtalk")
            self.assertIn("random", context_variables)
            self.assertIsInstance(context_variables["random"], str)
            self.assertEqual(len(context_variables["random"]), 5)
            random = context_variables["random"]
            self.assertIn("data", context_variables)
            data = context_variables["data"]
            self.assertIn("authorization", context_variables)
            self.assertEqual(len(context_variables["authorization"]), 32)
            authorization = context_variables["authorization"]
            self.assertEqual(utils.gen_md5(TOKEN, data, random), authorization)
            self.assertIn("SECRET_KEY", context_variables)
            SECRET_KEY = context_variables["SECRET_KEY"]
            self.assertEqual(SECRET_KEY, "DebugTalk")

    def test_get_parsed_request(self):
        test_runner = runner.Runner()
        testcase = {
            "import_module_items": ["tests.data.debugtalk"],
            "variables": [{
                "TOKEN": "debugtalk"
            }, {
                "random": "${gen_random_string(5)}"
            }, {
                "data": '{"name": "user", "password": "******"}'
            }, {
                "authorization": "${gen_md5($TOKEN, $data, $random)}"
            }],
            "request": {
                "url": "http://127.0.0.1:5000/api/users/1000",
                "METHOD": "POST",
                "Headers": {
                    "Content-Type": "application/json",
                    "authorization": "$authorization",
                    "random": "$random",
                    "SECRET_KEY": "$SECRET_KEY"
                },
                "Data": "$data"
            }
        }
        parsed_request = test_runner.init_config(testcase, level="testcase")
        self.assertIn("authorization", parsed_request["headers"])
        self.assertEqual(len(parsed_request["headers"]["authorization"]), 32)
        self.assertIn("random", parsed_request["headers"])
        self.assertEqual(len(parsed_request["headers"]["random"]), 5)
        self.assertIn("data", parsed_request)
        self.assertEqual(parsed_request["data"],
                         testcase["variables"][2]["data"])
        self.assertEqual(parsed_request["headers"]["secret_key"], "DebugTalk")

    def test_exec_content_functions(self):
        test_runner = runner.Runner()
        content = "${sleep(1)}"
        start_time = time.time()
        test_runner.context.eval_content(content)
        end_time = time.time()
        elapsed_time = end_time - start_time
        self.assertGreater(elapsed_time, 1)

    def test_do_validation(self):
        self.context.do_validation({
            "check": "check",
            "check_value": 1,
            "expect": 1,
            "comparator": "eq"
        })
        self.context.do_validation({
            "check": "check",
            "check_value": "abc",
            "expect": "abc",
            "comparator": "=="
        })

        config_dict = {"path": 'tests/data/demo_testset_hardcode.yml'}
        self.context.config_context(config_dict, "testset")
        self.context.do_validation({
            "check": "status_code",
            "check_value": "201",
            "expect": 3,
            "comparator": "sum_status_code"
        })

    def test_validate(self):
        url = "http://127.0.0.1:5000/"
        resp = requests.get(url)
        resp_obj = response.ResponseObject(resp)

        validators = [{
            "eq": ["$resp_status_code", 201]
        }, {
            "check": "$resp_status_code",
            "comparator": "eq",
            "expect": 201
        }, {
            "check": "$resp_body_success",
            "comparator": "eq",
            "expect": True
        }]
        variables = [{"resp_status_code": 200}, {"resp_body_success": True}]
        self.context.bind_variables(variables)

        with self.assertRaises(exception.ValidationError):
            self.context.validate(validators, resp_obj)

        variables = [{"resp_status_code": 201}, {"resp_body_success": True}]
        self.context.bind_variables(variables)

        self.assertTrue(self.context.validate(validators, resp_obj))

    def test_validate_exception(self):
        url = "http://127.0.0.1:5000/"
        resp = requests.get(url)
        resp_obj = response.ResponseObject(resp)

        # expected value missed in validators
        validators = [{
            "eq": ["$resp_status_code", 201]
        }, {
            "check": "$resp_status_code",
            "comparator": "eq",
            "expect": 201
        }, {
            "check": "$resp_body_success",
            "comparator": "eq",
            "expect": True
        }]
        variables = []
        self.context.bind_variables(variables)

        with self.assertRaises(exception.ParamsError):
            self.context.validate(validators, resp_obj)

        # expected value missed in variables mapping
        variables = [{"resp_status_code": 200}]
        self.context.bind_variables(variables)

        with self.assertRaises(exception.ValidationError):
            self.context.validate(validators, resp_obj)
Beispiel #2
0
class VariableBindsUnittest(unittest.TestCase):

    def setUp(self):
        self.context = Context()
        testcase_file_path = os.path.join(os.getcwd(), 'tests/data/demo_binds.yml')
        self.testcases = testcase._load_file(testcase_file_path)

    def test_context_init_functions(self):
        self.assertIn("get_timestamp", self.context.testset_functions_config)
        self.assertIn("gen_random_string", self.context.testset_functions_config)

        variables = [
            {"random": "${gen_random_string(5)}"},
            {"timestamp10": "${get_timestamp(10)}"}
        ]
        self.context.bind_variables(variables)
        context_variables = self.context.get_testcase_variables_mapping()

        self.assertEqual(len(context_variables["random"]), 5)
        self.assertEqual(len(context_variables["timestamp10"]), 10)

    def test_context_bind_testset_variables(self):
        # testcase in JSON format
        testcase1 = {
            "variables": [
                {"GLOBAL_TOKEN": "debugtalk"},
                {"token": "$GLOBAL_TOKEN"}
            ]
        }
        # testcase in YAML format
        testcase2 = self.testcases["bind_variables"]

        for testcase in [testcase1, testcase2]:
            variables = testcase['variables']
            self.context.bind_variables(variables, level="testset")

            testset_variables = self.context.testset_shared_variables_mapping
            testcase_variables = self.context.get_testcase_variables_mapping()
            self.assertIn("GLOBAL_TOKEN", testset_variables)
            self.assertIn("GLOBAL_TOKEN", testcase_variables)
            self.assertEqual(testset_variables["GLOBAL_TOKEN"], "debugtalk")
            self.assertIn("token", testset_variables)
            self.assertIn("token", testcase_variables)
            self.assertEqual(testset_variables["token"], "debugtalk")

    def test_context_bind_testcase_variables(self):
        testcase1 = {
            "variables": [
                {"GLOBAL_TOKEN": "debugtalk"},
                {"token": "$GLOBAL_TOKEN"}
            ]
        }
        testcase2 = self.testcases["bind_variables"]

        for testcase in [testcase1, testcase2]:
            variables = testcase['variables']
            self.context.bind_variables(variables)

            testset_variables = self.context.testset_shared_variables_mapping
            testcase_variables = self.context.get_testcase_variables_mapping()
            self.assertNotIn("GLOBAL_TOKEN", testset_variables)
            self.assertIn("GLOBAL_TOKEN", testcase_variables)
            self.assertEqual(testcase_variables["GLOBAL_TOKEN"], "debugtalk")
            self.assertNotIn("token", testset_variables)
            self.assertIn("token", testcase_variables)
            self.assertEqual(testcase_variables["token"], "debugtalk")

    def test_context_bind_lambda_functions(self):
        testcase1 = {
            "function_binds": {
                "add_one": lambda x: x + 1,
                "add_two_nums": lambda x, y: x + y
            },
            "variables": [
                {"add1": "${add_one(2)}"},
                {"sum2nums": "${add_two_nums(2,3)}"}
            ]
        }
        testcase2 = self.testcases["bind_lambda_functions"]

        for testcase in [testcase1, testcase2]:
            function_binds = testcase.get('function_binds', {})
            self.context.bind_functions(function_binds)

            variables = testcase['variables']
            self.context.bind_variables(variables)

            context_variables = self.context.get_testcase_variables_mapping()
            self.assertIn("add1", context_variables)
            self.assertEqual(context_variables["add1"], 3)
            self.assertIn("sum2nums", context_variables)
            self.assertEqual(context_variables["sum2nums"], 5)

    def test_context_bind_lambda_functions_with_import(self):
        testcase1 = {
            "requires": ["random", "string", "hashlib"],
            "function_binds": {
                "gen_random_string": "lambda str_len: ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(str_len))",
                "gen_md5": "lambda *str_args: hashlib.md5(''.join(str_args).encode('utf-8')).hexdigest()"
            },
            "variables": [
                {"TOKEN": "debugtalk"},
                {"random": "${gen_random_string(5)}"},
                {"data": '{"name": "user", "password": "******"}'},
                {"authorization": "${gen_md5($TOKEN, $data, $random)}"}
            ]
        }
        testcase2 = self.testcases["bind_lambda_functions_with_import"]

        for testcase in [testcase1, testcase2]:
            requires = testcase.get('requires', [])
            self.context.import_requires(requires)

            function_binds = testcase.get('function_binds', {})
            self.context.bind_functions(function_binds)

            variables = testcase['variables']
            self.context.bind_variables(variables)
            context_variables = self.context.get_testcase_variables_mapping()

            self.assertIn("TOKEN", context_variables)
            TOKEN = context_variables["TOKEN"]
            self.assertEqual(TOKEN, "debugtalk")
            self.assertIn("random", context_variables)
            self.assertIsInstance(context_variables["random"], str)
            self.assertEqual(len(context_variables["random"]), 5)
            random = context_variables["random"]
            self.assertIn("data", context_variables)
            data = context_variables["data"]
            self.assertIn("authorization", context_variables)
            self.assertEqual(len(context_variables["authorization"]), 32)
            authorization = context_variables["authorization"]
            self.assertEqual(utils.gen_md5(TOKEN, data, random), authorization)

    def test_import_module_items(self):
        testcase1 = {
            "import_module_items": ["tests.data.debugtalk"],
            "variables": [
                {"TOKEN": "debugtalk"},
                {"random": "${gen_random_string(5)}"},
                {"data": '{"name": "user", "password": "******"}'},
                {"authorization": "${gen_md5($TOKEN, $data, $random)}"}
            ]
        }
        testcase2 = self.testcases["bind_module_functions"]

        for testcase in [testcase1, testcase2]:
            module_items = testcase.get('import_module_items', [])
            self.context.import_module_items(module_items)

            variables = testcase['variables']
            self.context.bind_variables(variables)
            context_variables = self.context.get_testcase_variables_mapping()

            self.assertIn("TOKEN", context_variables)
            TOKEN = context_variables["TOKEN"]
            self.assertEqual(TOKEN, "debugtalk")
            self.assertIn("random", context_variables)
            self.assertIsInstance(context_variables["random"], str)
            self.assertEqual(len(context_variables["random"]), 5)
            random = context_variables["random"]
            self.assertIn("data", context_variables)
            data = context_variables["data"]
            self.assertIn("authorization", context_variables)
            self.assertEqual(len(context_variables["authorization"]), 32)
            authorization = context_variables["authorization"]
            self.assertEqual(utils.gen_md5(TOKEN, data, random), authorization)
            self.assertIn("SECRET_KEY", context_variables)
            SECRET_KEY = context_variables["SECRET_KEY"]
            self.assertEqual(SECRET_KEY, "DebugTalk")

    def test_get_parsed_request(self):
        test_runner = runner.Runner()
        testcase = {
            "import_module_items": ["tests.data.debugtalk"],
            "variables": [
                {"TOKEN": "debugtalk"},
                {"random": "${gen_random_string(5)}"},
                {"data": '{"name": "user", "password": "******"}'},
                {"authorization": "${gen_md5($TOKEN, $data, $random)}"}
            ],
            "request": {
                "url": "http://127.0.0.1:5000/api/users/1000",
                "METHOD": "POST",
                "Headers": {
                    "Content-Type": "application/json",
                    "authorization": "$authorization",
                    "random": "$random",
                    "SECRET_KEY": "$SECRET_KEY"
                },
                "Data": "$data"
            }
        }
        parsed_request = test_runner.init_config(testcase, level="testcase")
        self.assertIn("authorization", parsed_request["headers"])
        self.assertEqual(len(parsed_request["headers"]["authorization"]), 32)
        self.assertIn("random", parsed_request["headers"])
        self.assertEqual(len(parsed_request["headers"]["random"]), 5)
        self.assertIn("data", parsed_request)
        self.assertEqual(parsed_request["data"], testcase["variables"][2]["data"])
        self.assertEqual(parsed_request["headers"]["SECRET_KEY"], "DebugTalk")

    def test_exec_content_functions(self):
        test_runner = runner.Runner()
        content = "${sleep(1)}"
        start_time = time.time()
        test_runner.context.exec_content_functions(content)
        end_time = time.time()
        elapsed_time = end_time - start_time
        self.assertGreater(elapsed_time, 1)
class VariableBindsUnittest(ApiServerUnittest):

    def setUp(self):
        self.context = Context()
        testcase_file_path = os.path.join(os.getcwd(), 'tests/data/demo_binds.yml')
        self.testcases = FileUtils.load_file(testcase_file_path)

    def test_context_init_functions(self):
        self.assertIn("get_timestamp", self.context.testset_functions_config)
        self.assertIn("gen_random_string", self.context.testset_functions_config)

        variables = [
            {"random": "${gen_random_string(5)}"},
            {"timestamp10": "${get_timestamp(10)}"}
        ]
        self.context.bind_variables(variables)
        context_variables = self.context.testcase_variables_mapping

        self.assertEqual(len(context_variables["random"]), 5)
        self.assertEqual(len(context_variables["timestamp10"]), 10)

    def test_context_bind_testset_variables(self):
        # testcase in JSON format
        testcase1 = {
            "variables": [
                {"GLOBAL_TOKEN": "debugtalk"},
                {"token": "$GLOBAL_TOKEN"}
            ]
        }
        # testcase in YAML format
        testcase2 = self.testcases["bind_variables"]

        for testcase in [testcase1, testcase2]:
            variables = testcase['variables']
            self.context.bind_variables(variables, level="testset")

            testset_variables = self.context.testset_shared_variables_mapping
            testcase_variables = self.context.testcase_variables_mapping
            self.assertIn("GLOBAL_TOKEN", testset_variables)
            self.assertIn("GLOBAL_TOKEN", testcase_variables)
            self.assertEqual(testset_variables["GLOBAL_TOKEN"], "debugtalk")
            self.assertIn("token", testset_variables)
            self.assertIn("token", testcase_variables)
            self.assertEqual(testset_variables["token"], "debugtalk")

    def test_context_bind_testcase_variables(self):
        testcase1 = {
            "variables": [
                {"GLOBAL_TOKEN": "debugtalk"},
                {"token": "$GLOBAL_TOKEN"}
            ]
        }
        testcase2 = self.testcases["bind_variables"]

        for testcase in [testcase1, testcase2]:
            variables = testcase['variables']
            self.context.bind_variables(variables)

            testset_variables = self.context.testset_shared_variables_mapping
            testcase_variables = self.context.testcase_variables_mapping
            self.assertNotIn("GLOBAL_TOKEN", testset_variables)
            self.assertIn("GLOBAL_TOKEN", testcase_variables)
            self.assertEqual(testcase_variables["GLOBAL_TOKEN"], "debugtalk")
            self.assertNotIn("token", testset_variables)
            self.assertIn("token", testcase_variables)
            self.assertEqual(testcase_variables["token"], "debugtalk")

    def test_context_bind_lambda_functions(self):
        testcase1 = {
            "function_binds": {
                "add_one": lambda x: x + 1,
                "add_two_nums": lambda x, y: x + y
            },
            "variables": [
                {"add1": "${add_one(2)}"},
                {"sum2nums": "${add_two_nums(2,3)}"}
            ]
        }
        testcase2 = self.testcases["bind_lambda_functions"]

        for testcase in [testcase1, testcase2]:
            function_binds = testcase.get('function_binds', {})
            self.context.bind_functions(function_binds)

            variables = testcase['variables']
            self.context.bind_variables(variables)

            context_variables = self.context.testcase_variables_mapping
            self.assertIn("add1", context_variables)
            self.assertEqual(context_variables["add1"], 3)
            self.assertIn("sum2nums", context_variables)
            self.assertEqual(context_variables["sum2nums"], 5)

    def test_call_builtin_functions(self):
        testcase1 = {
            "variables": [
                {"length": "${len(debugtalk)}"},
                {"smallest": "${min(2, 3, 8)}"},
                {"largest": "${max(2, 3, 8)}"}
            ]
        }
        testcase2 = self.testcases["builtin_functions"]

        for testcase in [testcase1, testcase2]:
            variables = testcase['variables']
            self.context.bind_variables(variables)

            context_variables = self.context.testcase_variables_mapping
            self.assertEqual(context_variables["length"], 9)
            self.assertEqual(context_variables["smallest"], 2)
            self.assertEqual(context_variables["largest"], 8)

    def test_context_bind_lambda_functions_with_import(self):
        testcase1 = {
            "requires": ["random", "string", "hashlib"],
            "function_binds": {
                "gen_random_string": "lambda str_len: ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(str_len))",
                "gen_md5": "lambda *str_args: hashlib.md5(''.join(str_args).encode('utf-8')).hexdigest()"
            },
            "variables": [
                {"TOKEN": "debugtalk"},
                {"random": "${gen_random_string(5)}"},
                {"data": '{"name": "user", "password": "******"}'},
                {"authorization": "${gen_md5($TOKEN, $data, $random)}"}
            ]
        }
        testcase2 = self.testcases["bind_lambda_functions_with_import"]

        for testcase in [testcase1, testcase2]:
            requires = testcase.get('requires', [])
            self.context.import_requires(requires)

            function_binds = testcase.get('function_binds', {})
            self.context.bind_functions(function_binds)

            variables = testcase['variables']
            self.context.bind_variables(variables)
            context_variables = self.context.testcase_variables_mapping

            self.assertIn("TOKEN", context_variables)
            TOKEN = context_variables["TOKEN"]
            self.assertEqual(TOKEN, "debugtalk")
            self.assertIn("random", context_variables)
            self.assertIsInstance(context_variables["random"], str)
            self.assertEqual(len(context_variables["random"]), 5)
            random = context_variables["random"]
            self.assertIn("data", context_variables)
            data = context_variables["data"]
            self.assertIn("authorization", context_variables)
            self.assertEqual(len(context_variables["authorization"]), 32)
            authorization = context_variables["authorization"]
            self.assertEqual(gen_md5(TOKEN, data, random), authorization)

    def test_import_module_items(self):
        testcase1 = {
            "import_module_items": ["tests.debugtalk"],
            "variables": [
                {"TOKEN": "debugtalk"},
                {"random": "${gen_random_string(5)}"},
                {"data": '{"name": "user", "password": "******"}'},
                {"authorization": "${gen_md5($TOKEN, $data, $random)}"}
            ]
        }
        testcase2 = self.testcases["bind_module_functions"]

        for testcase in [testcase1, testcase2]:
            module_items = testcase.get('import_module_items', [])
            self.context.import_module_items(module_items)

            variables = testcase['variables']
            self.context.bind_variables(variables)
            context_variables = self.context.testcase_variables_mapping

            self.assertIn("TOKEN", context_variables)
            TOKEN = context_variables["TOKEN"]
            self.assertEqual(TOKEN, "debugtalk")
            self.assertIn("random", context_variables)
            self.assertIsInstance(context_variables["random"], str)
            self.assertEqual(len(context_variables["random"]), 5)
            random = context_variables["random"]
            self.assertIn("data", context_variables)
            data = context_variables["data"]
            self.assertIn("authorization", context_variables)
            self.assertEqual(len(context_variables["authorization"]), 32)
            authorization = context_variables["authorization"]
            self.assertEqual(gen_md5(TOKEN, data, random), authorization)
            self.assertIn("SECRET_KEY", context_variables)
            SECRET_KEY = context_variables["SECRET_KEY"]
            self.assertEqual(SECRET_KEY, "DebugTalk")

    def test_get_parsed_request(self):
        test_runner = runner.Runner()
        testcase = {
            "import_module_items": ["tests.debugtalk"],
            "variables": [
                {"TOKEN": "debugtalk"},
                {"random": "${gen_random_string(5)}"},
                {"data": '{"name": "user", "password": "******"}'},
                {"authorization": "${gen_md5($TOKEN, $data, $random)}"}
            ],
            "request": {
                "url": "http://127.0.0.1:5000/api/users/1000",
                "METHOD": "POST",
                "Headers": {
                    "Content-Type": "application/json",
                    "authorization": "$authorization",
                    "random": "$random",
                    "SECRET_KEY": "$SECRET_KEY"
                },
                "Data": "$data"
            }
        }
        parsed_request = test_runner.init_config(testcase, level="testcase")
        self.assertIn("authorization", parsed_request["headers"])
        self.assertEqual(len(parsed_request["headers"]["authorization"]), 32)
        self.assertIn("random", parsed_request["headers"])
        self.assertEqual(len(parsed_request["headers"]["random"]), 5)
        self.assertIn("data", parsed_request)
        self.assertEqual(parsed_request["data"], testcase["variables"][2]["data"])
        self.assertEqual(parsed_request["headers"]["secret_key"], "DebugTalk")

    def test_exec_content_functions(self):
        test_runner = runner.Runner()
        content = "${sleep_N_secs(1)}"
        start_time = time.time()
        test_runner.context.eval_content(content)
        end_time = time.time()
        elapsed_time = end_time - start_time
        self.assertGreater(elapsed_time, 1)

    def test_do_validation(self):
        self.context.do_validation(
            {"check": "check", "check_value": 1, "expect": 1, "comparator": "eq"}
        )
        self.context.do_validation(
            {"check": "check", "check_value": "abc", "expect": "abc", "comparator": "=="}
        )

        config_dict = {
            "path": 'tests/data/demo_testset_hardcode.yml'
        }
        self.context.config_context(config_dict, "testset")
        self.context.do_validation(
            {"check": "status_code", "check_value": "201", "expect": 3, "comparator": "sum_status_code"}
        )

    def test_validate(self):
        url = "http://127.0.0.1:5000/"
        resp = requests.get(url)
        resp_obj = response.ResponseObject(resp)

        validators = [
            {"eq": ["$resp_status_code", 201]},
            {"check": "$resp_status_code", "comparator": "eq", "expect": 201},
            {"check": "$resp_body_success", "comparator": "eq", "expect": True},
            {"check": "${is_status_code_200($resp_status_code)}", "comparator": "eq", "expect": False}
        ]
        variables = [
            {"resp_status_code": 200},
            {"resp_body_success": True}
        ]
        self.context.bind_variables(variables)

        with self.assertRaises(exception.ValidationError):
            self.context.validate(validators, resp_obj)

        variables = [
            {"resp_status_code": 201},
            {"resp_body_success": True}
        ]
        self.context.bind_variables(variables)
        from tests.debugtalk import is_status_code_200
        functions = {
            "is_status_code_200": is_status_code_200
        }
        self.context.bind_functions(functions)

        self.assertTrue(self.context.validate(validators, resp_obj))

    def test_validate_exception(self):
        url = "http://127.0.0.1:5000/"
        resp = requests.get(url)
        resp_obj = response.ResponseObject(resp)

        # expected value missed in validators
        validators = [
            {"eq": ["$resp_status_code", 201]},
            {"check": "$resp_status_code", "comparator": "eq", "expect": 201},
            {"check": "$resp_body_success", "comparator": "eq", "expect": True}
        ]
        variables = []
        self.context.bind_variables(variables)

        with self.assertRaises(exception.ParamsError):
            self.context.validate(validators, resp_obj)

        # expected value missed in variables mapping
        variables = [
            {"resp_status_code": 200}
        ]
        self.context.bind_variables(variables)

        with self.assertRaises(exception.ValidationError):
            self.context.validate(validators, resp_obj)
class VariableBindsUnittest(ApiServerUnittest):
    def setUp(self):
        self.context = Context()
        testcase_file_path = os.path.join(os.getcwd(),
                                          'tests/data/demo_binds.yml')
        self.testcases = FileUtils.load_file(testcase_file_path)

    def test_context_init_functions(self):
        self.assertIn("get_timestamp", self.context.testset_functions_config)
        self.assertIn("gen_random_string",
                      self.context.testset_functions_config)

        variables = [{
            "random": "${gen_random_string(5)}"
        }, {
            "timestamp10": "${get_timestamp(10)}"
        }]
        self.context.bind_variables(variables)
        context_variables = self.context.testcase_variables_mapping

        self.assertEqual(len(context_variables["random"]), 5)
        self.assertEqual(len(context_variables["timestamp10"]), 10)

    def test_context_bind_testset_variables(self):
        # testcase in JSON format
        testcase1 = {
            "variables": [{
                "GLOBAL_TOKEN": "debugtalk"
            }, {
                "token": "$GLOBAL_TOKEN"
            }]
        }
        # testcase in YAML format
        testcase2 = self.testcases["bind_variables"]

        for testcase in [testcase1, testcase2]:
            variables = testcase['variables']
            self.context.bind_variables(variables, level="testset")

            testset_variables = self.context.testset_shared_variables_mapping
            testcase_variables = self.context.testcase_variables_mapping
            self.assertIn("GLOBAL_TOKEN", testset_variables)
            self.assertIn("GLOBAL_TOKEN", testcase_variables)
            self.assertEqual(testset_variables["GLOBAL_TOKEN"], "debugtalk")
            self.assertIn("token", testset_variables)
            self.assertIn("token", testcase_variables)
            self.assertEqual(testset_variables["token"], "debugtalk")

    def test_context_bind_testcase_variables(self):
        testcase1 = {
            "variables": [{
                "GLOBAL_TOKEN": "debugtalk"
            }, {
                "token": "$GLOBAL_TOKEN"
            }]
        }
        testcase2 = self.testcases["bind_variables"]

        for testcase in [testcase1, testcase2]:
            variables = testcase['variables']
            self.context.bind_variables(variables)

            testset_variables = self.context.testset_shared_variables_mapping
            testcase_variables = self.context.testcase_variables_mapping
            self.assertNotIn("GLOBAL_TOKEN", testset_variables)
            self.assertIn("GLOBAL_TOKEN", testcase_variables)
            self.assertEqual(testcase_variables["GLOBAL_TOKEN"], "debugtalk")
            self.assertNotIn("token", testset_variables)
            self.assertIn("token", testcase_variables)
            self.assertEqual(testcase_variables["token"], "debugtalk")

    def test_context_bind_lambda_functions(self):
        function_binds = {
            "add_one": lambda x: x + 1,
            "add_two_nums": lambda x, y: x + y
        }
        variables = [{
            "add1": "${add_one(2)}"
        }, {
            "sum2nums": "${add_two_nums(2,3)}"
        }]
        self.context.bind_functions(function_binds)
        self.context.bind_variables(variables)

        context_variables = self.context.testcase_variables_mapping
        self.assertIn("add1", context_variables)
        self.assertEqual(context_variables["add1"], 3)
        self.assertIn("sum2nums", context_variables)
        self.assertEqual(context_variables["sum2nums"], 5)

    def test_call_builtin_functions(self):
        testcase1 = {
            "variables": [{
                "length": "${len(debugtalk)}"
            }, {
                "smallest": "${min(2, 3, 8)}"
            }, {
                "largest": "${max(2, 3, 8)}"
            }]
        }
        testcase2 = self.testcases["builtin_functions"]

        for testcase in [testcase1, testcase2]:
            variables = testcase['variables']
            self.context.bind_variables(variables)

            context_variables = self.context.testcase_variables_mapping
            self.assertEqual(context_variables["length"], 9)
            self.assertEqual(context_variables["smallest"], 2)
            self.assertEqual(context_variables["largest"], 8)

    def test_import_module_items(self):
        variables = [{
            "TOKEN": "debugtalk"
        }, {
            "random": "${gen_random_string(5)}"
        }, {
            "data": '{"name": "user", "password": "******"}'
        }, {
            "authorization": "${gen_md5($TOKEN, $data, $random)}"
        }]
        from tests import debugtalk
        self.context.import_module_items(debugtalk)
        self.context.bind_variables(variables)
        context_variables = self.context.testcase_variables_mapping

        self.assertIn("TOKEN", context_variables)
        TOKEN = context_variables["TOKEN"]
        self.assertEqual(TOKEN, "debugtalk")
        self.assertIn("random", context_variables)
        self.assertIsInstance(context_variables["random"], str)
        self.assertEqual(len(context_variables["random"]), 5)
        random = context_variables["random"]
        self.assertIn("data", context_variables)
        data = context_variables["data"]
        self.assertIn("authorization", context_variables)
        self.assertEqual(len(context_variables["authorization"]), 32)
        authorization = context_variables["authorization"]
        self.assertEqual(gen_md5(TOKEN, data, random), authorization)
        self.assertIn("SECRET_KEY", context_variables)
        SECRET_KEY = context_variables["SECRET_KEY"]
        self.assertEqual(SECRET_KEY, "DebugTalk")

    def test_get_parsed_request(self):
        test_runner = runner.Runner()
        testcase = {
            "variables": [{
                "TOKEN": "debugtalk"
            }, {
                "random": "${gen_random_string(5)}"
            }, {
                "data": '{"name": "user", "password": "******"}'
            }, {
                "authorization": "${gen_md5($TOKEN, $data, $random)}"
            }],
            "request": {
                "url": "http://127.0.0.1:5000/api/users/1000",
                "method": "POST",
                "headers": {
                    "Content-Type": "application/json",
                    "authorization": "$authorization",
                    "random": "$random",
                    "secret_key": "$SECRET_KEY"
                },
                "data": "$data"
            }
        }
        from tests import debugtalk
        self.context.import_module_items(debugtalk)
        self.context.bind_variables(testcase["variables"])
        parsed_request = self.context.get_parsed_request(testcase["request"])
        self.assertIn("authorization", parsed_request["headers"])
        self.assertEqual(len(parsed_request["headers"]["authorization"]), 32)
        self.assertIn("random", parsed_request["headers"])
        self.assertEqual(len(parsed_request["headers"]["random"]), 5)
        self.assertIn("data", parsed_request)
        self.assertEqual(parsed_request["data"],
                         testcase["variables"][2]["data"])
        self.assertEqual(parsed_request["headers"]["secret_key"], "DebugTalk")

    def test_exec_content_functions(self):
        test_runner = runner.Runner()
        content = "${sleep_N_secs(1)}"
        start_time = time.time()
        test_runner.context.eval_content(content)
        end_time = time.time()
        elapsed_time = end_time - start_time
        self.assertGreater(elapsed_time, 1)

    def test_do_validation(self):
        self.context.do_validation({
            "check": "check",
            "check_value": 1,
            "expect": 1,
            "comparator": "eq"
        })
        self.context.do_validation({
            "check": "check",
            "check_value": "abc",
            "expect": "abc",
            "comparator": "=="
        })

        config_dict = {"path": 'tests/data/demo_testset_hardcode.yml'}
        self.context.config_context(config_dict, "testset")
        self.context.do_validation({
            "check": "status_code",
            "check_value": "201",
            "expect": 3,
            "comparator": "sum_status_code"
        })

    def test_validate(self):
        url = "http://127.0.0.1:5000/"
        resp = requests.get(url)
        resp_obj = response.ResponseObject(resp)

        validators = [{
            "eq": ["$resp_status_code", 201]
        }, {
            "check": "$resp_status_code",
            "comparator": "eq",
            "expect": 201
        }, {
            "check": "$resp_body_success",
            "comparator": "eq",
            "expect": True
        }]
        variables = [{"resp_status_code": 200}, {"resp_body_success": True}]
        self.context.bind_variables(variables)

        with self.assertRaises(exceptions.ValidationFailure):
            self.context.validate(validators, resp_obj)

        validators = [{
            "eq": ["$resp_status_code", 201]
        }, {
            "check": "$resp_status_code",
            "comparator": "eq",
            "expect": 201
        }, {
            "check": "$resp_body_success",
            "comparator": "eq",
            "expect": True
        }, {
            "check": "${is_status_code_200($resp_status_code)}",
            "comparator": "eq",
            "expect": False
        }]
        variables = [{"resp_status_code": 201}, {"resp_body_success": True}]
        self.context.bind_variables(variables)
        from tests.debugtalk import is_status_code_200
        functions = {"is_status_code_200": is_status_code_200}
        self.context.bind_functions(functions)

        self.context.validate(validators, resp_obj)

    def test_validate_exception(self):
        url = "http://127.0.0.1:5000/"
        resp = requests.get(url)
        resp_obj = response.ResponseObject(resp)

        # expected value missed in validators
        validators = [{
            "eq": ["$resp_status_code", 201]
        }, {
            "check": "$resp_status_code",
            "comparator": "eq",
            "expect": 201
        }]
        variables = []
        self.context.bind_variables(variables)

        with self.assertRaises(exceptions.ParamsError):
            self.context.validate(validators, resp_obj)

        # expected value missed in variables mapping
        variables = [{"resp_status_code": 200}]
        self.context.bind_variables(variables)

        with self.assertRaises(exceptions.ValidationFailure):
            self.context.validate(validators, resp_obj)