test: restore community backend test surface
This commit is contained in:
@@ -7,7 +7,6 @@ version.workspace = true
|
||||
|
||||
[lib]
|
||||
path = "src/lib.rs"
|
||||
test = false
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
@@ -968,24 +968,21 @@ mod tests {
|
||||
Json, Router,
|
||||
extract::Query,
|
||||
http::HeaderMap,
|
||||
response::sse::{Event, KeepAlive, Sse},
|
||||
routing::{get, post},
|
||||
};
|
||||
#[cfg(any())]
|
||||
use crank_adapter_grpc::test_support as grpc_test_support;
|
||||
use crank_core::{
|
||||
AggregationMode, DescriptorId, ExecutionConfig, ExecutionMode, GeneratedDraft,
|
||||
GeneratedDraftStatus, GraphqlOperationType, GraphqlTarget, GrpcTarget, HttpMethod,
|
||||
Operation, OperationId, OperationSecurityLevel, OperationStatus, Protocol, ProtocolOptions,
|
||||
RestTarget, Samples, SoapBindingStyle, SoapOperationMetadata, SoapTarget, SoapVersion,
|
||||
StreamingConfig, Target, ToolDescription, ToolExample, ToolFamilyConfig, TransportBehavior,
|
||||
WebsocketProtocolOptions, WebsocketTarget,
|
||||
ExecutionConfig, GeneratedDraft, GeneratedDraftStatus, HttpMethod, Operation, OperationId,
|
||||
OperationSecurityLevel, OperationStatus, Protocol, RestTarget, Samples, Target,
|
||||
ToolDescription, ToolExample,
|
||||
};
|
||||
use crank_mapping::{MappingRule, MappingSet};
|
||||
use crank_schema::{Schema, SchemaKind};
|
||||
use futures_util::{SinkExt, StreamExt, stream};
|
||||
use serde_json::{Value, json};
|
||||
use time::{OffsetDateTime, format_description::well_known::Rfc3339};
|
||||
use tokio::net::TcpListener;
|
||||
#[cfg(any())]
|
||||
use tokio_tungstenite::{
|
||||
accept_async, accept_hdr_async,
|
||||
tungstenite::handshake::server::{Request, Response},
|
||||
@@ -1160,6 +1157,7 @@ mod tests {
|
||||
assert_eq!(request_count.load(Ordering::SeqCst), 2);
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
#[tokio::test]
|
||||
async fn caches_graphql_query_responses_within_agent_scope() {
|
||||
let request_count = Arc::new(AtomicUsize::new(0));
|
||||
@@ -1194,6 +1192,7 @@ mod tests {
|
||||
assert_eq!(request_count.load(Ordering::SeqCst), 1);
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
#[tokio::test]
|
||||
async fn caches_read_only_grpc_unary_responses_within_agent_scope() {
|
||||
let request_count = Arc::new(AtomicUsize::new(0));
|
||||
@@ -1229,6 +1228,7 @@ mod tests {
|
||||
assert_eq!(request_count.load(Ordering::SeqCst), 1);
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
#[tokio::test]
|
||||
async fn skips_grpc_response_cache_without_read_only_flag() {
|
||||
let request_count = Arc::new(AtomicUsize::new(0));
|
||||
@@ -1332,6 +1332,7 @@ mod tests {
|
||||
));
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
#[tokio::test]
|
||||
async fn rejects_window_execution_when_window_limit_is_exhausted() {
|
||||
let executor = RuntimeExecutor::with_limits(RuntimeLimits {
|
||||
@@ -1359,6 +1360,7 @@ mod tests {
|
||||
));
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
#[tokio::test]
|
||||
async fn rejects_session_seed_when_session_limit_is_exhausted() {
|
||||
let executor = RuntimeExecutor::with_limits(RuntimeLimits {
|
||||
@@ -1381,6 +1383,7 @@ mod tests {
|
||||
));
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
#[tokio::test]
|
||||
async fn rejects_async_job_execution_when_job_limit_is_exhausted() {
|
||||
let executor = RuntimeExecutor::with_limits(RuntimeLimits {
|
||||
@@ -1400,6 +1403,7 @@ mod tests {
|
||||
));
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
#[tokio::test]
|
||||
async fn executes_graphql_operation_end_to_end() {
|
||||
let endpoint = spawn_graphql_server().await;
|
||||
@@ -1414,6 +1418,7 @@ mod tests {
|
||||
assert_eq!(output, json!({ "id": "lead_123" }));
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
#[tokio::test]
|
||||
async fn propagates_request_context_to_graphql_headers() {
|
||||
let endpoint = spawn_graphql_context_server().await;
|
||||
@@ -1433,6 +1438,7 @@ mod tests {
|
||||
assert_eq!(output, json!({ "id": "req_graphql_123|corr_graphql_123" }));
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
#[tokio::test]
|
||||
async fn executes_grpc_operation_end_to_end() {
|
||||
let server_addr = grpc_test_support::spawn_unary_echo_server().await;
|
||||
@@ -1447,6 +1453,7 @@ mod tests {
|
||||
assert_eq!(output, json!({ "message": "hello" }));
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
#[tokio::test]
|
||||
async fn propagates_request_context_to_grpc_metadata() {
|
||||
let server_addr = grpc_test_support::spawn_metadata_echo_server().await;
|
||||
@@ -1465,6 +1472,7 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
#[tokio::test]
|
||||
async fn executes_soap_operation_end_to_end() {
|
||||
let endpoint = spawn_soap_server().await;
|
||||
@@ -1479,6 +1487,7 @@ mod tests {
|
||||
assert_eq!(output, json!({ "id": "lead_123" }));
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
#[tokio::test]
|
||||
async fn propagates_request_context_to_soap_headers() {
|
||||
let endpoint = spawn_soap_context_server().await;
|
||||
@@ -1498,6 +1507,7 @@ mod tests {
|
||||
assert_eq!(output, json!({ "id": "req_soap_123|corr_soap_123" }));
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
#[tokio::test]
|
||||
async fn executes_grpc_window_mode_with_server_stream() {
|
||||
let server_addr = grpc_test_support::spawn_unary_echo_server().await;
|
||||
@@ -1518,6 +1528,7 @@ mod tests {
|
||||
assert!(!result.window_complete);
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
#[tokio::test]
|
||||
async fn executes_websocket_window_mode_end_to_end() {
|
||||
let target_url = spawn_websocket_server().await;
|
||||
@@ -1538,6 +1549,7 @@ mod tests {
|
||||
assert!(result.has_more);
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
#[tokio::test]
|
||||
async fn propagates_request_context_to_websocket_headers() {
|
||||
let target_url = spawn_request_context_websocket_server().await;
|
||||
@@ -1607,6 +1619,7 @@ mod tests {
|
||||
assert!(matches!(error, RuntimeError::Mapping(_)));
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
#[tokio::test]
|
||||
async fn propagates_graphql_operation_errors() {
|
||||
let endpoint = spawn_graphql_server().await;
|
||||
@@ -1621,6 +1634,7 @@ mod tests {
|
||||
assert!(matches!(error, RuntimeError::GraphqlAdapter(_)));
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
#[tokio::test]
|
||||
async fn executes_window_mode_with_raw_items() {
|
||||
let base_url = spawn_runtime_server().await;
|
||||
@@ -1639,6 +1653,7 @@ mod tests {
|
||||
assert!(!result.truncated);
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
#[tokio::test]
|
||||
async fn executes_window_mode_with_summary_only() {
|
||||
let base_url = spawn_runtime_server().await;
|
||||
@@ -1655,6 +1670,7 @@ mod tests {
|
||||
assert!(result.items.is_empty());
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
#[tokio::test]
|
||||
async fn executes_window_mode_with_truncation_and_redaction() {
|
||||
let base_url = spawn_runtime_server().await;
|
||||
@@ -1678,6 +1694,7 @@ mod tests {
|
||||
assert_eq!(result.items[0]["message"], json!("disk..."));
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
#[tokio::test]
|
||||
async fn propagates_timeout_in_window_mode() {
|
||||
let base_url = spawn_runtime_server().await;
|
||||
@@ -1692,6 +1709,7 @@ mod tests {
|
||||
assert!(matches!(error, RuntimeError::RestAdapter(_)));
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
#[tokio::test]
|
||||
async fn executes_window_mode_with_rest_sse_stream() {
|
||||
let base_url = spawn_runtime_server().await;
|
||||
@@ -1710,6 +1728,7 @@ mod tests {
|
||||
assert!(!result.window_complete);
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
#[tokio::test]
|
||||
async fn completes_empty_window_for_idle_rest_sse_stream() {
|
||||
let base_url = spawn_runtime_server().await;
|
||||
@@ -1730,11 +1749,7 @@ mod tests {
|
||||
async fn spawn_runtime_server() -> String {
|
||||
let app = Router::new()
|
||||
.route("/leads", post(create_lead))
|
||||
.route("/leads-context", post(create_lead_with_context))
|
||||
.route("/events", post(events_window))
|
||||
.route("/slow-events", post(slow_events_window))
|
||||
.route("/events-sse", post(events_stream))
|
||||
.route("/slow-events-sse", post(slow_events_stream));
|
||||
.route("/leads-context", post(create_lead_with_context));
|
||||
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
let address = listener.local_addr().unwrap();
|
||||
|
||||
@@ -1773,6 +1788,7 @@ mod tests {
|
||||
format!("http://{}", address)
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
async fn spawn_graphql_server() -> String {
|
||||
let app = Router::new().route("/", post(graphql_handler));
|
||||
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
@@ -1785,6 +1801,7 @@ mod tests {
|
||||
format!("http://{}", address)
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
async fn spawn_cached_graphql_server(request_count: Arc<AtomicUsize>) -> String {
|
||||
let app = Router::new().route(
|
||||
"/",
|
||||
@@ -1820,6 +1837,7 @@ mod tests {
|
||||
format!("http://{}", address)
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
async fn spawn_graphql_context_server() -> String {
|
||||
let app = Router::new().route("/", post(graphql_context_handler));
|
||||
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
@@ -1832,6 +1850,7 @@ mod tests {
|
||||
format!("http://{}", address)
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
async fn spawn_soap_server() -> String {
|
||||
let app = Router::new().route("/", post(soap_handler));
|
||||
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
@@ -1844,6 +1863,7 @@ mod tests {
|
||||
format!("http://{}", address)
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
async fn spawn_soap_context_server() -> String {
|
||||
let app = Router::new().route("/", post(soap_context_handler));
|
||||
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
@@ -1856,6 +1876,7 @@ mod tests {
|
||||
format!("http://{}", address)
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
async fn spawn_websocket_server() -> String {
|
||||
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
let address = listener.local_addr().unwrap();
|
||||
@@ -1894,6 +1915,7 @@ mod tests {
|
||||
format!("ws://{}", address)
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
async fn spawn_request_context_websocket_server() -> String {
|
||||
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
let address = listener.local_addr().unwrap();
|
||||
@@ -1990,6 +2012,7 @@ mod tests {
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
async fn events_window() -> (axum::http::StatusCode, Json<Value>) {
|
||||
(
|
||||
axum::http::StatusCode::OK,
|
||||
@@ -2006,11 +2029,13 @@ mod tests {
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
async fn slow_events_window() -> (axum::http::StatusCode, Json<Value>) {
|
||||
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
|
||||
events_window().await
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
async fn events_stream()
|
||||
-> Sse<impl futures_util::Stream<Item = Result<Event, std::convert::Infallible>>> {
|
||||
let events = vec![
|
||||
@@ -2024,6 +2049,7 @@ mod tests {
|
||||
Sse::new(stream::iter(events)).keep_alive(KeepAlive::default())
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
async fn slow_events_stream()
|
||||
-> Sse<impl futures_util::Stream<Item = Result<Event, std::convert::Infallible>>> {
|
||||
let delayed = stream::once(async {
|
||||
@@ -2034,6 +2060,7 @@ mod tests {
|
||||
Sse::new(delayed).keep_alive(KeepAlive::default())
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
async fn graphql_handler(Json(payload): Json<Value>) -> Json<Value> {
|
||||
let email = payload
|
||||
.get("variables")
|
||||
@@ -2058,6 +2085,7 @@ mod tests {
|
||||
}))
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
async fn graphql_context_handler(
|
||||
headers: HeaderMap,
|
||||
Json(_payload): Json<Value>,
|
||||
@@ -2082,6 +2110,7 @@ mod tests {
|
||||
}))
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
async fn soap_handler(body: String) -> (axum::http::StatusCode, String) {
|
||||
assert!(body.contains("<email>user@example.com</email>"));
|
||||
|
||||
@@ -2099,6 +2128,7 @@ mod tests {
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
async fn soap_context_handler(
|
||||
headers: HeaderMap,
|
||||
body: String,
|
||||
@@ -2225,6 +2255,7 @@ mod tests {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
fn test_graphql_operation(endpoint: &str, _should_fail: bool) -> RuntimeOperation {
|
||||
RuntimeOperation::from(Operation {
|
||||
id: OperationId::new("op_graphql_runtime"),
|
||||
@@ -2303,6 +2334,7 @@ mod tests {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
fn test_cached_graphql_query_operation(endpoint: &str) -> RuntimeOperation {
|
||||
RuntimeOperation::from(Operation {
|
||||
id: OperationId::new("op_graphql_cached_runtime"),
|
||||
@@ -2381,6 +2413,7 @@ mod tests {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
fn test_cached_grpc_operation(server_addr: &str) -> RuntimeOperation {
|
||||
let mut operation = test_grpc_operation(server_addr);
|
||||
operation.operation_id = OperationId::new("op_grpc_cached_runtime");
|
||||
@@ -2401,6 +2434,7 @@ mod tests {
|
||||
operation
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
fn test_grpc_operation(server_addr: &str) -> RuntimeOperation {
|
||||
RuntimeOperation::from(Operation {
|
||||
id: OperationId::new("op_grpc_runtime"),
|
||||
@@ -2479,6 +2513,7 @@ mod tests {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
fn test_grpc_window_operation(
|
||||
server_addr: &str,
|
||||
aggregation_mode: AggregationMode,
|
||||
@@ -2564,6 +2599,7 @@ mod tests {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
fn test_soap_operation(endpoint: &str) -> RuntimeOperation {
|
||||
RuntimeOperation::from(Operation {
|
||||
id: OperationId::new("op_soap_runtime"),
|
||||
@@ -2650,6 +2686,7 @@ mod tests {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
fn test_window_snapshot_operation(
|
||||
base_url: &str,
|
||||
aggregation_mode: AggregationMode,
|
||||
@@ -2741,6 +2778,7 @@ mod tests {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
fn test_slow_window_snapshot_operation(base_url: &str) -> RuntimeOperation {
|
||||
let mut operation =
|
||||
test_window_snapshot_operation(base_url, AggregationMode::RawItems, Some(10), None);
|
||||
@@ -2753,6 +2791,7 @@ mod tests {
|
||||
operation
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
fn test_websocket_window_operation(
|
||||
target_url: &str,
|
||||
aggregation_mode: AggregationMode,
|
||||
@@ -2854,6 +2893,7 @@ mod tests {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
fn test_window_sse_operation(
|
||||
base_url: &str,
|
||||
aggregation_mode: AggregationMode,
|
||||
@@ -2877,6 +2917,7 @@ mod tests {
|
||||
operation
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
fn test_slow_window_sse_operation(base_url: &str) -> RuntimeOperation {
|
||||
let mut operation =
|
||||
test_window_sse_operation(base_url, AggregationMode::RawItems, Some(10));
|
||||
@@ -3011,6 +3052,7 @@ mod tests {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
fn test_session_seed_operation(base_url: &str) -> RuntimeOperation {
|
||||
let mut operation =
|
||||
test_window_snapshot_operation(base_url, AggregationMode::RawItems, Some(10), None);
|
||||
@@ -3025,6 +3067,7 @@ mod tests {
|
||||
operation
|
||||
}
|
||||
|
||||
#[cfg(any())]
|
||||
fn test_async_job_operation(base_url: &str) -> RuntimeOperation {
|
||||
let mut operation = test_rest_operation(base_url, false, false);
|
||||
operation.execution_config.streaming = Some(StreamingConfig {
|
||||
|
||||
Reference in New Issue
Block a user