# Path: nanoservice/reqrep.py
# class Responder(Endpoint, Process):
#     """ A service which responds to requests """
# 
#     # pylint: disable=too-many-arguments
#     # pylint: disable=no-member
#     def __init__(self, address, encoder=None, authenticator=None,
#                  socket=None, bind=True, timeouts=(None, None)):
# 
#         # Defaults
#         socket = socket or nanomsg.Socket(nanomsg.REP)
#         encoder = encoder or MsgPackEncoder()
# 
#         super(Responder, self).__init__(
#             socket, address, bind, encoder, authenticator, timeouts)
# 
#         self.methods = {}
#         self.descriptions = {}
# 
#     def execute(self, method, args, ref):
#         """ Execute the method with args """
# 
#         response = {'result': None, 'error': None, 'ref': ref}
#         fun = self.methods.get(method)
#         if not fun:
#             response['error'] = 'Method `{}` not found'.format(method)
#         else:
#             try:
#                 response['result'] = fun(*args)
#             except Exception as exception:
#                 logging.error(exception, exc_info=1)
#                 response['error'] = str(exception)
#         return response
# 
#     def register(self, name, fun, description=None):
#         """ Register function on this service """
#         self.methods[name] = fun
#         self.descriptions[name] = description
# 
#     @classmethod
#     def parse(cls, payload):
#         """ Parse client request """
#         try:
#             method, args, ref = payload
#         except Exception as exception:
#             raise RequestParseError(exception)
#         else:
#             return method, args, ref
# 
#     # pylint: disable=logging-format-interpolation
#     def process(self):
#         """ Receive data from socket and process request """
# 
#         response = None
# 
#         try:
#             payload = self.receive()
#             method, args, ref = self.parse(payload)
#             response = self.execute(method, args, ref)
# 
#         except AuthenticateError as exception:
#             logging.error(
#                 'Service error while authenticating request: {}'
#                 .format(exception), exc_info=1)
# 
#         except AuthenticatorInvalidSignature as exception:
#             logging.error(
#                 'Service error while authenticating request: {}'
#                 .format(exception), exc_info=1)
# 
#         except DecodeError as exception:
#             logging.error(
#                 'Service error while decoding request: {}'
#                 .format(exception), exc_info=1)
# 
#         except RequestParseError as exception:
#             logging.error(
#                 'Service error while parsing request: {}'
#                 .format(exception), exc_info=1)
# 
#         else:
#             logging.debug('Service received payload: {}'.format(payload))
# 
#         if response:
#             self.send(response)
#         else:
#             self.send('')
# 
# Path: nanoservice/reqrep.py
# class Requester(Endpoint):
#     """ A requester client """
# 
#     # pylint: disable=too-many-arguments
#     # pylint: disable=no-member
#     def __init__(self, address, encoder=None, authenticator=None,
#                  socket=None, bind=False, timeouts=(None, None)):
# 
#         # Defaults
#         socket = socket or nanomsg.Socket(nanomsg.REQ)
#         encoder = encoder or MsgPackEncoder()
# 
#         super(Requester, self).__init__(
#             socket, address, bind, encoder, authenticator, timeouts)
# 
#     @classmethod
#     def build_payload(cls, method, args):
#         """ Build the payload to be sent to a `Responder` """
#         ref = str(uuid.uuid4())
#         return (method, args, ref)
# 
#     # pylint: disable=logging-format-interpolation
#     def call(self, method, *args):
#         """ Make a call to a `Responder` and return the result """
# 
#         payload = self.build_payload(method, args)
#         logging.debug('* Client will send payload: {}'.format(payload))
#         self.send(payload)
# 
#         res = self.receive()
#         assert payload[2] == res['ref']
#         return res['result'], res['error']


import unittest
from nanoservice import Responder
from nanoservice import Requester
    def test_build_payload(self):
        payload = self.client.build_payload('echo', 'My Name')
        method, args, ref = payload
        self.assertTrue(method == 'echo')
        self.assertTrue(len(payload) == 3)

    def test_encoder(self):
        data = {'name': 'Joe Doe'}
        encoded = self.client.encode(data)
        decoded = self.client.decode(encoded)
        self.assertEqual(data, decoded)

    def test_call_wo_receive(self):
        # Requester side ops
        method, args = 'echo', 'hello world'
        payload = self.client.build_payload(method, args)
        self.client.socket.send(self.client.encode(payload))
        # Responder side ops
        method, args, ref = self.service.receive()
        self.assertEqual(method, 'echo')
        self.assertEqual(args, 'hello world')
        self.assertEqual(ref, payload[2])

    def test_basic_socket_operation(self):
        msg = 'abc'
        self.client.socket.send(msg)
        res = self.service.socket.recv().decode('utf-8')
        self.assertEqual(msg, res)

    def test_timeout(self):

