コード例 #1
0
            public async Task InitializeAsync(WebJobsTestEnvironment testEnvironment)
            {
                RandomNameResolver nameResolver = new RandomNameResolver();

                Host = new HostBuilder()
                       .ConfigureDefaultTestHost <BlobBindingEndToEndTests>(b =>
                {
                    b.AddAzureStorageBlobs().AddAzureStorageQueues();
                    b.AddAzureStorageCoreServices();
                })
                       .ConfigureServices(services =>
                {
                    services.AddSingleton <INameResolver>(nameResolver);
                })
                       .Build();


                JobHost = Host.GetJobHost();

                BlobServiceClient = new BlobServiceClient(testEnvironment.PrimaryStorageAccountConnectionString);

                BlobContainer = BlobServiceClient.GetBlobContainerClient(nameResolver.ResolveInString(ContainerName));
                Assert.False(await BlobContainer.ExistsAsync());
                await BlobContainer.CreateAsync();

                OutputBlobContainer = BlobServiceClient.GetBlobContainerClient(nameResolver.ResolveInString(OutputContainerName));

                var pageBlobContainer = BlobServiceClient.GetBlobContainerClient(nameResolver.ResolveInString(PageBlobContainerName));

                Assert.False(await pageBlobContainer.ExistsAsync());
                await pageBlobContainer.CreateAsync();

                var hierarchicalBlobContainer = BlobServiceClient.GetBlobContainerClient(nameResolver.ResolveInString(HierarchicalBlobContainerName));

                Assert.False(await hierarchicalBlobContainer.ExistsAsync());
                await hierarchicalBlobContainer.CreateAsync();

                var appendBlobContainer = BlobServiceClient.GetBlobContainerClient(nameResolver.ResolveInString(AppendBlobContainerName));

                Assert.False(await appendBlobContainer.ExistsAsync());
                await appendBlobContainer.CreateAsync();

                await Host.StartAsync();

                // upload some test blobs
                BlockBlobClient blob = BlobContainer.GetBlockBlobClient("blob1");
                await blob.UploadTextAsync(TestData);

                blob = BlobContainer.GetBlockBlobClient("blob2");
                await blob.UploadTextAsync(TestData);

                blob = BlobContainer.GetBlockBlobClient("blob3");
                await blob.UploadTextAsync(TestData);

                blob = BlobContainer.GetBlockBlobClient("file1");
                await blob.UploadTextAsync(TestData);

                blob = BlobContainer.GetBlockBlobClient("file2");
                await blob.UploadTextAsync(TestData);

                blob = BlobContainer.GetBlockBlobClient("overwrite");
                await blob.UploadTextAsync(TestData);

                // add a couple hierarchical blob paths
                blob = hierarchicalBlobContainer.GetBlockBlobClient("sub/blob1");
                await blob.UploadTextAsync(TestData);

                blob = hierarchicalBlobContainer.GetBlockBlobClient("sub/blob2");
                await blob.UploadTextAsync(TestData);

                blob = hierarchicalBlobContainer.GetBlockBlobClient("sub/sub/blob3");
                await blob.UploadTextAsync(TestData);

                blob = hierarchicalBlobContainer.GetBlockBlobClient("blob4");
                await blob.UploadTextAsync(TestData);

                byte[] bytes     = new byte[512];
                byte[] testBytes = Encoding.UTF8.GetBytes(TestData);
                for (int i = 0; i < testBytes.Length; i++)
                {
                    bytes[i] = testBytes[i];
                }
                PageBlobClient pageBlob = pageBlobContainer.GetPageBlobClient("blob1");
                await pageBlob.UploadFromByteArrayAsync(bytes, 0);

                pageBlob = pageBlobContainer.GetPageBlobClient("blob2");
                await pageBlob.UploadFromByteArrayAsync(bytes, 0);

                AppendBlobClient appendBlob = appendBlobContainer.GetAppendBlobClient("blob1");
                await appendBlob.UploadTextAsync(TestData);

                appendBlob = appendBlobContainer.GetAppendBlobClient("blob2");
                await appendBlob.UploadTextAsync(TestData);

                appendBlob = appendBlobContainer.GetAppendBlobClient("blob3");
                await appendBlob.UploadTextAsync(TestData);
            }
