update api, fix tests and examples
This commit is contained in:
190
examples/integration_test.rs
Normal file
190
examples/integration_test.rs
Normal file
@@ -0,0 +1,190 @@
|
||||
//! 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(())
|
||||
}
|
Reference in New Issue
Block a user