7b3b71a4b3
- Remove underscore suffix from FINALIZE_SHELL_ENVPREFIX constant - Split FINALIZE_PLUGIN_MANIFEST into name + extensions for flexible manifest discovery - Add ManifestNotFound error variant for clearer plugin loading errors - Add debug logging for plugin download operations - Add integration tests for finalize hook execution - Remove obsolete clarification.md
207 lines
5.5 KiB
Rust
207 lines
5.5 KiB
Rust
//! Integration tests for workshop-executor engine
|
|
//!
|
|
//! These tests execute real commands and verify results.
|
|
//! Run with: cargo test --test engine_integration
|
|
//!
|
|
//! Note: These are TRUE integration tests - they run in a separate test binary
|
|
//! and execute actual commands on the system.
|
|
|
|
use std::collections::HashMap;
|
|
use std::path::PathBuf;
|
|
use std::time::Duration;
|
|
use workshop_baker::engine::{Engine, ExecutionContext};
|
|
|
|
fn create_executor() -> Engine {
|
|
Engine::new()
|
|
}
|
|
|
|
fn create_context() -> ExecutionContext {
|
|
ExecutionContext {
|
|
task_id: "test-integration-1".to_string(),
|
|
pipeline_name: "test-pipeline".to_string(),
|
|
username: "testuser".to_string(),
|
|
working_dir: std::env::temp_dir(),
|
|
env_vars: HashMap::new(),
|
|
timeout: Some(Duration::from_secs(30)),
|
|
cgroup_path: None,
|
|
shell: "bash".to_string(),
|
|
dry_run: false,
|
|
privileged: false,
|
|
standalone: false,
|
|
}
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_execute_echo_outputs_correct_message() {
|
|
let executor = create_executor();
|
|
let ctx = create_context();
|
|
|
|
use tokio::process::Command;
|
|
let mut cmd = Command::new("echo");
|
|
cmd.arg("hello world");
|
|
|
|
let result = executor.execute(cmd, &ctx, &None).await.unwrap();
|
|
|
|
assert!(result.success);
|
|
assert_eq!(result.exit_code, 0);
|
|
assert!(result.stdout.contains("hello world"));
|
|
assert!(result.stderr.is_empty());
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_execute_true_returns_zero_exit_code() {
|
|
let executor = create_executor();
|
|
let ctx = create_context();
|
|
|
|
use tokio::process::Command;
|
|
let cmd = Command::new("true");
|
|
|
|
let result = executor.execute(cmd, &ctx, &None).await.unwrap();
|
|
|
|
assert!(result.success);
|
|
assert_eq!(result.exit_code, 0);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_execute_false_returns_nonzero_exit_code() {
|
|
let executor = create_executor();
|
|
let ctx = create_context();
|
|
|
|
use tokio::process::Command;
|
|
let cmd = Command::new("false");
|
|
|
|
let result = executor.execute(cmd, &ctx, &None).await;
|
|
|
|
assert!(result.is_err());
|
|
// assert!(!result.success);
|
|
// assert_ne!(result.exit_code, 0);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_execute_ls_lists_directory() {
|
|
let executor = create_executor();
|
|
let ctx = create_context();
|
|
|
|
use tokio::process::Command;
|
|
let mut cmd = Command::new("ls");
|
|
cmd.arg("-la");
|
|
cmd.arg("/tmp");
|
|
|
|
let result = executor.execute(cmd, &ctx, &None).await.unwrap();
|
|
|
|
assert!(result.success);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_execute_date_command() {
|
|
let executor = create_executor();
|
|
let ctx = create_context();
|
|
|
|
use tokio::process::Command;
|
|
let cmd = Command::new("date");
|
|
|
|
let result = executor.execute(cmd, &ctx, &None).await.unwrap();
|
|
|
|
assert!(result.success);
|
|
assert!(!result.stdout.trim().is_empty());
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_execute_invalid_command_returns_error() {
|
|
let executor = create_executor();
|
|
let ctx = create_context();
|
|
|
|
use tokio::process::Command;
|
|
let cmd = Command::new("this_command_definitely_does_not_exist_12345");
|
|
|
|
let result = executor.execute(cmd, &ctx, &None).await;
|
|
|
|
assert!(result.is_err());
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_execute_passes_custom_env_var() {
|
|
let executor = create_executor();
|
|
let mut ctx = create_context();
|
|
ctx.env_vars
|
|
.insert("MY_CUSTOM_VAR".to_string(), "my_value_123".to_string());
|
|
|
|
use tokio::process::Command;
|
|
let cmd = Command::new("env");
|
|
|
|
let result = executor.execute(cmd, &ctx, &None).await.unwrap();
|
|
|
|
assert!(result.stdout.contains("MY_CUSTOM_VAR=my_value_123"));
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_execute_sets_ws_taskid() {
|
|
let executor = create_executor();
|
|
let mut ctx = create_context();
|
|
ctx.task_id = "task-abc-123".to_string();
|
|
ctx.pipeline_name = "pipeline-xyz".to_string();
|
|
|
|
use tokio::process::Command;
|
|
let cmd = Command::new("env");
|
|
|
|
let result = executor.execute(cmd, &ctx, &None).await.unwrap();
|
|
|
|
assert!(result.stdout.contains("HBW_TASKID=task-abc-123"));
|
|
assert!(result.stdout.contains("HBW_PIPELINE=pipeline-xyz"));
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_execute_sets_ws_user_info() {
|
|
let executor = create_executor();
|
|
let ctx = create_context();
|
|
|
|
use tokio::process::Command;
|
|
let cmd = Command::new("env");
|
|
|
|
let result = executor.execute(cmd, &ctx, &None).await.unwrap();
|
|
|
|
assert!(result.stdout.contains("HBW_USERNAME=testuser"));
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_execute_respects_working_directory() {
|
|
let executor = create_executor();
|
|
let ctx = ExecutionContext {
|
|
task_id: "test-context-1".to_string(),
|
|
pipeline_name: "test-pipeline".to_string(),
|
|
username: "testuser".to_string(),
|
|
working_dir: PathBuf::from("/tmp"),
|
|
env_vars: HashMap::new(),
|
|
timeout: Some(Duration::from_secs(30)),
|
|
cgroup_path: None,
|
|
shell: "bash".to_string(),
|
|
standalone: false,
|
|
..Default::default()
|
|
};
|
|
|
|
use tokio::process::Command;
|
|
let cmd = Command::new("pwd");
|
|
|
|
let result = executor.execute(cmd, &ctx, &None).await.unwrap();
|
|
|
|
assert!(result.success);
|
|
let trimmed = result.stdout.trim();
|
|
assert!(trimmed == "/tmp" || trimmed.ends_with("tmp"));
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_execute_captures_stderr() {
|
|
let executor = create_executor();
|
|
let ctx = create_context();
|
|
|
|
use tokio::process::Command;
|
|
let mut cmd = Command::new("bash");
|
|
cmd.arg("-c");
|
|
cmd.arg("echo error >&2");
|
|
|
|
let result = executor.execute(cmd, &ctx, &None).await.unwrap();
|
|
|
|
assert!(result.success);
|
|
assert!(result.stderr.contains("error"));
|
|
}
|