예제 #1
0
    def setUp(self):
        # Set up the server
        self.server = UtilityServer().start('', 0)
        self.port = self.server.get_port()

        # Prepare the client
        self.history = jsonrpclib.history.History()
예제 #2
0
 def setUp(self):
     """
     Sets up the test
     """
     # Set up the server
     self.server = UtilityServer().start('', 0)
     self.port = self.server.get_port()
예제 #3
0
    def setUp(self):
        """
        Pre-test set up
        """
        # Set up the server
        self.server = UtilityServer().start('', 0)
        self.port = self.server.get_port()

        # Set up the client
        self.history = jsonrpclib.history.History()
        self.client = jsonrpclib.ServerProxy(
            'http://localhost:{0}'.format(self.port), history=self.history)
예제 #4
0
    def setUp(self):
        # Set up the server
        self.server = UtilityServer().start('', 0)
        self.port = self.server.get_port()

        # Prepare the client
        self.history = jsonrpclib.history.History()
예제 #5
0
 def setUp(self):
     """
     Sets up the test
     """
     # Set up the server
     self.server = UtilityServer().start('', 0)
     self.port = self.server.get_port()
예제 #6
0
class InternalTests(unittest.TestCase):
    """
    These tests verify that the client and server portions of
    jsonrpclib talk to each other properly.
    """
    def setUp(self):
        # Set up the server
        self.server = UtilityServer().start('', 0)
        self.port = self.server.get_port()

        # Prepare the client
        self.history = jsonrpclib.history.History()


    def tearDown(self):
        """
        Post-test clean up
        """
        # Stop the server
        self.server.stop()


    def get_client(self):
        return jsonrpclib.ServerProxy('http://localhost:{0}'.format(self.port),
                                      history=self.history)

    def get_multicall_client(self):
        server = self.get_client()
        return jsonrpclib.MultiCall(server)

    def test_connect(self):
        client = self.get_client()
        result = client.ping()
        self.assertTrue(result)

    def test_single_args(self):
        client = self.get_client()
        result = client.add(5, 10)
        self.assertTrue(result == 15)

    def test_single_kwargs(self):
        client = self.get_client()
        result = client.add(x=5, y=10)
        self.assertTrue(result == 15)

    def test_single_kwargs_and_args(self):
        client = self.get_client()
        self.assertRaises(jsonrpclib.ProtocolError, client.add, (5,), {'y':10})

    def test_single_notify(self):
        client = self.get_client()
        result = client._notify.add(5, 10)
        self.assertTrue(result == None)

    def test_single_namespace(self):
        client = self.get_client()
        client.namespace.sum(1, 2, 4)
        request = json.loads(self.history.request)
        response = json.loads(self.history.response)
        verify_request = {
            "jsonrpc": "2.0", "params": [1, 2, 4],
            "id": "5", "method": "namespace.sum"
        }
        verify_response = {
            "jsonrpc": "2.0", "result": 7, "id": "5"
        }
        verify_request['id'] = request['id']
        verify_response['id'] = request['id']
        self.assertTrue(verify_request == request)
        self.assertTrue(verify_response == response)

    def test_multicall_success(self):
        multicall = self.get_multicall_client()
        multicall.ping()
        multicall.add(5, 10)
        multicall.namespace.sum(5, 10, 15)
        correct = [True, 15, 30]

        for i, result in enumerate(multicall()):
            self.assertTrue(result == correct[i])

    def test_multicall_success_2(self):
        multicall = self.get_multicall_client()
        for i in range(3):
            multicall.add(5, i)
        result = multicall()
        self.assertTrue(result[2] == 7)

    def test_multicall_failure(self):
        multicall = self.get_multicall_client()
        multicall.ping()
        multicall.add(x=5, y=10, z=10)
        raises = [None, jsonrpclib.ProtocolError]
        result = multicall()
        for i in range(2):
            if not raises[i]:
                result[i]
            else:
                def func():
                    return result[i]
                self.assertRaises(raises[i], func)
예제 #7
0
class InternalTests(unittest.TestCase):
    """
    These tests verify that the client and server portions of
    jsonrpclib talk to each other properly.
    """
    def setUp(self):
        # Set up the server
        self.server = UtilityServer().start('', 0)
        self.port = self.server.get_port()

        # Prepare the client
        self.history = jsonrpclib.history.History()

    def tearDown(self):
        """
        Post-test clean up
        """
        # Stop the server
        self.server.stop()

    def get_client(self):
        return jsonrpclib.ServerProxy('http://localhost:{0}'.format(self.port),
                                      history=self.history)

    def get_multicall_client(self):
        server = self.get_client()
        return jsonrpclib.MultiCall(server)

    def test_connect(self):
        client = self.get_client()
        result = client.ping()
        self.assertTrue(result)

    def test_single_args(self):
        client = self.get_client()
        result = client.add(5, 10)
        self.assertTrue(result == 15)

    def test_single_kwargs(self):
        client = self.get_client()
        result = client.add(x=5, y=10)
        self.assertTrue(result == 15)

    def test_single_kwargs_and_args(self):
        client = self.get_client()
        self.assertRaises(jsonrpclib.ProtocolError, client.add, (5, ),
                          {'y': 10})

    def test_single_notify(self):
        client = self.get_client()
        result = client._notify.add(5, 10)
        self.assertTrue(result is None)

    def test_single_namespace(self):
        client = self.get_client()
        client.namespace.sum(1, 2, 4)
        request = json.loads(self.history.request)
        response = json.loads(self.history.response)
        verify_request = {
            "jsonrpc": "2.0",
            "params": [1, 2, 4],
            "id": "5",
            "method": "namespace.sum"
        }
        verify_response = {"jsonrpc": "2.0", "result": 7, "id": request['id']}
        verify_request['id'] = request['id']
        self.assertTrue(verify_request == request)
        self.assertTrue(verify_response == response)

    def test_multicall_success(self):
        multicall = self.get_multicall_client()
        multicall.ping()
        multicall.add(5, 10)
        multicall.namespace.sum(5, 10, 15)
        correct = [True, 15, 30]

        for i, result in enumerate(multicall()):
            self.assertTrue(result == correct[i])

    def test_multicall_success_2(self):
        multicall = self.get_multicall_client()
        for i in range(3):
            multicall.add(5, i)
        result = multicall()
        self.assertTrue(result[2] == 7)

    def test_multicall_failure(self):
        multicall = self.get_multicall_client()
        multicall.ping()
        multicall.add(x=5, y=10, z=10)
        raises = [None, jsonrpclib.ProtocolError]
        result = multicall()
        for i in range(2):
            if not raises[i]:
                result[i]
            else:

                def func():
                    return result[i]

                self.assertRaises(raises[i], func)
