def get_response(request_uri=None):
    """
        Description: Gets the next response data for the server
        
        input_param: request_uri - Request Uri present in client request
        input_type: string
        
        out_param: response_data - Response data as a string
        out_type: String
        
        sample output: "HTTP/1.1 200 OK\r\nConnection:Close\r\n\r\n"
        
    """

    
    if not request_uri:
        return {}
    test_id, req_id = [ int(parts) for parts in request_uri.strip().split("/")[:3] if len(parts) ]
    running_test_row = session.query(HttpTestResults)\
                    .filter(HttpTestResults.test_id==test_id)\
                    .filter(HttpTestResults.request_id==req_id)\
                    .filter(HttpTestResults.is_running==True).first()
    if running_test_row and running_test_row.sub_response_id:
        sub_response = session.query(HttpSubResponse).get(running_test_row.sub_response_id)
        if not sub_response:
            failure_data = "Proxy sent one extra request. The Request should have been served from cache"
            server_failure_reason = HttpServerTestFailureReason(reason=failure_data)
            session.add(server_failure_reason)
            session.flush()
            running_test_row.request_result=False
            running_test_row.server_failure_id = server_failure_reason.id
            session.commit()
            return "HTTP/1.1 404 Not Found\r\nConnection:Close\r\nContent-Length:0\r\n\r\n"
    else:
        failure_data = "Proxy sent one extra request. The Request should have been served from cache"
        server_failure_reason = HttpServerTestFailureReason(reason=failure_data)
        session.add(server_failure_reason)
        session.flush()
        running_test_row.request_result=False
        running_test_row.server_failure_id = server_failure_reason.id
        session.commit()
        return "HTTP/1.1 404 Not Found\r\nConnection:Close\r\nContent-Length:0\r\n\r\n"
    
    response_data = "HTTP/" + sub_response.version + " "
    response_data = response_data + sub_response.response_code.code_name + "\r\n"
    for response_header in sub_response.response_hdrs:
        response_data = response_data + response_header.header_name + ":"
        value_list = eval(response_header.server_value)
        if response_header.single_value_hdr:
            response_data = response_data + value_list[0]+ "\r\n"
        else:
            response_data = response_data + + ";".join(value_list) + "\r\n"
    if sub_response.data_id:
        response_data = response_data + "Content-Length:" + str( len(sub_response.data.data) )
        response_data = response_data + "\r\n\r\n"
        response_data = response_data + sub_response.data.data
    else:
        response_data = response_data + "Content-Length:0\r\n\r\n"
    logger.debug("Response From Server : " + response_data)
    return str(response_data)
def update_change_item(items, mapper, attr_map):
    """
        Description : For given static data types, updates all the details
                      if present, and creates objects in the db it 
                      is not present
        input_param : items - details that need to updated to the static data
        input_type : list of dicts
        
        input_param : mapper name of the static table
        input_type : class
        
        input_param : attr_map - details the attribute map between form 
                       data and class attribute
        input_type : dict
 
    """
    edit_ids = [ item.get('id') for item in items ]
    db_objects = session.query(
                                 mapper
                               ).filter(
                                    mapper.id.in_(edit_ids)
                               ).all()
    for form_item in items: 
        if form_item.get('id') == 0:
            db_object = mapper()
            for key, attr_name in attr_map.iteritems():
                if attr_name != 'id':
                    setattr(db_object, attr_name, form_item.get(key))
                    session.add(db_object)
        else:
            for db_object in db_objects:
                if db_object.id == form_item.get('id'):
                    for key, attr_name in attr_map.iteritems():
                        setattr(db_object, attr_name, form_item.get(key))