コード例 #2
0
        public async Task TableFilterTest()
        {
            // Reinitialize the name resolver to avoid conflicts
            _resolver = new RandomNameResolver();

            JobHostConfiguration hostConfig = new JobHostConfiguration()
            {
                NameResolver = _resolver,
                TypeLocator  = new FakeTypeLocator(
                    this.GetType(),
                    typeof(BlobToCustomObjectBinder))
            };

            hostConfig.AddService <IWebJobsExceptionHandler>(new TestExceptionHandler());

            // write test entities
            string           testTableName = _resolver.ResolveInString(TableName);
            CloudTableClient tableClient   = _storageAccount.CreateCloudTableClient();
            CloudTable       table         = tableClient.GetTableReference(testTableName);
            await table.CreateIfNotExistsAsync();

            var operation = new TableBatchOperation();

            operation.Insert(new Person
            {
                PartitionKey = "1",
                RowKey       = "1",
                Name         = "Lary",
                Age          = 20,
                Location     = "Seattle"
            });
            operation.Insert(new Person
            {
                PartitionKey = "1",
                RowKey       = "2",
                Name         = "Moe",
                Age          = 35,
                Location     = "Seattle"
            });
            operation.Insert(new Person
            {
                PartitionKey = "1",
                RowKey       = "3",
                Name         = "Curly",
                Age          = 45,
                Location     = "Texas"
            });
            operation.Insert(new Person
            {
                PartitionKey = "1",
                RowKey       = "4",
                Name         = "Bill",
                Age          = 28,
                Location     = "Tam O'Shanter"
            });
            await table.ExecuteBatchAsync(operation);

            JobHost host       = new JobHost(hostConfig);
            var     methodInfo = this.GetType().GetMethod("TableWithFilter", BindingFlags.Public | BindingFlags.Static);
            var     input      = new Person {
                Age = 25, Location = "Seattle"
            };
            string json      = JsonConvert.SerializeObject(input);
            var    arguments = new { person = json };
            await host.CallAsync(methodInfo, arguments);

            // wait for test results to appear
            await TestHelpers.Await(() => testResult != null);

            JArray results = (JArray)testResult;

            Assert.Equal(1, results.Count);

            input = new Person {
                Age = 25, Location = "Tam O'Shanter"
            };
            json      = JsonConvert.SerializeObject(input);
            arguments = new { person = json };
            await host.CallAsync(methodInfo, arguments);

            await TestHelpers.Await(() => testResult != null);

            results = (JArray)testResult;
            Assert.Equal(1, results.Count);
            Assert.Equal("Bill", (string)results[0]["Name"]);
        }
