예제 #1
0
    def test_custom_types_with_typed_array_fields(self):
        rpc = RpcProcessor()

        example_type = JsonHashType('Example', 'A named hash')
        example_type.add_field('somestrs', 'array<string>', 'Some strings')
        example_type.add_field('someints', 'array<int>', 'Some integers')

        func = RpcFunction(echo_hash, 'echo_hash', 'Expects an Example hash and returns it',
                'Example', 'Returns the hash passed by the caller')
        func.add_param('Example', 'examples', 'An example hash')

        rpc.add_custom_type(example_type)
        rpc.add_function(func)

        reply = rpc.process_request('{"method": "echo_hash", "params": [{"somestrs": "", "someints": ""}], "id": 1}')
        self.assertEqual(reply['error'], {'name': 'TypeError', 'message': "echo_hash: Expected value of type 'array<string>' for parameter 'examples.somestrs' but got value of type 'string'"})
        self.assertEqual(reply['result'], None)

        reply = rpc.process_request('{"method": "echo_hash", "params": [{"somestrs": ["str1", "str2"], "someints": [1, 2, "test", 3]}], "id": 2}')
        self.assertEqual(reply['error'], {'name': 'TypeError', 'message': "echo_hash: Expected value of type 'int' for parameter 'examples.someints[2]' but got value of type 'string'"})
        self.assertEqual(reply['result'], None)

        reply = rpc.process_request('{"method": "echo_hash", "params": [{"somestrs": ["str1", "str2"], "someints": [1, 2, 3]}], "id": 3}')
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], {'somestrs': ['str1', 'str2'], 'someints': [1, 2, 3]})
예제 #2
0
 def test_custom_type_in_add_param(self):
     dummy_func = RpcFunction(dummy_function, 'dummy', 'Dummy function',
                              'int', 'Return value')
     try:
         dummy_func.add_param('ImaginaryCustomType', 'a', 'First parameter')
     except:
         self.fail("add_param raised an unexpected exception!")
예제 #3
0
    def test_enum_type_check_in_add_function(self):
        rpc = RpcProcessor()

        echo_enum_func = RpcFunction(echo_enum, 'echo_enum', '', 'PhoneType', '')
        self.assertRaises(ValueError, rpc.add_function, echo_enum_func)

        echo_enum_func = RpcFunction(echo_enum, 'echo_enum', '', 'int', '')
        echo_enum_func.add_param('PhoneType', 'phonetype', '')
        self.assertRaises(ValueError, rpc.add_function, echo_enum_func)

        rpc = RpcProcessor()

        echo_enum_func = RpcFunction(echo_enum, 'echo_enum', '', 'PhoneType', '')
        enum = JsonEnumType('PhoneType', 'Type of a phone number')
        rpc.add_custom_type(enum)

        try:
            rpc.add_function(echo_enum_func)
        except ValueError:
            self.fail("add_function raised unexpected exception!")

        rpc = RpcProcessor()

        echo_enum_func = RpcFunction(echo_enum, 'echo_enum', '', 'int', '')
        echo_enum_func.add_param('PhoneType', 'phonetype', '')
        enum = JsonEnumType('PhoneType', 'Type of a phone number')
        rpc.add_custom_type(enum)

        try:
            rpc.add_function(echo_enum_func)
        except ValueError:
            self.fail("add_function raised unexpected exception!")
예제 #4
0
    def test_type_checks_for_enums(self):
        rpc = RpcProcessor()

        enum = JsonEnumType('PhoneType', 'Type of a phone number')
        enum.add_value('HOME', 'Home phone')
        enum.add_value('WORK', 'Work phone')
        enum.add_value('MOBILE', 'Mobile phone')
        enum.add_value('FAX', 'FAX number')

        rpc.add_custom_type(enum)

        echo_enum_func = RpcFunction(echo_enum, 'echo_enum',
                                     'Returns what it was given', 'PhoneType',
                                     'Same value as the first parameter')
        echo_enum_func.add_param('PhoneType', 'type', 'Type of phone number')

        rpc.add_function(echo_enum_func)

        reply = rpc.process_request(
            '{"method": "echo_enum", "params": [-1], "id": 1}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(
            reply['error'], {
                'name':
                'TypeError',
                'message':
                "echo_enum: '-1' is not a valid value for parameter 'type' of enum type 'PhoneType'"
            })

        reply = rpc.process_request(
            '{"method": "echo_enum", "params": [4], "id": 2}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(
            reply['error'], {
                'name':
                'TypeError',
                'message':
                "echo_enum: '4' is not a valid value for parameter 'type' of enum type 'PhoneType'"
            })

        reply = rpc.process_request(
            '{"method": "echo_enum", "params": ["BLABLA"], "id": 3}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(
            reply['error'], {
                'name':
                'TypeError',
                'message':
                "echo_enum: 'BLABLA' is not a valid value for parameter 'type' of enum type 'PhoneType'"
            })

        reply = rpc.process_request(
            '{"method": "echo_enum", "params": [3], "id": 4}')
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], 3)

        reply = rpc.process_request(
            '{"method": "echo_enum", "params": ["MOBILE"], "id": 5}')
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], 'MOBILE')
예제 #5
0
    def test_hash_type_check_in_add_function(self):
        rpc = RpcProcessor()

        echo_hash_func = RpcFunction(echo_hash, 'echo_hash', '', 'Address', '')
        self.assertRaises(ValueError, rpc.add_function, echo_hash_func)

        echo_hash_func = RpcFunction(echo_hash, 'echo_hash', '', 'hash', '')
        echo_hash_func.add_param('Address', 'address', '')
        self.assertRaises(ValueError, rpc.add_function, echo_hash_func)

        rpc = RpcProcessor()

        echo_hash_func = RpcFunction(echo_hash, 'echo_hash', '', 'Address', '')
        address = JsonHashType('Address', '')
        rpc.add_custom_type(address)

        try:
            rpc.add_function(echo_hash_func)
        except ValueError:
            self.fail("add_function raised unexpected exception!")

        rpc = RpcProcessor()

        echo_hash_func = RpcFunction(echo_hash, 'echo_hash', '', 'hash', '')
        echo_hash_func.add_param('Address', 'address', '')
        address = JsonHashType('Address', '')
        rpc.add_custom_type(address)

        try:
            rpc.add_function(echo_hash_func)
        except ValueError:
            self.fail("add_function raised unexpected exception!")
예제 #6
0
    def test_wrong_number_of_params(self):
        rpc = RpcProcessor()

        echo_func = RpcFunction(echo, 'echo', 'Returns what it was given',
                                'string', 'Same value as the first parameter')
        echo_func.add_param('string', 'message', 'Message to send back')

        rpc.add_function(echo_func)

        reply = rpc.process_request(
            '{"method": "echo", "params": ["Hello Server", 42], "id": 1}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(
            reply['error'], {
                'name': 'ParamError',
                'message': 'Expected 1 parameters for \'echo\' but got 2'
            })

        reply = rpc.process_request(
            '{"method": "echo", "params": [], "id": 2}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(
            reply['error'], {
                'name': 'ParamError',
                'message': 'Expected 1 parameters for \'echo\' but got 0'
            })
