import json from uuid import uuid4 import bottle from bottle import HTTPResponse from pretend_extended.common.constants import FOREVER from pretend_extended.server.log import get_logger from pretend_extended.server.mock_servers.http.handler import HttpHandler from pretend_extended.server.mock_servers.smtp.handler import SmtpHandler from pretend_extended.server import app, settings from pretend_extended.server.apps import history LOGGER = get_logger('pretend_extended.server.apps.pretender') HANDLERS = { 'http': HttpHandler(), 'smtp': SmtpHandler(), } def get_pretenders(protocol): """ Get a dict mapping UID to pretender data for the given protocol """ return HANDLERS[protocol].PRETENDERS def keep_alive(protocol, uid):
import subprocess import sys import time from pretend_extended.common.constants import ( RETURN_CODE_PORT_IN_USE, PRETEND_PORT_RANGE ) from pretend_extended.common.exceptions import NoPortAvailableException from pretend_extended.server.log import get_logger from pretend_extended.server import data from pretend_extended.server.mock_servers import PretenderModel LOGGER = get_logger('pretend_extended.server.mock_servers.smtp.handler') class SMTPPretenderModel(PretenderModel): def __init__(self, start, name, timeout, last_call, port, pid): super(SMTPPretenderModel, self).__init__( start, name, timeout, last_call, protocol='smtp' ) self.__dict__.update({ 'port': port, 'pid': pid, }) class SmtpHandler(object):
import datetime import json from pretend_extended.common.constants import FOREVER from pretend_extended.server.log import get_logger from pretend_extended.server.mock_servers import PretenderModel LOGGER = get_logger('pretend_extended.http.handler') class HTTPPretenderModel(PretenderModel): def __init__(self, path, **kwargs): super(HTTPPretenderModel, self).__init__(protocol='http', **kwargs) self.path = path class HttpHandler(object): PRETENDERS = {} def get_or_create_pretender(self, name, timeout): start = datetime.datetime.now() if name in self.PRETENDERS: pretender = self.PRETENDERS[name] else: path = "/mockhttp/{0}".format(name) if name != 'global' else '/' if timeout != FOREVER: timeout = datetime.timedelta(seconds=timeout)
import bottle from pretend_extended.server.log import get_logger from pretend_extended.common.constants import REQUEST_ONLY_HEADERS LOGGER = get_logger('pretend_extended.server.utils') def acceptable_response_header(header): "Use to filter which HTTP headers in the request should be removed" return header not in REQUEST_ONLY_HEADERS def get_header(header, default=None): return bottle.request.headers.get(header, default)
import json import bottle from bottle import HTTPResponse from pretend_extended.common.http import Preset, RequestSerialiser from pretend_extended.server.log import get_logger from pretend_extended.server import app from pretend_extended.server.apps import pretender from pretend_extended.server.apps.history import save_history from pretend_extended.server.apps.preset import preset_count, select_preset LOGGER = get_logger('pretend_extended.server.apps.replay') def replay(uid, body): "Save the request and replay response" mock_request = json.loads(body) LOGGER.debug('[UID:{0}] Saving history:\n{1}'.format(uid, mock_request)) save_history(uid, mock_request) if preset_count(uid) == 0: LOGGER.error("Cannot find matching request\n{0}".format(body)) raise HTTPResponse(b"No preset response", status=404) selected = select_preset(uid, mock_request) LOGGER.debug("SELECTED:\n{0}".format(selected)) return selected @app.post('/replay/<uid>') def replay_smtp(uid):
import argparse import socket from pretend_extended.server.base import in_parent_process, save_pid_file from pretend_extended.server.log import get_logger from pretend_extended.client import BossClient from pretend_extended.common.constants import RETURN_CODE_PORT_IN_USE LOGGER = get_logger("pretend_extended.server.pretender") class Pretender(object): def __init__(self, uid, host, port, boss_port): self.uid = uid self.boss_port = boss_port self.host = host self.port = port self.boss_api_handler = BossClient(host, boss_port).boss_access if in_parent_process(): save_pid_file("pretend_extended-mock-{0}.pid".format(uid)) def run(self): raise NotImplementedError("run() not defined in {0}".format(self.__class__)) @classmethod def start(cls): server = cls.from_command_line_args() try: server.run() except socket.error:
import sys import traceback from pretend_extended.server.log import get_logger from bottle import html_escape LOGGER = get_logger('pretend_extended.server.middleware') class ExceptionLoggingMiddleware(object): """ Middleware that logs exceptions raised by the server. """ def __init__(self, app, *args, **kwargs): self.app = app def __call__(self, environ, start_response): try: return self.app(environ, start_response) except Exception: # This code is largely taken from ``def wsgi()`` in the bottle # code itself, but logs to the log file rather than writing to # environ['wsgi.errors'] traceback.print_exc() LOGGER.exception("Error processing request") err = '<h1>Critical error while processing request: %s</h1>' \ % html_escape(environ.get('PATH_INFO', '/')) environ['wsgi.errors'].write(err) headers = [('Content-Type', 'text/html; charset=UTF-8')] start_response('500 INTERNAL SERVER ERROR', headers,
import json from collections import defaultdict from bottle import HTTPResponse from pretend_extended.server.log import get_logger from pretend_extended.server import app LOGGER = get_logger('pretend_extended.server.apps.history') HISTORY = defaultdict(list) def save_history(uid, request): """ Save a value in history """ HISTORY[uid].append(request) @app.get('/history/<uid>/<ordinal:int>') def get_history(uid, ordinal): """ Access requests issued to the mock server """ try: return json.dumps(HISTORY[uid][ordinal]) except IndexError: raise HTTPResponse(b"No recorded request", status=404) except Exception: LOGGER.exception('Unexpected exception')