예제 #1
0
    def test_candidate_server_wins_election(self):
        board = MemoryBoard()
        state = Follower()
        server0 = Server(0, state, [], board, [])

        board = MemoryBoard()
        state = Follower()
        oserver = Server(1, state, [], board, [])

        board = MemoryBoard()
        state = Candidate()
        server = Server(2, state, [], board, [oserver, server0])

        server0._neighbors.append(server)
        oserver._neighbors.append(server)

        oserver.on_message(oserver._messageBoard.get_message())
        server0.on_message(server0._messageBoard.get_message())

        server._total_nodes = 3

        server.on_message(server._messageBoard.get_message())
        server.on_message(server._messageBoard.get_message())

        self.assertEqual(type(server._state), Leader)
예제 #2
0
    def setUp(self):
        board = MemoryBoard()
        state = Follower()
        self.oserver = Server(0, state, [], board, [])

        board = MemoryBoard()
        state = Follower()
        self.server = Server(1, state, [], board, [self.oserver])
예제 #3
0
    def setUp(self):
        board = MemoryBoard()
        state = Follower()
        self.oserver = Server(0, state, [], board, [])

        board = MemoryBoard()
        state = Candidate()
        self.server = Server(1, state, [], board, [self.oserver])

        self.oserver._neighbors.append(self.server)
예제 #4
0
    def test_two_candidates_tie(self):
        followers = []

        for i in range(4):
            board = MemoryBoard()
            state = Follower()
            followers.append(Server(i, state, [], board, []))

        board = MemoryBoard()
        state = Candidate()
        c0 = Server(5, state, [], board, followers[0:2])

        board = MemoryBoard()
        state = Candidate()
        c1 = Server(6, state, [], board, followers[2:])

        for i in range(2):
            followers[i]._neighbors.append(c0)
            followers[i].on_message(followers[i]._messageBoard.get_message())

        for i in range(2, 4):
            followers[i]._neighbors.append(c1)
            followers[i].on_message(followers[i]._messageBoard.get_message())

        c0._total_nodes = 6
        c1._total_nodes = 6

        for i in range(2):
            c0.on_message(c0._messageBoard.get_message())
            c1.on_message(c1._messageBoard.get_message())

        self.assertEqual(type(c0._state), Candidate)
        self.assertEqual(type(c1._state), Candidate)
예제 #5
0
    def setUp(self):

        followers = []
        for i in range(1, 4):
            board = MemoryBoard()
            state = Follower()
            followers.append(Server(i, state, [], board, []))

        board = MemoryBoard()
        state = Leader()

        self.leader = Server(0, state, [], board, followers)

        for i in followers:
            i._neighbors.append(self.leader)
예제 #6
0
    def setUp(self):
        board = MemoryBoard()
        state = Follower()
        self.oserver = Server(0, state, [], board, [])

        board = MemoryBoard()
        state = Follower()
        self.server = Server(1, state, [], board, [self.oserver])
예제 #7
0
    def setUp(self):
        board = MemoryBoard()
        state = Follower()
        self.oserver = Server(0, state, [], board, [])

        board = MemoryBoard()
        state = Candidate()
        self.server = Server(1, state, [], board, [self.oserver])

        self.oserver._neighbors.append(self.server)
예제 #8
0
    def setUp(self):

        followers = []
        for i in range(1, 4):
            board = MemoryBoard()
            state = Follower()
            followers.append(Server(i, state, [], board, []))

        board = MemoryBoard()
        state = Leader()

        self.leader = Server(0, state, [], board, followers)

        for i in followers:
            i._neighbors.append(self.leader)
