def update_request(request_id):
    """
        Description : View function for Request Updation
        
    """
    form_data = request.json if request.json else request.form
    if form_data.get('request') and form_data.get('response'):
        # clean_previous_requests, to keep the logic simple
        # we delete all the details of this request group
        # and re-generate them using the details present in post request
        session.query(HttpSubResponse).filter(HttpSubResponse.request_id==request_id).delete()
        session.query(HttpSubRequest).filter(HttpSubRequest.request_id==request_id).delete()
        session.commit()
        request_info_dict = format_request_details(form_data) 
        new_request_insert([request_info_dict], True)
        session.commit()
        response_data = { 
                      'post_response': { 
                            'response_text': 'Data have beed saved successfully'
                       }
                    }
        resp = make_response(jsonify(response_data), 200)
    else:
        response_data = {'error': "unknown request"}
        resp = make_response(jsonify(response_data), 400)
    return resp
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 prepare_client_connection(epoll, client_connections_info, client_requests, client_responses, test_id, request_id=None):
    """
        Description: Prepares the client connection for sending the request
        
        input_param: epoll - poll for the client sockets
        input_type: epoll instance
        input_param: client_connections_info - Client connection information dictionary
        input_type: dict
        input_param: client_requests  - Client requests information dictionary
        input_type: dict
        input_param: client_requests  - Client response information dictionary
        input_type: dict
        input_param: test_id - Test Unit Id
        input_type: int
        input_param: request_id - Unique Request Id
        input_type: int
        
        out_param: 
        out_type: 
        
        sample output:
        
    """
    client_socket = creat_socket()
    new_client_no = client_socket.fileno()
    next_request_info = get_next_request(test_id, request_id)
    if not next_request_info.get('id'):
        return
    request_row = session.query(HttpRequest).filter(HttpRequest.id==int(next_request_info['id'])).first()
    if request_id:
        remaining_requests = session.query(HttpTestResults)\
                                .filter(HttpTestResults.test_id==test_id)\
                                .filter(HttpTestResults.request_id==int(next_request_info['id']))\
                                .filter(HttpTestResults.is_completed==False)\
                                .filter(HttpTestResults.is_running==False).count()
        request_info = {
                    'tot_requests_per_connection' : request_row.total_requests,
                    'remaining_requests' : remaining_requests,
                    'last_accessed_time' : datetime.datetime.now(),
                    'request_id': request_id,
                    'socket': client_socket
                }
    else:
        request_info = {
                    'tot_requests_per_connection' : request_row.total_requests,
                    'remaining_requests' : request_row.total_requests,
                    'last_accessed_time' : datetime.datetime.now(),
                    'request_id': next_request_info['id'],
                    'socket': client_socket
                }
    client_connections_info[new_client_no] = request_info
    client_requests[new_client_no] = intialize_client_request_info(next_request_info['data']) # change the 1 to category id
    client_responses[new_client_no] = intialize_client_response_info()
    connect_with_server(client_connections_info[new_client_no]['socket'], SERVER_HOST, SERVER_PORT)
    register_socket_epoll_event(epoll, new_client_no, select.EPOLLOUT)
    client_connections_info[new_client_no]['remaining_requests'] = client_connections_info[new_client_no]['remaining_requests'] - 1
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
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 get_search_data():
    """
        Description : Constructs the SQL search query based on the
                      given form data
        
        input_param :
        input_type :
        
        out_param : tests - mached HttpTest rows
        out_type : HttpTest
       
    """
    tests = []
    form_data = request.json if request.json else request.form
    query = session.query(HttpTest)
    if form_data.get('test_name'):
        query = query.filter( HttpTest.name==form_data.get('test_name') )
    if form_data.get('user_name'):
        query = query.filter( HttpTest.scheduled_by==form_data.get('user_name') )
    if form_data.get('category_ids'):
        query = query.filter( HttpTest.category_id.in_(form_data.get('category_ids') ))

    for test in query.all():
        tests.append(format_test_data(test))
    return tests
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 handle_client_timer(client_connections_info, epoll, test_id, idle_time_out=60):
    """
        Description: Handles the client sockets timer. 
                    when the socket in idle for some duration
                    then closes that socket

        input_param:
        input_type:

        out_param:
        out_type:
        
        sample output:

    """
    while True:
        try:
            now = datetime.datetime.now()    
            for fileno in client_connections_info.keys():
                if int((now-client_connections_info[fileno]['last_accessed_time']).total_seconds()) >= idle_time_out:
                    logger.warning("Timout reached for the socket in client side " + str(fileno))
                    modify_socket_epoll_event(epoll, fileno, 0)
                    client_connections_info[fileno]['socket'].shutdown(socket.SHUT_RDWR)
            test = session.query(HttpTest).get(test_id)
            if test and test.completed:
                logger.debug("Test completed, so exiting the timer thread : Test ID : " + str(test_id) ) 
                break
            time.sleep(int(idle_time_out/2))
        except Exception as e:
            logger.exception(" Error in Client Time Thread : " + str(e) )
            raise
