internal static void Initialize(ContainerBuilder builder, WebHostSettings settings) { ScriptHostConfiguration scriptHostConfig = new ScriptHostConfiguration() { RootScriptPath = settings.ScriptPath, RootLogPath = settings.LogPath, FileLoggingEnabled = true }; // If running on Azure Web App, derive the host ID from the site name string hostId = Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME"); if (!String.IsNullOrEmpty(hostId)) { // Truncate to the max host name length if needed const int MaximumHostIdLength = 32; if (hostId.Length > MaximumHostIdLength) { hostId = hostId.Substring(0, MaximumHostIdLength); } // Trim any trailing - as they can cause problems with queue names hostId = hostId.TrimEnd('-'); scriptHostConfig.HostConfig.HostId = hostId.ToLowerInvariant(); } WebScriptHostManager scriptHostManager = new WebScriptHostManager(scriptHostConfig); builder.RegisterInstance <WebScriptHostManager>(scriptHostManager); SecretManager secretManager = new SecretManager(settings.SecretsPath); // Make sure that host secrets get created on startup if they don't exist secretManager.GetHostSecrets(); builder.RegisterInstance <SecretManager>(secretManager); WebHookReceiverManager webHookReceiverManager = new WebHookReceiverManager(secretManager); builder.RegisterInstance <WebHookReceiverManager>(webHookReceiverManager); if (!settings.IsSelfHost) { HostingEnvironment.QueueBackgroundWorkItem((ct) => scriptHostManager.RunAndBlock(ct)); } else { Task.Run(() => scriptHostManager.RunAndBlock()); } }
public void GeneratedMethods_WithOutParams_DoNotCauseDeadlocks() { var traceWriter = new TestTraceWriter(TraceLevel.Verbose); ScriptHostConfiguration config = new ScriptHostConfiguration() { RootScriptPath = @"TestScripts\FunctionGeneration", TraceWriter = traceWriter }; using (var manager = new WebScriptHostManager(config)) { Thread runLoopThread = new Thread(_ => { manager.RunAndBlock(CancellationToken.None); }); runLoopThread.IsBackground = true; runLoopThread.Start(); while (!manager.IsRunning) { Thread.Sleep(100); } FunctionDescriptor function = manager.GetHttpFunctionOrNull(new Uri("http://localhost/api/httptrigger-csharp")); var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/api/httptrigger-csharp"); SynchronizationContext currentContext = SynchronizationContext.Current; var resetEvent = new ManualResetEventSlim(); try { var requestThread = new Thread(() => { var context = new SingleThreadSynchronizationContext(); SynchronizationContext.SetSynchronizationContext(context); manager.HandleRequestAsync(function, request, CancellationToken.None) .ContinueWith(task => resetEvent.Set()); Thread.Sleep(500); context.Run(); }); requestThread.IsBackground = true; requestThread.Start(); bool threadSignaled = resetEvent.Wait(TimeSpan.FromSeconds(10)); requestThread.Abort(); Assert.True(threadSignaled, "Thread execution did not complete"); } finally { SynchronizationContext.SetSynchronizationContext(currentContext); manager.Stop(); } } }
private async Task <WebScriptHostManager> CreateAndStartWebScriptHostManager(TraceWriter traceWriter) { var functions = new Collection <string> { "TimeoutToken" }; ScriptHostConfiguration config = new ScriptHostConfiguration() { RootScriptPath = $@"TestScripts\CSharp", TraceWriter = traceWriter, FileLoggingMode = FileLoggingMode.Always, Functions = functions, FunctionTimeout = TimeSpan.FromSeconds(3) }; var mockEventManager = new Mock <IScriptEventManager>(); var mockRouter = new Mock <IWebJobsRouter>(); var manager = new WebScriptHostManager( config, new TestSecretManagerFactory(), mockEventManager.Object, ScriptSettingsManager.Instance, new WebHostSettings { SecretsPath = _secretsDirectory.Path }, mockRouter.Object); Task task = Task.Run(() => { manager.RunAndBlock(); }); await TestHelpers.Await(() => manager.State == ScriptHostState.Running); return(manager); }
internal static void Initialize(ContainerBuilder builder, WebHostSettings settings) { ScriptHostConfiguration scriptHostConfig = new ScriptHostConfiguration() { RootScriptPath = settings.ScriptPath, RootLogPath = settings.LogPath, FileLoggingEnabled = true }; // If running on Azure Web App, derive the host ID from the site name string hostId = Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME"); if (!String.IsNullOrEmpty(hostId)) { // Truncate to the max host name length if needed const int MaximumHostIdLength = 32; if (hostId.Length > MaximumHostIdLength) { hostId = hostId.Substring(0, MaximumHostIdLength); } // Trim any trailing - as they can cause problems with queue names hostId = hostId.TrimEnd('-'); scriptHostConfig.HostConfig.HostId = hostId.ToLowerInvariant(); } WebScriptHostManager scriptHostManager = new WebScriptHostManager(scriptHostConfig); builder.RegisterInstance<WebScriptHostManager>(scriptHostManager); SecretManager secretManager = new SecretManager(settings.SecretsPath); // Make sure that host secrets get created on startup if they don't exist secretManager.GetHostSecrets(); builder.RegisterInstance<SecretManager>(secretManager); WebHookReceiverManager webHookReceiverManager = new WebHookReceiverManager(secretManager); builder.RegisterInstance<WebHookReceiverManager>(webHookReceiverManager); if (!settings.IsSelfHost) { HostingEnvironment.QueueBackgroundWorkItem((ct) => scriptHostManager.RunAndBlock(ct)); } else { Task.Run(() => scriptHostManager.RunAndBlock()); } }
public async Task EmptyHost_StartsSuccessfully() { await _fixture.InitializationTask; string functionTestDir = Path.Combine(_fixture.TestFunctionRoot, Guid.NewGuid().ToString()); Directory.CreateDirectory(functionTestDir); // important for the repro that these directories no not exist string logDir = Path.Combine(_fixture.TestLogsRoot, Guid.NewGuid().ToString()); string secretsDir = Path.Combine(_fixture.TestSecretsRoot, Guid.NewGuid().ToString()); JObject hostConfig = new JObject { { "id", "123456" } }; File.WriteAllText(Path.Combine(functionTestDir, ScriptConstants.HostMetadataFileName), hostConfig.ToString()); ScriptHostConfiguration config = new ScriptHostConfiguration { RootScriptPath = functionTestDir, RootLogPath = logDir, FileLoggingMode = FileLoggingMode.Always }; string connectionString = AmbientConnectionStringProvider.Instance.GetConnectionString(ConnectionStringNames.Storage); ISecretsRepository repository = new BlobStorageSecretsRepository(secretsDir, connectionString, "EmptyHost_StartsSuccessfully"); ISecretManager secretManager = new SecretManager(_settingsManager, repository, null); WebHostSettings webHostSettings = new WebHostSettings(); webHostSettings.SecretsPath = _secretsDirectory.Path; var mockEventManager = new Mock <IScriptEventManager>(); IWebJobsRouter router = _fixture.CreateRouter(); ScriptHostManager hostManager = new WebScriptHostManager(config, new TestSecretManagerFactory(secretManager), mockEventManager.Object, _settingsManager, webHostSettings, router, NullLoggerFactory.Instance); Task runTask = Task.Run(() => hostManager.RunAndBlock()); await TestHelpers.Await(() => hostManager.State == ScriptHostState.Running, timeout : 10000); hostManager.Stop(); Assert.Equal(ScriptHostState.Default, hostManager.State); // give some time for the logs to be flushed fullly await Task.Delay(FileWriter.LogFlushIntervalMs * 3); string hostLogFilePath = Directory.EnumerateFiles(Path.Combine(logDir, "Host")).Single(); string hostLogs = File.ReadAllText(hostLogFilePath); Assert.Contains("Generating 0 job function(s)", hostLogs); Assert.Contains("No job functions found.", hostLogs); Assert.Contains("Job host started", hostLogs); Assert.Contains("Job host stopped", hostLogs); }
public async Task MultipleHostRestarts() { string functionTestDir = Path.Combine(_fixture.TestFunctionRoot, Guid.NewGuid().ToString()); Directory.CreateDirectory(functionTestDir); string logDir = Path.Combine(_fixture.TestLogsRoot, Guid.NewGuid().ToString()); string secretsDir = Path.Combine(_fixture.TestSecretsRoot, Guid.NewGuid().ToString()); ScriptHostConfiguration config = new ScriptHostConfiguration { RootLogPath = logDir, RootScriptPath = functionTestDir, FileLoggingMode = FileLoggingMode.Always, }; ISecretsRepository repository = new FileSystemSecretsRepository(_secretsDirectory.Path); SecretManager secretManager = new SecretManager(_settingsManager, repository, NullTraceWriter.Instance, null); WebHostSettings webHostSettings = new WebHostSettings(); webHostSettings.SecretsPath = _secretsDirectory.Path; var mockEventManager = new Mock <IScriptEventManager>(); var factoryMock = new Mock <IScriptHostFactory>(); int count = 0; factoryMock.Setup(p => p.Create(It.IsAny <IScriptHostEnvironment>(), It.IsAny <IScriptEventManager>(), _settingsManager, config)).Callback(() => { count++; }).Throws(new Exception("Kaboom!")); ScriptHostManager hostManager = new WebScriptHostManager(config, new TestSecretManagerFactory(secretManager), mockEventManager.Object, _settingsManager, webHostSettings, factoryMock.Object); Task runTask = Task.Run(() => hostManager.RunAndBlock()); await TestHelpers.Await(() => { return(count > 3); }); hostManager.Stop(); Assert.Equal(ScriptHostState.Default, hostManager.State); // regression test: previously on multiple restarts we were recomposing // the writer on each restart, resulting in a nested chain of writers // increasing on each restart Assert.Equal(typeof(SystemTraceWriter), config.TraceWriter.GetType()); }
internal static void Initialize(ContainerBuilder builder) { string logFilePath; string scriptRootPath; string secretsPath; string home = Environment.GetEnvironmentVariable("HOME"); bool isLocal = string.IsNullOrEmpty(home); if (isLocal) { // we're running locally scriptRootPath = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, @"..\..\sample"); logFilePath = Path.Combine(Path.GetTempPath(), @"Functions"); secretsPath = HttpContext.Current.Server.MapPath("~/App_Data/Secrets"); } else { // we're running in Azure scriptRootPath = Path.Combine(home, @"site\wwwroot"); logFilePath = Path.Combine(home, @"LogFiles\Application\Functions"); secretsPath = Path.Combine(home, @"data\Functions\secrets"); } ScriptHostConfiguration scriptHostConfig = new ScriptHostConfiguration() { RootScriptPath = scriptRootPath, RootLogPath = logFilePath, FileLoggingEnabled = true }; WebScriptHostManager scriptHostManager = new WebScriptHostManager(scriptHostConfig); builder.RegisterInstance <WebScriptHostManager>(scriptHostManager); SecretManager secretManager = new SecretManager(secretsPath); builder.RegisterInstance <SecretManager>(secretManager); WebHookReceiverManager webHookRecieverManager = new WebHookReceiverManager(secretManager); builder.RegisterInstance <WebHookReceiverManager>(webHookRecieverManager); Task.Run(() => scriptHostManager.RunAndBlock(CancellationToken.None)); }
internal static void Initialize(ContainerBuilder builder) { string logFilePath; string scriptRootPath; string secretsPath; string home = Environment.GetEnvironmentVariable("HOME"); bool isLocal = string.IsNullOrEmpty(home); if (isLocal) { // we're running locally scriptRootPath = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, @"..\..\sample"); logFilePath = Path.Combine(Path.GetTempPath(), @"Functions"); secretsPath = HttpContext.Current.Server.MapPath("~/App_Data/Secrets"); } else { // we're running in Azure scriptRootPath = Path.Combine(home, @"site\wwwroot"); logFilePath = Path.Combine(home, @"LogFiles\Application\Functions"); secretsPath = Path.Combine(home, @"data\Functions\secrets"); } ScriptHostConfiguration scriptHostConfig = new ScriptHostConfiguration() { RootScriptPath = scriptRootPath, RootLogPath = logFilePath, FileLoggingEnabled = true }; WebScriptHostManager scriptHostManager = new WebScriptHostManager(scriptHostConfig); builder.RegisterInstance<WebScriptHostManager>(scriptHostManager); SecretManager secretManager = new SecretManager(secretsPath); builder.RegisterInstance<SecretManager>(secretManager); WebHookReceiverManager webHookRecieverManager = new WebHookReceiverManager(secretManager); builder.RegisterInstance<WebHookReceiverManager>(webHookRecieverManager); Task.Run(() => scriptHostManager.RunAndBlock(CancellationToken.None)); }
internal async Task GeneratedMethods_WithOutParams_DoNotCauseDeadlocks(string fixture) { var traceWriter = new TestTraceWriter(TraceLevel.Verbose); ScriptHostConfiguration config = new ScriptHostConfiguration() { RootScriptPath = @"TestScripts\FunctionGeneration", TraceWriter = traceWriter }; string secretsPath = Path.Combine(Path.GetTempPath(), @"FunctionTests\Secrets"); ISecretsRepository repository = new FileSystemSecretsRepository(secretsPath); WebHostSettings webHostSettings = new WebHostSettings(); webHostSettings.SecretsPath = secretsPath; var secretManager = new SecretManager(SettingsManager, repository, NullTraceWriter.Instance); using (var manager = new WebScriptHostManager(config, new TestSecretManagerFactory(secretManager), SettingsManager, webHostSettings)) { Thread runLoopThread = new Thread(_ => { manager.RunAndBlock(CancellationToken.None); }); runLoopThread.IsBackground = true; runLoopThread.Start(); await TestHelpers.Await(() => { return(manager.State == ScriptHostState.Running); }); var request = new HttpRequestMessage(HttpMethod.Get, String.Format("http://localhost/api/httptrigger-{0}", fixture)); FunctionDescriptor function = manager.GetHttpFunctionOrNull(request); SynchronizationContext currentContext = SynchronizationContext.Current; var resetEvent = new ManualResetEventSlim(); try { var requestThread = new Thread(() => { var context = new SingleThreadSynchronizationContext(); SynchronizationContext.SetSynchronizationContext(context); manager.HandleRequestAsync(function, request, CancellationToken.None) .ContinueWith(task => resetEvent.Set()); Thread.Sleep(500); context.Run(); }); requestThread.IsBackground = true; requestThread.Start(); bool threadSignaled = resetEvent.Wait(TimeSpan.FromSeconds(10)); requestThread.Abort(); Assert.True(threadSignaled, "Thread execution did not complete"); } finally { SynchronizationContext.SetSynchronizationContext(currentContext); manager.Stop(); } } }