예제 #9
0
class TestLeaderServer(unittest.TestCase):

    def setUp(self):

        followers = []
        for i in range(1, 4):
            board = MemoryBoard()
            state = Follower()
            followers.append(Server(i, state, [], board, []))

        board = MemoryBoard()
        state = Leader()

        self.leader = Server(0, state, [], board, followers)

        for i in followers:
            i._neighbors.append(self.leader)

    def _perform_hearbeat(self):
        self.leader._state._send_heart_beat()
        for i in self.leader._neighbors:
            i.on_message(i._messageBoard.get_message())

        for i in self.leader._messageBoard._board:
            self.leader.on_message(i)

    def test_leader_server_sends_heartbeat_to_all_neighbors(self):

        self._perform_hearbeat()
        self.assertEqual(
            {1: 0, 2: 0, 3: 0}, self.leader._state._nextIndexes)

    def test_leader_server_sends_appendentries_to_all_neighbors_and_is_appended_to_their_logs(self):

        self._perform_hearbeat()

        msg = AppendEntriesMessage(0, None, 1, {
            "prevLogIndex": 0,
            "prevLogTerm": 0,
            "leaderCommit": 1,
            "entries": [{"term": 1, "value": 100}]})

        self.leader.send_message(msg)

        for i in self.leader._neighbors:
            i.on_message(i._messageBoard.get_message())

        for i in self.leader._neighbors:
            self.assertEqual([{"term": 1, "value": 100}], i._log)

    def test_leader_server_sends_appendentries_to_all_neighbors_but_some_have_dirtied_logs(self):

        self.leader._neighbors[0]._log.append({"term": 2, "value": 100})
        self.leader._neighbors[0]._log.append({"term": 2, "value": 200})
        self.leader._neighbors[1]._log.append({"term": 3, "value": 200})
        self.leader._log.append({"term": 1, "value": 100})

        self._perform_hearbeat()

        msg = AppendEntriesMessage(0, None, 1, {
            "prevLogIndex": 0,
            "prevLogTerm": 0,
            "leaderCommit": 1,
            "entries": [{"term": 1, "value": 100}]})

        self.leader.send_message(msg)

        for i in self.leader._neighbors:
            i.on_message(i._messageBoard.get_message())

        for i in self.leader._neighbors:
            self.assertEqual([{"term": 1, "value": 100}], i._log)
예제 #10
0
    def test_two_candidates_tie(self):
        followers = []

        for i in range(4):
            board = MemoryBoard()
            state = Follower()
            followers.append(Server(i, state, [], board, []))

        board = MemoryBoard()
        state = Candidate()
        c0 = Server(5, state, [], board, followers[0:2])

        board = MemoryBoard()
        state = Candidate()
        c1 = Server(6, state, [], board, followers[2:])

        for i in range(2):
            followers[i]._neighbors.append(c0)
            followers[i].on_message(followers[i]._messageBoard.get_message())

        for i in range(2, 4):
            followers[i]._neighbors.append(c1)
            followers[i].on_message(followers[i]._messageBoard.get_message())

        c0._total_nodes = 6
        c1._total_nodes = 6

        for i in range(2):
            c0.on_message(c0._messageBoard.get_message())
            c1.on_message(c1._messageBoard.get_message())

        self.assertEqual(type(c0._state), Candidate)
        self.assertEqual(type(c1._state), Candidate)
예제 #11
0
    def test_candidate_server_wins_election(self):
        board = MemoryBoard()
        state = Follower()
        server0 = Server(0, state, [], board, [])

        board = MemoryBoard()
        state = Follower()
        oserver = Server(1, state, [], board, [])

        board = MemoryBoard()
        state = Candidate()
        server = Server(2, state, [], board, [oserver, server0])

        server0._neighbors.append(server)
        oserver._neighbors.append(server)

        oserver.on_message(oserver._messageBoard.get_message())
        server0.on_message(server0._messageBoard.get_message())

        server._total_nodes = 3

        server.on_message(server._messageBoard.get_message())
        server.on_message(server._messageBoard.get_message())

        self.assertEqual(type(server._state), Leader)
예제 #12
0
from boards.memory_board import MemoryBoard
from messages.append_entries import AppendEntriesMessage
from messages.request_vote import RequestVoteMessage
from servers.server import Server
from states.follower import Follower
"""
follower-0 follower-1
oserver    server
sender     receiver

"""

