#[allow(dead_code)]
mod common;
use crate::common::integ_dev_server_config;
use anyhow::{anyhow, bail};
use clap::Parser;
use common::INTEG_SERVER_TARGET_ENV_VAR;
use std::{
env,
path::{Path, PathBuf},
process::Stdio,
};
use temporalio_sdk_core::ephemeral_server::{TestServerConfig, default_cached_download};
use tokio::{self, process::Command};
const INTEG_TEMPORAL_DEV_SERVER_USED_ENV_VAR: &str = "INTEG_TEMPORAL_DEV_SERVER_ON";
const INTEG_TEST_SERVER_USED_ENV_VAR: &str = "INTEG_TEST_SERVER_ON";
#[derive(clap::Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
#[arg(short, long, default_value = "integ_tests")]
test_name: String,
#[arg(short, long, value_enum, default_value = "temporal-cli")]
server_kind: ServerKind,
#[arg(short, long, allow_hyphen_values(true))]
cargo_test_args: Vec<String>,
#[arg(long)]
just_build: bool,
harness_args: Vec<String>,
}
#[derive(Copy, Clone, PartialEq, Eq, clap::ValueEnum)]
enum ServerKind {
TemporalCLI,
TestServer,
External,
}
#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
let Cli {
test_name,
server_kind,
cargo_test_args,
just_build,
harness_args,
} = Cli::parse();
let cargo = env::var("CARGO").unwrap_or_else(|_| "cargo".to_string());
let test_args_preamble = [
"test",
"--features",
"temporalio-common/serde_serialize",
"--features",
"test-utilities",
"--features",
"ephemeral-server",
"--features",
"temporalio-sdk-core/otel",
"--test",
&test_name,
]
.into_iter()
.map(ToString::to_string)
.chain(cargo_test_args)
.collect::<Vec<_>>();
let mut build_cmd = Command::new(&cargo);
strip_cargo_env_vars(&mut build_cmd);
let status = build_cmd
.args([test_args_preamble.as_slice(), &["--no-run".to_string()]].concat())
.status()
.await?;
if !status.success() {
bail!("Building integration tests failed!");
}
if just_build {
return Ok(());
}
let (server, envs) = match server_kind {
ServerKind::TemporalCLI => {
let config =
integ_dev_server_config(vec!["--http-port".to_string(), "7243".to_string()], true);
println!("Using temporal CLI: {config:?}");
(
Some(
config
.start_server_with_output(Stdio::null(), Stdio::null())
.await?,
),
vec![(INTEG_TEMPORAL_DEV_SERVER_USED_ENV_VAR, "true")],
)
}
ServerKind::TestServer => {
let config = TestServerConfig::builder()
.exe(default_cached_download())
.build();
println!("Using java test server");
(
Some(
config
.start_server_with_output(Stdio::null(), Stdio::null())
.await?,
),
vec![(INTEG_TEST_SERVER_USED_ENV_VAR, "true")],
)
}
ServerKind::External => {
println!("========================================================");
println!("Not starting up a server. One should be running already.");
println!("========================================================");
(None, vec![])
}
};
let mut cmd = Command::new(&cargo);
strip_cargo_env_vars(&mut cmd);
if let Some(srv) = server.as_ref() {
println!("Running on {}", srv.target);
cmd.env(
INTEG_SERVER_TARGET_ENV_VAR,
format!("http://{}", &srv.target),
);
}
let status = cmd
.envs(envs)
.current_dir(project_root())
.args(
test_args_preamble
.into_iter()
.chain(["--".to_string()])
.chain(harness_args),
)
.status()
.await?;
if let Some(mut srv) = server {
srv.shutdown().await?;
}
if status.success() {
Ok(())
} else {
Err(anyhow!("Integ tests failed!"))
}
}
fn strip_cargo_env_vars(build_cmd: &mut Command) {
let envs = env::vars().filter(|(k, _)| k.starts_with("CARGO_"));
for (k, _) in envs {
build_cmd.env_remove(k);
}
}
fn project_root() -> PathBuf {
Path::new(&env!("CARGO_MANIFEST_DIR"))
.ancestors()
.nth(1)
.unwrap()
.to_path_buf()
}