예제 #8
0
class TestCompatibility(unittest.TestCase):
    """
    Tests JSON-RPC compatibility
    """

    def setUp(self):
        """
        Pre-test set up
        """
        # Set up the server
        self.server = UtilityServer().start("", 0)
        self.port = self.server.get_port()

        # Set up the client
        self.history = jsonrpclib.history.History()
        self.client = jsonrpclib.ServerProxy(
            "http://localhost:{0}".format(self.port), history=self.history
        )

    def tearDown(self):
        """
        Post-test clean up
        """
        # Close the client
        self.client("close")()

        # Stop the server
        self.server.stop()

    # Version 2.0 Tests
    def test_positional(self):
        """ Positional arguments in a single call """
        result = self.client.subtract(23, 42)
        self.assertTrue(result == -19)
        result = self.client.subtract(42, 23)
        self.assertTrue(result == 19)
        request = json.loads(self.history.request)
        response = json.loads(self.history.response)
        verify_request = {
            "jsonrpc": "2.0",
            "method": "subtract",
            "params": [42, 23],
            "id": request["id"],
        }
        verify_response = {"jsonrpc": "2.0", "result": 19, "id": request["id"]}
        self.assertTrue(request == verify_request)
        self.assertTrue(response == verify_response)

    def test_named(self):
        """ Named arguments in a single call """
        result = self.client.subtract(subtrahend=23, minuend=42)
        self.assertTrue(result == 19)
        result = self.client.subtract(minuend=42, subtrahend=23)
        self.assertTrue(result == 19)
        request = json.loads(self.history.request)
        response = json.loads(self.history.response)
        verify_request = {
            "jsonrpc": "2.0",
            "method": "subtract",
            "params": {"subtrahend": 23, "minuend": 42},
            "id": request["id"],
        }
        verify_response = {"jsonrpc": "2.0", "result": 19, "id": request["id"]}
        self.assertTrue(request == verify_request)
        self.assertTrue(response == verify_response)

    def test_notification(self):
        """ Testing a notification (response should be null) """
        result = self.client._notify.update(1, 2, 3, 4, 5)
        self.assertTrue(result is None)
        request = json.loads(self.history.request)
        response = self.history.response
        verify_request = {
            "jsonrpc": "2.0",
            "method": "update",
            "params": [1, 2, 3, 4, 5],
        }
        verify_response = ""
        self.assertTrue(request == verify_request)
        self.assertTrue(response == verify_response)

    def test_non_existent_method(self):
        """ Testing behaviour when calling a non-existent method """
        self.assertRaises(jsonrpclib.ProtocolError, self.client.foobar)
        request = json.loads(self.history.request)
        response = json.loads(self.history.response)
        verify_request = {
            "jsonrpc": "2.0",
            "method": "foobar",
            "id": request["id"],
        }
        verify_response = {
            "jsonrpc": "2.0",
            "error": {"code": -32601, "message": response["error"]["message"]},
            "id": request["id"],
        }
        self.assertTrue(request == verify_request)
        self.assertTrue(response == verify_response)

    def test_special_method(self):
        """ Tests behaviour on dunder methods """
        self.assertRaises(
            AttributeError, getattr, self.client, "__special_method__"
        )
        self.assertIsNone(self.history.request)

    def test_invalid_json(self):
        """ Tests behaviour on invalid JSON request """
        invalid_json = (
            '{"jsonrpc": "2.0", "method": "foobar, ' + '"params": "bar", "baz]'
        )
        self.client._run_request(invalid_json)
        response = json.loads(self.history.response)
        verify_response = json.loads(
            '{"jsonrpc": "2.0", "error": {"code": -32700,'
            + ' "message": "Parse error."}, "id": null}'
        )
        verify_response["error"]["message"] = response["error"]["message"]
        self.assertTrue(response == verify_response)

    def test_invalid_request(self):
        """ Tests incomplete request """
        invalid_request = '{"jsonrpc": "2.0", "method": 1, "params": "bar"}'
        self.client._run_request(invalid_request)
        response = json.loads(self.history.response)
        verify_response = json.loads(
            '{"jsonrpc": "2.0", "error": {"code": -32600, '
            + '"message": "Invalid Request."}, "id": null}'
        )
        verify_response["error"]["message"] = response["error"]["message"]
        self.assertTrue(response == verify_response)

    def test_batch_invalid_json(self):
        """ Tests invalid JSON request on batch call """
        invalid_request = (
            '[ {"jsonrpc": "2.0", "method": "sum", '
            + '"params": [1,2,4], "id": "1"},{"jsonrpc": "2.0", "method" ]'
        )
        self.client._run_request(invalid_request)
        response = json.loads(self.history.response)
        verify_response = json.loads(
            '{"jsonrpc": "2.0", "error": {"code": -32700,'
            + '"message": "Parse error."}, "id": null}'
        )
        verify_response["error"]["message"] = response["error"]["message"]
        self.assertTrue(response == verify_response)

    def test_empty_array(self):
        """ Tests empty array as request """
        invalid_request = "[]"
        self.client._run_request(invalid_request)
        response = json.loads(self.history.response)
        verify_response = json.loads(
            '{"jsonrpc": "2.0", "error": {"code": -32600, '
            + '"message": "Invalid Request."}, "id": null}'
        )
        verify_response["error"]["message"] = response["error"]["message"]
        self.assertTrue(response == verify_response)

    def test_nonempty_array(self):
        """ Tests array as request """
        invalid_request = "[1,2]"
        request_obj = json.loads(invalid_request)
        self.client._run_request(invalid_request)
        response = json.loads(self.history.response)
        self.assertTrue(len(response) == len(request_obj))
        for resp in response:
            verify_resp = json.loads(
                '{"jsonrpc": "2.0", "error": {"code": -32600, '
                + '"message": "Invalid Request."}, "id": null}'
            )
            verify_resp["error"]["message"] = resp["error"]["message"]
            self.assertTrue(resp == verify_resp)

    def test_batch(self):
        """ Tests batch call """
        multicall = jsonrpclib.MultiCall(self.client)
        multicall.sum(1, 2, 4)
        multicall._notify.notify_hello(7)
        multicall.subtract(42, 23)
        multicall.foo.get(name="myself")
        multicall.get_data()
        job_requests = [j.request() for j in multicall._job_list]
        job_requests.insert(3, '{"foo": "boo"}')
        json_requests = "[%s]" % ",".join(job_requests)
        requests = json.loads(json_requests)
        responses = self.client._run_request(json_requests)

        verify_requests = json.loads(
            """[
            {"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},
            {"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
            {"jsonrpc": "2.0", "method": "subtract",
             "params": [42,23], "id": "2"},
            {"foo": "boo"},
            {"jsonrpc": "2.0", "method": "foo.get",
             "params": {"name": "myself"}, "id": "5"},
            {"jsonrpc": "2.0", "method": "get_data", "id": "9"}
        ]"""
        )

        # Thankfully, these are in order so testing is pretty simple.
        verify_responses = json.loads(
            """[
            {"jsonrpc": "2.0", "result": 7, "id": "1"},
            {"jsonrpc": "2.0", "result": 19, "id": "2"},
            {"jsonrpc": "2.0",
             "error": {"code": -32600, "message": "Invalid Request."},
             "id": null},
            {"jsonrpc": "2.0",
             "error": {"code": -32601, "message": "Method not found."},
             "id": "5"},
            {"jsonrpc": "2.0", "result": ["hello", 5], "id": "9"}
        ]"""
        )

        self.assertTrue(len(requests) == len(verify_requests))
        self.assertTrue(len(responses) == len(verify_responses))

        responses_by_id = {}
        response_i = 0

        for verify_request, request in zip(verify_requests, requests):
            response = None
            if request.get("method") != "notify_hello":
                req_id = request.get("id")
                if "id" in verify_request:
                    verify_request["id"] = req_id
                verify_response = verify_responses[response_i]
                verify_response["id"] = req_id
                responses_by_id[req_id] = verify_response
                response_i += 1
                response = verify_response
            self.assertTrue(request == verify_request)

        for response in responses:
            verify_response = responses_by_id.get(response.get("id"))
            if "error" in verify_response:
                verify_response["error"]["message"] = response["error"][
                    "message"
                ]
            self.assertTrue(response == verify_response)

    def test_batch_notifications(self):
        """ Tests batch notifications """
        multicall = jsonrpclib.MultiCall(self.client)
        multicall._notify.notify_sum(1, 2, 4)
        multicall._notify.notify_hello(7)
        result = multicall()
        self.assertTrue(len(result) == 0)
        valid_request = json.loads(
            '[{"jsonrpc": "2.0", "method": "notify_sum", '
            + '"params": [1,2,4]},{"jsonrpc": "2.0", '
            + '"method": "notify_hello", "params": [7]}]'
        )
        request = json.loads(self.history.request)
        self.assertTrue(len(request) == len(valid_request))
        for req, valid_req in zip(request, valid_request):
            self.assertTrue(req == valid_req)
        self.assertTrue(self.history.response == "")

    def test_url_query_string(self):
        """ Tests if the query string arguments are kept """
        # Prepare a simple server
        class ReqHandler(BaseHTTPRequestHandler):
            """
            Basic request handler that returns parameters
            """

            def do_POST(self):
                parsed = urlparse(self.path)
                result = {
                    "id": 0,
                    "error": None,
                    "result": {
                        "path": parsed.path,
                        "qs": parsed.query,
                    },
                }
                result_str = json.dumps(result).encode("utf8")

                self.send_response(200)
                self.send_header("content-type", "application/json")
                self.send_header("content-length", str(len(result_str)))
                self.end_headers()

                self.wfile.write(result_str)

        # Start it
        httpd = HTTPServer(("", 0), ReqHandler)

        # Run it in a thread
        thread = threading.Thread(target=httpd.serve_forever)
        thread.daemon = True
        thread.start()

        # Prepare a random value
        arg = str(random.randint(0, 1024))

        # Prepare the client
        client = jsonrpclib.ServerProxy(
            "http://localhost:{port}/test?q={arg}".format(
                port=httpd.server_port, arg=arg
            )
        )

        # Run a query
        result = client.test()

        # Stop the server
        httpd.shutdown()
        httpd.server_close()

        # Check the result
        self.assertEqual(result["path"], "/test", "Invalid path")
        self.assertEqual(
            result["qs"], "q={}".format(arg), "Invalid query string"
        )

        # Wait the server to stop (5 sec max)
        thread.join(5)