board = MemoryBoard()
state = Follower()
oserver = Server(0, state, [], board, [])
# print(oserver)
"""
_name: 0, 
_state: <states.follower.Follower object at 0x1047fbd68>, 
_log: [], 
_messageBoard: board: [], 
_neighbors: [], 
_total_nodes: 0, 
_commitIndex: 0, 
_currentTerm: 0,
_lastApplied: 0,
_lastLogIndex: 0, 
_lastLogTerm: None
"""
예제 #13
0
class TestCandidateServer(unittest.TestCase):
    def setUp(self):
        board = MemoryBoard()
        state = Follower()
        self.oserver = Server(0, state, [], board, [])

        board = MemoryBoard()
        state = Candidate()
        self.server = Server(1, state, [], board, [self.oserver])

        self.oserver._neighbors.append(self.server)

    def test_candidate_server_had_intiated_the_election(self):

        self.assertEqual(1, len(self.oserver._messageBoard._board))

        self.oserver.on_message(self.oserver._messageBoard.get_message())

        self.assertEqual(1, len(self.server._messageBoard._board))
        self.assertEqual(
            True,
            self.server._messageBoard.get_message().data["response"])

    def test_candidate_server_had_gotten_the_vote(self):
        self.oserver.on_message(self.oserver._messageBoard.get_message())

        self.assertEqual(1, len(self.server._messageBoard._board))
        self.assertEqual(
            True,
            self.server._messageBoard.get_message().data["response"])

    def test_candidate_server_wins_election(self):
        board = MemoryBoard()
        state = Follower()
        server0 = Server(0, state, [], board, [])

        board = MemoryBoard()
        state = Follower()
        oserver = Server(1, state, [], board, [])

        board = MemoryBoard()
        state = Candidate()
        server = Server(2, state, [], board, [oserver, server0])

        server0._neighbors.append(server)
        oserver._neighbors.append(server)

        oserver.on_message(oserver._messageBoard.get_message())
        server0.on_message(server0._messageBoard.get_message())

        server._total_nodes = 3

        server.on_message(server._messageBoard.get_message())
        server.on_message(server._messageBoard.get_message())

        self.assertEqual(type(server._state), Leader)

    def test_two_candidates_tie(self):
        followers = []

        for i in range(4):
            board = MemoryBoard()
            state = Follower()
            followers.append(Server(i, state, [], board, []))

        board = MemoryBoard()
        state = Candidate()
        c0 = Server(5, state, [], board, followers[0:2])

        board = MemoryBoard()
        state = Candidate()
        c1 = Server(6, state, [], board, followers[2:])

        for i in range(2):
            followers[i]._neighbors.append(c0)
            followers[i].on_message(followers[i]._messageBoard.get_message())

        for i in range(2, 4):
            followers[i]._neighbors.append(c1)
            followers[i].on_message(followers[i]._messageBoard.get_message())

        c0._total_nodes = 6
        c1._total_nodes = 6

        for i in range(2):
            c0.on_message(c0._messageBoard.get_message())
            c1.on_message(c1._messageBoard.get_message())

        self.assertEqual(type(c0._state), Candidate)
        self.assertEqual(type(c1._state), Candidate)

    def test_two_candidates_one_wins(self):
        followers = []

        for i in range(6):
            board = MemoryBoard()
            state = Follower()
            followers.append(Server(i, state, [], board, []))

        board = MemoryBoard()
        state = Candidate()
        c0 = Server(7, state, [], board, followers[0:2])

        board = MemoryBoard()
        state = Candidate()
        c1 = Server(8, state, [], board, followers[2:])

        for i in range(2):
            followers[i]._neighbors.append(c0)
            followers[i].on_message(followers[i]._messageBoard.get_message())

        for i in range(2, 6):
            followers[i]._neighbors.append(c1)
            followers[i].on_message(followers[i]._messageBoard.get_message())

        c0._total_nodes = 7
        c1._total_nodes = 7

        for i in range(2):
            c0.on_message(c0._messageBoard.get_message())

        for i in range(4):
            c1.on_message(c1._messageBoard.get_message())

        self.assertEqual(type(c0._state), Candidate)
        self.assertEqual(type(c1._state), Leader)

    def test_candidate_fails_to_win_election_so_resend_request(self):
        pass

    def test_multiple_candidates_fail_to_win_so_resend_requests(self):
        pass