예제 #7
0
    def test_method_as_rpc(self):
        obj = TestMethod()

        rpc = RpcProcessor()

        echo_func = RpcFunction(obj.echo, 'echo', 'Returns what it was given',
                                'string', 'Same value as the first parameter')
        echo_func.add_param('string', 'message', 'Message to send back')

        rpc.add_function(echo_func)

        reply = rpc.process_request(
            '{"method": "echo", "params": ["Hello Server"], "id": 1}')
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], "Hello Server")

        change_variable_func = RpcFunction(obj.change_variable,
                                           'change_variable',
                                           'Changes object attribute', 'bool',
                                           '')

        rpc.add_function(change_variable_func)

        self.assertFalse(obj.testvar)

        reply = rpc.process_request(
            '{"method": "change_variable", "params": [], "id": 2}')
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], None)

        self.assertTrue(obj.testvar)
예제 #8
0
    def test_method_as_rpc(self):
        obj = TestMethod()

        rpc = RpcProcessor()

        echo_func = RpcFunction(obj.echo, 'echo', 'Returns what it was given',
                'string', 'Same value as the first parameter')
        echo_func.add_param('string', 'message', 'Message to send back')

        rpc.add_function(echo_func)

        reply = rpc.process_request('{"method": "echo", "params": ["Hello Server"], "id": 1}')
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], "Hello Server")

        change_variable_func = RpcFunction(obj.change_variable, 'change_variable',
                'Changes object attribute', 'bool', '')

        rpc.add_function(change_variable_func)

        self.assertFalse(obj.testvar)

        reply = rpc.process_request('{"method": "change_variable", "params": [], "id": 2}')
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], None)

        self.assertTrue(obj.testvar)
예제 #9
0
 def test_typed_array_in_add_param(self):
     dummy_func = RpcFunction(dummy_function, 'dummy', 'Dummy function',
                              'int', 'Return value')
     try:
         dummy_func.add_param('array<int>', 'a', 'Typed array of integers')
     except:
         self.fail("add_param raised an unexpected exception!")
예제 #10
0
    def test_typed_arrays_with_custom_types(self):
        rpc = RpcProcessor()

        example_type = JsonHashType('Example', 'A named hash')
        example_type.add_field('somestr', 'string', 'Some string')
        example_type.add_field('someint', 'int', 'Some integer')

        func = RpcFunction(echo_array, 'echo_array', 'Expects an array of examples and returns it',
                'array<Example>', 'Returns the array passed by the caller')
        func.add_param('array<Example>', 'examples', 'An array of integer values')

        rpc.add_custom_type(example_type)
        rpc.add_function(func)

        reply = rpc.process_request('{"method": "echo_array", "params": [[5, 6, 7]], "id": 1}')
        self.assertEqual(reply['error'], {'name': 'TypeError', 'message': "echo_array: Named hash parameter 'examples[0]' of type 'Example' requires a hash value but got 'int'"})
        self.assertEqual(reply['result'], None)

        reply = rpc.process_request('{"method": "echo_array", "params": [[{"somestr": "str", "someint": 5}, {"somestr": "str", "someint": true}]], "id": 2}')
        self.assertEqual(reply['error'], {'name': 'TypeError', 'message': "echo_array: Expected value of type 'int' for parameter 'examples[1].someint' but got value of type 'bool'"})
        self.assertEqual(reply['result'], None)

        reply = rpc.process_request('{"method": "echo_array", "params": [[{"somestr": "str1", "someint": 5}, {"somestr": "str2", "someint": 6}]], "id": 3}')
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], [{'somestr': 'str1', 'someint': 5}, {'somestr': 'str2', 'someint': 6}])
예제 #11
0
    def test_enum_type_check_in_add_function(self):
        rpc = RpcProcessor()

        echo_enum_func = RpcFunction(echo_enum, 'echo_enum', '', 'PhoneType',
                                     '')
        self.assertRaises(ValueError, rpc.add_function, echo_enum_func)

        echo_enum_func = RpcFunction(echo_enum, 'echo_enum', '', 'int', '')
        echo_enum_func.add_param('PhoneType', 'phonetype', '')
        self.assertRaises(ValueError, rpc.add_function, echo_enum_func)

        rpc = RpcProcessor()

        echo_enum_func = RpcFunction(echo_enum, 'echo_enum', '', 'PhoneType',
                                     '')
        enum = JsonEnumType('PhoneType', 'Type of a phone number')
        rpc.add_custom_type(enum)

        try:
            rpc.add_function(echo_enum_func)
        except ValueError:
            self.fail("add_function raised unexpected exception!")

        rpc = RpcProcessor()

        echo_enum_func = RpcFunction(echo_enum, 'echo_enum', '', 'int', '')
        echo_enum_func.add_param('PhoneType', 'phonetype', '')
        enum = JsonEnumType('PhoneType', 'Type of a phone number')
        rpc.add_custom_type(enum)

        try:
            rpc.add_function(echo_enum_func)
        except ValueError:
            self.fail("add_function raised unexpected exception!")
예제 #12
0
    def test_json_messages(self):
        rpc = RpcProcessor()

        echo_func = RpcFunction(echo, 'echo', 'Returns what it was given',
                'string', 'Same value as the first parameter')
        echo_func.add_param('string', 'message', 'Message to send back')

        rpc.add_function(echo_func)
        server = DummyServer(rpc, None)

        # JSON-RPC call with linebreak gets processed immediatelly
        server.data_received(b'{"method": "echo", "params": ["Hello Server"], "id": 1}\r\n')
        self.assertEqual(1, len(server.responses))
        msgstr = server.responses[0].decode("utf-8")
        msg = json.loads(msgstr)
        self.assertEqual({"result": "Hello Server", "error": None, "id": 1}, msg)

        # if JSON is received in chunks the request must be processed after the linebreak
        server.data_received(b'{"method":')
        server.data_received(b' "echo", "params": ["Hello')
        server.data_received(b' Server"], "id": 2}\r\n{"method": "echo",')
        self.assertEqual(2, len(server.responses))
        msgstr = server.responses[1].decode("utf-8")
        msg = json.loads(msgstr)
        self.assertEqual({"result": "Hello Server", "error": None, "id": 2}, msg)

        # completing the next message should work too
        server.data_received(b' "params": ["Hello Echo"], "id": 3}\r\n')
        self.assertEqual(3, len(server.responses))
        msgstr = server.responses[2].decode("utf-8")
        msg = json.loads(msgstr)
        self.assertEqual({"result": "Hello Echo", "error": None, "id": 3}, msg)
예제 #13
0
 def test_typed_array_with_custom_type_in_add_param(self):
     dummy_func = RpcFunction(dummy_function, 'dummy',
             'Dummy function', 'int', 'Return value')
     try:
         dummy_func.add_param('array<SomeCustomType>', 'a', 'First parameter')
     except:
         self.fail("add_param raised an unexpected exception!")