コード例 #3
0
        public async Task BadQueueMessageE2ETests()
        {
            // This test ensures that the host does not crash on a bad message (it previously did)
            // Insert a bad message into a queue that should:
            // - trigger BadMessage_CloudQueueMessage, which will put it into a second queue that will
            // - trigger BadMessage_String, which should fail
            // - BadMessage_String should fail repeatedly until it is moved to the poison queue
            // The test will watch that poison queue to know when to complete

            // Reinitialize the name resolver to avoid conflicts
            _resolver = new RandomNameResolver();

            JobHostConfiguration hostConfig = new JobHostConfiguration()
            {
                NameResolver = _resolver,
                TypeLocator  = new FakeTypeLocator(
                    this.GetType(),
                    typeof(BlobToCustomObjectBinder))
            };

            hostConfig.AddService <IWebJobsExceptionHandler>(new TestExceptionHandler());

            // use a custom processor so we can grab the Id and PopReceipt
            hostConfig.Queues.QueueProcessorFactory = new TestQueueProcessorFactory();

            var tracer = new TestTraceWriter(System.Diagnostics.TraceLevel.Verbose);

            hostConfig.Tracing.Tracers.Add(tracer);

            ILoggerFactory     loggerFactory  = new LoggerFactory();
            TestLoggerProvider loggerProvider = new TestLoggerProvider();

            loggerFactory.AddProvider(loggerProvider);
            hostConfig.LoggerFactory = loggerFactory;

            // The jobs host is started
            JobHost host = new JobHost(hostConfig);

            host.Start();

            // use reflection to construct a bad message:
            // - use a GUID as the content, which is not a valid base64 string
            // - pass 'true', to indicate that it is a base64 string
            string messageContent = Guid.NewGuid().ToString();

            object[]          parameters = new object[] { messageContent, true };
            CloudQueueMessage message    = Activator.CreateInstance(typeof(CloudQueueMessage),
                                                                    BindingFlags.Instance | BindingFlags.NonPublic, null, parameters, null) as CloudQueueMessage;

            var queueClient = _storageAccount.CreateCloudQueueClient();
            var queue       = queueClient.GetQueueReference(_resolver.ResolveInString(BadMessageQueue1));
            await queue.CreateIfNotExistsAsync();

            await queue.ClearAsync();

            // the poison queue will end up off of the second queue
            var poisonQueue = queueClient.GetQueueReference(_resolver.ResolveInString(BadMessageQueue2) + "-poison");
            await poisonQueue.DeleteIfExistsAsync();

            await queue.AddMessageAsync(message);

            CloudQueueMessage poisonMessage = null;
            await TestHelpers.Await(async() =>
            {
                bool done = false;
                if (await poisonQueue.ExistsAsync())
                {
                    poisonMessage = await poisonQueue.GetMessageAsync();
                    done          = poisonMessage != null;

                    if (done)
                    {
                        // Sleep briefly, then make sure the other message has been deleted.
                        // If so, trying to delete it again will throw an error.
                        Thread.Sleep(1000);

                        // The message is in the second queue
                        var queue2 = queueClient.GetQueueReference(_resolver.ResolveInString(BadMessageQueue2));

                        StorageException ex = await Assert.ThrowsAsync <StorageException>(
                            () => queue2.DeleteMessageAsync(_lastMessageId, _lastMessagePopReceipt));
                        Assert.Equal("MessageNotFound", ex.RequestInformation.ExtendedErrorInformation.ErrorCode);
                    }
                }
                return(done);
            });

            host.Stop();

            // find the raw string to compare it to the original
            Assert.NotNull(poisonMessage);
            var    propInfo  = typeof(CloudQueueMessage).GetProperty("RawString", BindingFlags.Instance | BindingFlags.NonPublic);
            string rawString = propInfo.GetValue(poisonMessage) as string;

            Assert.Equal(messageContent, rawString);

            // Make sure the functions were called correctly
            Assert.Equal(1, _badMessage1Calls);
            Assert.Equal(0, _badMessage2Calls);

            // make sure the exception is being properly logged
            var errors = tracer.Traces.Where(t => t.Level == System.Diagnostics.TraceLevel.Error);

            Assert.True(errors.All(t => t.Exception.InnerException.InnerException is FormatException));

            // Validate Logger
            var loggerErrors = loggerProvider.GetAllLogMessages().Where(l => l.Level == Microsoft.Extensions.Logging.LogLevel.Error);

            Assert.True(loggerErrors.All(t => t.Exception.InnerException.InnerException is FormatException));
        }
