def export_stubs(handler, scenario_name): from stubo.model.exporter import YAML_FORMAT_SUBDIR # export stubs in the old format command_links = export_stubs_to_commands_format(handler, scenario_name) # continue stub export in the new format cache = Cache(get_hostname(handler.request)) scenario_name_key = cache.scenario_key_name(scenario_name) exporter = Exporter(static_dir=handler.settings['static_path']) runnable = asbool(handler.get_argument('runnable', False)) playback_session = handler.get_argument('playback_session', None) export_dir_path, files, runnable_info = exporter.export( scenario_name_key, runnable=runnable, playback_session=playback_session, session_id=handler.get_argument('session_id', None), export_dir=handler.get_argument('export_dir', None)) # getting export links yaml_links = get_export_links(handler, scenario_name_key + "/" + YAML_FORMAT_SUBDIR, files) payload = dict(scenario=scenario_name, export_dir_path=export_dir_path, command_links=command_links, yaml_links=yaml_links) if runnable_info: payload['runnable'] = runnable_info return dict(version=version, data=payload)
def _import_module(self): cache = Cache('localhost') _ = cache.set_stubo_setting("tracking_level", "full", True) self.http_client.fetch(self.get_url('/stubo/api/exec/cmds?cmdfile=/static/cmds/formatted_date/response.commands'), self.stop) response = self.wait() self.assertEqual(response.code, 200)
def delete(self, scenario_name): """ Deletes scenario object from database. Fails if there are existing stubs in the database :param scenario_name: <string> scenario name """ scenario_name = _get_scenario_full_name(self, scenario_name) query = {'name': scenario_name} # query MongoDB document = yield self.db.scenario.find_one(query) if document is not None: # delete document yield self.db.scenario.remove(query) try: # scenario name contains host, splitting it and using this value to clear cache host, name = scenario_name.split(":") cache = Cache(host) # change cache cache.delete_caches(name) except Exception as ex: log.warn( "Failed to delete caches for scenario: %s. Got error: %s" % (scenario_name, ex)) self.set_status(200) else: self.send_error( 412, reason="Precondition failed - scenario (%s) does not exist." % scenario_name)
def delete(self, scenario_name): """ Deletes scenario object from database. Fails if there are existing stubs in the database :param scenario_name: <string> scenario name """ scenario_name = _get_scenario_full_name(self, scenario_name) query = {'name': scenario_name} # query MongoDB document = yield self.db.scenario.find_one(query) if document is not None: # delete document yield self.db.scenario.remove(query) try: # scenario name contains host, splitting it and using this value to clear cache host, name = scenario_name.split(":") cache = Cache(host) # change cache cache.delete_caches(name) except Exception as ex: log.warn("Failed to delete caches for scenario: %s. Got error: %s" % (scenario_name, ex)) self.set_status(200) else: self.send_error(412, reason="Precondition failed - scenario (%s) does not exist." % scenario_name)
def export_stubs(handler, scenario_name): from stubo.model.exporter import YAML_FORMAT_SUBDIR # export stubs in the old format command_links = export_stubs_to_commands_format(handler, scenario_name) # continue stub export in the new format cache = Cache(get_hostname(handler.request)) scenario_name_key = cache.scenario_key_name(scenario_name) exporter = Exporter(static_dir = handler.settings['static_path']) runnable = asbool(handler.get_argument('runnable', False)) playback_session = handler.get_argument('playback_session', None) export_dir_path, files, runnable_info = exporter.export(scenario_name_key, runnable=runnable, playback_session=playback_session, session_id=handler.get_argument('session_id', None), export_dir=handler.get_argument('export_dir', None)) # getting export links yaml_links = get_export_links(handler, scenario_name_key+"/"+YAML_FORMAT_SUBDIR, files) payload = dict(scenario=scenario_name, export_dir_path=export_dir_path, command_links=command_links, yaml_links=yaml_links) if runnable_info: payload['runnable'] = runnable_info return dict(version=version, data=payload)
def update_delay_policy(handler, doc): """Record delay policy in redis to be available globally to any users for their sessions. put/delay_policy?name=rtz_1&delay_type=fixed&milliseconds=700 put/delay_policy?name=rtz_2&delay_type=normalvariate&mean=100&stddev=50 """ cache = Cache(get_hostname(handler.request)) response = {'version': version} err = None if 'name' not in doc: err = "'name' param not found in request" if 'delay_type' not in doc: err = "'delay_type' param not found in request" if doc['delay_type'] == 'fixed': if 'milliseconds' not in doc: err = "'milliseconds' param is required for 'fixed' delays" elif doc['delay_type'] == 'normalvariate': if 'mean' not in doc or 'stddev' not in doc: err = "'mean' and 'stddev' params are required for " \ "'normalvariate' delays" else: err = 'Unknown delay type: {0}'.format(doc['delay_type']) if err: raise exception_response( 400, title=u'put/delay_policy arg error: {0}'.format(err)) result = cache.set_delay_policy(doc['name'], doc) updated = 'new' if result else 'updated' response['data'] = { 'message': 'Put Delay Policy Finished', 'name': doc['name'], 'delay_type': doc['delay_type'], 'status': updated } return response
def end_sessions(handler, scenario_name): """ End all sessions for specified scenario :param handler: request handler :param scenario_name: scenario name - can be supplied with hostname ("mirage-app:scenario_x") :return: """ response = {'version': version, 'data': {}} # checking whether full name (with hostname) was passed, if not - getting full name # scenario_name_key = "localhost:scenario_1" if ":" not in scenario_name: hostname = get_hostname(handler.request) cache = Cache(hostname) else: # removing hostname from scenario name slices = scenario_name.split(":") scenario_name = slices[1] hostname = slices[0] cache = Cache(hostname) # cache = Cache(get_hostname(handler.request)) sessions = list( cache.get_sessions_status(scenario_name, status=('record', 'playback'))) # ending all sessions for session_name, session in sessions: session_response = end_session(hostname, session_name) response['data'][session_name] = session_response.get('data') return response
def put_bookmark(handler, session_name, name): cache = Cache(get_hostname(handler.request)) response = dict(version=version, data = {}) if not session_name: raise exception_response(400, title="No session provided") scenario_key = cache.find_scenario_key(session_name) scenario_name = scenario_key.partition(':')[-1] # retrieve the request index state for selected session index_state = {} request_index_data = cache.get_request_index_data(scenario_name) if request_index_data: for k, v in request_index_data.iteritems(): indexed_session_name, _, stub_key = k.partition(':') if indexed_session_name == session_name: index_state[stub_key] = v if not index_state: raise exception_response(400, title="No indexes found for session '{0}'. Is the session in " 'playback mode and have state?'.format(session_name)) log.debug("save request index state '{0}' = {1}".format(name, index_state)) cache.set_saved_request_index_data(scenario_name, name, index_state) response['data'][name] = index_state return response
def list_stubs(handler, scenario_name, host=None): cache = Cache(host or get_hostname(handler.request)) scenario = Scenario() stubs = scenario.get_stubs(cache.scenario_key_name(scenario_name)) result = dict(version=version, data=dict(scenario=scenario_name)) if stubs: result['data']['stubs'] = [x['stub'] for x in stubs] return result
def get_delay_policy(handler, name, cache_loc): cache = Cache(get_hostname(handler.request)) response = { 'version' : version } delay = cache.get_delay_policy(name, cache_loc) response['data'] = delay or {} return response
def get_delay_policy(handler, name, cache_loc): cache = Cache(get_hostname(handler.request)) response = { 'version': version } delay = cache.get_delay_policy(name, cache_loc) response['data'] = delay or {} return response
def get(self): """ Returns a list with all scenarios (and URL paths to these resources), stub count """ # getting all scenarios cursor = self.db.scenario.find() # sorting based on name cursor.sort([('name', pymongo.ASCENDING)]) # get size scenario_cl = Scenario() scenarios_sizes = scenario_cl.size() scenarios_recorded = scenario_cl.recorded() scenarios_stub_counts = scenario_cl.stub_counts() # start mapping data scenarios = [] result_dict = {} while (yield cursor.fetch_next): document = cursor.next_object() try: # getting information about recorded, sizes and stub counts scenario_recorded = scenarios_recorded.get( document['name'], '-') scenario_size = int(scenarios_sizes.get(document['name'], 0)) scenario_stub_count = scenarios_stub_counts.get( document['name'], 0) scenario_name = document['name'] host, scenario = scenario_name.split(':') # getting session data sessions = [] cache = Cache(host) for session_info in cache.get_scenario_sessions_information( scenario): sessions.append(session_info) scenarios.append({ 'name': scenario_name, 'recorded': scenario_recorded, 'space_used_kb': scenario_size, 'stub_count': scenario_stub_count, 'sessions': sessions, 'scenarioRef': '/stubo/api/v2/scenarios/objects/%s' % document['name'] }) except KeyError: log.warn('Scenario name not found for object: %s' % document['_id']) result_dict['data'] = scenarios self.set_status(200) self.write(result_dict)
def delete_delay_policy(handler, names): cache = Cache(get_hostname(handler.request)) response = {'version': version} num_deleted = cache.delete_delay_policy(names) response['data'] = { 'message': 'Deleted {0} delay policies from {1}'.format(num_deleted, names) } return response
def _import_module(self): cache = Cache('localhost') _ = cache.set_stubo_setting("tracking_level", "full", True) self.http_client.fetch( self.get_url( '/stubo/api/exec/cmds?cmdfile=/static/cmds/formatted_date/response.commands' ), self.stop) response = self.wait() self.assertEqual(response.code, 200)
def get_session_status(handler, all_hosts=True): scenario = Scenario() host_scenarios = defaultdict() # getting a dictionary with sizes for all scenarios scenario_sizes = scenario.size() scenarios_recorded = scenario.recorded() for s in scenario.get_all(): host, scenario_name = s['name'].split(':') if not all_hosts and get_hostname(handler.request) != host: continue if host not in host_scenarios: host_scenarios[host] = {} # getting session data sessions = [] cache = Cache(host) for session_name, session in cache.get_sessions(scenario_name): # try and get the last_used from the last tracker get/response # else when the begin/session playback was called last_used = session_last_used(s['name'], session_name, 'playback') if last_used: last_used = last_used['start_time'].strftime('%Y-%m-%d %H:%M:%S') else: # session has never been used for playback last_used = session.get('last_used', '-') session['last_used'] = last_used # removing stub information since we aren't using it anyway and it can consume a lot of memory session.pop('stubs', None) # creating sessions list sessions.append(session) # getting stub count stub_counts = stub_count(host, scenario_name)['data']['count'] recorded = '-' # adding session information if sessions: if stub_counts: # getting scenario size and recorded values scenario_size = 0 try: scenario_size = scenario_sizes[s['name']] recorded = scenarios_recorded[s['name']] except KeyError: log.debug("Could not get scenario size for: %s" % s['name']) except Exception as ex: log.warn("Failed to get scenario size for: %s, got error: %s" % (s['name'], ex)) # creating a dict with scenario information host_scenarios[host][scenario_name] = (sessions, stub_counts, recorded, round(scenario_size, 0)) else: host_scenarios[host][scenario_name] = (sessions, 0, '-', 0) return host_scenarios
def end_sessions(handler, scenario_name): response = {'version': version, 'data': {}} cache = Cache(get_hostname(handler.request)) sessions = list( cache.get_sessions_status(scenario_name, status=('record', 'playback'))) for session_name, session in sessions: session_response = end_session(handler, session_name) response['data'][session_name] = session_response.get('data') return response
def delete_delay_policy(handler, names): cache = Cache(get_hostname(handler.request)) response = { 'version' : version } num_deleted = cache.delete_delay_policy(names) response['data'] = { 'message' : 'Deleted {0} delay policies from {1}'.format(num_deleted, names) } return response
def get_setting(handler, host, setting=None): all_hosts = True if host == 'all' else False if all_hosts: host = get_hostname(handler.request) cache = Cache(host) result = cache.get_stubo_setting(setting, all_hosts) response = dict(version=version, data=dict(host=host, all=all_hosts)) if setting: response['data'][setting] = result else: response['data']['settings'] = result return response
def end_sessions(handler, scenario_name): response = { 'version' : version, 'data' : {} } cache = Cache(get_hostname(handler.request)) sessions = list(cache.get_sessions_status(scenario_name, status=('record', 'playback'))) for session_name, session in sessions: session_response = end_session(handler, session_name) response['data'][session_name] = session_response.get('data') return response
def get(self, scenario_name): """ Returns scenario name, current sessions and their states, stub count, total, document size. Also, provides direct URL link to stub list. :param scenario_name: <string> scenario name Response JSON: { "stubs": 32, "space_used_kb": 840, "recorded": "2015-07-15", "name": "localhost:scenario_16", "scenarioRef": "/stubo/api/v2/scenarios/objects/localhost:scenario_16" } """ # check if hostname is supplied - if not, override scenario name with new value scenario_name = _get_scenario_full_name(self, scenario_name) # query MongoDB document = yield self.db.scenario.find_one({'name': scenario_name}) # form a result dictionary if document is not None: # get stub count stub_count = yield self.db.scenario_stub.find({'scenario': scenario_name}).count() # get size scenario_cl = Scenario() size = scenario_cl.size(scenario_name) # check if size is None if size is None: size = 0 recorded = scenario_cl.recorded(scenario_name) if recorded is None: recorded = '-' host, scenario = scenario_name.split(':') # getting session data sessions = [] cache = Cache(host) for session_info in cache.get_scenario_sessions_information(scenario): sessions.append(session_info) result_dict = {'name': scenario_name, 'stub_count': stub_count, 'recorded': recorded, 'space_used_kb': int(size), 'scenarioRef': '/stubo/api/v2/scenarios/objects/{0}'.format(scenario_name), 'sessions': sessions} self.set_status(200) self.write(result_dict) else: self.send_error(404)
class StubCache(StubData): def __init__(self, payload, scenario, session_name): StubData.__init__(self, payload, scenario) self.session_name = session_name from stubo.cache import Cache self.cache = Cache(self.hostname) def id(self): return "{0} => {1}".format(self.scenario_key(), self.session_name) def request_index_id(self): matchers = u"".join([u"".join(x.split()).strip() for x in self.contains_matchers() or []]) return compute_hash( u"".join( [ self.scenario_name, matchers, self.request_path() or "", self.request_method(), self.request_query_args() or "", ] ) ) def load_from_cache(self, response_ids, delay_policy_name, recorded, system_date, module_info, request_index_key): self.payload = dict(response=dict(ids=response_ids)) response = self.get_response_from_cache(request_index_key) self.payload["response"] = response self.set_recorded(recorded) if module_info: self.set_module(module_info) if delay_policy_name: self.load_delay_from_cache(delay_policy_name) def get_response_from_cache(self, request_index_key): # look up response return self.cache.get_response(self.scenario_name, self.session_name, self.response_ids(), request_index_key) def load_delay_from_cache(self, name): self.set_delay_policy(self.cache.get_delay_policy(name)) def response_ids(self): return self.response()["ids"] def delay_policy_name(self): name = "" policy = self.delay_policy() if policy: name = policy.get("name") return name
class StubCache(StubData): def __init__(self, payload, scenario, session_name): StubData.__init__(self, payload, scenario) self.session_name = session_name from stubo.cache import Cache self.cache = Cache(self.hostname) def id(self): return '{0} => {1}'.format(self.scenario_key(), self.session_name) def request_index_id(self): matchers = u"".join([ u''.join(x.split()).strip() for x in self.contains_matchers() or [] ]) return compute_hash(u"".join([ self.scenario_name, matchers, self.request_path() or "", self.request_method(), self.request_query_args() or "" ])) def load_from_cache(self, response_ids, delay_policy_name, recorded, system_date, module_info, request_index_key): self.payload = dict(response=dict(ids=response_ids)) response = self.get_response_from_cache(request_index_key) self.payload['response'] = response self.set_recorded(recorded) if module_info: self.set_module(module_info) if delay_policy_name: self.load_delay_from_cache(delay_policy_name) def get_response_from_cache(self, request_index_key): # look up response return self.cache.get_response(self.scenario_name, self.session_name, self.response_ids(), request_index_key) def load_delay_from_cache(self, name): self.set_delay_policy(self.cache.get_delay_policy(name)) def response_ids(self): return self.response()['ids'] def delay_policy_name(self): name = '' policy = self.delay_policy() if policy: name = policy.get('name') return name
def put_setting(handler, setting, value, host): response = {'version': version} all_hosts = True if host == 'all' else False if all_hosts: host = get_hostname(handler.request) cache = Cache(host) new_setting = cache.set_stubo_setting(setting, value, all_hosts) response['data'] = { 'host': host, 'all': all_hosts, 'new': 'true' if new_setting else 'false', setting: value } return response
def end_session(handler, session_name): response = {'version': version} cache = Cache(get_hostname(handler.request)) scenario_key = cache.get_scenario_key(session_name) if not scenario_key: # end/session?session=x called before begin/session response['data'] = {'message': 'Session ended'} return response host, scenario_name = scenario_key.split(':') # if session exists it can only be dormant session = cache.get_session(scenario_name, session_name, local=False) if not session: # end/session?session=x called before begin/session response['data'] = {'message': 'Session ended'} return response handler.track.scenario = scenario_name session_status = session['status'] if session_status not in ('record', 'playback'): log.warn('expecting session={0} to be in record of playback for ' 'end/session'.format(session_name)) session['status'] = 'dormant' # clear stubs cache & scenario session data session.pop('stubs', None) cache.set(scenario_key, session_name, session) cache.delete_session_data(scenario_name, session_name) response['data'] = {'message': 'Session ended'} return response
def delete_scenario(scenario_name_key, force): log.debug(u'delete_scenario: {0}'.format(scenario_name_key)) host, scenario_name = scenario_name_key.split(':') cache = Cache(host) if not force: active_sessions = cache.get_active_sessions(scenario_name, local=False) if active_sessions: raise exception_response(400, title='Sessons in playback/record, can not delete. Found th' 'e following active sessions: {0} for scenario: {1}'.format( active_sessions, scenario_name)) scenario_db.remove_all(scenario_name_key) cache.delete_caches(scenario_name)
def put_setting(handler, setting, value, host): response = { 'version' : version } all_hosts = True if host == 'all' else False if all_hosts: host = get_hostname(handler.request) cache = Cache(host) new_setting = cache.set_stubo_setting(setting, value, all_hosts) response['data'] = { 'host' : host, 'all' : all_hosts, 'new' : 'true' if new_setting else 'false', setting : value } return response
def delete_scenario(sce_name_key, frc): log.debug(u'delete_scenario: {0}'.format(sce_name_key)) # getting host and scenario names hst, sce_name = sce_name_key.split(':') cache = Cache(hst) if not frc: active_sessions = cache.get_active_sessions(sce_name, local=False) if active_sessions: raise exception_response( 400, title='Sessons in playback/record, can not delete. ' 'Found the following active sessions: {0} ' 'for scenario: {1}'.format(active_sessions, sce_name)) scenario_db.remove_all(sce_name_key) cache.delete_caches(sce_name)
def put_stub(handler, session_name, delay_policy, stateful, priority, recorded=None, module_name=None, recorded_module_system_date=None): log.debug('put_stub request: {0}'.format(handler.request)) request = handler.request stubo_request = StuboRequest(request) session_name = session_name.partition(',')[0] cache = Cache(get_hostname(request)) scenario_key = cache.find_scenario_key(session_name) trace = TrackTrace(handler.track, 'put_stub') url_args = handler.track.request_params err_msg = 'put/stub body format error - {0}, for session: {1}' try: stub = parse_stub(stubo_request.body_unicode, scenario_key, url_args) except Exception, e: raise exception_response(400, title=err_msg.format(e.message, session_name))
def update_delay_policy(handler, doc): """Record delay policy in redis to be available globally to any users for their sessions. put/delay_policy?name=rtz_1&delay_type=fixed&milliseconds=700 put/delay_policy?name=rtz_2&delay_type=normalvariate&mean=100&stddev=50 """ cache = Cache(get_hostname(handler.request)) response = {'version': version} err = None if 'name' not in doc: err = "'name' param not found in request" if 'delay_type' not in doc: err = "'delay_type' param not found in request" if doc['delay_type'] == 'fixed': if 'milliseconds' not in doc: err = "'milliseconds' param is required for 'fixed' delays" elif doc['delay_type'] == 'normalvariate': if 'mean' not in doc or 'stddev' not in doc: err = "'mean' and 'stddev' params are required for " \ "'normalvariate' delays" elif doc['delay_type'] == 'weighted': if 'delays' not in doc: err = "'delays' are required for 'weighted' delays" else: try: Delay.parse_args(doc) except Exception, e: err = 'Unable to parse weighted delay arguments: {0}'.format( str(e))
def get_status(handler): """Check status. query args: scenario=name session=name check_database=true|false (default true) local_cache=true|false (default true) """ request = handler.request cache = Cache(get_hostname(request)) response = dict(version=version, data={}) args = dict( (key, value[0]) for key, value in request.arguments.iteritems()) local_cache = asbool(args.get('local_cache', True)) redis_server = get_redis_server(local_cache) response['data']['cache_server'] = {'local': local_cache} response['data']['info'] = { 'cluster': handler.settings.get('cluster_name'), 'graphite_host': handler.settings.get('graphite.host') } try: result = redis_server.ping() response['data']['cache_server']['status'] = 'ok' if result else 'bad' except Exception, e: response['data']['cache_server']['status'] = 'bad' response['data']['cache_server']['error'] = str(e) return response
def delete_scenario(scenario_name_key, force): log.debug(u'delete_scenario: {0}'.format(scenario_name_key)) host, scenario_name = scenario_name_key.split(':') cache = Cache(host) if not force: active_sessions = cache.get_active_sessions(scenario_name, local=False) if active_sessions: raise exception_response( 400, title='E016: Sessons in playback/record, can' 'not delete. Found the following active sessions: {0} for ' 'scenario: {1}'.format(active_sessions, scenario_name)) scenario_db.remove_all(scenario_name_key) cache.delete_caches(scenario_name)
def get(self): """ Returns a list with all scenarios (and URL paths to these resources), stub count """ # getting all scenarios cursor = self.db.scenario.find() # sorting based on name cursor.sort([('name', pymongo.ASCENDING)]) # get size scenario_cl = Scenario() scenarios_sizes = scenario_cl.size() scenarios_recorded = scenario_cl.recorded() scenarios_stub_counts = scenario_cl.stub_counts() # start mapping data scenarios = [] result_dict = {} while (yield cursor.fetch_next): document = cursor.next_object() try: # getting information about recorded, sizes and stub counts scenario_recorded = scenarios_recorded.get(document['name'], '-') scenario_size = int(scenarios_sizes.get(document['name'], 0)) scenario_stub_count = scenarios_stub_counts.get(document['name'], 0) scenario_name = document['name'] host, scenario = scenario_name.split(':') # getting session data sessions = [] cache = Cache(host) for session_info in cache.get_scenario_sessions_information(scenario): sessions.append(session_info) scenarios.append({'name': scenario_name, 'recorded': scenario_recorded, 'space_used_kb': scenario_size, 'stub_count': scenario_stub_count, 'sessions': sessions, 'scenarioRef': '/stubo/api/v2/scenarios/objects/%s' % document['name']}) except KeyError: log.warn('Scenario name not found for object: %s' % document['_id']) result_dict['data'] = scenarios self.set_status(200) self.write(result_dict)
def export_stubs(handler, scenario_name): cache = Cache(get_hostname(handler.request)) scenario_name_key = cache.scenario_key_name(scenario_name) exporter = Exporter(static_dir = handler.settings['static_path']) runnable = asbool(handler.get_argument('runnable', False)) playback_session = handler.get_argument('playback_session', None) export_dir_path, files, runnable_info = exporter.export(scenario_name_key, runnable=runnable, playback_session=playback_session, session_id=handler.get_argument('session_id', None), export_dir=handler.get_argument('export_dir', None)) links = get_export_links(handler, scenario_name_key, files) payload = dict(scenario=scenario_name, export_dir_path=export_dir_path, links=links) if runnable_info: payload['runnable'] = runnable_info return dict(version=version, data=payload)
def import_bookmarks(handler, location): request = handler.request cache = Cache(get_hostname(request)) response = dict(version=version, data={}) uri, bookmarks_name = UriLocation(request)(location) log.info('uri={0}, bookmarks_name={1}'.format(uri, bookmarks_name)) payload, _, status_code = UrlFetch().get(uri) payload = json.loads(payload) # e.g payload #{"converse": {"first": {"8981c0dda19403f5cc054aea758689e65db2": "2"}}} imported = {} for scenario, bookmarks in payload.iteritems(): for bookmark_name, bookmark in bookmarks.iteritems(): is_new = cache.set_saved_request_index_data(scenario, bookmark_name, bookmark) scenario_book = '{0}:{1}'.format(scenario, bookmark_name) imported[scenario_book] = ('new' if is_new else 'updated', bookmark) response['data']['imported'] = imported return response
def rename_scenario(handler, scenario_name, new_name): """ Renames specified scenario, renames Stubs, reloads cache :param handler: TrackRequest handler :param scenario_name: <string> scenario name :param new_name: <string> new scenario name :return: <tuple> containing status code and message that will be returned """ response = { 'version': version } scenario = Scenario() # getting hostname host = handler.get_argument('host', get_hostname(handler.request)) # full names hostname:scenario_name full_scenario_name = "{0}:{1}".format(host, scenario_name) new_full_scenario_name = "{0}:{1}".format(host, new_name) # getting scenario object scenario_obj = scenario.get(full_scenario_name) # checking if scenario exist, if not - quit if scenario_obj is None: handler.set_status(400) handler.track.scenario = scenario_name response['error'] = "Scenario not found. Name provided: {0}, host checked: {1}.".format(scenario_name, host) log.debug("Scenario not found. Name provided: {0}, host checked: {1}.".format(scenario_name, host)) return response # renaming scenario and all stubs, getting a dict with results try: response = scenario.change_name(full_scenario_name, new_full_scenario_name) except Exception as ex: handler.set_status() log.debug("Failed to change scenario name, got error: %s" % ex) response['error']['database'] = "Failed to change scenario name, got error: %s" % ex try: cache = Cache(host) # change cache scenario_sessions = cache.get_sessions_status(scenario_name) # scenario sessions contains tuples [(u'myscenario_session2_1', u'dormant'), ....] session_info = [] cache.delete_caches(scenario_name) # rebuild cache for session_name, mode in scenario_sessions: cache.create_session_cache(new_name, session_name) session_info.append({'name': session_name}) # sessions after creation go into playback mode, ending them end_session(handler, session_name) response['Remapped sessions'] = session_info except Exception as ex: log.debug("Failed to repopulate cache, got error: %s" % ex) response['error']['cache'] = "Failed to repopulate cache, got error: %s" % ex return response
def import_bookmarks(handler, location): request = handler.request cache = Cache(get_hostname(request)) response = dict(version=version, data={}) uri, bookmarks_name = UriLocation(request)(location) log.info('uri={0}, bookmarks_name={1}'.format(uri, bookmarks_name)) payload, _ = UrlFetch().get(uri) payload = json.loads(payload) # e.g payload #{"converse": {"first": {"8981c0dda19403f5cc054aea758689e65db2": "2"}}} imported = {} for scenario, bookmarks in payload.iteritems(): for bookmark_name, bookmark in bookmarks.iteritems(): is_new = cache.set_saved_request_index_data( scenario, bookmark_name, bookmark) scenario_book = '{0}:{1}'.format(scenario, bookmark_name) imported[scenario_book] = ('new' if is_new else 'updated', bookmark) response['data']['imported'] = imported return response
def prepare(self): function = self.request.path if function.startswith('/stubo/api/'): function = function.partition('/stubo/api/')[-1] elif function == '/stubo/default/execCmds': # LEGACY function = 'exec/cmds' args = self.skip_dotted_names(self.request.arguments) headers = self.skip_dotted_names(self.request.headers) self.track = ObjectDict(request_params=args, request_headers=headers, request_method=self.request.method) host_parts = self.request.host.partition(':') host = host_parts[0].lower() port = host_parts[-1] cache = Cache(host) track_setting = cache.get_stubo_setting('tracking_level') if not track_setting: track_setting = cache.get_stubo_setting('tracking_level', all_hosts=True) if not track_setting: track_setting = 'normal' self.track.tracking_level = args.get('tracking_level', track_setting) request_size = len(self.request.body) # always track put/stub recordings if self.track.tracking_level == 'full' or function == 'put/stub': self.track.request_text = self.request.body if function == 'get/response' and request_size <= 0: self.track.error = 'NoTextInBody' self.track.update( dict(function=function, start_time=tsecs_to_date(self.request._start_time), host=host, port=port, remote_ip=self.request.remote_ip, server=socket.getfqdn(), request_size=request_size)) log.debug('tracking: {0}:{1}'.format(self.request.host, function))
def prepare(self): function = self.request.path if function.startswith("/stubo/api/"): function = function.partition("/stubo/api/")[-1] elif function == "/stubo/default/execCmds": # LEGACY function = "exec/cmds" args = self.skip_dotted_names(self.request.arguments) headers = self.skip_dotted_names(self.request.headers) self.track = ObjectDict(request_params=args, request_headers=headers, request_method=self.request.method) host_parts = self.request.host.partition(":") host = host_parts[0].lower() port = host_parts[-1] cache = Cache(host) track_setting = cache.get_stubo_setting("tracking_level") if not track_setting: track_setting = cache.get_stubo_setting("tracking_level", all_hosts=True) if not track_setting: track_setting = "normal" self.track.tracking_level = args.get("tracking_level", track_setting) request_size = len(self.request.body) # always track put/stub recordings if self.track.tracking_level == "full" or function == "put/stub": self.track.request_text = self.request.body if function == "get/response" and request_size <= 0: self.track.error = "NoTextInBody" self.track.update( dict( function=function, start_time=tsecs_to_date(self.request._start_time), host=host, port=port, remote_ip=self.request.remote_ip, server=socket.getfqdn(), request_size=request_size, ) ) log.debug("tracking: {0}:{1}".format(self.request.host, function))
def delete(self, scenario_name): """ Deletes specified scenario. If force is not supplied - checks for active sessions and if there are any - stops deletion. If force is supplied or there are no active sessions - deletes all stubs for scenario :param scenario_name: :return: """ response = { 'version': version } # checking for supplied headers host = None force = False if 'target_host' in self.request.headers: host = self.request.headers['target_host'] if 'force' in self.request.headers: force = asbool(self.request.headers['force']) # getting full scenario database scenario_name = _get_scenario_full_name(self, scenario_name, host) host, scenario = scenario_name.split(':') cache = Cache(host) # if force is False or absent - checking for active sessions and if there are any - aborting deletion if not force: active_sessions = cache.get_active_sessions(scenario, local=False) if active_sessions: self.set_status(409) error = 'Sessons in playback/record, can not delete. Found the ' \ 'following active sessions: {0} for scenario: {1}'.format(active_sessions, scenario_name) response['error'] = error self.write(response) return # asynchronous deletion of stubs, returns two params - "ok" and "n" (deleted items count) result = yield self.db.scenario_stub.remove({'scenario': scenario_name}) # deleting scenario from cache cache.delete_caches(scenario) response['data'] = "Deleted stubs count: %s" % result['n'] self.write(response)
def get_delay_policy(handler, name, cache_loc): """ Gets specified or all delays, returns dictionary :param handler: RequestHandler (or TrackRequest, BaseHandler, etc..) :param name: Delay name, if None is passed - gets all delays :param cache_loc: Cache location, usually just 'master' :return: dictionary of dictionaries with scenario information and reference URI and status_code for response """ cache = Cache(get_hostname(handler.request)) response = { 'version': version } status_code = 200 delays = cache.get_delay_policy(name, cache_loc) # if delay policy not found but name was specified, return error message if delays is None and name is not None: status_code = 404 response['error'] = "Delay policy '%s' not found" % name return response, status_code # list for storing delay objects since cache.get_delay_policy(name, cache_loc) returns a dict delay_list = [] # adding references if name is None: if delays is not None: # All stored delays should be returned for k, v in delays.items(): v['delayPolicyRef'] = "/stubo/api/v2/delay-policy/objects/%s" % k delay_list.append(v) else: # Returning empty dict delays = {} delay_list.append(delays) else: delays['delayPolicyRef'] = "/stubo/api/v2/delay-policy/objects/%s" % name delay_list.append(delays) response['data'] = delay_list return response, status_code
def get_session_status(handler, all_hosts=True): scenario = Scenario() host_scenarios = {} for s in scenario.get_all(): host, scenario_name = s['name'].split(':') if not all_hosts and get_hostname(handler.request) != host: continue if host not in host_scenarios: host_scenarios[host] = {} sessions = [] cache = Cache(host) for session_name, session in cache.get_sessions(scenario_name): # try and get the last_used from the last tracker get/response # else when the begin/session playback was called last_used = session_last_used(s['name'], session_name) if last_used: last_used = last_used['start_time'].strftime( '%Y-%m-%d %H:%M:%S') else: # session has never been used for playback last_used = session.get('last_used', '-') session['last_used'] = last_used sessions.append(session) stub_counts = stub_count(host, scenario_name)['data']['count'] recorded = '-' space_used = 0 if sessions: if stub_counts: stubs = list(get_stubs(host, scenario_name)) recorded = max(x['stub'].get('recorded') for x in stubs) for stub in stubs: stub = Stub(stub['stub'], s['name']) for matcher in stub.contains_matchers(): space_used += len(matcher) space_used += stub.space_used() host_scenarios[host][scenario_name] = (sessions, stub_counts, recorded, human_size(space_used)) else: host_scenarios[host][scenario_name] = (sessions, 0, '-', 0) return host_scenarios
def jump_bookmark(handler, name, sessions, index=None): request = handler.request cache = Cache(get_hostname(request)) response = dict(version=version, data = {}) scenario_key = cache.find_scenario_key(host, sessions[0]) scenario_name = scenario_key.partition(':')[-1] if not all(cache.find_scenario_key(host, x) == scenario_key for x in sessions): raise exception_response(400, title="All sessions must belong to the same scenario") index_state = cache.get_saved_request_index_data(scenario_name, name) check_bookmark(host, name, index_state) results = [] for session in sessions: for k, v in index_state.iteritems(): v = v if index is None else index session_key = '{0}:{1}'.format(session, k) result = set_request_index_item(scenario_name, session_key, v) results.append((k, v, result)) response['data']['results'] = results return response
def export_stubs(handler, scenario_name): cache = Cache(get_hostname(handler.request)) scenario_name_key = cache.scenario_key_name(scenario_name) exporter = Exporter(static_dir=handler.settings['static_path']) runnable = asbool(handler.get_argument('runnable', False)) playback_session = handler.get_argument('playback_session', None) export_dir_path, files, runnable_info = exporter.export( scenario_name_key, runnable=runnable, playback_session=playback_session, session_id=handler.get_argument('session_id', None), export_dir=handler.get_argument('export_dir', None)) links = get_export_links(handler, scenario_name_key, files) payload = dict(scenario=scenario_name, export_dir_path=export_dir_path, links=links) if runnable_info: payload['runnable'] = runnable_info return dict(version=version, data=payload)
class StubCache(StubData): def __init__(self, payload, scenario, session_name): StubData.__init__(self, payload, scenario) self.session_name = session_name from stubo.cache import Cache self.cache = Cache(self.hostname) def id(self): return '{0} => {1}'.format(self.scenario_key(), self.session_name) def load_from_cache(self, response_ids, delay_policy_name, recorded, system_date, module_info, request_index_key): self.payload = dict(response=dict(status=200, ids=response_ids)) self.set_response_body( self.get_response_body_from_cache(request_index_key)) self.set_recorded(recorded) if module_info: self.set_module(module_info) if delay_policy_name: self.load_delay_from_cache(delay_policy_name) def get_response_body_from_cache(self, request_index_key): # look up response return self.cache.get_response_text(self.scenario_name, self.session_name, self.response_ids(), request_index_key) def load_delay_from_cache(self, name): self.set_delay_policy(self.cache.get_delay_policy(name)) def response_ids(self): return self.response()['ids'] def delay_policy_name(self): name = '' policy = self.delay_policy() if policy: name = policy.get('name') return name
def prepare(self): function = self.request.path if function.startswith('/stubo/api/'): function = function.partition('/stubo/api/')[-1] elif function == '/stubo/default/execCmds': # LEGACY function = 'exec/cmds' args = self.skip_dotted_names(self.request.arguments) headers = self.skip_dotted_names(self.request.headers) self.track = ObjectDict(request_params=args, request_headers=headers, request_method=self.request.method) host_parts = self.request.host.partition(':') host = host_parts[0].lower() port = host_parts[-1] cache = Cache(host) track_setting = cache.get_stubo_setting('tracking_level') if not track_setting: track_setting = cache.get_stubo_setting('tracking_level', all_hosts=True) if not track_setting: track_setting = 'normal' self.track.tracking_level = args.get('tracking_level', track_setting) request_size = len(self.request.body) # always track put/stub recordings if self.track.tracking_level == 'full' or function == 'put/stub': self.track.request_text = self.request.body if function == 'get/response' and request_size <= 0: self.track.error = 'NoTextInBody' self.track.update(dict(function=function, start_time=tsecs_to_date(self.request._start_time), host=host, port=port, remote_ip=self.request.remote_ip, server=socket.getfqdn(), request_size=request_size)) log.debug('tracking: {0}:{1}'.format(self.request.host, function))
def put_bookmark(handler, session_name, name): cache = Cache(get_hostname(handler.request)) response = dict(version=version, data={}) if not session_name: raise exception_response(400, title="No session provided") scenario_key = cache.find_scenario_key(session_name) scenario_name = scenario_key.partition(':')[-1] # retrieve the request index state for selected session index_state = {} request_index_data = cache.get_request_index_data(scenario_name) if request_index_data: for k, v in request_index_data.iteritems(): indexed_session_name, _, stub_key = k.partition(':') if indexed_session_name == session_name: index_state[stub_key] = v if not index_state: raise exception_response( 400, title="No indexes found for session '{0}'. Is the session in " 'playback mode and have state?'.format(session_name)) log.debug("save request index state '{0}' = {1}".format(name, index_state)) cache.set_saved_request_index_data(scenario_name, name, index_state) response['data'][name] = index_state return response
def get_delay_policy(handler, name, cache_loc): """ Gets specified or all delays, returns dictionary :param handler: RequestHandler (or TrackRequest, BaseHandler, etc..) :param name: Delay name, if None is passed - gets all delays :param cache_loc: Cache location, usually just 'master' :return: dictionary of dictionaries with scenario information and reference URI and status_code for response """ cache = Cache(get_hostname(handler.request)) response = {'version': version} status_code = 200 delays = cache.get_delay_policy(name, cache_loc) # if delay policy not found but name was specified, return error message if delays is None and name is not None: status_code = 404 response['error'] = "Delay policy '%s' not found" % name return response, status_code # list for storing delay objects since cache.get_delay_policy(name, cache_loc) returns a dict delay_list = [] # adding references if name is None: if delays is not None: # All stored delays should be returned for k, v in delays.items(): v['delayPolicyRef'] = "/stubo/api/v2/delay-policy/objects/%s" % k delay_list.append(v) else: # Returning empty dict delays = {} delay_list.append(delays) else: delays[ 'delayPolicyRef'] = "/stubo/api/v2/delay-policy/objects/%s" % name delay_list.append(delays) response['data'] = delay_list return response, status_code
def delete(self, scenario_name): """ Deletes specified scenario. If force is not supplied - checks for active sessions and if there are any - stops deletion. If force is supplied or there are no active sessions - deletes all stubs for scenario :param scenario_name: :return: """ response = {'version': version} # checking for supplied headers host = None force = False if 'target_host' in self.request.headers: host = self.request.headers['target_host'] if 'force' in self.request.headers: force = asbool(self.request.headers['force']) # getting full scenario database scenario_name = _get_scenario_full_name(self, scenario_name, host) host, scenario = scenario_name.split(':') cache = Cache(host) # if force is False or absent - checking for active sessions and if there are any - aborting deletion if not force: active_sessions = cache.get_active_sessions(scenario, local=False) if active_sessions: self.set_status(409) error = 'Sessons in playback/record, can not delete. Found the ' \ 'following active sessions: {0} for scenario: {1}'.format(active_sessions, scenario_name) response['error'] = error self.write(response) return # asynchronous deletion of stubs, returns two params - "ok" and "n" (deleted items count) result = yield self.db.scenario_stub.remove( {'scenario': scenario_name}) # deleting scenario from cache cache.delete_caches(scenario) response['data'] = "Deleted stubs count: %s" % result['n'] self.write(response)
def jump_bookmark(handler, name, sessions, index=None): request = handler.request cache = Cache(get_hostname(request)) response = dict(version=version, data={}) scenario_key = cache.find_scenario_key(host, sessions[0]) scenario_name = scenario_key.partition(':')[-1] if not all( cache.find_scenario_key(host, x) == scenario_key for x in sessions): raise exception_response( 400, title="All sessions must belong to the same scenario") index_state = cache.get_saved_request_index_data(scenario_name, name) check_bookmark(host, name, index_state) results = [] for session in sessions: for k, v in index_state.iteritems(): v = v if index is None else index session_key = '{0}:{1}'.format(session, k) result = set_request_index_item(scenario_name, session_key, v) results.append((k, v, result)) response['data']['results'] = results return response
def get_session_status(handler, all_hosts=True): scenario = Scenario() host_scenarios = {} for s in scenario.get_all(): host, scenario_name = s['name'].split(':') if not all_hosts and get_hostname(handler.request) != host: continue if host not in host_scenarios: host_scenarios[host] = {} sessions = [] cache = Cache(host) for session_name, session in cache.get_sessions(scenario_name): # try and get the last_used from the last tracker get/response # else when the begin/session playback was called last_used = session_last_used(s['name'], session_name, 'playback') if last_used: last_used = last_used['start_time'].strftime('%Y-%m-%d %H:%M:%S') else: # session has never been used for playback last_used = session.get('last_used', '-') session['last_used'] = last_used sessions.append(session) stub_counts = stub_count(host, scenario_name)['data']['count'] recorded = '-' space_used = 0 if sessions: if stub_counts: stubs = list(get_stubs(host, scenario_name)) recorded = max(x['stub'].get('recorded') for x in stubs) for stub in stubs: stub = Stub(stub['stub'], s['name']) space_used += stub.space_used() host_scenarios[host][scenario_name] = (sessions, stub_counts, recorded, human_size(space_used)) else: host_scenarios[host][scenario_name] = (sessions, 0, '-', 0) return host_scenarios
def put_stub(handler, session_name, delay_policy, stateful, recorded=None, module_name=None, recorded_module_system_date=None): log.debug('put_stub request: {0}'.format(handler.request)) request = handler.request stubo_request = StuboRequest(request) session_name = session_name.partition(',')[0] cache = Cache(get_hostname(request)) scenario_key = cache.find_scenario_key(session_name) trace = TrackTrace(handler.track, 'put_stub') url_args = handler.track.request_params try: is_json = 'application/json' in request.headers.get('Content-Type', {}) stub = parse_stub(stubo_request.body_unicode, scenario_key, url_args, is_json) except Exception, e: raise exception_response(400, title='put/stub body format error - {0}, ' 'on session: {1}'.format( e.message, session_name))
def end_session(handler, session_name): response = { 'version' : version } cache = Cache(get_hostname(handler.request)) scenario_key = cache.get_scenario_key(session_name) if not scenario_key: # end/session?session=x called before begin/session response['data'] = { 'message' : 'Session ended' } return response host, scenario_name = scenario_key.split(':') session = cache.get_session(scenario_name, session_name, local=False) if not session: # end/session?session=x called before begin/session response['data'] = { 'message' : 'Session ended' } return response handler.track.scenario = scenario_name session_status = session['status'] if session_status not in ('record', 'playback'): log.warn('expecting session={0} to be in record or playback for ' 'end/session'.format(session_name)) session['status'] = 'dormant' # clear stubs cache & scenario session data session.pop('stubs', None) cache.set(scenario_key, session_name, session) cache.delete_session_data(scenario_name, session_name) if session_status == 'record': log.debug('store source recording to pre_scenario_stub') store_source_recording(scenario_key, session_name) response['data'] = { 'message' : 'Session ended' } return response
def export_stubs_to_commands_format(handler, scenario_name): """ Exports scenario to .commands file format. :param handler: :param scenario_name: <string> Scenario name :return: :raise exception_response: """ cache = Cache(get_hostname(handler.request)) scenario_name_key = cache.scenario_key_name(scenario_name) # use user arg or epoch time session_id = handler.get_argument('session_id', int(time.time())) session = u'{0}_{1}'.format(scenario_name, session_id) cmds = [ 'delete/stubs?scenario={0}'.format(scenario_name), 'begin/session?scenario={0}&session={1}&mode=record'.format( scenario_name, session) ] files = [] scenario = Scenario() # get scenario pre stubs for specified scenario stubs = list(scenario.get_pre_stubs(scenario_name_key)) if stubs: for i in range(len(stubs)): entry = stubs[i] stub = Stub(entry['stub'], scenario_name_key) # if stub is rest - matcher may be None, checking that if stub.contains_matchers() is None: cmds.append('# Stub skipped since no matchers were found. Consider using .yaml format for additional ' 'capabilities') # skipping to next stub, this stub is not compatible with .commands format continue matchers = [('{0}_{1}_{2}.textMatcher'.format(session, i, x), stub.contains_matchers()[x]) for x in range(len(stub.contains_matchers()))] matchers_str = ",".join(x[0] for x in matchers) url_args = stub.args() url_args['session'] = session module_info = stub.module() if module_info: # Note: not including put/module in the export, modules are shared # by multiple scenarios. url_args['ext_module'] = module_info['name'] url_args['stub_created_date'] = stub.recorded() url_args['stubbedSystemDate'] = module_info.get('recorded_system_date') url_args['system_date'] = module_info.get('system_date') url_args = urlencode(url_args) responses = stub.response_body() assert(len(responses) == 1) response = responses[0] response = ('{0}_{1}.response'.format(session, i), response) cmds.append('put/stub?{0},{1},{2}'.format(url_args, matchers_str, response[0])) files.append(response) files.extend(matchers) else: cmds.append('put/stub?session={0},text=a_dummy_matcher,text=a_dummy_response'.format(session)) cmds.append('end/session?session={0}'.format(session)) runnable = asbool(handler.get_argument('runnable', False)) runnable_info = dict() if runnable: playback_session = handler.get_argument('playback_session', None) if not playback_session: raise exception_response(400, title="'playback_session' argument required with 'runnable") runnable_info['playback_session'] = playback_session tracker = Tracker() last_used = tracker.session_last_used(scenario_name_key, playback_session, 'playback') if not last_used: raise exception_response(400, title="Unable to find playback session") runnable_info['last_used'] = dict(remote_ip=last_used['remote_ip'], start_time=str(last_used['start_time'])) playback = tracker.get_last_playback(scenario_name, playback_session, last_used['start_time']) playback = list(playback) if not playback: raise exception_response(400, title="Unable to find a playback for scenario='{0}', playback_session='{1}'".format(scenario_name, playback_session)) cmds.append('begin/session?scenario={0}&session={1}&mode=playback'.format( scenario_name, session)) number_of_requests = len(playback) runnable_info['number_of_playback_requests'] = number_of_requests for nrequest in range(number_of_requests): track = playback[nrequest] request_text = track.get('request_text') if not request_text: raise exception_response(400, title='Unable to obtain playback details, was full tracking enabled?') request_file_name = '{0}_{1}.request'.format(session, nrequest) files.append((request_file_name, request_text)) stubo_response_text = track['stubo_response'] if not isinstance(stubo_response_text, basestring): stubo_response_text = unicode(stubo_response_text) stubo_response_file_name = '{0}_{1}.stubo_response'.format(session, nrequest) files.append((stubo_response_file_name, stubo_response_text)) url_args = track['request_params'] url_args['session'] = session url_args = urlencode(url_args) cmds.append(u'get/response?{0},{1}'.format(url_args, request_file_name)) cmds.append('end/session?session={0}'.format(session)) try: bookmarks = cache.get_all_saved_request_index_data() if bookmarks: cmds.append('import/bookmarks?location=bookmarks') files.append(('bookmarks', json.dumps(bookmarks))) except Exception as ex: log.warn("failed to export bookmarks, error: %s" % ex) pass files.append(('{0}.commands'.format(scenario_name), b"\r\n".join(cmds))) static_dir = handler.settings['static_path'] export_dir = handler.get_argument('export_dir', scenario_name_key).replace(':', '_') export_dir_path = os.path.join(static_dir, 'exports', export_dir) if os.path.exists(export_dir_path): shutil.rmtree(export_dir_path) os.makedirs(export_dir_path) archive_name = os.path.join(export_dir_path, scenario_name) zout = zipfile.ZipFile(archive_name+'.zip', "w") tar = tarfile.open(archive_name+".tar.gz", "w:gz") for finfo in files: fname, contents = finfo file_path = os.path.join(export_dir_path, fname) with codecs.open(file_path, mode='wb', encoding='utf-8') as f: f.write(contents) f.close() tar.add(file_path, fname) zout.write(file_path, fname) tar.close() zout.close() shutil.copy(archive_name+'.zip', archive_name+'.jar') files.extend([(scenario_name+'.zip',), (scenario_name+'.tar.gz',), (scenario_name+'.jar',)]) # getting links links = get_export_links(handler, scenario_name_key, files) return links
def delete_bookmark(handler, name, scenario): cache = Cache(get_hostname(handler.request)) response = dict(version=version, data={}) result = cache.delete_saved_request_index(scenario, name) response['data'] = {'bookmark' : name, 'deleted' : result} return response
def __init__(self, host): Cache.__init__(self, host) self._hash = DummyHash()
def begin_session(handler, scenario_name, session_name, mode, system_date=None, warm_cache=False): """ Begins session for given scenario :param handler: request handler class :param scenario_name: scenario name :param session_name: session name :param mode: mode - record, playback :param system_date: :param warm_cache: :return: :raise exception_response: """ log.debug('begin_session') response = { 'version': version } scenario_manager = Scenario() cache = Cache(get_hostname(handler.request)) if cache.blacklisted(): raise exception_response(400, title="Sorry the host URL '{0}' has been " "blacklisted. Please contact Stub-O-Matic support.".format(cache.host)) # checking whether full name (with hostname) was passed, if not - getting full name # scenario_name_key = "localhost:scenario_1" if ":" not in scenario_name: scenario_name_key = cache.scenario_key_name(scenario_name) else: # setting scenario full name scenario_name_key = scenario_name # removing hostname from scenario name scenario_name = scenario_name.split(":")[1] # get scenario document scenario_doc = scenario_manager.get(scenario_name_key) if not scenario_doc: raise exception_response(404, title='Scenario not found - {0}. To begin a' ' session - create a scenario.'.format(scenario_name_key)) cache.assert_valid_session(scenario_name, session_name) if mode == 'record': log.debug('begin_session, mode=record') # check if there are any existing stubs in this scenario if scenario_manager.stub_count(scenario_name_key) > 0: err = exception_response(400, title='Scenario ({0}) has existing stubs, delete them before ' 'recording or create another scenario!'.format(scenario_name_key)) raise err scenario_id = scenario_doc['_id'] log.debug('new scenario: {0}'.format(scenario_id)) session_payload = { 'status': 'record', 'scenario': scenario_name_key, 'scenario_id': str(scenario_id), 'session': str(session_name) } cache.set_session(scenario_name, session_name, session_payload) log.debug('new redis session: {0}:{1}'.format(scenario_name_key, session_name)) response["data"] = { 'message': 'Record mode initiated....', } response["data"].update(session_payload) cache.set_session_map(scenario_name, session_name) log.debug('finish record') elif mode == 'playback': recordings = cache.get_sessions_status(scenario_name, status='record', local=False) if recordings: raise exception_response(400, title='Scenario recordings taking ' 'place - {0}. Found the ' 'following record sessions: {1}'.format(scenario_name_key, recordings)) cache.create_session_cache(scenario_name, session_name, system_date) if warm_cache: # iterate over stubs and call get/response for each stub matchers # to build the request & request_index cache # reset request_index to 0 log.debug("warm cache for session '{0}'".format(session_name)) scenario_manager = Scenario() for payload in scenario_manager.get_stubs(scenario_name_key): stub = Stub(payload['stub'], scenario_name_key) mock_request = " ".join(stub.contains_matchers()) handler.request.body = mock_request get_response(handler, session_name) cache.reset_request_index(scenario_name) response["data"] = { "message": "Playback mode initiated...." } response["data"].update({ "status": "playback", "scenario": scenario_name_key, "session": str(session_name) }) else: raise exception_response(400, title='Mode of playback or record required') return response