예제 #14
0
    def test_hash_type_check_in_add_function(self):
        rpc = RpcProcessor()

        echo_hash_func = RpcFunction(echo_hash, 'echo_hash', '', 'Address', '')
        self.assertRaises(ValueError, rpc.add_function, echo_hash_func)

        echo_hash_func = RpcFunction(echo_hash, 'echo_hash', '', 'hash', '')
        echo_hash_func.add_param('Address', 'address', '')
        self.assertRaises(ValueError, rpc.add_function, echo_hash_func)

        rpc = RpcProcessor()

        echo_hash_func = RpcFunction(echo_hash, 'echo_hash', '', 'Address', '')
        address = JsonHashType('Address', '')
        rpc.add_custom_type(address)

        try:
            rpc.add_function(echo_hash_func)
        except ValueError:
            self.fail("add_function raised unexpected exception!")

        rpc = RpcProcessor()

        echo_hash_func = RpcFunction(echo_hash, 'echo_hash', '', 'hash', '')
        echo_hash_func.add_param('Address', 'address', '')
        address = JsonHashType('Address', '')
        rpc.add_custom_type(address)

        try:
            rpc.add_function(echo_hash_func)
        except ValueError:
            self.fail("add_function raised unexpected exception!")
예제 #15
0
 def test_typed_array_in_add_param(self):
     dummy_func = RpcFunction(dummy_function, 'dummy',
             'Dummy function', 'int', 'Return value')
     try:
         dummy_func.add_param('array<int>', 'a', 'Typed array of integers')
     except:
         self.fail("add_param raised an unexpected exception!")
예제 #16
0
    def test_type_checks_enums_in_named_hashes(self):
        rpc = RpcProcessor()

        enum = JsonEnumType('PhoneType', 'Type of a phone number')
        enum.add_value('HOME', 'Home phone')
        enum.add_value('WORK', 'Work phone')
        enum.add_value('MOBILE', 'Mobile phone')
        enum.add_value('FAX', 'FAX number')

        rpc.add_custom_type(enum)

        custom_hash = JsonHashType('CustomHash', 'Dummy named hash for testing')
        custom_hash.add_field('phonetype', 'PhoneType', 'Type of phone number')

        rpc.add_custom_type(custom_hash)

        echo_hash_func = RpcFunction(echo_hash, 'echo_hash', 'Returns what it was given',
                'hash', 'Same value as the first parameter')
        echo_hash_func.add_param('CustomHash', 'custom_hash', 'Some custom hash instance')

        rpc.add_function(echo_hash_func)
        rpc.enable_named_hash_validation()

        reply = rpc.process_request('{"method": "echo_hash", "params": [{"phonetype": "TEST"}], "id": 1}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(reply['error'], {'name': 'TypeError', 'message': "echo_hash: 'TEST' is not a valid value for parameter 'custom_hash.phonetype' of enum type 'PhoneType'"})

        reply = rpc.process_request('{"method": "echo_hash", "params": [{"phonetype": []}], "id": 2}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(reply['error'], {'name': 'TypeError', 'message': "echo_hash: Enum parameter 'custom_hash.phonetype' requires a value of type 'int' or 'string' but type was 'array'"})

        reply = rpc.process_request('{"method": "echo_hash", "params": [{"phonetype": "HOME"}], "id": 3}')
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], {'phonetype': 'HOME'})
예제 #17
0
 def test_custom_type_in_add_param(self):
     dummy_func = RpcFunction(dummy_function, 'dummy',
             'Dummy function', 'int', 'Return value')
     try:
         dummy_func.add_param('ImaginaryCustomType', 'a', 'First parameter')
     except:
         self.fail("add_param raised an unexpected exception!")
예제 #18
0
 def test_typed_array_with_custom_type_in_add_param(self):
     dummy_func = RpcFunction(dummy_function, 'dummy', 'Dummy function',
                              'int', 'Return value')
     try:
         dummy_func.add_param('array<SomeCustomType>', 'a',
                              'First parameter')
     except:
         self.fail("add_param raised an unexpected exception!")
예제 #19
0
    def test_echo(self):
        rpc = RpcProcessor()

        echo_func = RpcFunction(echo, 'echo', 'Returns what it was given',
                'string', 'Same value as the first parameter')
        echo_func.add_param('string', 'message', 'Message to send back')

        rpc.add_function(echo_func)
        reply = rpc.process_request('{"method": "echo", "params": ["Hello Server"], "id": 1}')
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], "Hello Server")
예제 #20
0
    def test_type_checks_enums_in_named_hashes(self):
        rpc = RpcProcessor()

        enum = JsonEnumType('PhoneType', 'Type of a phone number')
        enum.add_value('HOME', 'Home phone')
        enum.add_value('WORK', 'Work phone')
        enum.add_value('MOBILE', 'Mobile phone')
        enum.add_value('FAX', 'FAX number')

        rpc.add_custom_type(enum)

        custom_hash = JsonHashType('CustomHash',
                                   'Dummy named hash for testing')
        custom_hash.add_field('phonetype', 'PhoneType', 'Type of phone number')

        rpc.add_custom_type(custom_hash)

        echo_hash_func = RpcFunction(echo_hash, 'echo_hash',
                                     'Returns what it was given', 'hash',
                                     'Same value as the first parameter')
        echo_hash_func.add_param('CustomHash', 'custom_hash',
                                 'Some custom hash instance')

        rpc.add_function(echo_hash_func)
        rpc.enable_named_hash_validation()

        reply = rpc.process_request(
            '{"method": "echo_hash", "params": [{"phonetype": "TEST"}], "id": 1}'
        )
        self.assertEqual(reply['result'], None)
        self.assertEqual(
            reply['error'], {
                'name':
                'TypeError',
                'message':
                "echo_hash: 'TEST' is not a valid value for parameter 'custom_hash.phonetype' of enum type 'PhoneType'"
            })

        reply = rpc.process_request(
            '{"method": "echo_hash", "params": [{"phonetype": []}], "id": 2}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(
            reply['error'], {
                'name':
                'TypeError',
                'message':
                "echo_hash: Enum parameter 'custom_hash.phonetype' requires a value of type 'int' or 'string' but type was 'array'"
            })

        reply = rpc.process_request(
            '{"method": "echo_hash", "params": [{"phonetype": "HOME"}], "id": 3}'
        )
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], {'phonetype': 'HOME'})
예제 #21
0
    def test_basic_type_checks_for_named_hashes(self):
        rpc = RpcProcessor()

        address_type = JsonHashType('Address', 'Street address')
        address_type.add_field('firstname', 'string', 'First name')
        address_type.add_field('lastname', 'string', 'Last name')
        address_type.add_field('street1', 'string', 'First address line')
        address_type.add_field('zipcode', 'int', 'Zip code')
        address_type.add_field('city', 'string', 'City')

        rpc.add_custom_type(address_type)

        echo_hash_func = RpcFunction(echo_hash, 'echo_hash',
                                     'Returns what it was given', 'hash',
                                     'Same value as the first parameter')
        echo_hash_func.add_param('Address', 'address', 'Address hash')

        rpc.add_function(echo_hash_func)

        reply = rpc.process_request(
            '{"method": "echo_hash", "params": ["String"], "id": 1}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(
            reply['error'], {
                'name':
                'TypeError',
                'message':
                "echo_hash: Named hash parameter 'address' of type 'Address' requires a hash value but got 'string'"
            })

        reply = rpc.process_request(
            '{"method": "echo_hash", "params": [{"firstname": "first", "lastname": "last", "street1": "", "zipcode": 56732, "city": ""}], "id": 2}'
        )
        self.assertEqual(reply['error'], None)
        self.assertEqual(
            reply['result'], {
                'firstname': 'first',
                'lastname': 'last',
                'street1': '',
                'zipcode': 56732,
                'city': '',
            })

        reply = rpc.process_request(
            '{"method": "echo_hash", "params": [{"firstname": "first", "lastname": "test", "street1": "", "zipcode": 56732, "city": "", "number": 42}], "id": 3}'
        )
        self.assertEqual(reply['result'], None)
        self.assertEqual(
            reply['error'], {
                'name':
                'TypeError',
                'message':
                "echo_hash: Named hash parameter 'address' of type 'Address': Unknown field 'number'"
            })