コード例 #4
0
            public async Task InitializeAsync()
            {
                RandomNameResolver nameResolver = new RandomNameResolver();

                Host = new HostBuilder()
                       .ConfigureDefaultTestHost <BlobBindingEndToEndTests>(b =>
                {
                    b.AddAzureStorage();
                    RuntimeStorageWebJobsBuilderExtensions.AddAzureStorageCoreServices(b);
                })
                       .ConfigureServices(services =>
                {
                    services.AddSingleton <INameResolver>(nameResolver);
                })
                       .Build();


                JobHost = Host.GetJobHost();

                var provider = Host.Services.GetService <StorageAccountProvider>();

                StorageAccount = provider.GetHost().SdkObject;
                CloudBlobClient blobClient = StorageAccount.CreateCloudBlobClient();

                BlobContainer = blobClient.GetContainerReference(nameResolver.ResolveInString(ContainerName));
                Assert.False(await BlobContainer.ExistsAsync());
                await BlobContainer.CreateAsync();

                OutputBlobContainer = blobClient.GetContainerReference(nameResolver.ResolveInString(OutputContainerName));

                CloudBlobContainer pageBlobContainer = blobClient.GetContainerReference(nameResolver.ResolveInString(PageBlobContainerName));

                Assert.False(await pageBlobContainer.ExistsAsync());
                await pageBlobContainer.CreateAsync();

                CloudBlobContainer hierarchicalBlobContainer = blobClient.GetContainerReference(nameResolver.ResolveInString(HierarchicalBlobContainerName));

                Assert.False(await hierarchicalBlobContainer.ExistsAsync());
                await hierarchicalBlobContainer.CreateAsync();

                CloudBlobContainer appendBlobContainer = blobClient.GetContainerReference(nameResolver.ResolveInString(AppendBlobContainerName));

                Assert.False(await appendBlobContainer.ExistsAsync());
                await appendBlobContainer.CreateAsync();

                await Host.StartAsync();

                // upload some test blobs
                CloudBlockBlob blob = BlobContainer.GetBlockBlobReference("blob1");
                await blob.UploadTextAsync(TestData);

                blob = BlobContainer.GetBlockBlobReference("blob2");
                await blob.UploadTextAsync(TestData);

                blob = BlobContainer.GetBlockBlobReference("blob3");
                await blob.UploadTextAsync(TestData);

                blob = BlobContainer.GetBlockBlobReference("file1");
                await blob.UploadTextAsync(TestData);

                blob = BlobContainer.GetBlockBlobReference("file2");
                await blob.UploadTextAsync(TestData);

                blob = BlobContainer.GetBlockBlobReference("overwrite");
                await blob.UploadTextAsync(TestData);

                // add a couple hierarchical blob paths
                blob = hierarchicalBlobContainer.GetBlockBlobReference("sub/blob1");
                await blob.UploadTextAsync(TestData);

                blob = hierarchicalBlobContainer.GetBlockBlobReference("sub/blob2");
                await blob.UploadTextAsync(TestData);

                blob = hierarchicalBlobContainer.GetBlockBlobReference("sub/sub/blob3");
                await blob.UploadTextAsync(TestData);

                blob = hierarchicalBlobContainer.GetBlockBlobReference("blob4");
                await blob.UploadTextAsync(TestData);

                byte[] bytes     = new byte[512];
                byte[] testBytes = Encoding.UTF8.GetBytes(TestData);
                for (int i = 0; i < testBytes.Length; i++)
                {
                    bytes[i] = testBytes[i];
                }
                CloudPageBlob pageBlob = pageBlobContainer.GetPageBlobReference("blob1");
                await pageBlob.UploadFromByteArrayAsync(bytes, 0, bytes.Length);

                pageBlob = pageBlobContainer.GetPageBlobReference("blob2");
                await pageBlob.UploadFromByteArrayAsync(bytes, 0, bytes.Length);

                CloudAppendBlob appendBlob = appendBlobContainer.GetAppendBlobReference("blob1");
                await appendBlob.UploadTextAsync(TestData);

                appendBlob = appendBlobContainer.GetAppendBlobReference("blob2");
                await appendBlob.UploadTextAsync(TestData);

                appendBlob = appendBlobContainer.GetAppendBlobReference("blob3");
                await appendBlob.UploadTextAsync(TestData);
            }