예제 #9
0
class HeadersTests(unittest.TestCase):
    """
    These tests verify functionality of additional headers.
    """
    REQUEST_LINE = "^send: POST"

    def setUp(self):
        """
        Sets up the test
        """
        # Set up the server
        self.server = UtilityServer().start('', 0)
        self.port = self.server.get_port()

    def tearDown(self):
        """
        Post-test clean up
        """
        # Stop the server
        self.server.stop()

    @contextlib.contextmanager
    def captured_headers(self, check_duplicates=True):
        """
        Captures the request headers. Yields the {header : value} dictionary,
        where keys are in lower case.

        :param check_duplicates: If True, raises an error if a header appears
                                 twice
        """
        # Redirect the standard output, to catch jsonrpclib verbose messages
        stdout = sys.stdout
        sys.stdout = f = StringIO()
        headers = {}
        yield headers
        sys.stdout = stdout

        # Extract the sent request content
        request_lines = f.getvalue().splitlines()
        request_lines = list(
            filter(lambda l: l.startswith("send:"), request_lines))
        request_line = request_lines[0].split("send: ")[-1]

        # Convert it to a string
        try:
            # Use eval to convert the representation into a string
            request_line = from_bytes(eval(request_line))
        except:
            # Keep the received version
            pass

        # Extract headers
        raw_headers = request_line.splitlines()[1:-1]
        raw_headers = map(lambda h: re.split(r":\s?", h, 1), raw_headers)
        for header, value in raw_headers:
            header = header.lower()
            if check_duplicates and header in headers:
                raise KeyError("Header defined twice: {0}".format(header))
            headers[header] = value

    def test_should_extract_headers(self):
        # given
        client = jsonrpclib.ServerProxy('http://localhost:{0}'.format(
            self.port),
                                        verbose=1)

        # when
        with self.captured_headers() as headers:
            response = client.ping()
            self.assertTrue(response)

        # then
        self.assertTrue(len(headers) > 0)
        self.assertTrue('content-type' in headers)
        self.assertEqual(headers['content-type'], 'application/json-rpc')

    def test_should_add_additional_headers(self):
        # given
        client = jsonrpclib.ServerProxy('http://localhost:{0}'.format(
            self.port),
                                        verbose=1,
                                        headers={'X-My-Header': 'Test'})

        # when
        with self.captured_headers() as headers:
            response = client.ping()
            self.assertTrue(response)

        # then
        self.assertTrue('x-my-header' in headers)
        self.assertEqual(headers['x-my-header'], 'Test')

    def test_should_add_additional_headers_to_notifications(self):
        # given
        client = jsonrpclib.ServerProxy('http://localhost:{0}'.format(
            self.port),
                                        verbose=1,
                                        headers={'X-My-Header': 'Test'})

        # when
        with self.captured_headers() as headers:
            client._notify.ping()

        # then
        self.assertTrue('x-my-header' in headers)
        self.assertEqual(headers['x-my-header'], 'Test')

    def test_should_override_headers(self):
        # given
        client = jsonrpclib.ServerProxy('http://localhost:{0}'.format(
            self.port),
                                        verbose=1,
                                        headers={
                                            'User-Agent': 'jsonrpclib test',
                                            'Host': 'example.com'
                                        })

        # when
        with self.captured_headers(False) as headers:
            response = client.ping()
            self.assertTrue(response)

        # then
        self.assertEqual(headers['user-agent'], 'jsonrpclib test')
        self.assertEqual(headers['host'], 'example.com')

    def test_should_not_override_content_length(self):
        # given
        client = jsonrpclib.ServerProxy(
            'http://localhost:{0}'.format(self.port),
            verbose=1,
            headers={'Content-Length': 'invalid value'})

        # when
        with self.captured_headers() as headers:
            response = client.ping()
            self.assertTrue(response)

        # then
        self.assertTrue('content-length' in headers)
        self.assertNotEqual(headers['content-length'], 'invalid value')

    def test_should_convert_header_values_to_basestring(self):
        # given
        client = jsonrpclib.ServerProxy('http://localhost:{0}'.format(
            self.port),
                                        verbose=1,
                                        headers={'X-Test': 123})

        # when
        with self.captured_headers() as headers:
            response = client.ping()
            self.assertTrue(response)

        # then
        self.assertTrue('x-test' in headers)
        self.assertEqual(headers['x-test'], '123')

    def test_should_add_custom_headers_to_methods(self):
        # given
        client = jsonrpclib.ServerProxy('http://localhost:{0}'.format(
            self.port),
                                        verbose=1)

        # when
        with self.captured_headers() as headers:
            with client._additional_headers({'X-Method': 'Method'}) as cl:
                response = cl.ping()

            self.assertTrue(response)

        # then
        self.assertTrue('x-method' in headers)
        self.assertEqual(headers['x-method'], 'Method')

    def test_should_override_global_headers(self):
        # given
        client = jsonrpclib.ServerProxy('http://localhost:{0}'.format(
            self.port),
                                        verbose=1,
                                        headers={'X-Test': 'Global'})

        # when
        with self.captured_headers() as headers:
            with client._additional_headers({'X-Test': 'Method'}) as cl:
                response = cl.ping()
                self.assertTrue(response)

        # then
        self.assertTrue('x-test' in headers)
        self.assertEqual(headers['x-test'], 'Method')

    def test_should_restore_global_headers(self):
        # given
        client = jsonrpclib.ServerProxy('http://localhost:{0}'.format(
            self.port),
                                        verbose=1,
                                        headers={'X-Test': 'Global'})

        # when
        with self.captured_headers() as headers:
            with client._additional_headers({'X-Test': 'Method'}) as cl:
                response = cl.ping()
                self.assertTrue(response)

        self.assertTrue('x-test' in headers)
        self.assertEqual(headers['x-test'], 'Method')

        with self.captured_headers() as headers:
            response = cl.ping()
            self.assertTrue(response)

        # then
        self.assertTrue('x-test' in headers)
        self.assertEqual(headers['x-test'], 'Global')

    def test_should_allow_to_nest_additional_header_blocks(self):
        # given
        client = jsonrpclib.ServerProxy('http://localhost:{0}'.format(
            self.port),
                                        verbose=1)

        # when
        with client._additional_headers({'X-Level-1': '1'}) as cl_level1:
            with self.captured_headers() as headers1:
                response = cl_level1.ping()
                self.assertTrue(response)

            with cl_level1._additional_headers({'X-Level-2': '2'}) as cl:
                with self.captured_headers() as headers2:
                    response = cl.ping()
                    self.assertTrue(response)

        # then
        self.assertTrue('x-level-1' in headers1)
        self.assertEqual(headers1['x-level-1'], '1')

        self.assertTrue('x-level-1' in headers2)
        self.assertEqual(headers1['x-level-1'], '1')
        self.assertTrue('x-level-2' in headers2)
        self.assertEqual(headers2['x-level-2'], '2')
