예제 #1
0
async def test_clt_batch_empty():
    reg = RpcRegistry()

    clt = get_clt(reg)

    result = await clt.exec_batch()
    assert result == ()
예제 #2
0
async def test_rpc_response_header(loop, unused_tcp_port):
    reg = RpcRegistry()

    @reg.method()
    def method1():
        set_reponse_header('A', 'B')
        set_reponse_header('C', 'D')
        set_response_cookie('E', 'F')
        del_response_cookie('G')
        return 'ok'

    async with runapp(unused_tcp_port,
                      JsonRpcHttpHandler(reg, JsonRpcHttpHandlerConfig())):
        async with ClientSession() as sess:
            resp = await sess.request(
                'POST',
                'http://127.0.0.1:%s/' % unused_tcp_port,
                json={
                    'method': 'method1',
                    'jsonrpc': '2.0',
                    'id': 1
                },
            )

            assert resp.headers['A'] == 'B'
            assert resp.headers['C'] == 'D'
            assert resp.cookies['E'].value == 'F'
            assert resp.cookies['G'].value == ''
예제 #3
0
async def test_rpc_client_arg_as_bytes(loop, unused_tcp_port):
    reg = RpcRegistry()
    some_data = os.urandom(100)

    @reg.method()
    def compare_bytes(b_data: bytes) -> bool:
        return some_data == b_data

    class TestRpcClientBytesArg(JsonRpcHttpClient):
        def compare_bytes(
            self,
            b_data: bytes,
            timeout: Optional[float] = None,
        ) -> Awaitable[bool]:
            return self.exec(
                "compare_bytes",
                {'b_data': b_data},
                timeout=timeout,
            )

    async with runapp(unused_tcp_port,
                      JsonRpcHttpHandler(reg,
                                         JsonRpcHttpHandlerConfig())) as app:
        clt = TestRpcClientBytesArg(
            JsonRpcHttpClientConfig(url='http://%s:%s/' %
                                    (app.cfg.srv.host, app.cfg.srv.port)))
        app.add('clt_ba', clt)
        await clt.prepare()
        await clt.start()
        result = await clt.compare_bytes(some_data)
        assert result is True
예제 #4
0
async def test_rpc_response_header(loop, unused_tcp_port):  # type: ignore
    reg = RpcRegistry()

    @reg.method()
    def method1(a: Any):  # type: ignore
        set_reponse_header('A', 'B')
        set_reponse_header('C', 'D')
        set_response_cookie('E', 'F')
        del_response_cookie('G')
        return {'method1': 'ok'}

    async with runapp(unused_tcp_port,
                      RestRpcHttpHandler(reg, RestRpcHttpHandlerConfig())):
        async with ClientSession() as sess:
            resp = await sess.request(
                'POST',
                'http://127.0.0.1:%s/method1' % unused_tcp_port,
                json={'a': 'anything'},
            )

            assert resp.headers['A'] == 'B'
            assert resp.headers['C'] == 'D'
            assert resp.cookies['E'].value == 'F'
            assert resp.cookies['G'].value == ''

            resp_2 = await sess.request(
                'OPTIONS', 'http://127.0.0.1:%s/method1' % unused_tcp_port)

            assert (resp_2.headers['Access-Control-Allow-Methods'] ==
                    'OPTIONS, POST')
            assert resp_2.status == 200
            assert resp_2.reason == 'OK'
예제 #5
0
async def test_batch():
    reg = RpcRegistry()

    @reg.method()
    async def echo(text: str) -> str:
        return 'echo: %s' % text

    @reg.method()
    async def err() -> None:
        raise Exception('some error', {'pay': 'load'})

    ex = JsonRpcExecutor(reg, get_app())
    res = await ex.exec(
        b'[{"jsonrpc": "2.0", '
        b'"method": "echo", "params": {"text": "1"}, "id": 1},'
        b'{"jsonrpc": "2.0", '
        b'"method": "err", "params": {}, "id": 3},'
        b'{"jsonrpc": "2.0", '
        b'"method": "echo", "params": {"text": "2"}, "id": 2}]'
    )
    assert json.loads(res) == [
        {"jsonrpc": "2.0", "id": 1, "result": "echo: 1"},
        {
            "jsonrpc": "2.0",
            "id": 3,
            "error": {
                "message": "some error",
                "code": -32000,
                "data": {"pay": "load"},
            },
        },
        {"jsonrpc": "2.0", "id": 2, "result": "echo: 2"},
    ]