コード例 #5
0
        public async Task BadQueueMessageE2ETests()
        {
            // This test ensures that the host does not crash on a bad message (it previously did)
            // Insert a bad message into a queue that should:
            // - trigger BadMessage_CloudQueueMessage, which will put it into a second queue that will
            // - trigger BadMessage_String, which should fail
            // - BadMessage_String should fail repeatedly until it is moved to the poison queue
            // The test will watch that poison queue to know when to complete

            // Reinitialize the name resolver to avoid conflicts
            _resolver = new RandomNameResolver();
            IHost host = new HostBuilder()
                         .ConfigureDefaultTestHost <AzureStorageEndToEndTests>(b =>
            {
                b.AddAzureStorageBlobs().AddAzureStorageQueues();
            })
                         .ConfigureServices(services =>
            {
                // use a custom processor so we can grab the Id and PopReceipt
                services.AddSingleton <IQueueProcessorFactory>(new TestQueueProcessorFactory());
                services.AddSingleton <INameResolver>(_resolver);
            })
                         .Build();

            TestLoggerProvider loggerProvider = host.GetTestLoggerProvider();

            // The jobs host is started
            host.Start();

            // Construct a bad message:
            // - use a GUID as the content, which is not a valid base64 string
            // - pass 'true', to indicate that it is a base64 string
            string messageContent = Guid.NewGuid().ToString();
            // var message = new CloudQueueMessage(messageContent, true); // TODO (kasobol-msft) check this base64 thing

            var queue = _queueServiceClient.GetQueueClient(_resolver.ResolveInString(BadMessageQueue1));
            await queue.CreateIfNotExistsAsync();

            await queue.ClearMessagesAsync();

            // the poison queue will end up off of the second queue
            var poisonQueue = _queueServiceClient.GetQueueClient(_resolver.ResolveInString(BadMessageQueue2) + "-poison");
            await poisonQueue.DeleteIfExistsAsync();

            await queue.SendMessageAsync(messageContent);

            QueueMessage poisonMessage = null;
            await TestHelpers.Await(async() =>
            {
                bool done = false;
                if (await poisonQueue.ExistsAsync())
                {
                    poisonMessage = (await poisonQueue.ReceiveMessagesAsync(1)).Value.FirstOrDefault();
                    done          = poisonMessage != null;

                    if (done)
                    {
                        // Sleep briefly, then make sure the other message has been deleted.
                        // If so, trying to delete it again will throw an error.
                        Thread.Sleep(1000);

                        // The message is in the second queue
                        var queue2 = _queueServiceClient.GetQueueClient(_resolver.ResolveInString(BadMessageQueue2));

                        RequestFailedException ex = Assert.ThrowsAsync <RequestFailedException>(
                            () => queue2.DeleteMessageAsync(_lastMessageId, _lastMessagePopReceipt));
                        Assert.AreEqual("MessageNotFound", ex.ErrorCode);
                    }
                }
                var logs = loggerProvider.GetAllLogMessages();
                return(done);
            });

            await host.StopAsync();

            // find the raw string to compare it to the original
            Assert.NotNull(poisonMessage);
            Assert.AreEqual(messageContent, poisonMessage.MessageText);

            // Make sure the functions were called correctly
            Assert.AreEqual(1, _badMessage1Calls);
            Assert.AreEqual(0, _badMessage2Calls);

            // Validate Logger
            var loggerErrors = loggerProvider.GetAllLogMessages().Where(l => l.Level == Microsoft.Extensions.Logging.LogLevel.Error);

            Assert.True(loggerErrors.All(t => t.Exception.InnerException.InnerException is FormatException));
        }
コード例 #6
0
        public async Task BadQueueMessageE2ETests()
        {
            // This test ensures that the host does not crash on a bad message (it previously did)
            // Insert a bad message into a queue that should:
            // - trigger BadMessage_CloudQueueMessage, which will put it into a second queue that will
            // - trigger BadMessage_String, which should fail
            // - BadMessage_String should fail repeatedly until it is moved to the poison queue
            // The test will watch that poison queue to know when to complete

            // Reinitialize the name resolver to avoid conflicts
            _resolver = new RandomNameResolver();

            JobHostConfiguration hostConfig = new JobHostConfiguration()
            {
                NameResolver = _resolver,
                TypeLocator  = new FakeTypeLocator(
                    this.GetType(),
                    typeof(BlobToCustomObjectBinder))
            };
            var tracer = new TestTraceWriter(TraceLevel.Verbose);

            hostConfig.Tracing.Tracers.Add(tracer);

            // The jobs host is started
            JobHost host = new JobHost(hostConfig);

            host.Start();

            // use reflection to construct a bad message:
            // - use a GUID as the content, which is not a valid base64 string
            // - pass 'true', to indicate that it is a base64 string
            string messageContent = Guid.NewGuid().ToString();

            object[]          parameters = new object[] { messageContent, true };
            CloudQueueMessage message    = Activator.CreateInstance(typeof(CloudQueueMessage),
                                                                    BindingFlags.Instance | BindingFlags.NonPublic, null, parameters, null) as CloudQueueMessage;

            var queueClient = _storageAccount.CreateCloudQueueClient();
            var queue       = queueClient.GetQueueReference(_resolver.ResolveInString(BadMessageQueue1));
            await queue.CreateIfNotExistsAsync();

            await queue.ClearAsync();

            // the poison queue will end up off of the second queue
            var poisonQueue = queueClient.GetQueueReference(_resolver.ResolveInString(BadMessageQueue2) + "-poison");
            await poisonQueue.DeleteIfExistsAsync();

            await queue.AddMessageAsync(message);

            CloudQueueMessage poisonMessage = null;
            await TestHelpers.Await(() =>
            {
                bool done = false;
                if (poisonQueue.Exists())
                {
                    poisonMessage = poisonQueue.GetMessage();
                    done          = poisonMessage != null;
                }
                return(done);
            });

            host.Stop();

            // find the raw string to compare it to the original
            Assert.NotNull(poisonMessage);
            var    propInfo  = typeof(CloudQueueMessage).GetProperty("RawString", BindingFlags.Instance | BindingFlags.NonPublic);
            string rawString = propInfo.GetValue(poisonMessage) as string;

            Assert.Equal(messageContent, rawString);

            // Make sure the functions were called correctly
            Assert.Equal(1, _badMessage1Calls);
            Assert.Equal(0, _badMessage2Calls);

            // make sure the exception is being properly logged
            var errors = tracer.Traces.Where(t => t.Level == TraceLevel.Error);

            Assert.True(errors.All(t => t.Exception.InnerException.InnerException is FormatException));
        }
