# 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: nanoservice/error.py
# class NanoServiceError(Exception):
# class ServiceError(NanoServiceError):
# class ClientError(NanoServiceError):
# class ConfigError(NanoServiceError):
# class AuthenticatorInvalidSignature(NanoServiceError):
# class RequestParseError(NanoServiceError):
# class PublisherError(NanoServiceError):
# class SubscriberError(NameError):
# class DecodeError(ServiceError):
# class EncodeError(ServiceError):
# class AuthenticateError(ServiceError):
# class EndpointError(ServiceError):
# 
# Path: nanoservice/crypto.py
# class Authenticator(object):
#     def __init__(self, secret, digestmod=None):
#     def sign(self, encoded):
#     def signed(self, encoded):
#     def unsigned(self, encoded):
#     def split(self, encoded):
#     def auth(self, encoded):


import unittest
from nanoservice import Responder
from nanoservice import Requester
from nanoservice import error
from nanoservice import crypto
        got = self.service.verify(payload)
        self.assertEqual(got, payload)

    # Test error throwing

    def test_payload_decode_error(self):
        self.client.socket.send('"abc')
        self.assertRaises(error.DecodeError, self.service.receive)

    def test_payload_parse_error(self):
        for payload in [[1, 2], '', None]:
            self.assertRaises(
                error.RequestParseError, self.service.parse, payload)

    def test_payload_authenticate_error(self):
        payload = 'abc'
        auth = crypto.Authenticator('my secret')
        auth.unsigned = None  # Overwrite method to force error

        self.service.authenticator = auth
        self.client.authenticator = auth

        payload = self.client.encode(payload)
        payload = auth.signed(payload)
        self.client.socket.send(payload)
        self.assertRaises(
            error.AuthenticateError, self.service.receive)

    def test_payload_authenticator_invalid_signature(self):
        payload = 'abc'

# 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: nanoservice/error.py
# class NanoServiceError(Exception):
# class ServiceError(NanoServiceError):
# class ClientError(NanoServiceError):
# class ConfigError(NanoServiceError):
# class AuthenticatorInvalidSignature(NanoServiceError):
# class RequestParseError(NanoServiceError):
# class PublisherError(NanoServiceError):
# class SubscriberError(NameError):
# class DecodeError(ServiceError):
# class EncodeError(ServiceError):
# class AuthenticateError(ServiceError):
# class EndpointError(ServiceError):
# 
# Path: nanoservice/crypto.py
# class Authenticator(object):
#     def __init__(self, secret, digestmod=None):
#     def sign(self, encoded):
#     def signed(self, encoded):
#     def unsigned(self, encoded):
#     def split(self, encoded):
#     def auth(self, encoded):


# Path: test/test_base_service.py
import unittest
from nanoservice import Responder
from nanoservice import Requester
from nanoservice import error
from nanoservice import crypto

        got = self.service.verify(payload)
        self.assertEqual(got, payload)

    # Test error throwing

    def test_payload_decode_error(self):
        self.client.socket.send('"abc')
        self.assertRaises(error.DecodeError, self.service.receive)

    def test_payload_parse_error(self):
        for payload in [[1, 2], '', None]:
            self.assertRaises(
                error.RequestParseError, self.service.parse, payload)

    def test_payload_authenticate_error(self):
        payload = 'abc'
        auth = crypto.Authenticator('my secret')
        auth.unsigned = None  # Overwrite method to force error

        self.service.authenticator = auth
        self.client.authenticator = auth

        payload = self.client.encode(payload)
        payload = auth.signed(payload)
        self.client.socket.send(payload)
        self.assertRaises(
            error.AuthenticateError, self.service.receive)

    def test_payload_authenticator_invalid_signature(self):
        payload = 'abc'

        auth = crypto.Authenticator('my secret')