def load_all_tests():
    """
        Description : View function to render all the test details
        
    """
    tests = [ format_test_data(test)    for test in session.query(HttpTest).all() ]
    response_data = { 'form' : render_template('all_test_status.html'),
                          'response_data' : {'tests': tests}
                          }
    resp = make_response(jsonify(response_data), 200)
    return resp
def load_all_requests(request_id=None):
    """
        Description : View function to render all the Request details
        
    """
    if not request_id:
        requests = [ format_main_details_data(request_details) 
                        for request_details in session.query(
                            HttpRequest).all() 
                   ]
        response_data = { 'form' : render_template('all_requests.html'),
                          'response_data' : {'requests': requests}
                          }
        resp = make_response(jsonify(response_data), 200)
        return resp
    else:
        show_request = session.query(HttpRequest).get(request_id)
        sub_request_query = session.query(HttpSubRequest
                               ).filter(HttpSubRequest.request_id==request_id)

        if request.method == 'GET':
            response_data = {  
                             'form' : render_template('request_details.html'),
                             'response_data' : {'request_details': {}}
                        }
            if show_request:
                response_data.update({  'form' : render_template('request_details.html'),
                                      'response_data' : {
                                            'main_details': format_main_details_data(show_request),
                                            'sub_request_details': [ format_sub_request_data(sub_request)
                                                for sub_request in sub_request_query ],
                                       }
                               })
            response_data.get('response_data', {}).update(get_static_datas())
            resp = make_response(jsonify(response_data), 200)
            return resp
def load_testcase_details(test_id=0):
    """
        Description : View function for loading the specific test case details
        
    """
    test_result_type = request.args.get('test_result_type', True)
    query = session.query(HttpTestResults)
    if test_result_type:
        print test_result_type
        query = query.filter(and_(HttpTestResults.request_result==test_result_type, HttpTestResults.response_result==test_result_type))
    else:
        print test_result_type
        query = query.filter(or_(HttpTestResults.request_result==test_result_type, HttpTestResults.response_result==test_result_type))
    test_cases = [ format_test_case_data(testcase) for testcase in query.all() ]
    response_data = {  'form' : render_template('test_details.html'),
                        'response_data' : {'testcase_details': test_cases}
            }
    resp = make_response(jsonify(response_data), 200)
    return resp
def load_test_details(test_id=0):
    """
        Description : View function for loading the specific test details
        
    """
    test = session.query(HttpTest).get(test_id)
    if request.method == 'GET':
        response_data = {  'form' : render_template('test_details.html'),
                              'response_data' : {'test_details': {}}
                        }
        if test:
            response_data['response_data']['test_details'] = format_test_data(test)
        resp = make_response(jsonify(response_data), 200)
        return resp
    else:
        form_data = request.json if request.json else request.form
        test.paused = form_data.get('pause')
        test.running = not form_data.get('pause')
        session.commit()
        response_data = { 'post_response': { 'test_details' : format_test_data(test) }}
        resp = make_response(jsonify(response_data), 200)
        return resp
