def get_parsed(msg, only_incoming=None, only_outgoing=None): # To conform to the Recorder interface assert only_incoming is None assert only_outgoing is None n_msgs, c_msgs = msg.split(CombinedRecorder.separator) n_msgs = n_msgs.lstrip(CombinedRecorder.n_prefix) c_msgs = c_msgs.lstrip(CombinedRecorder.c_prefix) return [Recorder.get_parsed(n_msgs) if n_msgs else [], Recorder.get_parsed(c_msgs) if c_msgs else []]
def test_recorder_get_next_incoming_only(recorder): incoming_count = 100 incoming = [(randomString(100), randomString(6)) for _ in range(incoming_count)] while incoming: recorder.add_incoming(*incoming.pop()) time.sleep(random.choice([0, 1]) + random.random()) recorded_incomings = OrderedDict() keys = [] for k, v in recorder.store.iterator(include_value=True): v = Recorder.get_parsed(v) keys.append(int(k)) recorded_incomings[int(k)] = v assert len(recorded_incomings) == incoming_count assert sorted(keys) == keys max_time_to_run = incoming_count * 2 + 10 recorder.start_playing() start = time.perf_counter() while recorder.is_playing and (time.perf_counter() < start + max_time_to_run): vals = recorder.get_next() if vals: check = recorded_incomings.popitem(last=False)[1] assert check == vals else: time.sleep(0.01) assert len(recorded_incomings) == 0 assert not recorder.is_playing
def patch_sent_prepreapres(replaying_node, node_recorder): sent_pps = {} def add_preprepare(msg): inst_id, v, p = msg[f.INST_ID.nm], msg[f.VIEW_NO.nm], msg[ f.PP_SEQ_NO.nm] if inst_id not in sent_pps: sent_pps[inst_id] = {} sent_pps[inst_id][v, p] = [ msg[f.PP_TIME.nm], [l for l in msg[f.REQ_IDR.nm]], msg[f.DISCARDED.nm], ] msg_count = 0 min_msg_time = sys.maxsize max_msg_time = -1 for k, v in node_recorder.store.iterator(include_value=True): max_msg_time = max(max_msg_time, int(k)) min_msg_time = min(min_msg_time, int(k)) parsed = Recorder.get_parsed(v.decode()) msg_count += len(parsed) outgoings = Recorder.filter_outgoing(parsed) if not outgoings: continue for out in outgoings: try: msg = json.loads(out[0]) if isinstance(msg, dict) and OP_FIELD_NAME in msg: op_name = msg[OP_FIELD_NAME] if op_name == PREPREPARE: add_preprepare(msg) elif op_name == BATCH: for m in msg['messages']: try: m = json.loads(m) if m[OP_FIELD_NAME] == PREPREPARE: add_preprepare(m) except json.JSONDecodeError: continue else: continue except json.JSONDecodeError: continue for r in replaying_node.replicas.values(): r.sent_pps = sent_pps.pop(r.instId, {}) replaying_node.sent_pps = sent_pps replaying_node.replay_msg_count = msg_count run_time = max_msg_time - min_msg_time run_time = int(run_time / Recorder.TIME_FACTOR) print("Aprox run time: {}".format(str( datetime.timedelta(seconds=run_time))))
def patch_sent_prepreapres(replaying_node, node_recorder): sent_pps = {} def add_preprepare(msg): inst_id, v, p = msg[f.INST_ID.nm], msg[f.VIEW_NO.nm], msg[ f.PP_SEQ_NO.nm] if inst_id not in sent_pps: sent_pps[inst_id] = {} sent_pps[inst_id][v, p] = [msg[f.PP_TIME.nm], [l for l in msg[f.REQ_IDR.nm]], msg[f.DISCARDED.nm], ] msg_count = 0 min_msg_time = sys.maxsize max_msg_time = -1 for k, v in node_recorder.store.iterator(include_value=True): max_msg_time = max(max_msg_time, int(k)) min_msg_time = min(min_msg_time, int(k)) parsed = Recorder.get_parsed(v.decode()) msg_count += len(parsed) outgoings = Recorder.filter_outgoing(parsed) if not outgoings: continue for out in outgoings: try: msg = json.loads(out[0]) if isinstance(msg, dict) and OP_FIELD_NAME in msg: op_name = msg[OP_FIELD_NAME] if op_name == PREPREPARE: add_preprepare(msg) elif op_name == BATCH: for m in msg['messages']: try: m = json.loads(m) if m[OP_FIELD_NAME] == PREPREPARE: add_preprepare(m) except json.JSONDecodeError: continue else: continue except json.JSONDecodeError: continue for r in replaying_node.replicas.values(): r.sent_pps = sent_pps.pop(r.instId, {}) replaying_node.sent_pps = sent_pps replaying_node.replay_msg_count = msg_count run_time = max_msg_time - min_msg_time run_time = int(run_time / Recorder.TIME_FACTOR) print("Aprox run time: {}".format(str(datetime.timedelta(seconds=run_time))))
def test_recorded_parsings(recorder): incoming = [[randomString(10), randomString(6)] for i in range(3)] outgoing = [[randomString(10), randomString(6)] for i in range(5)] for m, f in incoming: recorder.add_incoming(m, f) time.sleep(0.01) for m, f in outgoing: recorder.add_outgoing(m, f) time.sleep(0.01) with pytest.raises(AssertionError): recorder.get_parsed(incoming[0], only_incoming=True, only_outgoing=True) combined = incoming + outgoing def sublist(lst1, lst2): ls1 = [element for element in lst1 if element in lst2] ls2 = [element for element in lst2 if element in lst1] return ls1 == ls2 for k, v in recorder.store.iterator(include_value=True): p = Recorder.get_parsed(v) assert sublist([i[1:] for i in p] , combined) p = Recorder.get_parsed(v, only_incoming=True) if p: assert sublist(p, incoming) for i in p: incoming.remove(i) p = Recorder.get_parsed(v, only_outgoing=True) if p: assert sublist(p, outgoing) for i in p: outgoing.remove(i) assert not incoming assert not outgoing
def test_recorded_parsings(recorder): incoming = [[randomString(10), randomString(6)] for i in range(3)] outgoing = [[randomString(10), randomString(6)] for i in range(5)] for m, f in incoming: recorder.add_incoming(m, f) time.sleep(0.01) for m, f in outgoing: recorder.add_outgoing(m, f) time.sleep(0.01) with pytest.raises(AssertionError): recorder.get_parsed(incoming[0], only_incoming=True, only_outgoing=True) combined = incoming + outgoing def sublist(lst1, lst2): ls1 = [element for element in lst1 if element in lst2] ls2 = [element for element in lst2 if element in lst1] return ls1 == ls2 for k, v in recorder.store.iterator(include_value=True): p = Recorder.get_parsed(v) assert sublist([i[1:] for i in p], combined) p = Recorder.get_parsed(v, only_incoming=True) if p: assert sublist(p, incoming) for i in p: incoming.remove(i) p = Recorder.get_parsed(v, only_outgoing=True) if p: assert sublist(p, outgoing) for i in p: outgoing.remove(i) assert not incoming assert not outgoing
def test_recorder_get_next(recorder): incoming_count = 100 outgoing_count = 50 incoming = [(randomString(100), randomString(6)) for _ in range(incoming_count)] outgoing = [(randomString(100), randomString(6)) for _ in range(outgoing_count)] while incoming or outgoing: if random.choice([0, 1]) and outgoing: recorder.add_outgoing(*outgoing.pop()) time.sleep(random.choice([0, 1]) + random.random()) elif incoming: recorder.add_incoming(*incoming.pop()) time.sleep(random.choice([0, 1]) + random.random()) else: continue recorded_incomings = OrderedDict() for k, v in recorder.store.iterator(include_value=True): v = Recorder.get_parsed(v, only_incoming=True) if v: recorded_incomings[int(k)] = v assert len(recorded_incomings) == incoming_count max_time_to_run = incoming_count * 2 + 10 recorder.start_playing() start = time.perf_counter() while recorder.is_playing and (time.perf_counter() < start + max_time_to_run): vals = recorder.get_next() if vals: inc = Recorder.filter_incoming(vals) if inc: assert recorded_incomings.popitem(last=False)[1] == inc else: time.sleep(0.01) assert len(recorded_incomings) == 0 assert not recorder.is_playing
def patch_sent_prepreapres(replaying_node, node_recorder): sent_pps = {} def add_preprepare(msg): inst_id, v, p = msg[f.INST_ID.nm], msg[f.VIEW_NO.nm], msg[ f.PP_SEQ_NO.nm] if inst_id not in sent_pps: sent_pps[inst_id] = {} sent_pps[inst_id][v, p] = [ msg[f.PP_TIME.nm], [tuple(l) for l in msg[f.REQ_IDR.nm]], msg[f.DISCARDED.nm], ] for k, v in node_recorder.store.iterator(include_value=True): parsed = Recorder.get_parsed(v.decode()) outgoings = Recorder.filter_outgoing(parsed) if not outgoings: continue for out in outgoings: try: msg = json.loads(out[0]) if isinstance(msg, dict) and OP_FIELD_NAME in msg: op_name = msg[OP_FIELD_NAME] if op_name == PREPREPARE: add_preprepare(msg) elif op_name == BATCH: for m in msg['messages']: try: m = json.loads(m) if m[OP_FIELD_NAME] == PREPREPARE: add_preprepare(m) except json.JSONDecodeError: continue else: continue except json.JSONDecodeError: continue for r in replaying_node.replicas: r.sent_pps = sent_pps.pop(r.instId, {}) replaying_node.sent_pps = sent_pps