def generate_some(rnd: SimRandom): integers = [rnd.integer(-37, 7342) for _ in range(1000)] floats = [rnd.float(0.1, 5.5) for _ in range(1000)] strings = [rnd.string(10) for _ in range(10)] choice = rnd.choice(*integers) sample = rnd.sample(integers, 10) shuffled = rnd.shuffle(integers) return integers, floats, strings, choice, sample, shuffled
def check_view_change_completes_under_normal_conditions(random: SimRandom, min_latency, max_latency, filtered_msg_types, filter_probability): # PREPARE # 1. Create random pool with random initial state pool, committed = some_pool(random) N = pool.size F = (N - 1) // 3 # 2. set latency pool.network.set_latency(min_latency, max_latency) # 3. set filter # TODO: Uncomment after fix # pool.network.set_filter([replica_name_to_node_name(pool.nodes[-1].name)], # filtered_msg_types, filter_probability) # EXECUTE # Schedule view change at different time on all nodes for node in pool.nodes: pool.timer.schedule(random.float(0, 10), partial(node._view_changer.process_need_view_change, NeedViewChange())) # CHECK # 1. Make sure all nodes complete view change pool.timer.wait_for(lambda: all(not node._data.waiting_for_new_view and node._data.view_no > 0 for node in pool.nodes)) # 2. check that equal stable checkpoint is set on at least N-F nodes (F nodes may lag behind and will catchup) stable_checkpoints = [n._data.stable_checkpoint for n in pool.nodes] most_freq_stable_ckeckpoint = Counter(stable_checkpoints).most_common(1) stable_checkpoint = most_freq_stable_ckeckpoint[0][0] assert most_freq_stable_ckeckpoint[0][1] >= N - F # 3. check that equal preprepares is set on all node with the found stable checkpoint preprepares = set() for n in pool.nodes: if n._data.stable_checkpoint >= stable_checkpoint: preprepares.add(tuple(n._data.preprepared)) assert len(preprepares) == 1 # 4. Make sure all nodes end up in same view for node_a, node_b in zip(pool.nodes, pool.nodes[1:]): assert node_a._data.view_no == node_b._data.view_no assert node_a._data.primary_name == node_b._data.primary_name # 5. Make sure that all committed reqs are ordered with the same ppSeqNo in the new view: committed_above_cp = [c for c in committed if c.pp_seq_no > stable_checkpoint] for n in pool.nodes: if n._data.stable_checkpoint >= stable_checkpoint: for expected_batch, actual_batch in zip(committed_above_cp, n._data.preprepared[:len(committed_above_cp)]): assert expected_batch.pp_view_no == actual_batch.pp_view_no assert expected_batch.pp_seq_no == actual_batch.pp_seq_no assert expected_batch.pp_digest == actual_batch.pp_digest