async def test_round_data_vote_sync(): round_num = 0 voter_num = 7 async with setup_items(voter_num, round_num) as (voters, event_system, round_, election, epoch, candidate_data, candidate_votes): data = await round_._data_factory.create_data( data_number=candidate_data.number + 1, prev_id=candidate_data.id, epoch_num=epoch.num, round_num=round_num, prev_votes=candidate_votes) vote_factories = [DefaultVoteFactory(voter) for voter in voters] votes = [] for vote_factory in vote_factories: vote = await vote_factory.create_vote(data.id, candidate_data.id, epoch.num, round_num) votes.append(vote) await round_.receive_vote(vote) election.receive_vote.assert_not_called() await round_.receive_data(data) assert len(votes) == len(election.receive_vote.call_args_list) for vote, call_args in zip(votes, election.receive_vote.call_args_list): arg_vote, = call_args[0] assert arg_vote is vote
async def test_round_already_vote(): round_num = 0 voter_num = 7 async with setup_items(voter_num, round_num) as (voters, event_system, round_, election, epoch, candidate_data, candidate_votes): vote = await round_._vote_factory.create_vote(b'test', candidate_data.id, epoch.num, round_num) await round_._receive_vote(vote) same_vote = await round_._vote_factory.create_vote( b'test', candidate_data.id, epoch.num, round_num) with pytest.raises(AlreadyVoted): await round_._receive_vote(same_vote) same_vote._id = b'1' await round_._receive_vote(same_vote) none_vote = round_._vote_factory.create_none_vote(epoch.num, round_num) await round_._receive_vote(none_vote) same_none_vote = round_._vote_factory.create_none_vote( epoch.num, round_num) with pytest.raises(AlreadyVoted): await round_._receive_vote(same_none_vote) same_none_vote._id = b'3' await round_._receive_vote(same_none_vote)
async def test_round_reach_quorum_consensus(voter_num: int): round_num = 0 async with setup_items(voter_num, round_num) as (voters, event_system, round_, election, epoch, candidate_data, candidate_votes): # Propose LazyData await round_.round_start() mediator = event_system.get_mediator(DelayedEventMediator) mediator.execute.assert_called_once() delay, event = mediator.execute.call_args_list[0][0] assert delay == TIMEOUT_PROPOSE assert isinstance(event, ReceiveDataEvent) assert event.data.is_lazy() mediator.execute.reset_mock() vote_factories = [DefaultVoteFactory(voter) for voter in voters] random.shuffle(vote_factories) quorum_vote_factories = vote_factories[:epoch.quorum_num] for vote_factory in quorum_vote_factories: vote = await vote_factory.create_vote(b'test', candidate_data.id, epoch.num, round_num) await round_.receive_vote(vote) mediator.execute.assert_not_called()
async def test_round_reach_quorum(voter_num: int): round_num = 0 async with setup_items(voter_num, round_num) as (voters, event_system, round_, election, epoch, candidate_data, candidate_votes): # Propose LazyData await round_.round_start() mediator = event_system.get_mediator(DelayedEventMediator) mediator.execute.assert_called_once() delay, event = mediator.execute.call_args_list[0][0] assert delay == TIMEOUT_PROPOSE assert isinstance(event, ReceiveDataEvent) assert event.data.is_lazy() mediator.execute.reset_mock() random.shuffle(voters) vote_factories = [DefaultVoteFactory(voter) for voter in voters] quorum_vote_factories = vote_factories[:epoch.quorum_num] for vote_factory in quorum_vote_factories[:-1]: vote = await vote_factory.create_vote(b"test", candidate_data.id, epoch.num, round_num) await round_.receive_vote(vote) mediator.execute.assert_not_called() none_vote = quorum_vote_factories[-1].create_none_vote( epoch.num, round_num) await round_.receive_vote(none_vote) assert len(mediator.execute.call_args_list) == len(voters) for voter, call_args in zip(voters, mediator.execute.call_args_list): timeout, event = call_args[0] assert timeout == TIMEOUT_VOTE assert isinstance(event, ReceiveVoteEvent) assert event.vote.is_lazy() mediator.execute.reset_mock() none_vote = vote_factories[-1].create_none_vote(epoch.num, round_num) await round_.receive_vote(none_vote) mediator.execute.assert_not_called()
async def test_round_invalid_round(): round_num = 0 voter_num = 7 async with setup_items(voter_num, round_num) as (voters, event_system, round_, election, epoch, candidate_data, candidate_votes): invalid_round_num = round_num + 1 vote = await round_._vote_factory.create_vote(b'test', candidate_data.id, epoch.num, invalid_round_num) with pytest.raises(InvalidRound): await round_._receive_vote(vote)
async def test_round_invalid_epoch(): round_num = 0 voter_num = 7 async with setup_items(voter_num, round_num) as (voters, event_system, round_, election, epoch, candidate_data, candidate_votes): invalid_epoch_num = epoch.num + 1 data = await round_._data_factory.create_data( data_number=candidate_data.number + 1, prev_id=candidate_data.id, epoch_num=invalid_epoch_num, round_num=round_num, prev_votes=candidate_votes) with pytest.raises(InvalidEpoch): await round_._receive_data(data)
async def test_round_already_propose(): round_num = 0 voter_num = 7 async with setup_items(voter_num, round_num) as (voters, event_system, round_, election, epoch, candidate_data, candidate_votes): data = await round_._data_factory.create_data( data_number=candidate_data.number + 1, prev_id=candidate_data.id, epoch_num=epoch.num, round_num=round_num, prev_votes=candidate_votes) await round_._receive_data(data) with pytest.raises(AlreadyProposed): await round_._receive_data(data)
async def test_round_none_vote_received(): round_num = 0 voter_num = 7 async with setup_items(voter_num, round_num) as (voters, event_system, round_, election, epoch, candidate_data, candidate_votes): # Propose NoneData await round_.round_start() random.shuffle(voters) none_votes = [] for voter in voters[:epoch.quorum_num]: none_vote = DefaultVoteFactory(voter).create_none_vote( epoch.num, round_num) none_votes.append(none_vote) await round_.receive_vote(none_vote) assert len(election.receive_vote.call_args_list) == epoch.quorum_num for none_vote, call_args in zip(none_votes, election.receive_vote.call_args_list): vote, = call_args[0] assert vote is none_vote