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 <BindToCloudBlob2Program>(b => { b.AddAzureStorage(); }) .ConfigureServices(services => { services.AddSingleton <IJobActivator>(activator); services.AddSingleton <StorageAccountProvider>(provider); }) .Build(); // Set the binding data, and verify it's accessible in the function. var container = CreateContainer(account, ContainerName); var blob = container.GetBlockBlobReference(BlobName); blob.Metadata["m1"] = "v1"; await host.GetJobHost().CallAsync(typeof(BindToCloudBlob2Program).GetMethod(nameof(BindToCloudBlob2Program.Run)), new { blob }); Assert.True(app.Success); }
public DispatchQueueTests() { _accountProviderMock = new Mock <IStorageAccountProvider>(); IStorageAccountProvider accountProvider = new FakeStorageAccountProvider { StorageAccount = new FakeStorageAccount() }; _accountProviderMock.Setup(m => m.TryGetAccountAsync(ConnectionStringNames.Storage, It.IsAny <CancellationToken>())) .Returns <string, CancellationToken>((name, cancel) => accountProvider.TryGetAccountAsync(name, cancel)); _hostIdMock = new Mock <IHostIdProvider>(); _hostIdMock.Setup(m => m.GetHostIdAsync(It.IsAny <CancellationToken>())).ReturnsAsync(HostId); _exceptionMock = new Mock <IWebJobsExceptionHandler>(); _queueConfiguration = new FakeQueuesOptionsFactory(accountProvider).Create(string.Empty); _sharedContextProvider = new SharedContextProvider(); _messageEnqueueSetterMock = new Mock <IContextSetter <IMessageEnqueuedWatcher> >(); ILoggerFactory factory = new LoggerFactory(); factory.AddProvider(_loggerProvider); _sharedQueue = new SharedQueueHandler(_accountProviderMock.Object, _hostIdMock.Object, _exceptionMock.Object, factory, new OptionsWrapper <JobHostQueuesOptions>(_queueConfiguration), _sharedContextProvider, _messageEnqueueSetterMock.Object ); }
public void QueueTrigger_IfDequeueCountReachesMaxDequeueCount_MovesToPoisonQueue() { try { // Arrange const string expectedContents = "abc"; IStorageAccount account = CreateFakeStorageAccount(); IStorageQueue queue = CreateQueue(account, QueueName); queue.AddMessage(queue.CreateMessage(expectedContents)); // Act RunTrigger <object>(account, typeof(MaxDequeueCountProgram), (s) => MaxDequeueCountProgram.TaskSource = s, new string[] { typeof(MaxDequeueCountProgram).FullName + ".PutInPoisonQueue" }); // Assert IStorageAccountProvider storageAccountProvider = new FakeStorageAccountProvider() { StorageAccount = new FakeStorageAccount() }; Assert.Equal(new FakeQueueConfiguration(storageAccountProvider).MaxDequeueCount, MaxDequeueCountProgram.DequeueCount); } finally { MaxDequeueCountProgram.DequeueCount = 0; } }
public async Task QueueTrigger_IfDequeueCountReachesMaxDequeueCount_MovesToPoisonQueue() { try { // Arrange const string expectedContents = "abc"; var account = CreateFakeStorageAccount(); await SetupAsync(account, expectedContents); // Act RunTrigger <object>(account, typeof(MaxDequeueCountProgram), (s) => MaxDequeueCountProgram.TaskSource = s, new string[] { typeof(MaxDequeueCountProgram).FullName + ".PutInPoisonQueue" }); // Assert var storageAccountProvider = new FakeStorageAccountProvider(account); // These tests use the FakeQueueOptionsFactory, so compare dequeue count to that // $$$ enable //JobHostQueuesOptions options = new FakeQueuesOptionsFactory(storageAccountProvider).Create(string.Empty); // Assert.Equal(options.MaxDequeueCount, MaxDequeueCountProgram.DequeueCount); } finally { MaxDequeueCountProgram.DequeueCount = 0; } }
public async Task BlobTrigger_Binding_Metadata() { var app = new BindToCloudBlob2Program(); var activator = new FakeActivator(app); var provider = new FakeStorageAccountProvider(account); var host = new HostBuilder() .ConfigureDefaultTestHost <BindToCloudBlob2Program>(b => { b.AddAzureStorageBlobs().AddAzureStorageQueues(); }) .ConfigureServices(services => { services.AddSingleton <IJobActivator>(activator); services.AddSingleton <StorageAccountProvider>(provider); }) .Build(); // Set the binding data, and verify it's accessible in the function. var container = CreateContainer(account, ContainerName); var blob = container.GetBlockBlobClient(BlobName); await blob.UploadTextAsync(string.Empty); await blob.SetMetadataAsync(new Dictionary <string, string> { { "m1", "v1" } }); await host.GetJobHost().CallAsync(typeof(BindToCloudBlob2Program).GetMethod(nameof(BindToCloudBlob2Program.Run)), new { blob }); Assert.True(app.Success); }
// Helper to create a JobHostConfiguraiton from a set of services. // Default config, pure-in-memory // Default is pure-in-memory, good for unit testing. public static JobHostConfiguration NewConfig( Type functions, params object[] services ) { JobHostConfiguration config = new JobHostConfiguration() { TypeLocator = new FakeTypeLocator(functions), // Pure in-memory, no storage. HostId = Guid.NewGuid().ToString("n"), DashboardConnectionString = null, StorageConnectionString = null }; IExtensionRegistry extensions = config.GetService <IExtensionRegistry>(); foreach (var obj in services) { IStorageAccount account = obj as IStorageAccount; if (account != null) { IStorageAccountProvider storageAccountProvider = new FakeStorageAccountProvider { StorageAccount = account }; config.ContextFactory = new JobHostContextFactory(storageAccountProvider, new DefaultConsoleProvider(), config); continue; } INameResolver nameResolver = obj as INameResolver; if (nameResolver != null) { config.NameResolver = nameResolver; continue; } IJobActivator jobActivator = obj as IJobActivator; if (jobActivator != null) { config.JobActivator = jobActivator; continue; } IExtensionConfigProvider extension = obj as IExtensionConfigProvider; if (extension != null) { extensions.RegisterExtension <IExtensionConfigProvider>(extension); continue; } throw new InvalidOperationException("Test bug: Unrecognized type: " + obj.GetType().FullName); } return(config); }
private static IServiceProvider CreateServiceProvider <TResult>(IStorageAccount storageAccount, Type programType, IExtensionTypeLocator extensionTypeLocator, IJobActivator activator, TaskCompletionSource <TResult> taskSource, IFunctionInstanceLogger functionInstanceLogger) { IStorageAccountProvider storageAccountProvider = new FakeStorageAccountProvider { StorageAccount = storageAccount }; IServiceBusAccountProvider serviceBusAccountProvider = new NullServiceBusAccountProvider(); IHostIdProvider hostIdProvider = new FakeHostIdProvider(); INameResolver nameResolver = null; IQueueConfiguration queueConfiguration = new FakeQueueConfiguration(); IBackgroundExceptionDispatcher backgroundExceptionDispatcher = new TaskBackgroundExceptionDispatcher <TResult>(taskSource); ContextAccessor <IMessageEnqueuedWatcher> messageEnqueuedWatcherAccessor = new ContextAccessor <IMessageEnqueuedWatcher>(); ContextAccessor <IBlobWrittenWatcher> blobWrittenWatcherAccessor = new ContextAccessor <IBlobWrittenWatcher>(); ISharedContextProvider sharedContextProvider = new SharedContextProvider(); ITriggerBindingProvider triggerBindingProvider = DefaultTriggerBindingProvider.Create(nameResolver, storageAccountProvider, serviceBusAccountProvider, extensionTypeLocator, hostIdProvider, queueConfiguration, backgroundExceptionDispatcher, messageEnqueuedWatcherAccessor, blobWrittenWatcherAccessor, sharedContextProvider, TextWriter.Null); IBindingProvider bindingProvider = DefaultBindingProvider.Create(nameResolver, storageAccountProvider, serviceBusAccountProvider, extensionTypeLocator, messageEnqueuedWatcherAccessor, blobWrittenWatcherAccessor); IJobHostContextFactory contextFactory = new FakeJobHostContextFactory { FunctionIndexProvider = new FunctionIndexProvider(new FakeTypeLocator(programType), triggerBindingProvider, bindingProvider, activator), StorageAccountProvider = storageAccountProvider, ServiceBusAccountProvider = serviceBusAccountProvider, BackgroundExceptionDispatcher = backgroundExceptionDispatcher, BindingProvider = bindingProvider, ConsoleProvider = new NullConsoleProvider(), HostInstanceLoggerProvider = new NullHostInstanceLoggerProvider(), FunctionInstanceLoggerProvider = new FakeFunctionInstanceLoggerProvider(functionInstanceLogger), FunctionOutputLoggerProvider = new NullFunctionOutputLoggerProvider(), HostIdProvider = hostIdProvider, QueueConfiguration = new FakeQueueConfiguration() }; return(new FakeServiceProvider { ContextFactory = contextFactory }); }
private JobHostConfiguration CreateConfig(bool addFactory = true) { IStorageAccountProvider accountProvider = new FakeStorageAccountProvider() { StorageAccount = new FakeStorageAccount() }; ILoggerFactory factory = new LoggerFactory(); factory.AddProvider(_loggerProvider); var config = new JobHostConfiguration(); config.AddService(accountProvider); config.TypeLocator = new FakeTypeLocator(new[] { typeof(ILoggerFunctions) }); config.AddService(factory); config.Aggregator.IsEnabled = false; // disable aggregator return(config); }
private static JobHostConfiguration CreateConfiguration <TResult>(IStorageAccount storageAccount, Type programType, IExtensionTypeLocator extensionTypeLocator, IJobActivator activator, TaskCompletionSource <TResult> taskSource, IFunctionInstanceLogger functionInstanceLogger, IExtensionRegistry extensions = null) { IStorageAccountProvider storageAccountProvider = new FakeStorageAccountProvider { StorageAccount = storageAccount }; IHostIdProvider hostIdProvider = new FakeHostIdProvider(); IWebJobsExceptionHandler exceptionHandler = new TaskBackgroundExceptionHandler <TResult>(taskSource); return(TestHelpers.NewConfig( programType, new FakeQueueConfiguration(storageAccountProvider), storageAccountProvider, extensionTypeLocator, activator, extensions, exceptionHandler, new NullFunctionInstanceLoggerProvider(functionInstanceLogger), new NullHostInstanceLoggerProvider(), new NullFunctionOutputLoggerProvider() )); }
public static void AddServices(this JobHostConfiguration config, params object[] services) { // Set extensionRegistry first since other services may depend on it. foreach (var obj in services) { IExtensionRegistry extensionRegistry = obj as IExtensionRegistry; if (extensionRegistry != null) { config.AddService <IExtensionRegistry>(extensionRegistry); break; } } IExtensionRegistry extensions = config.GetService <IExtensionRegistry>(); var types = new Type[] { typeof(IAsyncCollector <FunctionInstanceLogEntry>), typeof(IHostInstanceLoggerProvider), typeof(IFunctionInstanceLoggerProvider), typeof(IFunctionOutputLoggerProvider), typeof(IConsoleProvider), typeof(ITypeLocator), typeof(IWebJobsExceptionHandler), typeof(INameResolver), typeof(IJobActivator), typeof(IExtensionTypeLocator), typeof(SingletonManager), typeof(IHostIdProvider), typeof(IQueueConfiguration), typeof(IExtensionRegistry), typeof(IDistributedLockManager), typeof(ILoggerFactory), typeof(IFunctionIndexProvider) // set to unit test indexing. }; foreach (var obj in services) { if (obj == null || obj is ILoggerProvider) { continue; } IStorageAccountProvider storageAccountProvider = obj as IStorageAccountProvider; IStorageAccount account = obj as IStorageAccount; if (account != null) { storageAccountProvider = new FakeStorageAccountProvider { StorageAccount = account }; } if (storageAccountProvider != null) { config.AddService <IStorageAccountProvider>(storageAccountProvider); continue; } // A new extension IExtensionConfigProvider extension = obj as IExtensionConfigProvider; if (extension != null) { extensions.RegisterExtension <IExtensionConfigProvider>(extension); continue; } // A function filter if (obj is IFunctionInvocationFilter) { extensions.RegisterExtension <IFunctionInvocationFilter>((IFunctionInvocationFilter)obj); continue; } if (obj is IFunctionExceptionFilter) { extensions.RegisterExtension <IFunctionExceptionFilter>((IFunctionExceptionFilter)obj); continue; } // basic pattern. bool ok = false; foreach (var type in types) { if (type.IsAssignableFrom(obj.GetType())) { config.AddService(type, obj); ok = true; break; } } if (ok) { continue; } throw new InvalidOperationException("Test bug: Unrecognized type: " + obj.GetType().FullName); } }
private static IServiceProvider CreateServiceProvider <TResult>(IStorageAccount storageAccount, Type programType, IExtensionTypeLocator extensionTypeLocator, IJobActivator activator, TaskCompletionSource <TResult> taskSource, IFunctionInstanceLogger functionInstanceLogger, IExtensionRegistry extensions = null) { IStorageAccountProvider storageAccountProvider = new FakeStorageAccountProvider { StorageAccount = storageAccount }; IHostIdProvider hostIdProvider = new FakeHostIdProvider(); INameResolver nameResolver = null; IQueueConfiguration queueConfiguration = new FakeQueueConfiguration(storageAccountProvider); IBackgroundExceptionDispatcher backgroundExceptionDispatcher = new TaskBackgroundExceptionDispatcher <TResult>(taskSource); ContextAccessor <IMessageEnqueuedWatcher> messageEnqueuedWatcherAccessor = new ContextAccessor <IMessageEnqueuedWatcher>(); ContextAccessor <IBlobWrittenWatcher> blobWrittenWatcherAccessor = new ContextAccessor <IBlobWrittenWatcher>(); ISharedContextProvider sharedContextProvider = new SharedContextProvider(); if (extensions == null) { extensions = new DefaultExtensionRegistry(); } ITriggerBindingProvider triggerBindingProvider = DefaultTriggerBindingProvider.Create(nameResolver, storageAccountProvider, extensionTypeLocator, hostIdProvider, queueConfiguration, backgroundExceptionDispatcher, messageEnqueuedWatcherAccessor, blobWrittenWatcherAccessor, sharedContextProvider, extensions, TextWriter.Null); IBindingProvider bindingProvider = DefaultBindingProvider.Create(nameResolver, storageAccountProvider, extensionTypeLocator, messageEnqueuedWatcherAccessor, blobWrittenWatcherAccessor, extensions); IFunctionInstanceLoggerProvider functionInstanceLoggerProvider = new NullFunctionInstanceLoggerProvider(); IFunctionOutputLoggerProvider functionOutputLoggerProvider = new NullFunctionOutputLoggerProvider(); Task <IFunctionOutputLogger> task = functionOutputLoggerProvider.GetAsync(CancellationToken.None); task.Wait(); IFunctionOutputLogger functionOutputLogger = task.Result; FunctionExecutor executor = new FunctionExecutor(functionInstanceLogger, functionOutputLogger, backgroundExceptionDispatcher); ITypeLocator typeLocator = new FakeTypeLocator(programType); FunctionIndexProvider functionIndexProvider = new FunctionIndexProvider( typeLocator, triggerBindingProvider, bindingProvider, activator, executor, extensions); IJobHostContextFactory contextFactory = new FakeJobHostContextFactory { TypeLocator = typeLocator, FunctionIndexProvider = functionIndexProvider, StorageAccountProvider = storageAccountProvider, BackgroundExceptionDispatcher = backgroundExceptionDispatcher, BindingProvider = bindingProvider, ConsoleProvider = new NullConsoleProvider(), HostInstanceLoggerProvider = new NullHostInstanceLoggerProvider(), FunctionExecutor = executor, FunctionInstanceLoggerProvider = functionInstanceLoggerProvider, FunctionOutputLoggerProvider = functionOutputLoggerProvider, HostIdProvider = hostIdProvider, QueueConfiguration = queueConfiguration }; return(new FakeServiceProvider { ContextFactory = contextFactory }); }