Skip to content

Commit 756f72e

Browse files
committed
Refactored testing to add an integration test project for the functions. The intention is to start the local emulator, and call the functions to test actually hitting the Azure infrastructure from the function, using Azure DevTest Labs in the CI/CD process.
1 parent d5582ef commit 756f72e

17 files changed

+291
-30
lines changed

.github/workflows/test_azure_devtest_labs_integration.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ jobs:
5252
ls -ltAR ./${{ env.FUNCTIONS_PROJECT_NAME }}/bin/${{ env.BUILD_CONFIGURATION }}
5353
5454
- name: Run Unit Tests
55-
run: dotnet test --no-build --configuration ${{ env.BUILD_CONFIGURATION }} --output ./output --verbosity normal
55+
run: dotnet test --no-build --configuration ${{ env.BUILD_CONFIGURATION }} --filter TestCategory=UnitTest --output ./output --verbosity normal
5656

5757
# - name: Extract
5858
# run: |

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ bld/
3737
# NUNIT
3838
*.VisualState.xml
3939
TestResult.xml
40+
*.runsettings
4041

4142
# Build Results of an ATL Project
4243
[Dd]ebugPS/

Azure.DataPipelineTools.sln

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
1212
LICENSE = LICENSE
1313
EndProjectSection
1414
EndProject
15-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataPipelineTools.Tests", "DataPipelineTools.Tests\DataPipelineTools.Tests.csproj", "{A2C01394-16F9-4783-9629-2857C400D6E6}"
15+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataPipelineTools.Tests", "DataPipelineTools.Tests\DataPipelineTools.Tests.csproj", "{A2C01394-16F9-4783-9629-2857C400D6E6}"
16+
EndProject
17+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataPipelineTools.Functions.Tests", "DataPipelineTools.Functions.Tests\DataPipelineTools.Functions.Tests.csproj", "{C2448E27-7F4C-4E1E-BAF7-D5344F330073}"
18+
EndProject
19+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataPipelineTools.Tests.Common", "DataPipelineTools.Tests.Common\DataPipelineTools.Tests.Common.csproj", "{6C304777-0D1A-45A6-A5E0-5849022F319A}"
1620
EndProject
1721
Global
1822
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -32,6 +36,14 @@ Global
3236
{A2C01394-16F9-4783-9629-2857C400D6E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
3337
{A2C01394-16F9-4783-9629-2857C400D6E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
3438
{A2C01394-16F9-4783-9629-2857C400D6E6}.Release|Any CPU.Build.0 = Release|Any CPU
39+
{C2448E27-7F4C-4E1E-BAF7-D5344F330073}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
40+
{C2448E27-7F4C-4E1E-BAF7-D5344F330073}.Debug|Any CPU.Build.0 = Debug|Any CPU
41+
{C2448E27-7F4C-4E1E-BAF7-D5344F330073}.Release|Any CPU.ActiveCfg = Release|Any CPU
42+
{C2448E27-7F4C-4E1E-BAF7-D5344F330073}.Release|Any CPU.Build.0 = Release|Any CPU
43+
{6C304777-0D1A-45A6-A5E0-5849022F319A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
44+
{6C304777-0D1A-45A6-A5E0-5849022F319A}.Debug|Any CPU.Build.0 = Debug|Any CPU
45+
{6C304777-0D1A-45A6-A5E0-5849022F319A}.Release|Any CPU.ActiveCfg = Release|Any CPU
46+
{6C304777-0D1A-45A6-A5E0-5849022F319A}.Release|Any CPU.Build.0 = Release|Any CPU
3547
EndGlobalSection
3648
GlobalSection(SolutionProperties) = preSolution
3749
HideSolutionNode = FALSE
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using DataPipelineTools.Tests.Common;
2+
using Microsoft.Extensions.Logging;
3+
using NUnit.Framework;
4+
5+
namespace DataPipelineTools.Functions.Tests.DataLake.DataLakeFunctions.Integration
6+
{
7+
[TestFixture]
8+
[Category(nameof(TestType.IntegrationTest))]
9+
public class DataLakeGetItemsIntegrationTests: IntegrationTestBase
10+
{
11+
[SetUp]
12+
public void Setup()
13+
{
14+
15+
}
16+
17+
[Test]
18+
public void Test1()
19+
{
20+
Logger.LogInformation($"Running tests in { (IsRunningOnCIServer ? "CI": "local") } environment");
21+
22+
23+
Logger.LogError("Integration tests not implemented yet.");
24+
Assert.Fail();
25+
}
26+
}
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using DataPipelineTools.Tests.Common;
2+
using Microsoft.Extensions.Logging;
3+
using NUnit.Framework;
4+
5+
namespace DataPipelineTools.Functions.Tests.DataLake.DataLakeFunctions.Unit
6+
{
7+
[TestFixture]
8+
[Category(nameof(TestType.IntegrationTest))]
9+
public class DataLakeGetItemsTests: IntegrationTestBase
10+
{
11+
[SetUp]
12+
public void Setup()
13+
{
14+
15+
}
16+
17+
[Test]
18+
public void Test1()
19+
{
20+
Logger.LogInformation($"Running tests in { (IsRunningOnCIServer ? "CI": "local") } environment");
21+
22+
23+
Logger.LogError("Integration tests not implemented yet.");
24+
Assert.Fail();
25+
}
26+
}
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
6+
<IsPackable>false</IsPackable>
7+
8+
<RootNamespace>DataPipelineTools.Functions.Tests</RootNamespace>
9+
10+
<AssemblyName>DataPipelineTools.Functions.Tests</AssemblyName>
11+
12+
<PackageId>DataPipelineTools.Functions.Tests</PackageId>
13+
</PropertyGroup>
14+
15+
<ItemGroup>
16+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
17+
<PackageReference Include="NUnit" Version="3.13.1" />
18+
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
19+
<PackageReference Include="coverlet.collector" Version="3.0.2" />
20+
</ItemGroup>
21+
22+
<ItemGroup>
23+
<ProjectReference Include="..\DataPipelineTools.Functions\DataPipelineTools.Functions.csproj" />
24+
<ProjectReference Include="..\DataPipelineTools.Tests.Common\DataPipelineTools.Tests.Common.csproj" />
25+
</ItemGroup>
26+
27+
</Project>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using DataPipelineTools.Tests.Common;
5+
6+
namespace DataPipelineTools.Functions.Tests
7+
{
8+
/// <summary>
9+
/// Base class for functions tests. Exposes the
10+
/// </summary>
11+
public abstract class IntegrationTestBase : TestBase
12+
{
13+
protected bool IsRunningOnCIServer
14+
{
15+
get
16+
{
17+
// Github Actions
18+
if (Environment.GetEnvironmentVariable("CI") != null)
19+
return true;
20+
21+
//Azure Devops
22+
if (Environment.GetEnvironmentVariable("TF_BUILD") != null)
23+
return true;
24+
25+
return false;
26+
}
27+
}
28+
29+
protected void StartLocalFunctionsInstance()
30+
{
31+
throw new NotImplementedException();
32+
}
33+
34+
}
35+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<RunSettings>
3+
<!-- Parameters used by tests at run time -->
4+
<TestRunParameters>
5+
<!--
6+
**********************************************************************************************************************************************
7+
**** Integration Test Params
8+
****
9+
**** The integration tests can't use the Azure Storage emulator as is does not support hierarchical storage accounts (ie ADLS). This means
10+
**** to run the integration tests you need a storage account/container with the test file structure added to it, and a Azure Key Vault to
11+
**** hold keys for testing connectivity.
12+
****
13+
**** The following credentials are required:
14+
**** - Functions App Service Principal with access to the ADLS container and an Azure Key Vault to retrieve secrets
15+
**** - Service Principal and its secret (both directly and via Key Vault) with access to the ADLS container
16+
**** - SAS token (both directly and via Key Vault) for the ADLS container
17+
**** - Storage Account Access Key (both directly and via Key Vault) for the ADLS container
18+
****
19+
**** Note: Secrets in this file are examples from the Azure portal that have been reset since.
20+
****
21+
**********************************************************************************************************************************************
22+
-->
23+
24+
<!-- Set whether to use the local function emulator or not -->
25+
<Parameter name="UseFunctionsEmulator" value="true" />
26+
27+
<!-- The URL for the functions app. Only required if the emulator flag (UseFunctionsEmulator) above is false. -->
28+
<Parameter name="FunctionsAppUrl" value="functionsapp.azurewebsites.net" />
29+
<!--Parameter name="FunctionsUrl" value="http://localhost:7071/api/HttpTrigger" /-->
30+
31+
<!-- The key to authorise calls to the functions app. Only required if the emulator flag (UseFunctionsEmulator) above is false. -->
32+
<Parameter name="FunctionsAppKey" value="" />
33+
34+
<!-- The name of the storage account -->
35+
<Parameter name="StorageAccountName" value="testadlsaccount" />
36+
37+
<!-- The name of the storage container -->
38+
<Parameter name="StorageContainerName" value="test" />
39+
40+
<!-- The name of the key vault -->
41+
<Parameter name="KeyVaultName" value="test_key_vault" />
42+
43+
<!-- The name of the Service Principal -->
44+
<Parameter name="ServicePrincipalName" value="testSpn" />
45+
46+
<!-- The secret/password for the Service Principal -->
47+
<Parameter name="ServicePrincipalSecret" value="" />
48+
49+
<!-- The name of the Azure Key Vault secret holding the secret/password for the Service Principal -->
50+
<Parameter name="ServicePrincipalNameKeyName" value="" />
51+
52+
<!-- The SAS token. This needs to be escaped for XML when you copy it from the Azure portal (it should only be the & sign that is an issue) -->
53+
<Parameter name="SasToken" value="sp=r&amp;st=2021-07-01T13:16:28Z&amp;se=2021-07-01T21:16:28Z&amp;spr=https&amp;sv=2020-08-04&amp;sr=c&amp;sig=lUXpUl0u6kV1hrnIyQtIztOWIGfvmO56Nred4qP5dK8%3D" />
54+
55+
<!-- The name of the Azure Key Vault secret holding the SAS token -->
56+
<Parameter name="SasTokenKeyName" value="testSasToken" />
57+
58+
<!-- The Storage Account Access Key -->
59+
<Parameter name="AccessKey" value="nc8LtiyiKbeJawBW1pAJtOi4p6Id6rUqx1LqiY6zUZAplFEu9cuuT9YRlv+McTTqZJKI6RRhJDNTdPJykKk5wA==" />
60+
61+
<!-- The name of the Azure Key Vault secret holding the Storage Account Access Key -->
62+
<Parameter name="AccessKeyKeyName" value="testAccessKey" />
63+
64+
</TestRunParameters>
65+
</RunSettings>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netcoreapp3.1</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.13" />
9+
<PackageReference Include="Moq" Version="4.16.1" />
10+
<PackageReference Include="NUnit" Version="3.12.0" />
11+
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1">
12+
<PrivateAssets>all</PrivateAssets>
13+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
14+
</PackageReference>
15+
</ItemGroup>
16+
17+
<ItemGroup>
18+
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
19+
<_Parameter1>DataPipelineTools.Tests</_Parameter1>
20+
</AssemblyAttribute>
21+
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
22+
<_Parameter1>DataPipelineTools.Functions.Tests</_Parameter1>
23+
</AssemblyAttribute>
24+
</ItemGroup>
25+
26+
</Project>

DataPipelineTools.Tests/MockILoggerExtensions.cs renamed to DataPipelineTools.Tests.Common/MockILoggerExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using Microsoft.Extensions.Logging;
33
using Moq;
44

5-
namespace DataPipelineTools.Tests
5+
namespace DataPipelineTools.Tests.Common
66
{
77
// Based once code / ideas here: https://adamstorr.azurewebsites.net/blog/mocking-ilogger-with-moq
88
public static class MockILoggerExtensions

0 commit comments

Comments
 (0)