class LoggingTestServer(object):
    """
    Class that starts an odin HTTPServer instance and allows its log output to be checked
    via the pytest capture log mechanism.
    """

    def __init__(self, caplog):
        """Initialise the logging test server."""
        self.http_server = HttpServer(adapters=[])
        self.request_summary = 'request'
        self.request_time = 1234
        self.caplog = caplog

    def do_log_request(self, http_status, level):
        """
        Generate a mock request handler and verify that the logger generates the 
        appropriate message.
        """
        handler = MockHandler(http_status, self.request_summary, self.request_time)
        self.http_server.log_request(handler)

        msg_seen = False
        for record in self.caplog.records:
            if record.levelno == level and record.getMessage() == '{:d} {:s} {:.2f}ms'.format(
                    http_status, self.request_summary, self.request_time*1000.0):
                msg_seen = True
        return msg_seen
Exemple #2
0
def main(argv=None):
    """Run ODIN server.

    This function is the main entry point for the ODIN server. It parses configuration
    options from the command line and any files, resolves adapters and launches the main
    API server before entering the IO processing loop.

    :param argv: argument list to pass to parser if called programatically
    """
    config = ConfigParser()

    # Define configuration options and add to the configuration parser
    config.define('http_addr', default='0.0.0.0', option_help='Set HTTP server address')
    config.define('http_port', default=8888, option_help='Set HTTP server port')
    config.define('debug_mode', default=False, option_help='Enable tornado debug mode')
    config.define('access_logging', default=None, option_help="Set the tornado access log level",
                  metavar="debug|info|warning|error|none")
    config.define('static_path', default='./static', option_help='Set path for static file content')

    # Parse configuration options and any configuration file specified
    try:
        config.parse(argv)
    except ConfigError as e:
        logging.error('Failed to parse configuration: %s', e)
        return 2

    # Resolve the list of adapters specified
    try:
        adapters = config.resolve_adapters()
    except ConfigError as e:
        logging.warning('Failed to resolve API adapters: %s', e)
        adapters = {}

    logging.info('Using the %s IOLoop instance', '0MQ' if using_zmq_loop else 'tornado')

    # Launch the HTTP server
    http_server = HttpServer(config.debug_mode, config.access_logging,
                             config.static_path, adapters)
    http_server.listen(config.http_port, config.http_addr)

    logging.info('HTTP server listening on %s:%s', config.http_addr, config.http_port)

    # Register a SIGINT signal handler only if this is the main thread
    if isinstance(threading.current_thread(), threading._MainThread):  # pragma: no cover
        signal.signal(signal.SIGINT, lambda signum, frame: shutdown_handler())

    # Enter IO processing loop
    tornado.ioloop.IOLoop.instance().start()

    # At shutdown, clean up the state of the loaded adapters
    http_server.cleanup_adapters()

    logging.info('ODIN server shutdown')

    return 0
Exemple #3
0
    def test_bad_access_log_level(self, caplog):
        """Test that a bad access logging level generates an error."""
        bad_level = 'wibble'
        http_server = HttpServer(adapters=[], access_logging=bad_level)

        assert log_message_seen(
            caplog, logging.ERROR,
            'Access logging level {} not recognised'.format(bad_level))
Exemple #4
0
 def setup_class(cls):
     cls.http_server = HttpServer(adapters=[])
     cls.handler = Mock()
     cls.handler.get_status = Mock(return_value=200)
     cls.request_summary = 'request'
     cls.handler._request_summary = Mock(return_value=cls.request_summary)
     cls.handler.request = Mock()
     cls.request_time = 1234
     cls.handler.request.request_time = Mock(return_value=cls.request_time)
     cls.log_capture_filter = LogCaptureFilter()
 def test_bad_access_log_level(self):
     """Test that a bad access logging level generates an error."""
     log_capture_filter = LogCaptureFilter()
     bad_level='wibble'
     http_server = HttpServer(adapters=[], access_logging=bad_level)
     
     msg_seen = False
     expected_msg = 'Access logging level {} not recognised'.format(bad_level)
     for msg in log_capture_filter.log_error():
         if msg == expected_msg:
             msg_seen = True
     assert msg_seen
Exemple #6
0
def main(argv=None):
    """Run ODIN server.

    This function is the main entry point for the ODIN server. It parses configuration
    options from the command line and any files, resolves adapters and launches the main
    API server before entering the IO processing loop.

    :param argv: argument list to pass to parser if called programatically
    """
    config = ConfigParser()

    # Define configuration options and add to the configuration parser
    config.define('http_addr', default='0.0.0.0', option_help='Set HTTP server address')
    config.define('http_port', default=8888, option_help='Set HTTP server port')
    config.define('debug_mode', default=False, option_help='Enable tornado debug mode')
    config.define('access_logging', default=None, option_help="Set the tornado access log level",
                  metavar="debug|info|warning|error|none")
    config.define('static_path', default='./static', option_help='Set path for static file content')

    # Parse configuration options and any configuration file specified
    try:
        config.parse(argv)
    except ConfigError as e:
        logging.error('Failed to parse configuration: %s', e)
        return 2

    # Resolve the list of adapters specified
    try:
        adapters = config.resolve_adapters()
    except ConfigError as e:
        logging.warning('Failed to resolve API adapters: %s', e)
        adapters = {}

    # Launch the HTTP server
    http_server = HttpServer(config.debug_mode, config.access_logging,
                             config.static_path, adapters)
    http_server.listen(config.http_port, config.http_addr)

    logging.info('HTTP server listening on %s:%s', config.http_addr, config.http_port)

    # Register a SIGINT signal handler only if this is the main thread
    if isinstance(threading.current_thread(), threading._MainThread):  # pragma: no cover
        signal.signal(signal.SIGINT, lambda signum, frame: shutdown_handler())

    # Enter IO processing loop
    tornado.ioloop.IOLoop.instance().start()

    # At shutdown, clean up the state of the loaded adapters
    http_server.cleanup_adapters()

    logging.info('ODIN server shutdown')

    return 0
 def __init__(self, caplog):
     """Initialise the logging test server."""
     self.http_server = HttpServer(adapters=[])
     self.request_summary = 'request'
     self.request_time = 1234
     self.caplog = caplog