Skip to content

Commit 73c8ee0

Browse files
committed
Add test for suborchestration failure.
1 parent 6b67b9d commit 73c8ee0

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed

test/Grpc.IntegrationTests/TracingIntegrationTests.cs

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,117 @@ public async Task TaskWithSuborchestration()
350350
});
351351
}
352352

353+
[Fact]
354+
public async Task TaskWithSuborchestrationFailure()
355+
{
356+
var activities = new List<Activity>();
357+
358+
using var listener = CreateListener(ActivitySourceNames, activities);
359+
360+
string orchestratorName = nameof(TaskWithSuborchestrationFailure);
361+
string subOrchestratorName = "SubOrchestration";
362+
string activityName = nameof(TestActivityAsync);
363+
364+
await using HostTestLifetime server = await this.StartWorkerAsync(b =>
365+
{
366+
b.AddTasks(tasks => tasks
367+
.AddOrchestratorFunc<bool, bool>(
368+
orchestratorName,
369+
async (ctx, input) =>
370+
{
371+
await ctx.CallSubOrchestratorAsync(subOrchestratorName, input: false);
372+
373+
return true;
374+
})
375+
.AddOrchestratorFunc<bool, bool>(
376+
subOrchestratorName,
377+
async (ctx, input) =>
378+
{
379+
await ctx.CallActivityAsync(nameof(TestActivityAsync), input);
380+
381+
return true;
382+
})
383+
.AddActivityFunc<bool, bool>(activityName, (_, input) => TestActivityAsync(input)));
384+
});
385+
386+
string instanceId;
387+
388+
using (var activity = TestActivitySource.StartActivity("Test"))
389+
{
390+
instanceId = await server.Client.ScheduleNewOrchestrationInstanceAsync(orchestratorName, input: true, cancellation: this.TimeoutToken);
391+
392+
OrchestrationMetadata metadata = await server.Client.WaitForInstanceCompletionAsync(instanceId, getInputsAndOutputs: true, this.TimeoutToken);
393+
}
394+
395+
var testActivity = activities.Single(a => a.Source == TestActivitySource && a.OperationName == "Test");
396+
var createActivity = activities.Single(a => a.Source.Name == CoreActivitySourceName && a.OperationName == $"create_orchestration:{orchestratorName}");
397+
398+
// The creation activity should be parented to the test activity.
399+
createActivity.ParentId.Should().Be(testActivity.Id);
400+
createActivity.ParentSpanId.Should().Be(testActivity.SpanId);
401+
createActivity.TagObjects.Should().ContainKey("durabletask.task.instance_id").WhoseValue.Should().Be(instanceId);
402+
createActivity.TagObjects.Should().ContainKey("durabletask.task.name").WhoseValue.Should().Be(orchestratorName);
403+
createActivity.TagObjects.Should().ContainKey("durabletask.type").WhoseValue.Should().Be("orchestration");
404+
405+
var orchestrationActivities = activities.Where(a => a.Source.Name == CoreActivitySourceName && a.OperationName == $"orchestration:{orchestratorName}").ToList();
406+
407+
orchestrationActivities.Should().HaveCountGreaterThan(0);
408+
409+
// The orchestration activities should be the same "logical" orchestration activity.
410+
orchestrationActivities.Select(a => a.StartTimeUtc).Distinct().Should().HaveCount(1);
411+
orchestrationActivities.Select(a => a.Id).Distinct().Should().HaveCount(1);
412+
orchestrationActivities.Select(a => a.SpanId).Distinct().Should().HaveCount(1);
413+
414+
// The orchestration activities should be parented to the create activity.
415+
orchestrationActivities
416+
.Should().AllSatisfy(a =>
417+
{
418+
a.Kind.Should().Be(ActivityKind.Server);
419+
a.ParentId.Should().Be(createActivity.Id);
420+
a.ParentSpanId.Should().Be(createActivity.SpanId);
421+
a.Status.Should().Be(ActivityStatusCode.Error);
422+
423+
a.TagObjects.Should().ContainKey("durabletask.task.instance_id").WhoseValue.Should().Be(instanceId);
424+
a.TagObjects.Should().ContainKey("durabletask.task.name").WhoseValue.Should().Be(orchestratorName);
425+
a.TagObjects.Should().ContainKey("durabletask.type").WhoseValue.Should().Be("orchestration");
426+
});
427+
428+
var orchestrationActivity = orchestrationActivities.First();
429+
430+
var clientSuborchestrationActivities = activities.Where(a => a.Kind == ActivityKind.Client && a.Source.Name == CoreActivitySourceName && a.OperationName == $"orchestration:{subOrchestratorName}").ToList();
431+
432+
// The client suborchestration activities should be parented to the orchestration activity.
433+
clientSuborchestrationActivities
434+
.Should().HaveCount(1)
435+
.And.AllSatisfy(a =>
436+
{
437+
a.ParentId.Should().Be(orchestrationActivity.Id);
438+
a.ParentSpanId.Should().Be(orchestrationActivity.SpanId);
439+
a.Status.Should().Be(ActivityStatusCode.Error);
440+
441+
a.TagObjects.Should().ContainKey("durabletask.task.instance_id").WhoseValue.Should().Be(instanceId);
442+
a.TagObjects.Should().ContainKey("durabletask.task.name").WhoseValue.Should().Be(subOrchestratorName);
443+
a.TagObjects.Should().ContainKey("durabletask.type").WhoseValue.Should().Be("orchestration");
444+
});
445+
446+
var clientSuborchestrationActivity = clientSuborchestrationActivities.First();
447+
448+
var serverSuborchestrationActivities = activities.Where(a => a.Kind == ActivityKind.Server && a.Source.Name == CoreActivitySourceName && a.OperationName == $"orchestration:{subOrchestratorName}").ToList();
449+
450+
// The server suborchestration activities should be parented to the client orchestration activity.
451+
serverSuborchestrationActivities
452+
.Should().HaveCountGreaterThan(0)
453+
.And.AllSatisfy(a =>
454+
{
455+
a.ParentId.Should().Be(clientSuborchestrationActivity.Id);
456+
a.ParentSpanId.Should().Be(clientSuborchestrationActivity.SpanId);
457+
a.Status.Should().Be(ActivityStatusCode.Error);
458+
459+
a.TagObjects.Should().ContainKey("durabletask.task.name").WhoseValue.Should().Be(subOrchestratorName);
460+
a.TagObjects.Should().ContainKey("durabletask.type").WhoseValue.Should().Be("orchestration");
461+
});
462+
}
463+
353464
[Fact]
354465
public async Task TaskOrchestrationWithSentEvent()
355466
{

0 commit comments

Comments
 (0)