feat: complete Epic 1 production foundation
This commit is contained in:
@@ -6,15 +6,14 @@ use std::sync::{
|
||||
|
||||
use async_trait::async_trait;
|
||||
use crank_core::{
|
||||
AdapterResponse, ExecutionConfig, ExecutionMode, HttpMethod, IdempotencyMode,
|
||||
IdempotencyPolicy, Operation, OperationId, OperationSecurityLevel, OperationStatus, Protocol,
|
||||
ProtocolAdapter, ProtocolAdapterError, RestTarget, RuntimeRequestContext, Target,
|
||||
ToolDescription,
|
||||
AdapterResponse, ExecutionConfig, ExecutionErrorCode, ExecutionMode, HttpMethod,
|
||||
IdempotencyMode, IdempotencyPolicy, Operation, OperationId, OperationSecurityLevel,
|
||||
OperationStatus, Protocol, ProtocolAdapter, ProtocolAdapterError, RestTarget,
|
||||
RuntimeRequestContext, Target, ToolDescription,
|
||||
};
|
||||
use crank_mapping::{MappingRule, MappingSet};
|
||||
use crank_runtime::{
|
||||
InMemoryCoordinationStateStore, InMemoryResponseCacheStore, RuntimeError,
|
||||
RuntimeExecutorBuilder,
|
||||
InMemoryCoordinationStateStore, InMemoryResponseCacheStore, RuntimeExecutorBuilder,
|
||||
};
|
||||
use crank_schema::{Schema, SchemaKind};
|
||||
use serde_json::json;
|
||||
@@ -71,10 +70,10 @@ async fn required_idempotency_rejects_missing_key_before_adapter_call() {
|
||||
.await
|
||||
.expect_err("missing idempotency key must fail");
|
||||
|
||||
assert!(matches!(
|
||||
error,
|
||||
crank_runtime::RuntimeError::InvalidPreparedRequest { .. }
|
||||
));
|
||||
assert_eq!(
|
||||
error.error_code(),
|
||||
ExecutionErrorCode::PreparedRequestInvalid
|
||||
);
|
||||
assert_eq!(call_count.load(Ordering::SeqCst), 0);
|
||||
}
|
||||
|
||||
@@ -100,10 +99,10 @@ async fn required_idempotency_fails_closed_without_coordination_store() {
|
||||
.await
|
||||
.expect_err("required idempotency must not execute without an atomic store");
|
||||
|
||||
assert!(matches!(
|
||||
error,
|
||||
RuntimeError::IdempotencyStoreUnavailable { .. }
|
||||
));
|
||||
assert_eq!(
|
||||
error.error_code(),
|
||||
ExecutionErrorCode::SafetyStoreUnavailable
|
||||
);
|
||||
assert_eq!(call_count.load(Ordering::SeqCst), 0);
|
||||
}
|
||||
|
||||
@@ -186,7 +185,7 @@ async fn same_key_with_different_input_is_rejected() {
|
||||
.await
|
||||
.expect_err("same key must not accept a different request fingerprint");
|
||||
|
||||
assert!(matches!(error, RuntimeError::IdempotencyConflict { .. }));
|
||||
assert_eq!(error.error_code(), ExecutionErrorCode::IdempotencyConflict);
|
||||
assert_eq!(call_count.load(Ordering::SeqCst), 1);
|
||||
}
|
||||
|
||||
@@ -208,16 +207,19 @@ async fn uncertain_adapter_failure_blocks_automatic_retry() {
|
||||
.execute_with_context(&operation, &input, Some(&context))
|
||||
.await
|
||||
.expect_err("adapter failure must be returned");
|
||||
assert!(matches!(first, RuntimeError::ProtocolAdapter(_)));
|
||||
assert_eq!(
|
||||
first.error_code(),
|
||||
ExecutionErrorCode::UpstreamTransportError
|
||||
);
|
||||
|
||||
let retry = executor
|
||||
.execute_with_context(&operation, &input, Some(&context))
|
||||
.await
|
||||
.expect_err("an uncertain external outcome must not be retried automatically");
|
||||
assert!(matches!(
|
||||
retry,
|
||||
RuntimeError::IdempotencyOutcomeUnknown { .. }
|
||||
));
|
||||
assert_eq!(
|
||||
retry.error_code(),
|
||||
ExecutionErrorCode::IdempotencyOutcomeUnknown
|
||||
);
|
||||
assert_eq!(call_count.load(Ordering::SeqCst), 1);
|
||||
}
|
||||
|
||||
@@ -257,9 +259,9 @@ impl ProtocolAdapter for FailingAdapter {
|
||||
_context: &RuntimeRequestContext,
|
||||
) -> Result<AdapterResponse, ProtocolAdapterError> {
|
||||
self.call_count.fetch_add(1, Ordering::SeqCst);
|
||||
Err(ProtocolAdapterError::Message(
|
||||
"upstream outcome is unknown".to_owned(),
|
||||
))
|
||||
Err(ProtocolAdapterError::Transport {
|
||||
dispatch: crank_core::DispatchEvidence::MayHaveDispatched,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,3 +383,4 @@ fn string_schema() -> Schema {
|
||||
variants: Vec::new(),
|
||||
}
|
||||
}
|
||||
use crate::support::RuntimeExecutorTestExt;
|
||||
|
||||
Reference in New Issue
Block a user