예제 #10
0
class TestCompatibility(unittest.TestCase):
    """
    Tests JSON-RPC compatibility
    """
    def setUp(self):
        """
        Pre-test set up
        """
        # Set up the server
        self.server = UtilityServer().start('', 0)
        self.port = self.server.get_port()

        # Set up the client
        self.history = jsonrpclib.history.History()
        self.client = jsonrpclib.ServerProxy('http://localhost:{0}'.format(
            self.port),
                                             history=self.history)

    def tearDown(self):
        """
        Post-test clean up
        """
        # Close the client
        self.client("close")()

        # Stop the server
        self.server.stop()

    # Version 2.0 Tests
    def test_positional(self):
        """ Positional arguments in a single call """
        result = self.client.subtract(23, 42)
        self.assertTrue(result == -19)
        result = self.client.subtract(42, 23)
        self.assertTrue(result == 19)
        request = json.loads(self.history.request)
        response = json.loads(self.history.response)
        verify_request = {
            "jsonrpc": "2.0",
            "method": "subtract",
            "params": [42, 23],
            "id": request['id']
        }
        verify_response = {"jsonrpc": "2.0", "result": 19, "id": request['id']}
        self.assertTrue(request == verify_request)
        self.assertTrue(response == verify_response)

    def test_named(self):
        """ Named arguments in a single call """
        result = self.client.subtract(subtrahend=23, minuend=42)
        self.assertTrue(result == 19)
        result = self.client.subtract(minuend=42, subtrahend=23)
        self.assertTrue(result == 19)
        request = json.loads(self.history.request)
        response = json.loads(self.history.response)
        verify_request = {
            "jsonrpc": "2.0",
            "method": "subtract",
            "params": {
                "subtrahend": 23,
                "minuend": 42
            },
            "id": request['id']
        }
        verify_response = {"jsonrpc": "2.0", "result": 19, "id": request['id']}
        self.assertTrue(request == verify_request)
        self.assertTrue(response == verify_response)

    def test_notification(self):
        """ Testing a notification (response should be null) """
        result = self.client._notify.update(1, 2, 3, 4, 5)
        self.assertTrue(result is None)
        request = json.loads(self.history.request)
        response = self.history.response
        verify_request = {
            "jsonrpc": "2.0",
            "method": "update",
            "params": [1, 2, 3, 4, 5]
        }
        verify_response = ''
        self.assertTrue(request == verify_request)
        self.assertTrue(response == verify_response)

    def test_non_existent_method(self):
        self.assertRaises(jsonrpclib.ProtocolError, self.client.foobar)
        request = json.loads(self.history.request)
        response = json.loads(self.history.response)
        verify_request = {
            "jsonrpc": "2.0",
            "method": "foobar",
            "id": request['id']
        }
        verify_response = {
            "jsonrpc": "2.0",
            "error": {
                "code": -32601,
                "message": response['error']['message']
            },
            "id": request['id']
        }
        self.assertTrue(request == verify_request)
        self.assertTrue(response == verify_response)

    def test_special_method(self):
        self.assertRaises(AttributeError, getattr, self.client,
                          '__special_method__')
        self.assertIsNone(self.history.request)

    def test_invalid_json(self):
        invalid_json = '{"jsonrpc": "2.0", "method": "foobar, ' + \
            '"params": "bar", "baz]'
        self.client._run_request(invalid_json)
        response = json.loads(self.history.response)
        verify_response = json.loads(
            '{"jsonrpc": "2.0", "error": {"code": -32700,' +
            ' "message": "Parse error."}, "id": null}')
        verify_response['error']['message'] = response['error']['message']
        self.assertTrue(response == verify_response)

    def test_invalid_request(self):
        invalid_request = '{"jsonrpc": "2.0", "method": 1, "params": "bar"}'
        self.client._run_request(invalid_request)
        response = json.loads(self.history.response)
        verify_response = json.loads(
            '{"jsonrpc": "2.0", "error": {"code": -32600, ' +
            '"message": "Invalid Request."}, "id": null}')
        verify_response['error']['message'] = response['error']['message']
        self.assertTrue(response == verify_response)

    def test_batch_invalid_json(self):
        invalid_request = '[ {"jsonrpc": "2.0", "method": "sum", ' + \
            '"params": [1,2,4], "id": "1"},{"jsonrpc": "2.0", "method" ]'
        self.client._run_request(invalid_request)
        response = json.loads(self.history.response)
        verify_response = json.loads(
            '{"jsonrpc": "2.0", "error": {"code": -32700,' +
            '"message": "Parse error."}, "id": null}')
        verify_response['error']['message'] = response['error']['message']
        self.assertTrue(response == verify_response)

    def test_empty_array(self):
        invalid_request = '[]'
        self.client._run_request(invalid_request)
        response = json.loads(self.history.response)
        verify_response = json.loads(
            '{"jsonrpc": "2.0", "error": {"code": -32600, ' +
            '"message": "Invalid Request."}, "id": null}')
        verify_response['error']['message'] = response['error']['message']
        self.assertTrue(response == verify_response)

    def test_nonempty_array(self):
        invalid_request = '[1,2]'
        request_obj = json.loads(invalid_request)
        self.client._run_request(invalid_request)
        response = json.loads(self.history.response)
        self.assertTrue(len(response) == len(request_obj))
        for resp in response:
            verify_resp = json.loads(
                '{"jsonrpc": "2.0", "error": {"code": -32600, ' +
                '"message": "Invalid Request."}, "id": null}')
            verify_resp['error']['message'] = resp['error']['message']
            self.assertTrue(resp == verify_resp)

    def test_batch(self):
        multicall = jsonrpclib.MultiCall(self.client)
        multicall.sum(1, 2, 4)
        multicall._notify.notify_hello(7)
        multicall.subtract(42, 23)
        multicall.foo.get(name='myself')
        multicall.get_data()
        job_requests = [j.request() for j in multicall._job_list]
        job_requests.insert(3, '{"foo": "boo"}')
        json_requests = '[%s]' % ','.join(job_requests)
        requests = json.loads(json_requests)
        responses = self.client._run_request(json_requests)

        verify_requests = json.loads("""[
            {"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},
            {"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
            {"jsonrpc": "2.0", "method": "subtract",
             "params": [42,23], "id": "2"},
            {"foo": "boo"},
            {"jsonrpc": "2.0", "method": "foo.get",
             "params": {"name": "myself"}, "id": "5"},
            {"jsonrpc": "2.0", "method": "get_data", "id": "9"}
        ]""")

        # Thankfully, these are in order so testing is pretty simple.
        verify_responses = json.loads("""[
            {"jsonrpc": "2.0", "result": 7, "id": "1"},
            {"jsonrpc": "2.0", "result": 19, "id": "2"},
            {"jsonrpc": "2.0",
             "error": {"code": -32600, "message": "Invalid Request."},
             "id": null},
            {"jsonrpc": "2.0",
             "error": {"code": -32601, "message": "Method not found."},
             "id": "5"},
            {"jsonrpc": "2.0", "result": ["hello", 5], "id": "9"}
        ]""")

        self.assertTrue(len(requests) == len(verify_requests))
        self.assertTrue(len(responses) == len(verify_responses))

        responses_by_id = {}
        response_i = 0

        for i in range(len(requests)):
            verify_request = verify_requests[i]
            request = requests[i]
            response = None
            if request.get('method') != 'notify_hello':
                req_id = request.get('id')
                if 'id' in verify_request:
                    verify_request['id'] = req_id
                verify_response = verify_responses[response_i]
                verify_response['id'] = req_id
                responses_by_id[req_id] = verify_response
                response_i += 1
                response = verify_response
            self.assertTrue(request == verify_request)

        for response in responses:
            verify_response = responses_by_id.get(response.get('id'))
            if 'error' in verify_response:
                verify_response['error']['message'] = \
                    response['error']['message']
            self.assertTrue(response == verify_response)

    def test_batch_notifications(self):
        multicall = jsonrpclib.MultiCall(self.client)
        multicall._notify.notify_sum(1, 2, 4)
        multicall._notify.notify_hello(7)
        result = multicall()
        self.assertTrue(len(result) == 0)
        valid_request = json.loads(
            '[{"jsonrpc": "2.0", "method": "notify_sum", ' +
            '"params": [1,2,4]},{"jsonrpc": "2.0", ' +
            '"method": "notify_hello", "params": [7]}]')
        request = json.loads(self.history.request)
        self.assertTrue(len(request) == len(valid_request))
        for i in range(len(request)):
            req = request[i]
            valid_req = valid_request[i]
            self.assertTrue(req == valid_req)
        self.assertTrue(self.history.response == '')