예제 #6
0
async def test_rpc_error(loop, unused_tcp_port):
    class MyError(JsonRpcError):
        jsonrpc_error_code = 100
        message = 'Err'

    reg = RpcRegistry()

    @reg.method()
    def method1():
        raise MyError(data={'a': 1})

    async with runapp(unused_tcp_port,
                      JsonRpcHttpHandler(reg, JsonRpcHttpHandlerConfig())):
        async with ClientSession() as sess:
            resp = await sess.request(
                'POST',
                'http://127.0.0.1:%s/' % unused_tcp_port,
                json={
                    'method': 'method1',
                    'jsonrpc': '2.0',
                    'id': 1
                },
            )
            result = await resp.json()
            assert result == {
                'id': 1,
                'jsonrpc': '2.0',
                'error': {
                    'code': 100,
                    'message': 'Err',
                    'data': {
                        'a': 1
                    }
                },
            }
예제 #7
0
async def test_rpc_error(loop, unused_tcp_port):  # type: ignore
    class MyError(RestRpcError):
        code = 1000
        message = 'Err'

    class MyError409(RestRpcError):
        code = 409
        message = 'Err'

    reg = RpcRegistry()

    @reg.method()
    def method1(a: Any):  # type: ignore
        raise MyError(data={'a': 1})

    @reg.method()
    def method2(a: Any):  # type: ignore
        raise MyError409(data={'b': 2})

    async with runapp(unused_tcp_port,
                      RestRpcHttpHandler(reg, RestRpcHttpHandlerConfig())):
        async with ClientSession() as sess:
            resp = await sess.request(
                'POST',
                'http://127.0.0.1:%s/method1/' % unused_tcp_port,
                json={'a': 'anything'},
            )
            result = await resp.json()
            assert resp.status == 200
            assert resp.reason == 'OK'
            assert result == {
                'error': {
                    'code': 1000,
                    'message': 'Err',
                    'data': {
                        'a': 1
                    }
                },
            }
            resp_2 = await sess.request(
                'POST',
                'http://127.0.0.1:%s/method2/' % unused_tcp_port,
                json={'a': 'anything'},
            )
            result_2 = await resp_2.json()
            assert result_2 == {
                'error': {
                    'code': 409,
                    'message': 'Err',
                    'data': {
                        'b': 2
                    }
                },
            }
            assert resp_2.status == 409
            assert resp_2.reason == 'Conflict'
예제 #8
0
async def test_err_invalid_req_2():
    reg = RpcRegistry()

    ex = JsonRpcExecutor(reg, get_app())
    res = await ex.exec(b'{"params": []}')
    assert json.loads(res) == {
        "jsonrpc": "2.0",
        "id": None,
        "error": {"message": "Invalid Request", "code": -32600},
    }
예제 #9
0
async def test_err_parse_1():
    reg = RpcRegistry()

    ex = JsonRpcExecutor(reg, get_app())
    res = await ex.exec(b'eeeee')
    assert json.loads(res) == {
        "jsonrpc": "2.0",
        "id": None,
        "error": {"message": "Parse error", "code": -32700},
    }
예제 #10
0
async def test_error() -> None:
    reg = RpcRegistry()

    @reg.method()
    async def echo(text: str) -> str:
        raise Exception('Ex')

    ex = RestRpcExecutor(reg, get_app())
    res, status = await ex.exec(b'{"text": "123"}', method_name='echo')
    assert json.loads(res) == {'error': {'code': 500, 'message': 'Ex'}}
    assert status == 500
예제 #11
0
async def test_clt_single_notification():
    reg = RpcRegistry()

    @reg.method()
    async def sum(a: int, b: int) -> int:
        return a + b

    clt = get_clt(reg)

    result = await clt.exec('sum', [1, 2], one_way=True)
    assert result is None
예제 #12
0
async def test_clt() -> None:
    reg = RpcRegistry()

    @reg.method()
    async def sum(a: int, b: int) -> Dict[str, int]:
        return {'sum': a + b}

    clt = get_clt(reg)

    result = await clt.exec('sum', {'a': 1, 'b': 2})
    assert result == {'sum': 3}
