def stored_procedure( script_name, *args ): try: sha = REDIS.get( 'lua_function:%s' % script_name ) return REDIS.evalsha( sha, len(args), *args ) except Exception as err: LOG.debug( '%s failed to run stored procedure, with error %s and args %s' % (script_name, str(err), str(args)) ) return str(err)
def create_comment(self, app_url, access_token, message): LOG.info("create_comment") request_headers = build_request_headers(access_token) payload = {"text": message} LOG.debug(f"Request payload: {payload}") response = SESSION.post(f"{app_url}{self.comment_url}/", headers=request_headers, params=payload) return response
def test_reverse_string_other_data_types_raise_value_error(input): LOG.info( f"test_reverse_string_other_data_types_raise_value_error({ input })") with pytest.raises(TypeError) as error_info: reverse_string(input) exception_actual = error_info.value LOG.debug(exception_actual) exception_expected = f"reverse_string() expects a string but got a { type(input) }" assert str(exception_actual) == exception_expected
def test_read_file(tmpdir): LOG.info("test_read_file()") file_contents = "a\nab\nabc\nabcd\nabcde" expected = file_contents.split() # create temp file for testing test_file = tmpdir.join("test_file.txt") test_file.write(file_contents) # read temp file actual = read_file(test_file) LOG.debug(actual) assert actual == expected
def login(self, app_url, username, password): LOG.info("login") request_headers = { "Content-Type": "application/x-www-form-urlencoded", "accept": "application/json" } payload = {"username": username, "password": password} LOG.debug(f"Request payload: {payload}") response = SESSION.post(f"{app_url}{self.auth_url}/login", headers=request_headers, data=payload) return response
def update_northbound_handler(session): try: event = get_element('event', session, data_type=str) if (event == 'CONNECTION_REQUEST' and session['client_id'] in RPCS.Northbound_Queue): # Northbridge session is waiting for a response, # return 'error' via stream socket to communicate CPE disconnection result = 'error' session['nb_response_stream'].send(result.encode()) except KeyError: LOG.debug( "Event is CONNECTION_REQUEST but Northbound session was not found!" )
def build_request_headers(access_token, accept_type="application/json", **kwargs): LOG.info("build_request_headers") headers = { "Authorization": f"Bearer {access_token}", "accept": accept_type } if "content_type" in kwargs: headers["Content-Type"] = kwargs["content_type"] LOG.debug(f"Request headers: {headers}") return headers
def handle_response(self, session, message): """ Process the return from the set RPC an error response is already handled """ result = misc.get_element('result', message) if result == 0: LOG.debug("Response to 'set': Success") pass elif result == 1: LOG.debug("Response to 'set': Error") pass else: # Unknown result raise ClientMethodException('handle response', 'RpcSet')
def update_comment(self, app_url, access_token, comment_id, **kwargs): LOG.info("update_comment") request_headers = build_request_headers(access_token, content_type="application/json") payload = {} if "message" in kwargs: payload["comment_text"] = kwargs["message"] if "likes" in kwargs: payload["likes"] = kwargs["likes"] LOG.debug(f"Request payload: {payload}") response = SESSION.put(f"{app_url}{self.comment_url}/{comment_id}", headers=request_headers, json=payload) return response
def create_user(self, app_url, access_token, username, password, role="user"): LOG.info("create_user") request_headers = build_request_headers( access_token, content_type="application/json") payload = { "username": username, "password_hash": password, "roles": role } LOG.debug(f"Request payload: {payload}") response = SESSION.post(f"{app_url}{self.user_url}", headers=request_headers, json=payload) return response
def test_cud_comment(login_as_admin): LOG.info("test_cud_comment") response = Comments().create_comment(APP_URL, login_as_admin, "first post") assert response.ok response_data = response.json() comment_id = response_data["id"] LOG.debug(response_data) assert response_data["comment_text"] == "first post" response = Comments().update_comment(APP_URL, login_as_admin, comment_id, message="updated to second post", likes=3) assert response.ok response_data = response.json() LOG.debug(response_data) assert response_data["comment_text"] == "updated to second post" assert response_data["likes"] == 3 response = Comments().delete_comment(APP_URL, login_as_admin, comment_id) assert response.ok response_data = response.json() LOG.debug(response_data) assert response_data["detail"] == f"Deleted comment {comment_id}"
def mock_file_directory(tmpdir_factory): mock_file_dir = tmpdir_factory.mktemp("files") # create text file per challenge example abcde_txt = mock_file_dir.join("abcde.txt") abcde_txt.write("a\nab\nabc\nabcd\nabcde") # challenge example in random order abcde_random_txt = mock_file_dir.join("abcde_random.txt") abcde_random_txt.write("abc\nabcde\nab\na\nabcd ") # separated by other whitespace characters abcde_whitespace_txt = mock_file_dir.join("abcde_whitespace.txt") abcde_whitespace_txt.write("a ab \tabc\f abcd \rabcde") # restricted permission file (unsuccessful) # restricted_txt = mock_file_dir.join("restricted.txt") # restricted_txt.write("This file should not be accessible.\n") # restricting the permissions on this file did not successfully trigger the PermissionError on read # os.chmod(restricted_txt, 400) LOG.debug(f"Created mock file directory at { mock_file_dir }") return mock_file_dir
def test_read_file_bad_filepath(mock_file_directory): LOG.info("test_read_file_bad_filepath()") file = os.path.join(mock_file_directory, "badfilepath.txt") with pytest.raises(FileNotFoundError) as e: read_file(file) LOG.debug(e)
def send_request(self, session): # Each class that inherits should have its own implementation of the # "prepare_request" method LOG.debug("Sending RPC for %s" % self.__class__.__name__) self.prepare_request(session) return prepare_rpc(session, self.method, self.rpc_params)
def __init__(self, operation, client_method): self.operation = operation self.client_method = client_method LOG.debug("Error: %s of %s client method" % (self.operation, self.client_method))
def test_get_longest_word_incorrect_types(words, wrong_type_element): LOG.info(f"test_get_longest_word_incorrect_types({ wrong_type_element })") with pytest.raises(TypeError) as ve: longest = get_longest_word(words) error_msg = ve.value.args[0] LOG.debug(error_msg)
def test_get_all_comments(login_as_admin): LOG.info("test_get_all_comments") response = Comments().get_all_comments(APP_URL, login_as_admin) LOG.debug(response.json()) assert response.ok
def session_handler(reader, writer): """ This is a call back routine for an SSL session Read messages from the device, handle them and write the responses """ # initialize defaults session = { 'queue': [], 'rpc': { 'id': 0 }, 'cpe': {}, 'dm': {}, 'rtwan_layer3_keep': False, 'voice_layer3_keep': False } # start authentication of client state = RPCS.Authenticating state = state.prepare_session(writer, session) try: LOG.debug("Open connection with: %s", session['cpe']['ip']) # RPC SERVER while state in RPCS.RPC_SERVER_STATES: response = None request = yield from asyncio.wait_for(reader.readline(), timeout=RPCSD_TIMEOUT) if reader.at_eof(): # Received disconnect signal from CPE update_northbound_handler(session) session['log'] = { 'rc': 'error', 'msg': 'Connection terminated by client' } LOG.debug("CPE closed connection with RPC Server") break session['rpc']['message'] = parse_message(request, 'request') # Respond with error to invalid requests, when possible if 'error' in session['rpc']['message']: if session['rpc']['message']['error'] is not None: response = session['rpc']['message'] # Handle message and move between states else: state, response = state.run(session) # Prepare and send response if not (response is None): LOG.debug("Message to cpe: " + str(response)) send_rpc(response, writer) # RPC CLIENT while state in RPCS.RPC_CLIENT_STATES: request = None rpc = None # Only listen for messages during 'ExpectResponse' state if state == RPCS.ExpectResponse: request = yield from asyncio.wait_for(reader.readline(), timeout=RPCSD_TIMEOUT) if reader.at_eof(): # Received disconnect signal from CPE update_northbound_handler(session) session['log'] = { 'rc': 'error', 'msg': 'Connection terminated by client' } LOG.debug("CPE closed connection with RPC Server") break session['rpc']['message'] = parse_message(request, 'response') # Either check if there are RPCs in queue to send, or handle CPE # response state, rpc = state.run(session) if rpc is not None: LOG.debug("Message to cpe: " + str(rpc)) send_rpc(rpc, writer) except asyncio.TimeoutError: LOG.debug("CPE connection timed out") # Write an error to the database session['log'] = {'rc': 'error', 'msg': 'Connection timeout'} reader.feed_eof() except ConnectionResetError: LOG.debug("CPE closed the connection with RPC Server") session['log'] = {'rc': 'error', 'msg': 'Connection reset by peer'} reader.feed_eof() except Exception: # Catch everything else, prevents daemon from crashing err = sys.exc_info()[0] traceback.print_exc() LOG.error("Internal server error: %s", err) reader.feed_eof() finally: # Make sure session is always closed tidily even if an error occurs if 'db' in session: log_to_database(session) session['db'].disconnect() writer.close() # Get any response left and throw away while not (reader.at_eof()): yield from reader.read() LOG.debug("Close connection with: %s", session['cpe']['ip']) # Running a forceful full garbage collection collected = gc.collect() LOG.debug("Unreachable objects after forceful garbage collection: %d", collected)
import os.path import glob from config import LOG, REDIS # load all the lua scripts into redis # storing keys and sha's LOG.info( "loading stored procedures" ) for script in glob.glob( os.path.join( 'lua', '*.lua' ) ): try: script_code = open( script, "r" ).read() script_name, script_type = os.path.splitext( script ) script_name = os.path.basename( script_name ) REDIS.set( 'lua_function:%s' % script_name, REDIS.register_script( script_code ).sha ) LOG.debug( 'loaded %s' % script_name ) except Exception as err: LOG.debug( '%s failed to load, with error %s' % (script_name, str(err)) ) def pairs_to_dictionary( array ): result = {} if len( array ) % 2 != 0: response = array.pop() if type( response ) == list: while len( response ) > 0: key = response.pop(0) value = response.pop(0) result[ key ] = value if len( array ) > 0: for key, value in pairs_to_dictionary([array]).iteritems(): if value > 0:
def parse_message(message, message_type): """ Parse a JSON request and return a message in python dictionary format Input values: request - RPC request from CPE message_type - Type of incoming message - Request or Response Return values: result - Either succesfully parsed message or described error """ # Check for valid JSON message error = None session_message = {} LOG.debug("Message from CPE:" + str(message)) try: parsed = json.loads(message.decode()) message_jsonrpc = get_element('jsonrpc', parsed) message_id = get_element('id', parsed) message_method = get_element('method', parsed) message_result = get_element('result', parsed) message_params = get_element('params', parsed) if message_jsonrpc != '2.0': # TODO create error code mapping error = { 'error': { 'code': -32600, 'message': 'Invalid request: ' 'Wrong version of JSON-RPC' } } # If method is done, id must be None. Otherwise, it must be an integer if not isinstance(message_id, int) and not message_method == 'done': # TODO create error code mapping error = { 'error': { 'code': -32600, 'message': 'Invalid request: ID field is ' 'not an integer' } } if message_type == 'request': # If it is a request and method is not valid if not (message_method in RPCS.VALID_METHODS): # TODO create error code mapping error = { 'error': { 'code': -32601, 'message': 'Method not found' } } elif message_type == 'response': # If response has no result, it is an error response if message_result is None: if 'error' in parsed: error = parsed else: # TODO create error code mapping error = { 'error': { 'code': -32600, 'message': 'Invalid request: Response message ' 'with no result field' } } # Otherwise we need to parse its result field else: error = parse_result(message_result) if error is None: session_message['jsonrpc'] = message_jsonrpc session_message['id'] = message_id session_message['method'] = message_method session_message['result'] = message_result session_message['params'] = message_params return session_message else: error['id'] = message_id LOG.debug(str(error)) return error except Exception as e: LOG.debug("Error during parsing CPE message: %s", e) error = {'error': {'code': -32700, 'message': 'Parse error'}} return error
def test_get_txt_files_in_directory(mock_file_directory): LOG.info("test_get_txt_files_in_directory()") files = get_txt_files_in_directory(mock_file_directory) for file in files: LOG.debug(file)
def test_reverse_string_other_languages(input): LOG.info(f"test_reverse_string_other_languages(\"{ input }\")") expected = "".join(reversed(input)) actual = reverse_string(input) LOG.debug(f"input: { input }, reversed: {actual}") assert expected == actual
def test_login(): LOG.info("test_login") response = Auth().login(APP_URL, ADMIN_USER, ADMIN_PASSWORD) LOG.debug(response.json()) assert response.ok