From 442e922e87dcac69c29460beaa3e9b5f438b1154 Mon Sep 17 00:00:00 2001 From: Kamil Sobol <61715331+kasobol-msft@users.noreply.github.com> Date: Tue, 29 Sep 2020 17:35:20 -0700 Subject: [PATCH] [Storage][Webjobs] reduce number of times azurite is created. (#15541) In this PR: - changes in tests to assure isolation through storage resources naming - AzuriteFixture creates just one account - Changed collection behavior to per class (more parallelism - faster run) - azurite is created once per test assembly instead of once per test class (from 34 to 6 in local run) Note: lot of binding tests rely on attributes that can only take constant strings, so the options for isolating through resource names are somewhat limited. --- ...Jobs.Extensions.Storage.Blobs.Tests.csproj | 4 ++ .../tests/BlobTests.cs | 16 +++--- .../tests/BlobTriggerTests.cs | 24 +++----- .../tests/HostCallTests.cs | 45 ++------------- .../BlobQueueTriggerExecutorTests.cs | 12 ++-- .../Listeners/BlobTriggerExecutorTests.cs | 23 ++++---- .../Listeners/ScanContainersStrategyTests.cs | 18 +++--- .../StorageBlobScanInfoManagerTests.cs | 12 ++-- .../tests/Properties/AssemblyInfo.cs | 2 +- ...obs.Extensions.Storage.Common.Tests.csproj | 4 ++ .../tests/AzuriteFixture.cs | 32 +++-------- .../tests/Shared/AzuriteCollection.cs | 17 ++++++ ...obs.Extensions.Storage.Queues.Tests.csproj | 4 ++ .../tests/BinderTests.cs | 16 ++---- .../tests/DataBindingFunctionalTests.cs | 13 +++-- .../tests/HostCallTests.cs | 55 +++---------------- .../tests/HostStartTests.cs | 9 +-- .../tests/HostStopTests.cs | 11 ++-- .../tests/InstanceTests.cs | 14 ++--- .../tests/Properties/AssemblyInfo.cs | 2 +- .../tests/QueueTests.cs | 31 ++++------- .../QueueTriggerBindingIntegrationTests.cs | 5 +- .../tests/QueueTriggerTests.cs | 37 ++----------- sdk/storage/Directory.Build.props | 1 + .../Azure.WebJobs.Host.EndToEnd.Tests.csproj | 4 ++ .../tests/ScenarioTests.cs | 26 ++++----- 26 files changed, 163 insertions(+), 274 deletions(-) create mode 100644 sdk/storage/Azure.Storage.Webjobs.Extensions.Common/tests/Shared/AzuriteCollection.cs diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Azure.WebJobs.Extensions.Storage.Blobs.Tests.csproj b/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Azure.WebJobs.Extensions.Storage.Blobs.Tests.csproj index 1f631d5e598c6..a14c4c3f4620c 100644 --- a/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Azure.WebJobs.Extensions.Storage.Blobs.Tests.csproj +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Azure.WebJobs.Extensions.Storage.Blobs.Tests.csproj @@ -17,6 +17,10 @@ + + + + diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/BlobTests.cs b/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/BlobTests.cs index 06c9ec49fa4d5..d5fb6feded300 100644 --- a/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/BlobTests.cs +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/BlobTests.cs @@ -15,26 +15,27 @@ namespace Microsoft.Azure.WebJobs.Host.FunctionalTests { - public class BlobTests : IClassFixture + [Collection(AzuriteCollection.Name)] + public class BlobTests { - private const string TriggerQueueName = "input"; - private const string ContainerName = "container"; + private const string TriggerQueueName = "input-blobtests"; + private const string ContainerName = "container-blobtests"; private const string BlobName = "blob"; private const string BlobPath = ContainerName + "/" + BlobName; - private readonly AzuriteFixture azuriteFixture; + private readonly StorageAccount account; public BlobTests(AzuriteFixture azuriteFixture) { - this.azuriteFixture = azuriteFixture; + account = azuriteFixture.GetAccount(); + account.CreateBlobServiceClient().GetBlobContainerClient(ContainerName).DeleteIfExists(); + account.CreateQueueServiceClient().GetQueueClient(TriggerQueueName).DeleteIfExists(); } [Fact] public async Task Blob_IfBoundToCloudBlockBlob_BindsAndCreatesContainerButNotBlob() { // Act - var account = azuriteFixture.GetAccount(); - var prog = new BindToCloudBlockBlobProgram(); IHost host = new HostBuilder() .ConfigureDefaultTestHost(prog, builder => @@ -65,7 +66,6 @@ public async Task Blob_IfBoundToTextWriter_CreatesBlob() { // Arrange const string expectedContent = "message"; - var account = azuriteFixture.GetAccount(); QueueClient triggerQueue = CreateQueue(account, TriggerQueueName); await triggerQueue.SendMessageAsync(expectedContent); diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/BlobTriggerTests.cs b/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/BlobTriggerTests.cs index ccc21ab3b45c5..5f8c6c4839caa 100644 --- a/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/BlobTriggerTests.cs +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/BlobTriggerTests.cs @@ -15,23 +15,26 @@ namespace Microsoft.Azure.WebJobs.Host.FunctionalTests { - public class BlobTriggerTests : IClassFixture + [Collection(AzuriteCollection.Name)] + public class BlobTriggerTests { - private const string ContainerName = "container"; + private const string ContainerName = "container-blobtriggertests"; private const string BlobName = "blob"; private const string BlobPath = ContainerName + "/" + BlobName; - private readonly AzuriteFixture azuriteFixture; + private readonly StorageAccount account; public BlobTriggerTests(AzuriteFixture azuriteFixture) { - this.azuriteFixture = azuriteFixture; + account = azuriteFixture.GetAccount(); + account.CreateBlobServiceClient().GetBlobContainerClient(ContainerName).DeleteIfExists(); + // make sure our system containers are present + CreateContainer(account, "azure-webjobs-hosts"); } [Fact] public async Task BlobTrigger_IfBoundToCloudBlob_Binds() { // Arrange - var account = CreateFakeStorageAccount(); var container = CreateContainer(account, ContainerName); var blob = container.GetBlockBlobClient(BlobName); @@ -60,7 +63,6 @@ public async Task BlobTrigger_Binding_Metadata() { var app = new BindToCloudBlob2Program(); var activator = new FakeActivator(app); - var account = CreateFakeStorageAccount(); var provider = new FakeStorageAccountProvider(account); var host = new HostBuilder() .ConfigureDefaultTestHost(b => @@ -106,16 +108,6 @@ private static BlobContainerClient CreateContainer(StorageAccount account, strin return container; } - private StorageAccount CreateFakeStorageAccount() - { - var account = azuriteFixture.GetAccount(); - - // make sure our system containers are present - var container = CreateContainer(account, "azure-webjobs-hosts"); - - return account; - } - private static async Task RunTriggerAsync(StorageAccount account, Type programType, Action> setTaskSource) { diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/HostCallTests.cs b/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/HostCallTests.cs index d2299851f5add..496ee6e7cd612 100644 --- a/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/HostCallTests.cs +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/HostCallTests.cs @@ -22,19 +22,21 @@ namespace Microsoft.Azure.WebJobs.Host.FunctionalTests { // Some tests in this class aren't as targeted as most other tests in this project. // (Look elsewhere for better examples to use as templates for new tests.) - public class HostCallTests : IClassFixture + [Collection(AzuriteCollection.Name)] + public class HostCallTests { - private const string ContainerName = "container"; + private const string ContainerName = "container-hostcalltests"; private const string BlobName = "blob"; private const string BlobPath = ContainerName + "/" + BlobName; private const string OutputBlobName = "blob.out"; private const string OutputBlobPath = ContainerName + "/" + OutputBlobName; private const int TestValue = Int32.MinValue; - private readonly AzuriteFixture azuriteFixture; + private readonly StorageAccount account; public HostCallTests(AzuriteFixture azuriteFixture) { - this.azuriteFixture = azuriteFixture; + account = azuriteFixture.GetAccount(); + account.CreateBlobServiceClient().GetBlobContainerClient(ContainerName).DeleteIfExists(); } [Theory] @@ -49,7 +51,6 @@ public HostCallTests(AzuriteFixture azuriteFixture) public async Task Blob_IfBoundToTypeAndBlobIsMissing_DoesNotCreate(string methodName) { // Arrange - var account = CreateFakeStorageAccount(); var client = account.CreateBlobServiceClient(); var container = client.GetBlobContainerClient(ContainerName); var blob = container.GetBlockBlobClient(BlobName); @@ -71,7 +72,6 @@ public async Task Blob_IfBoundToTypeAndBlobIsMissing_DoesNotCreate(string method public async Task Blob_IfBoundToTypeAndBlobIsMissing_Creates(string methodName) { // Arrange - StorageAccount account = CreateFakeStorageAccount(); var client = account.CreateBlobServiceClient(); var container = client.GetBlobContainerClient(ContainerName); var blob = container.GetBlockBlobClient(BlobName); @@ -87,7 +87,6 @@ public async Task Blob_IfBoundToTypeAndBlobIsMissing_Creates(string methodName) public async Task BlobTrigger_IfHasUnboundParameter_CanCall() { // Arrange - StorageAccount account = CreateFakeStorageAccount(); var client = account.CreateBlobServiceClient(); var container = client.GetBlobContainerClient(ContainerName); const string inputBlobName = "note-monday.csv"; @@ -119,7 +118,6 @@ public async Task BlobTrigger_IfHasUnboundParameter_CanCall() public async Task Blob_IfBoundToCloudBlockBlob_CanCall() { // Arrange - var account = CreateFakeStorageAccount(); var client = account.CreateBlobServiceClient(); var container = client.GetBlobContainerClient(ContainerName); var inputBlob = container.GetBlockBlobClient(BlobName); @@ -134,7 +132,6 @@ public async Task Blob_IfBoundToCloudBlockBlob_CanCall() public async Task Blob_IfBoundToString_CanCall() { // Arrange - var account = CreateFakeStorageAccount(); var client = account.CreateBlobServiceClient(); var container = client.GetBlobContainerClient(ContainerName); var inputBlob = container.GetBlockBlobClient(BlobName); @@ -148,7 +145,6 @@ public async Task Blob_IfBoundToString_CanCall() public async Task Blob_IfCopiedViaString_CanCall() { // Arrange - var account = CreateFakeStorageAccount(); var client = account.CreateBlobServiceClient(); var container = client.GetBlobContainerClient(ContainerName); var inputBlob = container.GetBlockBlobClient(BlobName); @@ -169,7 +165,6 @@ public async Task Blob_IfCopiedViaString_CanCall() public async Task BlobTrigger_IfCopiedViaTextReaderTextWriter_CanCall() { // Arrange - StorageAccount account = CreateFakeStorageAccount(); var client = account.CreateBlobServiceClient(); var container = client.GetBlobContainerClient(ContainerName); var inputBlob = container.GetBlockBlobClient(BlobName); @@ -196,7 +191,6 @@ public async Task BlobTrigger_IfCopiedViaTextReaderTextWriter_CanCall() public async Task BlobTrigger_IfBoundToICloudBlob_CanCallWithBlockBlob() { // Arrange - StorageAccount account = CreateFakeStorageAccount(); var client = account.CreateBlobServiceClient(); var container = client.GetBlobContainerClient(ContainerName); var blob = container.GetBlockBlobClient(BlobName); @@ -222,7 +216,6 @@ public async Task BlobTrigger_IfBoundToICloudBlob_CanCallWithBlockBlob() public async Task BlobTrigger_IfBoundToICloudBlob_CanCallWithPageBlob() { // Arrange - StorageAccount account = CreateFakeStorageAccount(); var client = account.CreateBlobServiceClient(); var container = client.GetBlobContainerClient(ContainerName); var blob = container.GetPageBlobClient(BlobName); @@ -247,9 +240,6 @@ public async Task BlobTrigger_IfBoundToICloudBlob_CanCallWithPageBlob() [Fact] public async Task BlobTrigger_IfBoundToICloudBlobAndTriggerArgumentIsMissing_CallThrows() { - // Arrange - StorageAccount account = CreateFakeStorageAccount(); - // Act Exception exception = await CallFailureAsync(account, typeof(BlobTriggerBindToICloudBlobProgram), "Call"); @@ -262,7 +252,6 @@ public async Task BlobTrigger_IfBoundToICloudBlobAndTriggerArgumentIsMissing_Cal public async Task BlobTrigger_IfBoundToCloudBlockBlob_CanCall() { // Arrange - StorageAccount account = CreateFakeStorageAccount(); var client = account.CreateBlobServiceClient(); var container = client.GetBlobContainerClient(ContainerName); var blob = container.GetBlockBlobClient(BlobName); @@ -286,9 +275,6 @@ public async Task BlobTrigger_IfBoundToCloudBlockBlob_CanCall() [Fact] public async Task BlobTrigger_IfBoundToCloudBLockBlobAndTriggerArgumentIsMissing_CallThrows() { - // Arrange - StorageAccount account = CreateFakeStorageAccount(); - // Act Exception exception = await CallFailureAsync(account, typeof(BlobTriggerBindToCloudBlockBlobProgram), "Call"); @@ -311,7 +297,6 @@ public static void Call([BlobTrigger(BlobPath)] BlockBlobClient blob) public async Task BlobTrigger_IfBoundToCloudPageBlob_CanCall() { // Arrange - StorageAccount account = CreateFakeStorageAccount(); var client = account.CreateBlobServiceClient(); var container = client.GetBlobContainerClient(ContainerName); var blob = container.GetPageBlobClient(BlobName); @@ -335,9 +320,6 @@ public async Task BlobTrigger_IfBoundToCloudPageBlob_CanCall() [Fact] public async Task BlobTrigger_IfBoundToCloudPageBlobAndTriggerArgumentIsMissing_CallThrows() { - // Arrange - var account = CreateFakeStorageAccount(); - // Act Exception exception = await CallFailureAsync(account, typeof(BlobTriggerBindToCloudPageBlobProgram), "Call"); @@ -360,7 +342,6 @@ public static void Call([BlobTrigger(BlobPath)] PageBlobClient blob) public async Task BlobTrigger_IfBoundToCloudAppendBlob_CanCall() { // Arrange - var account = CreateFakeStorageAccount(); var client = account.CreateBlobServiceClient(); var container = client.GetBlobContainerClient(ContainerName); var blob = container.GetAppendBlobClient(BlobName); @@ -384,9 +365,6 @@ public async Task BlobTrigger_IfBoundToCloudAppendBlob_CanCall() [Fact] public async Task BlobTrigger_IfBoundToCloudAppendBlobAndTriggerArgumentIsMissing_CallThrows() { - // Arrange - var account = CreateFakeStorageAccount(); - // Act Exception exception = await CallFailureAsync(account, typeof(BlobTriggerBindToCloudAppendBlobProgram), "Call"); @@ -408,8 +386,6 @@ public static void Call([BlobTrigger(BlobPath)] AppendBlobClient blob) [Fact] public async Task Int32Argument_CanCallViaStringParse() { - // Arrange - var account = CreateFakeStorageAccount(); IDictionary arguments = new Dictionary { { "value", "15" } @@ -436,9 +412,6 @@ public static void Call(int value) [Fact] public async Task Binder_IfBindingBlobToTextWriter_CanCall() { - // Arrange - StorageAccount account = CreateFakeStorageAccount(); - // Act await CallAsync(account, typeof(BindToBinderBlobTextWriterProgram), "Call"); @@ -465,7 +438,6 @@ public static void Call(IBinder binder) public async Task BlobTrigger_IfCopiedViaPoco_CanCall() { // Arrange - StorageAccount account = CreateFakeStorageAccount(); var client = account.CreateBlobServiceClient(); var container = client.GetBlobContainerClient(ContainerName); var inputBlob = container.GetBlockBlobClient(BlobName); @@ -523,11 +495,6 @@ private static async Task CallFailureAsync(StorageAccount account, Ty return await FunctionalTest.CallFailureAsync(account, programType, programType.GetMethod(methodName), null); } - private StorageAccount CreateFakeStorageAccount() - { - return azuriteFixture.GetAccount(); - } - private struct CustomDataValue { public int ValueId { get; set; } diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Listeners/BlobQueueTriggerExecutorTests.cs b/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Listeners/BlobQueueTriggerExecutorTests.cs index ac33cc0fed53d..5fed25cfa099c 100644 --- a/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Listeners/BlobQueueTriggerExecutorTests.cs +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Listeners/BlobQueueTriggerExecutorTests.cs @@ -25,10 +25,11 @@ namespace Microsoft.Azure.WebJobs.Host.UnitTests.Blobs.Listeners { - public class BlobQueueTriggerExecutorTests : IClassFixture + [Collection(AzuriteCollection.Name)] + public class BlobQueueTriggerExecutorTests { private const string TestBlobName = "TestBlobName"; - private const string TestContainerName = "container"; + private const string TestContainerName = "container-blobqueuetriggerexecutortests"; private const string TestQueueMessageId = "abc123"; private readonly TestLoggerProvider _loggerProvider = new TestLoggerProvider(); @@ -36,17 +37,16 @@ public class BlobQueueTriggerExecutorTests : IClassFixture private readonly BlobServiceClient blobServiceClient; private readonly BlobContainerClient blobContainer; - private readonly AzuriteFixture azuriteFixture; - public BlobQueueTriggerExecutorTests(AzuriteFixture azuriteFixture) { var loggerFactory = new LoggerFactory(); loggerFactory.AddProvider(_loggerProvider); _logger = loggerFactory.CreateLogger(); - this.azuriteFixture = azuriteFixture; - blobServiceClient = azuriteFixture.GetAccount().CreateBlobServiceClient(); + var account = azuriteFixture.GetAccount(); + blobServiceClient = account.CreateBlobServiceClient(); blobContainer = blobServiceClient.GetBlobContainerClient(TestContainerName); + blobContainer.DeleteIfExists(); blobContainer.CreateIfNotExists(); } diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Listeners/BlobTriggerExecutorTests.cs b/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Listeners/BlobTriggerExecutorTests.cs index 64e994bb9fdb3..9b0460903afb1 100644 --- a/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Listeners/BlobTriggerExecutorTests.cs +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Listeners/BlobTriggerExecutorTests.cs @@ -21,19 +21,23 @@ namespace Microsoft.Azure.WebJobs.Host.UnitTests.Blobs.Listeners { - public class BlobTriggerExecutorTests : IClassFixture + [Collection(AzuriteCollection.Name)] + public class BlobTriggerExecutorTests { // Note: The tests that return true consume the notification. // The tests that return false reset the notification (to be provided again later). private const string TestClientRequestId = "testClientRequestId"; + private const string ContainerName = "container-blobtriggerexecutortests"; + private readonly TestLoggerProvider _loggerProvider = new TestLoggerProvider(); private readonly ILogger _logger; - private readonly AzuriteFixture azuriteFixture; + private readonly StorageAccount account; public BlobTriggerExecutorTests(AzuriteFixture azuriteFixture) { - this.azuriteFixture = azuriteFixture; + account = azuriteFixture.GetAccount(); + account.CreateBlobServiceClient().GetBlobContainerClient(ContainerName).DeleteIfExists(); var loggerFactory = new LoggerFactory(); loggerFactory.AddProvider(_loggerProvider); _logger = loggerFactory.CreateLogger(); @@ -43,9 +47,8 @@ public BlobTriggerExecutorTests(AzuriteFixture azuriteFixture) public void ExecuteAsync_IfBlobDoesNotMatchPattern_ReturnsSuccessfulResult() { // Arrange - var account = CreateAccount(); var client = account.CreateBlobServiceClient(); - string containerName = "container"; + string containerName = ContainerName; var container = client.GetBlobContainerClient(containerName); var otherContainer = client.GetBlobContainerClient("other"); @@ -431,16 +434,11 @@ public void ExecuteAsync_IfLeasedIncompleteReceipt_EnqueuesMessageMarksCompleted Assert.True(!string.IsNullOrWhiteSpace(logMessage.GetStateValue("{OriginalFormat}"))); } - private StorageAccount CreateAccount() - { - return azuriteFixture.GetAccount(); - } - private BlobTriggerExecutorContext CreateExecutorContext(bool createBlob = true) { return new BlobTriggerExecutorContext { - Blob = CreateBlobReference("container", "blob", createBlob), + Blob = CreateBlobReference(ContainerName, "blob", createBlob), PollId = TestClientRequestId, TriggerSource = BlobTriggerSource.ContainerScan }; @@ -448,7 +446,6 @@ private BlobTriggerExecutorContext CreateExecutorContext(bool createBlob = true) private BlobWithContainer CreateBlobReference(string containerName, string blobName, bool createBlob = true) { - var account = CreateAccount(); var client = account.CreateBlobServiceClient(); var container = client.GetBlobContainerClient(containerName); container.CreateIfNotExists(); @@ -514,7 +511,7 @@ private BlobTriggerExecutor CreateProductUnderTest(string functionId, IBlobPathS private Mock CreateReceiptManagerReferenceMock() { - var blobServiceClient = CreateAccount().CreateBlobServiceClient(); + var blobServiceClient = account.CreateBlobServiceClient(); var blobContainerClient = blobServiceClient.GetBlobContainerClient("receipts"); var receiptBlob = blobContainerClient.GetBlockBlobClient("item"); Mock mock = new Mock(MockBehavior.Strict); diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Listeners/ScanContainersStrategyTests.cs b/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Listeners/ScanContainersStrategyTests.cs index 2b2d48b12b6d8..d0a86dbedeadf 100644 --- a/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Listeners/ScanContainersStrategyTests.cs +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Listeners/ScanContainersStrategyTests.cs @@ -14,22 +14,23 @@ namespace Microsoft.Azure.WebJobs.Host.FunctionalTests.Blobs.Listeners { - public class ScanContainersStrategyTests : IClassFixture + [Collection(AzuriteCollection.Name)] + public class ScanContainersStrategyTests { - private readonly AzuriteFixture azuriteFixture; + private const string ContainerName = "container-scancontainersstrategytests"; + private readonly StorageAccount account; public ScanContainersStrategyTests(AzuriteFixture azuriteFixture) { - this.azuriteFixture = azuriteFixture; + account = azuriteFixture.GetAccount(); + account.CreateBlobServiceClient().GetBlobContainerClient(ContainerName).DeleteIfExists(); } [Fact] public async Task TestBlobListener() { - const string containerName = "container"; - var account = CreateFakeStorageAccount(); var blobServiceClient = account.CreateBlobServiceClient(); - var container = blobServiceClient.GetBlobContainerClient(containerName); + var container = blobServiceClient.GetBlobContainerClient(ContainerName); IBlobListenerStrategy product = new ScanContainersStrategy(); LambdaBlobTriggerExecutor executor = new LambdaBlobTriggerExecutor(); product.Register(blobServiceClient, container, executor); @@ -64,11 +65,6 @@ public async Task TestBlobListener() product.Execute(); } - private StorageAccount CreateFakeStorageAccount() - { - return azuriteFixture.GetAccount(); - } - private class LambdaBlobTriggerExecutor : ITriggerExecutor { public Func ExecuteLambda { get; set; } diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Listeners/StorageBlobScanInfoManagerTests.cs b/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Listeners/StorageBlobScanInfoManagerTests.cs index 0be54ed9c8c1c..6a593e9c230a7 100644 --- a/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Listeners/StorageBlobScanInfoManagerTests.cs +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Listeners/StorageBlobScanInfoManagerTests.cs @@ -14,13 +14,14 @@ namespace Microsoft.Azure.WebJobs.Host.FunctionalTests.Blobs.Listeners { - public class StorageBlobScanInfoManagerTests : IClassFixture + [Collection(AzuriteCollection.Name)] + public class StorageBlobScanInfoManagerTests { - private readonly AzuriteFixture azuriteFixture; + private readonly StorageAccount account; public StorageBlobScanInfoManagerTests(AzuriteFixture azuriteFixture) { - this.azuriteFixture = azuriteFixture; + account = azuriteFixture.GetAccount(); } [Fact] @@ -30,7 +31,6 @@ public async Task LoadLatestScan_NoContainer_ReturnsNull() string storageAccountName = Guid.NewGuid().ToString(); string containerName = Guid.NewGuid().ToString(); - var account = azuriteFixture.GetAccount(); var client = account.CreateBlobServiceClient(); // by default there is no table in this client @@ -48,7 +48,6 @@ public async Task LoadLatestScan_NoBlob_ReturnsNull() string storageAccountName = Guid.NewGuid().ToString(); string containerName = Guid.NewGuid().ToString(); - var account = azuriteFixture.GetAccount(); var client = account.CreateBlobServiceClient(); var container = client.GetBlobContainerClient(HostContainerNames.Hosts); await container.CreateIfNotExistsAsync(); @@ -67,7 +66,6 @@ public async Task LoadLatestScan_Returns_Timestamp() string storageAccountName = "account=" + Guid.NewGuid().ToString(); string containerName = "container-" + Guid.NewGuid().ToString(); - var account = azuriteFixture.GetAccount(); var client = account.CreateBlobServiceClient(); var container = client.GetBlobContainerClient(HostContainerNames.Hosts); await container.CreateIfNotExistsAsync(); @@ -89,7 +87,6 @@ public async Task UpdateLatestScan_Inserts() string storageAccountName = Guid.NewGuid().ToString(); string containerName = Guid.NewGuid().ToString(); - var account = azuriteFixture.GetAccount(); var client = account.CreateBlobServiceClient(); var container = client.GetBlobContainerClient(HostContainerNames.Hosts); await container.CreateIfNotExistsAsync(); @@ -114,7 +111,6 @@ public async Task UpdateLatestScan_Updates() string storageAccountName = Guid.NewGuid().ToString(); string containerName = Guid.NewGuid().ToString(); - var account = azuriteFixture.GetAccount(); var client = account.CreateBlobServiceClient(); var container = client.GetBlobContainerClient(HostContainerNames.Hosts); await container.CreateIfNotExistsAsync(); diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Properties/AssemblyInfo.cs b/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Properties/AssemblyInfo.cs index 33a4724df3960..55d94aa32c43f 100644 --- a/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Properties/AssemblyInfo.cs +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Blobs/tests/Properties/AssemblyInfo.cs @@ -3,4 +3,4 @@ using Xunit; -[assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly)] +[assembly: CollectionBehavior(CollectionBehavior.CollectionPerClass)] diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Common/tests/Azure.WebJobs.Extensions.Storage.Common.Tests.csproj b/sdk/storage/Azure.Storage.Webjobs.Extensions.Common/tests/Azure.WebJobs.Extensions.Storage.Common.Tests.csproj index 556365f959efe..4c7e5f850869d 100644 --- a/sdk/storage/Azure.Storage.Webjobs.Extensions.Common/tests/Azure.WebJobs.Extensions.Storage.Common.Tests.csproj +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Common/tests/Azure.WebJobs.Extensions.Storage.Common.Tests.csproj @@ -15,6 +15,10 @@ + + + + diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Common/tests/AzuriteFixture.cs b/sdk/storage/Azure.Storage.Webjobs.Extensions.Common/tests/AzuriteFixture.cs index 7510643bcae2d..eb20e0c94fd16 100644 --- a/sdk/storage/Azure.Storage.Webjobs.Extensions.Common/tests/AzuriteFixture.cs +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Common/tests/AzuriteFixture.cs @@ -2,12 +2,9 @@ // Licensed under the MIT License. using System; -using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; -using System.Net; -using System.Net.Sockets; using System.Text; using System.Threading; using Azure.Storage.Blobs; @@ -31,12 +28,10 @@ public class AzuriteFixture : IDisposable { private const BlobClientOptions.ServiceVersion SupportedBlobServiceVersion = BlobClientOptions.ServiceVersion.V2019_12_12; private const QueueClientOptions.ServiceVersion SupportedQueueServiceVersion = QueueClientOptions.ServiceVersion.V2019_12_12; - private const int AccountPoolSize = 50; private const string AzuriteLocationKey = "AZURE_AZURITE_LOCATION"; private string tempDirectory; private Process process; - private Queue accounts = new Queue(); - private List accountsList = new List(); + private AzuriteAccount account; private CountdownEvent countdownEvent = new CountdownEvent(2); private StringBuilder azuriteOutput = new StringBuilder(); private int blobsPort; @@ -55,23 +50,18 @@ public AzuriteFixture() throw new ArgumentException(ErrorMessage($"{azuriteScriptLocation} does not exist, check if {AzuriteLocationKey} is pointing to right location")); } - for (int i = 0; i < AccountPoolSize; i++) + account = new AzuriteAccount() { - var account = new AzuriteAccount() - { - Name = Guid.NewGuid().ToString(), - Key = System.Convert.ToBase64String(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())), - }; - accounts.Enqueue(account); - accountsList.Add($"{account.Name}:{account.Key}"); - } + Name = Guid.NewGuid().ToString(), + Key = System.Convert.ToBase64String(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())), + }; tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); Directory.CreateDirectory(tempDirectory); process = new Process(); process.StartInfo.FileName = "node"; process.StartInfo.Arguments = $"{azuriteScriptLocation} -l {tempDirectory} --blobPort 0 --queuePort 0"; - process.StartInfo.EnvironmentVariables.Add("AZURITE_ACCOUNTS", $"{string.Join(";", accountsList)}"); + process.StartInfo.EnvironmentVariables.Add("AZURITE_ACCOUNTS", $"{account.Name}:{account.Key}"); process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardInput = true; @@ -108,11 +98,8 @@ public AzuriteFixture() { throw new InvalidOperationException(ErrorMessage($"azurite process could not start with following output:\n{azuriteOutput}")); } - foreach (var account in accounts) - { - account.BlobsPort = blobsPort; - account.QueuesPort = queuesPort; - } + account.BlobsPort = blobsPort; + account.QueuesPort = queuesPort; } private int ParseAzuritePort(string outputLine) @@ -132,8 +119,7 @@ private string ErrorMessage(string specificReason) public StorageAccount GetAccount() { - var azuriteAccount = accounts.Dequeue(); - return new StorageAccount(azuriteAccount.ConnectionString, + return new StorageAccount(account.ConnectionString, SupportedBlobServiceVersion, SupportedQueueServiceVersion); } diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Common/tests/Shared/AzuriteCollection.cs b/sdk/storage/Azure.Storage.Webjobs.Extensions.Common/tests/Shared/AzuriteCollection.cs new file mode 100644 index 0000000000000..fea01779e1272 --- /dev/null +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Common/tests/Shared/AzuriteCollection.cs @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using Xunit; + +namespace Azure.WebJobs.Extensions.Storage.Common.Tests +{ + [CollectionDefinition(Name)] + public class AzuriteCollection : ICollectionFixture + { + public const string Name = nameof(AzuriteCollection); + // This class has no code, and is never created. Its purpose is simply + // to be the place to apply [CollectionDefinition] and all the + // ICollectionFixture<> interfaces. + // It has to be compiled into assembly using it. + } +} diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/Azure.WebJobs.Extensions.Storage.Queues.Tests.csproj b/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/Azure.WebJobs.Extensions.Storage.Queues.Tests.csproj index 3da739b3928cd..5bf3a95743ab1 100644 --- a/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/Azure.WebJobs.Extensions.Storage.Queues.Tests.csproj +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/Azure.WebJobs.Extensions.Storage.Queues.Tests.csproj @@ -17,6 +17,10 @@ + + + + diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/BinderTests.cs b/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/BinderTests.cs index 4799e041d2e33..96939eae30265 100644 --- a/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/BinderTests.cs +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/BinderTests.cs @@ -11,14 +11,16 @@ namespace Microsoft.Azure.WebJobs.Host.FunctionalTests { - public class BinderTests : IClassFixture + [Collection(AzuriteCollection.Name)] + public class BinderTests { - private const string QueueName = "input"; - private readonly AzuriteFixture azuriteFixture; + private const string QueueName = "input-bindertests"; + private readonly StorageAccount account; public BinderTests(AzuriteFixture azuriteFixture) { - this.azuriteFixture = azuriteFixture; + account = azuriteFixture.GetAccount(); + account.CreateQueueServiceClient().GetQueueClient(QueueName).DeleteIfExists(); } [Fact] @@ -26,7 +28,6 @@ public async Task Trigger_ViaIBinder_CannotBind() { // Arrange const string expectedContents = "abc"; - var account = CreateFakeStorageAccount(); QueueClient queue = CreateQueue(account, QueueName); await queue.SendMessageAsync(expectedContents); @@ -38,11 +39,6 @@ public async Task Trigger_ViaIBinder_CannotBind() Assert.Equal("No binding found for attribute 'Microsoft.Azure.WebJobs.QueueTriggerAttribute'.", exception.Message); } - private StorageAccount CreateFakeStorageAccount() - { - return azuriteFixture.GetAccount(); - } - private static QueueClient CreateQueue(StorageAccount account, string queueName) { var client = account.CreateQueueServiceClient(); diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/DataBindingFunctionalTests.cs b/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/DataBindingFunctionalTests.cs index 7a32ddc22fb00..2c255f6922fca 100644 --- a/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/DataBindingFunctionalTests.cs +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/DataBindingFunctionalTests.cs @@ -13,13 +13,16 @@ namespace Microsoft.Azure.WebJobs.Host.UnitTests.Bindings.Data { - public class DataBindingFunctionalTests : IClassFixture + [Collection(AzuriteCollection.Name)] + public class DataBindingFunctionalTests { - private readonly AzuriteFixture azuriteFixture; + private const string QueueName = "queue-databindingfunctionaltests"; + private readonly StorageAccount account; public DataBindingFunctionalTests(AzuriteFixture azuriteFixture) { - this.azuriteFixture = azuriteFixture; + account = azuriteFixture.GetAccount(); + account.CreateQueueServiceClient().GetQueueClient(QueueName).DeleteIfExists(); } [Fact] @@ -29,7 +32,7 @@ public async Task BindStringableParameter_CanInvoke() var builder = new HostBuilder() .ConfigureDefaultTestHost(b => { - b.UseStorage(azuriteFixture.GetAccount()); + b.UseStorage(account); }); @@ -64,7 +67,7 @@ private class TestFunctions { public static string Result { get; set; } - public static void BindStringableParameter([QueueTrigger("ignore")] MessageWithStringableProperty message, + public static void BindStringableParameter([QueueTrigger(QueueName)] MessageWithStringableProperty message, string guidValue) { Result = guidValue; diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/HostCallTests.cs b/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/HostCallTests.cs index 6605158a5105f..40e245a9440e3 100644 --- a/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/HostCallTests.cs +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/HostCallTests.cs @@ -3,19 +3,14 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Text; -using System.Threading; using System.Threading.Tasks; -using Microsoft.Azure.WebJobs.Host.Config; using Microsoft.Azure.WebJobs.Host.Indexers; using Newtonsoft.Json; using Xunit; using Azure.Storage.Queues; using Azure.Storage.Queues.Models; -using Azure.Storage.Blobs.Specialized; -using Microsoft.Azure.WebJobs.Host.TestCommon; using Azure.WebJobs.Extensions.Storage.Common.Tests; using Microsoft.Azure.WebJobs.Extensions.Storage.Common; @@ -23,24 +18,26 @@ namespace Microsoft.Azure.WebJobs.Host.FunctionalTests { // Some tests in this class aren't as targeted as most other tests in this project. // (Look elsewhere for better examples to use as templates for new tests.) - public class HostCallTests : IClassFixture + [Collection(AzuriteCollection.Name)] + public class HostCallTests { - private const string QueueName = "input"; - private const string OutputQueueName = "output"; + private const string QueueName = "input-hostcalltests"; + private const string OutputQueueName = "output-hostcalltests"; private const int TestValue = Int32.MinValue; private const string TestQueueMessage = "ignore"; - private readonly AzuriteFixture azuriteFixture; + private readonly StorageAccount account; public HostCallTests(AzuriteFixture azuriteFixture) { - this.azuriteFixture = azuriteFixture; + account = azuriteFixture.GetAccount(); + account.CreateQueueServiceClient().GetQueueClient(QueueName).DeleteIfExists(); + account.CreateQueueServiceClient().GetQueueClient(OutputQueueName).DeleteIfExists(); } [Fact] public async Task Int32Argument_CanCallViaStringParse() { // Arrange - var account = CreateFakeStorageAccount(); IDictionary arguments = new Dictionary { { "value", "15" } @@ -67,8 +64,6 @@ public static void Call(int value) [Fact] public async Task Queue_IfBoundToOutPoco_CanCall() { - var account = CreateFakeStorageAccount(); - // Act await CallAsync(account, typeof(QueueProgram), "BindToOutPoco"); @@ -92,8 +87,6 @@ public async Task Queue_IfBoundToIAsyncCollectorPoco_CanCall() [Fact] public async Task Queue_IfBoundToIAsyncCollectorByteArray_CanCall() { - var account = CreateFakeStorageAccount(); - // Act await CallAsync(account, typeof(QueueProgram), "BindToIAsyncCollectorByteArray"); // TODO (kasobol-msft) revisit when BinaryData is in SDK @@ -113,8 +106,6 @@ public async Task Queue_IfBoundToIAsyncCollectorByteArray_CanCall() [Fact] public async Task Queue_IfBoundToICollectorByteArray_CanCall() // TODO (kasobol-msft) revisit when BinaryData is in SDK { - var account = CreateFakeStorageAccount(); - // Act await CallAsync(account, typeof(QueueProgram), "BindToICollectorByteArray"); @@ -133,8 +124,6 @@ public async Task Queue_IfBoundToICollectorByteArray_CanCall() // TODO (kasobol- [Fact] public async Task Queue_IfBoundToIAsyncCollectorInt_NotSupported() { - StorageAccount account = CreateFakeStorageAccount(); - // Act FunctionIndexingException ex = await Assert.ThrowsAsync(() => { @@ -147,8 +136,6 @@ public async Task Queue_IfBoundToIAsyncCollectorInt_NotSupported() private async Task TestEnqueueMultiplePocoMessages(string methodName) { - StorageAccount account = CreateFakeStorageAccount(); - // Act await CallAsync(account, typeof(QueueProgram), methodName); @@ -169,9 +156,6 @@ private async Task TestEnqueueMultiplePocoMessages(string methodName) [Fact] public async Task Queue_IfBoundToIAsyncCollector_AddEnqueuesImmediately() { - // Arrange - StorageAccount account = CreateFakeStorageAccount(); - // Act await CallAsync(account, typeof(QueueProgram), "BindToIAsyncCollectorEnqueuesImmediately"); } @@ -179,9 +163,6 @@ public async Task Queue_IfBoundToIAsyncCollector_AddEnqueuesImmediately() [Fact] public async Task Queue_IfBoundToCloudQueue_CanCall() { - // Arrange - StorageAccount account = CreateFakeStorageAccount(); - // Act QueueClient result = await CallAsync(account, typeof(BindToCloudQueueProgram), "BindToCloudQueue", (s) => BindToCloudQueueProgram.TaskSource = s); @@ -194,9 +175,6 @@ public async Task Queue_IfBoundToCloudQueue_CanCall() [Fact] public async Task Queue_IfBoundToCloudQueueAndQueueIsMissing_Creates() { - // Arrange - StorageAccount account = CreateFakeStorageAccount(); - // Act QueueClient result = await CallAsync(account, typeof(BindToCloudQueueProgram), "BindToCloudQueue", (s) => BindToCloudQueueProgram.TaskSource = s); @@ -224,9 +202,6 @@ public static void BindToCloudQueue([Queue(QueueName)] QueueClient queue) [InlineData("FuncWithICollector", TestQueueMessage)] public async Task Queue_IfBoundToTypeAndQueueIsMissing_CreatesAndSends(string methodName, string expectedMessage) { - // Arrange - StorageAccount account = CreateFakeStorageAccount(); - // Act await CallAsync(account, typeof(MissingQueueProgram), methodName); @@ -239,9 +214,6 @@ public async Task Queue_IfBoundToTypeAndQueueIsMissing_CreatesAndSends(string me [Fact] public async Task Queue_IfBoundToOutPocoAndQueueIsMissing_CreatesAndSends() { - // Arrange - StorageAccount account = CreateFakeStorageAccount(); - // Act await CallAsync(account, typeof(MissingQueueProgram), "FuncWithOutT"); @@ -254,9 +226,6 @@ public async Task Queue_IfBoundToOutPocoAndQueueIsMissing_CreatesAndSends() [Fact] public async Task Queue_IfBoundToOutStructAndQueueIsMissing_CreatesAndSends() { - // Arrange - StorageAccount account = CreateFakeStorageAccount(); - // Act await CallAsync(account, typeof(MissingQueueProgram), "FuncWithOutT"); @@ -273,9 +242,6 @@ public async Task Queue_IfBoundToOutStructAndQueueIsMissing_CreatesAndSends() [InlineData("FuncWithICollectorNoop")] public async Task Queue_IfBoundToTypeAndQueueIsMissing_DoesNotCreate(string methodName) { - // Arrange - StorageAccount account = CreateFakeStorageAccount(); - // Act await CallAsync(account, typeof(MissingQueueProgram), methodName); @@ -364,11 +330,6 @@ private static async Task CallAsync(StorageAccount account, Ty return await FunctionalTest.CallAsync(account, programType, programType.GetMethod(methodName), arguments, setTaskSource); } - private StorageAccount CreateFakeStorageAccount() - { - return azuriteFixture.GetAccount(); - } - private struct CustomDataValue { public int ValueId { get; set; } diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/HostStartTests.cs b/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/HostStartTests.cs index d69c10bf2ed2c..40c2cf7a91b1b 100644 --- a/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/HostStartTests.cs +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/HostStartTests.cs @@ -13,13 +13,14 @@ namespace Microsoft.Azure.WebJobs.Host.FunctionalTests { - public class HostStartTests : IClassFixture + [Collection(AzuriteCollection.Name)] + public class HostStartTests { - private readonly AzuriteFixture azuriteFixture; + private readonly StorageAccount account; public HostStartTests(AzuriteFixture azuriteFixture) { - this.azuriteFixture = azuriteFixture; + account = azuriteFixture.GetAccount(); } [Fact] @@ -29,7 +30,7 @@ public async Task Queue_IfNameIsInvalid_ThrowsDuringIndexing() .ConfigureDefaultTestHost(b => { b.AddAzureStorageBlobs().AddAzureStorageQueues() - .UseStorage(azuriteFixture.GetAccount()); + .UseStorage(account); }) .Build(); diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/HostStopTests.cs b/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/HostStopTests.cs index 85ad8f1dc6cdc..0c31f37950533 100644 --- a/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/HostStopTests.cs +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/HostStopTests.cs @@ -13,23 +13,24 @@ namespace Microsoft.Azure.WebJobs.Host.FunctionalTests { - public class HostStopTests : IClassFixture + [Collection(AzuriteCollection.Name)] + public class HostStopTests { - private const string QueueName = "input"; + private const string QueueName = "input-hoststoptests"; private static readonly TaskCompletionSource _functionStarted = new TaskCompletionSource(); private static readonly TaskCompletionSource _stopHostCalled = new TaskCompletionSource(); private static readonly TaskCompletionSource _testTaskSource = new TaskCompletionSource(); - private readonly AzuriteFixture azuriteFixture; + private readonly StorageAccount account; public HostStopTests(AzuriteFixture azuriteFixture) { - this.azuriteFixture = azuriteFixture; + account = azuriteFixture.GetAccount(); + account.CreateQueueServiceClient().GetQueueClient(QueueName).DeleteIfExists(); } [Fact] public async Task Stop_TriggersCancellationToken() { - StorageAccount account = azuriteFixture.GetAccount(); QueueClient queue = await CreateQueueAsync(account, QueueName); await queue.SendMessageAsync("ignore"); diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/InstanceTests.cs b/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/InstanceTests.cs index fd4c63a815862..b9d185907adc3 100644 --- a/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/InstanceTests.cs +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/InstanceTests.cs @@ -13,14 +13,16 @@ namespace Microsoft.Azure.WebJobs.Host.FunctionalTests { - public class InstanceTests : IClassFixture + [Collection(AzuriteCollection.Name)] + public class InstanceTests { - private const string QueueName = "input"; - private readonly AzuriteFixture azuriteFixture; + private const string QueueName = "input-instancetests"; + private readonly StorageAccount account; public InstanceTests(AzuriteFixture azuriteFixture) { - this.azuriteFixture = azuriteFixture; + account = azuriteFixture.GetAccount(); + account.CreateQueueServiceClient().GetQueueClient(QueueName).DeleteIfExists(); } [Fact] @@ -28,7 +30,6 @@ public async Task Trigger_CanBeInstanceMethod() { // Arrange string expectedGuid = Guid.NewGuid().ToString(); - var account = azuriteFixture.GetAccount(); await account.AddQueueMessageAsync(expectedGuid, QueueName); var prog = new InstanceProgram(); @@ -64,7 +65,6 @@ public async Task Trigger_CanBeAsyncInstanceMethod() { // Arrange string expectedGuid = Guid.NewGuid().ToString(); - var account = azuriteFixture.GetAccount(); await account.AddQueueMessageAsync(expectedGuid, QueueName); var prog = new InstanceAsyncProgram(); @@ -100,7 +100,6 @@ public Task RunAsync([QueueTrigger(QueueName)] QueueMessage message) public async Task Trigger_IfClassIsDisposable_Disposes() { // Arrange - var account = azuriteFixture.GetAccount(); await account.AddQueueMessageAsync("ignore", QueueName); IHost host = new HostBuilder() @@ -145,7 +144,6 @@ public async Task Trigger_IfClassConstructorHasDependencies_CanUseCustomJobActiv .Returns(() => new InstanceCustomActivatorProgram(resultFactory)); IJobActivator activator = activatorMock.Object; - var account = azuriteFixture.GetAccount(); await account.AddQueueMessageAsync("ignore", QueueName); IHost host = new HostBuilder() diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/Properties/AssemblyInfo.cs b/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/Properties/AssemblyInfo.cs index 33a4724df3960..55d94aa32c43f 100644 --- a/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/Properties/AssemblyInfo.cs +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/Properties/AssemblyInfo.cs @@ -3,4 +3,4 @@ using Xunit; -[assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly)] +[assembly: CollectionBehavior(CollectionBehavior.CollectionPerClass)] diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/QueueTests.cs b/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/QueueTests.cs index cf7461c5a4052..9b8494fed4d38 100644 --- a/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/QueueTests.cs +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/QueueTests.cs @@ -18,15 +18,18 @@ namespace Microsoft.Azure.WebJobs.Host.FunctionalTests { - public class QueueTests : IClassFixture + [Collection(AzuriteCollection.Name)] + public class QueueTests { - private const string TriggerQueueName = "input"; - private const string QueueName = "output"; - private readonly AzuriteFixture azuriteFixture; + private const string TriggerQueueName = "input-queuetests"; + private const string QueueName = "output-queuetests"; + private readonly StorageAccount account; public QueueTests(AzuriteFixture azuriteFixture) { - this.azuriteFixture = azuriteFixture; + account = azuriteFixture.GetAccount(); + account.CreateQueueServiceClient().GetQueueClient(TriggerQueueName).DeleteIfExists(); + account.CreateQueueServiceClient().GetQueueClient(QueueName).DeleteIfExists(); } // Test binding to generics. @@ -42,7 +45,6 @@ public void Func([Queue(QueueName)] T q) [Fact] public async Task TestGenericSucceeds() { - var account = CreateFakeStorageAccount(); IHost host = new HostBuilder() .ConfigureDefaultTestHost>>(b => { @@ -112,7 +114,7 @@ public async Task Catch_Bad_Name_At_Runtime() IHost host = new HostBuilder() .ConfigureDefaultTestHost(builder => { - builder.UseStorage(azuriteFixture.GetAccount()); + builder.UseStorage(account); }) .ConfigureServices(services => { @@ -145,7 +147,7 @@ public async Task Catch_Bad_Name_At_Runtime_With_Illegal_Static_Chars() IHost host = new HostBuilder() .ConfigureDefaultTestHost(builder => { - builder.UseStorage(azuriteFixture.GetAccount()); + builder.UseStorage(account); }) .ConfigureServices(services => { @@ -189,7 +191,6 @@ public async Task InvokeWithBindingData() // Verify that queue binding pattern has uppercase letters in it. These get normalized to lowercase. Assert.NotEqual(ProgramWithTriggerAndBindingData.QueueOutName, ProgramWithTriggerAndBindingData.QueueOutName.ToLower()); - var account = CreateFakeStorageAccount(); IHost host = new HostBuilder() .ConfigureDefaultTestHost(b => { @@ -250,7 +251,6 @@ public async Task InvokeWithCompoundBindingData() // Verify that queue binding pattern has uppercase letters in it. These get normalized to lowercase. Assert.NotEqual(ProgramWithTriggerAndBindingData.QueueOutName, ProgramWithTriggerAndBindingData.QueueOutName.ToLower()); - var account = CreateFakeStorageAccount(); IHost host = new HostBuilder() .ConfigureDefaultTestHost(b => { @@ -361,7 +361,6 @@ public void Func([QueueTrigger(QueueName)] string triggers, [Queue("queuName-{xy public void Fails_BindingContract_Mismatch() { // Verify that indexing fails if the [Queue] trigger needs binding data that's not present. - var account = CreateFakeStorageAccount(); IHost host = new HostBuilder() .ConfigureDefaultTestHost(b => { @@ -386,7 +385,6 @@ public void Func([Queue(QueueName)] out object o) [Fact] public void Fails_Cant_Bind_To_Object() { - var account = CreateFakeStorageAccount(); IHost host = new HostBuilder() .ConfigureDefaultTestHost(b => { @@ -422,7 +420,7 @@ private void Fails_Cant_Bind_To_Types_Worker(string typeName) IHost host = new HostBuilder() .ConfigureDefaultTestHost>(b => { - b.UseStorage(azuriteFixture.GetAccount()); + b.UseStorage(account); }) .Build(); @@ -435,7 +433,6 @@ private void Fails_Cant_Bind_To_Types_Worker(string typeName) public async Task Queue_IfBoundToCloudQueue_BindsAndCreatesQueue() { // Arrange - var account = CreateFakeStorageAccount(); var client = account.CreateQueueServiceClient(); var triggerQueue = await CreateQueue(client, TriggerQueueName); await triggerQueue.SendMessageAsync("ignore"); @@ -456,7 +453,6 @@ public async Task Queue_IfBoundToICollectorCloudQueueMessage_AddEnqueuesMessage( { // Arrange string expectedContent = Guid.NewGuid().ToString(); - var account = CreateFakeStorageAccount(); var client = account.CreateQueueServiceClient(); var triggerQueue = await CreateQueue(client, TriggerQueueName); await triggerQueue.SendMessageAsync(expectedContent); @@ -474,11 +470,6 @@ await RunTriggerAsync(account, typeof(BindToICollectorCloudQueueMessageP Assert.Equal(expectedContent, message.MessageText); } - private StorageAccount CreateFakeStorageAccount() - { - return azuriteFixture.GetAccount(); - } - private static async Task CreateQueue(QueueServiceClient client, string queueName) { var queue = client.GetQueueClient(queueName); diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/QueueTriggerBindingIntegrationTests.cs b/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/QueueTriggerBindingIntegrationTests.cs index c96fa14e1e636..e835f692fb464 100644 --- a/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/QueueTriggerBindingIntegrationTests.cs +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/QueueTriggerBindingIntegrationTests.cs @@ -16,7 +16,8 @@ namespace Microsoft.Azure.WebJobs.Host.UnitTests.Queues { - public class QueueTriggerBindingIntegrationTests : IClassFixture, IClassFixture + [Collection(AzuriteCollection.Name)] + public class QueueTriggerBindingIntegrationTests : IClassFixture { private ITriggerBinding _binding; @@ -28,7 +29,7 @@ public QueueTriggerBindingIntegrationTests(AzuriteFixture azuriteFixture) var fakeAccount = azuriteFixture.GetAccount(); QueueServiceClient queueServiceClient = fakeAccount.CreateQueueServiceClient(); - QueueClient queue = queueServiceClient.GetQueueClient("queueName"); + QueueClient queue = queueServiceClient.GetQueueClient("queueName-queuetriggerbindingintegrationtests"); IWebJobsExceptionHandler exceptionHandler = new WebJobsExceptionHandler(new Mock().Object); var enqueueWatcher = new Host.Queues.Listeners.SharedQueueWatcher(); diff --git a/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/QueueTriggerTests.cs b/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/QueueTriggerTests.cs index f7d49e4b61e4b..bce239f5229de 100644 --- a/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/QueueTriggerTests.cs +++ b/sdk/storage/Azure.Storage.Webjobs.Extensions.Queues/tests/QueueTriggerTests.cs @@ -16,14 +16,16 @@ namespace Microsoft.Azure.WebJobs.Host.FunctionalTests { - public class QueueTriggerTests : IClassFixture + [Collection(AzuriteCollection.Name)] + public class QueueTriggerTests { - private const string QueueName = "input"; - private readonly AzuriteFixture azuriteFixture; + private const string QueueName = "input-queuetriggertests"; + private readonly StorageAccount account; public QueueTriggerTests(AzuriteFixture azuriteFixture) { - this.azuriteFixture = azuriteFixture; + account = azuriteFixture.GetAccount(); + account.CreateQueueServiceClient().GetQueueClient(QueueName).DeleteIfExists(); } private async Task SetupAsync(StorageAccount account, object contents) @@ -53,7 +55,6 @@ public async Task QueueTrigger_IfBoundToCloudQueueMessage_Binds() { // Arrange string expectedGuid = Guid.NewGuid().ToString(); - var account = CreateFakeStorageAccount(); var queue = await CreateQueue(account, QueueName); await queue.SendMessageAsync(expectedGuid); @@ -81,7 +82,6 @@ public async Task QueueTrigger_IfBoundToStringAndMessageIsEmpty_Binds() private async Task TestBindToString(string expectedContent) { // Arrange - var account = CreateFakeStorageAccount(); var queue = await CreateQueue(account, QueueName); await queue.SendMessageAsync(expectedContent); @@ -98,7 +98,6 @@ public async Task QueueTrigger_IfBoundToStringAndMessageIsNotUtf8ByteArray_DoesN { // Arrange byte[] content = new byte[] { 0xFF, 0x00 }; // Not a valid UTF-8 byte sequence. - var account = CreateFakeStorageAccount(); var queue = await CreateQueue(account, QueueName); await queue.SendMessageAsync(Convert.ToBase64String(content)); @@ -139,7 +138,6 @@ public async Task QueueTrigger_IfBoundToByteArrayAndMessageIsNonUtf8_Binds() private async Task TestBindToByteArray(byte[] expectedContent) // TODO (kasobol-msft) Revisit base64 encoding story { // Arrange - var account = CreateFakeStorageAccount(); var queue = await CreateQueue(account, QueueName); await queue.SendMessageAsync(Convert.ToBase64String(expectedContent)); @@ -168,7 +166,6 @@ public async Task QueueTrigger_IfBoundToPocoAndMessageIsJsonNull_Binds() private async Task TestBindToPoco(Poco expectedContent) { // Arrange - var account = CreateFakeStorageAccount(); var queue = await CreateQueue(account, QueueName); string content = JsonConvert.SerializeObject(expectedContent, typeof(Poco), settings: null); await queue.SendMessageAsync(content); @@ -199,7 +196,6 @@ public async Task QueueTrigger_IfBoundToPocoAndMessageIsNotJson_DoesNotBind() { // Arrange const string content = "not json"; // Not a valid JSON byte sequence. - var account = CreateFakeStorageAccount(); var queue = await CreateQueue(account, QueueName); await queue.SendMessageAsync(content); @@ -226,7 +222,6 @@ public async Task QueueTrigger_IfBoundToPocoAndMessageIsIncompatibleJson_DoesNot { // Arrange const string content = "123"; // A JSON int rather than a JSON object. - var account = CreateFakeStorageAccount(); var queue = await CreateQueue(account, QueueName); await queue.SendMessageAsync(content); @@ -253,7 +248,6 @@ public async Task QueueTrigger_IfBoundToPocoStruct_Binds() { // Arrange const int expectedContent = 123; - var account = CreateFakeStorageAccount(); var queue = await CreateQueue(account, QueueName); string content = JsonConvert.SerializeObject(expectedContent, typeof(int), settings: null); await queue.SendMessageAsync(content); @@ -271,7 +265,6 @@ public async Task QueueTrigger_IfMessageIsString_ProvidesQueueTriggerBindingData { // Arrange string expectedQueueTrigger = Guid.NewGuid().ToString(); - var account = CreateFakeStorageAccount(); var queue = await CreateQueue(account, QueueName); await queue.SendMessageAsync(expectedQueueTrigger); @@ -289,7 +282,6 @@ public async Task QueueTrigger_IfMessageIsUtf8ByteArray_ProvidesQueueTriggerBind // Arrange const string expectedQueueTrigger = "abc"; byte[] content = Encoding.UTF8.GetBytes(expectedQueueTrigger); // TODO (kasobol-msft) Revisit base64 encoding story - var account = CreateFakeStorageAccount(); var queue = await CreateQueue(account, QueueName); await queue.SendMessageAsync(expectedQueueTrigger); @@ -306,7 +298,6 @@ public async Task QueueTrigger_IfMessageIsNonUtf8ByteArray_DoesNotProvideQueueTr { // Arrange byte[] content = new byte[] { 0xFF, 0x00 }; // Not a valid UTF-8 byte sequence. - var account = CreateFakeStorageAccount(); var queue = await CreateQueue(account, QueueName); await queue.SendMessageAsync(Convert.ToBase64String(content)); @@ -326,7 +317,6 @@ public async Task QueueTrigger_IfMessageIsNonUtf8ByteArray_DoesNotProvideQueueTr public async Task QueueTrigger_ProvidesDequeueCountBindingData() { // Arrange - var account = CreateFakeStorageAccount(); var queue = await CreateQueue(account, QueueName); // message.DequeueCount is provided by FakeStorageAccount when the message is retrieved. await queue.SendMessageAsync("ignore"); @@ -343,7 +333,6 @@ public async Task QueueTrigger_ProvidesDequeueCountBindingData() public async Task QueueTrigger_ProvidesExpirationTimeBindingData() { // Arrange - var account = CreateFakeStorageAccount(); var queue = await CreateQueue(account, QueueName); // message.ExpirationTime is provided by FakeStorageAccount when the message is inserted. await queue.SendMessageAsync("ignore"); @@ -360,7 +349,6 @@ public async Task QueueTrigger_ProvidesExpirationTimeBindingData() public async Task QueueTrigger_ProvidesIdBindingData() { // Arrange - var account = CreateFakeStorageAccount(); var queue = await CreateQueue(account, QueueName); // message.Id is provided by FakeStorageAccount when the message is inserted. await queue.SendMessageAsync("ignore"); @@ -378,7 +366,6 @@ public async Task QueueTrigger_ProvidesIdBindingData() public async Task QueueTrigger_ProvidesInsertionTimeBindingData() { // Arrange - var account = CreateFakeStorageAccount(); await SetupAsync(account, "ignore"); // Act @@ -393,7 +380,6 @@ public async Task QueueTrigger_ProvidesInsertionTimeBindingData() public async Task QueueTrigger_ProvidesNextVisibleTimeBindingData() { // Arrange - var account = CreateFakeStorageAccount(); await SetupAsync(account, "ignore"); // Act @@ -408,7 +394,6 @@ public async Task QueueTrigger_ProvidesNextVisibleTimeBindingData() public async Task QueueTrigger_ProvidesPopReceiptBindingData() { // Arrange - var account = CreateFakeStorageAccount(); await SetupAsync(account, "ignore"); // Act @@ -425,7 +410,6 @@ public async Task QueueTrigger_ProvidesPocoStructPropertyBindingData() { // Arrange const int expectedInt32Value = 123; - var account = CreateFakeStorageAccount(); Poco value = new Poco { Int32Value = expectedInt32Value }; string content = JsonConvert.SerializeObject(value, typeof(Poco), settings: null); @@ -449,7 +433,6 @@ public async Task QueueTrigger_ProvidesPocoComplexPropertyBindingData() Value = "abc", Int32Value = 123 }; - var account = CreateFakeStorageAccount(); Poco value = new Poco { Child = expectedChild }; string content = JsonConvert.SerializeObject(value, typeof(Poco), settings: null); @@ -469,7 +452,6 @@ public async Task QueueTrigger_IfBindingAlwaysFails_MovesToPoisonQueue() { // Arrange const string expectedContents = "abc"; - var account = CreateFakeStorageAccount(); await SetupAsync(account, expectedContents); // Act @@ -488,7 +470,6 @@ public async Task QueueTrigger_IfDequeueCountReachesMaxDequeueCount_MovesToPoiso { // Arrange const string expectedContents = "abc"; - var account = CreateFakeStorageAccount(); await SetupAsync(account, expectedContents); // Act @@ -715,7 +696,6 @@ private static async Task RunTriggerFailureAsync(StorageAcco private async Task CallQueueTriggerAsync(object message, Type programType, Action> setTaskSource) { - var account = azuriteFixture.GetAccount(); var method = programType.GetMethod("Run"); Assert.NotNull(method); @@ -727,11 +707,6 @@ private async Task CallQueueTriggerAsync(object message, Type return result; } - private StorageAccount CreateFakeStorageAccount() - { - return azuriteFixture.GetAccount(); - } - private static async Task CreateQueue(StorageAccount account, string queueName) { var client = account.CreateQueueServiceClient(); diff --git a/sdk/storage/Directory.Build.props b/sdk/storage/Directory.Build.props index 66146613f1548..85fda6bd6d43b 100644 --- a/sdk/storage/Directory.Build.props +++ b/sdk/storage/Directory.Build.props @@ -83,5 +83,6 @@ $(MSBuildThisFileDirectory)\Azure.Storage.Common\src\Shared\ $(MSBuildThisFileDirectory)\Azure.Storage.Webjobs.Extensions.Common\src\Shared\ + $(MSBuildThisFileDirectory)\Azure.Storage.Webjobs.Extensions.Common\tests\Shared\ \ No newline at end of file diff --git a/sdk/storage/Microsoft.Azure.WebJobs.Host.EndToEndTests/tests/Azure.WebJobs.Host.EndToEnd.Tests.csproj b/sdk/storage/Microsoft.Azure.WebJobs.Host.EndToEndTests/tests/Azure.WebJobs.Host.EndToEnd.Tests.csproj index ad2d52003327b..fdb5bdde46b62 100644 --- a/sdk/storage/Microsoft.Azure.WebJobs.Host.EndToEndTests/tests/Azure.WebJobs.Host.EndToEnd.Tests.csproj +++ b/sdk/storage/Microsoft.Azure.WebJobs.Host.EndToEndTests/tests/Azure.WebJobs.Host.EndToEnd.Tests.csproj @@ -28,6 +28,10 @@ + + + + diff --git a/sdk/storage/Microsoft.Azure.WebJobs.Host.EndToEndTests/tests/ScenarioTests.cs b/sdk/storage/Microsoft.Azure.WebJobs.Host.EndToEndTests/tests/ScenarioTests.cs index 74a035cf316fc..63752c3477d86 100644 --- a/sdk/storage/Microsoft.Azure.WebJobs.Host.EndToEndTests/tests/ScenarioTests.cs +++ b/sdk/storage/Microsoft.Azure.WebJobs.Host.EndToEndTests/tests/ScenarioTests.cs @@ -13,26 +13,30 @@ namespace Microsoft.Azure.WebJobs.Host.FunctionalTests { - public class ScenarioTests : IClassFixture + [Collection(AzuriteCollection.Name)] + public class ScenarioTests { - private const string ContainerName = "container"; + private const string ContainerName = "container-scenariotests"; private const string BlobName = "blob"; private const string BlobPath = ContainerName + "/" + BlobName; private const string OutputBlobName = "blob.out"; private const string OutputBlobPath = ContainerName + "/" + OutputBlobName; - private const string QueueName = "queue"; - private readonly AzuriteFixture azuriteFixture; + private const string QueueName = "queue-scenariotests"; + private readonly StorageAccount account; public ScenarioTests(AzuriteFixture azuriteFixture) { - this.azuriteFixture = azuriteFixture; + account = azuriteFixture.GetAccount(); + account.CreateBlobServiceClient().GetBlobContainerClient(ContainerName).DeleteIfExists(); + // make sure our system containers are present + account.CreateBlobServiceClient().GetBlobContainerClient("azure-webjobs-hosts").CreateIfNotExists(); + account.CreateQueueServiceClient().GetQueueClient(QueueName).DeleteIfExists(); } [Fact] public async Task BlobTriggerToQueueTriggerToBlob_WritesFinalBlob() { // Arrange - StorageAccount account = await CreateFakeStorageAccountAsync(); var container = await CreateContainerAsync(account, ContainerName); var inputBlob = container.GetBlockBlobClient(BlobName); await inputBlob.UploadTextAsync("15"); @@ -55,16 +59,6 @@ private static async Task CreateContainerAsync(StorageAccou return container; } - private async Task CreateFakeStorageAccountAsync() - { - var account = azuriteFixture.GetAccount(); - - // make sure our system containers are present - var container = await CreateContainerAsync(account, "azure-webjobs-hosts"); - - return account; - } - private static async Task RunTriggerAsync(StorageAccount account, Type programType, Action> setTaskSource) {