예제 #13
0
async def test_clt_single():
    reg = RpcRegistry()

    @reg.method()
    async def sum(a: int, b: int) -> int:
        return a + b

    clt = get_clt(reg)

    result = await clt.exec('sum', [1, 2])
    assert result == 3
예제 #14
0
async def test_notification():
    reg = RpcRegistry()

    @reg.method()
    async def echo(self, text: str) -> str:
        return text

    ex = JsonRpcExecutor(reg, get_app())
    res = await ex.exec(
        b'{"jsonrpc": "2.0",' b' "method": "echo", "params": {"text": "123"}}'
    )
    assert res == b''
예제 #15
0
async def test_error_method() -> None:
    reg = RpcRegistry()

    ex = RestRpcExecutor(reg, get_app())
    res, status = await ex.exec(b'{"text": "123"}', method_name='echo')
    assert json.loads(res) == {
        'error': {
            'code': 404,
            'message': 'Method not found'
        }
    }
    assert status == 404
예제 #16
0
async def test_success_by_name() -> None:
    reg = RpcRegistry()

    @reg.method()
    async def echo(text: str) -> Dict[str, str]:
        return {'echo': text}

    ex = RestRpcExecutor(reg, get_app())
    res, status = await ex.exec(b' {"text": "123"}', method_name='echo')

    assert json.loads(res) == {'echo': '123'}
    assert status == 200
예제 #17
0
async def test_rpc(loop, rabbitmq_url):
    reg = RpcRegistry()

    @reg.method()
    def method1(val: str) -> str:
        return 'ok %s' % val

    async with runapp(rabbitmq_url, reg) as app:
        with app.logger.span_new():
            val = 123
            res = await app.clt.exec('method1', {'val': val}, timeout=2)
            assert res == 'ok %s' % val
예제 #18
0
async def test_rpc_client(loop, unused_tcp_port):
    reg = RpcRegistry()

    @reg.method()
    def method1():
        return 'ok'

    async with runapp(unused_tcp_port,
                      JsonRpcHttpHandler(reg,
                                         JsonRpcHttpHandlerConfig())) as app:
        result = await app.clt.exec('method1')
        assert result == 'ok'
예제 #19
0
async def test_success_by_pos_default() -> None:
    reg = RpcRegistry()

    @reg.method()
    async def sum(a: int, b: int, c: int = 3) -> Dict[str, int]:
        return {'sum': a + b + c}

    ex = RestRpcExecutor(reg, get_app())
    res, status = await ex.exec(b'{"a": 1,"b": 2}', method_name='sum')

    assert json.loads(res) == {"sum": 6}
    assert status == 200
예제 #20
0
async def test_rpc_client(loop, unused_tcp_port):  # type: ignore
    reg = RpcRegistry()

    @reg.method()
    def method1(a: Any):  # type: ignore
        return {'method1': 'ok'}

    async with runapp(unused_tcp_port,
                      RestRpcHttpHandler(reg,
                                         RestRpcHttpHandlerConfig())) as app:
        result = await app.clt.exec('method1', {'a': 'anything'})
        assert result == {'method1': 'ok'}
예제 #21
0
async def test_clt_err_method() -> None:
    reg = RpcRegistry()

    @reg.method()
    async def sum(a: int, b: int) -> Dict[str, int]:
        return {'sum': a + b}

    clt = get_clt(reg)

    with pytest.raises(RestRpcError) as exc_info:
        await clt.exec('sum2', {'a': 1, 'b': 2})
    assert exc_info.value.code == 404
    assert exc_info.value.message == 'Method not found'
예제 #22
0
async def test_clt_batch():
    reg = RpcRegistry()

    @reg.method()
    async def sum(a: int, b: int) -> int:
        return a + b

    clt = get_clt(reg)

    result = await clt.exec_batch(
        clt.exec('sum', [1, 2]), clt.exec('sum', [3, 4])
    )
    assert result == (3, 7)
예제 #23
0
async def test_error_method():
    reg = RpcRegistry()

    ex = JsonRpcExecutor(reg, get_app())
    res = await ex.exec(
        b'{"jsonrpc": "2.0",'
        b' "method": "echo", "params": {"text": "123"}, "id": 10}'
    )
    assert json.loads(res) == {
        'error': {'code': -32601, 'message': 'Method not found'},
        'id': 10,
        'jsonrpc': '2.0',
    }
