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 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