예제 #11
0
class HeadersTests(unittest.TestCase):
    """
    These tests verify functionality of additional headers.
    """
    REQUEST_LINE = "^send: POST"

    def setUp(self):
        """
        Sets up the test
        """
        # Set up the server
        self.server = UtilityServer().start('', 0)
        self.port = self.server.get_port()

    def tearDown(self):
        """
        Post-test clean up
        """
        # Stop the server
        self.server.stop()

    @contextlib.contextmanager
    def captured_headers(self):
        """
        Captures the request headers. Yields the {header : value} dictionary,
        where keys are in lower case.
        """
        # Redirect the standard output, to catch jsonrpclib verbose messages
        stdout = sys.stdout
        sys.stdout = f = StringIO()
        headers = {}
        yield headers
        sys.stdout = stdout

        # Extract the sent request content
        request_lines = f.getvalue().splitlines()
        request_lines = list(filter(lambda l: l.startswith("send:"),
                                    request_lines))
        request_line = request_lines[0].split("send: ")[-1]

        # Convert it to a string
        try:
            # Use eval to convert the representation into a string
            request_line = from_bytes(eval(request_line))
        except:
            # Keep the received version
            pass

        # Extract headers
        raw_headers = request_line.splitlines()[1:-1]
        raw_headers = map(lambda h: re.split(r":\s?", h, 1), raw_headers)
        for header, value in raw_headers:
            headers[header.lower()] = value

    def test_should_extract_headers(self):
        # given
        client = jsonrpclib.ServerProxy('http://localhost:{0}'
                                        .format(self.port), verbose=1)

        # when
        with self.captured_headers() as headers:
            response = client.ping()
            self.assertTrue(response)

        # then
        self.assertTrue(len(headers) > 0)
        self.assertTrue('content-type' in headers)
        self.assertEqual(headers['content-type'], 'application/json-rpc')

    def test_should_add_additional_headers(self):
        # given
        client = jsonrpclib.ServerProxy(
            'http://localhost:{0}'.format(self.port), verbose=1,
            headers={'X-My-Header': 'Test'})

        # when
        with self.captured_headers() as headers:
            response = client.ping()
            self.assertTrue(response)

        # then
        self.assertTrue('x-my-header' in headers)
        self.assertEqual(headers['x-my-header'], 'Test')

    def test_should_add_additional_headers_to_notifications(self):
        # given
        client = jsonrpclib.ServerProxy(
            'http://localhost:{0}'.format(self.port), verbose=1,
            headers={'X-My-Header': 'Test'})

        # when
        with self.captured_headers() as headers:
            client._notify.ping()

        # then
        self.assertTrue('x-my-header' in headers)
        self.assertEqual(headers['x-my-header'], 'Test')

    def test_should_override_headers(self):
        # given
        client = jsonrpclib.ServerProxy(
            'http://localhost:{0}'.format(self.port), verbose=1,
            headers={'User-Agent': 'jsonrpclib test', 'Host': 'example.com'})

        # when
        with self.captured_headers() as headers:
            response = client.ping()
            self.assertTrue(response)

        # then
        self.assertEqual(headers['user-agent'], 'jsonrpclib test')
        self.assertEqual(headers['host'], 'example.com')

    def test_should_not_override_content_length(self):
        # given
        client = jsonrpclib.ServerProxy(
            'http://localhost:{0}'.format(self.port), verbose=1,
            headers={'Content-Length': 'invalid value'})

        # when
        with self.captured_headers() as headers:
            response = client.ping()
            self.assertTrue(response)

        # then
        self.assertTrue('content-length' in headers)
        self.assertNotEqual(headers['content-length'], 'invalid value')

    def test_should_convert_header_values_to_basestring(self):
        # given
        client = jsonrpclib.ServerProxy(
            'http://localhost:{0}'.format(self.port), verbose=1,
            headers={'X-Test': 123})

        # when
        with self.captured_headers() as headers:
            response = client.ping()
            self.assertTrue(response)

        # then
        self.assertTrue('x-test' in headers)
        self.assertEqual(headers['x-test'], '123')

    def test_should_add_custom_headers_to_methods(self):
        # given
        client = jsonrpclib.ServerProxy('http://localhost:{0}'
                                        .format(self.port), verbose=1)

        # when
        with self.captured_headers() as headers:
            with client._additional_headers({'X-Method': 'Method'}) as cl:
                response = cl.ping()

            self.assertTrue(response)

        # then
        self.assertTrue('x-method' in headers)
        self.assertEqual(headers['x-method'], 'Method')

    def test_should_override_global_headers(self):
        # given
        client = jsonrpclib.ServerProxy(
            'http://localhost:{0}'.format(self.port), verbose=1,
            headers={'X-Test': 'Global'})

        # when
        with self.captured_headers() as headers:
            with client._additional_headers({'X-Test': 'Method'}) as cl:
                response = cl.ping()
                self.assertTrue(response)

        # then
        self.assertTrue('x-test' in headers)
        self.assertEqual(headers['x-test'], 'Method')

    def test_should_restore_global_headers(self):
        # given
        client = jsonrpclib.ServerProxy(
            'http://localhost:{0}'.format(self.port), verbose=1,
            headers={'X-Test': 'Global'})

        # when
        with self.captured_headers() as headers:
            with client._additional_headers({'X-Test': 'Method'}) as cl:
                response = cl.ping()
                self.assertTrue(response)

        self.assertTrue('x-test' in headers)
        self.assertEqual(headers['x-test'], 'Method')

        with self.captured_headers() as headers:
            response = cl.ping()
            self.assertTrue(response)

        # then
        self.assertTrue('x-test' in headers)
        self.assertEqual(headers['x-test'], 'Global')

    def test_should_allow_to_nest_additional_header_blocks(self):
        # given
        client = jsonrpclib.ServerProxy('http://localhost:{0}'
                                        .format(self.port), verbose=1)

        # when
        with client._additional_headers({'X-Level-1': '1'}) as cl_level1:
            with self.captured_headers() as headers1:
                response = cl_level1.ping()
                self.assertTrue(response)

            with cl_level1._additional_headers({'X-Level-2': '2'}) as cl:
                with self.captured_headers() as headers2:
                    response = cl.ping()
                    self.assertTrue(response)

        # then
        self.assertTrue('x-level-1' in headers1)
        self.assertEqual(headers1['x-level-1'], '1')

        self.assertTrue('x-level-1' in headers2)
        self.assertEqual(headers1['x-level-1'], '1')
        self.assertTrue('x-level-2' in headers2)
        self.assertEqual(headers2['x-level-2'], '2')
