public async Task GetExtensionsStartupTypes_ExtensionBundleReturnsNullPath_ReturnsNull() { var mockExtensionBundleManager = new Mock <IExtensionBundleManager>(); mockExtensionBundleManager.Setup(e => e.IsExtensionBundleConfigured()).Returns(true); mockExtensionBundleManager.Setup(e => e.GetExtensionBundlePath()).ReturnsAsync(string.Empty); using (var directory = new TempDirectory()) { TestLoggerProvider testLoggerProvider = new TestLoggerProvider(); LoggerFactory factory = new LoggerFactory(); factory.AddProvider(testLoggerProvider); var testLogger = factory.CreateLogger <ScriptStartupTypeLocator>(); var discoverer = new ScriptStartupTypeLocator(string.Empty, testLogger, mockExtensionBundleManager.Object); // Act var types = await discoverer.GetExtensionsStartupTypesAsync(); var traces = testLoggerProvider.GetAllLogMessages(); // Assert Assert.Null(types); Assert.True(traces.Any(m => string.Equals(m.FormattedMessage, $"Unable to find or download extension bundle"))); } }
public async Task GetExtensionsStartupTypes_RejectsBundleBelowMinimumVersion() { using (var directory = GetTempDirectory()) { TestMetricsLogger testMetricsLogger = new TestMetricsLogger(); TestLoggerProvider testLoggerProvider = new TestLoggerProvider(); LoggerFactory factory = new LoggerFactory(); factory.AddProvider(testLoggerProvider); var testLogger = factory.CreateLogger <ScriptStartupTypeLocator>(); var binPath = Path.Combine(directory.Path, "bin"); var mockExtensionBundleManager = new Mock <IExtensionBundleManager>(); mockExtensionBundleManager.Setup(e => e.IsExtensionBundleConfigured()).Returns(true); mockExtensionBundleManager.Setup(e => e.GetExtensionBundleBinPathAsync()).Returns(Task.FromResult(binPath)); mockExtensionBundleManager.Setup(e => e.IsLegacyExtensionBundle()).Returns(false); mockExtensionBundleManager.Setup(e => e.GetExtensionBundleDetails()).Returns(Task.FromResult(GetV2BundleDetails("2.1.0"))); var mockFunctionMetadataManager = GetTestFunctionMetadataManager(); var languageWorkerOptions = new OptionsWrapper <LanguageWorkerOptions>(new LanguageWorkerOptions()); var discoverer = new ScriptStartupTypeLocator(directory.Path, testLogger, mockExtensionBundleManager.Object, mockFunctionMetadataManager, testMetricsLogger, languageWorkerOptions); // Act var exception = await Assert.ThrowsAsync <HostInitializationException>(async() => await discoverer.GetExtensionsStartupTypesAsync()); var traces = testLoggerProvider.GetAllLogMessages(); // Assert Assert.True(traces.Any(m => string.Equals(m.FormattedMessage, $"Referenced bundle Microsoft.Azure.Functions.ExtensionBundle of version 2.1.0 does not meet the required minimum version of 2.6.1. Update your extension bundle reference in host.json to reference 2.6.1 or later."))); } }
public async Task GetExtensionsStartupTypes_NonLegacyBundles_UsesBundlesForNonPrecompiledFunctions(bool hasPrecompiledFunctions) { using (var directory = GetTempDirectory()) { TestMetricsLogger testMetricsLogger = new TestMetricsLogger(); var testLogger = GetTestLogger(); string bundlePath = hasPrecompiledFunctions ? "FakePath" : directory.Path; var binPath = Path.Combine(directory.Path, "bin"); var mockExtensionBundleManager = new Mock <IExtensionBundleManager>(); mockExtensionBundleManager.Setup(e => e.IsExtensionBundleConfigured()).Returns(true); mockExtensionBundleManager.Setup(e => e.GetExtensionBundleBinPathAsync()).Returns(Task.FromResult(binPath)); mockExtensionBundleManager.Setup(e => e.IsLegacyExtensionBundle()).Returns(false); var mockFunctionMetadataManager = GetTestFunctionMetadataManager(hasPrecompiledFunction: hasPrecompiledFunctions); var discoverer = new ScriptStartupTypeLocator(directory.Path, testLogger, mockExtensionBundleManager.Object, mockFunctionMetadataManager, testMetricsLogger); // Act var types = await discoverer.GetExtensionsStartupTypesAsync(); //Assert AreExpectedMetricsGenerated(testMetricsLogger); Assert.Single(types); Assert.Equal(typeof(AzureStorageWebJobsStartup).FullName, types.Single().FullName); } }
public async Task GetExtensionsStartupTypes_UnableToDownloadExtensionBundle_ReturnsNull() { var mockExtensionBundleManager = new Mock <IExtensionBundleManager>(); mockExtensionBundleManager.Setup(e => e.IsExtensionBundleConfigured()).Returns(true); mockExtensionBundleManager.Setup(e => e.GetExtensionBundlePath()).ReturnsAsync(string.Empty); TestLoggerProvider testLoggerProvider = new TestLoggerProvider(); LoggerFactory factory = new LoggerFactory(); TestMetricsLogger testMetricsLogger = new TestMetricsLogger(); factory.AddProvider(testLoggerProvider); var testLogger = factory.CreateLogger <ScriptStartupTypeLocator>(); var mockFunctionMetadataManager = GetTestFunctionMetadataManager(ImmutableArray <FunctionMetadata> .Empty); var discoverer = new ScriptStartupTypeLocator(string.Empty, testLogger, mockExtensionBundleManager.Object, mockFunctionMetadataManager, testMetricsLogger); // Act var types = await discoverer.GetExtensionsStartupTypesAsync(); var traces = testLoggerProvider.GetAllLogMessages(); // Assert Assert.True(traces.Any(m => string.Equals(m.FormattedMessage, $"Unable to find or download extension bundle"))); AreExpectedMetricsGenerated(testMetricsLogger); Assert.NotNull(types); Assert.Equal(types.Count(), 0); }
public async Task GetExtensionsStartupTypes_FiltersBuiltinExtensionsAsync() { var references = new[] { new ExtensionReference { Name = "Http", TypeName = typeof(HttpWebJobsStartup).AssemblyQualifiedName }, new ExtensionReference { Name = "Timers", TypeName = typeof(ExtensionsWebJobsStartup).AssemblyQualifiedName }, new ExtensionReference { Name = "Storage", TypeName = typeof(AzureStorageWebJobsStartup).AssemblyQualifiedName }, }; var extensions = new JObject { { "extensions", JArray.FromObject(references) } }; var mockExtensionBundleManager = new Mock <IExtensionBundleManager>(); mockExtensionBundleManager.Setup(e => e.IsExtensionBundleConfigured()).Returns(false); using (var directory = new TempDirectory()) { var binPath = Path.Combine(directory.Path, "bin"); Directory.CreateDirectory(binPath); void CopyToBin(string path) { File.Copy(path, Path.Combine(binPath, Path.GetFileName(path))); } CopyToBin(typeof(HttpWebJobsStartup).Assembly.Location); CopyToBin(typeof(ExtensionsWebJobsStartup).Assembly.Location); CopyToBin(typeof(AzureStorageWebJobsStartup).Assembly.Location); File.WriteAllText(Path.Combine(binPath, "extensions.json"), extensions.ToString()); TestLoggerProvider testLoggerProvider = new TestLoggerProvider(); LoggerFactory factory = new LoggerFactory(); factory.AddProvider(testLoggerProvider); var testLogger = factory.CreateLogger <ScriptStartupTypeLocator>(); var mockFunctionMetadataProvider = GetTestFunctionMetadataProvider(ImmutableArray <FunctionMetadata> .Empty); var discoverer = new ScriptStartupTypeLocator(directory.Path, testLogger, mockExtensionBundleManager.Object, mockFunctionMetadataProvider); // Act var types = await discoverer.GetExtensionsStartupTypesAsync(); var traces = testLoggerProvider.GetAllLogMessages(); // Assert Assert.Single(types); Assert.Equal(typeof(AzureStorageWebJobsStartup).FullName, types.Single().FullName); Assert.True(traces.Any(m => string.Equals(m.FormattedMessage, $"The extension startup type '{references[0].TypeName}' belongs to a builtin extension"))); Assert.True(traces.Any(m => string.Equals(m.FormattedMessage, $"The extension startup type '{references[1].TypeName}' belongs to a builtin extension"))); } }
public async Task GetExtensionsStartupTypes_LegacyBundles_UsesExtensionBundleBinaries(bool hasPrecompiledFunctions) { using (var directory = GetTempDirectory()) { var binPath = Path.Combine(directory.Path, "bin"); TestMetricsLogger testMetricsLogger = new TestMetricsLogger(); var testLogger = GetTestLogger(); var mockExtensionBundleManager = new Mock <IExtensionBundleManager>(); mockExtensionBundleManager.Setup(e => e.IsExtensionBundleConfigured()).Returns(true); mockExtensionBundleManager.Setup(e => e.GetExtensionBundleBinPathAsync()).Returns(Task.FromResult(binPath)); mockExtensionBundleManager.Setup(e => e.IsLegacyExtensionBundle()).Returns(true); mockExtensionBundleManager.Setup(e => e.GetExtensionBundleDetails()).Returns(Task.FromResult(GetV2BundleDetails())); var mockFunctionMetadataManager = GetTestFunctionMetadataManager(hasPrecompiledFunction: hasPrecompiledFunctions); var languageWorkerOptions = new OptionsWrapper <LanguageWorkerOptions>(new LanguageWorkerOptions()); var discoverer = new ScriptStartupTypeLocator(directory.Path, testLogger, mockExtensionBundleManager.Object, mockFunctionMetadataManager, testMetricsLogger, languageWorkerOptions); // Act var types = await discoverer.GetExtensionsStartupTypesAsync(); //Assert AreExpectedMetricsGenerated(testMetricsLogger); Assert.Single(types); Assert.Equal(typeof(AzureStorageWebJobsStartup).FullName, types.Single().FullName); } }
private static IServiceCollection AddScriptStartupTypeLocator(this IServiceCollection services) { var mockExtensionBundleManager = new Mock <IExtensionBundleManager>(); mockExtensionBundleManager.Setup(e => e.IsExtensionBundleConfigured()).Returns(false); var scriptStartupTypeLocator = new ScriptStartupTypeLocator(string.Empty, null, mockExtensionBundleManager.Object); return(services.AddSingleton(scriptStartupTypeLocator)); }
public async Task GetExtensionsStartupTypes_BundlesConfiguredBindingsConfigured_PerformsSelectiveLoading() { var storageExtensionReference = new ExtensionReference { Name = "Storage", TypeName = typeof(AzureStorageWebJobsStartup).AssemblyQualifiedName }; storageExtensionReference.Bindings.Add("blob"); var sendGridExtensionReference = new ExtensionReference { Name = "SendGrid", TypeName = typeof(AzureStorageWebJobsStartup).AssemblyQualifiedName }; sendGridExtensionReference.Bindings.Add("sendGrid"); var references = new[] { storageExtensionReference, sendGridExtensionReference }; TestMetricsLogger testMetricsLogger = new TestMetricsLogger(); var extensions = new JObject { { "extensions", JArray.FromObject(references) } }; using (var directory = new TempDirectory()) { var binPath = Path.Combine(directory.Path, "bin"); Directory.CreateDirectory(binPath); void CopyToBin(string path) { File.Copy(path, Path.Combine(binPath, Path.GetFileName(path))); } CopyToBin(typeof(AzureStorageWebJobsStartup).Assembly.Location); File.WriteAllText(Path.Combine(binPath, "extensions.json"), extensions.ToString()); TestLoggerProvider testLoggerProvider = new TestLoggerProvider(); LoggerFactory factory = new LoggerFactory(); factory.AddProvider(testLoggerProvider); var testLogger = factory.CreateLogger <ScriptStartupTypeLocator>(); var mockFunctionMetadataManager = GetTestFunctionMetadataManager(); var mockExtensionBundleManager = new Mock <IExtensionBundleManager>(); mockExtensionBundleManager.Setup(e => e.IsExtensionBundleConfigured()).Returns(true); mockExtensionBundleManager.Setup(e => e.GetExtensionBundleBinPathAsync()).Returns(Task.FromResult(binPath)); mockExtensionBundleManager.Setup(e => e.GetExtensionBundleDetails()).Returns(Task.FromResult(GetV2BundleDetails())); var languageWorkerOptions = new OptionsWrapper <LanguageWorkerOptions>(new LanguageWorkerOptions()); var discoverer = new ScriptStartupTypeLocator(directory.Path, testLogger, mockExtensionBundleManager.Object, mockFunctionMetadataManager, testMetricsLogger, languageWorkerOptions); // Act var types = await discoverer.GetExtensionsStartupTypesAsync(); //Assert AreExpectedMetricsGenerated(testMetricsLogger); Assert.Single(types); Assert.Equal(typeof(AzureStorageWebJobsStartup).FullName, types.Single().FullName); } }
public async Task GetExtensionsStartupTypes_BundlesNotConfiguredBindingsNotConfigured_LoadsAllExtensions() { var references = new[] { new ExtensionReference { Name = "Storage", TypeName = typeof(AzureStorageWebJobsStartup).AssemblyQualifiedName } }; var extensions = new JObject { { "extensions", JArray.FromObject(references) } }; var mockExtensionBundleManager = new Mock <IExtensionBundleManager>(); TestMetricsLogger testMetricsLogger = new TestMetricsLogger(); mockExtensionBundleManager.Setup(e => e.IsExtensionBundleConfigured()).Returns(false); using (var directory = new TempDirectory()) { var binPath = Path.Combine(directory.Path, "bin"); Directory.CreateDirectory(binPath); void CopyToBin(string path) { File.Copy(path, Path.Combine(binPath, Path.GetFileName(path))); } CopyToBin(typeof(AzureStorageWebJobsStartup).Assembly.Location); File.WriteAllText(Path.Combine(binPath, "extensions.json"), extensions.ToString()); TestLoggerProvider testLoggerProvider = new TestLoggerProvider(); LoggerFactory factory = new LoggerFactory(); factory.AddProvider(testLoggerProvider); var testLogger = factory.CreateLogger <ScriptStartupTypeLocator>(); // mock Function metadata var mockFunctionMetadataManager = GetTestFunctionMetadataManager(ImmutableArray <FunctionMetadata> .Empty); var discoverer = new ScriptStartupTypeLocator(directory.Path, testLogger, mockExtensionBundleManager.Object, mockFunctionMetadataManager, testMetricsLogger); // Act var types = await discoverer.GetExtensionsStartupTypesAsync(); // Assert AreExpectedMetricsGenerated(testMetricsLogger); Assert.Single(types); Assert.Equal(typeof(AzureStorageWebJobsStartup).FullName, types.Single().FullName); } }
public async Task GetExtensionsStartupTypes_BundlesNotConfiguredBindingsConfigured_LoadsAllExtensions() { var storageExtensionReference = new ExtensionReference { Name = "Storage", TypeName = typeof(AzureStorageWebJobsStartup).AssemblyQualifiedName }; storageExtensionReference.Bindings.Add("blob"); var sendGridExtensionReference = new ExtensionReference { Name = "SendGrid", TypeName = typeof(AzureStorageWebJobsStartup).AssemblyQualifiedName }; sendGridExtensionReference.Bindings.Add("sendGrid"); var references = new[] { storageExtensionReference, sendGridExtensionReference }; var extensions = new JObject { { "extensions", JArray.FromObject(references) } }; using (var directory = new TempDirectory()) { var binPath = Path.Combine(directory.Path, "bin"); Directory.CreateDirectory(binPath); void CopyToBin(string path) { File.Copy(path, Path.Combine(binPath, Path.GetFileName(path))); } CopyToBin(typeof(AzureStorageWebJobsStartup).Assembly.Location); File.WriteAllText(Path.Combine(binPath, "extensions.json"), extensions.ToString()); TestLoggerProvider testLoggerProvider = new TestLoggerProvider(); LoggerFactory factory = new LoggerFactory(); factory.AddProvider(testLoggerProvider); var testLogger = factory.CreateLogger <ScriptStartupTypeLocator>(); var mockExtensionBundleManager = new Mock <IExtensionBundleManager>(); mockExtensionBundleManager.Setup(e => e.IsExtensionBundleConfigured()).Returns(false); var mockFunctionMetadataProvider = GetTestFunctionMetadataProvider(); var discoverer = new ScriptStartupTypeLocator(directory.Path, testLogger, mockExtensionBundleManager.Object, mockFunctionMetadataProvider); // Act var types = await discoverer.GetExtensionsStartupTypesAsync(); Assert.Equal(types.Count(), 2); Assert.Equal(typeof(AzureStorageWebJobsStartup).FullName, types.FirstOrDefault().FullName); } }
public void GetExtensionsStartupTypes_FiltersBuiltinExtensions() { var references = new[] { new ExtensionReference { Name = "Http", TypeName = typeof(HttpWebJobsStartup).AssemblyQualifiedName }, new ExtensionReference { Name = "Timers", TypeName = typeof(ExtensionsWebJobsStartup).AssemblyQualifiedName }, new ExtensionReference { Name = "Storage", TypeName = typeof(AzureStorageWebJobsStartup).AssemblyQualifiedName }, }; var extensions = new JObject { { "extensions", JArray.FromObject(references) } }; using (var directory = new TempDirectory()) { var binPath = Path.Combine(directory.Path, "bin"); Directory.CreateDirectory(binPath); void CopyToBin(string path) { File.Copy(path, Path.Combine(binPath, Path.GetFileName(path))); } CopyToBin(typeof(HttpWebJobsStartup).Assembly.Location); CopyToBin(typeof(ExtensionsWebJobsStartup).Assembly.Location); CopyToBin(typeof(AzureStorageWebJobsStartup).Assembly.Location); File.WriteAllText(Path.Combine(binPath, "extensions.json"), extensions.ToString()); var testLogger = new TestLogger("test"); var discoverer = new ScriptStartupTypeLocator(directory.Path, testLogger); // Act var types = discoverer.GetExtensionsStartupTypes(); var traces = testLogger.GetLogMessages(); // Assert Assert.Single(types); Assert.Equal(typeof(AzureStorageWebJobsStartup).FullName, types.Single().FullName); Assert.True(traces.Any(m => string.Equals(m.FormattedMessage, $"The extension startup type '{references[0].TypeName}' belongs to a builtin extension"))); Assert.True(traces.Any(m => string.Equals(m.FormattedMessage, $"The extension startup type '{references[1].TypeName}' belongs to a builtin extension"))); } }
public async Task GetExtensionsStartupTypes_RejectsExtensionsBelowMinimumVersion() { var mockExtensionBundleManager = new Mock <IExtensionBundleManager>(); TestMetricsLogger testMetricsLogger = new TestMetricsLogger(); mockExtensionBundleManager.Setup(e => e.IsExtensionBundleConfigured()).Returns(false); using (var directory = new TempDirectory()) { var binPath = Path.Combine(directory.Path, "bin"); Directory.CreateDirectory(binPath); void CopyToBin(string path) { File.Copy(path, Path.Combine(binPath, Path.GetFileName(path))); } // create a bin folder that has out of date extensions var extensionBinPath = Path.Combine(Environment.CurrentDirectory, @"TestScripts\OutOfDateExtension\bin"); foreach (var f in Directory.GetFiles(extensionBinPath)) { CopyToBin(f); } TestLoggerProvider testLoggerProvider = new TestLoggerProvider(); LoggerFactory factory = new LoggerFactory(); factory.AddProvider(testLoggerProvider); var testLogger = factory.CreateLogger <ScriptStartupTypeLocator>(); var mockFunctionMetadataManager = GetTestFunctionMetadataManager(ImmutableArray <FunctionMetadata> .Empty); var languageWorkerOptions = new OptionsWrapper <LanguageWorkerOptions>(new LanguageWorkerOptions()); var discoverer = new ScriptStartupTypeLocator(directory.Path, testLogger, mockExtensionBundleManager.Object, mockFunctionMetadataManager, testMetricsLogger, languageWorkerOptions); // Act var exception = await Assert.ThrowsAsync <HostInitializationException>(async() => await discoverer.GetExtensionsStartupTypesAsync()); var traces = testLoggerProvider.GetAllLogMessages(); // Assert var storageTrace = traces.FirstOrDefault(m => m.FormattedMessage.StartsWith("ExtensionStartupType AzureStorageWebJobsStartup")); Assert.NotNull(storageTrace); Assert.Equal("ExtensionStartupType AzureStorageWebJobsStartup from assembly 'Microsoft.Azure.WebJobs.Extensions.Storage, Version=3.0.10.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' does not meet the required minimum version of 4.0.4.0. Update your NuGet package reference for Microsoft.Azure.WebJobs.Extensions.Storage to 4.0.4 or later.", storageTrace.FormattedMessage); } }
public async Task GetExtensionsStartupTypes_UnableToDownloadExtensionBundle_ReturnsNull() { var mockExtensionBundleManager = new Mock <IExtensionBundleManager>(); mockExtensionBundleManager.Setup(e => e.IsExtensionBundleConfigured()).Returns(true); mockExtensionBundleManager.Setup(e => e.GetExtensionBundlePath()).ReturnsAsync(string.Empty); var testLogger = new TestLogger("test"); var discoverer = new ScriptStartupTypeLocator(string.Empty, testLogger, mockExtensionBundleManager.Object); // Act var types = await discoverer.GetExtensionsStartupTypesAsync(); var traces = testLogger.GetLogMessages(); // Assert Assert.True(traces.Any(m => string.Equals(m.FormattedMessage, $"Unable to find or download extension bundle"))); Assert.Null(types); }
public static IHostBuilder AddScriptHost(this IHostBuilder builder, ScriptApplicationHostOptions applicationOptions, ILoggerFactory loggerFactory, IMetricsLogger metricsLogger, Action <IWebJobsBuilder> configureWebJobs = null) { loggerFactory = loggerFactory ?? NullLoggerFactory.Instance; builder.SetAzureFunctionsConfigurationRoot(); // Host configuration builder.ConfigureLogging((context, loggingBuilder) => { loggingBuilder.AddDefaultWebJobsFilters(); string loggingPath = ConfigurationPath.Combine(ConfigurationSectionNames.JobHost, "Logging"); loggingBuilder.AddConfiguration(context.Configuration.GetSection(loggingPath)); loggingBuilder.Services.AddSingleton <IFileWriterFactory, DefaultFileWriterFactory>(); loggingBuilder.Services.AddSingleton <ILoggerProvider, HostFileLoggerProvider>(); loggingBuilder.Services.AddSingleton <ILoggerProvider, FunctionFileLoggerProvider>(); loggingBuilder.AddConsoleIfEnabled(context); ConfigureApplicationInsights(context, loggingBuilder); }) .ConfigureAppConfiguration((context, configBuilder) => { if (!context.Properties.ContainsKey(ScriptConstants.SkipHostJsonConfigurationKey)) { configBuilder.Add(new HostJsonFileConfigurationSource(applicationOptions, SystemEnvironment.Instance, loggerFactory, metricsLogger)); } }); // WebJobs configuration builder.AddScriptHostCore(applicationOptions, configureWebJobs, loggerFactory); // Allow FunctionsStartup to add configuration after all other configuration is registered. builder.ConfigureAppConfiguration((context, configBuilder) => { // Pre-build configuration here to load bundles and to store for later validation. var config = configBuilder.Build(); var extensionBundleOptions = GetExtensionBundleOptions(config); var bundleManager = new ExtensionBundleManager(extensionBundleOptions, SystemEnvironment.Instance, loggerFactory); var metadataServiceManager = applicationOptions.RootServiceProvider.GetService <IFunctionMetadataManager>(); var languageWorkerOptions = applicationOptions.RootServiceProvider.GetService <IOptions <LanguageWorkerOptions> >(); var locator = new ScriptStartupTypeLocator(applicationOptions.ScriptPath, loggerFactory.CreateLogger <ScriptStartupTypeLocator>(), bundleManager, metadataServiceManager, metricsLogger, languageWorkerOptions); // The locator (and thus the bundle manager) need to be created now in order to configure app configuration. // Store them so they do not need to be re-created later when configuring services. context.Properties[BundleManagerKey] = bundleManager; context.Properties[StartupTypeLocatorKey] = locator; // If we're skipping host initialization, this key will not exist and this will also be skipped. if (context.Properties.TryGetValue(DelayedConfigurationActionKey, out object actionObject) && actionObject is Action <IWebJobsStartupTypeLocator> delayedConfigAction) { context.Properties.Remove(DelayedConfigurationActionKey); delayedConfigAction(locator); // store the snapshot for validation later, but only if there // are any registered external configuration startups. if (locator.HasExternalConfigurationStartups()) { context.Properties[ConfigurationSnapshotKey] = config; } } }); return(builder); }
public async Task GetExtensionsStartupTypes_WorkerIndexing_BypassesSelectiveLoading() { var storageExtensionReference = new ExtensionReference { Name = "Storage", TypeName = typeof(AzureStorageWebJobsStartup).AssemblyQualifiedName }; storageExtensionReference.Bindings.Add("blob"); var sendGridExtensionReference = new ExtensionReference { Name = "SendGrid", TypeName = typeof(AzureStorageWebJobsStartup).AssemblyQualifiedName }; sendGridExtensionReference.Bindings.Add("sendGrid"); var references = new[] { storageExtensionReference, sendGridExtensionReference }; TestMetricsLogger testMetricsLogger = new TestMetricsLogger(); var extensions = new JObject { { "extensions", JArray.FromObject(references) } }; using (var directory = new TempDirectory()) { var binPath = Path.Combine(directory.Path, "bin"); Directory.CreateDirectory(binPath); void CopyToBin(string path) { File.Copy(path, Path.Combine(binPath, Path.GetFileName(path))); } CopyToBin(typeof(AzureStorageWebJobsStartup).Assembly.Location); File.WriteAllText(Path.Combine(binPath, "extensions.json"), extensions.ToString()); TestLoggerProvider testLoggerProvider = new TestLoggerProvider(); LoggerFactory factory = new LoggerFactory(); factory.AddProvider(testLoggerProvider); var testLogger = factory.CreateLogger <ScriptStartupTypeLocator>(); var mockFunctionMetadataManager = GetTestFunctionMetadataManager(); var mockExtensionBundleManager = new Mock <IExtensionBundleManager>(); mockExtensionBundleManager.Setup(e => e.IsExtensionBundleConfigured()).Returns(true); mockExtensionBundleManager.Setup(e => e.GetExtensionBundleBinPathAsync()).Returns(Task.FromResult(binPath)); // mock worker config and environment variables to make host choose worker indexing RpcWorkerConfig workerConfig = new RpcWorkerConfig() { Description = TestHelpers.GetTestWorkerDescription("python", "none", true) }; var tempOptions = new LanguageWorkerOptions(); tempOptions.WorkerConfigs = new List <RpcWorkerConfig>(); tempOptions.WorkerConfigs.Add(workerConfig); var languageWorkerOptions = new OptionsWrapper <LanguageWorkerOptions>(tempOptions); Environment.SetEnvironmentVariable(EnvironmentSettingNames.AzureWebJobsFeatureFlags, ScriptConstants.FeatureFlagEnableWorkerIndexing); Environment.SetEnvironmentVariable(EnvironmentSettingNames.FunctionWorkerRuntime, "python"); var discoverer = new ScriptStartupTypeLocator(directory.Path, testLogger, mockExtensionBundleManager.Object, mockFunctionMetadataManager, testMetricsLogger, languageWorkerOptions); // Act var types = await discoverer.GetExtensionsStartupTypesAsync(); Environment.SetEnvironmentVariable(EnvironmentSettingNames.AzureWebJobsFeatureFlags, null); Environment.SetEnvironmentVariable(EnvironmentSettingNames.FunctionWorkerRuntime, null); //Assert that filtering did not take place because of worker indexing Assert.True(types.Count() == 2); Assert.Equal(typeof(AzureStorageWebJobsStartup).FullName, types.ElementAt(0).FullName); Assert.Equal(typeof(AzureStorageWebJobsStartup).FullName, types.ElementAt(1).FullName); } }