Esempio n. 1
0
def begin_session(handler,
                  scenario_name,
                  session_name,
                  mode,
                  system_date=None,
                  warm_cache=False):
    log.debug('begin_session')
    response = {'version': version}
    scenario_col = 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))
    scenario_name_key = cache.scenario_key_name(scenario_name)
    scenario = scenario_col.get(scenario_name_key)
    cache.assert_valid_session(scenario_name, session_name)
    if mode == 'record':
        log.debug('begin_session, mode=record')
        # precond: delete/stubs?scenario={scenario_name}
        if scenario:
            err = exception_response(
                400,
                title='Duplicate scenario found - {0}'.format(
                    scenario_name_key))
            raise err
        if scenario_col.stub_count(scenario_name_key) != 0:
            raise exception_response(
                500,
                title='stub_count !=0 for scenario: {0}'.format(
                    scenario_name_key))
        scenario_id = scenario_col.insert(name=scenario_name_key)
        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':
        if not scenario:
            raise exception_response(
                400,
                title='Scenario not found - {0}'.format(scenario_name_key))
        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_col = Scenario()
            for payload in scenario_col.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
Esempio n. 2
0
def get_response(handler, session_name):
    request = handler.request
    stubo_request = StuboRequest(request)
    request_body = stubo_request.request_body()
    if not request_body:
        # TODO: not an error if they match on other attrs
        raise exception_response(400, title='No text in body')
    cache = Cache(get_hostname(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))
    scenario_key = cache.find_scenario_key(session_name)
    scenario_name = scenario_key.partition(':')[-1]
    handler.track.scenario = scenario_name
    request_id = compute_hash(request_body)
    module_system_date = handler.get_argument('system_date', None)
    url_args = handler.track.request_params
    if not module_system_date:
        # BA LEGACY
        module_system_date = handler.get_argument('stubbedSystemDate', None)
    trace_matcher = TrackTrace(handler.track, 'matcher')
    user_cache = handler.settings['ext_cache']
    # check cached requests
    cached_request = cache.get_request(scenario_name, session_name, request_id)
    if cached_request:
        response_ids, delay_policy_name, recorded, system_date, module_info, request_index_key = cached_request
    else:
        retry_count = 5 if handler.settings.get('is_cluster', False) else 1
        session, retries = cache.get_session_with_delay(
            scenario_name,
            session_name,
            retry_count=retry_count,
            retry_interval=1)
        if retries > 0:
            log.warn("replication was slow for session: {0} {1}, it took {2} "\
              "secs!".format(scenario_key, session_name, retries+1))
        if session['status'] != 'playback':
            raise exception_response(
                500,
                title='cache status != playback. session={0}'.format(session))

        system_date = session['system_date']
        if not system_date:
            raise exception_response(
                500,
                title="slave session {0} not available for scenario {1}".
                format(session_name, scenario_key))

        session['ext_cache'] = user_cache
        results = match(stubo_request,
                        session,
                        trace_matcher,
                        as_date(system_date),
                        url_args=url_args,
                        hooks=handler.settings['hooks'],
                        module_system_date=module_system_date)
        # 0 is best match
        hits_info, stub = results[0]
        log.debug(u'match result: (hits_info={0}, stub={1})'.format(
            hits_info, stub.payload))
        hits, stub_number = hits_info
        if not hits:
            raise exception_response(400,
                                     title='E017:No matching response found')
        response_ids = stub.response_ids()
        delay_policy_name = stub.delay_policy_name()
        recorded = stub.recorded()
        module_info = stub.module()
        request_index_key = add_request(
            session, request_id, stub, system_date, stub_number,
            handler.settings['request_cache_limit'])
        if not stub.response_body():
            stub.set_response_body(
                stub.get_response_body_from_cache(request_index_key))
        if delay_policy_name:
            stub.load_delay_from_cache(delay_policy_name)

    if cached_request:
        stub = StubCache({}, scenario_key, session_name)
        stub.load_from_cache(response_ids, delay_policy_name, recorded,
                             system_date, module_info, request_index_key)
    trace_response = TrackTrace(handler.track, 'response')
    if module_info:
        trace_response.info('module used', str(module_info))
    response_text = stub.response_body()
    if not response_text:
        raise exception_response(
            500,
            title='Unable to find response in '
            'cache using session: {0}:{1}, response_ids: {2}'.format(
                scenario_key, session_name, response_ids))

    # get latest delay policy
    delay_policy = stub.delay_policy()
    if delay_policy:
        delay = calculate_delay(delay_policy)
        if delay:
            msg = 'apply delay: {0} => {1}'.format(delay_policy, delay)
            log.debug(msg)
            handler.track['delay'] = delay
            trace_response.info(msg)

    trace_response.info('found response')
    module_system_date = as_date(module_system_date) if module_system_date \
        else module_system_date
    stub, _ = transform(stub,
                        stubo_request,
                        module_system_date=module_system_date,
                        system_date=as_date(system_date),
                        function='get/response',
                        cache=user_cache,
                        hooks=handler.settings['hooks'],
                        stage='response',
                        trace=trace_response,
                        url_args=url_args)
    transfomed_response_text = stub.response_body()[0]
    # Note transformed_response_text can be encoded in utf8
    if response_text[0] != transfomed_response_text:
        trace_response.diff('response:transformed',
                            dict(response=response_text[0]),
                            dict(response=transfomed_response_text))

    return transfomed_response_text