예제 #12
0
class TestCompatibility(unittest.TestCase):
    """
    Tests JSON-RPC compatibility
    """
    def setUp(self):
        """
        Pre-test set up
        """
        # Set up the server
        self.server = UtilityServer().start('', 0)
        self.port = self.server.get_port()

        # Set up the client
        self.history = jsonrpclib.history.History()
        self.client = jsonrpclib.ServerProxy(
            'http://localhost:{0}'.format(self.port), history=self.history)

    def tearDown(self):
        """
        Post-test clean up
        """
        # Close the client
        self.client("close")()

        # Stop the server
        self.server.stop()

    # Version 2.0 Tests
    def test_positional(self):
        """ Positional arguments in a single call """
        result = self.client.subtract(23, 42)
        self.assertTrue(result == -19)
        result = self.client.subtract(42, 23)
        self.assertTrue(result == 19)
        request = json.loads(self.history.request)
        response = json.loads(self.history.response)
        verify_request = {
            "jsonrpc": "2.0", "method": "subtract",
            "params": [42, 23], "id": request['id']
        }
        verify_response = {
            "jsonrpc": "2.0", "result": 19, "id": request['id']
        }
        self.assertTrue(request == verify_request)
        self.assertTrue(response == verify_response)

    def test_named(self):
        """ Named arguments in a single call """
        result = self.client.subtract(subtrahend=23, minuend=42)
        self.assertTrue(result == 19)
        result = self.client.subtract(minuend=42, subtrahend=23)
        self.assertTrue(result == 19)
        request = json.loads(self.history.request)
        response = json.loads(self.history.response)
        verify_request = {
            "jsonrpc": "2.0", "method": "subtract",
            "params": {"subtrahend": 23, "minuend": 42},
            "id": request['id']
        }
        verify_response = {
            "jsonrpc": "2.0", "result": 19, "id": request['id']
        }
        self.assertTrue(request == verify_request)
        self.assertTrue(response == verify_response)

    def test_notification(self):
        """ Testing a notification (response should be null) """
        result = self.client._notify.update(1, 2, 3, 4, 5)
        self.assertTrue(result is None)
        request = json.loads(self.history.request)
        response = self.history.response
        verify_request = {
            "jsonrpc": "2.0", "method": "update", "params": [1, 2, 3, 4, 5]
        }
        verify_response = ''
        self.assertTrue(request == verify_request)
        self.assertTrue(response == verify_response)

    def test_non_existent_method(self):
        self.assertRaises(jsonrpclib.ProtocolError, self.client.foobar)
        request = json.loads(self.history.request)
        response = json.loads(self.history.response)
        verify_request = {
            "jsonrpc": "2.0", "method": "foobar", "id": request['id']
        }
        verify_response = {
            "jsonrpc": "2.0",
            "error":
                {"code": -32601, "message": response['error']['message']},
            "id": request['id']
        }
        self.assertTrue(request == verify_request)
        self.assertTrue(response == verify_response)

    def test_invalid_json(self):
        invalid_json = '{"jsonrpc": "2.0", "method": "foobar, ' + \
            '"params": "bar", "baz]'
        self.client._run_request(invalid_json)
        response = json.loads(self.history.response)
        verify_response = json.loads(
            '{"jsonrpc": "2.0", "error": {"code": -32700,' +
            ' "message": "Parse error."}, "id": null}'
        )
        verify_response['error']['message'] = response['error']['message']
        self.assertTrue(response == verify_response)

    def test_invalid_request(self):
        invalid_request = '{"jsonrpc": "2.0", "method": 1, "params": "bar"}'
        self.client._run_request(invalid_request)
        response = json.loads(self.history.response)
        verify_response = json.loads(
            '{"jsonrpc": "2.0", "error": {"code": -32600, ' +
            '"message": "Invalid Request."}, "id": null}'
        )
        verify_response['error']['message'] = response['error']['message']
        self.assertTrue(response == verify_response)

    def test_batch_invalid_json(self):
        invalid_request = '[ {"jsonrpc": "2.0", "method": "sum", ' + \
            '"params": [1,2,4], "id": "1"},{"jsonrpc": "2.0", "method" ]'
        self.client._run_request(invalid_request)
        response = json.loads(self.history.response)
        verify_response = json.loads(
            '{"jsonrpc": "2.0", "error": {"code": -32700,' +
            '"message": "Parse error."}, "id": null}'
        )
        verify_response['error']['message'] = response['error']['message']
        self.assertTrue(response == verify_response)

    def test_empty_array(self):
        invalid_request = '[]'
        self.client._run_request(invalid_request)
        response = json.loads(self.history.response)
        verify_response = json.loads(
            '{"jsonrpc": "2.0", "error": {"code": -32600, ' +
            '"message": "Invalid Request."}, "id": null}'
        )
        verify_response['error']['message'] = response['error']['message']
        self.assertTrue(response == verify_response)

    def test_nonempty_array(self):
        invalid_request = '[1,2]'
        request_obj = json.loads(invalid_request)
        self.client._run_request(invalid_request)
        response = json.loads(self.history.response)
        self.assertTrue(len(response) == len(request_obj))
        for resp in response:
            verify_resp = json.loads(
                '{"jsonrpc": "2.0", "error": {"code": -32600, ' +
                '"message": "Invalid Request."}, "id": null}'
            )
            verify_resp['error']['message'] = resp['error']['message']
            self.assertTrue(resp == verify_resp)

    def test_batch(self):
        multicall = jsonrpclib.MultiCall(self.client)
        multicall.sum(1, 2, 4)
        multicall._notify.notify_hello(7)
        multicall.subtract(42, 23)
        multicall.foo.get(name='myself')
        multicall.get_data()
        job_requests = [j.request() for j in multicall._job_list]
        job_requests.insert(3, '{"foo": "boo"}')
        json_requests = '[%s]' % ','.join(job_requests)
        requests = json.loads(json_requests)
        responses = self.client._run_request(json_requests)

        verify_requests = json.loads("""[
            {"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},
            {"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
            {"jsonrpc": "2.0", "method": "subtract",
             "params": [42,23], "id": "2"},
            {"foo": "boo"},
            {"jsonrpc": "2.0", "method": "foo.get",
             "params": {"name": "myself"}, "id": "5"},
            {"jsonrpc": "2.0", "method": "get_data", "id": "9"}
        ]""")

        # Thankfully, these are in order so testing is pretty simple.
        verify_responses = json.loads("""[
            {"jsonrpc": "2.0", "result": 7, "id": "1"},
            {"jsonrpc": "2.0", "result": 19, "id": "2"},
            {"jsonrpc": "2.0",
             "error": {"code": -32600, "message": "Invalid Request."},
             "id": null},
            {"jsonrpc": "2.0",
             "error": {"code": -32601, "message": "Method not found."},
             "id": "5"},
            {"jsonrpc": "2.0", "result": ["hello", 5], "id": "9"}
        ]""")

        self.assertTrue(len(requests) == len(verify_requests))
        self.assertTrue(len(responses) == len(verify_responses))

        responses_by_id = {}
        response_i = 0

        for i in range(len(requests)):
            verify_request = verify_requests[i]
            request = requests[i]
            response = None
            if request.get('method') != 'notify_hello':
                req_id = request.get('id')
                if 'id' in verify_request:
                    verify_request['id'] = req_id
                verify_response = verify_responses[response_i]
                verify_response['id'] = req_id
                responses_by_id[req_id] = verify_response
                response_i += 1
                response = verify_response
            self.assertTrue(request == verify_request)

        for response in responses:
            verify_response = responses_by_id.get(response.get('id'))
            if 'error' in verify_response:
                verify_response['error']['message'] = \
                    response['error']['message']
            self.assertTrue(response == verify_response)

    def test_batch_notifications(self):
        multicall = jsonrpclib.MultiCall(self.client)
        multicall._notify.notify_sum(1, 2, 4)
        multicall._notify.notify_hello(7)
        result = multicall()
        self.assertTrue(len(result) == 0)
        valid_request = json.loads(
            '[{"jsonrpc": "2.0", "method": "notify_sum", ' +
            '"params": [1,2,4]},{"jsonrpc": "2.0", ' +
            '"method": "notify_hello", "params": [7]}]'
        )
        request = json.loads(self.history.request)
        self.assertTrue(len(request) == len(valid_request))
        for i in range(len(request)):
            req = request[i]
            valid_req = valid_request[i]
            self.assertTrue(req == valid_req)
        self.assertTrue(self.history.response == '')
