use std::env::consts::EXE_SUFFIX;
use axoasset::LocalAsset;
use axoprocess::Cmd;
use camino::{Utf8Path, Utf8PathBuf};
use tempfile::TempDir;
static BIN: &str = env!("CARGO_BIN_EXE_axoupdater");
static RECEIPT_TEMPLATE: &str = r#"{"binaries":["axolotlsay"],"install_prefix":"INSTALL_PREFIX","provider":{"source":"cargo-dist","version":"CARGO_DIST_VERSION"},"source":{"app_name":"axolotlsay","name":"cargodisttest","owner":"mistydemeo","release_type":"github"},"version":"VERSION"}"#;
fn triple() -> String {
match std::env::consts::OS {
"windows" => "x86_64-pc-windows-msvc".to_owned(),
"macos" => {
if std::env::consts::ARCH == "x86_64" {
"x86_64-apple-darwin".to_owned()
} else {
"aarch64-apple-darwin".to_owned()
}
}
"linux" => {
if std::env::consts::ARCH == "x86_64" {
"x86_64-unknown-linux-gnu".to_owned()
} else {
"aarch64-unknown-linux-gnu".to_owned()
}
}
_ => unimplemented!(),
}
}
fn axolotlsay_tarball_path(version: &str) -> String {
let triple = triple();
format!("https://github.com/mistydemeo/cargodisttest/releases/download/v{version}/axolotlsay-{triple}.tar.gz")
}
fn install_receipt(version: &str, cargo_dist_version: &str, prefix: &Utf8PathBuf) -> String {
RECEIPT_TEMPLATE
.replace("INSTALL_PREFIX", &prefix.to_string().replace('\\', "\\\\"))
.replace("CARGO_DIST_VERSION", cargo_dist_version)
.replace("VERSION", version)
}
fn write_receipt(
version: &str,
cargo_dist_version: &str,
prefix: &Utf8PathBuf,
) -> std::io::Result<()> {
let contents = install_receipt(version, cargo_dist_version, prefix);
let receipt_name = prefix.join("axolotlsay-receipt.json");
LocalAsset::write_new(&contents, receipt_name).unwrap();
Ok(())
}
#[test]
fn bails_out_with_default_name() {
let mut command = Cmd::new(BIN, "execute axoupdater");
command.check(false);
let result = command.output().unwrap();
assert!(!result.status.success());
let stderr_string = String::from_utf8(result.stderr).unwrap();
assert!(stderr_string.contains("App name calculated as `axoupdater'"));
}
#[test]
fn test_upgrade() -> std::io::Result<()> {
let tempdir = TempDir::new()?;
let bindir_path = &tempdir.path().join("bin");
let bindir = Utf8Path::from_path(bindir_path).unwrap();
std::fs::create_dir_all(bindir)?;
let base_version = "0.2.115";
let url = axolotlsay_tarball_path(base_version);
let compressed_path =
Utf8PathBuf::from_path_buf(tempdir.path().join("axolotlsay.tar.gz")).unwrap();
let client = axoasset::AxoClient::with_reqwest(axoasset::reqwest::Client::new());
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(client.load_and_write_to_file(&url, &compressed_path))
.unwrap();
write_receipt(base_version, "0.11.1", &bindir.to_path_buf())?;
LocalAsset::untar_gz_all(&compressed_path, bindir).unwrap();
let updater_path = bindir.join(format!("axolotlsay-update{EXE_SUFFIX}"));
std::fs::copy(BIN, &updater_path)?;
let mut updater = Cmd::new(&updater_path, "run updater");
updater.env("AXOUPDATER_CONFIG_PATH", bindir);
updater.check(false);
let res = updater.output().unwrap();
let output_stdout = String::from_utf8(res.stdout).unwrap();
let output_stderr = String::from_utf8(res.stderr).unwrap();
let new_axolotlsay_path = &bindir.join(format!("axolotlsay{EXE_SUFFIX}"));
assert!(
new_axolotlsay_path.exists(),
"update result was\nstdout\n{}\nstderr\n{}",
output_stdout,
output_stderr
);
let mut new_axolotlsay = Cmd::new(new_axolotlsay_path, "version test");
new_axolotlsay.arg("--version");
let output = new_axolotlsay.output().unwrap();
let stderr_string = String::from_utf8(output.stdout).unwrap();
assert!(stderr_string.starts_with("axolotlsay "));
assert_ne!(stderr_string, format!("axolotlsay {}\n", base_version));
Ok(())
}
#[test]
fn test_upgrade_allow_prerelease() -> std::io::Result<()> {
let tempdir = TempDir::new()?;
let bindir_path = &tempdir.path().join("bin");
let bindir = Utf8Path::from_path(bindir_path).unwrap();
std::fs::create_dir_all(bindir)?;
let base_version = "0.2.115";
let url = axolotlsay_tarball_path(base_version);
let compressed_path =
Utf8PathBuf::from_path_buf(tempdir.path().join("axolotlsay.tar.gz")).unwrap();
let client = axoasset::AxoClient::with_reqwest(axoasset::reqwest::Client::new());
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(client.load_and_write_to_file(&url, &compressed_path))
.unwrap();
write_receipt(base_version, "0.11.1", &bindir.to_path_buf())?;
LocalAsset::untar_gz_all(&compressed_path, bindir).unwrap();
let updater_path = bindir.join(format!("axolotlsay-update{EXE_SUFFIX}"));
std::fs::copy(BIN, &updater_path)?;
let mut updater = Cmd::new(&updater_path, "run updater");
updater.env("AXOUPDATER_CONFIG_PATH", bindir);
updater.arg("--prerelease");
updater.check(false);
let res = updater.output().unwrap();
let output_stdout = String::from_utf8(res.stdout).unwrap();
let output_stderr = String::from_utf8(res.stderr).unwrap();
let new_axolotlsay_path = &bindir.join(format!("axolotlsay{EXE_SUFFIX}"));
assert!(
new_axolotlsay_path.exists(),
"update result was\nstdout\n{}\nstderr\n{}",
output_stdout,
output_stderr
);
let mut new_axolotlsay = Cmd::new(new_axolotlsay_path, "version test");
new_axolotlsay.arg("--version");
let output = new_axolotlsay.output().unwrap();
let stderr_string = String::from_utf8(output.stdout).unwrap();
assert!(stderr_string.starts_with("axolotlsay "));
assert_ne!(stderr_string, format!("axolotlsay {}\n", base_version));
Ok(())
}
#[test]
fn test_upgrade_to_specific_version() -> std::io::Result<()> {
let tempdir = TempDir::new()?;
let bindir_path = &tempdir.path().join("bin");
let bindir = Utf8Path::from_path(bindir_path).unwrap();
std::fs::create_dir_all(bindir)?;
let base_version = "0.2.115";
let target_version = "0.2.116";
let url = axolotlsay_tarball_path(base_version);
let compressed_path =
Utf8PathBuf::from_path_buf(tempdir.path().join("axolotlsay.tar.gz")).unwrap();
let client = axoasset::AxoClient::with_reqwest(axoasset::reqwest::Client::new());
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(client.load_and_write_to_file(&url, &compressed_path))
.unwrap();
write_receipt(base_version, "0.11.1", &bindir.to_path_buf())?;
LocalAsset::untar_gz_all(&compressed_path, bindir).unwrap();
let updater_path = bindir.join(format!("axolotlsay-update{EXE_SUFFIX}"));
std::fs::copy(BIN, &updater_path)?;
let mut updater = Cmd::new(&updater_path, "run updater");
updater.arg("--version").arg(target_version);
updater.env("AXOUPDATER_CONFIG_PATH", bindir);
updater.check(false);
let _res = updater.output().unwrap();
let new_axolotlsay_path = &bindir.join(format!("axolotlsay{EXE_SUFFIX}"));
assert!(new_axolotlsay_path.exists());
let mut new_axolotlsay = Cmd::new(new_axolotlsay_path, "version test");
new_axolotlsay.arg("--version");
let output = new_axolotlsay.output().unwrap();
let stderr_string = String::from_utf8(output.stdout).unwrap();
assert_eq!(stderr_string, format!("axolotlsay {}\n", target_version));
Ok(())
}
#[test]
fn test_downgrade_to_specific_version() -> std::io::Result<()> {
let tempdir = TempDir::new()?;
let bindir_path = &tempdir.path().join("bin");
let bindir = Utf8Path::from_path(bindir_path).unwrap();
std::fs::create_dir_all(bindir)?;
let base_version = "0.2.116";
let target_version = "0.2.115";
let url = axolotlsay_tarball_path(base_version);
let compressed_path =
Utf8PathBuf::from_path_buf(tempdir.path().join("axolotlsay.tar.gz")).unwrap();
let client = axoasset::AxoClient::with_reqwest(axoasset::reqwest::Client::new());
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(client.load_and_write_to_file(&url, &compressed_path))
.unwrap();
write_receipt(base_version, "0.11.1", &bindir.to_path_buf())?;
LocalAsset::untar_gz_all(&compressed_path, bindir).unwrap();
let updater_path = bindir.join(format!("axolotlsay-update{EXE_SUFFIX}"));
std::fs::copy(BIN, &updater_path)?;
let mut updater = Cmd::new(&updater_path, "run updater");
updater.arg("--version").arg(target_version);
updater.env("AXOUPDATER_CONFIG_PATH", bindir);
updater.check(false);
let _res = updater.output().unwrap();
let new_axolotlsay_path = &bindir.join(format!("axolotlsay{EXE_SUFFIX}"));
assert!(new_axolotlsay_path.exists());
let mut new_axolotlsay = Cmd::new(new_axolotlsay_path, "version test");
new_axolotlsay.arg("--version");
let output = new_axolotlsay.output().unwrap();
let stderr_string = String::from_utf8(output.stdout).unwrap();
assert_eq!(stderr_string, format!("axolotlsay {}\n", target_version));
Ok(())
}
#[test]
fn test_downgrade_to_specific_old_version() -> std::io::Result<()> {
match std::env::consts::OS {
"linux" | "macos" => {
if std::env::consts::ARCH != "x86_64" {
return Ok(());
}
}
"windows" => return Ok(()),
_ => return Ok(()),
}
let tempdir = TempDir::new()?;
let bindir_path = &tempdir.path().join("bin");
let bindir = Utf8Path::from_path(bindir_path).unwrap();
std::fs::create_dir_all(bindir)?;
let base_version = "0.2.116";
let target_version = "0.2.50";
let url = axolotlsay_tarball_path(base_version);
let compressed_path =
Utf8PathBuf::from_path_buf(tempdir.path().join("axolotlsay.tar.gz")).unwrap();
let client = axoasset::AxoClient::with_reqwest(axoasset::reqwest::Client::new());
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(client.load_and_write_to_file(&url, &compressed_path))
.unwrap();
write_receipt(base_version, "0.11.1", &bindir.to_path_buf())?;
LocalAsset::untar_gz_all(&compressed_path, bindir).unwrap();
let updater_path = bindir.join(format!("axolotlsay-update{EXE_SUFFIX}"));
std::fs::copy(BIN, &updater_path)?;
let mut updater = Cmd::new(&updater_path, "run updater");
updater.arg("--version").arg(target_version);
updater.env("AXOUPDATER_CONFIG_PATH", bindir);
updater.env("CARGO_HOME", tempdir.path());
updater.check(false);
let _res = updater.output().unwrap();
let new_axolotlsay_path = &bindir.join(format!("axolotlsay{EXE_SUFFIX}"));
assert!(new_axolotlsay_path.exists());
let mut new_axolotlsay = Cmd::new(new_axolotlsay_path, "version test");
new_axolotlsay.arg("--version");
let output = new_axolotlsay.output().unwrap();
let stderr_string = String::from_utf8(output.stdout).unwrap();
assert_eq!(stderr_string, format!("axolotlsay {}\n", target_version));
Ok(())
}
#[test]
fn test_upgrade_from_prefix_with_no_bin() -> std::io::Result<()> {
let tempdir = TempDir::new()?;
let prefix = Utf8PathBuf::from_path_buf(tempdir.path().to_path_buf()).unwrap();
let bindir_path = &tempdir.path().join("bin");
let bindir = Utf8Path::from_path(bindir_path).unwrap();
std::fs::create_dir_all(bindir)?;
let base_version = "0.2.133";
let url = axolotlsay_tarball_path(base_version);
let compressed_path =
Utf8PathBuf::from_path_buf(tempdir.path().join("axolotlsay.tar.gz")).unwrap();
let client = axoasset::AxoClient::with_reqwest(axoasset::reqwest::Client::new());
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(client.load_and_write_to_file(&url, &compressed_path))
.unwrap();
write_receipt(base_version, "0.15.0", &prefix)?;
LocalAsset::untar_gz_all(&compressed_path, bindir).unwrap();
let updater_path = bindir.join(format!("axolotlsay-update{EXE_SUFFIX}"));
std::fs::copy(BIN, &updater_path)?;
let mut updater = Cmd::new(&updater_path, "run updater");
updater.env("AXOUPDATER_CONFIG_PATH", prefix);
updater.check(false);
let res = updater.output().unwrap();
let output_stdout = String::from_utf8(res.stdout).unwrap();
let output_stderr = String::from_utf8(res.stderr).unwrap();
let new_axolotlsay_path = &bindir.join(format!("axolotlsay{EXE_SUFFIX}"));
assert!(
new_axolotlsay_path.exists(),
"update result was\nstdout\n{}\nstderr\n{}",
output_stdout,
output_stderr
);
let mut new_axolotlsay = Cmd::new(new_axolotlsay_path, "version test");
new_axolotlsay.arg("--version");
let output = new_axolotlsay.output().unwrap();
let stderr_string = String::from_utf8(output.stdout).unwrap();
assert!(stderr_string.starts_with("axolotlsay "));
assert_ne!(stderr_string, format!("axolotlsay {}\n", base_version));
Ok(())
}