예제 #22
0
    def test_echo(self):
        rpc = RpcProcessor()

        echo_func = RpcFunction(echo, 'echo', 'Returns what it was given',
                                'string', 'Same value as the first parameter')
        echo_func.add_param('string', 'message', 'Message to send back')

        rpc.add_function(echo_func)
        reply = rpc.process_request(
            '{"method": "echo", "params": ["Hello Server"], "id": 1}')
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], "Hello Server")
예제 #23
0
    def test_add(self):
        rpc = RpcProcessor()

        add_func = RpcFunction(add, 'add', 'Returns the sum of the two parameters',
                'int', 'Sum of a and b')
        add_func.add_param('int', 'a', 'First int to add')
        add_func.add_param('int', 'b', 'Second int to add')

        rpc.add_function(add_func)
        reply = rpc.process_request('{"method": "add", "params": [4, 5], "id": 1}')
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], 9)
예제 #24
0
    def test_typed_arrays_with_custom_types(self):
        rpc = RpcProcessor()

        example_type = JsonHashType('Example', 'A named hash')
        example_type.add_field('somestr', 'string', 'Some string')
        example_type.add_field('someint', 'int', 'Some integer')

        func = RpcFunction(echo_array, 'echo_array',
                           'Expects an array of examples and returns it',
                           'array<Example>',
                           'Returns the array passed by the caller')
        func.add_param('array<Example>', 'examples',
                       'An array of integer values')

        rpc.add_custom_type(example_type)
        rpc.add_function(func)

        reply = rpc.process_request(
            '{"method": "echo_array", "params": [[5, 6, 7]], "id": 1}')
        self.assertEqual(
            reply['error'], {
                'name':
                'TypeError',
                'message':
                "echo_array: Named hash parameter 'examples[0]' of type 'Example' requires a hash value but got 'int'"
            })
        self.assertEqual(reply['result'], None)

        reply = rpc.process_request(
            '{"method": "echo_array", "params": [[{"somestr": "str", "someint": 5}, {"somestr": "str", "someint": true}]], "id": 2}'
        )
        self.assertEqual(
            reply['error'], {
                'name':
                'TypeError',
                'message':
                "echo_array: Expected value of type 'int' for parameter 'examples[1].someint' but got value of type 'bool'"
            })
        self.assertEqual(reply['result'], None)

        reply = rpc.process_request(
            '{"method": "echo_array", "params": [[{"somestr": "str1", "someint": 5}, {"somestr": "str2", "someint": 6}]], "id": 3}'
        )
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], [{
            'somestr': 'str1',
            'someint': 5
        }, {
            'somestr': 'str2',
            'someint': 6
        }])
예제 #25
0
    def test_add(self):
        rpc = RpcProcessor()

        add_func = RpcFunction(add, 'add',
                               'Returns the sum of the two parameters', 'int',
                               'Sum of a and b')
        add_func.add_param('int', 'a', 'First int to add')
        add_func.add_param('int', 'b', 'Second int to add')

        rpc.add_function(add_func)
        reply = rpc.process_request(
            '{"method": "add", "params": [4, 5], "id": 1}')
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], 9)
예제 #26
0
    def test_wrong_number_of_params(self):
        rpc = RpcProcessor()

        echo_func = RpcFunction(echo, 'echo', 'Returns what it was given',
                'string', 'Same value as the first parameter')
        echo_func.add_param('string', 'message', 'Message to send back')

        rpc.add_function(echo_func)

        reply = rpc.process_request('{"method": "echo", "params": ["Hello Server", 42], "id": 1}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(reply['error'], {'name': 'ParamError', 'message': 'Expected 1 parameters for \'echo\' but got 2'})

        reply = rpc.process_request('{"method": "echo", "params": [], "id": 2}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(reply['error'], {'name': 'ParamError', 'message': 'Expected 1 parameters for \'echo\' but got 0'})
예제 #27
0
    def test_custom_types_with_typed_array_fields(self):
        rpc = RpcProcessor()

        example_type = JsonHashType('Example', 'A named hash')
        example_type.add_field('somestrs', 'array<string>', 'Some strings')
        example_type.add_field('someints', 'array<int>', 'Some integers')

        func = RpcFunction(echo_hash, 'echo_hash',
                           'Expects an Example hash and returns it', 'Example',
                           'Returns the hash passed by the caller')
        func.add_param('Example', 'examples', 'An example hash')

        rpc.add_custom_type(example_type)
        rpc.add_function(func)

        reply = rpc.process_request(
            '{"method": "echo_hash", "params": [{"somestrs": "", "someints": ""}], "id": 1}'
        )
        self.assertEqual(
            reply['error'], {
                'name':
                'TypeError',
                'message':
                "echo_hash: Expected value of type 'array<string>' for parameter 'examples.somestrs' but got value of type 'string'"
            })
        self.assertEqual(reply['result'], None)

        reply = rpc.process_request(
            '{"method": "echo_hash", "params": [{"somestrs": ["str1", "str2"], "someints": [1, 2, "test", 3]}], "id": 2}'
        )
        self.assertEqual(
            reply['error'], {
                'name':
                'TypeError',
                'message':
                "echo_hash: Expected value of type 'int' for parameter 'examples.someints[2]' but got value of type 'string'"
            })
        self.assertEqual(reply['result'], None)

        reply = rpc.process_request(
            '{"method": "echo_hash", "params": [{"somestrs": ["str1", "str2"], "someints": [1, 2, 3]}], "id": 3}'
        )
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], {
            'somestrs': ['str1', 'str2'],
            'someints': [1, 2, 3]
        })
예제 #28
0
    def test_nested_named_hash_validation(self):
        rpc = RpcProcessor()

        type1_type = JsonHashType('Type1', 'First type in the hierarchy')
        type1_type.add_field('somestr', 'string', 'Some string')
        type1_type.add_field('type2', 'Type2', 'Embedded Type2')

        type2_type = JsonHashType('Type2', 'Second type in the hierarchy')
        type2_type.add_field('someint', 'int', 'Some int')
        type2_type.add_field('type3', 'Type3', 'Embedded Type3')

        type3_type = JsonHashType('Type3', 'Third type in the hierarchy')
        type3_type.add_field('somebool', 'bool', 'Some bool')

        rpc.add_custom_type(type1_type)
        rpc.add_custom_type(type2_type)
        rpc.add_custom_type(type3_type)

        echo_hash_func = RpcFunction(echo_hash, 'echo_hash', 'Returns what it was given',
                'hash', 'Same value as the first parameter')
        echo_hash_func.add_param('Type1', 'value', 'Type1 one Named Hash')

        rpc.add_function(echo_hash_func)

        reply = rpc.process_request('{"method": "echo_hash", "params": [{"somestr": "mystr"}], "id": 1}')
        self.assertEqual(reply['error'], {'message': "echo_hash: Named hash parameter 'value' of type 'Type1': Missing field 'type2'", 'name': 'TypeError'})
        self.assertEqual(reply['result'], None)

        reply = rpc.process_request('{"method": "echo_hash", "params": [{"somestr": "mystr", "type2": {"someint": 5}}], "id": 2}')
        self.assertEqual(reply['error'], {'name': 'TypeError', 'message':
            "echo_hash: Named hash parameter 'value.type2' of type 'Type2': Missing field 'type3'"})
        self.assertEqual(reply['result'], None)

        reply = rpc.process_request('{"method": "echo_hash", "params": [{"somestr": "mystr", "type2": {"someint": 5, "type3": {"somebool": 8}}}], "id": 3}')
        self.assertEqual(reply['error'], {'message': "echo_hash: Expected value of type 'bool' for parameter 'value.type2.type3.somebool' but got value of type 'int'", 'name': 'TypeError'})
        self.assertEqual(reply['result'], None)

        reply = rpc.process_request('{"method": "echo_hash", "params": [{"somestr": "mystr", "type2": {"someint": 5, "type3": {"somebool": true}}}], "id": 4}')
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], {
            'somestr': 'mystr',
            'type2': {
                'someint': 5,
                'type3': {'somebool': True}
            }
        })