예제 #14
0
import socket
import datetime
import time
import sys
import threading
from server_config import CONFIG as server_config
from servers.server import Server, ZeroMQServer
#from states.follower import Follower
from blocks.block import BlockChain
from boards.memory_board import MemoryBoard
import logging

from states.characters import Follower

if __name__ == '__main__':
    server_id = int(sys.argv[1])
    logging.basicConfig(filename='server_' + str(server_id) + '.log',
                        level=logging.DEBUG)
    observers = [
        Server('localhost\t' + str(server_config[i]), Follower(), BlockChain(),
               MemoryBoard(), [], True) for i in server_config
        if i != server_id
    ]
    #for this_item in observers:
    #    this_item._state.set_server(this_item)
    ZeroMQServer('localhost\t' + str(server_config[server_id]), Follower(),
                 BlockChain(), MemoryBoard(), observers)
    #ZeroMQServer(this_server)
    while True:
        time.sleep(10)
예제 #15
0
class TestFollowerServer(unittest.TestCase):
    def setUp(self):
        board = MemoryBoard()
        state = Follower()
        self.oserver = Server(0, state, [], board, [])

        board = MemoryBoard()
        state = Follower()
        self.server = Server(1, state, [], board, [self.oserver])

    def test_follower_server_on_message(self):
        msg = AppendEntriesMessage(0, 1, 2, {})
        self.server.on_message(msg)

    def test_follower_server_on_receive_message_with_lesser_term(self):

        msg = AppendEntriesMessage(0, 1, -1, {})

        self.server.on_message(msg)

        self.assertEqual(
            False,
            self.oserver._messageBoard.get_message().data["response"])

    def test_follower_server_on_receive_message_with_greater_term(self):

        msg = AppendEntriesMessage(0, 1, 2, {})

        self.server.on_message(msg)

        self.assertEqual(2, self.server._currentTerm)

    def test_follower_server_on_receive_message_where_log_does_not_have_prevLogTerm(
            self):
        self.server._log.append({"term": 100, "value": 2000})
        msg = AppendEntriesMessage(
            0, 1, 2, {
                "prevLogIndex": 0,
                "prevLogTerm": 1,
                "leaderCommit": 1,
                "entries": [{
                    "term": 1,
                    "value": 100
                }]
            })

        self.server.on_message(msg)

        self.assertEqual(
            False,
            self.oserver._messageBoard.get_message().data["response"])
        self.assertEqual([], self.server._log)

    def test_follower_server_on_receive_message_where_log_contains_conflicting_entry_at_new_index(
            self):

        self.server._log.append({"term": 1, "value": 0})
        self.server._log.append({"term": 1, "value": 200})
        self.server._log.append({"term": 1, "value": 300})
        self.server._log.append({"term": 2, "value": 400})

        msg = AppendEntriesMessage(
            0, 1, 2, {
                "prevLogIndex": 0,
                "prevLogTerm": 1,
                "leaderCommit": 1,
                "entries": [{
                    "term": 1,
                    "value": 100
                }]
            })

        self.server.on_message(msg)
        self.assertEqual({"term": 1, "value": 100}, self.server._log[1])
        self.assertEqual([{
            "term": 1,
            "value": 0
        }, {
            "term": 1,
            "value": 100
        }], self.server._log)

    def test_follower_server_on_receive_message_where_log_is_empty_and_receives_its_first_value(
            self):

        msg = AppendEntriesMessage(
            0, 1, 2, {
                "prevLogIndex": 0,
                "prevLogTerm": 100,
                "leaderCommit": 1,
                "entries": [{
                    "term": 1,
                    "value": 100
                }]
            })

        self.server.on_message(msg)
        self.assertEqual({"term": 1, "value": 100}, self.server._log[0])

    def test_follower_server_on_receive_vote_request_message(self):
        msg = RequestVoteMessage(0, 1, 2, {
            "lastLogIndex": 0,
            "lastLogTerm": 0,
            "entries": []
        })

        self.server.on_message(msg)

        self.assertEqual(0, self.server._state._last_vote)
        self.assertEqual(
            True,
            self.oserver._messageBoard.get_message().data["response"])

    def test_follower_server_on_receive_vote_request_after_sending_a_vote(
            self):
        msg = RequestVoteMessage(0, 1, 2, {
            "lastLogIndex": 0,
            "lastLogTerm": 0,
            "entries": []
        })

        self.server.on_message(msg)

        msg = RequestVoteMessage(2, 1, 2, {})
        self.server.on_message(msg)

        self.assertEqual(0, self.server._state._last_vote)
