def test_headers(self):
        url = 'http://127.0.0.1:%d/test_headers/' % self.port
        token = 'dfwerwer1548hgjhfre35656'

        @tornado_util.fn(url=r"/test_headers/")
        def get_test_test_headers(self, **kwargs):
            if self.request.headers.get("Accept-Token", "") == token:
                return 111
            else:
                return 222

        # get 请求
        res = http_util.get(url)
        assert isinstance(res, basestring)
        assert res == '222'

        res = http_util.get(url, headers={"Accept-Token": token})
        assert isinstance(res, basestring)
        assert res == '111'

        # post 请求
        res = http_util.post(url)
        assert isinstance(res, basestring)
        assert res == '222'

        res = http_util.post(url, headers={"Accept-Token": token})
        assert isinstance(res, basestring)
        assert res == '111'
    def test_error(self):
        # 设成默认异步请求
        http_util.init(repeat_time=3)
        url = 'http://127.0.0.1:%d/test_error' % self.port
        global error_times
        error_times = 0

        # 自定义一个出错页面
        class _ExceptionHandler(tornado_util.RequestHandler):
            def get(self):
                global error_times
                error_times += 1
                raise Exception('出错测试')

            post = get

        # 添加到请求地址列表
        tornado_util.add_apps(r"/test_error/?", _ExceptionHandler)

        # GET 请求,返回 None
        res = http_util.get(url)
        assert res == '<html><title>500: Internal Server Error</title><body>500: Internal Server Error</body></html>'
        assert error_times == 3  # 请求次数

        # POST 请求,返回 None
        error_times = 0
        res = http_util.post(url)
        assert res == '<html><title>500: Internal Server Error</title><body>500: Internal Server Error</body></html>'
        assert error_times == 3  # 请求次数

        # 改回默认值,避免影响其它测试
        http_util.init(repeat_time=1)
    def test_delete_options(self):
        url = 'http://127.0.0.1:%d/test_delete_options' % self.port
        param_url = url + '?a=11&b=22&c=%E5%93%88&d=%E5%93%88&e='
        result = '{"use_time": "0.0003", "reason": "\u8bbf\u95ee\u6210\u529f", "version": "2.0.0", "result": 0}'

        methods = ['delete', 'options']

        @tornado_util.fn(url=r"/test_delete_options/?", method=methods)
        def test_delete_options(self, **kwargs):
            if self.request.body is None:
                return {"result": -1, "reason": '这是GET请求,请求方式有误!'}
            return result

        for method in methods:
            fun = getattr(http_util, method)

            # 普通请求,原样返回
            res = fun(param_url)
            assert isinstance(res, basestring)
            assert res == result

        # get 请求,访问不了
        res = http_util.get(param_url)
        assert isinstance(res, basestring)
        assert res == "<html><title>405: Method Not Allowed</title><body>405: Method Not Allowed</body></html>"

        # post 请求,访问不了
        res = http_util.post(param_url)
        assert isinstance(res, basestring)
        assert res == "<html><title>405: Method Not Allowed</title><body>405: Method Not Allowed</body></html>"
    def test_put_patch(self):
        url = 'http://127.0.0.1:%d/test_put_patch' % self.port
        param = {'a': 11, 'b': '22', 'c': '哈', 'd': u'哈', 'e': None}
        result = '{"use_time": "0.0003", "reason": "\u8bbf\u95ee\u6210\u529f", "version": "2.0.0", "result": 0}'

        methods = ['put', 'patch']

        @tornado_util.fn(url=r"/test_put_patch/?", method=methods)
        def test_put_patch(self, **kwargs):
            if self.request.body is None:
                return {"result": -1, "reason": '这是GET请求,请求方式有误!'}
            if (self.get_argument('a', '') == '11'
                    and self.get_argument('b', '') == '22'
                    and self.get_argument('c', '') == u'哈'
                    and self.get_argument('d', '') == u'哈'
                    and self.get_argument('e', '') == ''):
                return result
            else:
                return kwargs

        for method in methods:
            fun = getattr(http_util, method)

            # 无参数请求,原样返回
            res = fun(url)
            assert isinstance(res, basestring)
            assert res == "{}"

            # 参数转换
            res = fun(url, param)
            assert isinstance(res, basestring)
            assert res == result
            res2 = fun(url, {'b': '22', 'c': '哈', 'd': u'哈', 'e': 0})
            assert isinstance(res2, basestring)
            assert str_util.to_json(res2) == {
                'b': '22',
                'c': u'哈',
                'd': u'哈',
                'e': '0'
            }

            # return_json 返回结果转换
            res = fun(url, param, return_json=True)
            assert isinstance(res, dict)
            assert res == {
                "use_time": "0.0003",
                "reason": u"访问成功",
                "version": "2.0.0",
                "result": 0
            }

        # get 请求,访问不了
        res = http_util.get(url)
        assert isinstance(res, basestring)
        assert res == "<html><title>405: Method Not Allowed</title><body>405: Method Not Allowed</body></html>"

        # post 请求,访问不了
        res = http_util.post(url)
        assert isinstance(res, basestring)
        assert res == "<html><title>405: Method Not Allowed</title><body>405: Method Not Allowed</body></html>"
    def test_post(self):
        url = 'http://127.0.0.1:%d/test_post' % self.port
        param = {'a': 11, 'b': '22', 'c': '哈', 'd': u'哈', 'e': None}
        result = '{"use_time": "0.0003", "reason": "\u8bbf\u95ee\u6210\u529f", "version": "2.0.0", "result": 0}'

        @tornado_util.fn(url=r"/test_post/?", method='post')
        def get_test_post(self, **kwargs):
            if self.request.body is None:
                return {"result": -1, "reason": '这是GET请求,请求方式有误!'}
            if (self.get_argument('a', '') == '11'
                    and self.get_argument('b', '') == '22'
                    and self.get_argument('c', '') == u'哈'
                    and self.get_argument('d', '') == u'哈'
                    and self.get_argument('e', '') == ''):
                return result
            else:
                return kwargs

        # 无参数请求,原样返回
        res = http_util.post(url)
        assert isinstance(res, basestring)
        assert res == "{}"

        # 参数转换
        res = http_util.post(url, param)
        assert isinstance(res, basestring)
        assert res == result
        res2 = http_util.post(url, {'b': '22', 'c': '哈', 'd': u'哈', 'e': 0})
        assert isinstance(res2, basestring)
        assert str_util.to_json(res2) == {
            'b': '22',
            'c': u'哈',
            'd': u'哈',
            'e': '0'
        }

        # return_json 返回结果转换
        res = http_util.post(url, param, return_json=True)
        assert isinstance(res, dict)
        assert res == {
            "use_time": "0.0003",
            "reason": u"访问成功",
            "version": "2.0.0",
            "result": 0
        }
    def test_send_json(self):
        url = 'http://127.0.0.1:%d/test_send_json' % self.port
        result = '{"use_time": "0.0003", "reason": "\u8bbf\u95ee\u6210\u529f", "version": "2.0.0", "result": 0}'

        @tornado_util.fn(url=r"/test_send_json/?", method='post')
        def test_send_json(self, **kwargs):
            if self.request.body is None:
                return {"result": -1, "reason": '这是GET请求,请求方式有误!'}
            return str_util.to_json(self.request.body)

        # 提交 json
        param = {'a': 11, 'b': '22', 'c': '哈', 'd': u'哈', 'e': None}
        res = http_util.post(url, param, send_json=True)
        assert isinstance(res, basestring)
        assert str_util.to_json(res) == param

        param2 = {'b': '22', 'c': '哈', 'd': u'哈', 'e': 0}
        res2 = http_util.post(url, param2, send_json=True)
        assert isinstance(res2, basestring)
        assert str_util.to_json(res2) == param2
    def test_gzip(self):
        url = 'http://127.0.0.1:%d/test_gzip' % self.port
        result = '{"use_time": "0.0003", "reason": "\u8bbf\u95ee\u6210\u529f", "version": "2.0.0", "result": 0}' * 100

        @tornado_util.fn(url=r"/test_gzip/?", gzip_length=10)
        def get_test_gzip(self, **kwargs):
            if self.request.headers.get("Accept-Encoding",
                                        "") in ('gzip', 'deflate'):
                return result
            else:
                return {"result": -1, "reason": '这是没有压缩的请求,请求方式有误!'}

        # get 请求
        global NOW_LOG_RECORD
        NOW_LOG_RECORD = []
        res = http_util.get(url, gzip=True)
        assert isinstance(res, basestring)
        assert res == result

        assert len(NOW_LOG_RECORD) >= 2
        record = NOW_LOG_RECORD[-2]  # 倒数第二条日志,正是解压日志
        assert record is not None
        assert record.levelno == logging.INFO
        assert u'压缩请求' in record.msg
        assert record.method == 'GET'
        assert record.before_length  # 有写入解压前长度
        assert record.after_length  # 有写入解压后长度
        assert record.after_length == len(result)
        assert record.before_length < record.after_length  # 解压后长度更长

        # post 请求
        NOW_LOG_RECORD = []
        res = http_util.post(url, gzip=True)
        assert isinstance(res, basestring)
        assert res == result

        assert len(NOW_LOG_RECORD) >= 2
        record = NOW_LOG_RECORD[-2]  # 倒数第二条日志,正是解压日志
        assert record is not None
        assert record.levelno == logging.INFO
        assert u'压缩请求' in record.msg
        assert record.method == 'POST'
        assert record.before_length  # 有写入解压前长度
        assert record.after_length  # 有写入解压后长度
        assert record.after_length == len(result)
        assert record.before_length < record.after_length  # 解压后长度更长
    def test_method(self):
        url = 'http://127.0.0.1:%d/get_test_method/' % self.port

        # 定义处理各种请求方式的类
        class MethodHandler(tornado_util.RequestHandler):
            def get(self):
                return self.finish('get')

            def post(self):
                return self.finish('post')

            def put(self):
                return self.finish('put')

            def delete(self):
                return self.finish('delete')

            def patch(self):
                return self.finish('patch')

            def options(self):
                return self.finish('options')

        tornado_util.add_apps(r"/get_test_method/", MethodHandler)

        # 测试请求
        res = http_util.get(url)
        assert isinstance(res, basestring) and res == "get"

        res = http_util.post(url)
        assert isinstance(res, basestring) and res == "post"

        res = http_util.put(url)
        assert isinstance(res, basestring) and res == "put"

        res = http_util.delete(url)
        assert isinstance(res, basestring) and res == "delete"

        res = http_util.patch(url)
        assert isinstance(res, basestring) and res == "patch"

        res = http_util.options(url)
        assert isinstance(res, basestring) and res == "options"
    def test_threads(self):
        # 设成默认异步请求
        http_util.init(threads=True)
        url = 'http://127.0.0.1:%d/test_threads' % self.port
        result = '{"use_time": "0.0003", "reason": "\u8bbf\u95ee\u6210\u529f", "version": "2.0.0", "result": 0}'

        @tornado_util.fn(url=r"/test_threads/?")
        def get_test_threads(self, **kwargs):
            return result

        # 异步 GET 请求,返回线程
        global NOW_LOG_RECORD
        NOW_LOG_RECORD = []
        th1 = http_util.get(url)
        assert len(NOW_LOG_RECORD) == 0  # 通过日志查看有没有发启线程,因为发启线程肯定没有这么快打印日志
        assert isinstance(th1, threading.Thread)
        th1.join()  # 等待线程返回,以便检查日志
        assert len(NOW_LOG_RECORD) >= 1
        record = NOW_LOG_RECORD[0]
        assert record is not None
        assert record.levelno == logging.INFO
        assert record.method == 'GET'
        log_msg = record.getMessage()
        assert url in log_msg
        assert result in log_msg

        # 异步 POST 请求,返回线程
        NOW_LOG_RECORD = []
        th2 = http_util.post(url)
        assert len(NOW_LOG_RECORD) == 0  # 通过日志查看有没有发启线程,因为发启线程肯定没有这么快打印日志
        assert isinstance(th2, threading.Thread)
        th2.join()  # 等待线程返回,以便检查日志
        assert len(NOW_LOG_RECORD) >= 1
        record = NOW_LOG_RECORD[0]
        assert record is not None
        assert record.levelno == logging.INFO
        assert record.method == 'POST'
        log_msg = record.getMessage()
        assert url in log_msg
        assert result in log_msg

        # 改回默认值,避免影响其它测试
        http_util.init(threads=False)