예제 #29
0
    def test_json_messages(self):
        rpc = RpcProcessor()

        echo_func = RpcFunction(echo, 'echo', 'Returns what it was given',
                                'string', 'Same value as the first parameter')
        echo_func.add_param('string', 'message', 'Message to send back')

        rpc.add_function(echo_func)
        server = DummyServer(rpc, None)

        # JSON-RPC call with linebreak gets processed immediatelly
        server.data_received(
            b'{"method": "echo", "params": ["Hello Server"], "id": 1}\r\n')
        self.assertEqual(1, len(server.responses))
        msgstr = server.responses[0].decode("utf-8")
        msg = json.loads(msgstr)
        self.assertEqual({
            "result": "Hello Server",
            "error": None,
            "id": 1
        }, msg)

        # if JSON is received in chunks the request must be processed after the linebreak
        server.data_received(b'{"method":')
        server.data_received(b' "echo", "params": ["Hello')
        server.data_received(b' Server"], "id": 2}\r\n{"method": "echo",')
        self.assertEqual(2, len(server.responses))
        msgstr = server.responses[1].decode("utf-8")
        msg = json.loads(msgstr)
        self.assertEqual({
            "result": "Hello Server",
            "error": None,
            "id": 2
        }, msg)

        # completing the next message should work too
        server.data_received(b' "params": ["Hello Echo"], "id": 3}\r\n')
        self.assertEqual(3, len(server.responses))
        msgstr = server.responses[2].decode("utf-8")
        msg = json.loads(msgstr)
        self.assertEqual({"result": "Hello Echo", "error": None, "id": 3}, msg)
예제 #30
0
    def test_typed_arrays_basic(self):
        rpc = RpcProcessor()

        func = RpcFunction(echo_array, 'echo_array', 'Expects an array of ints and returns it',
                'array<int>', 'Returns the array passed by the caller')
        func.add_param('array<int>', 'numbers', 'An array of integer values')

        rpc.add_function(func)

        reply = rpc.process_request('{"method": "echo_array", "params": [[1, 2, 3, 4, 5, 6 ,7, 8, 9]], "id": 1}')
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], [1, 2, 3, 4, 5, 6, 7, 8, 9])

        # test what happens if we send a non-array type
        reply = rpc.process_request('{"method": "echo_array", "params": [5], "id": 2}')
        self.assertEqual(reply['error'], {'message': "echo_array: Expected value of type 'array<int>' for parameter 'numbers' but got value of type 'int'", 'name': 'TypeError'})
        self.assertEqual(reply['result'], None)

        reply = rpc.process_request('{"method": "echo_array", "params": [[1, 2, "invalid string", 9]], "id": 3}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(reply['error'], {'name': 'TypeError', 'message': "echo_array: Expected value of type 'int' for parameter 'numbers[2]' but got value of type 'string'"})
예제 #31
0
    def test_type_checks(self):
        rpc = RpcProcessor()

        echo_func = RpcFunction(echo, 'echo', 'Returns what it was given',
                'string', 'Same value as the first parameter')
        echo_func.add_param('string', 'message', 'Message to send back')

        rpc.add_function(echo_func)

        add_func = RpcFunction(add, 'add', 'Returns the sum of the two parameters',
                'int', 'Sum of a and b')
        add_func.add_param('int', 'a', 'First int to add')
        add_func.add_param('int', 'b', 'Second int to add')

        rpc.add_function(add_func)

        reply = rpc.process_request('{"method": "echo", "params": [42], "id": 1}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(reply['error'], {'name': 'TypeError', 'message':'echo: Expected value of type \'string\' for parameter \'message\' but got value of type \'int\''})

        reply = rpc.process_request('{"method": "echo", "params": [[]], "id": 2}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(reply['error'], {'name': 'TypeError', 'message':'echo: Expected value of type \'string\' for parameter \'message\' but got value of type \'array\''})

        reply = rpc.process_request('{"method": "add", "params": [4, 8.9], "id": 3}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(reply['error'], {'name': 'TypeError', 'message':'add: Expected value of type \'int\' for parameter \'b\' but got value of type \'float\''})

        reply = rpc.process_request('{"method": "add", "params": [4, {"test": 8}], "id": 3}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(reply['error'], {'name': 'TypeError', 'message':'add: Expected value of type \'int\' for parameter \'b\' but got value of type \'hash\''})
예제 #32
0
    def test_type_checks(self):
        rpc = RpcProcessor()

        echo_func = RpcFunction(echo, 'echo', 'Returns what it was given',
                                'string', 'Same value as the first parameter')
        echo_func.add_param('string', 'message', 'Message to send back')

        rpc.add_function(echo_func)

        add_func = RpcFunction(add, 'add',
                               'Returns the sum of the two parameters', 'int',
                               'Sum of a and b')
        add_func.add_param('int', 'a', 'First int to add')
        add_func.add_param('int', 'b', 'Second int to add')

        rpc.add_function(add_func)

        reply = rpc.process_request(
            '{"method": "echo", "params": [42], "id": 1}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(
            reply['error'], {
                'name':
                'TypeError',
                'message':
                'echo: Expected value of type \'string\' for parameter \'message\' but got value of type \'int\''
            })

        reply = rpc.process_request(
            '{"method": "echo", "params": [[]], "id": 2}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(
            reply['error'], {
                'name':
                'TypeError',
                'message':
                'echo: Expected value of type \'string\' for parameter \'message\' but got value of type \'array\''
            })

        reply = rpc.process_request(
            '{"method": "add", "params": [4, 8.9], "id": 3}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(
            reply['error'], {
                'name':
                'TypeError',
                'message':
                'add: Expected value of type \'int\' for parameter \'b\' but got value of type \'float\''
            })

        reply = rpc.process_request(
            '{"method": "add", "params": [4, {"test": 8}], "id": 3}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(
            reply['error'], {
                'name':
                'TypeError',
                'message':
                'add: Expected value of type \'int\' for parameter \'b\' but got value of type \'hash\''
            })
