// Copyright 2023 CratesLand Contributors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. use std::ops::{Deref, DerefMut}; use mephisto_raft::{eraftpb::Message, storage::MemStorage, Raft, Result}; /// A simulated Raft facade for testing. /// /// If the contained value is a `Some` operations happen. If they are a `None` operations are /// a no-op. pub struct Interface { /// The raft peer. pub raft: Option>, } impl Interface { /// Create a new interface to a new raft. pub fn new(r: Raft) -> Interface { Interface { raft: Some(r) } } /// Step the raft, if it exists. pub fn step(&mut self, m: Message) -> Result<()> { match self.raft { Some(_) => Raft::step(self, m), None => Ok(()), } } /// Read messages out of the raft. pub fn read_messages(&mut self) -> Vec { match self.raft { Some(_) => self.msgs.drain(..).collect(), None => vec![], } } /// Persist the unstable snapshot and entries. pub fn persist(&mut self) { if self.raft.is_some() { if let Some(snapshot) = self.raft_log.unstable_snapshot() { let snap = snapshot.clone(); let index = snap.get_metadata().index; self.raft_log.stable_snap(index); self.mut_store().wl().apply_snapshot(snap).expect(""); self.on_persist_snap(index); self.commit_apply(index); } let unstable = self.raft_log.unstable_entries().to_vec(); if let Some(e) = unstable.last() { let (last_idx, last_term) = (e.index, e.term); self.raft_log.stable_entries(last_idx, last_term); self.mut_store().wl().append(&unstable).expect(""); self.on_persist_entries(last_idx, last_term); } } } } impl From>> for Interface { fn from(raft: Option>) -> Self { Self { raft } } } impl From> for Interface { fn from(raft: Raft) -> Self { Self { raft: Some(raft) } } } impl Deref for Interface { type Target = Raft; fn deref(&self) -> &Raft { self.raft.as_ref().unwrap() } } impl DerefMut for Interface { fn deref_mut(&mut self) -> &mut Raft { self.raft.as_mut().unwrap() } }