コード例 #7
0
            public TestFixture()
            {
                RandomNameResolver   nameResolver      = new RandomNameResolver();
                JobHostConfiguration hostConfiguration = new JobHostConfiguration()
                {
                    NameResolver = nameResolver,
                    TypeLocator  = new FakeTypeLocator(typeof(MultipleStorageAccountsEndToEndTests)),
                };

                Config = hostConfiguration;

                Account1 = CloudStorageAccount.Parse(hostConfiguration.StorageConnectionString);
                string secondaryConnectionString = AmbientConnectionStringProvider.Instance.GetConnectionString(Secondary);

                Account2 = CloudStorageAccount.Parse(secondaryConnectionString);

                CleanContainers();

                CloudBlobClient    blobClient1     = Account1.CreateCloudBlobClient();
                string             inputName       = nameResolver.ResolveInString(Input);
                CloudBlobContainer inputContainer1 = blobClient1.GetContainerReference(inputName);

                inputContainer1.Create();
                string outputName = nameResolver.ResolveWholeString(Output);

                OutputContainer1 = blobClient1.GetContainerReference(outputName);
                OutputContainer1.CreateIfNotExists();

                CloudBlobClient    blobClient2     = Account2.CreateCloudBlobClient();
                CloudBlobContainer inputContainer2 = blobClient2.GetContainerReference(inputName);

                inputContainer2.Create();
                OutputContainer2 = blobClient2.GetContainerReference(outputName);
                OutputContainer2.CreateIfNotExists();

                CloudQueueClient queueClient1 = Account1.CreateCloudQueueClient();
                CloudQueue       inputQueue1  = queueClient1.GetQueueReference(inputName);

                inputQueue1.CreateIfNotExists();
                OutputQueue1 = queueClient1.GetQueueReference(outputName);
                OutputQueue1.CreateIfNotExists();

                CloudQueueClient queueClient2 = Account2.CreateCloudQueueClient();
                CloudQueue       inputQueue2  = queueClient2.GetQueueReference(inputName);

                inputQueue2.CreateIfNotExists();
                OutputQueue2 = queueClient2.GetQueueReference(outputName);
                OutputQueue2.CreateIfNotExists();

                CloudTableClient tableClient1    = Account1.CreateCloudTableClient();
                string           outputTableName = nameResolver.ResolveWholeString(OutputTableName);

                OutputTable1 = tableClient1.GetTableReference(outputTableName);
                OutputTable2 = Account2.CreateCloudTableClient().GetTableReference(outputTableName);

                // upload some test blobs to the input containers of both storage accounts
                CloudBlockBlob blob = inputContainer1.GetBlockBlobReference("blob1");

                blob.UploadText(TestData);
                blob = inputContainer2.GetBlockBlobReference("blob2");
                blob.UploadText(TestData);

                // upload some test queue messages to the input queues of both storage accounts
                inputQueue1.AddMessage(new CloudQueueMessage(TestData));
                inputQueue2.AddMessage(new CloudQueueMessage(TestData));

                Host = new JobHost(hostConfiguration);
                Host.Start();
            }