예제 #33
0
    def test_typed_arrays_basic(self):
        rpc = RpcProcessor()

        func = RpcFunction(echo_array, 'echo_array',
                           'Expects an array of ints and returns it',
                           'array<int>',
                           'Returns the array passed by the caller')
        func.add_param('array<int>', 'numbers', 'An array of integer values')

        rpc.add_function(func)

        reply = rpc.process_request(
            '{"method": "echo_array", "params": [[1, 2, 3, 4, 5, 6 ,7, 8, 9]], "id": 1}'
        )
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], [1, 2, 3, 4, 5, 6, 7, 8, 9])

        # test what happens if we send a non-array type
        reply = rpc.process_request(
            '{"method": "echo_array", "params": [5], "id": 2}')
        self.assertEqual(
            reply['error'], {
                'message':
                "echo_array: Expected value of type 'array<int>' for parameter 'numbers' but got value of type 'int'",
                'name': 'TypeError'
            })
        self.assertEqual(reply['result'], None)

        reply = rpc.process_request(
            '{"method": "echo_array", "params": [[1, 2, "invalid string", 9]], "id": 3}'
        )
        self.assertEqual(reply['result'], None)
        self.assertEqual(
            reply['error'], {
                'name':
                'TypeError',
                'message':
                "echo_array: Expected value of type 'int' for parameter 'numbers[2]' but got value of type 'string'"
            })
예제 #34
0
    def test_type_checks_for_enums(self):
        rpc = RpcProcessor()

        enum = JsonEnumType('PhoneType', 'Type of a phone number')
        enum.add_value('HOME', 'Home phone')
        enum.add_value('WORK', 'Work phone')
        enum.add_value('MOBILE', 'Mobile phone')
        enum.add_value('FAX', 'FAX number')

        rpc.add_custom_type(enum)

        echo_enum_func = RpcFunction(echo_enum, 'echo_enum', 'Returns what it was given',
                'PhoneType', 'Same value as the first parameter')
        echo_enum_func.add_param('PhoneType', 'type', 'Type of phone number')

        rpc.add_function(echo_enum_func)

        reply = rpc.process_request('{"method": "echo_enum", "params": [-1], "id": 1}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(reply['error'], {'name': 'TypeError',
            'message':"echo_enum: '-1' is not a valid value for parameter 'type' of enum type 'PhoneType'"})

        reply = rpc.process_request('{"method": "echo_enum", "params": [4], "id": 2}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(reply['error'], {'name': 'TypeError',
            'message':"echo_enum: '4' is not a valid value for parameter 'type' of enum type 'PhoneType'"})

        reply = rpc.process_request('{"method": "echo_enum", "params": ["BLABLA"], "id": 3}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(reply['error'], {'name': 'TypeError',
            'message':"echo_enum: 'BLABLA' is not a valid value for parameter 'type' of enum type 'PhoneType'"})

        reply = rpc.process_request('{"method": "echo_enum", "params": [3], "id": 4}')
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], 3)

        reply = rpc.process_request('{"method": "echo_enum", "params": ["MOBILE"], "id": 5}')
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], 'MOBILE')
예제 #35
0
    def test_basic_type_checks_for_named_hashes(self):
        rpc = RpcProcessor()

        address_type = JsonHashType('Address', 'Street address')
        address_type.add_field('firstname', 'string', 'First name')
        address_type.add_field('lastname', 'string', 'Last name')
        address_type.add_field('street1', 'string', 'First address line')
        address_type.add_field('zipcode', 'int', 'Zip code')
        address_type.add_field('city', 'string', 'City')

        rpc.add_custom_type(address_type)

        echo_hash_func = RpcFunction(echo_hash, 'echo_hash', 'Returns what it was given',
                'hash', 'Same value as the first parameter')
        echo_hash_func.add_param('Address', 'address', 'Address hash')

        rpc.add_function(echo_hash_func)

        reply = rpc.process_request('{"method": "echo_hash", "params": ["String"], "id": 1}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(reply['error'], {'name': 'TypeError', 'message':
            "echo_hash: Named hash parameter 'address' of type 'Address' requires a hash value but got 'string'"})

        reply = rpc.process_request('{"method": "echo_hash", "params": [{"firstname": "first", "lastname": "last", "street1": "", "zipcode": 56732, "city": ""}], "id": 2}')
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], {
            'firstname': 'first',
            'lastname': 'last',
            'street1': '',
            'zipcode': 56732,
            'city': '',
        })

        reply = rpc.process_request('{"method": "echo_hash", "params": [{"firstname": "first", "lastname": "test", "street1": "", "zipcode": 56732, "city": "", "number": 42}], "id": 3}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(reply['error'], {'name': 'TypeError',
            'message': "echo_hash: Named hash parameter 'address' of type 'Address': Unknown field 'number'"
        })
예제 #36
0
    def test_invalid_json(self):
        rpc = RpcProcessor()

        echo_func = RpcFunction(echo, 'echo', 'Returns what it was given',
                                'string', 'Same value as the first parameter')
        echo_func.add_param('string', 'message', 'Message to send back')

        rpc.add_function(echo_func)
        server = DummyServer(rpc, None)

        # data with linebreak gets processed immediatelly
        server.data_received(b"data\r\n")
        self.assertEqual(1, len(server.responses))

        # without linebreak it doesn't get processed
        server.data_received(b"data")
        server.data_received(b"data")
        server.data_received(b"data")
        self.assertEqual(1, len(server.responses))

        # once the linebreak arrives data gets processed again
        server.data_received(b"\r\n")
        self.assertEqual(2, len(server.responses))
예제 #37
0
    def test_invalid_json(self):
        rpc = RpcProcessor()

        echo_func = RpcFunction(echo, 'echo', 'Returns what it was given',
                'string', 'Same value as the first parameter')
        echo_func.add_param('string', 'message', 'Message to send back')

        rpc.add_function(echo_func)
        server = DummyServer(rpc, None)

        # data with linebreak gets processed immediatelly
        server.data_received(b"data\r\n")
        self.assertEqual(1, len(server.responses))

        # without linebreak it doesn't get processed
        server.data_received(b"data")
        server.data_received(b"data")
        server.data_received(b"data")
        self.assertEqual(1, len(server.responses))

        # once the linebreak arrives data gets processed again
        server.data_received(b"\r\n")
        self.assertEqual(2, len(server.responses))