예제 #24
0
async def test_clt_batch_notification():
    reg = RpcRegistry()

    @reg.method()
    async def sum(a: int, b: int) -> int:
        return a + b

    clt = get_clt(reg)

    result = await clt.exec_batch(
        clt.exec('sum', [1, 2], one_way=True),
        clt.exec('sum', [3, 4], one_way=True),
    )
    assert result == (None, None)
예제 #25
0
async def test_legacy_v1_format_success_2():
    reg = RpcRegistry()

    @reg.method()
    async def noop(text: str) -> None:
        pass

    ex = JsonRpcExecutor(reg, get_app())
    res = await ex.exec(b'{"method": "noop", "text": "123"}')

    assert json.loads(res) == {
        'code': 0,
        'message': 'OK',
    }
예제 #26
0
async def test_rpc_batch(loop, rabbitmq_url):
    reg = RpcRegistry()

    @reg.method()
    def method1(val: str) -> str:
        return 'ok %s' % val

    async with runapp(rabbitmq_url, reg) as app:
        with app.logger.span_new():
            res1, res2 = await app.clt.exec_batch(
                app.clt.exec('method1', {'val': 123}),
                app.clt.exec('method1', {'val': 234}),
            )
            assert res1 == 'ok 123'
예제 #27
0
async def test_rpc_with_any_subpath(loop, unused_tcp_port):  # type: ignore
    reg = RpcRegistry()

    @reg.method()
    def method1(a: Any):  # type: ignore
        return {'status': 'ok'}

    async with runapp_with_any_subpath(
            unused_tcp_port,
            RestRpcHttpHandler(reg, RestRpcHttpHandlerConfig(path='/api/v1/')),
    ):
        async with ClientSession() as sess:
            resp = await sess.request(
                'POST',
                'http://127.0.0.1:%s/api/v1/method1/' % unused_tcp_port,
                json={'a': 'anything'},
            )

            result = await resp.json()
            assert resp.status == 200
            assert resp.reason == 'OK'
            assert resp.headers.get('Content-Type', None) == 'application/json'
            assert result == {'status': 'ok'}

            resp_2 = await sess.request(
                'POST',
                'http://127.0.0.1:%s/api/v1/method1' % unused_tcp_port,
                json={'a': 'anything'},
            )

            result_2 = await resp_2.json()
            assert result_2 == {'status': 'ok'}

            resp_3 = await sess.request(
                'POST',
                'http://127.0.0.1:%s/api/v1/nonexistentmethod' %
                unused_tcp_port,
                json={'a': 'anything'},
            )
            assert resp_3.status == 404
            assert resp_3.reason == 'Not Found'

            resp_4 = await sess.request(
                'POST',
                'http://127.0.0.1:%s/api/v0/method1' % unused_tcp_port,
                json={'a': 'anything'},
            )
            assert resp_4.status == 404
            assert resp_4.reason == 'Not Found'
예제 #28
0
async def test_legacy_v1_format_error():
    reg = RpcRegistry()

    @reg.method()
    async def echo(text: str) -> None:
        return None

    ex = JsonRpcExecutor(reg, get_app())
    res = await ex.exec(b'{"method": "echo", "int": 1}')

    assert json.loads(res) == {
        'code': -32602,
        'message': 'Invalid params',
        'info': 'Got an unexpected argument: int',
    }
예제 #29
0
async def test_legacy_v2_format_success():
    reg = RpcRegistry()

    @reg.method()
    async def echo(text: str) -> str:
        return 'echo: %s' % text

    ex = JsonRpcExecutor(reg, get_app())
    res = await ex.exec(b'{"method": "echo", "params": {"text": "123"}}')

    assert json.loads(res) == {
        'code': 0,
        'message': 'OK',
        'result': 'echo: 123',
    }
예제 #30
0
async def test_legacy_v2_format_error():
    reg = RpcRegistry()

    @reg.method()
    async def echo(text: str) -> str:
        return 'echo: %s' % text

    ex = JsonRpcExecutor(reg, get_app())
    res = await ex.exec(b'{"method": "echo", "params": {}}')

    assert json.loads(res) == {
        'code': -32602,
        'details': {'info': 'Missing 1 required argument(s):  text'},
        'message': 'Invalid params',
    }