Esempio n. 1
0
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)
Esempio n. 3
0
    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)
Esempio n. 4
0
    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)
Esempio n. 5
0
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)
Esempio n. 6
0
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
Esempio n. 7
0
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
Esempio n. 8
0
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   
Esempio n. 9
0
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
Esempio n. 10
0
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
Esempio n. 11
0
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
Esempio n. 12
0
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
Esempio n. 13
0
    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)
Esempio n. 14
0
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
Esempio n. 15
0
 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)
Esempio n. 16
0
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
Esempio n. 17
0
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
Esempio n. 18
0
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
Esempio n. 19
0
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
Esempio n. 20
0
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                         
Esempio n. 21
0
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    
Esempio n. 22
0
    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)
Esempio n. 23
0
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
Esempio n. 24
0
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
Esempio n. 25
0
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
Esempio n. 26
0
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
Esempio n. 27
0
 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)
Esempio n. 28
0
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   
Esempio n. 29
0
    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)
Esempio n. 30
0
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))
Esempio n. 31
0
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))
Esempio n. 32
0
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
Esempio n. 33
0
    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)
Esempio n. 34
0
    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)
Esempio n. 35
0
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)
Esempio n. 36
0
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
Esempio n. 37
0
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
Esempio n. 38
0
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
Esempio n. 39
0
    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))
Esempio n. 40
0
    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))
Esempio n. 41
0
    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)
Esempio n. 42
0
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
Esempio n. 43
0
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
Esempio n. 44
0
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 
Esempio n. 45
0
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)
Esempio n. 46
0
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
Esempio n. 47
0
    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))
Esempio n. 48
0
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
Esempio n. 49
0
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
Esempio n. 50
0
    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)
Esempio n. 51
0
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
Esempio n. 52
0
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  
Esempio n. 53
0
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))
Esempio n. 54
0
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
Esempio n. 55
0
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
Esempio n. 56
0
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            
Esempio n. 57
0
 def __init__(self, host):
     Cache.__init__(self, host)
     self._hash =  DummyHash()
Esempio n. 58
0
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