def master_replica_discovery_rate_limiting(): master = RedisServer(address="127.0.0.1", port=1234) replica = RedisServer(unix_socket=REDIS_SOCKET_PATH, master=master) filter = Filter(filter_name='test', nb_threads=5) filter.configure(FTEST_CONF_TEMPLATE) filter.start() try: # success filter.send_single(REDIS_LIST_TRIGGER) except Exception as e: logging.error( "master_replica_discovery_rate_limiting: Could not connect to test filter: {}" .format(function_name, e)) return False # master shuts down master.stop() #brutal def thread_brute_time(filter, time_end): end = time() + time_end while time() < end: # accelerate throughput by avoiding constant calls to time() for i in range(0, 9): try: filter.send_single(REDIS_LIST_TRIGGER) except: return False return True thread_list = [] for num in range(0, 5): thread_list.append( threading.Thread(target=thread_brute_time, args=(filter, 9))) # ought to crash if command fails initial_connections_num = replica.connect().info( )['total_connections_received'] for thread in thread_list: thread.start() for thread in thread_list: thread.join() # new generated connections generated, minus the one generated by the call to get it new_connections = replica.connect().info( )['total_connections_received'] - initial_connections_num - 1 if new_connections > 10: logging.error( "master_replica_discovery_rate_limiting: Wrong number of new connection attempts, " + "was supposed to have 10 new at most, but got ".format( new_connections)) return False return True
def master_replica_transfer(function_name, healthcheck): master = RedisServer(address="127.0.0.1", port=1234) replica = RedisServer(address="127.0.0.1", port=1235, unix_socket=REDIS_SOCKET_PATH, master=master) filter = Filter(filter_name='test') filter.configure(FTEST_CONF_TEMPLATE) filter.valgrind_start() try: # success filter.send_single(REDIS_LIST_TRIGGER) except Exception as e: logging.error("{}: Could not connect to test filter: {}".format( function_name, e)) return False # master becomes replica with master.connect() as master_connection: master_connection.slaveof(replica.address, replica.port) #replica becomes master with replica.connect() as replica_connection: replica_connection.slaveof() sleep(1) if healthcheck: sleep(8) try: # success return_code = filter.send_single(REDIS_LIST_TRIGGER) except Exception as e: logging.error("{}: Could not connect to test filter: {}".format( function_name, e)) return False if return_code != 0: logging.error( "{}: Filter didn't return correct code, " + "waited for 0 but got {}".format(function_name, return_code)) return False with replica.connect() as new_master_connection: num_entries = new_master_connection.llen(REDIS_LIST_NAME) if num_entries != 2: logging.error("{}: Wrong number of entries in {}, " + "expected 2 but got {}".format( function_name, REDIS_LIST_NAME, num_entries)) return False return True
def simple_master_server(): master = RedisServer(unix_socket=REDIS_SOCKET_PATH) filter = Filter(filter_name='test') filter.configure(FTEST_CONF_TEMPLATE) filter.valgrind_start() try: filter.send_single(REDIS_LIST_TRIGGER) except Exception as e: logging.error( "simple_master_server: Could not connect to test filter: {}". format(e)) return False sleep(1) with master.connect() as redis_connection: num_list_entries = redis_connection.llen(REDIS_LIST_NAME) if num_list_entries != 1: logging.error( "simple_master_server: wrong number of entries in the redis list {}: " + "expected 1 but got {}".format(REDIS_LIST_NAME, str(num_list_entries))) return False return True
def master_replica_master_temp_fail(): master = RedisServer(address="127.0.0.1", port=1234) replica = RedisServer(address="127.0.0.1", unix_socket=REDIS_SOCKET_PATH, master=master) filter = Filter(filter_name='test') filter.configure(FTEST_CONF_TEMPLATE) filter.valgrind_start() try: # success filter.send_single(REDIS_LIST_TRIGGER) except Exception as e: logging.error( "master_replica_master_temp_fail: Could not connect to test filter: {}" .format(e)) return False master.stop() sleep(1) try: # failure filter.send_single(REDIS_LIST_TRIGGER) except Exception as e: logging.error( "master_replica_master_temp_fail: Could not connect to test filter: {}" .format(e)) return False sleep(1) if not filter.check_run(): logging.error( "master_replica_master_temp_fail: filter seems to have crashed when master Redis got offline" ) return False master.start() # rate limiting will prevent to reconnect immediately after failure, so there should have a wait # (rate limiting is not tested here) sleep(8) try: # success filter.send_single(REDIS_LIST_TRIGGER) except Exception as e: logging.error( "master_replica_master_temp_fail: Could not connect to test filter: {}" .format(e)) return False with master.connect() as master_connection: num_list_entries = master_connection.llen(REDIS_LIST_NAME) if num_list_entries != 1: logging.error( "master_replica_master_temp_fail: wrong number of entries in the redis list {}: " + "expected 1 but got {}".format(REDIS_LIST_NAME, num_list_entries)) return False return True
def file_and_redis_simple_report(): ret = False file_conf = """"file": {{"filepath": "{}"}},""".format(DEFAULT_STATS_FILE) redis_conf = """"redis": {{"ip": "127.0.0.1", "port": 7890, "channel": "{}", "list": "{}"}},""".format( DEFAULT_REDIS_CHANNEL, DEFAULT_REDIS_LIST) darwin_configure( CONF_TEMPLATE.substitute(log_path=DEFAULT_FILTER_PATH, conf_path=PATH_CONF_FLOGS, conf_redis=redis_conf, conf_file=file_conf, proc_stats="")) darwin_configure(CONF_FLOGS, path=PATH_CONF_FLOGS) redis_server = RedisServer(address="127.0.0.1", port=7890) redis_probe = redis_server.connect() redis_pubsub = redis_probe.pubsub(ignore_subscribe_messages=True) redis_pubsub.subscribe(DEFAULT_REDIS_CHANNEL) # Remove subscribe notification message sleep(0.1) redis_pubsub.get_message() process = darwin_start() try: with open(DEFAULT_STATS_FILE, "r") as statsfile: sleep(1) channel_message = redis_pubsub.get_message().get('data').decode( "utf-8") list_message = redis_probe.lpop(DEFAULT_REDIS_LIST).decode("utf-8") file_message = statsfile.readline() # File message has an additional '\n' if channel_message in file_message and list_message in file_message: if STAT_LOG_MATCH in file_message: ret = True else: logging.error( "file_and_redis_simple_report(): expected \"{}\", but got \"{}\"" .format(STAT_LOG_MATCH, file_message)) else: logging.error( "file_and_redis_simple_report(): messages are not identical" ) logging.error("file_and_redis_simple_report(): {}".format( channel_message)) logging.error( "file_and_redis_simple_report(): {}".format(list_message)) logging.error( "file_and_redis_simple_report(): {}".format(file_message)) except Exception as e: logging.error( "file_and_redis_simple_report(): could not open file -> {}".format( e)) try: os.remove(DEFAULT_STATS_FILE) except Exception: pass darwin_stop(process) darwin_remove_configuration() darwin_remove_configuration(path=PATH_CONF_FLOGS) return ret
def redis_reports(): ret = False part = 1 connections = [{ "name": "ip", "conf": "\"ip\": \"127.0.0.1\", \"port\": 7890", "partial_result": "" }, { "name": "ip_wrong_port", "conf": "\"ip\": \"127.0.0.1\", \"port\": 7891", "partial_result": "nodata" }, { "name": "ip_wrong_ip", "conf": "\"ip\": \"127.0.0.2\", \"port\": 7890", "partial_result": "nodata" }, { "name": "unix", "conf": "\"unix_path\": \"{}\"".format(DEFAULT_REDIS_SOCKET), "partial_result": "" }, { "name": "unix_wrong", "conf": "\"unix_path\": \"wrong_path\"", "partial_result": "nodata" }] report_methods = [ { "name": "list", "conf": "\"list\": \"{}\"".format(DEFAULT_REDIS_LIST), "partial_result": STAT_LOG_MATCH }, { "name": "channel", "conf": "\"channel\": \"{}\"".format(DEFAULT_REDIS_CHANNEL), "partial_result": STAT_LOG_MATCH }, ] for method in report_methods: for connection in connections: print("[{}/10]".format(part), end='', flush=True) redis_conf = "\"redis\": {{{connection}, {method}}},".format( connection=connection['conf'], method=method['conf']) expected_result = method['partial_result'] if connection[ 'partial_result'] == "" else connection['partial_result'] darwin_configure( CONF_TEMPLATE.substitute(log_path=DEFAULT_FILTER_PATH, conf_path=PATH_CONF_FLOGS, conf_redis=redis_conf, conf_file="", proc_stats="")) darwin_configure(CONF_FLOGS, path=PATH_CONF_FLOGS) redis_server = RedisServer(unix_socket=DEFAULT_REDIS_SOCKET, address="127.0.0.1", port=7890) redis_probe = redis_server.connect() process = darwin_start() if method['name'] == "channel": redis_pubsub = redis_probe.pubsub( ignore_subscribe_messages=True) redis_pubsub.subscribe(DEFAULT_REDIS_CHANNEL) # Remove subscribe notification message sleep(0.1) redis_pubsub.get_message() sleep(1) message = redis_pubsub.get_message() try: message = str(message['data']) except Exception: message = "nodata" elif method['name'] == "list": sleep(1) message = redis_probe.lpop(DEFAULT_REDIS_LIST) if not message: message = "nodata" else: message = str(message) ret = True if expected_result in message else False if not ret: logging.error( "redis_reports(): while trying '{}' with '{}', didn't find '{}' in '{}'" .format(method['conf'], connection['conf'], expected_result, message)) del redis_server del message darwin_stop(process) darwin_remove_configuration() darwin_remove_configuration(path=PATH_CONF_FLOGS) # Don't judge me... part += 1 print("\x08\x08\x08\x08\x08\x08", end='', flush=True) if not ret: break if not ret: break # Dirty much... But pretty printing! if part == 11: print("\x08", end='', flush=True) print(" ", end='', flush=True) print("\x08\x08\x08\x08\x08\x08\x08", end='', flush=True) return ret