예제 #13
0
class HeadersTests(unittest.TestCase):
    """
    These tests verify functionality of additional headers.
    """

    REQUEST_LINE = "^send: POST"

    def setUp(self):
        """
        Sets up the test
        """
        # Set up the server
        self.server = UtilityServer().start("", 0)
        self.port = self.server.get_port()

    def tearDown(self):
        """
        Post-test clean up
        """
        # Stop the server
        self.server.stop()

    @contextlib.contextmanager
    def captured_headers(self, check_duplicates=True):
        """
        Captures the request headers. Yields the {header : value} dictionary,
        where keys are in lower case.

        :param check_duplicates: If True, raises an error if a header appears
                                 twice
        """
        # Redirect the standard output, to catch jsonrpclib verbose messages
        stdout = sys.stdout
        sys.stdout = f = StringIO()
        headers = {}
        yield headers
        sys.stdout = stdout

        # Extract the sent request content
        request_lines = f.getvalue().splitlines()
        request_lines = list(
            filter(lambda l: l.startswith("send:"), request_lines))
        request_line = request_lines[0].split("send: ")[-1]

        # Convert it to a string
        try:
            # Use eval to convert the representation into a string
            request_line = from_bytes(eval(request_line))
        except:
            # Keep the received version
            pass

        # Extract headers
        raw_headers = request_line.splitlines()[1:-1]
        raw_headers = map(lambda h: re.split(r":\s?", h, 1), raw_headers)
        for header, value in raw_headers:
            header = header.lower()
            if check_duplicates and header in headers:
                raise KeyError("Header defined twice: {0}".format(header))
            headers[header] = value

    def test_should_extract_headers(self):
        """ Check client headers capture """
        # given
        client = jsonrpclib.ServerProxy("http://localhost:{0}".format(
            self.port),
                                        verbose=1)

        # when
        with self.captured_headers() as headers:
            response = client.ping()
            self.assertTrue(response)

        # then
        self.assertTrue(len(headers) > 0)
        self.assertTrue("content-type" in headers)
        self.assertEqual(headers["content-type"], "application/json-rpc")

    def test_should_add_additional_headers(self):
        """ Check sending of custom headers """
        # given
        client = jsonrpclib.ServerProxy(
            "http://localhost:{0}".format(self.port),
            verbose=1,
            headers={"X-My-Header": "Test"},
        )

        # when
        with self.captured_headers() as headers:
            response = client.ping()
            self.assertTrue(response)

        # then
        self.assertTrue("x-my-header" in headers)
        self.assertEqual(headers["x-my-header"], "Test")

    def test_should_add_additional_headers_to_notifications(self):
        """ Check custom headers on notifications """
        # given
        client = jsonrpclib.ServerProxy(
            "http://localhost:{0}".format(self.port),
            verbose=1,
            headers={"X-My-Header": "Test"},
        )

        # when
        with self.captured_headers() as headers:
            client._notify.ping()

        # then
        self.assertTrue("x-my-header" in headers)
        self.assertEqual(headers["x-my-header"], "Test")

    def test_should_override_headers(self):
        """ Custom headers must override default ones """
        # given
        client = jsonrpclib.ServerProxy(
            "http://localhost:{0}".format(self.port),
            verbose=1,
            headers={
                "User-Agent": "jsonrpclib test",
                "Host": "example.com"
            },
        )

        # when
        with self.captured_headers(False) as headers:
            response = client.ping()
            self.assertTrue(response)

        # then
        self.assertEqual(headers["user-agent"], "jsonrpclib test")
        self.assertEqual(headers["host"], "example.com")

    def test_should_not_override_content_length(self):
        """ Custom headers can't override Content-Length """
        # given
        client = jsonrpclib.ServerProxy(
            "http://localhost:{0}".format(self.port),
            verbose=1,
            headers={"Content-Length": "invalid value"},
        )

        # when
        with self.captured_headers() as headers:
            response = client.ping()
            self.assertTrue(response)

        # then
        self.assertTrue("content-length" in headers)
        self.assertNotEqual(headers["content-length"], "invalid value")

    def test_should_convert_header_values_to_basestring(self):
        """ Custom headers values should be converted to str """
        # given
        client = jsonrpclib.ServerProxy(
            "http://localhost:{0}".format(self.port),
            verbose=1,
            headers={"X-Test": 123},
        )

        # when
        with self.captured_headers() as headers:
            response = client.ping()
            self.assertTrue(response)

        # then
        self.assertTrue("x-test" in headers)
        self.assertEqual(headers["x-test"], "123")

    def test_should_add_custom_headers_to_methods(self):
        """ Check method-based custom headers """
        # given
        client = jsonrpclib.ServerProxy("http://localhost:{0}".format(
            self.port),
                                        verbose=1)

        # when
        with self.captured_headers() as headers:
            with client._additional_headers({"X-Method": "Method"}) as cl:
                response = cl.ping()

            self.assertTrue(response)

        # then
        self.assertTrue("x-method" in headers)
        self.assertEqual(headers["x-method"], "Method")

    def test_should_override_global_headers(self):
        """ Method-based custom headers override context ones """
        # given
        client = jsonrpclib.ServerProxy(
            "http://localhost:{0}".format(self.port),
            verbose=1,
            headers={"X-Test": "Global"},
        )

        # when
        with self.captured_headers() as headers:
            with client._additional_headers({"X-Test": "Method"}) as cl:
                response = cl.ping()
                self.assertTrue(response)

        # then
        self.assertTrue("x-test" in headers)
        self.assertEqual(headers["x-test"], "Method")

    def test_should_restore_global_headers(self):
        """ Check custom headers context clean up """
        # given
        client = jsonrpclib.ServerProxy(
            "http://localhost:{0}".format(self.port),
            verbose=1,
            headers={"X-Test": "Global"},
        )

        # when
        with self.captured_headers() as headers:
            with client._additional_headers({"X-Test": "Method"}) as cl:
                response = cl.ping()
                self.assertTrue(response)

        self.assertTrue("x-test" in headers)
        self.assertEqual(headers["x-test"], "Method")

        with self.captured_headers() as headers:
            response = cl.ping()
            self.assertTrue(response)

        # then
        self.assertTrue("x-test" in headers)
        self.assertEqual(headers["x-test"], "Global")

    def test_should_allow_to_nest_additional_header_blocks(self):
        """ Check nested additional headers """
        # given
        client = jsonrpclib.ServerProxy("http://localhost:{0}".format(
            self.port),
                                        verbose=1)

        # when
        with client._additional_headers({"X-Level-1": "1"}) as cl_level1:
            with self.captured_headers() as headers1:
                response = cl_level1.ping()
                self.assertTrue(response)

            with cl_level1._additional_headers({"X-Level-2": "2"}) as cl:
                with self.captured_headers() as headers2:
                    response = cl.ping()
                    self.assertTrue(response)

        # then
        self.assertTrue("x-level-1" in headers1)
        self.assertEqual(headers1["x-level-1"], "1")

        self.assertTrue("x-level-1" in headers2)
        self.assertEqual(headers1["x-level-1"], "1")
        self.assertTrue("x-level-2" in headers2)
        self.assertEqual(headers2["x-level-2"], "2")
