public async Task ProcessDefaultInvocationRequest_CustomHandler_EnableRequestForwarding_False() { var handlerMock = new Mock <HttpMessageHandler>(MockBehavior.Strict); var customHandlerOptions = new HttpWorkerOptions() { Port = _defaultPort, Type = CustomHandlerType.Http }; handlerMock.Protected().Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>()) .Callback <HttpRequestMessage, CancellationToken>((request, token) => ValidateeSimpleHttpTriggerSentAsDefaultInvocationRequest(request)) .ReturnsAsync(HttpWorkerTestUtilities.GetValidHttpResponseMessageWithJsonRes()); _httpClient = new HttpClient(handlerMock.Object); _defaultHttpWorkerService = new DefaultHttpWorkerService(_httpClient, new OptionsWrapper <HttpWorkerOptions>(customHandlerOptions), _testLogger, _testEnvironment); var testScriptInvocationContext = HttpWorkerTestUtilities.GetSimpleHttpTriggerScriptInvocationContext(TestFunctionName, _testInvocationId, _functionLogger); await _defaultHttpWorkerService.InvokeAsync(testScriptInvocationContext); var invocationResult = await testScriptInvocationContext.ResultSource.Task; var expectedHttpScriptInvocationResult = HttpWorkerTestUtilities.GetHttpScriptInvocationResultWithJsonRes(); var testLogs = _functionLogger.GetLogMessages(); Assert.True(testLogs.Count() == expectedHttpScriptInvocationResult.Logs.Count()); Assert.True(testLogs.All(m => m.FormattedMessage.Contains("invocation log"))); Assert.Equal(expectedHttpScriptInvocationResult.Outputs.Count(), invocationResult.Outputs.Count()); Assert.Equal(expectedHttpScriptInvocationResult.ReturnValue, invocationResult.Return); var responseJson = JObject.Parse(invocationResult.Outputs["res"].ToString()); Assert.Equal("my world", responseJson["Body"]); Assert.Equal("201", responseJson["StatusCode"]); }
public void CustomHandlerConfig_ExpandEnvVars() { string hostJsonContent = @"{ 'version': '2.0', 'customHandler': { 'description': { 'defaultExecutablePath': '%TestEnv%', 'defaultWorkerPath': '%TestEnv%' } } }"; try { Environment.SetEnvironmentVariable("TestEnv", "TestVal"); File.WriteAllText(_hostJsonFile, hostJsonContent); var configuration = BuildHostJsonConfiguration(); HttpWorkerOptionsSetup setup = new HttpWorkerOptionsSetup(new OptionsWrapper <ScriptJobHostOptions>(_scriptJobHostOptions), configuration, _testLoggerFactory, _metricsLogger); HttpWorkerOptions options = new HttpWorkerOptions(); setup.Configure(options); Assert.Equal("TestVal", options.Description.DefaultExecutablePath); Assert.Contains("TestVal", options.Description.DefaultWorkerPath); } finally { Environment.SetEnvironmentVariable("TestEnv", string.Empty); } }
public HttpWorkerChannelFactory(IEnvironment environment, ILoggerFactory loggerFactory, IOptions <HttpWorkerOptions> httpInvokerOptions, IOptionsMonitor <ScriptApplicationHostOptions> applicationHostOptions, IHttpWorkerProcessFactory httpInvokerProcessFactory, IHttpInvokerService httpInvokerService) { _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); _httpInvokerOptions = httpInvokerOptions.Value ?? throw new ArgumentNullException(nameof(httpInvokerOptions.Value)); _httpInvokerProcessFactory = httpInvokerProcessFactory ?? throw new ArgumentNullException(nameof(httpInvokerProcessFactory)); _httpInvokerService = httpInvokerService ?? throw new ArgumentNullException(nameof(httpInvokerService)); }
public FunctionMetadataManagerTests() { _mockFunctionMetadataProvider = new Mock <IFunctionMetadataProvider>(); string functionsPath = Path.Combine(Environment.CurrentDirectory, @"..\..\..\..\..\sample\node"); _defaultHttpWorkerOptions = new HttpWorkerOptions(); _scriptJobHostOptions.RootScriptPath = functionsPath; _testFunctionMetadataManager = new FunctionMetadataManager(new OptionsWrapper <ScriptJobHostOptions>(_scriptJobHostOptions), _mockFunctionMetadataProvider.Object, new OptionsWrapper <LanguageWorkerOptions>(GetTestLanguageWorkerOptions()), new OptionsWrapper <HttpWorkerOptions>(_defaultHttpWorkerOptions), MockNullLoggerFactory.CreateLoggerFactory()); }
public DefaultHttpWorkerServiceTests() { _testLoggerFactory = new LoggerFactory(); _testInvocationId = Guid.NewGuid(); _httpWorkerOptions = new HttpWorkerOptions() { Port = _defaultPort }; }
public DefaultHttpWorkerServiceTests() { _testLoggerFactory = new LoggerFactory(); _testInvocationId = Guid.NewGuid(); _httpWorkerOptions = new HttpWorkerOptions() { Port = _defaultPort, Type = CustomHandlerType.None }; }
public void TestBuildAndGetUri(string pathValue, string expectedUriString) { HttpWorkerOptions testOptions = new HttpWorkerOptions { Port = 8080, }; DefaultHttpWorkerService defaultHttpWorkerService = new DefaultHttpWorkerService(new HttpClient(), new OptionsWrapper <HttpWorkerOptions>(testOptions), _testLogger, _testEnvironment, new OptionsWrapper <ScriptJobHostOptions>(_scriptJobHostOptions)); Assert.Equal(expectedUriString, defaultHttpWorkerService.BuildAndGetUri(pathValue)); }
public void AddHeadersTest() { HttpWorkerOptions testOptions = new HttpWorkerOptions(); DefaultHttpWorkerService defaultHttpWorkerService = new DefaultHttpWorkerService(new HttpClient(), new OptionsWrapper <HttpWorkerOptions>(testOptions), _testLogger, _testEnvironment, new OptionsWrapper <ScriptJobHostOptions>(_scriptJobHostOptions)); HttpRequestMessage input = new HttpRequestMessage(); string invocationId = Guid.NewGuid().ToString(); defaultHttpWorkerService.AddHeaders(input, invocationId); Assert.Equal(input.Headers.GetValues(HttpWorkerConstants.HostVersionHeaderName).FirstOrDefault(), ScriptHost.Version); Assert.Equal(input.Headers.GetValues(HttpWorkerConstants.InvocationIdHeaderName).FirstOrDefault(), invocationId); }
public HttpWorkerProcessTests() { _httpWorkerOptions = new HttpWorkerOptions() { Port = _workerPort, Arguments = new WorkerProcessArguments() { ExecutablePath = "test" } }; _settingsManager = ScriptSettingsManager.Instance; }
public void TestPathValue(string functionName, CustomHandlerType type, bool enableForwardingHttpRequest, string expectedValue, string hostValue = "localhost") { HttpRequest testHttpRequest = HttpWorkerTestUtilities.GetTestHttpRequest(hostValue); HttpWorkerOptions testOptions = new HttpWorkerOptions { Type = type, EnableForwardingHttpRequest = enableForwardingHttpRequest, }; DefaultHttpWorkerService defaultHttpWorkerService = new DefaultHttpWorkerService(new HttpClient(), new OptionsWrapper <HttpWorkerOptions>(testOptions), _testLogger, _testEnvironment, new OptionsWrapper <ScriptJobHostOptions>(_scriptJobHostOptions)); string actualValue = defaultHttpWorkerService.GetPathValue(testOptions, functionName, testHttpRequest); Assert.Equal(actualValue, expectedValue); }
public DefaultHttpWorkerServiceTests() { _testLoggerFactory = new LoggerFactory(); _testEnvironment = new TestEnvironment(); _testInvocationId = Guid.NewGuid(); _httpWorkerOptions = new HttpWorkerOptions() { Port = _defaultPort, Type = CustomHandlerType.None }; _scriptJobHostOptions = new ScriptJobHostOptions() { FunctionTimeout = TimeSpan.FromMinutes(15) }; }
public void MissingOrValid_HttpInvokerConfig_DoesNotThrowException(string hostJsonContent) { File.WriteAllText(_hostJsonFile, hostJsonContent); var configuration = BuildHostJsonConfiguration(); HttpWorkerOptionsSetup setup = new HttpWorkerOptionsSetup(configuration, _testLoggerFactory); HttpWorkerOptions options = new HttpWorkerOptions(); var ex = Record.Exception(() => setup.Configure(options)); Assert.Null(ex); if (options.Description != null && !string.IsNullOrEmpty(options.Description.DefaultExecutablePath)) { string expectedDefaultExecutablePath = Path.Combine(Directory.GetCurrentDirectory(), "testExe"); Assert.Equal(expectedDefaultExecutablePath, options.Description.DefaultExecutablePath); } }
public HttpWorkerProcessTests() { _httpWorkerOptions = new HttpWorkerOptions() { Port = _workerPort, Arguments = new WorkerProcessArguments() { ExecutablePath = "test" }, Description = new HttpWorkerDescription() { WorkingDirectory = @"c:\testDir" } }; _settingsManager = ScriptSettingsManager.Instance; }
public HttpWorkerProcessTests() { _httpWorkerOptions = new HttpWorkerOptions() { Port = _workerPort, Arguments = new WorkerProcessArguments() { ExecutablePath = "test" }, Description = new HttpWorkerDescription() { WorkingDirectory = @"c:\testDir" } }; _settingsManager = ScriptSettingsManager.Instance; _serviceProviderMock = new Mock <IServiceProvider>(MockBehavior.Strict); }
public void CustomHandler_Config_ExpectedValues_WorkerDirectory_WorkingDirectory(string hostJsonContent, bool appendCurrentDirToDefaultExe, bool appendCurrentDirToWorkingDir, bool appendCurrentDirToWorkerDir) { File.WriteAllText(_hostJsonFile, hostJsonContent); var configuration = BuildHostJsonConfiguration(); HttpWorkerOptionsSetup setup = new HttpWorkerOptionsSetup(new OptionsWrapper <ScriptJobHostOptions>(_scriptJobHostOptions), configuration, _testLoggerFactory, _metricsLogger); HttpWorkerOptions options = new HttpWorkerOptions(); options.Description = new HttpWorkerDescription(); options.Description.FileExists = path => { return(appendCurrentDirToDefaultExe); }; setup.Configure(options); Assert.True(_metricsLogger.LoggedEvents.Contains(MetricEventNames.CustomHandlerConfiguration)); //Verify worker exe path is expected if (appendCurrentDirToDefaultExe) { Assert.Equal(Path.Combine(_scriptJobHostOptions.RootScriptPath, "myWorkerDir", "node"), options.Description.DefaultExecutablePath); } else { Assert.Equal("node", options.Description.DefaultExecutablePath); } // Verify worker dir is expected if (appendCurrentDirToWorkerDir) { Assert.Equal(Path.Combine(_scriptJobHostOptions.RootScriptPath, "myWorkerDir"), options.Description.WorkerDirectory); } else { Assert.Equal(@"c:/myWorkerDir", options.Description.WorkerDirectory); } //Verify workering Dir is expected if (appendCurrentDirToWorkingDir) { Assert.Equal(Path.Combine(_scriptJobHostOptions.RootScriptPath, "myWorkingDir"), options.Description.WorkingDirectory); } else { Assert.Equal(@"c:/myWorkingDir", options.Description.WorkingDirectory); } }
public void InValid_HttpInvokerConfig_Throws_HostConfigurationException() { string hostJsonContent = @"{ 'version': '2.0', 'httpInvoker': { 'invalid': { 'defaultExecutablePath': 'testExe' } } }"; File.WriteAllText(_hostJsonFile, hostJsonContent); var configuration = BuildHostJsonConfiguration(); HttpWorkerOptionsSetup setup = new HttpWorkerOptionsSetup(configuration, _testLoggerFactory); HttpWorkerOptions options = new HttpWorkerOptions(); var ex = Assert.Throws <HostConfigurationException>(() => setup.Configure(options)); Assert.Contains("Missing WorkerDescription for HttpInvoker", ex.Message); }
public void InValid_HttpWorkerConfig_Throws_ValidationException() { string hostJsonContent = @"{ 'version': '2.0', 'httpWorker': { 'description': { 'langauge': 'testExe' } } }"; File.WriteAllText(_hostJsonFile, hostJsonContent); var configuration = BuildHostJsonConfiguration(); HttpWorkerOptionsSetup setup = new HttpWorkerOptionsSetup(new OptionsWrapper <ScriptJobHostOptions>(_scriptJobHostOptions), configuration, _testLoggerFactory); HttpWorkerOptions options = new HttpWorkerOptions(); var ex = Assert.Throws <ValidationException>(() => setup.Configure(options)); Assert.Contains("WorkerDescription DefaultExecutablePath cannot be empty", ex.Message); }
public void HttpWorkerConfig_OverrideConfigViaEnvVars_Test() { string hostJsonContent = @"{ 'version': '2.0', 'httpWorker': { 'description': { 'langauge': 'testExe', 'defaultExecutablePath': 'dotnet', 'defaultWorkerPath':'ManualTrigger/run.csx', 'arguments': ['--xTest1 --xTest2'], 'workerArguments': ['--xTest3 --xTest4'] } } }"; try { File.WriteAllText(_hostJsonFile, hostJsonContent); Environment.SetEnvironmentVariable("AzureFunctionsJobHost:httpWorker:description:defaultWorkerPath", "OneSecondTimer/run.csx"); Environment.SetEnvironmentVariable("AzureFunctionsJobHost:httpWorker:description:arguments", "[\"--xTest5\", \"--xTest6\", \"--xTest7\"]"); var configuration = BuildHostJsonConfiguration(); HttpWorkerOptionsSetup setup = new HttpWorkerOptionsSetup(new OptionsWrapper <ScriptJobHostOptions>(_scriptJobHostOptions), configuration, _testLoggerFactory, _metricsLogger); HttpWorkerOptions options = new HttpWorkerOptions(); setup.Configure(options); Assert.Equal("dotnet", options.Description.DefaultExecutablePath); // Verify options are overridden Assert.Contains("OneSecondTimer/run.csx", options.Description.DefaultWorkerPath); Assert.Equal(3, options.Description.Arguments.Count); Assert.Contains("--xTest5", options.Description.Arguments); Assert.Contains("--xTest6", options.Description.Arguments); Assert.Contains("--xTest7", options.Description.Arguments); // Verify options not overridden Assert.Equal(1, options.Description.WorkerArguments.Count); Assert.Equal("--xTest3 --xTest4", options.Description.WorkerArguments.ElementAt(0)); } finally { Environment.SetEnvironmentVariable("AzureFunctionsJobHost:httpWorker:description:defaultWorkerPath", string.Empty); Environment.SetEnvironmentVariable("AzureFunctionsJobHost:httpWorker:description:arguments", string.Empty); } }
public void InValid_HttpWorkerConfig_Throws_Exception(string hostJsonContent) { File.WriteAllText(_hostJsonFile, hostJsonContent); var configuration = BuildHostJsonConfiguration(); HttpWorkerOptionsSetup setup = new HttpWorkerOptionsSetup(new OptionsWrapper <ScriptJobHostOptions>(_scriptJobHostOptions), configuration, _testLoggerFactory, _metricsLogger); HttpWorkerOptions options = new HttpWorkerOptions(); var ex = Record.Exception(() => setup.Configure(options)); Assert.NotNull(ex); if (options.Description == null) { Assert.IsType <HostConfigurationException>(ex); Assert.Equal($"Missing worker Description.", ex.Message); } else { Assert.IsType <ValidationException>(ex); Assert.Equal($"WorkerDescription DefaultExecutablePath cannot be empty", ex.Message); } }
public void MissingOrValid_HttpWorkerConfig_DoesNotThrowException(string hostJsonContent) { File.WriteAllText(_hostJsonFile, hostJsonContent); var configuration = BuildHostJsonConfiguration(); HttpWorkerOptionsSetup setup = new HttpWorkerOptionsSetup(new OptionsWrapper <ScriptJobHostOptions>(_scriptJobHostOptions), configuration, _testLoggerFactory, _metricsLogger); HttpWorkerOptions options = new HttpWorkerOptions(); options.Description = new HttpWorkerDescription(); options.Description.FileExists = path => { return(true); }; setup.Configure(options); if (options.Description != null && !string.IsNullOrEmpty(options.Description.DefaultExecutablePath)) { string expectedDefaultExecutablePath = Path.Combine(_scriptJobHostOptions.RootScriptPath, "testExe"); Assert.Equal(expectedDefaultExecutablePath, options.Description.DefaultExecutablePath); } }
public async Task ProcessSimpleHttpTriggerInvocationRequest_CustomHandler_EnableForwardingHttpRequest_True() { var handlerMock = new Mock <HttpMessageHandler>(MockBehavior.Strict); var customHandlerOptions = new HttpWorkerOptions() { Port = _defaultPort, EnableForwardingHttpRequest = true }; handlerMock.Protected().Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>()) .Callback <HttpRequestMessage, CancellationToken>((request, token) => ValidateSimpleHttpTriggerInvocationRequest(request)) .ReturnsAsync(HttpWorkerTestUtilities.GetValidSimpleHttpResponseMessage()); _httpClient = new HttpClient(handlerMock.Object); _defaultHttpWorkerService = new DefaultHttpWorkerService(_httpClient, new OptionsWrapper <HttpWorkerOptions>(customHandlerOptions), _testLogger, _testEnvironment, new OptionsWrapper <ScriptJobHostOptions>(_scriptJobHostOptions)); var testScriptInvocationContext = HttpWorkerTestUtilities.GetSimpleHttpTriggerScriptInvocationContext(TestFunctionName, _testInvocationId, _functionLogger); await _defaultHttpWorkerService.InvokeAsync(testScriptInvocationContext); var invocationResult = await testScriptInvocationContext.ResultSource.Task; var expectedHttpResponseMessage = HttpWorkerTestUtilities.GetValidSimpleHttpResponseMessage(); var expectedResponseContent = await expectedHttpResponseMessage.Content.ReadAsStringAsync(); var testLogs = _functionLogger.GetLogMessages(); Assert.Equal(0, testLogs.Count()); Assert.Equal(1, invocationResult.Outputs.Count()); var httpOutputResponse = invocationResult.Outputs.FirstOrDefault().Value as HttpResponseMessage; Assert.NotNull(httpOutputResponse); Assert.Equal(expectedHttpResponseMessage.StatusCode, httpOutputResponse.StatusCode); Assert.Equal(expectedResponseContent, await httpOutputResponse.Content.ReadAsStringAsync()); var response = invocationResult.Return as HttpResponseMessage; Assert.NotNull(response); Assert.Equal(expectedHttpResponseMessage.StatusCode, response.StatusCode); Assert.Equal(expectedResponseContent, await response.Content.ReadAsStringAsync()); }
public void HttpWorker_Config_ExpectedValues(string hostJsonContent, bool appendCurrentDirectoryToExe, bool appendCurrentDirToWorkerPath, bool workerPathSet) { File.WriteAllText(_hostJsonFile, hostJsonContent); var configuration = BuildHostJsonConfiguration(); HttpWorkerOptionsSetup setup = new HttpWorkerOptionsSetup(new OptionsWrapper <ScriptJobHostOptions>(_scriptJobHostOptions), configuration, _testLoggerFactory, _metricsLogger); HttpWorkerOptions options = new HttpWorkerOptions(); setup.Configure(options); //Verify worker exe path is expected if (appendCurrentDirectoryToExe) { Assert.Equal(Path.Combine(_scriptJobHostOptions.RootScriptPath, "node"), options.Description.DefaultExecutablePath); } else if (Path.IsPathRooted(options.Description.DefaultExecutablePath)) { Assert.Equal(@"c:/myruntime/node", options.Description.DefaultExecutablePath); } else { Assert.Equal("node", options.Description.DefaultExecutablePath); } //Verify worker path is expected if (appendCurrentDirToWorkerPath) { Assert.Equal("httpWorker.js", options.Description.DefaultWorkerPath); } else if (!workerPathSet) { Assert.Null(options.Description.DefaultWorkerPath); } else { Assert.Equal(@"c:/myworkerPath/httpWorker.js", options.Description.DefaultWorkerPath); } Assert.Equal(1, options.Description.Arguments.Count); Assert.Equal("--xTest1 --xTest2", options.Description.Arguments[0]); }
// Specify the "builtin binding types". These are types that are directly accesible without needing an explicit load gesture. // This is the set of bindings we shipped prior to binding extensibility. // Map from BindingType to the Assembly Qualified Type name for its IExtensionConfigProvider object. public ScriptHost(IOptions <JobHostOptions> options, IOptions <HttpWorkerOptions> httpWorkerOptions, IEnvironment environment, IJobHostContextFactory jobHostContextFactory, IConfiguration configuration, IDistributedLockManager distributedLockManager, IScriptEventManager eventManager, ILoggerFactory loggerFactory, IFunctionInvocationDispatcherFactory functionDispatcherFactory, IFunctionMetadataManager functionMetadataManager, IFileLoggingStatusManager fileLoggingStatusManager, IMetricsLogger metricsLogger, IOptions <ScriptJobHostOptions> scriptHostOptions, ITypeLocator typeLocator, IScriptHostManager scriptHostManager, IDebugStateProvider debugManager, IEnumerable <IScriptBindingProvider> bindingProviders, IPrimaryHostStateProvider primaryHostStateProvider, IJobHostMetadataProvider metadataProvider, IHostIdProvider hostIdProvider, IHttpRoutesManager httpRoutesManager, IApplicationLifetime applicationLifetime, IExtensionBundleManager extensionBundleManager, IFunctionDataCache functionDataCache, IOptions <LanguageWorkerOptions> languageWorkerOptions, ScriptSettingsManager settingsManager = null) : base(options, jobHostContextFactory) { _environment = environment; _typeLocator = typeLocator as ScriptTypeLocator ?? throw new ArgumentException(nameof(typeLocator), $"A {nameof(ScriptTypeLocator)} instance is required."); _instanceId = Guid.NewGuid().ToString(); _hostOptions = options; _configuration = configuration; _distributedLockManager = distributedLockManager; _functionMetadataManager = functionMetadataManager; _fileLoggingStatusManager = fileLoggingStatusManager; _applicationLifetime = applicationLifetime; _hostIdProvider = hostIdProvider; _httpRoutesManager = httpRoutesManager; _isHttpWorker = httpWorkerOptions.Value.Description != null; _httpWorkerOptions = httpWorkerOptions.Value; ScriptOptions = scriptHostOptions.Value; _scriptHostManager = scriptHostManager; FunctionErrors = new Dictionary <string, ICollection <string> >(StringComparer.OrdinalIgnoreCase); EventManager = eventManager; _functionDispatcher = functionDispatcherFactory.GetFunctionDispatcher(); _settingsManager = settingsManager ?? ScriptSettingsManager.Instance; ExtensionBundleManager = extensionBundleManager; _metricsLogger = metricsLogger; _hostLogPath = Path.Combine(ScriptOptions.RootLogPath, "Host"); _workerRuntime = _environment.GetEnvironmentVariable(RpcWorkerConstants.FunctionWorkerRuntimeSettingName); _languageWorkerOptions = languageWorkerOptions; _loggerFactory = loggerFactory; _logger = loggerFactory.CreateLogger(LogCategories.Startup); Logger = _logger; _debugManager = debugManager; _primaryHostStateProvider = primaryHostStateProvider; _bindingProviders = new List <IScriptBindingProvider>(bindingProviders); _metadataProvider = metadataProvider; _eventSubscriptions.Add(EventManager.OfType <FunctionIndexingEvent>() .Subscribe(evt => { HandleHostError(evt.Exception); })); _functionDataCache = functionDataCache; }