def set_test_completion(test_id, req_id):
    """
        Description: Before closing the socket, verify the closing socket requested
                        completed successfuly or not
        
        input_param: test_id - Test Id of the given test
        input_type: int
        
        out_param: req_id - Request Id of the closing socket
        out_type:  int
        
        sample output : None
        
    """
    running_test_row = session.query(HttpTestResults)\
                    .filter(HttpTestResults.test_id==test_id)\
                    .filter(HttpTestResults.request_id==req_id)\
                    .filter(HttpTestResults.is_running==True)\
                    .filter(HttpTestResults.is_completed==False).first()
    if running_test_row:
        reason = "Unexpected Event Happened in while receiving client response"
        client_failure_reason = HttpClientTestFailureReason(reason=reason)
        session.add(client_failure_reason)
        session.flush()
        running_test_row.response_result=False
        running_test_row.client_failure_id = client_failure_reason.id
        running_test_row.is_completed=True
        running_test_row.is_running=False
        session.commit()
def verify_server_response(req_info, resp_info):
    """
        Description: Verifies the Server response for 
                    1. Expected status line
                    2. Response Header
                    3. Data checksum if present
                and inserts the result in respective tables
    
        input_param: req_info - Request information Dictionary
        input_type:  dict
        
        out_param: resp_info - Response information Dictionary
        out_type:  dict
        
        sample output : None
    """
    result = True
    result_reason = {'error':""}
    if req_info.get('uri'):
        test_id, req_id = [ int(parts) \
                                for parts in req_info.get('uri').strip().split("/")[:3] \
                                if len(parts) ]
        running_test_row = session.query(HttpTestResults)\
                    .filter(HttpTestResults.test_id==test_id)\
                    .filter(HttpTestResults.request_id==req_id)\
                    .filter(HttpTestResults.is_running==True)\
                    .filter(HttpTestResults.is_completed==False).first()
        if running_test_row:
            verification_details = session.query(HttpResponseVerification)\
                                    .filter(HttpResponseVerification.request_id==running_test_row.request_id)\
                                    .filter(HttpResponseVerification.sub_request_id==running_test_row.sub_request_id).first()
            if verification_details:
                status_line = "HTTP/" + verification_details.version + " " + verification_details.http_response_codes.code_name
                header_verification_result = verify_headers(verification_details.response_hdrs, resp_info, result_reason)
                if resp_info.get('status_line') == status_line and header_verification_result:
                    if verification_details.data_id:
                        if verification_details.http_data.cksum != find_checksum(resp_info['data']):  
                            result=False
                            result_reason['error'] = "CheckSum differes between expected and calculated from Response"
                else:
                    if not result_reason['error']:
                        result_reason['error'] = "Expected Status Line:" + status_line 
                        result_reason['error'] = result_reason['error'] + " Does not Match with response: " + resp_info.get('status_line')
                    result=False
            running_test_row.is_completed=True
            running_test_row.is_running=False
            if not result:
                client_failure_reason = HttpClientTestFailureReason(reason=result_reason['error'])
                session.add(client_failure_reason)
                session.flush()
                running_test_row.response_result=False
                running_test_row.client_failure_id = client_failure_reason.id
            else:
                running_test_row.response_result=True
            session.commit()
def load_tests(name, 
                description,
                scheduled_by,
            category_id):
    """
        Description: Inserts the new record in the global Test Table
                        and copies the new tests requires into HttpTestResults
                        Table
        
        input_param: category_id - Test Type Id ( minor, major, critical)
        input_type: int
        
        out_param: test_id - Newly inserted test primary Id
        out_type: int
        
        sample output : 1
        
    """
    
    test_id = 0
    new_test = HttpTest(name=name, description=description, category_id=category_id, scheduled_by=scheduled_by)
    session.add(new_test)
    session.flush()
    session.commit()
    
    test_id = new_test.id
    
    requests = session.query(HttpRequest).filter(HttpRequest.category_id==category_id).all()
    for request in requests:
        sub_requests = session.query(HttpSubRequest).filter(HttpSubRequest.request_id==request.id).all()
        for sub_request in sub_requests:
            http_sub_response = session.query(HttpSubResponse).filter(HttpSubResponse.request_id==request.id).filter(HttpSubResponse.sub_request_id==sub_request.id).first()
            http_test = HttpTestResults(test_id=test_id,
                                request_id=request.id,
                                sub_request_id=sub_request.id,
                                response_id= http_sub_response.response_id if http_sub_response else None,
                                sub_response_id= http_sub_response.id if http_sub_response else None,
                                request_result=None,
                                response_result=None,
                                is_running=False,
                                is_completed=False,
                                server_failure_id=None,
                                client_failure_id=None,
                                no_of_times=1
                        )
                
            session.add(http_test)
    session.commit()
    return test_id