예제 #14
0
class InternalTests(unittest.TestCase):
    """
    These tests verify that the client and server portions of
    jsonrpclib talk to each other properly.
    """
    def setUp(self):
        # Set up the server
        self.server = UtilityServer().start('', 0)
        self.port = self.server.get_port()

        # Prepare the client
        self.history = jsonrpclib.history.History()

    def tearDown(self):
        """
        Post-test clean up
        """
        # Stop the server
        self.server.stop()

    def get_client(self):
        """
        Utility method to get a proxy to the test server
        """
        return jsonrpclib.ServerProxy(
            "http://localhost:{0}".format(self.port),
            history=self.history
        )

    def get_multicall_client(self):
        """
        Utility method to get a multi-call proxy to the test server
        """
        server = self.get_client()
        return jsonrpclib.MultiCall(server)

    def test_connect(self):
        """
        Simple Ping() test
        """
        client = self.get_client()
        result = client.ping()
        self.assertTrue(result)

    def test_single_args(self):
        """
        Positional arguments test
        """
        client = self.get_client()
        result = client.add(5, 10)
        self.assertTrue(result == 15)

    def test_single_kwargs(self):
        """
        Keyword-arguments test
        """
        client = self.get_client()
        result = client.add(x=5, y=10)
        self.assertTrue(result == 15)

    def test_single_kwargs_and_args(self):
        """
        Mixed positional/keyword args failure test
        """
        client = self.get_client()
        self.assertRaises(jsonrpclib.ProtocolError,
                          client.add, (5,), {'y': 10})

    def test_single_notify(self):
        """
        Notification test
        """
        client = self.get_client()
        result = client._notify.add(5, 10)
        self.assertTrue(result is None)

    def test_single_namespace(self):
        """
        Namespace test
        """
        client = self.get_client()
        client.namespace.sum(1, 2, 4)
        request = json.loads(self.history.request)
        response = json.loads(self.history.response)
        verify_request = {
            "jsonrpc": "2.0", "params": [1, 2, 4],
            "id": "5", "method": "namespace.sum"
        }
        verify_response = {"jsonrpc": "2.0", "result": 7,
                           "id": request['id']}
        verify_request['id'] = request['id']
        self.assertTrue(verify_request == request)
        self.assertTrue(verify_response == response)

    def test_exception(self):
        """
        Tests the call to a method that will fail
        """
        client = self.get_client()
        try:
            client.fail()
        except jsonrpclib.ProtocolError as ex:
            self.assertIn("ValueError", str(ex))
        else:
            self.fail("Exception not raised")

    def test_multicall_success(self):
        """
        Multi-call test
        """
        multicall = self.get_multicall_client()
        multicall.ping()
        multicall.add(5, 10)
        multicall.namespace.sum(5, 10, 15)
        correct = [True, 15, 30]

        for i, result in enumerate(multicall()):
            self.assertTrue(result == correct[i])

    def test_multicall_success_2(self):
        """
        Another multi-call test
        """
        multicall = self.get_multicall_client()
        for i in range(3):
            multicall.add(5, i)
        result = multicall()
        self.assertTrue(result[2] == 7)

    def test_multicall_failure(self):
        """
        Multi-call test with failures
        """
        multicall = self.get_multicall_client()
        multicall.ping()
        multicall.add(x=5, y=10, z=10)
        raises = [None, jsonrpclib.ProtocolError]
        result = multicall()
        for i in range(2):
            if not raises[i]:
                result[i]
            else:
                def func():
                    return result[i]
                self.assertRaises(raises[i], func)