Skip to content

Commit

Permalink
feat: introduce TestFramework class to evaluate child executePipeline…
Browse files Browse the repository at this point in the history
…Activities
  • Loading branch information
arjendev committed Oct 4, 2023
1 parent b80a686 commit ba190ba
Show file tree
Hide file tree
Showing 21 changed files with 400 additions and 78 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,13 @@ The samples seen below is the _only_ code that you need to write! The framework
2. Evaluate Pipelines and test the flow of activities given a specific input

```csharp
var pipeline = PipelineFactory.ParseFromFile(pipelineFileName);
var testFramework = new TestFramework(dataFactoryFolderPath: "BatchJob");
var pipeline = testFramework.Repository.GetPipelineByName("batch_job");
Assert.Equal("example-pipeline", pipeline.Name);
Assert.Equal(6, pipeline.Activities.Count);

// Runs the pipeline with the provided parameters
var activities = pipeline.EvaluateWithActivityEnumerator(new List<RunParameter>
var activities = testFramework.Evaluate(pipeline, new List<RunParameter>
{
new(ParameterType.Parameter, "JobId", "123"),
new(ParameterType.Parameter, "ContainerName", "test-container"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@
</ItemGroup>

<ItemGroup>
<None Update="BatchJob\pipeline.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<ProjectReference Include="..\AzureDataFactory.TestingFramework\AzureDataFactory.TestingFramework.csproj" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\AzureDataFactory.TestingFramework\AzureDataFactory.TestingFramework.csproj" />
<None Update="BatchJob\pipeline\batch_job.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,20 @@
using AzureDataFactory.TestingFramework.Exceptions;
using AzureDataFactory.TestingFramework.Models;
using AzureDataFactory.TestingFramework.Models.Base;
using AzureDataFactory.TestingFramework.Models.Pipelines;

namespace AzureDataFactory.TestingFramework.Example.BatchJob;

public class BatchJobFunctionalTests
{

[Fact]
public void BatchJobTest()
{
var pipeline = PipelineFactory.ParseFromFile("BatchJob/pipeline.json");
var testFramework = new TestFramework(dataFactoryFolderPath: "BatchJob");
var pipeline = testFramework.Repository.GetPipelineByName("batch_job");
Assert.Equal("batch_job", pipeline.Name);
Assert.Equal(11, pipeline.Activities.Count);

var activities = pipeline.EvaluateWithActivityEnumerator(new List<IRunParameter>
var activities = testFramework.Evaluate(pipeline, new List<IRunParameter>
{
new RunParameter<string>(ParameterType.Parameter, "BatchPoolId", "batch-pool-id"),
new RunParameter<string>(ParameterType.Parameter, "WorkloadApplicationPackageName", "test-application"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class BatchJobUnitTests

public BatchJobUnitTests()
{
_pipeline = PipelineFactory.ParseFromFile("BatchJob/pipeline.json");
_pipeline = PipelineFactory.ParseFromFile("BatchJob/pipeline/batch_job.json");
_state = new PipelineRunState();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@
<None Update="Functional\CopyActivities\copyactivity-example.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Functional\Pipelines\Child\pipeline\child.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Functional\Pipelines\Child\pipeline\main.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using AzureDataFactory.TestingFramework.Exceptions;
using AzureDataFactory.TestingFramework.Models;
using AzureDataFactory.TestingFramework.Models.Base;
using AzureDataFactory.TestingFramework.Models.Pipelines;

namespace AzureDataFactory.TestingFramework.Tests.Functional.Pipelines.Child;

public class ChildPipelineTests
{
[Fact]
public void WhenExecutePipelineActivityIsCalled_ThenChildPipelineActivitiesAreExecuted()
{
// Arrange
var testFramework = new TestFramework(dataFactoryFolderPath: "Functional/Pipelines/Child", shouldEvaluateChildPipelines: true);
var pipeline = testFramework.Repository.GetPipelineByName("main");

// Act
var activities = testFramework.Evaluate(pipeline, new List<IRunParameter>()
{
new RunParameter<string>(ParameterType.Parameter, "Url", "https://example.com"),
new RunParameter<string>(ParameterType.Parameter, "Body", "{ \"key\": \"value\" }")
});

// Assert
var childWebActivity = activities.GetNext<WebActivity>();
Assert.Equal("API Call", childWebActivity.Name);
Assert.Equal("https://example.com", childWebActivity.Uri);
Assert.Equal("{ \"key\": \"value\" }", childWebActivity.Body);
}

[Fact]
public void WhenExecutePipelineActivityIsCalledAndIsConfiguredToEvaluateChildPipelinesAndChildPipelineIsNotKnown_ThenExceptionShouldBeThrown()
{
// Arrange
var testFramework = new TestFramework(shouldEvaluateChildPipelines: true);
var pipeline = PipelineFactory.ParseFromFile("Functional/Pipelines/Child/pipeline/main.json");

// Act
var exception = Assert.Throws<PipelineNotFoundException>(() => testFramework.EvaluateAll(pipeline, new List<IRunParameter>()
{
new RunParameter<string>(ParameterType.Parameter, "Url", "https://example.com"),
new RunParameter<string>(ParameterType.Parameter, "Body", "{ \"key\": \"value\" }")
}));

// Assert
Assert.Equal("Pipeline with name 'child' was not found in the repository. Make sure to load the repository before evaluating pipelines.", exception.Message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"name": "child",
"properties": {
"activities": [
{
"name": "API Call",
"type": "WebActivity",
"dependsOn": [],
"policy": {
"timeout": "0.12:00:00",
"retry": 0,
"retryIntervalInSeconds": 30,
"secureOutput": false,
"secureInput": false
},
"userProperties": [],
"typeProperties": {
"url": {
"value": "@pipeline().parameters.Url",
"type": "Expression"
},
"method": "POST",
"body": {
"value": "@pipeline().parameters.Body",
"type": "Expression"
}
}
}
],
"parameters": {
"Url": {
"type": "string"
},
"Body": {
"type": "string"
}
},
"folder": {
"name": "tests"
},
"annotations": []
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"name": "main",
"properties": {
"activities": [
{
"name": "Execute Child pipeline",
"type": "ExecutePipeline",
"dependsOn": [],
"userProperties": [],
"typeProperties": {
"pipeline": {
"referenceName": "child",
"type": "PipelineReference"
},
"waitOnCompletion": true,
"parameters": {
"Url": {
"value": "@pipeline().parameters.Url",
"type": "Expression"
},
"Body": {
"value": "@pipeline().parameters.Body",
"type": "Expression"
}
}
}
}
],
"parameters": {
"Url": {
"type": "string"
},
"Body": {
"type": "string"
}
},
"folder": {
"name": "tests"
},
"annotations": []
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public void WhenEvaluateChildActivities_ThenShouldReturnTheActivityWithItemExpre

// Act
forEachActivity.Evaluate(state);
var childActivities = forEachActivity.EvaluateChildActivities(state);
var childActivities = forEachActivity.EvaluateChildActivities(state, new TestFramework());

// Assert
using var enumarator = childActivities.GetEnumerator();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@

namespace AzureDataFactory.TestingFramework.Tests.Models.Activities.Base;

public class ActivitiesEvaluatorTests
public class TestFrameworkTests
{
private readonly List<PipelineActivity> _activities;
private readonly WebActivity _webActivity;
private readonly SetVariableActivity _setVariableActivity;
private readonly TestFramework _testFramework;

public ActivitiesEvaluatorTests()
public TestFrameworkTests()
{
_testFramework = new TestFramework();
_activities = new List<PipelineActivity>();
_webActivity = new WebActivity("webActivity", WebActivityMethod.Get, "https://www.example.com")
{
Expand All @@ -41,7 +43,7 @@ public void EvaluateWithoutIterationActivities_ShouldEvaluateAccordingToDependen
// Act
var state = new PipelineRunState();
state.Variables.Add(new PipelineRunVariable<string>("variable1", string.Empty));
var evaluatedActivities = ActivitiesEvaluator.Evaluate(_activities, state).ToList();
var evaluatedActivities = _testFramework.EvaluateActivities(_activities, state).ToList();

// Assert
Assert.NotNull(evaluatedActivities);
Expand All @@ -57,7 +59,7 @@ public void EvaluateWithCircularDependencies_ShouldThrowActivitiesEvaluatorInval
_setVariableActivity.DependsOn.Add(new PipelineActivityDependency("webActivity", new[] { DependencyCondition.Succeeded }));

// Assert
Assert.Throws<ActivitiesEvaluatorInvalidDependencyException>(() => ActivitiesEvaluator.Evaluate(_activities, new PipelineRunState()).ToList());
Assert.Throws<ActivitiesEvaluatorInvalidDependencyException>(() => _testFramework.EvaluateActivities(_activities, new PipelineRunState()).ToList());
}

[Fact]
Expand All @@ -73,7 +75,7 @@ public void EvaluateWithForeachActivities_ShouldEvaluateAccordingToDependencies(
_webActivity.Uri = new DataFactoryElement<string>("@concat('https://www.example.com/', item())", DataFactoryElementKind.Expression);

// Act
var evaluatedActivities = ActivitiesEvaluator.Evaluate(new List<PipelineActivity> { foreachActivity }, state);
var evaluatedActivities = _testFramework.EvaluateActivities(new List<PipelineActivity> { foreachActivity }, state);

// Assert
using var enumerator = evaluatedActivities.GetEnumerator();
Expand Down Expand Up @@ -106,7 +108,7 @@ public void EvaluateWithUntilActivities_ShouldEvaluateAccordingToDependencies()
_activities);

// Act
var evaluatedActivities = ActivitiesEvaluator.Evaluate(new List<PipelineActivity> { untilActivity }, state);
var evaluatedActivities = _testFramework.EvaluateActivities(new List<PipelineActivity> { untilActivity }, state);

// Assert
using var enumerator = evaluatedActivities.GetEnumerator();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,14 @@
<PackageReference Include="Azure.Core.Expressions.DataFactory" Version="1.0.0-beta.4" />
<PackageReference Include="Azure.ResourceManager" Version="1.7.0" />
<PackageReference Include="Microsoft.Azure.AutoRest.CSharp" Version="3.0.0-beta.20230804.1" PrivateAssets="All" />

</ItemGroup>

<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>AzureDataFactory.TestingFramework.Tests</_Parameter1>
</AssemblyAttribute>
</ItemGroup>

<PropertyGroup>
<PackageId>AzureDataFactory.TestingFramework</PackageId>
<PackageVersion>0.1.6-alpha</PackageVersion>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

namespace AzureDataFactory.TestingFramework.Exceptions;

public class PipelineNotFoundException : Exception
{
public PipelineNotFoundException(string name) : base($"Pipeline with name '{name}' was not found in the repository. Make sure to load the repository before evaluating pipelines.")
{
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,20 @@ protected virtual List<PipelineActivity> GetNextActivities()
return new List<PipelineActivity>();
}

public virtual IEnumerable<PipelineActivity> EvaluateChildActivities(PipelineRunState state)
internal virtual IEnumerable<PipelineActivity> EvaluateChildActivities(PipelineRunState state, TestFramework testFramework)
{
var scopedState = state.CreateIterationScope(null);
var activities = GetNextActivities();
foreach (var activity in ActivitiesEvaluator.Evaluate(activities, scopedState))
foreach (var activity in testFramework.EvaluateActivities(activities, scopedState))
{
yield return activity;
}

state.AddScopedActivityResultsFromScopedState(scopedState);
}

internal virtual IEnumerable<PipelineActivity> EvaluateChildActivities(PipelineRunState state)
{
return EvaluateChildActivities(state, new TestFramework());
}
}
Loading

0 comments on commit ba190ba

Please sign in to comment.