예제 #16
0
class TestFollowerServer(unittest.TestCase):

    def setUp(self):
        board = MemoryBoard()
        state = Follower()
        self.oserver = Server(0, state, [], board, [])

        board = MemoryBoard()
        state = Follower()
        self.server = Server(1, state, [], board, [self.oserver])

    def test_follower_server_on_message(self):
        msg = AppendEntriesMessage(0, 1, 2, {})
        self.server.on_message(msg)

    def test_follower_server_on_receive_message_with_lesser_term(self):

        msg = AppendEntriesMessage(0, 1, -1, {})

        self.server.on_message(msg)

        self.assertEqual(
            False, self.oserver._messageBoard.get_message().data["response"])

    def test_follower_server_on_receive_message_with_greater_term(self):

        msg = AppendEntriesMessage(0, 1, 2, {})

        self.server.on_message(msg)

        self.assertEqual(2, self.server._currentTerm)

    def test_follower_server_on_receive_message_where_log_does_not_have_prevLogTerm(self):
        self.server._log.append({"term": 100, "value": 2000})
        msg = AppendEntriesMessage(0, 1, 2, {
            "prevLogIndex": 0,
            "prevLogTerm": 1,
            "leaderCommit": 1,
            "entries": [{"term": 1, "value": 100}]})

        self.server.on_message(msg)

        self.assertEqual(
            False, self.oserver._messageBoard.get_message().data["response"])
        self.assertEqual([], self.server._log)

    def test_follower_server_on_receive_message_where_log_contains_conflicting_entry_at_new_index(self):

        self.server._log.append({"term": 1, "value": 0})
        self.server._log.append({"term": 1, "value": 200})
        self.server._log.append({"term": 1, "value": 300})
        self.server._log.append({"term": 2, "value": 400})

        msg = AppendEntriesMessage(0, 1, 2, {
            "prevLogIndex": 0,
            "prevLogTerm": 1,
            "leaderCommit": 1,
            "entries": [{"term": 1, "value": 100}]})

        self.server.on_message(msg)
        self.assertEqual({"term": 1, "value": 100}, self.server._log[1])
        self.assertEqual(
            [{"term": 1, "value": 0}, {"term": 1, "value": 100}], self.server._log)

    def test_follower_server_on_receive_message_where_log_is_empty_and_receives_its_first_value(self):

        msg = AppendEntriesMessage(0, 1, 2, {
            "prevLogIndex": 0,
            "prevLogTerm": 100,
            "leaderCommit": 1,
            "entries": [{"term": 1, "value": 100}]})

        self.server.on_message(msg)
        self.assertEqual({"term": 1, "value": 100}, self.server._log[0])

    def test_follower_server_on_receive_vote_request_message(self):
        msg = RequestVoteMessage(
            0, 1, 2, {"lastLogIndex": 0, "lastLogTerm": 0, "entries": []})

        self.server.on_message(msg)

        self.assertEqual(0, self.server._state._last_vote)
        self.assertEqual(
            True, self.oserver._messageBoard.get_message().data["response"])

    def test_follower_server_on_receive_vote_request_after_sending_a_vote(self):
        msg = RequestVoteMessage(
            0, 1, 2, {"lastLogIndex": 0, "lastLogTerm": 0, "entries": []})

        self.server.on_message(msg)

        msg = RequestVoteMessage(2, 1, 2, {})
        self.server.on_message(msg)

        self.assertEqual(0, self.server._state._last_vote)
