From 1f806971bb9156803e9b4fb3c75bf6a417951399 Mon Sep 17 00:00:00 2001 From: David Justo Date: Tue, 7 May 2024 16:26:07 -0700 Subject: [PATCH] entity tags patch --- .../TestTaskEntityDispatcher.cs | 79 +++++++++++++++++-- .../Entities/EntityTestHelper.cs | 55 ------------- src/DurableTask.Core/TaskEntityDispatcher.cs | 34 +------- .../DurableTask.SqlServer.Tests.csproj | 2 +- 4 files changed, 74 insertions(+), 96 deletions(-) delete mode 100644 src/DurableTask.Core/Entities/EntityTestHelper.cs diff --git a/Test/DurableTask.Core.Tests/TestTaskEntityDispatcher.cs b/Test/DurableTask.Core.Tests/TestTaskEntityDispatcher.cs index 13c886baa..42cc0b2c9 100644 --- a/Test/DurableTask.Core.Tests/TestTaskEntityDispatcher.cs +++ b/Test/DurableTask.Core.Tests/TestTaskEntityDispatcher.cs @@ -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 { + /// + /// Utiliy function to create a TaskEntityDispatcher instance. To be expanded upon as per testing needs. + /// + /// + 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(); + var entityMiddleware = new DispatchMiddlewarePipeline(); + var logger = new LogHelper(loggerFactory?.CreateLogger("DurableTask.Core")); + + TaskEntityDispatcher dispatcher = new TaskEntityDispatcher( + service, entityManager, entityMiddleware, logger, ErrorPropagationMode.UseFailureDetails); + return dispatcher; + } + + /// + /// 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. + /// [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(); + + // 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); } } } diff --git a/src/DurableTask.Core/Entities/EntityTestHelper.cs b/src/DurableTask.Core/Entities/EntityTestHelper.cs deleted file mode 100644 index a717ae20f..000000000 --- a/src/DurableTask.Core/Entities/EntityTestHelper.cs +++ /dev/null @@ -1,55 +0,0 @@ -using DurableTask.Core.History; -using DurableTask.Core.Logging; -using DurableTask.Core.Middleware; -using Microsoft.Extensions.Logging; - -namespace DurableTask.Core.Entities -{ - /// - /// Class to help test TaskEntityDispatcher. - /// - public class EntityTestHelper - { - IOrchestrationService orchestrationService; - TaskEntityDispatcher dispatcher; - - /// - /// Constructor for EntityTestHelper - /// - /// The for initialize TaskEntityDispatcher instance. - public EntityTestHelper(IOrchestrationService service) - { - this.orchestrationService = service; - this.dispatcher = CreateTestEntityDispatcherInstance(); - } - - /// - /// Create an instance of the TaskEntityDispatcher class for testing. - /// - /// Instance created for testing. - public TaskEntityDispatcher CreateTestEntityDispatcherInstance() - { - ILoggerFactory loggerFactory = null; - var entityManager = new NameVersionObjectManager(); - var entityMiddleware = new DispatchMiddlewarePipeline(); - var logger = new LogHelper(loggerFactory?.CreateLogger("DurableTask.Core")); - - return new TaskEntityDispatcher - ( - this.orchestrationService, - entityManager, - entityMiddleware, - logger, - ErrorPropagationMode.SerializeExceptions); - } - - /// - /// Method to test orchestration settings when entities schedule it. - /// - /// HistoryEvent contains the scheduled message. - public HistoryEvent TestScheduleOrchestrationTags() - { - return this.dispatcher.TestScheduleSendEvent(); - } - } -} diff --git a/src/DurableTask.Core/TaskEntityDispatcher.cs b/src/DurableTask.Core/TaskEntityDispatcher.cs index f04843566..a7ecb5267 100644 --- a/src/DurableTask.Core/TaskEntityDispatcher.cs +++ b/src/DurableTask.Core/TaskEntityDispatcher.cs @@ -182,7 +182,7 @@ async Task OnProcessWorkItemSessionAsync(TaskOrchestrationWorkItem workItem) } } - class WorkItemEffects + internal class WorkItemEffects { public List ActivityMessages; public List TimerMessages; @@ -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() { @@ -883,35 +883,5 @@ await this.dispatchPipeline.RunAsync(dispatchContext, async _ => return result; } - - /// - /// Test only. - /// - internal HistoryEvent TestScheduleSendEvent() - { - // Initialize arguments to pass to ProcessSendStartMessage(). - var effects = new WorkItemEffects(); - effects.taskIdCounter = 0; - effects.InstanceMessages = new List(); - - 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; - } } } diff --git a/test/DurableTask.SqlServer.Tests/DurableTask.SqlServer.Tests.csproj b/test/DurableTask.SqlServer.Tests/DurableTask.SqlServer.Tests.csproj index cf578db09..e698b6266 100644 --- a/test/DurableTask.SqlServer.Tests/DurableTask.SqlServer.Tests.csproj +++ b/test/DurableTask.SqlServer.Tests/DurableTask.SqlServer.Tests.csproj @@ -23,7 +23,7 @@ - +