# Path: nanoservice/reqrep.py
# class Responder(Endpoint, Process):
#     """ A service which responds to requests """
# 
#     # pylint: disable=too-many-arguments
#     # pylint: disable=no-member
#     def __init__(self, address, encoder=None, authenticator=None,
#                  socket=None, bind=True, timeouts=(None, None)):
# 
#         # Defaults
#         socket = socket or nanomsg.Socket(nanomsg.REP)
#         encoder = encoder or MsgPackEncoder()
# 
#         super(Responder, self).__init__(
#             socket, address, bind, encoder, authenticator, timeouts)
# 
#         self.methods = {}
#         self.descriptions = {}
# 
#     def execute(self, method, args, ref):
#         """ Execute the method with args """
# 
#         response = {'result': None, 'error': None, 'ref': ref}
#         fun = self.methods.get(method)
#         if not fun:
#             response['error'] = 'Method `{}` not found'.format(method)
#         else:
#             try:
#                 response['result'] = fun(*args)
#             except Exception as exception:
#                 logging.error(exception, exc_info=1)
#                 response['error'] = str(exception)
#         return response
# 
#     def register(self, name, fun, description=None):
#         """ Register function on this service """
#         self.methods[name] = fun
#         self.descriptions[name] = description
# 
#     @classmethod
#     def parse(cls, payload):
#         """ Parse client request """
#         try:
#             method, args, ref = payload
#         except Exception as exception:
#             raise RequestParseError(exception)
#         else:
#             return method, args, ref
# 
#     # pylint: disable=logging-format-interpolation
#     def process(self):
#         """ Receive data from socket and process request """
# 
#         response = None
# 
#         try:
#             payload = self.receive()
#             method, args, ref = self.parse(payload)
#             response = self.execute(method, args, ref)
# 
#         except AuthenticateError as exception:
#             logging.error(
#                 'Service error while authenticating request: {}'
#                 .format(exception), exc_info=1)
# 
#         except AuthenticatorInvalidSignature as exception:
#             logging.error(
#                 'Service error while authenticating request: {}'
#                 .format(exception), exc_info=1)
# 
#         except DecodeError as exception:
#             logging.error(
#                 'Service error while decoding request: {}'
#                 .format(exception), exc_info=1)
# 
#         except RequestParseError as exception:
#             logging.error(
#                 'Service error while parsing request: {}'
#                 .format(exception), exc_info=1)
# 
#         else:
#             logging.debug('Service received payload: {}'.format(payload))
# 
#         if response:
#             self.send(response)
#         else:
#             self.send('')
# 
# Path: nanoservice/reqrep.py
# class Requester(Endpoint):
#     """ A requester client """
# 
#     # pylint: disable=too-many-arguments
#     # pylint: disable=no-member
#     def __init__(self, address, encoder=None, authenticator=None,
#                  socket=None, bind=False, timeouts=(None, None)):
# 
#         # Defaults
#         socket = socket or nanomsg.Socket(nanomsg.REQ)
#         encoder = encoder or MsgPackEncoder()
# 
#         super(Requester, self).__init__(
#             socket, address, bind, encoder, authenticator, timeouts)
# 
#     @classmethod
#     def build_payload(cls, method, args):
#         """ Build the payload to be sent to a `Responder` """
#         ref = str(uuid.uuid4())
#         return (method, args, ref)
# 
#     # pylint: disable=logging-format-interpolation
#     def call(self, method, *args):
#         """ Make a call to a `Responder` and return the result """
# 
#         payload = self.build_payload(method, args)
#         logging.debug('* Client will send payload: {}'.format(payload))
#         self.send(payload)
# 
#         res = self.receive()
#         assert payload[2] == res['ref']
#         return res['result'], res['error']


# Path: test/test_base_client.py
import unittest
from nanoservice import Responder
from nanoservice import Requester

    def test_build_payload(self):
        payload = self.client.build_payload('echo', 'My Name')
        method, args, ref = payload
        self.assertTrue(method == 'echo')
        self.assertTrue(len(payload) == 3)

    def test_encoder(self):
        data = {'name': 'Joe Doe'}
        encoded = self.client.encode(data)
        decoded = self.client.decode(encoded)
        self.assertEqual(data, decoded)

    def test_call_wo_receive(self):
        # Requester side ops
        method, args = 'echo', 'hello world'
        payload = self.client.build_payload(method, args)
        self.client.socket.send(self.client.encode(payload))
        # Responder side ops
        method, args, ref = self.service.receive()
        self.assertEqual(method, 'echo')
        self.assertEqual(args, 'hello world')
        self.assertEqual(ref, payload[2])

    def test_basic_socket_operation(self):
        msg = 'abc'
        self.client.socket.send(msg)
        res = self.service.socket.recv().decode('utf-8')
        self.assertEqual(msg, res)

    def test_timeout(self):

        c = Requester('inproc://timeout', timeouts=(1, 1))