예제 #17
0
import argparse
from servers.server import Server
if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('port', type=int)
    parser.parse_args()
    args = parser.parse_args()
    host = 'localhost'
    try:
        server = Server(host, args.port)
        server.serve()
    except Exception as ex:
        print("couldn't start the server because:")
        print(ex)
예제 #18
0
class TestLeaderServer(unittest.TestCase):
    def setUp(self):

        followers = []
        for i in range(1, 4):
            board = MemoryBoard()
            state = Follower()
            followers.append(Server(i, state, [], board, []))

        board = MemoryBoard()
        state = Leader()

        self.leader = Server(0, state, [], board, followers)

        for i in followers:
            i._neighbors.append(self.leader)

    def _perform_hearbeat(self):
        self.leader._state._send_heart_beat()
        for i in self.leader._neighbors:
            i.on_message(i._messageBoard.get_message())

        for i in self.leader._messageBoard._board:
            self.leader.on_message(i)

    def test_leader_server_sends_heartbeat_to_all_neighbors(self):

        self._perform_hearbeat()
        self.assertEqual({1: 0, 2: 0, 3: 0}, self.leader._state._nextIndexes)

    def test_leader_server_sends_appendentries_to_all_neighbors_and_is_appended_to_their_logs(
            self):

        self._perform_hearbeat()

        msg = AppendEntriesMessage(
            0, None, 1, {
                "prevLogIndex": 0,
                "prevLogTerm": 0,
                "leaderCommit": 1,
                "entries": [{
                    "term": 1,
                    "value": 100
                }]
            })

        self.leader.send_message(msg)

        for i in self.leader._neighbors:
            i.on_message(i._messageBoard.get_message())

        for i in self.leader._neighbors:
            self.assertEqual([{"term": 1, "value": 100}], i._log)

    def test_leader_server_sends_appendentries_to_all_neighbors_but_some_have_dirtied_logs(
            self):

        self.leader._neighbors[0]._log.append({"term": 2, "value": 100})
        self.leader._neighbors[0]._log.append({"term": 2, "value": 200})
        self.leader._neighbors[1]._log.append({"term": 3, "value": 200})
        self.leader._log.append({"term": 1, "value": 100})

        self._perform_hearbeat()

        msg = AppendEntriesMessage(
            0, None, 1, {
                "prevLogIndex": 0,
                "prevLogTerm": 0,
                "leaderCommit": 1,
                "entries": [{
                    "term": 1,
                    "value": 100
                }]
            })

        self.leader.send_message(msg)

        for i in self.leader._neighbors:
            i.on_message(i._messageBoard.get_message())

        for i in self.leader._neighbors:
            self.assertEqual([{"term": 1, "value": 100}], i._log)
예제 #19
0
import unittest

from boards.memory_board import MemoryBoard
from messages.append_entries import AppendEntriesMessage
from messages.request_vote import RequestVoteMessage
from servers.server import Server
from states.follower import Follower
from states.candidate import Candidate
from states.leader import Leader

board = MemoryBoard()
state = Follower()
oserver = Server(0, state, [], board, [])
# print(oserver)
"""
_name: 0, 
_state: Follower ** _timeout: 500, _timeoutTime: 1581685132.670627, _last_vote: None, 
_log: [], 
_messageBoard: board: [], 
_neighbors: [], 
_total_nodes: 0, 
_commitIndex: 0, 
_currentTerm: 0, 
_lastApplied: 0, 
_lastLogIndex: 0, 
_lastLogTerm: None
"""

