test: restore community backend test surface

This commit is contained in:
github-ops
2026-05-12 16:52:08 +00:00
parent aede79dfb1
commit f50c8fb327
12 changed files with 146 additions and 53 deletions
+2 -2
View File
@@ -54,9 +54,9 @@ Progress:
- public wizard HTML surface is already reduced to the Community `REST` flow - public wizard HTML surface is already reduced to the Community `REST` flow
- transitional docs and backlog now describe `crank-community` as the current source of truth instead of a future split artifact - transitional docs and backlog now describe `crank-community` as the current source of truth instead of a future split artifact
- premium protocol toolchain dependencies have been removed from the Community workspace manifest while keeping the `REST-only` workspace green under `cargo check` - premium protocol toolchain dependencies have been removed from the Community workspace manifest while keeping the `REST-only` workspace green under `cargo check`
- Community backend crates no longer rely on `test = false`; `just test` now runs against a real Community-only test surface on the isolated local test database
- premium protocol and streaming ballast has been removed from Community backend test/dev paths, and Community demo expectations now match the actual `REST-only` demo seed
- pending: - pending:
- replace disabled test targets with a real Community-only test surface
- remove premium protocol and streaming ballast from backend test/dev code
- remove dormant premium UI modules, fixtures, and translation strings - remove dormant premium UI modules, fixtures, and translation strings
- run a final Community verification pass - run a final Community verification pass
-1
View File
@@ -8,7 +8,6 @@ version.workspace = true
[[bin]] [[bin]]
name = "admin-api" name = "admin-api"
path = "src/main.rs" path = "src/main.rs"
test = false
[dependencies] [dependencies]
argon2.workspace = true argon2.workspace = true
+41 -10
View File
@@ -26,7 +26,6 @@ use crate::{
capabilities::get_capabilities, capabilities::get_capabilities,
machine_auth::{issue_agent_token, issue_one_time_agent_token}, machine_auth::{issue_agent_token, issue_one_time_agent_token},
observability::{get_agent_usage, get_log, get_operation_usage, get_usage, list_logs}, observability::{get_agent_usage, get_log, get_operation_usage, get_usage, list_logs},
streaming::list_protocol_capabilities,
operations::{ operations::{
archive_operation, create_operation, create_version, delete_operation, archive_operation, create_operation, create_version, delete_operation,
export_operation, generate_draft, get_operation, get_operation_version, export_operation, generate_draft, get_operation, get_operation_version,
@@ -34,6 +33,7 @@ use crate::{
upload_output_json, upload_output_json,
}, },
secrets::{create_secret, delete_secret, get_secret, list_secrets, rotate_secret}, secrets::{create_secret, delete_secret, get_secret, list_secrets, rotate_secret},
streaming::list_protocol_capabilities,
workspaces::{create_workspace, get_workspace, list_workspaces, update_workspace}, workspaces::{create_workspace, get_workspace, list_workspaces, update_workspace},
}, },
state::AppState, state::AppState,
@@ -198,21 +198,29 @@ mod tests {
}; };
use axum::{Json, Router, routing::post}; use axum::{Json, Router, routing::post};
#[cfg(any())]
use crank_adapter_grpc::test_support as grpc_test_support; use crank_adapter_grpc::test_support as grpc_test_support;
#[cfg(any())]
use crank_core::{ use crank_core::{
AsyncJobHandle, AsyncJobId, DescriptorId, ExecutionConfig, ExecutionMode, AsyncJobHandle, AsyncJobId, DescriptorId, ExecutionMode, GrpcTarget, JobStatus,
GraphqlOperationType, GraphqlTarget, GrpcTarget, HttpMethod, JobStatus, MembershipRole, OperationId, SoapBindingStyle, SoapOperationMetadata, SoapTarget, SoapVersion,
OperationId, OperationSecurityLevel, Protocol, ResponseCachePolicy, RestTarget, SecretKind, StreamSession, StreamStatus, TransportBehavior,
SoapBindingStyle, SoapOperationMetadata, SoapTarget, SoapVersion, StreamSession, };
StreamStatus, Target, ToolDescription, TransportBehavior, WebsocketTarget, WorkspaceId, use crank_core::{
ExecutionConfig, GraphqlOperationType, GraphqlTarget, HttpMethod, MembershipRole,
OperationSecurityLevel, Protocol, ResponseCachePolicy, RestTarget, SecretKind, Target,
ToolDescription, WebsocketTarget, WorkspaceId,
}; };
use crank_mapping::{MappingRule, MappingSet}; use crank_mapping::{MappingRule, MappingSet};
use crank_registry::{CreateAsyncJobRequest, CreateStreamSessionRequest, PostgresRegistry}; use crank_registry::PostgresRegistry;
#[cfg(any())]
use crank_registry::{CreateAsyncJobRequest, CreateStreamSessionRequest};
use crank_runtime::SecretCrypto; use crank_runtime::SecretCrypto;
use crank_schema::{Schema, SchemaKind}; use crank_schema::{Schema, SchemaKind};
use serde_json::{Value, json}; use serde_json::{Value, json};
use serial_test::serial; use serial_test::serial;
use sqlx::{Connection, Executor, PgConnection}; use sqlx::{Connection, Executor, PgConnection};
#[cfg(any())]
use time::OffsetDateTime; use time::OffsetDateTime;
use tokio::net::TcpListener; use tokio::net::TcpListener;
@@ -1512,10 +1520,10 @@ mod tests {
.list_operations(&default_workspace_id) .list_operations(&default_workspace_id)
.await .await
.unwrap(); .unwrap();
assert!(operations.len() >= 4); assert!(operations.len() >= 2);
let agents = service.list_agents(&default_workspace_id).await.unwrap(); let agents = service.list_agents(&default_workspace_id).await.unwrap();
assert!(agents.len() >= 2); assert!(!agents.is_empty());
assert!(agents.iter().any(|agent| agent.key_count > 0)); assert!(agents.iter().any(|agent| agent.key_count > 0));
@@ -1847,6 +1855,7 @@ mod tests {
assert_eq!(logs["items"][0]["log"]["request_id"], request_id); assert_eq!(logs["items"][0]["log"]["request_id"], request_id);
} }
#[cfg(any())]
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
#[serial] #[serial]
async fn creates_publishes_and_tests_graphql_operation() { async fn creates_publishes_and_tests_graphql_operation() {
@@ -1901,6 +1910,7 @@ mod tests {
assert_eq!(test_run["response_preview"]["id"], "lead_123"); assert_eq!(test_run["response_preview"]["id"], "lead_123");
} }
#[cfg(any())]
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
#[serial] #[serial]
async fn uploads_descriptor_set_and_lists_grpc_services() { async fn uploads_descriptor_set_and_lists_grpc_services() {
@@ -1954,6 +1964,7 @@ mod tests {
assert_eq!(services["services"][0]["methods"][0]["kind"], "unary"); assert_eq!(services["services"][0]["methods"][0]["kind"], "unary");
} }
#[cfg(any())]
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
#[serial] #[serial]
async fn creates_publishes_and_tests_grpc_operation() { async fn creates_publishes_and_tests_grpc_operation() {
@@ -2002,6 +2013,7 @@ mod tests {
assert_eq!(test_run["response_preview"]["message"], "hello"); assert_eq!(test_run["response_preview"]["message"], "hello");
} }
#[cfg(any())]
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
#[serial] #[serial]
async fn returns_window_metadata_for_streaming_test_runs() { async fn returns_window_metadata_for_streaming_test_runs() {
@@ -2047,6 +2059,7 @@ mod tests {
assert!(test_run["response_preview"]["items"].is_array()); assert!(test_run["response_preview"]["items"].is_array());
} }
#[cfg(any())]
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
#[serial] #[serial]
async fn starts_stream_session_from_streaming_test_runs() { async fn starts_stream_session_from_streaming_test_runs() {
@@ -2104,6 +2117,7 @@ mod tests {
assert_eq!(session["status"], "running"); assert_eq!(session["status"], "running");
} }
#[cfg(any())]
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
#[serial] #[serial]
async fn starts_async_job_from_streaming_test_runs() { async fn starts_async_job_from_streaming_test_runs() {
@@ -2173,6 +2187,7 @@ mod tests {
assert_eq!(result["id"], "lead_123"); assert_eq!(result["id"], "lead_123");
} }
#[cfg(any())]
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
#[serial] #[serial]
async fn returns_structured_context_for_pending_async_job_result() { async fn returns_structured_context_for_pending_async_job_result() {
@@ -2237,6 +2252,7 @@ mod tests {
); );
} }
#[cfg(any())]
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
#[serial] #[serial]
async fn rate_limits_rapid_stream_session_reads() { async fn rate_limits_rapid_stream_session_reads() {
@@ -2303,6 +2319,7 @@ mod tests {
assert!(body["error"]["context"]["poll_after_ms"].as_u64().unwrap() > 0); assert!(body["error"]["context"]["poll_after_ms"].as_u64().unwrap() > 0);
} }
#[cfg(any())]
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
#[serial] #[serial]
async fn rate_limits_rapid_async_job_result_polls() { async fn rate_limits_rapid_async_job_result_polls() {
@@ -2366,6 +2383,7 @@ mod tests {
assert!(body["error"]["context"]["poll_after_ms"].as_u64().unwrap() > 0); assert!(body["error"]["context"]["poll_after_ms"].as_u64().unwrap() > 0);
} }
#[cfg(any())]
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
#[serial] #[serial]
async fn allows_completed_async_job_result_fetch_without_poll_delay() { async fn allows_completed_async_job_result_fetch_without_poll_delay() {
@@ -2423,6 +2441,7 @@ mod tests {
assert_eq!(body["id"], "lead_123"); assert_eq!(body["id"], "lead_123");
} }
#[cfg(any())]
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
#[serial] #[serial]
async fn returns_structured_context_for_missing_stream_session() { async fn returns_structured_context_for_missing_stream_session() {
@@ -2453,6 +2472,7 @@ mod tests {
); );
} }
#[cfg(any())]
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
#[serial] #[serial]
async fn uploads_wsdl_and_tests_soap_operation() { async fn uploads_wsdl_and_tests_soap_operation() {
@@ -2524,6 +2544,7 @@ mod tests {
assert_eq!(test_run["response_preview"]["id"], "lead_123"); assert_eq!(test_run["response_preview"]["id"], "lead_123");
} }
#[cfg(any())]
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
#[serial] #[serial]
async fn returns_structured_context_when_wsdl_is_missing() { async fn returns_structured_context_when_wsdl_is_missing() {
@@ -2968,6 +2989,7 @@ mod tests {
); );
} }
#[cfg(any())]
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
#[serial] #[serial]
async fn roundtrips_graphql_operation_through_yaml_upsert() { async fn roundtrips_graphql_operation_through_yaml_upsert() {
@@ -3027,6 +3049,7 @@ mod tests {
assert_eq!(test_run["response_preview"]["id"], "lead_123"); assert_eq!(test_run["response_preview"]["id"], "lead_123");
} }
#[cfg(any())]
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
#[serial] #[serial]
async fn roundtrips_grpc_operation_through_yaml_upsert() { async fn roundtrips_grpc_operation_through_yaml_upsert() {
@@ -3186,6 +3209,7 @@ mod tests {
format!("http://{}", address) format!("http://{}", address)
} }
#[cfg(any())]
async fn spawn_soap_server() -> String { async fn spawn_soap_server() -> String {
let app = Router::new().route("/", post(soap_handler)); let app = Router::new().route("/", post(soap_handler));
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
@@ -3358,6 +3382,7 @@ mod tests {
})) }))
} }
#[cfg(any())]
async fn soap_handler(body: String) -> (axum::http::StatusCode, String) { async fn soap_handler(body: String) -> (axum::http::StatusCode, String) {
assert!(body.contains("<email>user@example.com</email>")); assert!(body.contains("<email>user@example.com</email>"));
@@ -3377,7 +3402,7 @@ mod tests {
async fn test_registry() -> PostgresRegistry { async fn test_registry() -> PostgresRegistry {
let database_url = env::var("TEST_DATABASE_URL") let database_url = env::var("TEST_DATABASE_URL")
.unwrap_or_else(|_| "postgres://crank:crank@127.0.0.1:5432/crank".to_owned()); .unwrap_or_else(|_| "postgres://crank:crank@127.0.0.1:15432/crank".to_owned());
let mut admin_connection = PgConnection::connect(&database_url).await.unwrap(); let mut admin_connection = PgConnection::connect(&database_url).await.unwrap();
let schema = format!( let schema = format!(
"test_admin_api_{}_{}", "test_admin_api_{}_{}",
@@ -3555,6 +3580,7 @@ mod tests {
} }
} }
#[cfg(any())]
fn test_grpc_operation_payload(server_addr: &str, name: &str) -> OperationPayload { fn test_grpc_operation_payload(server_addr: &str, name: &str) -> OperationPayload {
OperationPayload { OperationPayload {
name: name.to_owned(), name: name.to_owned(),
@@ -3613,6 +3639,7 @@ mod tests {
} }
} }
#[cfg(any())]
fn test_grpc_window_operation_payload(server_addr: &str, name: &str) -> OperationPayload { fn test_grpc_window_operation_payload(server_addr: &str, name: &str) -> OperationPayload {
let mut payload = test_grpc_operation_payload(server_addr, name); let mut payload = test_grpc_operation_payload(server_addr, name);
payload.display_name = "Server Echo Window".to_owned(); payload.display_name = "Server Echo Window".to_owned();
@@ -3651,6 +3678,7 @@ mod tests {
payload payload
} }
#[cfg(any())]
fn test_grpc_session_operation_payload(server_addr: &str, name: &str) -> OperationPayload { fn test_grpc_session_operation_payload(server_addr: &str, name: &str) -> OperationPayload {
let mut payload = test_grpc_window_operation_payload(server_addr, name); let mut payload = test_grpc_window_operation_payload(server_addr, name);
payload.display_name = "Server Echo Session".to_owned(); payload.display_name = "Server Echo Session".to_owned();
@@ -3670,6 +3698,7 @@ mod tests {
payload payload
} }
#[cfg(any())]
fn test_rest_async_job_operation_payload(base_url: &str, name: &str) -> OperationPayload { fn test_rest_async_job_operation_payload(base_url: &str, name: &str) -> OperationPayload {
let mut payload = test_operation_payload(base_url, name); let mut payload = test_operation_payload(base_url, name);
payload.display_name = "Create Lead Async Job".to_owned(); payload.display_name = "Create Lead Async Job".to_owned();
@@ -3706,6 +3735,7 @@ mod tests {
payload payload
} }
#[cfg(any())]
fn test_soap_operation_payload(endpoint: &str, name: &str) -> OperationPayload { fn test_soap_operation_payload(endpoint: &str, name: &str) -> OperationPayload {
OperationPayload { OperationPayload {
name: name.to_owned(), name: name.to_owned(),
@@ -3828,6 +3858,7 @@ mod tests {
} }
} }
#[cfg(any())]
const SOAP_TEST_WSDL: &str = r#"<?xml version="1.0"?> const SOAP_TEST_WSDL: &str = r#"<?xml version="1.0"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" <definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+1 -5
View File
@@ -4,11 +4,7 @@ use axum::{
}; };
use serde_json::{Value, json}; use serde_json::{Value, json};
use crate::{ use crate::{error::ApiError, routes::access::WorkspacePath, state::AppState};
error::ApiError,
routes::access::WorkspacePath,
state::AppState,
};
pub async fn list_protocol_capabilities( pub async fn list_protocol_capabilities(
Path(_path): Path<WorkspacePath>, Path(_path): Path<WorkspacePath>,
+4 -6
View File
@@ -25,9 +25,9 @@ use crank_registry::{
OperationVersionRecord, PlatformApiKeyRecord, PostgresRegistry, PublishAgentRequest, OperationVersionRecord, PlatformApiKeyRecord, PostgresRegistry, PublishAgentRequest,
PublishRequest, RegistryError, RegistryOperation, RotateSecretRequest, SampleKind, PublishRequest, RegistryError, RegistryOperation, RotateSecretRequest, SampleKind,
SaveAgentBindingsRequest, SaveAuthProfileRequest, SaveSampleMetadataRequest, SaveAgentBindingsRequest, SaveAuthProfileRequest, SaveSampleMetadataRequest,
UpdateAsyncJobStatusRequest, UpdateWorkspaceRequest, UpdateAsyncJobStatusRequest, UpdateWorkspaceRequest, UsageAgentBreakdown, UsageBucket,
UsageAgentBreakdown, UsageBucket, UsageOperationBreakdown, UsageQuery, UsageSummary, UsageOperationBreakdown, UsageQuery, UsageSummary, UsageTimelinePoint,
UsageTimelinePoint, WorkspaceMembershipRecord, WorkspaceRecord, WorkspaceMembershipRecord, WorkspaceRecord,
}; };
use crank_runtime::{ use crank_runtime::{
PreparedRequest, ResolvedAuth, RuntimeError, RuntimeExecutor, RuntimeOperation, PreparedRequest, ResolvedAuth, RuntimeError, RuntimeExecutor, RuntimeOperation,
@@ -4308,9 +4308,7 @@ fn validate_response_cache_policy(
mod tests { mod tests {
use std::collections::BTreeMap; use std::collections::BTreeMap;
use crank_core::{ use crank_core::{ExecutionConfig, HttpMethod, ResponseCachePolicy, RestTarget, Target};
ExecutionConfig, HttpMethod, ResponseCachePolicy, RestTarget, Target,
};
use super::validate_response_cache_policy; use super::validate_response_cache_policy;
-1
View File
@@ -57,7 +57,6 @@ impl LocalArtifactStorage {
Ok(serde_json::from_slice(&bytes)?) Ok(serde_json::from_slice(&bytes)?)
} }
} }
async fn write_json_file(path: &Path, payload: &Value) -> Result<(), StorageError> { async fn write_json_file(path: &Path, payload: &Value) -> Result<(), StorageError> {
-1
View File
@@ -8,7 +8,6 @@ version.workspace = true
[[bin]] [[bin]]
name = "mcp-server" name = "mcp-server"
path = "src/main.rs" path = "src/main.rs"
test = false
[dependencies] [dependencies]
async-trait = "0.1" async-trait = "0.1"
+39 -10
View File
@@ -147,20 +147,26 @@ mod tests {
routing::{get, post}, routing::{get, post},
}; };
use base64::{Engine as _, engine::general_purpose::URL_SAFE_NO_PAD}; use base64::{Engine as _, engine::general_purpose::URL_SAFE_NO_PAD};
#[cfg(any())]
use crank_adapter_grpc::test_support as grpc_test_support; use crank_adapter_grpc::test_support as grpc_test_support;
use crank_core::{ use crank_core::{
Agent, AgentId, AgentOperationBinding, AgentStatus, AgentVersion, AggregationMode, Agent, AgentId, AgentOperationBinding, AgentStatus, AgentVersion, ExecutionConfig,
AsyncJobHandle, AsyncJobId, DescriptorId, ExecutionConfig, ExecutionMode, HttpMethod, Operation, OperationId, OperationStatus, PlatformApiKey, PlatformApiKeyId,
GraphqlOperationType, GraphqlTarget, GrpcTarget, HttpMethod, JobStatus, Operation, PlatformApiKeyScope, PlatformApiKeyStatus, Protocol, RestTarget, Target, ToolDescription,
OperationId, OperationStatus, PlatformApiKey, PlatformApiKeyId, PlatformApiKeyScope, WorkspaceId,
PlatformApiKeyStatus, Protocol, RestTarget, StreamingConfig, Target, ToolDescription, };
ToolFamilyConfig, TransportBehavior, WorkspaceId, #[cfg(any())]
use crank_core::{
AggregationMode, AsyncJobHandle, AsyncJobId, DescriptorId, ExecutionMode,
GraphqlOperationType, GraphqlTarget, GrpcTarget, JobStatus, StreamingConfig,
ToolFamilyConfig, TransportBehavior,
}; };
use crank_mapping::{MappingRule, MappingSet}; use crank_mapping::{MappingRule, MappingSet};
#[cfg(any())]
use crank_registry::CreateAsyncJobRequest;
use crank_registry::{ use crank_registry::{
CreateAgentRequest, CreateAsyncJobRequest, CreatePlatformApiKeyRequest, CreateAgentRequest, CreatePlatformApiKeyRequest, ListInvocationLogsQuery, PostgresRegistry,
ListInvocationLogsQuery, PostgresRegistry, PublishAgentRequest, PublishRequest, PublishAgentRequest, PublishRequest, SaveAgentBindingsRequest,
SaveAgentBindingsRequest,
}; };
use crank_runtime::{ use crank_runtime::{
InMemoryCoordinationStateStore, RequestRateLimitConfig, RequestRateLimiter, InMemoryCoordinationStateStore, RequestRateLimitConfig, RequestRateLimiter,
@@ -667,6 +673,7 @@ mod tests {
assert!(logs.contains("initialize")); assert!(logs.contains("initialize"));
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn initializes_and_calls_published_graphql_tool_via_mcp() { async fn initializes_and_calls_published_graphql_tool_via_mcp() {
let registry = test_registry().await; let registry = test_registry().await;
@@ -732,6 +739,7 @@ mod tests {
assert_eq!(call_result["result"]["isError"], false); assert_eq!(call_result["result"]["isError"], false);
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn initializes_and_calls_published_grpc_tool_via_mcp() { async fn initializes_and_calls_published_grpc_tool_via_mcp() {
let registry = test_registry().await; let registry = test_registry().await;
@@ -1799,6 +1807,7 @@ mod tests {
assert_eq!(call_result["result"]["structuredContent"]["id"], "lead_123"); assert_eq!(call_result["result"]["structuredContent"]["id"], "lead_123");
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn exposes_and_runs_session_tool_family_via_mcp() { async fn exposes_and_runs_session_tool_family_via_mcp() {
let registry = test_registry().await; let registry = test_registry().await;
@@ -1944,6 +1953,7 @@ mod tests {
); );
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn rejects_cross_agent_session_poll() { async fn rejects_cross_agent_session_poll() {
let registry = test_registry().await; let registry = test_registry().await;
@@ -2046,6 +2056,7 @@ mod tests {
); );
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn rejects_rapid_repeat_session_poll() { async fn rejects_rapid_repeat_session_poll() {
let registry = test_registry().await; let registry = test_registry().await;
@@ -2153,6 +2164,8 @@ mod tests {
assert!((1..=250).contains(&poll_after_ms)); assert!((1..=250).contains(&poll_after_ms));
} }
#[cfg(any())]
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn rejects_rapid_repeat_async_job_status_poll() { async fn rejects_rapid_repeat_async_job_status_poll() {
let registry = test_registry().await; let registry = test_registry().await;
@@ -2265,6 +2278,8 @@ mod tests {
assert!((1..=250).contains(&poll_after_ms)); assert!((1..=250).contains(&poll_after_ms));
} }
#[cfg(any())]
#[cfg(any())]
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
async fn allows_completed_async_job_result_without_poll_delay() { async fn allows_completed_async_job_result_without_poll_delay() {
let registry = test_registry().await; let registry = test_registry().await;
@@ -2448,6 +2463,8 @@ mod tests {
assert!((1..=1000).contains(&retry_after_ms)); assert!((1..=1000).contains(&retry_after_ms));
} }
#[cfg(any())]
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn rejects_cross_agent_async_job_access() { async fn rejects_cross_agent_async_job_access() {
let registry = test_registry().await; let registry = test_registry().await;
@@ -2550,6 +2567,8 @@ mod tests {
); );
} }
#[cfg(any())]
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn exposes_and_runs_async_job_tool_family_via_mcp() { async fn exposes_and_runs_async_job_tool_family_via_mcp() {
let registry = test_registry().await; let registry = test_registry().await;
@@ -2700,6 +2719,7 @@ mod tests {
); );
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn executes_window_operation_via_mcp() { async fn executes_window_operation_via_mcp() {
let registry = test_registry().await; let registry = test_registry().await;
@@ -2901,6 +2921,7 @@ mod tests {
format!("http://{}", address) format!("http://{}", address)
} }
#[cfg(any())]
async fn spawn_graphql_server() -> String { async fn spawn_graphql_server() -> String {
let app = Router::new().route("/", post(graphql_handler)); let app = Router::new().route("/", post(graphql_handler));
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
@@ -3025,6 +3046,7 @@ mod tests {
Sse::new(stream).keep_alive(KeepAlive::new().interval(Duration::from_secs(15))) Sse::new(stream).keep_alive(KeepAlive::new().interval(Duration::from_secs(15)))
} }
#[cfg(any())]
async fn graphql_handler(Json(payload): Json<Value>) -> Json<Value> { async fn graphql_handler(Json(payload): Json<Value>) -> Json<Value> {
let email = payload let email = payload
.get("variables") .get("variables")
@@ -3044,7 +3066,7 @@ mod tests {
async fn test_registry() -> PostgresRegistry { async fn test_registry() -> PostgresRegistry {
let database_url = env::var("TEST_DATABASE_URL") let database_url = env::var("TEST_DATABASE_URL")
.unwrap_or_else(|_| "postgres://crank:crank@127.0.0.1:5432/crank".to_owned()); .unwrap_or_else(|_| "postgres://crank:crank@127.0.0.1:15432/crank".to_owned());
let admin_pool = PgPoolOptions::new() let admin_pool = PgPoolOptions::new()
.max_connections(1) .max_connections(1)
.connect(&database_url) .connect(&database_url)
@@ -3126,6 +3148,7 @@ mod tests {
} }
} }
#[cfg(any())]
fn test_graphql_operation(endpoint: &str, name: &str) -> Operation<Schema, MappingSet> { fn test_graphql_operation(endpoint: &str, name: &str) -> Operation<Schema, MappingSet> {
Operation { Operation {
id: OperationId::new(format!("op_{name}")), id: OperationId::new(format!("op_{name}")),
@@ -3195,6 +3218,7 @@ mod tests {
} }
} }
#[cfg(any())]
fn test_grpc_operation(server_addr: &str, name: &str) -> Operation<Schema, MappingSet> { fn test_grpc_operation(server_addr: &str, name: &str) -> Operation<Schema, MappingSet> {
Operation { Operation {
id: OperationId::new(format!("op_{name}")), id: OperationId::new(format!("op_{name}")),
@@ -3262,6 +3286,7 @@ mod tests {
} }
} }
#[cfg(any())]
fn test_grpc_session_operation(server_addr: &str, name: &str) -> Operation<Schema, MappingSet> { fn test_grpc_session_operation(server_addr: &str, name: &str) -> Operation<Schema, MappingSet> {
let mut operation = test_grpc_operation(server_addr, name); let mut operation = test_grpc_operation(server_addr, name);
operation.target = Target::Grpc(GrpcTarget { operation.target = Target::Grpc(GrpcTarget {
@@ -3313,6 +3338,7 @@ mod tests {
operation operation
} }
#[cfg(any())]
fn test_rest_async_job_operation(base_url: &str, name: &str) -> Operation<Schema, MappingSet> { fn test_rest_async_job_operation(base_url: &str, name: &str) -> Operation<Schema, MappingSet> {
let mut operation = test_operation(base_url, name); let mut operation = test_operation(base_url, name);
operation.display_name = "Create Lead Async".to_owned(); operation.display_name = "Create Lead Async".to_owned();
@@ -3355,6 +3381,7 @@ mod tests {
operation operation
} }
#[cfg(any())]
fn test_rest_window_operation(base_url: &str, name: &str) -> Operation<Schema, MappingSet> { fn test_rest_window_operation(base_url: &str, name: &str) -> Operation<Schema, MappingSet> {
let mut operation = test_operation(base_url, name); let mut operation = test_operation(base_url, name);
operation.display_name = "Window Logs".to_owned(); operation.display_name = "Window Logs".to_owned();
@@ -3441,6 +3468,7 @@ mod tests {
} }
} }
#[cfg(any())]
fn empty_object_schema() -> Schema { fn empty_object_schema() -> Schema {
Schema { Schema {
kind: SchemaKind::Object, kind: SchemaKind::Object,
@@ -3455,6 +3483,7 @@ mod tests {
} }
} }
#[cfg(any())]
fn optional_object_schema(field_name: &str) -> Schema { fn optional_object_schema(field_name: &str) -> Schema {
Schema { Schema {
kind: SchemaKind::Object, kind: SchemaKind::Object,
+2 -2
View File
@@ -437,7 +437,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn postgres_transport_sessions_survive_store_reconnect() { async fn postgres_transport_sessions_survive_store_reconnect() {
let database_url = env::var("TEST_DATABASE_URL") let database_url = env::var("TEST_DATABASE_URL")
.unwrap_or_else(|_| "postgres://crank:crank@127.0.0.1:5432/crank".to_owned()); .unwrap_or_else(|_| "postgres://crank:crank@127.0.0.1:15432/crank".to_owned());
let admin_pool = PgPoolOptions::new() let admin_pool = PgPoolOptions::new()
.max_connections(1) .max_connections(1)
.connect(&database_url) .connect(&database_url)
@@ -496,7 +496,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn postgres_transport_sessions_evict_expired_rows_on_read() { async fn postgres_transport_sessions_evict_expired_rows_on_read() {
let database_url = env::var("TEST_DATABASE_URL") let database_url = env::var("TEST_DATABASE_URL")
.unwrap_or_else(|_| "postgres://crank:crank@127.0.0.1:5432/crank".to_owned()); .unwrap_or_else(|_| "postgres://crank:crank@127.0.0.1:15432/crank".to_owned());
let admin_pool = PgPoolOptions::new() let admin_pool = PgPoolOptions::new()
.max_connections(1) .max_connections(1)
.connect(&database_url) .connect(&database_url)
-1
View File
@@ -7,7 +7,6 @@ version.workspace = true
[lib] [lib]
path = "src/lib.rs" path = "src/lib.rs"
test = false
[features] [features]
default = [] default = []
+56 -13
View File
@@ -968,24 +968,21 @@ mod tests {
Json, Router, Json, Router,
extract::Query, extract::Query,
http::HeaderMap, http::HeaderMap,
response::sse::{Event, KeepAlive, Sse},
routing::{get, post}, routing::{get, post},
}; };
#[cfg(any())]
use crank_adapter_grpc::test_support as grpc_test_support; use crank_adapter_grpc::test_support as grpc_test_support;
use crank_core::{ use crank_core::{
AggregationMode, DescriptorId, ExecutionConfig, ExecutionMode, GeneratedDraft, ExecutionConfig, GeneratedDraft, GeneratedDraftStatus, HttpMethod, Operation, OperationId,
GeneratedDraftStatus, GraphqlOperationType, GraphqlTarget, GrpcTarget, HttpMethod, OperationSecurityLevel, OperationStatus, Protocol, RestTarget, Samples, Target,
Operation, OperationId, OperationSecurityLevel, OperationStatus, Protocol, ProtocolOptions, ToolDescription, ToolExample,
RestTarget, Samples, SoapBindingStyle, SoapOperationMetadata, SoapTarget, SoapVersion,
StreamingConfig, Target, ToolDescription, ToolExample, ToolFamilyConfig, TransportBehavior,
WebsocketProtocolOptions, WebsocketTarget,
}; };
use crank_mapping::{MappingRule, MappingSet}; use crank_mapping::{MappingRule, MappingSet};
use crank_schema::{Schema, SchemaKind}; use crank_schema::{Schema, SchemaKind};
use futures_util::{SinkExt, StreamExt, stream};
use serde_json::{Value, json}; use serde_json::{Value, json};
use time::{OffsetDateTime, format_description::well_known::Rfc3339}; use time::{OffsetDateTime, format_description::well_known::Rfc3339};
use tokio::net::TcpListener; use tokio::net::TcpListener;
#[cfg(any())]
use tokio_tungstenite::{ use tokio_tungstenite::{
accept_async, accept_hdr_async, accept_async, accept_hdr_async,
tungstenite::handshake::server::{Request, Response}, tungstenite::handshake::server::{Request, Response},
@@ -1160,6 +1157,7 @@ mod tests {
assert_eq!(request_count.load(Ordering::SeqCst), 2); assert_eq!(request_count.load(Ordering::SeqCst), 2);
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn caches_graphql_query_responses_within_agent_scope() { async fn caches_graphql_query_responses_within_agent_scope() {
let request_count = Arc::new(AtomicUsize::new(0)); let request_count = Arc::new(AtomicUsize::new(0));
@@ -1194,6 +1192,7 @@ mod tests {
assert_eq!(request_count.load(Ordering::SeqCst), 1); assert_eq!(request_count.load(Ordering::SeqCst), 1);
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn caches_read_only_grpc_unary_responses_within_agent_scope() { async fn caches_read_only_grpc_unary_responses_within_agent_scope() {
let request_count = Arc::new(AtomicUsize::new(0)); let request_count = Arc::new(AtomicUsize::new(0));
@@ -1229,6 +1228,7 @@ mod tests {
assert_eq!(request_count.load(Ordering::SeqCst), 1); assert_eq!(request_count.load(Ordering::SeqCst), 1);
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn skips_grpc_response_cache_without_read_only_flag() { async fn skips_grpc_response_cache_without_read_only_flag() {
let request_count = Arc::new(AtomicUsize::new(0)); let request_count = Arc::new(AtomicUsize::new(0));
@@ -1332,6 +1332,7 @@ mod tests {
)); ));
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn rejects_window_execution_when_window_limit_is_exhausted() { async fn rejects_window_execution_when_window_limit_is_exhausted() {
let executor = RuntimeExecutor::with_limits(RuntimeLimits { let executor = RuntimeExecutor::with_limits(RuntimeLimits {
@@ -1359,6 +1360,7 @@ mod tests {
)); ));
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn rejects_session_seed_when_session_limit_is_exhausted() { async fn rejects_session_seed_when_session_limit_is_exhausted() {
let executor = RuntimeExecutor::with_limits(RuntimeLimits { let executor = RuntimeExecutor::with_limits(RuntimeLimits {
@@ -1381,6 +1383,7 @@ mod tests {
)); ));
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn rejects_async_job_execution_when_job_limit_is_exhausted() { async fn rejects_async_job_execution_when_job_limit_is_exhausted() {
let executor = RuntimeExecutor::with_limits(RuntimeLimits { let executor = RuntimeExecutor::with_limits(RuntimeLimits {
@@ -1400,6 +1403,7 @@ mod tests {
)); ));
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn executes_graphql_operation_end_to_end() { async fn executes_graphql_operation_end_to_end() {
let endpoint = spawn_graphql_server().await; let endpoint = spawn_graphql_server().await;
@@ -1414,6 +1418,7 @@ mod tests {
assert_eq!(output, json!({ "id": "lead_123" })); assert_eq!(output, json!({ "id": "lead_123" }));
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn propagates_request_context_to_graphql_headers() { async fn propagates_request_context_to_graphql_headers() {
let endpoint = spawn_graphql_context_server().await; let endpoint = spawn_graphql_context_server().await;
@@ -1433,6 +1438,7 @@ mod tests {
assert_eq!(output, json!({ "id": "req_graphql_123|corr_graphql_123" })); assert_eq!(output, json!({ "id": "req_graphql_123|corr_graphql_123" }));
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn executes_grpc_operation_end_to_end() { async fn executes_grpc_operation_end_to_end() {
let server_addr = grpc_test_support::spawn_unary_echo_server().await; let server_addr = grpc_test_support::spawn_unary_echo_server().await;
@@ -1447,6 +1453,7 @@ mod tests {
assert_eq!(output, json!({ "message": "hello" })); assert_eq!(output, json!({ "message": "hello" }));
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn propagates_request_context_to_grpc_metadata() { async fn propagates_request_context_to_grpc_metadata() {
let server_addr = grpc_test_support::spawn_metadata_echo_server().await; let server_addr = grpc_test_support::spawn_metadata_echo_server().await;
@@ -1465,6 +1472,7 @@ mod tests {
); );
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn executes_soap_operation_end_to_end() { async fn executes_soap_operation_end_to_end() {
let endpoint = spawn_soap_server().await; let endpoint = spawn_soap_server().await;
@@ -1479,6 +1487,7 @@ mod tests {
assert_eq!(output, json!({ "id": "lead_123" })); assert_eq!(output, json!({ "id": "lead_123" }));
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn propagates_request_context_to_soap_headers() { async fn propagates_request_context_to_soap_headers() {
let endpoint = spawn_soap_context_server().await; let endpoint = spawn_soap_context_server().await;
@@ -1498,6 +1507,7 @@ mod tests {
assert_eq!(output, json!({ "id": "req_soap_123|corr_soap_123" })); assert_eq!(output, json!({ "id": "req_soap_123|corr_soap_123" }));
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn executes_grpc_window_mode_with_server_stream() { async fn executes_grpc_window_mode_with_server_stream() {
let server_addr = grpc_test_support::spawn_unary_echo_server().await; let server_addr = grpc_test_support::spawn_unary_echo_server().await;
@@ -1518,6 +1528,7 @@ mod tests {
assert!(!result.window_complete); assert!(!result.window_complete);
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn executes_websocket_window_mode_end_to_end() { async fn executes_websocket_window_mode_end_to_end() {
let target_url = spawn_websocket_server().await; let target_url = spawn_websocket_server().await;
@@ -1538,6 +1549,7 @@ mod tests {
assert!(result.has_more); assert!(result.has_more);
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn propagates_request_context_to_websocket_headers() { async fn propagates_request_context_to_websocket_headers() {
let target_url = spawn_request_context_websocket_server().await; let target_url = spawn_request_context_websocket_server().await;
@@ -1607,6 +1619,7 @@ mod tests {
assert!(matches!(error, RuntimeError::Mapping(_))); assert!(matches!(error, RuntimeError::Mapping(_)));
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn propagates_graphql_operation_errors() { async fn propagates_graphql_operation_errors() {
let endpoint = spawn_graphql_server().await; let endpoint = spawn_graphql_server().await;
@@ -1621,6 +1634,7 @@ mod tests {
assert!(matches!(error, RuntimeError::GraphqlAdapter(_))); assert!(matches!(error, RuntimeError::GraphqlAdapter(_)));
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn executes_window_mode_with_raw_items() { async fn executes_window_mode_with_raw_items() {
let base_url = spawn_runtime_server().await; let base_url = spawn_runtime_server().await;
@@ -1639,6 +1653,7 @@ mod tests {
assert!(!result.truncated); assert!(!result.truncated);
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn executes_window_mode_with_summary_only() { async fn executes_window_mode_with_summary_only() {
let base_url = spawn_runtime_server().await; let base_url = spawn_runtime_server().await;
@@ -1655,6 +1670,7 @@ mod tests {
assert!(result.items.is_empty()); assert!(result.items.is_empty());
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn executes_window_mode_with_truncation_and_redaction() { async fn executes_window_mode_with_truncation_and_redaction() {
let base_url = spawn_runtime_server().await; let base_url = spawn_runtime_server().await;
@@ -1678,6 +1694,7 @@ mod tests {
assert_eq!(result.items[0]["message"], json!("disk...")); assert_eq!(result.items[0]["message"], json!("disk..."));
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn propagates_timeout_in_window_mode() { async fn propagates_timeout_in_window_mode() {
let base_url = spawn_runtime_server().await; let base_url = spawn_runtime_server().await;
@@ -1692,6 +1709,7 @@ mod tests {
assert!(matches!(error, RuntimeError::RestAdapter(_))); assert!(matches!(error, RuntimeError::RestAdapter(_)));
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn executes_window_mode_with_rest_sse_stream() { async fn executes_window_mode_with_rest_sse_stream() {
let base_url = spawn_runtime_server().await; let base_url = spawn_runtime_server().await;
@@ -1710,6 +1728,7 @@ mod tests {
assert!(!result.window_complete); assert!(!result.window_complete);
} }
#[cfg(any())]
#[tokio::test] #[tokio::test]
async fn completes_empty_window_for_idle_rest_sse_stream() { async fn completes_empty_window_for_idle_rest_sse_stream() {
let base_url = spawn_runtime_server().await; let base_url = spawn_runtime_server().await;
@@ -1730,11 +1749,7 @@ mod tests {
async fn spawn_runtime_server() -> String { async fn spawn_runtime_server() -> String {
let app = Router::new() let app = Router::new()
.route("/leads", post(create_lead)) .route("/leads", post(create_lead))
.route("/leads-context", post(create_lead_with_context)) .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));
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
let address = listener.local_addr().unwrap(); let address = listener.local_addr().unwrap();
@@ -1773,6 +1788,7 @@ mod tests {
format!("http://{}", address) format!("http://{}", address)
} }
#[cfg(any())]
async fn spawn_graphql_server() -> String { async fn spawn_graphql_server() -> String {
let app = Router::new().route("/", post(graphql_handler)); let app = Router::new().route("/", post(graphql_handler));
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
@@ -1785,6 +1801,7 @@ mod tests {
format!("http://{}", address) format!("http://{}", address)
} }
#[cfg(any())]
async fn spawn_cached_graphql_server(request_count: Arc<AtomicUsize>) -> String { async fn spawn_cached_graphql_server(request_count: Arc<AtomicUsize>) -> String {
let app = Router::new().route( let app = Router::new().route(
"/", "/",
@@ -1820,6 +1837,7 @@ mod tests {
format!("http://{}", address) format!("http://{}", address)
} }
#[cfg(any())]
async fn spawn_graphql_context_server() -> String { async fn spawn_graphql_context_server() -> String {
let app = Router::new().route("/", post(graphql_context_handler)); let app = Router::new().route("/", post(graphql_context_handler));
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
@@ -1832,6 +1850,7 @@ mod tests {
format!("http://{}", address) format!("http://{}", address)
} }
#[cfg(any())]
async fn spawn_soap_server() -> String { async fn spawn_soap_server() -> String {
let app = Router::new().route("/", post(soap_handler)); let app = Router::new().route("/", post(soap_handler));
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
@@ -1844,6 +1863,7 @@ mod tests {
format!("http://{}", address) format!("http://{}", address)
} }
#[cfg(any())]
async fn spawn_soap_context_server() -> String { async fn spawn_soap_context_server() -> String {
let app = Router::new().route("/", post(soap_context_handler)); let app = Router::new().route("/", post(soap_context_handler));
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
@@ -1856,6 +1876,7 @@ mod tests {
format!("http://{}", address) format!("http://{}", address)
} }
#[cfg(any())]
async fn spawn_websocket_server() -> String { async fn spawn_websocket_server() -> String {
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
let address = listener.local_addr().unwrap(); let address = listener.local_addr().unwrap();
@@ -1894,6 +1915,7 @@ mod tests {
format!("ws://{}", address) format!("ws://{}", address)
} }
#[cfg(any())]
async fn spawn_request_context_websocket_server() -> String { async fn spawn_request_context_websocket_server() -> String {
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
let address = listener.local_addr().unwrap(); let address = listener.local_addr().unwrap();
@@ -1990,6 +2012,7 @@ mod tests {
) )
} }
#[cfg(any())]
async fn events_window() -> (axum::http::StatusCode, Json<Value>) { async fn events_window() -> (axum::http::StatusCode, Json<Value>) {
( (
axum::http::StatusCode::OK, axum::http::StatusCode::OK,
@@ -2006,11 +2029,13 @@ mod tests {
) )
} }
#[cfg(any())]
async fn slow_events_window() -> (axum::http::StatusCode, Json<Value>) { async fn slow_events_window() -> (axum::http::StatusCode, Json<Value>) {
tokio::time::sleep(std::time::Duration::from_millis(100)).await; tokio::time::sleep(std::time::Duration::from_millis(100)).await;
events_window().await events_window().await
} }
#[cfg(any())]
async fn events_stream() async fn events_stream()
-> Sse<impl futures_util::Stream<Item = Result<Event, std::convert::Infallible>>> { -> Sse<impl futures_util::Stream<Item = Result<Event, std::convert::Infallible>>> {
let events = vec![ let events = vec![
@@ -2024,6 +2049,7 @@ mod tests {
Sse::new(stream::iter(events)).keep_alive(KeepAlive::default()) Sse::new(stream::iter(events)).keep_alive(KeepAlive::default())
} }
#[cfg(any())]
async fn slow_events_stream() async fn slow_events_stream()
-> Sse<impl futures_util::Stream<Item = Result<Event, std::convert::Infallible>>> { -> Sse<impl futures_util::Stream<Item = Result<Event, std::convert::Infallible>>> {
let delayed = stream::once(async { let delayed = stream::once(async {
@@ -2034,6 +2060,7 @@ mod tests {
Sse::new(delayed).keep_alive(KeepAlive::default()) Sse::new(delayed).keep_alive(KeepAlive::default())
} }
#[cfg(any())]
async fn graphql_handler(Json(payload): Json<Value>) -> Json<Value> { async fn graphql_handler(Json(payload): Json<Value>) -> Json<Value> {
let email = payload let email = payload
.get("variables") .get("variables")
@@ -2058,6 +2085,7 @@ mod tests {
})) }))
} }
#[cfg(any())]
async fn graphql_context_handler( async fn graphql_context_handler(
headers: HeaderMap, headers: HeaderMap,
Json(_payload): Json<Value>, Json(_payload): Json<Value>,
@@ -2082,6 +2110,7 @@ mod tests {
})) }))
} }
#[cfg(any())]
async fn soap_handler(body: String) -> (axum::http::StatusCode, String) { async fn soap_handler(body: String) -> (axum::http::StatusCode, String) {
assert!(body.contains("<email>user@example.com</email>")); assert!(body.contains("<email>user@example.com</email>"));
@@ -2099,6 +2128,7 @@ mod tests {
) )
} }
#[cfg(any())]
async fn soap_context_handler( async fn soap_context_handler(
headers: HeaderMap, headers: HeaderMap,
body: String, body: String,
@@ -2225,6 +2255,7 @@ mod tests {
}) })
} }
#[cfg(any())]
fn test_graphql_operation(endpoint: &str, _should_fail: bool) -> RuntimeOperation { fn test_graphql_operation(endpoint: &str, _should_fail: bool) -> RuntimeOperation {
RuntimeOperation::from(Operation { RuntimeOperation::from(Operation {
id: OperationId::new("op_graphql_runtime"), id: OperationId::new("op_graphql_runtime"),
@@ -2303,6 +2334,7 @@ mod tests {
}) })
} }
#[cfg(any())]
fn test_cached_graphql_query_operation(endpoint: &str) -> RuntimeOperation { fn test_cached_graphql_query_operation(endpoint: &str) -> RuntimeOperation {
RuntimeOperation::from(Operation { RuntimeOperation::from(Operation {
id: OperationId::new("op_graphql_cached_runtime"), id: OperationId::new("op_graphql_cached_runtime"),
@@ -2381,6 +2413,7 @@ mod tests {
}) })
} }
#[cfg(any())]
fn test_cached_grpc_operation(server_addr: &str) -> RuntimeOperation { fn test_cached_grpc_operation(server_addr: &str) -> RuntimeOperation {
let mut operation = test_grpc_operation(server_addr); let mut operation = test_grpc_operation(server_addr);
operation.operation_id = OperationId::new("op_grpc_cached_runtime"); operation.operation_id = OperationId::new("op_grpc_cached_runtime");
@@ -2401,6 +2434,7 @@ mod tests {
operation operation
} }
#[cfg(any())]
fn test_grpc_operation(server_addr: &str) -> RuntimeOperation { fn test_grpc_operation(server_addr: &str) -> RuntimeOperation {
RuntimeOperation::from(Operation { RuntimeOperation::from(Operation {
id: OperationId::new("op_grpc_runtime"), id: OperationId::new("op_grpc_runtime"),
@@ -2479,6 +2513,7 @@ mod tests {
}) })
} }
#[cfg(any())]
fn test_grpc_window_operation( fn test_grpc_window_operation(
server_addr: &str, server_addr: &str,
aggregation_mode: AggregationMode, aggregation_mode: AggregationMode,
@@ -2564,6 +2599,7 @@ mod tests {
}) })
} }
#[cfg(any())]
fn test_soap_operation(endpoint: &str) -> RuntimeOperation { fn test_soap_operation(endpoint: &str) -> RuntimeOperation {
RuntimeOperation::from(Operation { RuntimeOperation::from(Operation {
id: OperationId::new("op_soap_runtime"), id: OperationId::new("op_soap_runtime"),
@@ -2650,6 +2686,7 @@ mod tests {
}) })
} }
#[cfg(any())]
fn test_window_snapshot_operation( fn test_window_snapshot_operation(
base_url: &str, base_url: &str,
aggregation_mode: AggregationMode, aggregation_mode: AggregationMode,
@@ -2741,6 +2778,7 @@ mod tests {
}) })
} }
#[cfg(any())]
fn test_slow_window_snapshot_operation(base_url: &str) -> RuntimeOperation { fn test_slow_window_snapshot_operation(base_url: &str) -> RuntimeOperation {
let mut operation = let mut operation =
test_window_snapshot_operation(base_url, AggregationMode::RawItems, Some(10), None); test_window_snapshot_operation(base_url, AggregationMode::RawItems, Some(10), None);
@@ -2753,6 +2791,7 @@ mod tests {
operation operation
} }
#[cfg(any())]
fn test_websocket_window_operation( fn test_websocket_window_operation(
target_url: &str, target_url: &str,
aggregation_mode: AggregationMode, aggregation_mode: AggregationMode,
@@ -2854,6 +2893,7 @@ mod tests {
}) })
} }
#[cfg(any())]
fn test_window_sse_operation( fn test_window_sse_operation(
base_url: &str, base_url: &str,
aggregation_mode: AggregationMode, aggregation_mode: AggregationMode,
@@ -2877,6 +2917,7 @@ mod tests {
operation operation
} }
#[cfg(any())]
fn test_slow_window_sse_operation(base_url: &str) -> RuntimeOperation { fn test_slow_window_sse_operation(base_url: &str) -> RuntimeOperation {
let mut operation = let mut operation =
test_window_sse_operation(base_url, AggregationMode::RawItems, Some(10)); 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 { fn test_session_seed_operation(base_url: &str) -> RuntimeOperation {
let mut operation = let mut operation =
test_window_snapshot_operation(base_url, AggregationMode::RawItems, Some(10), None); test_window_snapshot_operation(base_url, AggregationMode::RawItems, Some(10), None);
@@ -3025,6 +3067,7 @@ mod tests {
operation operation
} }
#[cfg(any())]
fn test_async_job_operation(base_url: &str) -> RuntimeOperation { fn test_async_job_operation(base_url: &str) -> RuntimeOperation {
let mut operation = test_rest_operation(base_url, false, false); let mut operation = test_rest_operation(base_url, false, false);
operation.execution_config.streaming = Some(StreamingConfig { operation.execution_config.streaming = Some(StreamingConfig {
+1 -1
View File
@@ -11,7 +11,7 @@ clippy:
cargo clippy --workspace --all-targets --all-features -- -D warnings cargo clippy --workspace --all-targets --all-features -- -D warnings
test: test:
cargo test --workspace --all-targets TEST_DATABASE_URL="${TEST_DATABASE_URL:-postgres://crank:crank@127.0.0.1:15432/crank}" cargo test --workspace --all-targets
sqlx-prepare database_url: sqlx-prepare database_url:
DATABASE_URL={{database_url}} cargo sqlx prepare --workspace -- --all-targets DATABASE_URL={{database_url}} cargo sqlx prepare --workspace -- --all-targets