예제 #38
0
    def test_type_checks_for_fields_of_named_hashes(self):
        rpc = RpcProcessor()

        custom_type = JsonHashType('CustomHash', 'Dummy named hash for testing')
        custom_type.add_field('boolfield', 'bool', 'Some bool')
        custom_type.add_field('stringfield', 'string', 'Some string')
        custom_type.add_field('intfield', 'int', 'Some integer')
        custom_type.add_field('floatfield', 'float', 'Some float')
        custom_type.add_field('arrayfield', 'array', 'City')
        custom_type.add_field('hashfield', 'hash', 'City')

        rpc.add_custom_type(custom_type)
        rpc.enable_named_hash_validation()

        echo_hash_func = RpcFunction(echo_hash, 'echo_hash', 'Returns what it was given',
                'hash', 'Same value as the first parameter')
        echo_hash_func.add_param('CustomHash', 'custom_hash', 'Some custom hash instance')

        rpc.add_function(echo_hash_func)

        # Call with an empty hash should get us an error mentioning the first missing field
        reply = rpc.process_request('{"method": "echo_hash", "params": [{}], "id": 1}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(reply['error'], {'name': 'TypeError',
            'message': "echo_hash: Named hash parameter 'custom_hash' of type 'CustomHash': Missing field 'boolfield'"
        })

        # Call with an invalid field should return the corresponding error
        reply = rpc.process_request('{"method": "echo_hash", "params": [{"boolfield": true, "stringfield": 5, "intfield": 5, "floatfield": 5.5, "arrayfield": [], "hashfield": {}}], "id": 2}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(reply['error'], {'name': 'TypeError', 'message': "echo_hash: Expected value of type 'string' for parameter 'custom_hash.stringfield' but got value of type 'int'"})

        # Call with a valid hash should return the same hash without error
        reply = rpc.process_request('{"method": "echo_hash", "params": [{"boolfield": true, "stringfield": "test", "intfield": 5, "floatfield": 5.5, "arrayfield": [], "hashfield": {}}], "id": 3}')
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], {"boolfield": True, "stringfield": "test", "intfield": 5, "floatfield": 5.5, "arrayfield": [], "hashfield": {}})
예제 #39
0
    def test_describe_functions(self):
        rpc = RpcProcessor()

        echo_func = RpcFunction(echo, 'echo', 'Returns what it was given',
                'string', 'Same value as the first parameter')
        echo_func.add_param('string', 'message', 'Message to send back')

        rpc.add_function(echo_func)
        reply = rpc.process_request('{"method": "__describe_functions", "params": [], "id": 1}')

        expected = [{
                    'name': 'echo',
                    'description': 'Returns what it was given',
                    'result_type': 'string',
                    'result_desc': 'Same value as the first parameter',
                    'params': [{'name': 'message', 'type': 'string',
                        'description': 'Message to send back'}]
        }]
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], expected)

        add_func = RpcFunction(add, 'add', 'Returns the sum of the two parameters',
                'int', 'Sum of a and b')
        add_func.add_param('int', 'a', 'First int to add')
        add_func.add_param('int', 'b', 'Second int to add')

        rpc.add_function(add_func)

        reply = rpc.process_request('{"method": "__describe_functions", "params": [], "id": 2}')

        expected = [
                {
                    'name': 'echo',
                    'description': 'Returns what it was given',
                    'result_type': 'string',
                    'result_desc': 'Same value as the first parameter',
                    'params': [{'name': 'message', 'type': 'string',
                        'description': 'Message to send back'}]
                },
                {
                    'name': 'add',
                    'description': 'Returns the sum of the two parameters',
                    'result_type': 'int',
                    'result_desc': 'Sum of a and b',
                    'params': [
                        {'name': 'a', 'type': 'int', 'description': 'First int to add'},
                        {'name': 'b', 'type': 'int', 'description': 'Second int to add'}
                    ]
                }
        ]

        self.assertEqual(reply['result'], expected)
예제 #40
0
        conn.close()
        return True

    return d


# Create service object
jsonrpc = RpcProcessor()
jsonrpc.set_description("JSON Store Service",
        "JSON-RPC service for storing JSON objects in a PostgreSQL database",
        reflectrpc.version)

# Register functions
get_object_func = RpcFunction(get_object, 'get_object', 'Gets a JSON object by its UUID',
        'hash', 'JSON object')
get_object_func.add_param('string', 'uuid', 'UUID of the JSON object to retrieve')
get_object_func.require_rpcinfo()
jsonrpc.add_function(get_object_func)

get_object_by_name_func = RpcFunction(get_object_by_name, 'get_object_by_name', 'Gets a JSON object by its name', 'hash', 'JSON object')
get_object_by_name_func.add_param('string', 'name', 'Name of the JSON object to retrieve')
get_object_by_name_func.require_rpcinfo()
jsonrpc.add_function(get_object_by_name_func)

find_objects_func = RpcFunction(find_objects, 'find_objects', 'Finds JSON objects which match a filter', 'array<hash>', 'List of matching JSON object')
find_objects_func.add_param('string', 'filter', 'Filter for the JSON objects to retrieve (e.g. "field1 = \'test\' AND score > 3")')
find_objects_func.require_rpcinfo()
jsonrpc.add_function(find_objects_func)

insert_object_func = RpcFunction(insert_object, 'insert_object', 'Inserts a new JSON object',
        'bool', 'true on success, false on failure')
예제 #41
0
    def test_valid_types_in_add_param(self):
        dummy_func = RpcFunction(dummy_function, 'dummy',
                'Dummy function', 'int', 'Return value')

        try:
            dummy_func.add_param('int', 'a', 'First parameter')
        except:
            self.fail("add_param raised unexpected exception!")

        try:
            dummy_func.add_param('bool', 'a', 'First parameter')
        except:
            self.fail("add_param raised unexpected exception!")

        try:
            dummy_func.add_param('float', 'a', 'First parameter')
        except:
            self.fail("add_param raised unexpected exception!")

        try:
            dummy_func.add_param('string', 'a', 'First parameter')
        except:
            self.fail("add_param raised unexpected exception!")

        try:
            dummy_func.add_param('array', 'a', 'First parameter')
        except:
            self.fail("add_param raised unexpected exception!")

        try:
            dummy_func.add_param('hash', 'a', 'First parameter')
        except:
            self.fail("add_param raised unexpected exception!")

        try:
            dummy_func.add_param('base64', 'a', 'First parameter')
        except:
            self.fail("add_param raised unexpected exception!")
예제 #42
0
    def test_valid_types_in_add_param(self):
        dummy_func = RpcFunction(dummy_function, 'dummy', 'Dummy function',
                                 'int', 'Return value')

        try:
            dummy_func.add_param('int', 'a', 'First parameter')
        except:
            self.fail("add_param raised unexpected exception!")

        try:
            dummy_func.add_param('bool', 'a', 'First parameter')
        except:
            self.fail("add_param raised unexpected exception!")

        try:
            dummy_func.add_param('float', 'a', 'First parameter')
        except:
            self.fail("add_param raised unexpected exception!")

        try:
            dummy_func.add_param('string', 'a', 'First parameter')
        except:
            self.fail("add_param raised unexpected exception!")

        try:
            dummy_func.add_param('array', 'a', 'First parameter')
        except:
            self.fail("add_param raised unexpected exception!")

        try:
            dummy_func.add_param('hash', 'a', 'First parameter')
        except:
            self.fail("add_param raised unexpected exception!")

        try:
            dummy_func.add_param('base64', 'a', 'First parameter')
        except:
            self.fail("add_param raised unexpected exception!")