def start_http_clients(test_id):
    """
        Description: Client HTTP Test start function
        
        input_param:
        input_type:
        
        out_param:
        out_type:
        
        sample output: 
    """
    client_connections_info = {}
    client_requests = {}
    client_responses = {}
    epoll = create_epoll()
    
    parallel_clients = 10
    
    tot_test_requests = session.query(HttpRequest).filter(HttpRequest.category_id==1).count()
    
    # Limit the parallel clients to maximum of 10
    parallel_clients = parallel_clients if parallel_clients <= 10 else 10

    # Limit the parallel clients greater than total requests.
    # Limit it to total requests
    parallel_clients = tot_test_requests if parallel_clients > tot_test_requests else parallel_clients
    
    for i in range(0,parallel_clients):
        prepare_client_connection(epoll, client_connections_info, client_requests, client_responses, test_id)
    
    # Start the client timer thread
    http_client_timer = HTTPClientTimer(client_connections_info, epoll, test_id=test_id, idle_time_out=60)
    http_client_timer.start()
    handle_client_socket_events(test_id, epoll, client_connections_info, client_requests, client_responses)
    
    # Wait for timer thread to complete
    http_client_timer.join()
    HttpSubRequest,
)
from db_tables.http_tests import HttpTest, HttpTestResults, HttpServerTestFailureReason, HttpClientTestFailureReason
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:
            
            out_param:
            out_type:
            
            sample output:
        """
        logger.debug("Starting the server Thread")
        start_http_server()

if __name__ == "__main__":
    http_server = HTTPServer()

    http_server.start()
    time.sleep(2)
    while True:
        try:
            tot_running_tests = session.query(HttpTest).filter(HttpTest.running==True).count()
            if tot_running_tests < MAX_CONCURRENT_TESTS and not os.path.isfile("dont_run"):
                new_test = session.query(HttpTest).filter(HttpTest.running==False)\
                            .filter(HttpTest.completed==False).first()
                if new_test:
                    http_clients = HTTPClient(new_test.id)
                    http_clients.start()
                    new_test.running=True
                    #http_clients.join()
                    time.sleep(2)
            time.sleep(10)
        except Exception as e:
            logger.exception("Exception in Main thread " + str(e) )
    http_server.join()
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 ''
def get_next_request(test_id=0, request_id=None):
    """
        Description: Gets the next request data for the client
        
        input_param: test_id - Test Id of the client running test
        input_type: int
        
        out_param: request_data - Request data as a string
        out_type: String
        
        sample output: "GET /test HTTP/1.1\r\nConnection:Close\r\n\r\n"
        
    """

    # Find the Request Ids that is already running    
    running_request_ids = [ test_result.request_id for test_result in session.query(HttpTestResults.request_id) \
                            .filter(HttpTestResults.test_id==test_id)\
                            .filter(HttpTestResults.is_running==True)\
                            .filter(HttpTestResults.is_completed==False)\
                            .order_by(HttpTestResults.request_id).all() ]
                        
    next_test_result_row_query = session.query(HttpTestResults) \
                        .filter(HttpTestResults.test_id==test_id)\
                        .filter(HttpTestResults.is_running==False)\
                        .filter(HttpTestResults.is_completed==False)
    if running_request_ids:
        next_test_result_row_query = next_test_result_row_query.filter(not_(HttpTestResults.request_id.in_(running_request_ids)))
    
    # If Request Id is given, we need to return the sub request 
    # for the given request Id
    if request_id:
        next_test_result_row_query = session.query(HttpTestResults)\
                                    .filter(HttpTestResults.test_id==test_id)\
                                    .filter(HttpTestResults.request_id==request_id)\
                                    .filter(HttpTestResults.is_running==False)\
                                    .filter(HttpTestResults.is_completed==False)
    
    next_test_result_row = next_test_result_row_query.order_by(HttpTestResults.request_id).first()
    if not next_test_result_row:
        logger.debug("All the requests are completed\n")
        return {}
    
    next_sub_request = session.query(HttpSubRequest)\
                    .filter(\
                            and_(HttpSubRequest.request_id==next_test_result_row.request_id, \
                                HttpSubRequest.id==next_test_result_row.sub_request_id
                            )
                    ).first()
    request_data = next_sub_request.method.method_name + " "
    request_data = request_data + "/" + str(test_id) + "/" + str(next_sub_request.request_id)
    request_data = request_data + " HTTP/" 
    request_data = request_data + next_sub_request.version + "\r\n"
    for request_header in next_sub_request.request_hdrs:
        request_data = request_data + request_header.header_name + ":" 
        value_list = eval(request_header.client_value)
        if request_header.single_value_hdr:
            request_data = request_data + value_list[0]+ "\r\n"
        else:
            request_data = request_data + ";".join(value_list) + "\r\n"
    if next_sub_request.data_id:
        request_data = request_data + "Content-Length:" + len(next_sub_request.data.data)
        request_data = request_data + "\r\n"
        request_data = request_data + next_sub_request.data.data
    else:
        request_data = request_data + "\r\n"
    
    next_test_result_row.is_running=True
    session.commit()
    logger.debug("Next Request : %s\r\n", request_data)
    return {'data': request_data,
            'id': next_test_result_row.request_id
            }
def search_test():
    """
        Description : View function to handle search URL
        
    """
    if request.method == 'GET':
        data ={'categories': [ {'id': category[0], 'name': category[1] } for category in session.query(HttpRequestCategory.id, HttpRequestCategory.category_name).all()]}
        response_data = { 'form' : render_template('search_test.html'),
                          'response_data' : data
                            }
        resp = make_response(jsonify(response_data), 200)
        return resp
    else:
        response_data = { 'form' : render_template('all_test_status.html'),
                            'post_response' : {'tests': get_search_data()}
            }
        resp = make_response(jsonify(response_data), 200)
        return resp
def get_static_datas():
    """
        Description : Gets details of the static tables
        
        out_param : formatted static table data
        out_type : dict
        
    """
    return {
         'categories' : [ 
                          {'id': category[0], 
                           'name': category[1] 
                          } for category in session.query(
                            HttpRequestCategory.id, 
                            HttpRequestCategory.category_name
                          ).all()
                        ],
         'methods' : [
                       {'id': method[0],
                           'name': method[1]
                          } for method in session.query(
                            HttpRequestMethods.id,
                            HttpRequestMethods.method_name
                         ).all()
											],
         'codes' : [
                       {'id': code[0],
                           'name': code[1]
                          } for code in session.query(
                            HttpResponseCodes.id,
                            HttpResponseCodes.code_name
                         ).all()
          ],
          'request_headers': [
                       { 'id': request_hdr.id,
                         'name': request_hdr.header_name,
                         'value': request_hdr.client_value
                       } for request_hdr in session.query(
                         HttpRequestHeaders.id,
                         HttpRequestHeaders.header_name,
                         HttpRequestHeaders.client_value
                        ).all()
          ],
          'request_verify_headers': [
                       { 'id': request_hdr.id,
                         'name': request_hdr.header_name,
                         'value': request_hdr.proxy_value
                       } for request_hdr in session.query(
                         HttpResponseHeaders.id,
                         HttpResponseHeaders.header_name,
                         HttpResponseHeaders.proxy_value
                        ).all()
          ],
          'response_headers': [
                       { 'id': response_hdr.id,
                         'name': response_hdr.header_name,
                         'value': response_hdr.server_value
                       } for response_hdr in session.query(
                         HttpResponseHeaders.id,
                         HttpResponseHeaders.header_name,
                         HttpResponseHeaders.server_value
                        ).all()
          ],
          'response_verify_headers': [
                       { 'id': response_hdr.id,
                         'name': response_hdr.header_name,
                         'value': response_hdr.proxy_value
                       } for response_hdr in session.query(
                         HttpRequestHeaders.id,
                         HttpRequestHeaders.header_name,
                         HttpRequestHeaders.proxy_value
                        ).all()
          ]
    }
def new_test():
    """
        Description : View function for the scheduling new tests
        
    """
    if request.method == 'GET':
        data ={'categories': [ {'id': category[0], 'name': category[1] } for category in session.query(HttpRequestCategory.id, HttpRequestCategory.category_name).all()]}
        response_data = { 'form' : render_template('schedule_new_test.html'),
                              'response_data' : data
                                }
        resp = make_response(jsonify(response_data), 200)

        return resp
    else:
        form_data = request.json if request.json else request.form
        load_test_args = { 'name' : form_data.get('test_name'),
                            'description' : form_data.get('description'),
                            'scheduled_by' : form_data.get('user_name'),
                            'category_id' : form_data.get('category_id')
                        }
        test_id = load_tests(**load_test_args)
        response_text = """Your test has been added in the que with <b>Id : {0}.</b> <br>
                        Please refer the staus of the test in the 
                        status page with the test id""".format(test_id)
        response_data = { 'post_response': { 'test_id' : 1, 'response_text': response_text}}
        resp = make_response(jsonify(response_data), 200)
        return resp
def handle_client_socket_events(test_id, epoll, client_connections_info, client_requests, client_responses):
    """
        Description: Handles all the events happens in client side sockets
        
        input_param: epoll - Epoll listener bucket for the client socket
        input_type: epoll
        
        out_param:
        out_type:
        
        sample output: None
    """
    try:
        while True:
            parallel_clients = len(client_connections_info.keys())
            if parallel_clients == 0:
                logger.debug("Test Completed Id : " + str(test_id))
                test = session.query(HttpTest).get(test_id)
                test.completed=True
                test.running=False
                test.completed_time=datetime.datetime.now()
                session.commit()
                break
            events = epoll.poll(parallel_clients)
            for fileno, event in events:
                conn_info = client_connections_info[fileno]
                resp_info = client_responses[fileno]
                req_info = client_requests[fileno]
                conn_info['last_accessed_time'] = datetime.datetime.now()
                if event & select.EPOLLERR:
                    logger.error("EPOLL ERROR in client response handling")
                if event & select.EPOLLIN:
                    new_data = None
                    read_err = None
                    # Receive the response from server
                    if resp_info['resp_start'] or resp_info['rem_bytes_to_read']:
                        new_data = read_data(client_connections_info[fileno]['socket'])
                        # If any read failure happens
                        if not new_data:
                            logger.error("Read failed so closing the socket\n")
                            read_err = True
                            resp_info['rem_bytes_to_read'] = 1
                            modify_socket_epoll_event(epoll, fileno, 0)
                            shut_down_socket(conn_info['socket'])
                        # Before receiving the all response headers
                        if new_data and not resp_info.get('full_header_received'):
                            resp_info['resp_start'] = False
                            resp_info['header_data'] = resp_info['header_data'] + new_data
                            if resp_info['header_data'].find(EOL1) != -1 or resp_info['header_data'].find(EOL2) != -1:
                                logger.debug("Full Header Received\n")
                                client_responses[fileno] = handle_server_response_data(resp_info)
                                resp_info = client_responses[fileno]
                                resp_info['full_header_received'] = True
                        # After receiving the all the response headers
                        # And when the response data is not chunked
                        elif new_data and resp_info.get('full_header_received') and not resp_info['is_chunked']:
                            resp_info['received_bytes'] = resp_info['received_bytes'] + len(new_data)
                            resp_info['rem_bytes_to_read'] = resp_info['rem_bytes_to_read'] - len(new_data)
                            resp_info['data'] = resp_info['data'] + new_data
                    # Once all response is received, verify the data
                    if not resp_info['rem_bytes_to_read'] and not read_err:
                        logger.info('-'*40 + '\n' + resp_info['header_data'])
                        logger.info(resp_info['data'])
                        verify_server_response(req_info, resp_info)
                        # For a non-persistent connection
                        if resp_info['not_persistent']:
                            logger.debug("Not Persistent Connection, So closing it\n")
                            modify_socket_epoll_event(epoll, fileno, 0)
                            shut_down_socket(conn_info['socket'])
                        else:
                            # For persistent connection, if there is any 
                            # sub-requests pending. Re-set the previous request, response dats
                            if conn_info['remaining_requests']:
                                logger.debug("Starting new request in persistent connection\n")
                                modify_socket_epoll_event(epoll, fileno, select.EPOLLOUT)
                                next_request_info = get_next_request(test_id, conn_info['request_id'])
                                conn_info['remaining_requests'] = conn_info['remaining_requests'] - 1
                                client_requests[fileno] = intialize_client_request_info(next_request_info['data'])
                                client_responses[fileno] = intialize_client_response_info()
                            else:
                                # For new request set, start the request sending in 
                                # already opened persistent connection
                                logger.debug("All Sub Request have completed for the request " + (conn_info['request_id']))
                                next_request_info = get_next_request(test_id)
                                # If any request set is pending for the test, start it
                                if next_request_info.get('id'):
                                    logger.debug("Opening New Request in persistent Connection \n")
                                    request_info = session.query(HttpRequest).filter(HttpRequest.id==int(next_request_info['id'])).first()
                                    conn_info['tot_requests_per_connection'] = request_info.total_requests
                                    conn_info['remaining_requests'] = request_info.total_requests
                                    conn_info['last_accessed_time'] = datetime.datetime.now(),
                                    conn_info['request_id'] =  next_request_info['id']
                                    client_requests[fileno] = intialize_client_request_info(next_request_info['data']) # change the 1 to category id
                                    client_responses[fileno] = intialize_client_response_info()
                                    client_connections_info[fileno]['remaining_requests'] = client_connections_info[new_client_no]['remaining_requests'] - 1
                                    modify_socket_epoll_event(epoll, fileno, select.EPOLLOUT)
                                else:
                                    # If there is not any request for test, close the connection
                                    modify_socket_epoll_event(epoll, fileno, 0)
                                    shut_down_socket(conn_info['socket'])
                elif event & select.EPOLLOUT:
                    # Send the Request to server
                    if req_info.get('rem_bytes_to_send'):
                        tot_sent = req_info['sent_bytes']
                        tot_sent = tot_sent + send_data(conn_info['socket'], req_info['request_data'][tot_sent:])
                        req_info['sent_bytes'] = tot_sent
                        req_info['rem_bytes_to_send'] = req_info['tot_bytes_to_send'] - req_info['sent_bytes']
                    else:
                        modify_socket_epoll_event(epoll, fileno, select.EPOLLIN)
                elif event & select.EPOLLHUP:
                    logger.warning("EPOLLHUP from client\n")
                    set_test_completion(test_id, conn_info['request_id'])
                    # If there is any remaining sub-request on closing socket
                    # open the new socket and assign closing socket's
                    # request set properties to it.
                    if conn_info['remaining_requests']:
                        prepare_client_connection(epoll, client_connections_info, client_requests, client_responses, test_id, conn_info['request_id'])
                    else:
                        prepare_client_connection(epoll, client_connections_info, client_requests, client_responses, test_id)
                    close_socket(epoll, fileno, client_connections_info)
                    del client_requests[fileno]
                    del client_responses[fileno]
    except:
        epoll.close()
        raise
)

static_data_routes = Module(__name__, url_prefix="/static", name="static_data_routes")

# Mapper for the static data
static_data_mapper ={
    '1' :{
        'name' : 'Response Codes',
        'data' : lambda: [
                   {
                    'id': row.id,
                    'name': row.code_name,
                    'is_active': row.is_active
                   } for row in session.query(
                          HttpResponseCodes.id,
                          HttpResponseCodes.code_name,
                          HttpResponseCodes.is_active
                     ).all()
                 ],
        'column_names' : ['Id', 'Code Name', 'Active'],
        'form' : 'static_single_value.html',
        'post_url': '/static/codes/update'
    },
    '2' :{
        'name' : 'Request Methods',
        'data' : lambda: [
                   {
                    'id': row.id,
                    'name': row.method_name,
                    'is_active': row.is_active
                   } for row in session.query(