use crate::replication::{ManageReplications, TransactionNotification};
use async_trait::async_trait;
use reduct_base::error::ReductError;
use reduct_base::forbidden;
use reduct_base::msg::replication_api::{
FullReplicationInfo, ReplicationInfo, ReplicationMode, ReplicationSettings,
};
pub(super) struct ReadOnlyReplicationRepository;
impl ReadOnlyReplicationRepository {
pub fn new() -> Self {
ReadOnlyReplicationRepository {}
}
}
#[async_trait]
impl ManageReplications for ReadOnlyReplicationRepository {
async fn create_replication(
&mut self,
_name: &str,
_settings: ReplicationSettings,
) -> Result<(), ReductError> {
Err(forbidden!("Cannot create replication in read-only mode"))
}
async fn update_replication(
&mut self,
_name: &str,
_settings: ReplicationSettings,
) -> Result<(), ReductError> {
Err(forbidden!("Cannot update replication in read-only mode"))
}
async fn replications(&self) -> Result<Vec<ReplicationInfo>, ReductError> {
Ok(vec![])
}
async fn get_info(&self, _name: &str) -> Result<FullReplicationInfo, ReductError> {
Err(forbidden!("Cannot get replication info in read-only mode"))
}
async fn get_replication_settings(
&self,
_name: &str,
) -> Result<ReplicationSettings, ReductError> {
Err(forbidden!(
"Cannot get replication settings in read-only mode"
))
}
async fn is_replication_running(&self, _name: &str) -> Result<bool, ReductError> {
Err(forbidden!("Cannot get replication in read-only mode"))
}
async fn set_replication_provisioned(
&mut self,
_name: &str,
_provisioned: bool,
) -> Result<(), ReductError> {
Err(forbidden!(
"Cannot set replication provisioned state in read-only mode"
))
}
async fn remove_replication(&mut self, _name: &str) -> Result<(), ReductError> {
Err(forbidden!("Cannot remove replication in read-only mode"))
}
async fn set_mode(&mut self, _name: &str, _mode: ReplicationMode) -> Result<(), ReductError> {
Err(forbidden!(
"Cannot update replication mode in read-only mode"
))
}
async fn notify(&mut self, _notification: TransactionNotification) -> Result<(), ReductError> {
Err(forbidden!("Cannot notify replication in read-only mode"))
}
fn start(&mut self) {
}
async fn stop(&mut self) {
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::replication::TransactionNotification;
use rstest::{fixture, rstest};
#[fixture]
fn repo() -> ReadOnlyReplicationRepository {
ReadOnlyReplicationRepository::new()
}
mod create {
use super::*;
#[rstest]
#[tokio::test]
async fn test_create_replication_forbidden(mut repo: ReadOnlyReplicationRepository) {
let settings = ReplicationSettings::default();
let result = repo.create_replication("test", settings).await;
assert_eq!(
result.err().unwrap(),
forbidden!("Cannot create replication in read-only mode")
);
}
}
mod update {
use super::*;
#[rstest]
#[tokio::test]
async fn test_update_replication_forbidden(mut repo: ReadOnlyReplicationRepository) {
let settings = ReplicationSettings::default();
let result = repo.update_replication("test", settings).await;
assert_eq!(
result.err().unwrap(),
forbidden!("Cannot update replication in read-only mode")
);
}
}
mod replications {
use super::*;
#[rstest]
#[tokio::test]
async fn test_replications_empty(repo: ReadOnlyReplicationRepository) {
let reps = repo.replications().await.unwrap();
assert!(reps.is_empty());
}
}
mod get_info {
use super::*;
#[rstest]
#[tokio::test]
async fn test_get_info_forbidden(repo: ReadOnlyReplicationRepository) {
let result = repo.get_info("test").await;
assert_eq!(
result.err().unwrap(),
forbidden!("Cannot get replication info in read-only mode")
);
}
}
mod get_replication {
use super::*;
#[rstest]
#[tokio::test]
async fn test_get_replication_settings_forbidden(repo: ReadOnlyReplicationRepository) {
let err = repo.get_replication_settings("test").await.err().unwrap();
assert_eq!(
err,
forbidden!("Cannot get replication settings in read-only mode")
);
}
#[rstest]
#[tokio::test]
async fn test_get_replication_forbidden(repo: ReadOnlyReplicationRepository) {
let err = repo.is_replication_running("test").await.err().unwrap();
assert_eq!(err, forbidden!("Cannot get replication in read-only mode"));
}
}
mod get_mut_replication {
use super::*;
#[rstest]
#[tokio::test]
async fn test_get_mut_replication_forbidden(mut repo: ReadOnlyReplicationRepository) {
let err = repo
.set_replication_provisioned("test", true)
.await
.err()
.unwrap();
assert_eq!(
err,
forbidden!("Cannot set replication provisioned state in read-only mode")
);
}
}
mod notify {
use super::*;
use reduct_base::io::RecordMeta;
#[rstest]
#[tokio::test]
async fn test_notify_forbidden(mut repo: ReadOnlyReplicationRepository) {
let notification = TransactionNotification {
bucket: "bucket".to_string(),
entry: "entry".to_string(),
meta: RecordMeta::builder().timestamp(0).build(),
event: crate::replication::Transaction::WriteRecord(0),
};
let err = repo.notify(notification).await.err().unwrap();
assert_eq!(
err,
forbidden!("Cannot notify replication in read-only mode")
);
}
}
mod set_mode {
use super::*;
#[rstest]
#[tokio::test]
async fn test_set_mode_forbidden(mut repo: ReadOnlyReplicationRepository) {
let err = repo
.set_mode("test", ReplicationMode::Paused)
.await
.err()
.unwrap();
assert_eq!(
err,
forbidden!("Cannot update replication mode in read-only mode")
);
}
}
}