191 lines
5.2 KiB
Rust
191 lines
5.2 KiB
Rust
//! Integration test for the new job API
|
|
//!
|
|
//! This test demonstrates the complete job lifecycle and validates
|
|
//! that all new API methods work correctly together.
|
|
|
|
use hero_supervisor_openrpc_client::{SupervisorClient, JobBuilder, JobResult};
|
|
use std::time::Duration;
|
|
use tokio::time::sleep;
|
|
|
|
#[tokio::test]
|
|
async fn test_complete_job_lifecycle() -> Result<(), Box<dyn std::error::Error>> {
|
|
// Skip test if supervisor is not running
|
|
let client = match SupervisorClient::new("http://localhost:3030") {
|
|
Ok(c) => c,
|
|
Err(_) => {
|
|
println!("Skipping integration test - supervisor not available");
|
|
return Ok(());
|
|
}
|
|
};
|
|
|
|
// Test connection
|
|
if client.discover().await.is_err() {
|
|
println!("Skipping integration test - supervisor not responding");
|
|
return Ok(());
|
|
}
|
|
|
|
let secret = "user-secret-456";
|
|
|
|
// Test 1: Create job
|
|
let job = JobBuilder::new()
|
|
.caller_id("integration_test")
|
|
.context_id("test_lifecycle")
|
|
.payload("echo 'Integration test job'")
|
|
.executor("osis")
|
|
.runner("osis_runner_1")
|
|
.timeout(30)
|
|
.build()?;
|
|
|
|
let job_id = client.jobs_create(secret, job).await?;
|
|
assert!(!job_id.is_empty());
|
|
|
|
// Test 2: Start job
|
|
client.job_start(secret, &job_id).await?;
|
|
|
|
// Test 3: Monitor status
|
|
let mut attempts = 0;
|
|
let max_attempts = 15; // 15 seconds max
|
|
let mut final_status = String::new();
|
|
|
|
while attempts < max_attempts {
|
|
let status = client.job_status(&job_id).await?;
|
|
final_status = status.status.clone();
|
|
|
|
if final_status == "completed" || final_status == "failed" || final_status == "timeout" {
|
|
break;
|
|
}
|
|
|
|
attempts += 1;
|
|
sleep(Duration::from_secs(1)).await;
|
|
}
|
|
|
|
// Test 4: Get result
|
|
let result = client.job_result(&job_id).await?;
|
|
match result {
|
|
JobResult::Success { success: _ } => {
|
|
assert_eq!(final_status, "completed");
|
|
},
|
|
JobResult::Error { error: _ } => {
|
|
assert!(final_status == "failed" || final_status == "timeout");
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_job_run_immediate() -> Result<(), Box<dyn std::error::Error>> {
|
|
let client = match SupervisorClient::new("http://localhost:3030") {
|
|
Ok(c) => c,
|
|
Err(_) => return Ok(()), // Skip if not available
|
|
};
|
|
|
|
if client.discover().await.is_err() {
|
|
return Ok(()); // Skip if not responding
|
|
}
|
|
|
|
let secret = "user-secret-456";
|
|
|
|
let job = JobBuilder::new()
|
|
.caller_id("integration_test")
|
|
.context_id("test_immediate")
|
|
.payload("echo 'Immediate job test'")
|
|
.executor("osis")
|
|
.runner("osis_runner_1")
|
|
.timeout(30)
|
|
.build()?;
|
|
|
|
// Test immediate execution
|
|
let result = client.job_run(secret, job).await?;
|
|
|
|
// Should get either success or error, but not panic
|
|
match result {
|
|
JobResult::Success { success } => {
|
|
assert!(!success.is_empty());
|
|
},
|
|
JobResult::Error { error } => {
|
|
assert!(!error.is_empty());
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_jobs_list() -> Result<(), Box<dyn std::error::Error>> {
|
|
let client = match SupervisorClient::new("http://localhost:3030") {
|
|
Ok(c) => c,
|
|
Err(_) => return Ok(()), // Skip if not available
|
|
};
|
|
|
|
if client.discover().await.is_err() {
|
|
return Ok(()); // Skip if not responding
|
|
}
|
|
|
|
// Test listing jobs
|
|
let job_ids = client.jobs_list().await?;
|
|
|
|
// Should return a vector (might be empty)
|
|
assert!(job_ids.len() >= 0);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_authentication_errors() -> Result<(), Box<dyn std::error::Error>> {
|
|
let client = match SupervisorClient::new("http://localhost:3030") {
|
|
Ok(c) => c,
|
|
Err(_) => return Ok(()), // Skip if not available
|
|
};
|
|
|
|
if client.discover().await.is_err() {
|
|
return Ok(()); // Skip if not responding
|
|
}
|
|
|
|
let invalid_secret = "invalid-secret";
|
|
|
|
let job = JobBuilder::new()
|
|
.caller_id("integration_test")
|
|
.context_id("test_auth")
|
|
.payload("echo 'Auth test'")
|
|
.executor("osis")
|
|
.runner("osis_runner_1")
|
|
.timeout(30)
|
|
.build()?;
|
|
|
|
// Test that invalid secret fails
|
|
let result = client.jobs_create(invalid_secret, job.clone()).await;
|
|
assert!(result.is_err());
|
|
|
|
let result = client.job_run(invalid_secret, job.clone()).await;
|
|
assert!(result.is_err());
|
|
|
|
let result = client.job_start(invalid_secret, "fake-job-id").await;
|
|
assert!(result.is_err());
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_nonexistent_job_operations() -> Result<(), Box<dyn std::error::Error>> {
|
|
let client = match SupervisorClient::new("http://localhost:3030") {
|
|
Ok(c) => c,
|
|
Err(_) => return Ok(()), // Skip if not available
|
|
};
|
|
|
|
if client.discover().await.is_err() {
|
|
return Ok(()); // Skip if not responding
|
|
}
|
|
|
|
let fake_job_id = "nonexistent-job-id";
|
|
|
|
// Test operations on nonexistent job
|
|
let result = client.job_status(fake_job_id).await;
|
|
assert!(result.is_err());
|
|
|
|
let result = client.job_result(fake_job_id).await;
|
|
assert!(result.is_err());
|
|
|
|
Ok(())
|
|
}
|