board = MemoryBoard()
state = Candidate()  # 候选人
# print(state)  # Candidate ** _last_vote: None, _votes: None
예제 #20
0
class TestCandidateServer(unittest.TestCase):

    def setUp(self):
        board = MemoryBoard()
        state = Follower()
        self.oserver = Server(0, state, [], board, [])

        board = MemoryBoard()
        state = Candidate()
        self.server = Server(1, state, [], board, [self.oserver])

        self.oserver._neighbors.append(self.server)

    def test_candidate_server_had_intiated_the_election(self):

        self.assertEqual(1, len(self.oserver._messageBoard._board))

        self.oserver.on_message(self.oserver._messageBoard.get_message())

        self.assertEqual(1, len(self.server._messageBoard._board))
        self.assertEqual(
            True, self.server._messageBoard.get_message().data["response"])

    def test_candidate_server_had_gotten_the_vote(self):
        self.oserver.on_message(self.oserver._messageBoard.get_message())

        self.assertEqual(1, len(self.server._messageBoard._board))
        self.assertEqual(
            True, self.server._messageBoard.get_message().data["response"])

    def test_candidate_server_wins_election(self):
        board = MemoryBoard()
        state = Follower()
        server0 = Server(0, state, [], board, [])

        board = MemoryBoard()
        state = Follower()
        oserver = Server(1, state, [], board, [])

        board = MemoryBoard()
        state = Candidate()
        server = Server(2, state, [], board, [oserver, server0])

        server0._neighbors.append(server)
        oserver._neighbors.append(server)

        oserver.on_message(oserver._messageBoard.get_message())
        server0.on_message(server0._messageBoard.get_message())

        server._total_nodes = 3

        server.on_message(server._messageBoard.get_message())
        server.on_message(server._messageBoard.get_message())

        self.assertEqual(type(server._state), Leader)

    def test_two_candidates_tie(self):
        followers = []

        for i in range(4):
            board = MemoryBoard()
            state = Follower()
            followers.append(Server(i, state, [], board, []))

        board = MemoryBoard()
        state = Candidate()
        c0 = Server(5, state, [], board, followers[0:2])

        board = MemoryBoard()
        state = Candidate()
        c1 = Server(6, state, [], board, followers[2:])

        for i in range(2):
            followers[i]._neighbors.append(c0)
            followers[i].on_message(followers[i]._messageBoard.get_message())

        for i in range(2, 4):
            followers[i]._neighbors.append(c1)
            followers[i].on_message(followers[i]._messageBoard.get_message())

        c0._total_nodes = 6
        c1._total_nodes = 6

        for i in range(2):
            c0.on_message(c0._messageBoard.get_message())
            c1.on_message(c1._messageBoard.get_message())

        self.assertEqual(type(c0._state), Candidate)
        self.assertEqual(type(c1._state), Candidate)

    def test_two_candidates_one_wins(self):
        followers = []

        for i in range(6):
            board = MemoryBoard()
            state = Follower()
            followers.append(Server(i, state, [], board, []))

        board = MemoryBoard()
        state = Candidate()
        c0 = Server(7, state, [], board, followers[0:2])

        board = MemoryBoard()
        state = Candidate()
        c1 = Server(8, state, [], board, followers[2:])

        for i in range(2):
            followers[i]._neighbors.append(c0)
            followers[i].on_message(followers[i]._messageBoard.get_message())

        for i in range(2, 6):
            followers[i]._neighbors.append(c1)
            followers[i].on_message(followers[i]._messageBoard.get_message())

        c0._total_nodes = 7
        c1._total_nodes = 7

        for i in range(2):
            c0.on_message(c0._messageBoard.get_message())

        for i in range(4):
            c1.on_message(c1._messageBoard.get_message())

        self.assertEqual(type(c0._state), Candidate)
        self.assertEqual(type(c1._state), Leader)

    def test_candidate_fails_to_win_election_so_resend_request(self):
        pass

    def test_multiple_candidates_fail_to_win_so_resend_requests(self):
        pass