Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
118 lines
4.3 KiB
Rust
118 lines
4.3 KiB
Rust
use alga_ext_runner::models::{ExecuteContext, ExecuteRequest, HttpPayload, Limits};
|
|
use reqwest::Client;
|
|
use std::collections::HashMap;
|
|
use std::time::Duration;
|
|
use tokio::net::TcpListener;
|
|
use tokio::task::JoinHandle;
|
|
|
|
/// Helper to start the runner server in a background task.
|
|
/// Returns the base URL of the runner and a shutdown handle.
|
|
async fn start_runner_server() -> anyhow::Result<(String, JoinHandle<()>)> {
|
|
// Pick a random port for the runner
|
|
let port = {
|
|
let listener = TcpListener::bind("127.0.0.1:0").await?;
|
|
let addr = listener.local_addr()?;
|
|
addr.port()
|
|
}; // Listener is dropped here, freeing the port
|
|
|
|
// Set necessary environment variables for the runner configuration
|
|
// In a real test, we would likely mock the registry and bundle store too.
|
|
unsafe {
|
|
std::env::set_var("PORT", port.to_string());
|
|
std::env::set_var("REGISTRY_BASE_URL", "http://127.0.0.1:9999"); // Dummy
|
|
std::env::set_var("BUNDLE_STORE_BASE", "http://127.0.0.1:9998"); // Dummy
|
|
std::env::set_var("ALGA_AUTH_KEY", "test-key");
|
|
std::env::set_var("EXT_CACHE_ROOT", std::env::temp_dir().join("alga-runner-test"));
|
|
// Disable strict validation if needed, or just let it fail later
|
|
}
|
|
|
|
// Spawn the runner
|
|
let handle = tokio::spawn(async move {
|
|
if let Err(e) = alga_ext_runner::http::server::run().await {
|
|
eprintln!("Runner server exited with error: {}", e);
|
|
}
|
|
});
|
|
|
|
// Give it a moment to start listening
|
|
let client = Client::builder()
|
|
.timeout(Duration::from_secs(1))
|
|
.build()?;
|
|
let base_url = format!("http://127.0.0.1:{}", port);
|
|
|
|
let start = std::time::Instant::now();
|
|
loop {
|
|
if handle.is_finished() {
|
|
anyhow::bail!("Runner server task exited prematurely");
|
|
}
|
|
if start.elapsed() > Duration::from_secs(10) {
|
|
anyhow::bail!("Runner failed to start within 10 seconds");
|
|
}
|
|
// We check healthz. It might return 503 if dependencies (registry) are unreachable,
|
|
// but that proves the HTTP server is UP.
|
|
match client.get(format!("{}/healthz", base_url)).send().await {
|
|
Ok(resp) => {
|
|
// 503 is expected since we have dummy dependencies
|
|
if resp.status().is_success() || resp.status() == reqwest::StatusCode::SERVICE_UNAVAILABLE {
|
|
break;
|
|
}
|
|
}
|
|
Err(_) => tokio::time::sleep(Duration::from_millis(100)).await,
|
|
}
|
|
}
|
|
|
|
Ok((base_url, handle))
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_execute_endpoint_structure() -> anyhow::Result<()> {
|
|
let (base_url, _server_handle) = start_runner_server().await?;
|
|
let client = Client::new();
|
|
|
|
let req_body = ExecuteRequest {
|
|
context: ExecuteContext {
|
|
request_id: Some("api-test".to_string()),
|
|
tenant_id: "tenant-1".to_string(),
|
|
extension_id: "ext-1".to_string(),
|
|
install_id: Some("inst-1".to_string()),
|
|
content_hash: "sha256:dummy".to_string(),
|
|
version_id: Some("v1".to_string()),
|
|
config: HashMap::new(),
|
|
},
|
|
http: HttpPayload {
|
|
method: "POST".to_string(),
|
|
path: "/foo".to_string(),
|
|
query: HashMap::new(),
|
|
headers: HashMap::new(),
|
|
body_b64: None,
|
|
},
|
|
limits: Limits::default(),
|
|
secret_envelope: None,
|
|
providers: vec![],
|
|
user: None,
|
|
};
|
|
|
|
let resp = client.post(format!("{}/v1/execute", base_url))
|
|
.header("x-request-id", "req-123")
|
|
.header("x-alga-tenant", "tenant-1")
|
|
.header("x-alga-extension", "ext-1")
|
|
.json(&req_body)
|
|
.send()
|
|
.await?;
|
|
|
|
let status = resp.status();
|
|
println!("Runner response status: {}", status);
|
|
|
|
// Since our "registry" is 127.0.0.1:9999 (which likely doesn't exist),
|
|
// the runner should fail inside `execute` when trying to fetch the bundle or init the engine.
|
|
// But the *HTTP endpoint* should be reachable.
|
|
// It will likely return 500 or 502.
|
|
// Crucially, it should NOT be 404.
|
|
assert!(status != reqwest::StatusCode::NOT_FOUND);
|
|
|
|
if let Ok(body_text) = resp.text().await {
|
|
println!("Runner response body: {}", body_text);
|
|
}
|
|
|
|
Ok(())
|
|
}
|