def test_broadcast_append_entries(self): self.server._server_state.is_leader.return_value = False pytest.raises(serverstate.InvalidState, self.server.broadcast_append_entries) self.server._server_state.is_leader.return_value = True ae_heartbeat = message.build_append_entry_request( self.server._server_state.term(), 0, 0, 0, ()) self.server._server_state._next_index = mock.MagicMock() self.server._server_state._next_index.__getitem__.return_value = 1 self.server._remote_peers = { 0: mock.Mock(), 1: mock.Mock(), 2: mock.Mock() } self.server._server_state.commit_index.return_value = 0 self.server._server_state.term.return_value = 0 for remote_server in six.iterkeys(self.server._remote_peers): ts = self.server ts._server_state._next_index[remote_server] = 1 ts._log = mock.Mock() ts._log.prev_index_and_term_of_entry.return_value = (0, 0) ts._log.entries_from_index.return_value = () self.server.broadcast_append_entries() for remote_server in range(3): m_remote_server = self.server._remote_peers[remote_server] m_remote_server.send_message.assert_called_once_with(ae_heartbeat)
def test_broadcast_append_entries(self): self.server._server_state.is_leader.return_value = False pytest.raises(serverstate.InvalidState, self.server.broadcast_append_entries) self.server._server_state.is_leader.return_value = True ae_heartbeat = message.build_append_entry_request( self.server._server_state.term(), 0, 0, 0, ()) self.server._server_state._next_index = mock.MagicMock() self.server._server_state._next_index.__getitem__.return_value = 1 self.server._remote_peers = {0: mock.Mock(), 1: mock.Mock(), 2: mock.Mock()} self.server._server_state.commit_index.return_value = 0 self.server._server_state.term.return_value = 0 for remote_server in six.iterkeys(self.server._remote_peers): ts = self.server ts._server_state._next_index[remote_server] = 1 ts._log = mock.Mock() ts._log.prev_index_and_term_of_entry.return_value = (0, 0) ts._log.entries_from_index.return_value = () self.server.broadcast_append_entries() for remote_server in range(3): m_remote_server = self.server._remote_peers[remote_server] m_remote_server.send_message.assert_called_once_with(ae_heartbeat)
def test_process_internal_raft_message(self): self.server._process_append_entry_request = mock.Mock() self.server._process_append_entry_response = mock.Mock() self.server._process_request_vote = mock.Mock() self.server._process_request_vote_response = mock.Mock() mock_socket = mock.Mock(spec=zmq.sugar.socket.Socket) # Append entry request. aereq = (1, 2, 3, 4, ()) aereq_packed = message.build_append_entry_request(*aereq) mock_socket.recv_multipart.return_value = ("identifier", aereq_packed) self.server._process_internal_message(mock_socket, zmq.POLLIN) self.server._process_append_entry_request.assert_called_once_with( "identifier", *aereq) # Append entry response. aeresp = (1, True, 0, None) aeresp_packed = message.build_append_entry_response(*aeresp) mock_socket.recv_multipart.return_value = ("identifier", aeresp_packed) self.server._process_internal_message(mock_socket, zmq.POLLIN) self.server._process_append_entry_response.\ assert_called_once_with("identifier", *aeresp) # Request vote. rv = (1, 2, 3) rv_packed = message.build_request_vote(*rv) mock_socket.recv_multipart.return_value = ("identifier", rv_packed) self.server._process_internal_message(mock_socket, zmq.POLLIN) self.server._process_request_vote.assert_called_once_with( "identifier", *rv) # Request vote response. rvresp = (0, False) rvresp_packed = message.build_request_vote_response(*rvresp) mock_socket.recv_multipart.return_value = ("identifier", rvresp_packed) self.server._process_internal_message(mock_socket, zmq.POLLIN) self.server._process_request_vote_response.\ assert_called_once_with("identifier", *rvresp)
def broadcast_append_entries(self): """Broadcast append entries to all peers. This method is periodically called by ZeroMQ timer within a period equals to '_leader_heartbeat_interval' ms. """ if not self._server_state.is_leader(): raise serverstate.InvalidState( "Invalid state '%d' while sending heartbeat.") LOG.info("send append entry heartbeat, term='%d'" % self._server_state.term()) # Broadcast an append entry request. for remote_server_id in six.iterkeys(self._remote_peers): next_index = self._server_state.next_index(remote_server_id) p_l_i, p_l_t = self._log.prev_index_and_term_of_entry(next_index) entries = self._log.entries_from_index(next_index) ae_request = message.build_append_entry_request( self._server_state.term(), p_l_i, p_l_t, self._server_state.commit_index(), entries) self._remote_peers[remote_server_id].send_message(ae_request)
def test_build_append_entry_request(): test_params = (1, 1, 2, 3, (4, 5)) ae_message = message.build_append_entry_request(*test_params) decoded_message = message.decode_message(ae_message) assert (message.APPEND_ENTRY_REQUEST, test_params) == decoded_message