private async Task ProcessJobTaskResult(Task jobTask, string jobId, ExtensionPostInstallActions postInstallActions = ExtensionPostInstallActions.None) { ExtensionsRestoreJob job = await GetJob(jobId); if (job == null) { return; } if (jobTask.IsFaulted) { job.Status = ExtensionsRestoreStatus.Failed; job.Error = jobTask.Exception.InnerException?.Message; } else { job.Status = ExtensionsRestoreStatus.Succeeded; } job.EndTime = DateTimeOffset.Now; if (postInstallActions.HasFlag(ExtensionPostInstallActions.BringAppOnline)) { await FileMonitoringService.SetAppOfflineState(_applicationHostOptions.Value.ScriptPath, false); } await SaveJob(job); }
public static async Task TestAppOfflineDebounceTime(string fileName, int delayInMs, bool expectShutdown, bool expectRestart) { using (var directory = new TempDirectory()) { // Setup string tempDir = directory.Path; Directory.CreateDirectory(Path.Combine(tempDir, "Host")); File.Create(Path.Combine(tempDir, fileName)); var jobHostOptions = new ScriptJobHostOptions { RootLogPath = tempDir, RootScriptPath = tempDir, FileWatchingEnabled = true }; var loggerFactory = new LoggerFactory(); var mockWebHostEnvironment = new Mock <IScriptJobHostEnvironment>(MockBehavior.Loose); var mockEventManager = new ScriptEventManager(); // Act FileMonitoringService fileMonitoringService = new FileMonitoringService(new OptionsWrapper <ScriptJobHostOptions>(jobHostOptions), loggerFactory, mockEventManager, mockWebHostEnvironment.Object); await fileMonitoringService.StartAsync(new CancellationToken(canceled : false)); var offlineEventArgs = new FileSystemEventArgs(WatcherChangeTypes.Created, tempDir, fileName); FileEvent offlinefileEvent = new FileEvent("ScriptFiles", offlineEventArgs); var randomFileEventArgs = new FileSystemEventArgs(WatcherChangeTypes.Created, tempDir, "random.txt"); FileEvent randomFileEvent = new FileEvent("ScriptFiles", randomFileEventArgs); mockEventManager.Publish(offlinefileEvent); await Task.Delay(delayInMs); mockEventManager.Publish(randomFileEvent); // Test if (expectShutdown) { mockWebHostEnvironment.Verify(m => m.Shutdown()); } else { mockWebHostEnvironment.Verify(m => m.Shutdown(), Times.Never); } if (expectRestart) { mockWebHostEnvironment.Verify(m => m.RestartHost()); } else { mockWebHostEnvironment.Verify(m => m.RestartHost(), Times.Never); } } }
public async Task <IActionResult> SetState([FromBody] string state) { if (!Enum.TryParse <ScriptHostState>(state, ignoreCase: true, out ScriptHostState desiredState) || !(desiredState == ScriptHostState.Offline || desiredState == ScriptHostState.Running)) { // currently we only allow states Offline and Running return(BadRequest()); } var currentState = _scriptHostManager.State; if (desiredState == currentState) { return(Ok()); } else if (desiredState == ScriptHostState.Running && currentState == ScriptHostState.Offline) { if (_environment.IsFileSystemReadOnly()) { return(BadRequest()); } // we're currently offline and the request is to bring the host back online await FileMonitoringService.SetAppOfflineState(_applicationHostOptions.Value.ScriptPath, false); } else if (desiredState == ScriptHostState.Offline && currentState != ScriptHostState.Offline) { if (_environment.IsFileSystemReadOnly()) { return(BadRequest()); } // we're currently online and the request is to take the host offline await FileMonitoringService.SetAppOfflineState(_applicationHostOptions.Value.ScriptPath, true); } else { return(BadRequest()); } return(Accepted()); }
public static async Task HostRestarts_OnWatchFilesChange() { using (var directory = new TempDirectory()) { // Setup string tempDir = directory.Path; Directory.CreateDirectory(Path.Combine(tempDir, "Host")); File.Create(Path.Combine(tempDir, "my_watched_file.txt")); File.Create(Path.Combine(tempDir, "my_ignored_file.txt")); var jobHostOptions = new ScriptJobHostOptions { RootLogPath = tempDir, RootScriptPath = tempDir, FileWatchingEnabled = true, WatchFiles = { "my_watched_file.txt" } }; var loggerFactory = new LoggerFactory(); var mockApplicationLifetime = new Mock <IApplicationLifetime>(); var mockScriptHostManager = new Mock <IScriptHostManager>(); var mockEventManager = new ScriptEventManager(); var environment = new TestEnvironment(); // Act FileMonitoringService fileMonitoringService = new FileMonitoringService(new OptionsWrapper <ScriptJobHostOptions>(jobHostOptions), loggerFactory, mockEventManager, mockApplicationLifetime.Object, mockScriptHostManager.Object, environment); await fileMonitoringService.StartAsync(new CancellationToken(canceled : false)); var ignoredFileEventArgs = new FileSystemEventArgs(WatcherChangeTypes.Created, tempDir, "my_ignored_file.txt"); FileEvent ignoredFileEvent = new FileEvent("ScriptFiles", ignoredFileEventArgs); var watchedFileEventArgs = new FileSystemEventArgs(WatcherChangeTypes.Created, tempDir, "my_watched_file.txt"); FileEvent watchedFileEvent = new FileEvent("ScriptFiles", watchedFileEventArgs); // Test mockEventManager.Publish(ignoredFileEvent); await Task.Delay(TimeSpan.FromSeconds(3)); mockScriptHostManager.Verify(m => m.RestartHostAsync(default), Times.Never);
public static void GetRelativeDirectory_ReturnsExpectedDirectoryName(string path, string expected) { Assert.Equal(expected, FileMonitoringService.GetRelativeDirectory(path, @"C:\Functions\Scripts")); }