Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 71 additions & 8 deletions Test/DurableTask.Core.Tests/TestTaskEntityDispatcher.cs
Original file line number Diff line number Diff line change
@@ -1,25 +1,88 @@
using DurableTask.Core.Entities;
using DurableTask.Core.Entities.OperationFormat;
using DurableTask.Core.History;
using DurableTask.Core.Logging;
using DurableTask.Core.Middleware;
using DurableTask.Emulator;
using DurableTask.Test.Orchestrations;
using Microsoft.Extensions.Logging;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using static DurableTask.Core.TaskEntityDispatcher;

namespace DurableTask.Core.Tests
{
[TestClass]
public class TestTaskEntityDispatcher
{
/// <summary>
/// Utiliy function to create a TaskEntityDispatcher instance. To be expanded upon as per testing needs.
/// </summary>
/// <returns></returns>
private TaskEntityDispatcher GetTaskEntityDispatcher()
{
// TODO: these should probably be injectable parameters to this method,
// initialized with sensible defaults if not provided
var service = new LocalOrchestrationService();
ILoggerFactory loggerFactory = null;
var entityManager = new NameVersionObjectManager<TaskEntity>();
var entityMiddleware = new DispatchMiddlewarePipeline();
var logger = new LogHelper(loggerFactory?.CreateLogger("DurableTask.Core"));

TaskEntityDispatcher dispatcher = new TaskEntityDispatcher(
service, entityManager, entityMiddleware, logger, ErrorPropagationMode.UseFailureDetails);
return dispatcher;
}

/// <summary>
/// See: https://github.com/Azure/durabletask/pull/1080
/// This test is motivated by a regression where Entities
/// that scheduled sub-orchestrators would incorrectly set
/// the FireAndForget tag on the ExecutionStartedEvent, causing
/// them to then receive a SubOrchestrationCompleted event, which
/// they did not know how to handle. Eventually, this led to them deleting
/// their own state. This test checks against that case.
/// </summary>
[TestMethod]
public void TestScheduleOrchestration()
public void TestEntityDoesNotSetFireAndForgetTags()
{
var service = new LocalOrchestrationService();
TaskEntityDispatcher dispatcher = GetTaskEntityDispatcher();

// Prepare effects
var effects = new WorkItemEffects();
effects.taskIdCounter = 0;
effects.InstanceMessages = new List<TaskMessage>();

// Prepare runtime state
var mockEntityStartEvent = new ExecutionStartedEvent(-1, null)
{
OrchestrationInstance = new OrchestrationInstance(),
Name = "testentity",
Version = "1.0",
};
var runtimeState = new OrchestrationRuntimeState();
runtimeState.AddEvent(mockEntityStartEvent);

// Prepare action.
// This mocks starting a new orchestration from an entity.
var action = new StartNewOrchestrationOperationAction()
{
InstanceId = "testsample",
Name = "test",
Version = "1.0",
Input = null,
};

// Invoke the dispatcher and obtain resulting event
dispatcher.ProcessSendStartMessage(effects, runtimeState, action);
HistoryEvent resultEvent = effects.InstanceMessages[0].Event;

var entityTestHelper = new EntityTestHelper(service);
var testEvent = entityTestHelper.TestScheduleOrchestrationTags();
Assert.IsInstanceOfType(resultEvent, typeof(ExecutionStartedEvent));
var executionStartedEvent = (ExecutionStartedEvent)resultEvent;

Assert.IsInstanceOfType(testEvent, typeof(ExecutionStartedEvent));
var testEventTags = (ExecutionStartedEvent)testEvent;
bool containsKey = testEventTags.Tags.ContainsKey(OrchestrationTags.FireAndForget);
Assert.IsTrue(containsKey);
// The resulting event should not contain a fire and forget tag
bool hasFireAndForgetTag = executionStartedEvent.Tags.ContainsKey(OrchestrationTags.FireAndForget);
Assert.IsFalse(hasFireAndForgetTag);
}
}
}
55 changes: 0 additions & 55 deletions src/DurableTask.Core/Entities/EntityTestHelper.cs

This file was deleted.

34 changes: 2 additions & 32 deletions src/DurableTask.Core/TaskEntityDispatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ async Task OnProcessWorkItemSessionAsync(TaskOrchestrationWorkItem workItem)
}
}

class WorkItemEffects
internal class WorkItemEffects
{
public List<TaskMessage> ActivityMessages;
public List<TaskMessage> TimerMessages;
Expand Down Expand Up @@ -794,7 +794,7 @@ void ProcessSendEventMessage(WorkItemEffects effects, OrchestrationInstance dest
});
}

void ProcessSendStartMessage(WorkItemEffects effects, OrchestrationRuntimeState runtimeState, StartNewOrchestrationOperationAction action)
internal void ProcessSendStartMessage(WorkItemEffects effects, OrchestrationRuntimeState runtimeState, StartNewOrchestrationOperationAction action)
{
OrchestrationInstance destination = new OrchestrationInstance()
{
Expand Down Expand Up @@ -883,35 +883,5 @@ await this.dispatchPipeline.RunAsync(dispatchContext, async _ =>

return result;
}

/// <summary>
/// Test only.
/// </summary>
internal HistoryEvent TestScheduleSendEvent()
{
// Initialize arguments to pass to ProcessSendStartMessage().
var effects = new WorkItemEffects();
effects.taskIdCounter = 0;
effects.InstanceMessages = new List<TaskMessage>();

var mockEntityStartEvent = new ExecutionStartedEvent(-1, null)
{
OrchestrationInstance = new OrchestrationInstance(),
Name = "testentity",
Version = "1.0",
};
var runtimeState = new OrchestrationRuntimeState();
runtimeState.AddEvent(mockEntityStartEvent);
var action = new StartNewOrchestrationOperationAction()
{
InstanceId = "testsample",
Name = "test",
Version = "1.0",
Input = null,
};

this.ProcessSendStartMessage(effects, runtimeState,action);
return effects.InstanceMessages[0].Event;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="MSTest.TestAdapter" Version="1.3.2" />
<PackageReference Include="MSTest.TestFramework" Version="1.3.2" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.5" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" />
</ItemGroup>

<ItemGroup>
Expand Down