use git_proc::Build;
const GIT_COMMITTER_DATE: cmd_proc::EnvVariableName =
cmd_proc::EnvVariableName::from_static_or_panic("GIT_COMMITTER_DATE");
#[allow(dead_code)]
pub static POSTGRES_IMAGE: std::sync::LazyLock<ociman::image::Reference> =
std::sync::LazyLock::new(|| "docker.io/library/postgres:17".parse().unwrap());
#[allow(dead_code)]
pub static RUBY_IMAGE: std::sync::LazyLock<ociman::image::Reference> =
std::sync::LazyLock::new(|| "docker.io/ruby:3.4-alpine".parse().unwrap());
#[allow(dead_code)]
pub static NODE_IMAGE: std::sync::LazyLock<ociman::image::Reference> =
std::sync::LazyLock::new(|| "docker.io/node:22-alpine".parse().unwrap());
#[allow(dead_code)]
#[must_use]
pub fn test_definition(backend: ociman::Backend) -> pg_ephemeral::Definition {
pg_ephemeral::Definition::new(
backend,
pg_ephemeral::Image::default(),
"test".parse().unwrap(),
)
.wait_available_timeout(std::time::Duration::from_secs(30))
}
#[allow(dead_code)]
pub async fn run_pg_ephemeral(args: &[&str], current_dir: &std::path::Path) -> String {
let pg_ephemeral_bin = env!("CARGO_BIN_EXE_pg-ephemeral");
let output = cmd_proc::Command::new(pg_ephemeral_bin)
.arguments(args)
.working_directory(current_dir)
.stdout_capture()
.stderr_capture()
.accept_nonzero_exit()
.run()
.await
.unwrap();
assert!(
output.status.success(),
"pg-ephemeral {} failed:\nstdout:\n{}\nstderr:\n{}",
args.join(" "),
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
);
String::from_utf8(output.stdout).unwrap()
}
#[allow(dead_code)]
pub struct TestDir {
pub path: std::path::PathBuf,
}
#[allow(dead_code)]
impl TestDir {
#[must_use]
pub fn new(name_suffix: &str) -> Self {
let path = std::env::temp_dir().join(format!(
"pg-ephemeral-{}-{}",
name_suffix,
std::process::id()
));
std::fs::create_dir_all(&path).unwrap();
Self { path }
}
pub fn write_file(&self, name: &str, content: &str) {
std::fs::write(self.path.join(name), content).unwrap();
}
}
impl Drop for TestDir {
fn drop(&mut self) {
let _ = std::fs::remove_dir_all(&self.path);
}
}
#[allow(dead_code)]
pub struct TestGitRepo {
pub path: std::path::PathBuf,
}
impl TestGitRepo {
#[allow(dead_code)]
pub async fn new(name_suffix: &str) -> Self {
let path = std::env::temp_dir().join(format!(
"pg-ephemeral-{}-{}",
name_suffix,
std::process::id()
));
std::fs::create_dir_all(&path).unwrap();
git_proc::init::new()
.directory(&path)
.status()
.await
.unwrap();
git_proc::config::new("user.name")
.repo_path(&path)
.value("Test User")
.status()
.await
.unwrap();
git_proc::config::new("user.email")
.repo_path(&path)
.value("test@example.com")
.status()
.await
.unwrap();
Self { path }
}
#[allow(dead_code)]
pub fn write_file(&self, name: &str, content: &str) {
std::fs::write(self.path.join(name), content).unwrap();
}
#[allow(dead_code)]
pub async fn commit(&self, message: &str) -> String {
git_proc::add::new()
.repo_path(&self.path)
.pathspec(".")
.status()
.await
.unwrap();
git_proc::commit::new()
.repo_path(&self.path)
.message(message)
.author("Test User <test@example.com>")
.date("2020-01-01T00:00:00Z")
.env(
GIT_COMMITTER_DATE,
std::ffi::OsStr::new("2020-01-01T00:00:00Z"),
)
.status()
.await
.unwrap();
git_proc::rev_parse::new()
.repo_path(&self.path)
.rev("HEAD")
.build()
.stdout_capture()
.string()
.await
.unwrap()
.trim()
.to_string()
}
}
impl Drop for TestGitRepo {
fn drop(&mut self) {
let _ = std::fs::remove_dir_all(&self.path);
}
}
#[allow(dead_code)]
pub async fn test_database_url_integration(
language: &str,
image_dir: &str,
base_image: &ociman::image::Reference,
) {
let backend = ociman::test_backend_setup!();
let definition = test_definition(backend.clone()).cross_container_access(true);
definition
.with_container(async |container| {
let image_tag =
ociman::testing::test_reference(&format!("pg-ephemeral-{language}-test:latest"))
.to_string();
backend
.command()
.argument("build")
.argument("--build-arg")
.argument(format!("BASE_IMAGE={base_image}"))
.argument("--tag")
.argument(&image_tag)
.argument(image_dir)
.stdout_capture()
.bytes()
.await
.unwrap();
let database_url = container
.cross_container_client_config()
.await
.to_url_string();
let stdout = backend
.command()
.argument("run")
.argument("--rm")
.argument("--env")
.argument(format!("DATABASE_URL={database_url}"))
.argument(&image_tag)
.stdout_capture()
.string()
.await
.unwrap_or_else(|error| panic!("Failed to run {language} container: {error:?}"));
assert!(
stdout.contains("SUCCESS: Connected to PostgreSQL successfully"),
"Expected success message not found in output.\nOutput: {stdout}"
);
})
.await
.unwrap()
}