예제 #1
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)
예제 #2
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)
예제 #3
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)
예제 #4
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)
예제 #5
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)
예제 #6
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)
예제 #7
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
예제 #8
0
_neighbors: [<servers.server.Server object at 0x1055104a8>], 
_total_nodes: 0, 
_commitIndex: 0, 
_currentTerm: 0, 
_lastApplied: 0, 
_lastLogIndex: 0, 
_lastLogTerm: None
"""

msg = oserver._messageBoard.get_message()
# print(msg)
"""
AppendEntries: 0, RequestVote: 1, RequestVoteResponse: 2, Response: 3, _timestamp: 1581684927, 
_sender: 1, _receiver: 0, _data: {'lastLogIndex': 0, 'lastLogTerm': None}, _term: 1, _type: 1
"""
oserver.on_message(msg)

# print(oserver)
# print(server)
"""

_name: 0, 
_state: Follower ** _timeout: 500, _timeoutTime: 1581685712.0402, _last_vote: 1, 
_log: [], 
_messageBoard: board: [], 
_neighbors: [<servers.server.Server object at 0x1055104a8>], 
_total_nodes: 0, 
_commitIndex: 0, 
_currentTerm: 1, 
_lastApplied: 0, 
_lastLogIndex: 0, 
예제 #9
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)
예제 #10
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)
예제 #11
0
_neighbors: [<servers.server.Server object at 0x10ef71cf8>], 
_total_nodes: 0, 
_commitIndex: 0, 
_currentTerm: 0, 
_lastApplied: 0, 
_lastLogIndex: 0, 
_lastLogTerm: None
"""

msg = AppendEntriesMessage(0, 1, 2, {})
# print(msg)
"""
AppendEntries: 0, RequestVote: 1, RequestVoteResponse: 2, Response: 3, 
_timestamp: 1581654239, _sender: 0, _receiver: 1, _data: {}, _term: 2, _type: 0
"""
server.on_message(msg)
# print(server)
"""
_name: 1, 
_state: <states.follower.Follower object at 0x10d08afd0>, 
_log: [], 
_messageBoard: board: [], 
_neighbors: [<servers.server.Server object at 0x10d08acf8>], 
_total_nodes: 0, 
_commitIndex: 0, 
_currentTerm: 2, 
_lastApplied: 0, 
_lastLogIndex: 0, 
_lastLogTerm: None
"""
예제 #12
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