mod common;
use std::io::{Error, ErrorKind};
#[allow(unused)]
fn if_error(value: bool, text: &'static str) -> Result<(), Box<dyn std::error::Error>> {
if value {
Err(Error::new(ErrorKind::Other, text).into())
} else {
Ok(())
}
}
#[cfg(all(feature = "simple", feature = "test_helpers"))]
mod simple {
use std::fs::{read_to_string, remove_file};
use std::io::Write;
use std::path::{Path, PathBuf};
use phazer::{Phazer, PhazerBuilder, RENAME_WITH_RETRY_STRATEGY, SIMPLE_RENAME_STRATEGY};
use crate::common::{
prepare_target_file, WRITE_COMMIT_SIMPLE_DEFAULT, WRITE_COMMIT_SIMPLE_RENAME,
WRITE_COMMIT_SIMPLE_WITH_RETRY,
};
use super::if_error;
fn write_commit_works<C, P>(
phazer_new: C,
filename: P,
) -> Result<(), Box<dyn std::error::Error>>
where
C: Fn(&PathBuf) -> Phazer,
P: AsRef<Path>,
{
let target_path = prepare_target_file(filename)?;
let p = phazer_new(&target_path);
let working_path = p.working_path().to_path_buf();
if_error(
target_path.exists(),
"target_path cannot exist at this point",
)?;
if_error(
working_path.exists(),
"working_path cannot exist at this point",
)?;
let mut w = p.simple_writer()?;
w.write_all("first".as_bytes())?;
drop(w);
if_error(
!working_path.exists(),
"working_path must exist at this point",
)?;
if_error(
target_path.exists(),
"target_path cannot exist at this point",
)?;
p.commit()?;
if_error(
!target_path.exists(),
"target_path must exist at this point",
)?;
if_error(
working_path.exists(),
"working_path cannot exist at this point",
)?;
let s = read_to_string(&target_path)?;
if_error(s != "first", "target_path file must contain \"first\" ")?;
let p = phazer_new(&target_path);
let working_path = p.working_path().to_path_buf();
if_error(
!target_path.exists(),
"target_path cannot exist at this point",
)?;
if_error(
working_path.exists(),
"working_path cannot exist at this point",
)?;
let mut w = p.simple_writer()?;
w.write_all("second".as_bytes())?;
drop(w);
if_error(
!working_path.exists(),
"working_path must exist at this point",
)?;
if_error(
!target_path.exists(),
"target_path must exist at this point",
)?;
p.commit()?;
if_error(
!target_path.exists(),
"target_path must exist at this point",
)?;
if_error(
working_path.exists(),
"working_path cannot exist at this point",
)?;
let s = read_to_string(&target_path)?;
if_error(s != "second", "target_path file must contain \"second\" ")?;
let _ = remove_file(&target_path);
Ok(())
}
#[test]
fn write_commit_using_default_constructor_works() -> Result<(), Box<dyn std::error::Error>> {
write_commit_works(|p| Phazer::new(p), WRITE_COMMIT_SIMPLE_DEFAULT)
}
#[test]
fn write_commit_using_simple_rename_works() -> Result<(), Box<dyn std::error::Error>> {
write_commit_works(
|p| {
PhazerBuilder::new()
.commit_strategy(SIMPLE_RENAME_STRATEGY)
.target(p)
.build()
},
WRITE_COMMIT_SIMPLE_RENAME,
)
}
#[test]
fn write_commit_using_rename_with_retry_works() -> Result<(), Box<dyn std::error::Error>> {
write_commit_works(
|p| {
PhazerBuilder::new()
.commit_strategy(RENAME_WITH_RETRY_STRATEGY)
.target(p)
.build()
},
WRITE_COMMIT_SIMPLE_WITH_RETRY,
)
}
}
#[cfg(all(feature = "tokio", feature = "test_helpers"))]
mod tokio {
use std::io::ErrorKind;
use std::path::{Path, PathBuf};
use phazer::{Phazer, PhazerBuilder, RENAME_WITH_RETRY_STRATEGY, SIMPLE_RENAME_STRATEGY};
use tokio::fs::{read_to_string, remove_file};
use tokio::io::AsyncWriteExt;
use crate::common::{
prepare_target_file, WRITE_COMMIT_TOKIO_DEFAULT, WRITE_COMMIT_TOKIO_RENAME,
WRITE_COMMIT_TOKIO_WITH_RETRY,
};
use super::if_error;
async fn write_commit_works<C, P>(
phazer_new: C,
filename: P,
) -> Result<(), Box<dyn std::error::Error>>
where
C: Fn(&PathBuf) -> Phazer,
P: AsRef<Path>,
{
let target_path = prepare_target_file(filename)?;
let p = phazer_new(&target_path);
let working_path = p.working_path().to_path_buf();
if_error(
target_path.exists(),
"target_path cannot exist at this point",
)?;
if_error(
working_path.exists(),
"working_path cannot exist at this point",
)?;
let mut w = p.tokio_writer().await?;
w.write_all("first".as_bytes()).await?;
drop(w);
if_error(
!working_path.exists(),
"working_path must exist at this point",
)?;
if_error(
target_path.exists(),
"target_path cannot exist at this point",
)?;
p.commit()?;
if_error(
!target_path.exists(),
"target_path must exist at this point",
)?;
if_error(
working_path.exists(),
"working_path cannot exist at this point",
)?;
let s = read_to_string(&target_path).await?;
if s != "first" {
let text = format!(
"target_path file must contain \"first\"; instead it contains \"{}\"",
s
);
return Err(std::io::Error::new(ErrorKind::Other, text).into());
}
let p = phazer_new(&target_path);
let working_path = p.working_path().to_path_buf();
if_error(
!target_path.exists(),
"target_path cannot exist at this point",
)?;
if_error(
working_path.exists(),
"working_path cannot exist at this point",
)?;
let mut w = p.tokio_writer().await?;
w.write_all("second".as_bytes()).await?;
drop(w);
if_error(
!working_path.exists(),
"working_path must exist at this point",
)?;
if_error(
!target_path.exists(),
"target_path must exist at this point",
)?;
p.commit()?;
if_error(
!target_path.exists(),
"target_path must exist at this point",
)?;
if_error(
working_path.exists(),
"working_path cannot exist at this point",
)?;
let s = read_to_string(&target_path).await?;
if s != "second" {
let text = format!(
"target_path file must contain \"second\"; instead it contains \"{}\"",
s
);
return Err(std::io::Error::new(ErrorKind::Other, text).into());
}
let _ = remove_file(&target_path).await;
Ok(())
}
#[tokio::test]
async fn write_commit_using_default_constructor_works() -> Result<(), Box<dyn std::error::Error>>
{
write_commit_works(|p| Phazer::new(p), WRITE_COMMIT_TOKIO_DEFAULT).await
}
#[tokio::test]
async fn write_commit_using_simple_rename_works() -> Result<(), Box<dyn std::error::Error>> {
write_commit_works(
|p| {
PhazerBuilder::new()
.commit_strategy(SIMPLE_RENAME_STRATEGY)
.target(p)
.build()
},
WRITE_COMMIT_TOKIO_RENAME,
)
.await
}
#[tokio::test]
async fn write_commit_using_rename_with_retry_works() -> Result<(), Box<dyn std::error::Error>>
{
write_commit_works(
|p| {
PhazerBuilder::new()
.commit_strategy(RENAME_WITH_RETRY_STRATEGY)
.target(p)
.build()
},
WRITE_COMMIT_TOKIO_WITH_RETRY,
)
.await
}
}