feat(inboundapi): mint inbound ExecutionId early, carry it as RouteToCallRequest.ParentExecutionId
This commit is contained in:
@@ -233,6 +233,71 @@ public class RouteHelperTests
|
||||
Assert.Equal(explicitCts.Token, seen);
|
||||
}
|
||||
|
||||
// --- Audit Log #23 (ParentExecutionId, T3): a routed call carries the
|
||||
// inbound request's ExecutionId as RouteToCallRequest.ParentExecutionId ---
|
||||
|
||||
[Fact]
|
||||
public async Task Call_WithoutParentExecutionId_LeavesParentExecutionIdNull()
|
||||
{
|
||||
// A RouteHelper not bound to an inbound execution id (e.g. the Central UI
|
||||
// sandbox path) builds requests with ParentExecutionId null.
|
||||
SiteResolves("inst-1", "SiteA");
|
||||
RouteToCallRequest? captured = null;
|
||||
_router.RouteToCallAsync("SiteA", Arg.Do<RouteToCallRequest>(r => captured = r), Arg.Any<CancellationToken>())
|
||||
.Returns(ci => new RouteToCallResponse(
|
||||
((RouteToCallRequest)ci[1]).CorrelationId, true, null, null, DateTimeOffset.UtcNow));
|
||||
|
||||
await CreateHelper().To("inst-1").Call("doWork");
|
||||
|
||||
Assert.NotNull(captured);
|
||||
Assert.Null(captured!.ParentExecutionId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Call_WithParentExecutionId_CarriesItOnRouteToCallRequest()
|
||||
{
|
||||
// A RouteHelper bound to the inbound request's ExecutionId must stamp that
|
||||
// id onto the routed RouteToCallRequest so the site script records it as
|
||||
// its ParentExecutionId.
|
||||
SiteResolves("inst-1", "SiteA");
|
||||
var inboundExecutionId = Guid.NewGuid();
|
||||
RouteToCallRequest? captured = null;
|
||||
_router.RouteToCallAsync("SiteA", Arg.Do<RouteToCallRequest>(r => captured = r), Arg.Any<CancellationToken>())
|
||||
.Returns(ci => new RouteToCallResponse(
|
||||
((RouteToCallRequest)ci[1]).CorrelationId, true, null, null, DateTimeOffset.UtcNow));
|
||||
|
||||
var bound = CreateHelper().WithParentExecutionId(inboundExecutionId);
|
||||
await bound.To("inst-1").Call("doWork");
|
||||
|
||||
Assert.NotNull(captured);
|
||||
Assert.Equal(inboundExecutionId, captured!.ParentExecutionId);
|
||||
// ParentExecutionId is a separate concern from the per-op CorrelationId —
|
||||
// the helper still mints its own routed-call correlation id.
|
||||
Assert.True(Guid.TryParse(captured.CorrelationId, out _));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WithParentExecutionId_PreservesDeadlineToken()
|
||||
{
|
||||
// The two builder methods compose — binding a parent execution id must
|
||||
// not drop a previously-bound deadline token.
|
||||
SiteResolves("inst-1", "SiteA");
|
||||
using var deadline = new CancellationTokenSource();
|
||||
CancellationToken seen = default;
|
||||
RouteToCallRequest? captured = null;
|
||||
_router.RouteToCallAsync("SiteA", Arg.Do<RouteToCallRequest>(r => captured = r), Arg.Do<CancellationToken>(t => seen = t))
|
||||
.Returns(ci => new RouteToCallResponse(
|
||||
((RouteToCallRequest)ci[1]).CorrelationId, true, null, null, DateTimeOffset.UtcNow));
|
||||
|
||||
var bound = CreateHelper()
|
||||
.WithDeadline(deadline.Token)
|
||||
.WithParentExecutionId(Guid.NewGuid());
|
||||
await bound.To("inst-1").Call("doWork");
|
||||
|
||||
Assert.Equal(deadline.Token, seen);
|
||||
Assert.NotNull(captured!.ParentExecutionId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetAttributes_WithNoExplicitToken_InheritsMethodDeadlineToken()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user