use anyhow::Result;
use std::path::PathBuf;
use tempfile::TempDir;
pub struct TestFixture {
pub temp_dir: TempDir,
pub workflow_path: Option<PathBuf>,
pub checkpoint_dir: PathBuf,
pub session_id: String,
}
impl TestFixture {
pub async fn new() -> Result<Self> {
let temp_dir = TempDir::new()?;
let checkpoint_dir = temp_dir.path().join("checkpoints");
tokio::fs::create_dir_all(&checkpoint_dir).await?;
let session_id = format!("test-session-{}", uuid::Uuid::new_v4());
Ok(Self {
temp_dir,
workflow_path: None,
checkpoint_dir,
session_id,
})
}
pub async fn with_session_id(session_id: impl Into<String>) -> Result<Self> {
let temp_dir = TempDir::new()?;
let checkpoint_dir = temp_dir.path().join("checkpoints");
tokio::fs::create_dir_all(&checkpoint_dir).await?;
Ok(Self {
temp_dir,
workflow_path: None,
checkpoint_dir,
session_id: session_id.into(),
})
}
pub fn temp_path(&self) -> &std::path::Path {
self.temp_dir.path()
}
pub fn set_workflow_path(&mut self, path: PathBuf) {
self.workflow_path = Some(path);
}
pub fn checkpoint_path(&self) -> PathBuf {
self.checkpoint_dir
.join(format!("{}.json", self.session_id))
}
pub async fn create_simple_workflow(&mut self) -> Result<PathBuf> {
let path = super::workflow_helpers::create_simple_workflow(self.temp_path()).await?;
self.workflow_path = Some(path.clone());
Ok(path)
}
pub async fn create_failing_workflow(&mut self, fail_at_step: usize) -> Result<PathBuf> {
let path =
super::workflow_helpers::create_failing_workflow(self.temp_path(), fail_at_step)
.await?;
self.workflow_path = Some(path.clone());
Ok(path)
}
pub async fn create_mapreduce_workflow(
&mut self,
num_items: usize,
) -> Result<(PathBuf, PathBuf)> {
let (workflow_path, items_path) =
super::workflow_helpers::create_mapreduce_workflow(self.temp_path(), num_items)
.await?;
self.workflow_path = Some(workflow_path.clone());
Ok((workflow_path, items_path))
}
pub async fn corrupt_checkpoint(&self) -> Result<()> {
super::checkpoint_helpers::corrupt_checkpoint_file(&self.checkpoint_path()).await
}
pub async fn remove_workflow_file(&self) -> Result<()> {
if let Some(ref path) = self.workflow_path {
tokio::fs::remove_file(path).await?;
}
Ok(())
}
pub async fn modify_workflow(&self) -> Result<()> {
if let Some(ref path) = self.workflow_path {
super::workflow_helpers::modify_workflow_file(path).await?;
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_fixture_creation() -> Result<()> {
let fixture = TestFixture::new().await?;
assert!(fixture.temp_path().exists());
assert!(fixture.checkpoint_dir.exists());
assert!(!fixture.session_id.is_empty());
Ok(())
}
#[tokio::test]
async fn test_fixture_with_workflow() -> Result<()> {
let mut fixture = TestFixture::new().await?;
let workflow_path = fixture.create_simple_workflow().await?;
assert!(workflow_path.exists());
assert_eq!(fixture.workflow_path, Some(workflow_path));
Ok(())
}
}