コード例 #8
0
        public async Task BadQueueMessageE2ETests()
        {
            // This test ensures that the host does not crash on a bad message (it previously did)
            // Insert a bad message into a queue that should:
            // - trigger BadMessage_String, which should fail
            // - BadMessage_String should be transfered to poison queue.
            // The test will watch that poison queue to know when to complete

            // Reinitialize the name resolver to avoid conflicts
            _resolver = new RandomNameResolver();
            IHost host = new HostBuilder()
                         .ConfigureDefaultTestHost <AzureStorageEndToEndTests>(b =>
            {
                b.AddAzureStorageBlobs().AddAzureStorageQueues();
            })
                         .ConfigureServices(services =>
            {
                // use a custom processor so we can grab the Id and PopReceipt
                services.AddSingleton <IQueueProcessorFactory>(new TestQueueProcessorFactory());
                services.AddSingleton <INameResolver>(_resolver);
            })
                         .Build();

            TestLoggerProvider loggerProvider = host.GetTestLoggerProvider();

            // The jobs host is started
            host.Start();

            // Construct a bad message:
            // - use a GUID as the content, which is not a valid base64 string
            // - pass 'true', to indicate that it is a base64 string
            string messageContent = Guid.NewGuid().ToString();

            var queue = _queueServiceClientWithoutEncoding.GetQueueClient(_resolver.ResolveInString(BadMessageQueue));
            await queue.CreateIfNotExistsAsync();

            await queue.ClearMessagesAsync();

            var poisonQueue = _queueServiceClientWithoutEncoding.GetQueueClient(_resolver.ResolveInString(BadMessageQueue) + "-poison");
            await poisonQueue.DeleteIfExistsAsync();

            await queue.SendMessageAsync(messageContent);

            QueueMessage poisonMessage = null;
            await TestHelpers.Await(async() =>
            {
                bool done = false;
                if (await poisonQueue.ExistsAsync())
                {
                    poisonMessage = await poisonQueue.ReceiveMessageAsync();
                    done          = poisonMessage != null;
                }
                var logs = loggerProvider.GetAllLogMessages();
                return(done);
            });

            await host.StopAsync();

            // find the raw string to compare it to the original
            Assert.NotNull(poisonMessage);
            Assert.AreEqual(messageContent, poisonMessage.MessageText);

            // Make sure the functions were called correctly
            Assert.AreEqual(0, _badMessageCalls);

            // Validate Logger
            var loggerErrors = loggerProvider.GetAllLogMessages().Where(l => l.Level == Microsoft.Extensions.Logging.LogLevel.Error);

            Assert.True(loggerErrors.All(t => t.Exception.InnerException.InnerException is FormatException));
        }
コード例 #9
0
        public async Task DynamicConcurrency_Blobs()
        {
            // Reinitialize the name resolver to avoid conflicts
            _resolver = new RandomNameResolver();
            DynamicConcurrencyTestJob.InvocationCount = 0;

            IHost host = new HostBuilder()
                         .ConfigureDefaultTestHost <DynamicConcurrencyTestJob>(b =>
            {
                b.AddAzureStorageBlobs();

                b.Services.AddOptions <ConcurrencyOptions>().Configure(options =>
                {
                    options.DynamicConcurrencyEnabled = true;
                });

                b.Services.AddOptions <QueuesOptions>().Configure(options =>
                {
                    options.MaxPollingInterval = TimeSpan.FromSeconds(1);
                });
            })
                         .ConfigureServices(services =>
            {
                services.AddSingleton <INameResolver>(_resolver);
            })
                         .ConfigureLogging((context, b) =>
            {
                b.SetMinimumLevel(LogLevel.Debug);
            })
                         .Build();

            string sharedListenerId   = "SharedBlobQueueListener";
            var    concurrencyManager = host.Services.GetServices <ConcurrencyManager>().SingleOrDefault();
            var    concurrencyStatus  = concurrencyManager.GetStatus(sharedListenerId);

            Assert.AreEqual(1, concurrencyStatus.CurrentConcurrency);

            // write some blobs
            int    numBlobs          = 50;
            string blobContainerName = _resolver.ResolveInString(DynamicConcurrencyBlobContainerName);

            await WriteBlobs(blobContainerName, numBlobs);

            // start the host
            await host.StartAsync();

            // wait for all messages to be processed
            await TestHelpers.Await(() =>
            {
                return(DynamicConcurrencyTestJob.InvocationCount >= numBlobs);
            });

            await host.StopAsync();

            // ensure we've dynamically increased concurrency
            concurrencyStatus = concurrencyManager.GetStatus("SharedBlobQueueListener");
            Assert.GreaterOrEqual(concurrencyStatus.CurrentConcurrency, 3);

            // check a few of the concurrency logs
            var concurrencyLogs             = host.GetTestLoggerProvider().GetAllLogMessages().Where(p => p.Category == LogCategories.Concurrency).Select(p => p.FormattedMessage).ToList();
            int concurrencyIncreaseLogCount = concurrencyLogs.Count(p => p.Contains($"{sharedListenerId} Increasing concurrency"));

            Assert.GreaterOrEqual(concurrencyIncreaseLogCount, 1);
        }
