Skip to content

Commit

Permalink
Add E2E tests for blob SDK type bindings (#1360)
Browse files Browse the repository at this point in the history
  • Loading branch information
liliankasem authored Feb 22, 2023
1 parent edc8015 commit f05b9df
Show file tree
Hide file tree
Showing 10 changed files with 557 additions and 132 deletions.
134 changes: 134 additions & 0 deletions test/E2ETests/E2EApps/E2EApp/Blob/BlobInputBindingFunctions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Azure.Storage.Blobs;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;

namespace Microsoft.Azure.Functions.Worker.E2EApp.Blob
{
public class BlobInputBindingFunctions
{
private readonly ILogger<BlobInputBindingFunctions> _logger;

public BlobInputBindingFunctions(ILogger<BlobInputBindingFunctions> logger)
{
_logger = logger;
}

[Function(nameof(BlobInputClientTest))]
public async Task<HttpResponseData> BlobInputClientTest(
[HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
[BlobInput("test-input-dotnet-isolated/testFile.txt")] BlobClient client)
{
var downloadResult = await client.DownloadContentAsync();
var response = req.CreateResponse(HttpStatusCode.OK);
await response.Body.WriteAsync(downloadResult.Value.Content);
return response;
}

[Function(nameof(BlobInputContainerClientTest))]
public async Task<HttpResponseData> BlobInputContainerClientTest(
[HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
[BlobInput("test-input-dotnet-isolated/testFile.txt")] BlobContainerClient client)
{
var blobClient = client.GetBlobClient("testFile.txt");
var downloadResult = await blobClient.DownloadContentAsync();
var response = req.CreateResponse(HttpStatusCode.OK);
await response.Body.WriteAsync(downloadResult.Value.Content);
return response;
}

[Function(nameof(BlobInputStreamTest))]
public async Task<HttpResponseData> BlobInputStreamTest(
[HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
[BlobInput("test-input-dotnet-isolated/testFile.txt")] Stream stream)
{
using var blobStreamReader = new StreamReader(stream);
var response = req.CreateResponse(HttpStatusCode.OK);
await response.WriteStringAsync(blobStreamReader.ReadToEnd());
return response;
}

[Function(nameof(BlobInputByteTest))]
public async Task<HttpResponseData> BlobInputByteTest(
[HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
[BlobInput("test-input-dotnet-isolated/testFile.txt")] Byte[] data)
{
var response = req.CreateResponse(HttpStatusCode.OK);
await response.WriteStringAsync(Encoding.Default.GetString(data));
return response;
}

[Function(nameof(BlobInputStringTest))]
public async Task<HttpResponseData> BlobInputStringTest(
[HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
[BlobInput("test-input-dotnet-isolated/testFile.txt")] string data)
{
var response = req.CreateResponse(HttpStatusCode.OK);
await response.WriteStringAsync(data);
return response;
}

[Function(nameof(BlobInputPocoTest))]
public async Task<HttpResponseData> BlobInputPocoTest(
[HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
[BlobInput("test-input-dotnet-isolated/testFile.txt")] Book data)
{
var response = req.CreateResponse(HttpStatusCode.OK);
await response.WriteStringAsync(data.Name);
return response;
}

[Function(nameof(BlobInputCollectionTest))]
public async Task<HttpResponseData> BlobInputCollectionTest(
[HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
[BlobInput("test-input-dotnet-isolated", IsBatched = true)] IEnumerable<BlobClient> blobs)
{
List<string> blobList = new();

foreach (BlobClient blob in blobs)
{
_logger.LogInformation("Blob name: {blobName}, Container name: {containerName}", blob.Name, blob.BlobContainerName);
blobList.Add(blob.Name);
}

var response = req.CreateResponse(HttpStatusCode.OK);
await response.WriteStringAsync(blobList.ToString());
return response;
}

[Function(nameof(BlobInputStringArrayTest))]
public async Task<HttpResponseData> BlobInputStringArrayTest(
[HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
[BlobInput("test-input-dotnet-isolated", IsBatched = true)] string[] blobContent)
{
var response = req.CreateResponse(HttpStatusCode.OK);
await response.WriteStringAsync(blobContent.ToString());
return response;
}

[Function(nameof(BlobInputPocoArrayTest))]
public async Task<HttpResponseData> BlobInputPocoArrayTest(
[HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req,
[BlobInput("test-input-dotnet-isolated", IsBatched = true)] Book[] books)
{
List<string> bookNames = new();

foreach (var item in books)
{
bookNames.Add(item.Name);
}

var response = req.CreateResponse(HttpStatusCode.OK);
await response.WriteStringAsync(bookNames.ToString());
return response;
}
}
}
57 changes: 0 additions & 57 deletions test/E2ETests/E2EApps/E2EApp/Blob/BlobTestFunctions.cs

This file was deleted.

90 changes: 90 additions & 0 deletions test/E2ETests/E2EApps/E2EApp/Blob/BlobTriggerBindingFunctions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.IO;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Azure.Storage.Blobs;
using Microsoft.Extensions.Logging;

namespace Microsoft.Azure.Functions.Worker.E2EApp.Blob
{
public class BlobTriggerBindingFunctions
{
private readonly ILogger<BlobTriggerBindingFunctions> _logger;

public BlobTriggerBindingFunctions(ILogger<BlobTriggerBindingFunctions> logger)
{
_logger = logger;
}

[Function(nameof(BlobTriggerToBlobTest))]
[BlobOutput("test-output-dotnet-isolated/{name}")]
public byte[] BlobTriggerToBlobTest(
[BlobTrigger("test-trigger-dotnet-isolated/{name}")] byte[] triggerBlob, string name,
[BlobInput("test-input-dotnet-isolated/{name}")] byte[] inputBlob,
FunctionContext context)
{
_logger.LogInformation("Trigger:\n Name: " + name + "\n Size: " + triggerBlob.Length + " Bytes");
_logger.LogInformation("Input:\n Name: " + name + "\n Size: " + inputBlob.Length + " Bytes");
return inputBlob;
}

[Function(nameof(BlobTriggerPocoTest))]
[BlobOutput("test-output-poco-dotnet-isolated/{name}")]
public TestBlobData BlobTriggerPocoTest(
[BlobTrigger("test-trigger-poco-dotnet-isolated/{name}")] TestBlobData triggerBlob, string name,
FunctionContext context)
{
_logger.LogInformation(".NET Blob trigger function processed a blob.\n Name: " + name + "\n Content: " + triggerBlob.BlobText);
return triggerBlob;
}

[Function(nameof(BlobTriggerStringTest))]
[BlobOutput("test-output-string-dotnet-isolated/{name}")]
public string BlobTriggerStringTest(
[BlobTrigger("test-trigger-string-dotnet-isolated/{name}")] string triggerBlobText, string name,
FunctionContext context)
{
_logger.LogInformation(".NET Blob trigger function processed a blob.\n Name: " + name + "\n Content: " + triggerBlobText);
return triggerBlobText;
}

[Function(nameof(BlobTriggerStreamTest))]
public async Task BlobTriggerStreamTest(
[BlobTrigger("test-trigger-stream-dotnet-isolated/{name}")] Stream stream, string name,
FunctionContext context)
{
using var blobStreamReader = new StreamReader(stream);
string content = await blobStreamReader.ReadToEndAsync();
_logger.LogInformation("StreamTriggerOutput: {c}", content);
}

[Function(nameof(BlobTriggerBlobClientTest))]
public async Task BlobTriggerBlobClientTest(
[BlobTrigger("test-trigger-blobclient-dotnet-isolated/{name}")] BlobClient client, string name,
FunctionContext context)
{
var downloadResult = await client.DownloadContentAsync();
string content = downloadResult.Value.Content.ToString();
_logger.LogInformation("BlobClientTriggerOutput: {c}", content);
}

[Function(nameof(BlobTriggerBlobContainerClientTest))]
public async Task BlobTriggerBlobContainerClientTest(
[BlobTrigger("test-trigger-containerclient-dotnet-isolated/{name}")] BlobContainerClient client, string name,
FunctionContext context)
{
var blobClient = client.GetBlobClient(name);
var downloadResult = await blobClient.DownloadContentAsync();
string content = downloadResult.Value.Content.ToString();
_logger.LogInformation("BlobContainerTriggerOutput: {c}", content);
}

public class TestBlobData
{
[JsonPropertyName("text")]
public string BlobText { get; set; }
}
}
}
11 changes: 11 additions & 0 deletions test/E2ETests/E2EApps/E2EApp/Blob/Book.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

namespace Microsoft.Azure.Functions.Worker.E2EApp.Blob
{
public class Book
{
public string Id { get; set; }
public string Name { get; set; }
}
}
4 changes: 2 additions & 2 deletions test/E2ETests/E2EApps/E2EApp/E2EApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.2.0" />
<PackageReference Condition="$(TestBuild) == 'true'" Include="Microsoft.Azure.Functions.Worker" Version="1.10.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.7.0" />
<PackageReference Condition="$(TestBuild) == 'true'" Include="Microsoft.Azure.Functions.Worker" Version="1.12.1-preview1" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.9.0-preview1" />

<PackageReference Condition="$(FunctionsRuntimeVersion) != '3'" Include="System.Text.Json" Version="6.0.5" />
<PackageReference Condition="$(FunctionsRuntimeVersion) == '3'" Include="System.Text.Json" Version="5.0.2" />
Expand Down
18 changes: 11 additions & 7 deletions test/E2ETests/E2ETests/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,19 @@ public static class Queue
//Blob tests
public static class Blob
{
public const string TriggerInputBindingContainer = "test-triggerinput-dotnet-isolated";
public const string TriggerInputBindingContainer = "test-trigger-dotnet-isolated";
public const string InputBindingContainer = "test-input-dotnet-isolated";
public const string OutputBindingContainer = "test-output-dotnet-isolated";

public const string TriggerPocoContainer = "test-triggerinputpoco-dotnet-isolated";
public const string OutputPocoContainer = "test-outputpoco-dotnet-isolated";

public const string TriggerStringContainer = "test-triggerinputstring-dotnet-isolated";
public const string OutputStringContainer = "test-outputstring-dotnet-isolated";
public const string TriggerPocoContainer = "test-trigger-poco-dotnet-isolated";
public const string OutputPocoContainer = "test-output-poco-dotnet-isolated";
public const string TriggerStringContainer = "test-trigger-string-dotnet-isolated";
public const string OutputStringContainer = "test-output-string-dotnet-isolated";
public const string TriggerStreamContainer = "test-trigger-stream-dotnet-isolated";
public const string OutputStreamContainer = "test-output-stream-dotnet-isolated";
public const string TriggerBlobClientContainer = "test-trigger-blobclient-dotnet-isolated";
public const string OutputBlobClientContainer = "test-output-blobclient-dotnet-isolated";
public const string TriggerBlobContainerClientContainer = "test-trigger-containerclient-dotnet-isolated";
public const string OutputBlobContainerClientContainer = "test-output-containerclient-dotnet-isolated";
}

// CosmosDB tests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using Xunit;
using Xunit.Abstractions;

namespace Microsoft.Azure.Functions.Tests.E2ETests
namespace Microsoft.Azure.Functions.Tests.E2ETests.Cosmos
{
[Collection(Constants.FunctionAppCollectionName)]
public class CosmosDBEndToEndTests : IDisposable
Expand All @@ -26,7 +26,7 @@ public async Task CosmosDBTriggerAndOutput_Succeeds()
string expectedDocId = Guid.NewGuid().ToString();
try
{
//Trigger
//Trigger
await CosmosDBHelpers.CreateDocument(expectedDocId);

//Read
Expand Down
6 changes: 6 additions & 0 deletions test/E2ETests/E2ETests/Helpers/StorageHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ public async static Task ClearBlobContainers()
await ClearBlobContainer(Constants.Blob.OutputPocoContainer);
await ClearBlobContainer(Constants.Blob.TriggerStringContainer);
await ClearBlobContainer(Constants.Blob.OutputStringContainer);
await ClearBlobContainer(Constants.Blob.TriggerStreamContainer);
await ClearBlobContainer(Constants.Blob.OutputStreamContainer);
await ClearBlobContainer(Constants.Blob.TriggerBlobClientContainer);
await ClearBlobContainer(Constants.Blob.OutputBlobClientContainer);
await ClearBlobContainer(Constants.Blob.TriggerBlobContainerClientContainer);
await ClearBlobContainer(Constants.Blob.OutputBlobContainerClientContainer);
}

public static Task UploadFileToContainer(string containerName, string fileName)
Expand Down
Loading

0 comments on commit f05b9df

Please sign in to comment.