Esempio n. 3
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
Esempio n. 4
0
def begin_session(handler, scenario_name, session_name, mode, system_date=None,
                  warm_cache=False):
    log.debug('begin_session')
    response = {
        'version' : version
    }
    scenario_col = 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))
    scenario_name_key = cache.scenario_key_name(scenario_name)
    scenario = scenario_col.get(scenario_name_key) 
    cache.assert_valid_session(scenario_name, session_name)      
    if mode == 'record':
        log.debug('begin_session, mode=record')
        # precond: delete/stubs?scenario={scenario_name} 
        if scenario:
            err = exception_response(400, 
              title='Duplicate scenario found - {0}'.format(scenario_name_key))
            raise err
        if scenario_col.stub_count(scenario_name_key) != 0:
            raise exception_response(500, 
              title='stub_count !=0 for scenario: {0}'.format(
                                                            scenario_name_key))
        scenario_id = scenario_col.insert(name=scenario_name_key)
        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':
        if not scenario:
            raise exception_response(400,
              title='Scenario not found - {0}'.format(scenario_name_key))
        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_col = Scenario()
            for payload in scenario_col.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
Esempio n. 5
0
def get_response(handler, session_name):
    request = handler.request
    stubo_request = StuboRequest(request)
    cache = Cache(get_hostname(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))
    scenario_key = cache.find_scenario_key(session_name)  
    scenario_name = scenario_key.partition(':')[-1] 
    handler.track.scenario = scenario_name   
    request_id = stubo_request.id()
    module_system_date = handler.get_argument('system_date', None)
    url_args = handler.track.request_params
    if not module_system_date:
        # LEGACY
        module_system_date = handler.get_argument('stubbedSystemDate', None)
    trace_matcher = TrackTrace(handler.track, 'matcher')
    user_cache = handler.settings['ext_cache']
    # check cached requests
    cached_request = cache.get_request(scenario_name, session_name, request_id)
    if cached_request:
        response_ids, delay_policy_name, recorded, system_date, module_info, request_index_key = cached_request
    else: 
        retry_count = 5 if handler.settings.get('is_cluster', False) else 1 
        session, retries = cache.get_session_with_delay(scenario_name, 
                                                        session_name,
                                                        retry_count=retry_count,
                                                        retry_interval=1)
        if retries > 0:
            log.warn("replication was slow for session: {0} {1}, it took {2} "\
              "secs!".format(scenario_key, session_name, retries+1))
        if session['status'] != 'playback':
            raise exception_response(500, 
                title='cache status != playback. session={0}'.format(session))
            
        system_date = session['system_date'] 
        if not system_date:
            raise exception_response(500,
                title="slave session {0} not available for scenario {1}".format(
                session_name, scenario_key))          
                
        session['ext_cache'] = user_cache   
        result = match(stubo_request, session, trace_matcher,
                       as_date(system_date),
                       url_args=url_args,
                       hooks=handler.settings['hooks'],
                       module_system_date=module_system_date)
        if not result[0]:
            raise exception_response(400, 
                                     title='E017:No matching response found')
        _, stub_number, stub = result    
        response_ids = stub.response_ids()
        delay_policy_name = stub.delay_policy_name() 
        recorded = stub.recorded()
        module_info = stub.module()    
        request_index_key = add_request(session, request_id, stub, system_date,
                                        stub_number,
                                        handler.settings['request_cache_limit'])
      
        if not stub.response_body():
            _response = stub.get_response_from_cache(request_index_key)
            stub.set_response_body(_response['body'])
       
        if delay_policy_name:    
            stub.load_delay_from_cache(delay_policy_name)     
        
    if cached_request:
        stub = StubCache({}, scenario_key, session_name)
        stub.load_from_cache(response_ids, delay_policy_name, recorded, 
                             system_date, module_info, request_index_key)   
    trace_response = TrackTrace(handler.track, 'response')
    if module_info:
        trace_response.info('module used', str(module_info))        
    response_text = stub.response_body()
    if not response_text:
        raise exception_response(500, title='Unable to find response in '
             'cache using session: {0}:{1}, response_ids: {2}'.format(
              scenario_key, session_name, response_ids))
    
    # get latest delay policy
    delay_policy = stub.delay_policy()
    if delay_policy:
        delay = Delay.parse_args(delay_policy)
        if delay:
            delay = delay.calculate()
            msg = 'apply delay: {0} => {1}'.format(delay_policy, delay)
            log.debug(msg) 
            handler.track['delay'] = delay 
            trace_response.info(msg)
               
    trace_response.info('found response') 
    module_system_date = as_date(module_system_date) if module_system_date \
        else module_system_date      
    stub, _ = transform(stub, 
                        stubo_request,
                        module_system_date=module_system_date, 
                        system_date=as_date(system_date),
                        function='get/response',
                        cache=user_cache,
                        hooks=handler.settings['hooks'],
                        stage='response',
                        trace=trace_response,
                        url_args=url_args)
    transfomed_response_text = stub.response_body()[0]   
    # Note transformed_response_text can be encoded in utf8
    if response_text[0] != transfomed_response_text:
        trace_response.diff('response:transformed',
                            dict(response=response_text[0]),
                            dict(response=transfomed_response_text)) 
    if stub.response_status() != 200:
        handler.set_status(stub.response_status())
    if stub.response_headers():     
        for k, v in stub.response_headers().iteritems():
            handler.set_header(k, v)                                     
    return transfomed_response_text
Esempio n. 6
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