예제 #43
0
    def test_type_checks_for_fields_of_named_hashes(self):
        rpc = RpcProcessor()

        custom_type = JsonHashType('CustomHash',
                                   'Dummy named hash for testing')
        custom_type.add_field('boolfield', 'bool', 'Some bool')
        custom_type.add_field('stringfield', 'string', 'Some string')
        custom_type.add_field('intfield', 'int', 'Some integer')
        custom_type.add_field('floatfield', 'float', 'Some float')
        custom_type.add_field('arrayfield', 'array', 'City')
        custom_type.add_field('hashfield', 'hash', 'City')

        rpc.add_custom_type(custom_type)
        rpc.enable_named_hash_validation()

        echo_hash_func = RpcFunction(echo_hash, 'echo_hash',
                                     'Returns what it was given', 'hash',
                                     'Same value as the first parameter')
        echo_hash_func.add_param('CustomHash', 'custom_hash',
                                 'Some custom hash instance')

        rpc.add_function(echo_hash_func)

        # Call with an empty hash should get us an error mentioning the first missing field
        reply = rpc.process_request(
            '{"method": "echo_hash", "params": [{}], "id": 1}')
        self.assertEqual(reply['result'], None)
        self.assertEqual(
            reply['error'], {
                'name':
                'TypeError',
                'message':
                "echo_hash: Named hash parameter 'custom_hash' of type 'CustomHash': Missing field 'boolfield'"
            })

        # Call with an invalid field should return the corresponding error
        reply = rpc.process_request(
            '{"method": "echo_hash", "params": [{"boolfield": true, "stringfield": 5, "intfield": 5, "floatfield": 5.5, "arrayfield": [], "hashfield": {}}], "id": 2}'
        )
        self.assertEqual(reply['result'], None)
        self.assertEqual(
            reply['error'], {
                'name':
                'TypeError',
                'message':
                "echo_hash: Expected value of type 'string' for parameter 'custom_hash.stringfield' but got value of type 'int'"
            })

        # Call with a valid hash should return the same hash without error
        reply = rpc.process_request(
            '{"method": "echo_hash", "params": [{"boolfield": true, "stringfield": "test", "intfield": 5, "floatfield": 5.5, "arrayfield": [], "hashfield": {}}], "id": 3}'
        )
        self.assertEqual(reply['error'], None)
        self.assertEqual(
            reply['result'], {
                "boolfield": True,
                "stringfield": "test",
                "intfield": 5,
                "floatfield": 5.5,
                "arrayfield": [],
                "hashfield": {}
            })
예제 #44
0
    return d


# Create service object
jsonrpc = RpcProcessor()
jsonrpc.set_description(
    "JSON Store Service",
    "JSON-RPC service for storing JSON objects in a PostgreSQL database",
    reflectrpc.version)

# Register functions
get_object_func = RpcFunction(get_object, 'get_object',
                              'Gets a JSON object by its UUID', 'hash',
                              'JSON object')
get_object_func.add_param('string', 'uuid',
                          'UUID of the JSON object to retrieve')
get_object_func.require_rpcinfo()
jsonrpc.add_function(get_object_func)

get_object_by_name_func = RpcFunction(get_object_by_name, 'get_object_by_name',
                                      'Gets a JSON object by its name', 'hash',
                                      'JSON object')
get_object_by_name_func.add_param('string', 'name',
                                  'Name of the JSON object to retrieve')
get_object_by_name_func.require_rpcinfo()
jsonrpc.add_function(get_object_by_name_func)

find_objects_func = RpcFunction(find_objects, 'find_objects',
                                'Finds JSON objects which match a filter',
                                'array<hash>', 'List of matching JSON object')
find_objects_func.add_param(
예제 #45
0
    def test_nested_named_hash_validation(self):
        rpc = RpcProcessor()

        type1_type = JsonHashType('Type1', 'First type in the hierarchy')
        type1_type.add_field('somestr', 'string', 'Some string')
        type1_type.add_field('type2', 'Type2', 'Embedded Type2')

        type2_type = JsonHashType('Type2', 'Second type in the hierarchy')
        type2_type.add_field('someint', 'int', 'Some int')
        type2_type.add_field('type3', 'Type3', 'Embedded Type3')

        type3_type = JsonHashType('Type3', 'Third type in the hierarchy')
        type3_type.add_field('somebool', 'bool', 'Some bool')

        rpc.add_custom_type(type1_type)
        rpc.add_custom_type(type2_type)
        rpc.add_custom_type(type3_type)

        echo_hash_func = RpcFunction(echo_hash, 'echo_hash',
                                     'Returns what it was given', 'hash',
                                     'Same value as the first parameter')
        echo_hash_func.add_param('Type1', 'value', 'Type1 one Named Hash')

        rpc.add_function(echo_hash_func)

        reply = rpc.process_request(
            '{"method": "echo_hash", "params": [{"somestr": "mystr"}], "id": 1}'
        )
        self.assertEqual(
            reply['error'], {
                'message':
                "echo_hash: Named hash parameter 'value' of type 'Type1': Missing field 'type2'",
                'name': 'TypeError'
            })
        self.assertEqual(reply['result'], None)

        reply = rpc.process_request(
            '{"method": "echo_hash", "params": [{"somestr": "mystr", "type2": {"someint": 5}}], "id": 2}'
        )
        self.assertEqual(
            reply['error'], {
                'name':
                'TypeError',
                'message':
                "echo_hash: Named hash parameter 'value.type2' of type 'Type2': Missing field 'type3'"
            })
        self.assertEqual(reply['result'], None)

        reply = rpc.process_request(
            '{"method": "echo_hash", "params": [{"somestr": "mystr", "type2": {"someint": 5, "type3": {"somebool": 8}}}], "id": 3}'
        )
        self.assertEqual(
            reply['error'], {
                'message':
                "echo_hash: Expected value of type 'bool' for parameter 'value.type2.type3.somebool' but got value of type 'int'",
                'name': 'TypeError'
            })
        self.assertEqual(reply['result'], None)

        reply = rpc.process_request(
            '{"method": "echo_hash", "params": [{"somestr": "mystr", "type2": {"someint": 5, "type3": {"somebool": true}}}], "id": 4}'
        )
        self.assertEqual(reply['error'], None)
        self.assertEqual(
            reply['result'], {
                'somestr': 'mystr',
                'type2': {
                    'someint': 5,
                    'type3': {
                        'somebool': True
                    }
                }
            })
예제 #46
0
    def test_describe_functions(self):
        rpc = RpcProcessor()

        echo_func = RpcFunction(echo, 'echo', 'Returns what it was given',
                                'string', 'Same value as the first parameter')
        echo_func.add_param('string', 'message', 'Message to send back')

        rpc.add_function(echo_func)
        reply = rpc.process_request(
            '{"method": "__describe_functions", "params": [], "id": 1}')

        expected = [{
            'name':
            'echo',
            'description':
            'Returns what it was given',
            'result_type':
            'string',
            'result_desc':
            'Same value as the first parameter',
            'params': [{
                'name': 'message',
                'type': 'string',
                'description': 'Message to send back'
            }]
        }]
        self.assertEqual(reply['error'], None)
        self.assertEqual(reply['result'], expected)

        add_func = RpcFunction(add, 'add',
                               'Returns the sum of the two parameters', 'int',
                               'Sum of a and b')
        add_func.add_param('int', 'a', 'First int to add')
        add_func.add_param('int', 'b', 'Second int to add')

        rpc.add_function(add_func)

        reply = rpc.process_request(
            '{"method": "__describe_functions", "params": [], "id": 2}')

        expected = [{
            'name':
            'echo',
            'description':
            'Returns what it was given',
            'result_type':
            'string',
            'result_desc':
            'Same value as the first parameter',
            'params': [{
                'name': 'message',
                'type': 'string',
                'description': 'Message to send back'
            }]
        }, {
            'name':
            'add',
            'description':
            'Returns the sum of the two parameters',
            'result_type':
            'int',
            'result_desc':
            'Sum of a and b',
            'params': [{
                'name': 'a',
                'type': 'int',
                'description': 'First int to add'
            }, {
                'name': 'b',
                'type': 'int',
                'description': 'Second int to add'
            }]
        }]

        self.assertEqual(reply['result'], expected)