コード例 #10
0
            private async Task Initialize()
            {
                RandomNameResolver   nameResolver      = new RandomNameResolver();
                JobHostConfiguration hostConfiguration = new JobHostConfiguration()
                {
                    NameResolver = nameResolver,
                    TypeLocator  = new FakeTypeLocator(typeof(BlobBindingEndToEndTests)),
                };

                hostConfiguration.AddService <IWebJobsExceptionHandler>(new TestExceptionHandler());

                Config = hostConfiguration;

                StorageAccount = CloudStorageAccount.Parse(hostConfiguration.StorageConnectionString);
                CloudBlobClient blobClient = StorageAccount.CreateCloudBlobClient();

                BlobContainer = blobClient.GetContainerReference(nameResolver.ResolveInString(ContainerName));
                Assert.False(await BlobContainer.ExistsAsync());
                await BlobContainer.CreateAsync();

                OutputBlobContainer = blobClient.GetContainerReference(nameResolver.ResolveInString(OutputContainerName));

                CloudBlobContainer pageBlobContainer = blobClient.GetContainerReference(nameResolver.ResolveInString(PageBlobContainerName));

                Assert.False(await pageBlobContainer.ExistsAsync());
                await pageBlobContainer.CreateAsync();

                CloudBlobContainer hierarchicalBlobContainer = blobClient.GetContainerReference(nameResolver.ResolveInString(HierarchicalBlobContainerName));

                Assert.False(await hierarchicalBlobContainer.ExistsAsync());
                await hierarchicalBlobContainer.CreateAsync();

                CloudBlobContainer appendBlobContainer = blobClient.GetContainerReference(nameResolver.ResolveInString(AppendBlobContainerName));

                Assert.False(await appendBlobContainer.ExistsAsync());
                await appendBlobContainer.CreateAsync();

                Host = new JobHost(hostConfiguration);
                Host.Start();

                // upload some test blobs
                CloudBlockBlob blob = BlobContainer.GetBlockBlobReference("blob1");
                await blob.UploadTextAsync(TestData);

                blob = BlobContainer.GetBlockBlobReference("blob2");
                await blob.UploadTextAsync(TestData);

                blob = BlobContainer.GetBlockBlobReference("blob3");
                await blob.UploadTextAsync(TestData);

                blob = BlobContainer.GetBlockBlobReference("file1");
                await blob.UploadTextAsync(TestData);

                blob = BlobContainer.GetBlockBlobReference("file2");
                await blob.UploadTextAsync(TestData);

                blob = BlobContainer.GetBlockBlobReference("overwrite");
                await blob.UploadTextAsync(TestData);

                // add a couple hierarchical blob paths
                blob = hierarchicalBlobContainer.GetBlockBlobReference("sub/blob1");
                await blob.UploadTextAsync(TestData);

                blob = hierarchicalBlobContainer.GetBlockBlobReference("sub/blob2");
                await blob.UploadTextAsync(TestData);

                blob = hierarchicalBlobContainer.GetBlockBlobReference("sub/sub/blob3");
                await blob.UploadTextAsync(TestData);

                blob = hierarchicalBlobContainer.GetBlockBlobReference("blob4");
                await blob.UploadTextAsync(TestData);

                byte[] bytes     = new byte[512];
                byte[] testBytes = Encoding.UTF8.GetBytes(TestData);
                for (int i = 0; i < testBytes.Length; i++)
                {
                    bytes[i] = testBytes[i];
                }
                CloudPageBlob pageBlob = pageBlobContainer.GetPageBlobReference("blob1");
                await pageBlob.UploadFromByteArrayAsync(bytes, 0, bytes.Length);

                pageBlob = pageBlobContainer.GetPageBlobReference("blob2");
                await pageBlob.UploadFromByteArrayAsync(bytes, 0, bytes.Length);

                CloudAppendBlob appendBlob = appendBlobContainer.GetAppendBlobReference("blob1");
                await appendBlob.UploadTextAsync(TestData);

                appendBlob = appendBlobContainer.GetAppendBlobReference("blob2");
                await appendBlob.UploadTextAsync(TestData);

                appendBlob = appendBlobContainer.GetAppendBlobReference("blob3");
                await appendBlob.UploadTextAsync(TestData);
            }