def run_commands(handler, cmds_text): response = {'version': version} host = get_hostname(handler.request) def get_links(cmd): cmd_uri = urlparse(cmd) links = [] if cmd_uri.path == 'get/export': scenario_name = cmd_uri.query.partition('=')[-1] scenario_name_key = '{0}:{1}'.format(host, scenario_name) files = [(scenario_name + '.zip', ), (scenario_name + '.tar.gz', ), (scenario_name + '.jar', )] links = get_export_links(handler, scenario_name_key, files) return links cmd_processor = StuboCommandFile(handler.request) cmds = cmd_processor.parse_commands(cmds_text) cmd_pairs = [(x, get_links(x)) for x in cmds if urlparse(x).path in form_input_cmds] if not cmd_pairs: raise exception_response(400, title='command/s not supported, must be ' 'one of these: {0}'.format(form_input_cmds)) cmds, _ = zip(*cmd_pairs) cmd_processor.run_cmds(cmds) response['data'] = {'executed_commands': cmd_pairs} 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 run_commands(handler, cmds_text): response = { 'version': version } host = get_hostname(handler.request) cmd_processor = TextCommandsImporter(UriLocation(handler.request)) cmds = cmd_processor.parse(cmds_text) if any(x for x in cmds if urlparse(x).path not in form_input_cmds): raise exception_response(400, title='command/s not supported, must be ' 'one of these: {0}'.format(form_input_cmds)) responses = cmd_processor.run_cmds(cmds) log.debug('responses: {0}'.format(responses)) response['data'] = { 'executed_commands': responses, 'number_of_requests': len(responses['commands']), 'number_of_errors': len([x for x in responses['commands'] if x[1] > 399]) } def get_links(cmd): cmd_uri = urlparse(cmd) scenario_name = cmd_uri.query.partition('=')[-1] scenario_name_key = '{0}:{1}'.format(host, scenario_name) files = [(scenario_name + '.zip',), (scenario_name + '.tar.gz',), (scenario_name + '.jar',)] links = get_export_links(handler, scenario_name_key, files) return links export_links = [(x, get_links(x)) for x in cmds if 'get/export' in x] if export_links: response['data']['export_links'] = export_links return response
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 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 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 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 run_commands(handler, cmds_text): response = {'version': version} host = get_hostname(handler.request) cmd_processor = TextCommandsImporter(UriLocation(handler.request)) cmds = cmd_processor.parse(cmds_text) if any(x for x in cmds if urlparse(x).path not in form_input_cmds): raise exception_response(400, title='command/s not supported, must be ' 'one of these: {0}'.format(form_input_cmds)) responses = cmd_processor.run_cmds(cmds) log.debug('responses: {0}'.format(responses)) response['data'] = { 'executed_commands': responses, 'number_of_requests': len(responses['commands']), 'number_of_errors': len([x for x in responses['commands'] if x[1] > 399]) } def get_links(cmd): cmd_uri = urlparse(cmd) scenario_name = cmd_uri.query.partition('=')[-1] scenario_name_key = '{0}:{1}'.format(host, scenario_name) files = [(scenario_name + '.zip', ), (scenario_name + '.tar.gz', ), (scenario_name + '.jar', )] links = get_export_links(handler, scenario_name_key, files) return links export_links = [(x, get_links(x)) for x in cmds if 'get/export' in x] if export_links: response['data']['export_links'] = export_links return response
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" 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 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 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 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 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 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 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 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_scenario_full_name(handler, name, host=None): """ Gets full name hostname:scenario_name :param name: :return: """ # check if hostname is supplied - if not, override scenario name with new value if ":" not in name: if host is None: host = get_hostname(handler.request) name = '%s:%s' % (host, name) return name
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_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 delete_stubs(handler, scenario_name=None, host=None, force=False): """delete all data relating to one named scenario or host/s.""" log.debug('delete_stubs') response = { 'version': version } scenario_db = Scenario() static_dir = handler.settings['static_path'] 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) scenarios = [] if scenario_name: # if scenario_name exists it takes priority handler.track.scenario = scenario_name hostname = host or get_hostname(handler.request) scenarios.append(':'.join([hostname, scenario_name])) elif host: if host == 'all': scenarios = [x['name'] for x in scenario_db.get_all()] export_dir = os.path.join(static_dir, 'exports') if os.path.exists(export_dir): log.info('delete export dir') shutil.rmtree(export_dir) else: # get all scenarios for host scenarios = [x['name'] for x in scenario_db.get_all( {'$regex': '{0}:.*'.format(host)})] else: raise exception_response(400, title='scenario or host argument required') for scenario_name_key in scenarios: delete_scenario(scenario_name_key, force) response['data'] = dict(message='stubs deleted.', scenarios=scenarios) return response
def delete_stubs(handler, scenario_name=None, host=None, force=False): """delete all data relating to one named scenario or host/s.""" log.debug('delete_stubs') response = {'version': version} scenario_db = Scenario() static_dir = handler.settings['static_path'] 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) scenarios = [] if scenario_name: # if scenario_name exists it takes priority handler.track.scenario = scenario_name hostname = host or get_hostname(handler.request) scenarios.append(':'.join([hostname, scenario_name])) elif host: if host == 'all': scenarios = [x['name'] for x in scenario_db.get_all()] export_dir = os.path.join(static_dir, 'exports') if os.path.exists(export_dir): log.info('delete export dir') shutil.rmtree(export_dir) else: # get all scenarios for host scenarios = [ x['name'] for x in scenario_db.get_all({'$regex': '{0}:.*'.format(host)}) ] else: raise exception_response(400, title='scenario or host argument required') for scenario_name_key in scenarios: delete_scenario(scenario_name_key, force) response['data'] = dict(message='stubs deleted.', scenarios=scenarios) return response
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_module(request, names): module = Module(get_hostname(request)) removed = [] for name in names: loaded_versions = [x for x in sys.modules.keys() if '{0}_v'.format(name) in x] for loaded in loaded_versions: module.remove_sys_module(loaded) if module.remove(name): removed.append('{0}:{1}'.format(module.host(), name)) return { 'version': version, 'data': {'message': 'delete modules: {0}'.format(names), 'deleted': removed} }
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 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 list_module(handler, names): module = Module(get_hostname(handler.request)) info = {} if not names: names = [x.rpartition(':')[-1] for x in get_keys( '{0}:modules:*'.format(module.host()))] for name in names: loaded_sys_versions = [x for x in sys.modules.keys() if '{0}_v'.format(name) in x] lastest_code_version = module.latest_version(name) info[name] = { 'latest_code_version': lastest_code_version, 'loaded_sys_versions': loaded_sys_versions } payload = dict(message='list modules', info=info) return { 'version': version, 'data': payload }
def list_module(handler, names): module = Module(get_hostname(handler.request)) info = {} if not names: names = [ x.rpartition(':')[-1] for x in get_keys('{0}:modules:*'.format(module.host())) ] for name in names: loaded_sys_versions = [x for x in sys.modules.keys() if \ '{0}_v'.format(name) in x] lastest_code_version = module.latest_version(name) info[name] = { 'latest_code_version': lastest_code_version, 'loaded_sys_versions': loaded_sys_versions } payload = dict(message='list modules', info=info) return {'version': version, 'data': payload}
def tracker_detail_request(handler, tracker_id): track_info = get_track(handler, tracker_id) error_message = "" if not track_info: error_message = "tracker record with id={0}, does not exist".format( tracker_id) scenario = track_info.get('scenario') _stub_count = stub_count(get_hostname(handler.request), scenario)['data'].get('count') tracking_data = track_info or {} trace = tracking_data.pop('trace', {}) return handler.render_string("tracker_record.html", page_title='Tracker Record', tracking_data=tracking_data, stub_count=_stub_count, error_message=error_message, pretty_format=pretty_format, client_data=convert_to_script(trace), human_size=human_size)
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 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 manage_request_api(handler): """ Generate data for /manage page. :param handler: instance of RequestHandler or TrackRequest :return: dictionary with information about stubo instance - modules, delays, sessions.. """ cache = Cache(get_hostname(handler.request)) action = handler.get_argument('action', None) all_hosts = asbool(handler.get_argument("all_hosts", False)) message = error_message = "" module_info = {} if action is not None: # handle btn action try: name = handler.get_argument('name') # It would be nice to really track these actions handler.track = DummyModel() if action == 'delete': _type = handler.get_argument('type') if _type == 'module': result = delete_module(handler.request, [name]) elif _type == 'delay_policy': result = delete_delay_policy(handler, [name]) elif _type == 'stubs': result = delete_stubs(handler, scenario_name=name, host=all_hosts) else: result = 'error: unexpected action type={0}'.format(_type) elif action == 'end_sessions': result = end_sessions(handler, name) else: result = 'error: unexpected action={0}'.format(action) if 'error' not in result: message = result else: error_message = result except MissingArgumentError, e: error_message = "Error: {0}".format(e) except StuboException, e: error_message = "Error: {0}".format(e.title)
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 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 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 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)
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 bookmarks_request_api(handler): hostname = get_hostname(handler.request) message = error_message = "" name = handler.get_argument('name', None) if name is not None: try: action = handler.get_argument('action', None) scenario = handler.get_argument('scenario', None) if action == 'delete': result = delete_bookmark(handler, name, scenario) if result['data']['deleted']: message = "deleted {0}".format(name) else: error_message = "Unable to delete bookmark '{0}', does "\ "it still exist?".format(name) elif action == 'jump': index = handler.get_argument('index', None) sessions = handler.get_arguments('session') if sessions: result = jump_bookmark(handler, name, sessions, index) if index: message = 'jumped to start' else: message = 'jumped to bookmark {0}'.format(name) message += ' for sessions "{0}"'.format( ", ".join(sessions)) else: error_message = "You must pick a session" else: # form POST to create a new bookmark if name: session = handler.get_argument('session', None) result = put_bookmark(handler, session, name) message = "created {0} bookmark".format(name) else: message = "You must supply a Name to create a new bookmark" except StuboException, e: error_message = "Error: {0}".format(e.title)
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 bookmarks_request_api(handler): hostname = get_hostname(handler.request) message = error_message = "" name = handler.get_argument('name', None) if name is not None: try: action = handler.get_argument('action', None) scenario = handler.get_argument('scenario', None) if action == 'delete': result = delete_bookmark(handler, name, scenario) if result['data']['deleted']: message = "deleted {0}".format(name) else: error_message = "Unable to delete bookmark '{0}', does "\ "it still exist?".format(name) elif action == 'jump': index = handler.get_argument('index', None) sessions = handler.get_arguments('session') if sessions: result = jump_bookmark(handler, name, sessions, index) if index: message = 'jumped to start' else: message = 'jumped to bookmark {0}'.format(name) message += ' for sessions "{0}"'.format(", ".join(sessions)) else: error_message = "You must pick a session" else: # form POST to create a new bookmark if name: session = handler.get_argument('session', None) result = put_bookmark(handler, session, name) message = "created {0} bookmark".format(name) else: message = "You must supply a Name to create a new bookmark" except StuboException, e: error_message = "Error: {0}".format(e.title)
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))
try: start = datetime.datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S') tracker_filter['start_time'] = {"$lt": start} except ValueError, e: raise exception_response(400, title='start_time format error: {0}'.format(e)) if scenario_filter: tracker_filter['scenario'] = {'$regex': scenario_filter} if session_filter: tracker_filter['request_params.session'] = {'$regex': session_filter} if show_only_errors: tracker_filter['return_code'] = {'$ne': 200} if latency: tracker_filter['duration_ms'] = {'$gt': latency} if not all_hosts: host = get_hostname(handler.request) tracker_filter['host'] = host if function != 'all': tracker_filter['function'] = function return tracker.find_tracker_data(tracker_filter, skip, limit) def get_track(request, tracker_id): tracker = Tracker() return tracker.find_tracker_data_full(tracker_id) def get_stats(handler): # cluster.host # "cluster1.ahost or cluster1.*", response = { 'version' : version }
def put_setting_request(handler): setting = handler.get_argument('setting') value = handler.get_argument('value') host = handler.get_argument('host', get_hostname(handler.request)) return put_setting(handler, setting, value, host)
def get_setting_request(handler): setting = handler.get_argument('setting', None) host = handler.get_argument('host', get_hostname(handler.request)) return get_setting(handler, host, setting)