#![cfg(feature = "update-tests")]
use std::process::Command;
fn is_ci_environment() -> bool {
std::env::var("CI").is_ok()
|| std::env::var("GITHUB_ACTIONS").is_ok()
|| (std::env::var("USER").as_deref() == Ok("root")
&& std::path::Path::new("/.dockerenv").exists())
|| std::env::var("HOME").as_deref() == Ok("/root")
}
fn get_binary_path() -> Option<&'static str> {
let path = "../../target/x86_64-unknown-linux-gnu/release/terraphim-agent";
if std::path::Path::new(path).exists() {
Some(path)
} else {
None
}
}
#[tokio::test]
async fn test_check_update_command() {
let Some(binary_path) = get_binary_path() else {
println!("Test skipped - terraphim-agent binary not found (expected in CI)");
return;
};
let output = Command::new(binary_path)
.arg("check-update")
.output()
.expect("Failed to execute check-update command");
assert!(
output.status.success(),
"check-update command should succeed"
);
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout.contains("Checking for terraphim-agent updates"),
"Should show checking message"
);
assert!(
stdout.contains("Already running latest version") || stdout.contains("Update available:"),
"Should show either up-to-date or update available message"
);
}
#[tokio::test]
async fn test_update_command_no_update_available() {
let Some(binary_path) = get_binary_path() else {
println!("Test skipped - terraphim-agent binary not found (expected in CI)");
return;
};
let output = Command::new(binary_path)
.arg("update")
.output()
.expect("Failed to execute update command");
assert!(output.status.success(), "update command should succeed");
let stdout = String::from_utf8_lossy(&output.stdout);
assert!(
stdout.contains("Updating terraphim-agent"),
"Should show updating message"
);
assert!(
stdout.contains("Already running latest version"),
"Should show already up to date message"
);
}
#[tokio::test]
async fn test_update_function_with_invalid_binary() {
if is_ci_environment() {
println!("Test skipped in CI - network-dependent test");
return;
}
use terraphim_update::check_for_updates;
let result = check_for_updates("non-existent-binary").await;
match result {
Ok(status) => {
let status_str = format!("{}", status);
assert!(!status_str.is_empty(), "Should return some status");
}
Err(e) => {
assert!(!e.to_string().is_empty(), "Error should have message");
}
}
}
#[tokio::test]
async fn test_version_comparison_logic() {
use terraphim_update::{TerraphimUpdater, UpdaterConfig};
let config = UpdaterConfig::new("test").with_version("1.0.0");
assert_eq!(config.bin_name, "test");
assert_eq!(config.current_version, "1.0.0");
let updater = TerraphimUpdater::new(config.clone());
let result = updater.check_update().await;
assert!(
result.is_ok() || result.is_err(),
"Should return some result"
);
}
#[tokio::test]
async fn test_updater_configuration() {
use terraphim_update::{TerraphimUpdater, UpdaterConfig};
let config = UpdaterConfig::new("terraphim-agent");
assert_eq!(config.bin_name, "terraphim-agent");
assert_eq!(config.repo_owner, "terraphim");
assert_eq!(config.repo_name, "terraphim-ai");
assert!(config.show_progress);
let config = UpdaterConfig::new("test-binary")
.with_version("1.0.0")
.with_progress(false);
assert_eq!(config.bin_name, "test-binary");
assert_eq!(config.current_version, "1.0.0");
assert!(!config.show_progress);
let updater = TerraphimUpdater::new(config);
let result = updater.check_update().await;
assert!(
result.is_ok() || result.is_err(),
"Should return some result"
);
}
#[tokio::test]
async fn test_github_release_connectivity() {
if is_ci_environment() {
println!("Test skipped in CI - network-dependent test");
return;
}
use terraphim_update::{TerraphimUpdater, UpdaterConfig};
let config = UpdaterConfig::new("terraphim-agent");
let updater = TerraphimUpdater::new(config);
match updater.check_update().await {
Ok(status) => {
let status_str = format!("{}", status);
assert!(!status_str.is_empty(), "Status should not be empty");
}
Err(e) => {
assert!(!e.to_string().is_empty(), "Error should have message");
}
}
}
#[tokio::test]
async fn test_update_help_messages() {
let Some(binary_path) = get_binary_path() else {
println!("Test skipped - terraphim-agent binary not found (expected in CI)");
return;
};
let output = Command::new(binary_path)
.arg("check-update")
.arg("--help")
.output()
.expect("Failed to execute check-update --help");
assert!(
output.status.success(),
"check-update --help should succeed"
);
let help_text = String::from_utf8_lossy(&output.stdout);
assert!(!help_text.is_empty(), "Help text should not be empty");
let output = Command::new(binary_path)
.arg("update")
.arg("--help")
.output()
.expect("Failed to execute update --help");
assert!(output.status.success(), "update --help should succeed");
let help_text = String::from_utf8_lossy(&output.stdout);
assert!(!help_text.is_empty(), "Help text should not be empty");
}
#[tokio::test]
async fn test_concurrent_update_checks() {
use terraphim_update::check_for_updates;
use tokio::task::JoinSet;
let mut set = JoinSet::new();
for _ in 0..5 {
set.spawn(async move { check_for_updates("terraphim-agent").await });
}
let mut results = Vec::new();
while let Some(result) = set.join_next().await {
match result {
Ok(update_result) => {
results.push(update_result);
}
Err(e) => {
println!("Join error: {}", e);
}
}
}
assert_eq!(
results.len(),
5,
"All concurrent operations should complete"
);
for result in results {
match result {
Ok(status) => {
let status_str = format!("{}", status);
assert!(!status_str.is_empty(), "Status should not be empty");
}
Err(e) => {
assert!(!e.to_string().is_empty(), "Error should have message");
}
}
}
}
#[tokio::test]
async fn test_update_commands_integration() {
let Some(binary_path) = get_binary_path() else {
println!("Test skipped - terraphim-agent binary not found (expected in CI)");
return;
};
let output = Command::new(binary_path)
.arg("--help")
.output()
.expect("Failed to execute --help");
assert!(output.status.success(), "--help should succeed");
let help_text = String::from_utf8_lossy(&output.stdout);
assert!(
help_text.contains("check-update"),
"check-update should be in help"
);
assert!(help_text.contains("update"), "update should be in help");
assert!(
help_text.contains("Check for updates without installing"),
"check-update description should be present"
);
assert!(
help_text.contains("Update to latest version if available"),
"update description should be present"
);
}