use std::process::Command;
use std::{thread, time};
use tempfile::tempdir;
#[test]
fn test_concurrent_processes_access() -> anyhow::Result<()> {
let temp = tempdir()?;
let db_path = temp.path();
let output = Command::new("cargo")
.args(["run", "--", "put", "--key", "foo", "--value", "bar"])
.env("BITASK_PATH", db_path.to_str().unwrap())
.output()?;
assert!(output.status.success());
let output = Command::new("cargo")
.args(["run", "--", "ask", "--key", "foo"])
.env("BITASK_PATH", db_path.to_str().unwrap())
.output()?;
assert!(output.status.success());
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "bar");
Ok(())
}
#[test]
fn test_process_lock_contention() -> anyhow::Result<()> {
let temp = tempdir()?;
let db_path = temp.path();
let _db = bitask::db::Bitask::open(db_path)?;
let output = Command::new("cargo")
.args(["run", "--", "put", "--key", "foo", "--value", "bar"])
.env("BITASK_PATH", db_path.to_str().unwrap())
.output()?;
assert!(!output.status.success());
Ok(())
}
#[test]
fn test_process_recovery_after_crash() -> anyhow::Result<()> {
let temp = tempdir()?;
let db_path = temp.path();
let output = Command::new("cargo")
.args(["run", "--", "put", "--key", "foo", "--value", "bar"])
.env("BITASK_PATH", db_path.to_str().unwrap())
.output()?;
assert!(output.status.success());
let mut child = Command::new("cargo")
.args(["run", "--", "put", "--key", "foo2", "--value", "bar2"])
.env("BITASK_PATH", db_path.to_str().unwrap())
.spawn()?;
thread::sleep(time::Duration::from_millis(100));
child.kill()?;
let output = Command::new("cargo")
.args(["run", "--", "ask", "--key", "foo"])
.env("BITASK_PATH", db_path.to_str().unwrap())
.output()?;
assert!(output.status.success());
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "bar");
Ok(())
}
#[test]
fn test_lock_file_cleanup() -> anyhow::Result<()> {
let temp = tempdir()?;
let db_path = temp.path();
let lock_path = db_path.join("db.lock");
let output = Command::new("cargo")
.args(["run", "--", "put", "--key", "foo", "--value", "bar"])
.env("BITASK_PATH", db_path.to_str().unwrap())
.output()?;
assert!(output.status.success());
assert!(
!lock_path.exists(),
"Lock file still exists after process exit"
);
let output = Command::new("cargo")
.args(["run", "--", "ask", "--key", "foo"])
.env("BITASK_PATH", db_path.to_str().unwrap())
.output()?;
assert!(output.status.success());
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "bar");
Ok(())
}
#[test]
fn test_sequential_opens() -> anyhow::Result<()> {
let temp = tempdir()?;
{
let _db = bitask::db::Bitask::open(temp.path())?;
}
{
let _db = bitask::db::Bitask::open(temp.path())?;
}
Ok(())
}