Skip to content

Commit

Permalink
EES-5492 - broke orchestrations into their own simplified files and m…
Browse files Browse the repository at this point in the history
…ade static, to avoid issues whereby exceptions thrown during the construction of Function classes caused the ImportMetadata stage to lock up
  • Loading branch information
duncan-at-hiveit committed Oct 15, 2024
1 parent 0a93f98 commit b7e1058
Show file tree
Hide file tree
Showing 20 changed files with 447 additions and 406 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ public async Task Success()
StartOrchestrationOptions? startOrchestrationOptions = null;
durableTaskClientMock.Setup(client =>
client.ScheduleNewOrchestrationInstanceAsync(
nameof(ProcessCompletionOfNextDataSetVersionFunction
.ProcessCompletionOfNextDataSetVersion),
nameof(ProcessCompletionOfNextDataSetVersionOrchestration
.ProcessCompletionOfNextDataSetVersionImport),
It.IsAny<ProcessDataSetVersionContext>(),
It.IsAny<StartOrchestrationOptions>(),
It.IsAny<CancellationToken>()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ await AddTestData<ContentDbContext>(context =>
StartOrchestrationOptions? startOrchestrationOptions = null;
durableTaskClientMock.Setup(client =>
client.ScheduleNewOrchestrationInstanceAsync(
nameof(ProcessInitialDataSetVersionFunction.ProcessInitialDataSetVersion),
nameof(ProcessInitialDataSetVersionOrchestration.ProcessInitialDataSetVersion),
It.IsAny<ProcessDataSetVersionContext>(),
It.IsAny<StartOrchestrationOptions>(),
It.IsAny<CancellationToken>()))
Expand Down Expand Up @@ -163,8 +163,8 @@ public async Task ReleaseFileIdHasDataSetVersion_ReturnsValidationProblem()
DataSet dataSet = DataFixture.DefaultDataSet();

DataSetVersion dataSetVersion = DataFixture.DefaultDataSetVersion()
.WithRelease(DataFixture.DefaultDataSetVersionRelease()
.WithReleaseFileId(releaseFile.Id))
.WithRelease(DataFixture.DefaultDataSetVersionRelease()
.WithReleaseFileId(releaseFile.Id))
.WithDataSet(dataSet);

await AddTestData<ContentDbContext>(context =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ public async Task Success()
StartOrchestrationOptions? startOrchestrationOptions = null;
durableTaskClientMock.Setup(client =>
client.ScheduleNewOrchestrationInstanceAsync(
nameof(ProcessNextDataSetVersionMappingsFunction.ProcessNextDataSetVersionMappings),
nameof(ProcessNextDataSetVersionMappingsFunctionOrchestration
.ProcessNextDataSetVersionMappings),
It.IsAny<ProcessDataSetVersionContext>(),
It.IsAny<StartOrchestrationOptions>(),
It.IsAny<CancellationToken>()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,9 @@
using GovUk.Education.ExploreEducationStatistics.Public.Data.Model.Parquet.Tables;
using GovUk.Education.ExploreEducationStatistics.Public.Data.Model.Tests.Fixtures;
using GovUk.Education.ExploreEducationStatistics.Public.Data.Processor.Functions;
using GovUk.Education.ExploreEducationStatistics.Public.Data.Processor.Model;
using GovUk.Education.ExploreEducationStatistics.Public.Data.Services.Interfaces;
using GovUk.Education.ExploreEducationStatistics.Public.Data.Utils;
using Microsoft.DurableTask;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging.Abstractions;
using Moq;
using static GovUk.Education.ExploreEducationStatistics.Common.Tests.Utils.MockUtils;
using FilterMeta = GovUk.Education.ExploreEducationStatistics.Public.Data.Model.FilterMeta;

namespace GovUk.Education.ExploreEducationStatistics.Public.Data.Processor.Tests.Functions;
Expand All @@ -37,93 +32,6 @@ public abstract class ProcessCompletionOfNextDataSetVersionImportFunctionTests(
TimePeriodsTable.ParquetFile
];

public class ProcessCompletionOfNextDataSetVersionImportTests(
ProcessorFunctionsIntegrationTestFixture fixture)
: ProcessCompletionOfNextDataSetVersionImportFunctionTests(fixture)
{
[Fact]
public async Task Success()
{
var mockOrchestrationContext = DefaultMockOrchestrationContext();
var activitySequence = new MockSequence();

string[] expectedActivitySequence =
[
ActivityNames.UpdateFileStoragePath,
ActivityNames.ImportMetadata,
ActivityNames.CreateChanges,
ActivityNames.ImportData,
ActivityNames.WriteDataFiles,
ActivityNames.CompleteNextDataSetVersionImportProcessing
];

foreach (var activityName in expectedActivitySequence)
{
mockOrchestrationContext
.InSequence(activitySequence)
.Setup(context => context.CallActivityAsync(activityName,
mockOrchestrationContext.Object.InstanceId,
null))
.Returns(Task.CompletedTask);
}

await ProcessCompletionOfNextDataSetVersionImport(mockOrchestrationContext.Object);

VerifyAllMocks(mockOrchestrationContext);
}

[Fact]
public async Task ActivityFunctionThrowsException_CallsHandleFailureActivity()
{
var mockOrchestrationContext = DefaultMockOrchestrationContext();

var activitySequence = new MockSequence();

mockOrchestrationContext
.InSequence(activitySequence)
.Setup(context =>
context.CallActivityAsync(ActivityNames.UpdateFileStoragePath,
mockOrchestrationContext.Object.InstanceId,
null))
.Throws<Exception>();

mockOrchestrationContext
.InSequence(activitySequence)
.Setup(context =>
context.CallActivityAsync(ActivityNames.HandleProcessingFailure,
mockOrchestrationContext.Object.InstanceId,
null))
.Returns(Task.CompletedTask);

await ProcessCompletionOfNextDataSetVersionImport(mockOrchestrationContext.Object);

VerifyAllMocks(mockOrchestrationContext);
}

private async Task ProcessCompletionOfNextDataSetVersionImport(TaskOrchestrationContext orchestrationContext)
{
var function = GetRequiredService<ProcessCompletionOfNextDataSetVersionFunction>();
await function.ProcessCompletionOfNextDataSetVersion(
orchestrationContext,
new ProcessDataSetVersionContext { DataSetVersionId = Guid.NewGuid() });
}

private static Mock<TaskOrchestrationContext> DefaultMockOrchestrationContext(Guid? instanceId = null)
{
var mock = new Mock<TaskOrchestrationContext>(MockBehavior.Strict);

mock.Setup(context =>
context.CreateReplaySafeLogger(
nameof(ProcessCompletionOfNextDataSetVersionFunction.ProcessCompletionOfNextDataSetVersion)))
.Returns(NullLogger.Instance);

mock.SetupGet(context => context.InstanceId)
.Returns(instanceId?.ToString() ?? Guid.NewGuid().ToString());

return mock;
}
}

public abstract class CreateChangesTests(
ProcessorFunctionsIntegrationTestFixture fixture)
: ProcessCompletionOfNextDataSetVersionImportFunctionTests(fixture)
Expand All @@ -132,7 +40,7 @@ public abstract class CreateChangesTests(

protected async Task CreateChanges(Guid instanceId)
{
var function = GetRequiredService<ProcessCompletionOfNextDataSetVersionFunction>();
var function = GetRequiredService<ProcessCompletionOfNextDataSetVersionFunctions>();
await function.CreateChanges(instanceId, CancellationToken.None);
}
}
Expand Down Expand Up @@ -3132,7 +3040,7 @@ public async Task Success_PathNotUpdated()

private async Task UpdateFileStoragePath(Guid instanceId)
{
var function = GetRequiredService<ProcessCompletionOfNextDataSetVersionFunction>();
var function = GetRequiredService<ProcessCompletionOfNextDataSetVersionFunctions>();
await function.UpdateFileStoragePath(instanceId, CancellationToken.None);
}
}
Expand Down Expand Up @@ -3190,7 +3098,7 @@ public async Task DuckDbFileIsDeleted()

private async Task CompleteProcessing(Guid instanceId)
{
var function = GetRequiredService<ProcessCompletionOfNextDataSetVersionFunction>();
var function = GetRequiredService<ProcessCompletionOfNextDataSetVersionFunctions>();
await function.CompleteNextDataSetVersionImportProcessing(instanceId, CancellationToken.None);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using GovUk.Education.ExploreEducationStatistics.Public.Data.Processor.Functions;
using GovUk.Education.ExploreEducationStatistics.Public.Data.Processor.Model;
using GovUk.Education.ExploreEducationStatistics.Public.Data.Processor.Tests.Extensions;
using Microsoft.DurableTask;
using Microsoft.DurableTask.Entities;
using Microsoft.Extensions.Logging.Abstractions;
using Moq;
using static GovUk.Education.ExploreEducationStatistics.Common.Tests.Utils.MockUtils;

namespace GovUk.Education.ExploreEducationStatistics.Public.Data.Processor.Tests.Functions;

public abstract class ProcessCompletionOfNextDataSetVersionImportOrchestrationTests
{
public class ProcessCompletionOfNextDataSetVersionImportTests
{
[Fact]
public async Task Success()
{
var mockOrchestrationContext = DefaultMockOrchestrationContext();
var activitySequence = new MockSequence();

// Expect an entity lock to be acquired for calling the ImportMetadata activity
var mockEntityFeature = new Mock<TaskOrchestrationEntityFeature>(MockBehavior.Strict);
mockEntityFeature.SetupLockForActivity(ActivityNames.ImportMetadata);
mockOrchestrationContext.SetupGet(context => context.Entities)
.Returns(mockEntityFeature.Object);

string[] expectedActivitySequence =
[
ActivityNames.UpdateFileStoragePath,
ActivityNames.ImportMetadata,
ActivityNames.CreateChanges,
ActivityNames.ImportData,
ActivityNames.WriteDataFiles,
ActivityNames.CompleteNextDataSetVersionImportProcessing
];

foreach (var activityName in expectedActivitySequence)
{
mockOrchestrationContext
.InSequence(activitySequence)
.Setup(context => context.CallActivityAsync(activityName,
mockOrchestrationContext.Object.InstanceId,
null))
.Returns(Task.CompletedTask);
}

await ProcessCompletionOfNextDataSetVersionImport(mockOrchestrationContext.Object);

VerifyAllMocks(mockOrchestrationContext, mockEntityFeature);
}

[Fact]
public async Task ActivityFunctionThrowsException_CallsHandleFailureActivity()
{
var mockOrchestrationContext = DefaultMockOrchestrationContext();

var activitySequence = new MockSequence();

mockOrchestrationContext
.InSequence(activitySequence)
.Setup(context =>
context.CallActivityAsync(ActivityNames.UpdateFileStoragePath,
mockOrchestrationContext.Object.InstanceId,
null))
.Throws<Exception>();

mockOrchestrationContext
.InSequence(activitySequence)
.Setup(context =>
context.CallActivityAsync(ActivityNames.HandleProcessingFailure,
mockOrchestrationContext.Object.InstanceId,
null))
.Returns(Task.CompletedTask);

await ProcessCompletionOfNextDataSetVersionImport(mockOrchestrationContext.Object);

VerifyAllMocks(mockOrchestrationContext);
}

private static async Task ProcessCompletionOfNextDataSetVersionImport(
TaskOrchestrationContext orchestrationContext)
{
await ProcessCompletionOfNextDataSetVersionOrchestration.ProcessCompletionOfNextDataSetVersionImport(
orchestrationContext,
new ProcessDataSetVersionContext { DataSetVersionId = Guid.NewGuid() });
}

private static Mock<TaskOrchestrationContext> DefaultMockOrchestrationContext(Guid? instanceId = null)
{
var mock = new Mock<TaskOrchestrationContext>(MockBehavior.Strict);

mock.Setup(context =>
context.CreateReplaySafeLogger(
nameof(ProcessCompletionOfNextDataSetVersionOrchestration
.ProcessCompletionOfNextDataSetVersionImport)))
.Returns(NullLogger.Instance);

mock.SetupGet(context => context.InstanceId)
.Returns(instanceId?.ToString() ?? Guid.NewGuid().ToString());

return mock;
}
}
}
Loading

0 comments on commit b7e1058

Please sign in to comment.