from db_tables.http_verification import HttpResponseVerification, HttpRequestVerification
import hashlib

methods = [
    {"id": 1, "method_name": "OPTIONS", "is_active": True},
    {"id": 2, "method_name": "HEAD", "is_active": True},
    {"id": 3, "method_name": "GET", "is_active": True},
    {"id": 4, "method_name": "POST", "is_active": True},
    {"id": 5, "method_name": "DELETE", "is_active": True},
]

for method in methods:
    result = session.query(HttpRequestMethods).filter(HttpRequestMethods.id == method["id"]).first()
    if not result:
        new_item = HttpRequestMethods(**method)
        session.add(new_item)

request_headers = [
    {
        "id": 1,
        "header_name": "Connection",
        "client_value": "['Keep-Alive']",
        "proxy_value": "['Keep-Alive', 'Close']",
        "single_value_hdr": True,
        "is_active": True,
    }
]
for request_header in request_headers:
    result = session.query(HttpRequestHeaders).filter(HttpRequestHeaders.id == request_header["id"]).first()
    if not result:
        new_item = HttpRequestHeaders(**request_header)
def new_request_insert(http_details, update=None):
    """
        Description: Inserts the new record in the Request/Response
                     RequestVerification/ResponseVerification tables
        
        input_param: http_details - list of dictionary contains information
                                    for the new request details
        input_type: list
        
    """
    new_request = None
    for details in http_details:
         request = details.get('request')
         request_details = details.get('request_details')
         response_verifications = details.get('response_verification')
     
         response = details.get('response')
         response_details = details.get('response_details')
         request_verifications = details.get('request_verification')
     
         if request:
             if not update:
                 new_request = HttpRequest(**request)
                 session.add(new_request)
                 session.flush()
                 new_response = HttpResponse(request_id=new_request.id, **response)
                 session.add(new_response)
                 session.flush()
             else:
                  new_request = session.query(HttpRequest).get(request['id'])
                  new_request.is_active = True
                  new_request.pipe_line = False
                  new_request.category_id = request['category_id']
                  new_request.description = request['description']
                  new_request.total_request = request['total_requests']
                  new_response = session.query(HttpResponse).get(response['id'])
                  new_response.pipe_line = False
                  new_response.description = response['description']
                  new_response.total_response = response['total_response']
                  new_response.is_active = True
                  session.commit()
     
             if request_details:
                 all_requests = [ HttpSubRequest(request_id=new_request.id, 
                                      **request_detail ) 
                                  for request_detail in request_details 
                                ]
                 session.add_all(all_requests)
                 session.flush()
                 
                 response_index = 0
                 all_responses = [
                         HttpSubResponse(request_id=new_request.id, 
                                     response_id=new_response.id,
                                     sub_request_id=request.id, 
                                     **response_details[response_index])
                         for response_index, request in enumerate(all_requests)
                            if request.reach_server and response_details[response_index]
                     ]
                 session.add_all(all_responses)
                 session.flush()
     
                 if response_verifications:
                     all_response_verification = [ HttpResponseVerification(
                                                    request_id=new_request.id,
                                                    sub_request_id=all_requests[index].id,
                                                     **response_verification)
                      for index, response_verification in enumerate(response_verifications)
                        if response_verification
                     ]
                     session.add_all(all_response_verification)
                     session.flush()
                
                 if request_verifications:
                     all_request_verification = []
                     index = 0
                     for request_verification in request_verifications:
                         if request_verification and all_requests[index].reach_server:
                             all_request_verification.append(HttpRequestVerification(
                                                   request_id=new_request.id, 
                                                   sub_request_id=all_responses[index].sub_request_id,
                                                   sub_response_id=all_responses[index].id,
                                                   **request_verification)
                             )
                             index = index + 1
                     session.add_all(all_request_verification)
                     session.flush()
    return new_request.id if new_request else ''