|
2 | 2 | // Licensed under the MIT License. See License.txt in the project root for license information.
|
3 | 3 |
|
4 | 4 | using System;
|
| 5 | +using System.Linq; |
5 | 6 | using System.Threading;
|
6 | 7 | using System.Threading.Tasks;
|
7 | 8 | using Microsoft.Azure.WebJobs.Script.Config;
|
| 9 | +using Microsoft.Azure.WebJobs.Script.Rpc; |
8 | 10 | using Microsoft.Azure.WebJobs.Script.Scale;
|
9 | 11 | using Microsoft.Azure.WebJobs.Script.WebHost;
|
10 |
| -using Microsoft.Azure.WebJobs.Script.WebHost.Management; |
| 12 | +using Microsoft.Extensions.Configuration; |
11 | 13 | using Microsoft.Extensions.DependencyInjection;
|
12 | 14 | using Microsoft.Extensions.Hosting;
|
| 15 | +using Microsoft.Extensions.Logging; |
13 | 16 | using Microsoft.Extensions.Logging.Abstractions;
|
14 | 17 | using Microsoft.Extensions.Options;
|
| 18 | +using Microsoft.WebJobs.Script.Tests; |
15 | 19 | using Moq;
|
16 | 20 | using Xunit;
|
17 | 21 |
|
18 | 22 | namespace Microsoft.Azure.WebJobs.Script.Tests
|
19 | 23 | {
|
20 | 24 | public class WebJobsScriptHostServiceTests
|
21 | 25 | {
|
22 |
| - [Fact] |
23 |
| - public async Task HostInitialization_OnInitializationException_MaintainsErrorInformation() |
| 26 | + private WebJobsScriptHostService _hostService; |
| 27 | + private ScriptApplicationHostOptionsMonitor _monitor; |
| 28 | + private TestLoggerProvider _testLoggerProvider; |
| 29 | + private ILoggerFactory _loggerFactory; |
| 30 | + private Mock<IServiceProvider> _mockRootServiceProvider; |
| 31 | + private Mock<IServiceScopeFactory> _mockRootScopeFactory; |
| 32 | + private Mock<IScriptWebHostEnvironment> _mockScriptWebHostEnvironment; |
| 33 | + private Mock<IEnvironment> _mockEnvironment; |
| 34 | + private OptionsWrapper<HostHealthMonitorOptions> _healthMonitorOptions; |
| 35 | + private HostPerformanceManager _hostPerformanceManager; |
| 36 | + private Mock<IHost> _host; |
| 37 | + |
| 38 | + public WebJobsScriptHostServiceTests() |
24 | 39 | {
|
25 | 40 | var options = new ScriptApplicationHostOptions
|
26 | 41 | {
|
27 | 42 | ScriptPath = @"c:\tests",
|
28 | 43 | LogPath = @"c:\tests\logs",
|
29 | 44 | };
|
30 |
| - |
31 |
| - var monitor = new ScriptApplicationHostOptionsMonitor(options); |
32 |
| - |
| 45 | + _monitor = new ScriptApplicationHostOptionsMonitor(options); |
33 | 46 | var services = new ServiceCollection()
|
34 | 47 | .AddLogging()
|
35 | 48 | .BuildServiceProvider();
|
36 |
| - |
37 |
| - var host = new Mock<IHost>(); |
38 |
| - host.Setup(h => h.Services) |
| 49 | + _host = new Mock<IHost>(); |
| 50 | + _host.Setup(h => h.Services) |
39 | 51 | .Returns(services);
|
40 |
| - host.SetupSequence(h => h.StartAsync(It.IsAny<CancellationToken>())) |
| 52 | + |
| 53 | + _mockRootServiceProvider = new Mock<IServiceProvider>(); |
| 54 | + _mockRootScopeFactory = new Mock<IServiceScopeFactory>(); |
| 55 | + _mockScriptWebHostEnvironment = new Mock<IScriptWebHostEnvironment>(); |
| 56 | + _mockEnvironment = new Mock<IEnvironment>(); |
| 57 | + _healthMonitorOptions = new OptionsWrapper<HostHealthMonitorOptions>(new HostHealthMonitorOptions()); |
| 58 | + _hostPerformanceManager = new HostPerformanceManager(_mockEnvironment.Object, _healthMonitorOptions); |
| 59 | + } |
| 60 | + |
| 61 | + [Fact] |
| 62 | + public async Task HostInitialization_OnInitializationException_MaintainsErrorInformation() |
| 63 | + { |
| 64 | + _host.SetupSequence(h => h.StartAsync(It.IsAny<CancellationToken>())) |
41 | 65 | .Throws(new HostInitializationException("boom"))
|
42 | 66 | .Returns(Task.CompletedTask);
|
43 | 67 |
|
44 | 68 | var hostBuilder = new Mock<IScriptHostBuilder>();
|
45 | 69 | hostBuilder.Setup(b => b.BuildHost(It.IsAny<bool>(), It.IsAny<bool>()))
|
46 |
| - .Returns(host.Object); |
| 70 | + .Returns(_host.Object); |
| 71 | + _hostService = new WebJobsScriptHostService( |
| 72 | + _monitor, hostBuilder.Object, NullLoggerFactory.Instance, _mockRootServiceProvider.Object, _mockRootScopeFactory.Object, |
| 73 | + _mockScriptWebHostEnvironment.Object, _mockEnvironment.Object, _hostPerformanceManager, _healthMonitorOptions); |
47 | 74 |
|
48 |
| - var mockRootServiceProvider = new Mock<IServiceProvider>(); |
49 |
| - var mockRootScopeFactory = new Mock<IServiceScopeFactory>(); |
50 |
| - var mockScriptWebHostEnvironment = new Mock<IScriptWebHostEnvironment>(); |
51 |
| - var mockEnvironment = new Mock<IEnvironment>(); |
52 |
| - var healthMonitorOptions = new OptionsWrapper<HostHealthMonitorOptions>(new HostHealthMonitorOptions()); |
53 |
| - var hostPerformanceManager = new HostPerformanceManager(mockEnvironment.Object, healthMonitorOptions); |
| 75 | + await _hostService.StartAsync(CancellationToken.None); |
54 | 76 |
|
55 |
| - var hostService = new WebJobsScriptHostService( |
56 |
| - monitor, hostBuilder.Object, NullLoggerFactory.Instance, mockRootServiceProvider.Object, mockRootScopeFactory.Object, |
57 |
| - mockScriptWebHostEnvironment.Object, mockEnvironment.Object, hostPerformanceManager, healthMonitorOptions); |
| 77 | + Assert.Equal(ScriptHostState.Error, _hostService.State); |
| 78 | + Assert.IsType<HostInitializationException>(_hostService.LastError); |
| 79 | + } |
58 | 80 |
|
59 |
| - await hostService.StartAsync(CancellationToken.None); |
| 81 | + [Fact] |
| 82 | + public async Task HostRestart_Specialization_Succeeds() |
| 83 | + { |
| 84 | + _host.Setup(h => h.StartAsync(It.IsAny<CancellationToken>())) |
| 85 | + .Returns(Task.CompletedTask); |
| 86 | + |
| 87 | + var hostBuilder = new Mock<IScriptHostBuilder>(); |
| 88 | + hostBuilder.Setup(b => b.BuildHost(It.IsAny<bool>(), It.IsAny<bool>())) |
| 89 | + .Returns(_host.Object); |
| 90 | + |
| 91 | + _testLoggerProvider = new TestLoggerProvider(); |
| 92 | + _loggerFactory = new LoggerFactory(); |
| 93 | + _loggerFactory.AddProvider(_testLoggerProvider); |
| 94 | + |
| 95 | + _hostService = new WebJobsScriptHostService( |
| 96 | + _monitor, hostBuilder.Object, _loggerFactory, _mockRootServiceProvider.Object, _mockRootScopeFactory.Object, |
| 97 | + _mockScriptWebHostEnvironment.Object, _mockEnvironment.Object, _hostPerformanceManager, _healthMonitorOptions); |
| 98 | + |
| 99 | + await _hostService.StartAsync(CancellationToken.None); |
| 100 | + |
| 101 | + Thread restartHostThread = new Thread(new ThreadStart(RestartHost)); |
| 102 | + Thread specializeHostThread = new Thread(new ThreadStart(SpecializeHost)); |
| 103 | + restartHostThread.Start(); |
| 104 | + specializeHostThread.Start(); |
| 105 | + restartHostThread.Join(); |
| 106 | + specializeHostThread.Join(); |
60 | 107 |
|
61 |
| - Assert.Equal(ScriptHostState.Error, hostService.State); |
62 |
| - Assert.IsType<HostInitializationException>(hostService.LastError); |
| 108 | + var logMessages = _testLoggerProvider.GetAllLogMessages().Where(m => m.FormattedMessage.Contains("Restarting host.")); |
| 109 | + Assert.Equal(2, logMessages.Count()); |
| 110 | + } |
| 111 | + |
| 112 | + public void RestartHost() |
| 113 | + { |
| 114 | + _hostService.RestartHostAsync(CancellationToken.None).Wait(); |
| 115 | + } |
| 116 | + |
| 117 | + public void SpecializeHost() |
| 118 | + { |
| 119 | + var mockScriptWebHostEnvironment = new Mock<IScriptWebHostEnvironment>(); |
| 120 | + Mock<IConfigurationRoot> mockConfiguration = new Mock<IConfigurationRoot>(); |
| 121 | + var mockEnvironment = new Mock<IEnvironment>(); |
| 122 | + Mock<ILanguageWorkerChannelManager> mockLanguageWorkerChannelManager = new Mock<ILanguageWorkerChannelManager>(); |
| 123 | + ILogger<StandbyManager> testLogger = new Logger<StandbyManager>(_loggerFactory); |
| 124 | + var manager = new StandbyManager(_hostService, mockLanguageWorkerChannelManager.Object, mockConfiguration.Object, mockScriptWebHostEnvironment.Object, mockEnvironment.Object, _monitor, testLogger); |
| 125 | + manager.SpecializeHostAsync().Wait(); |
63 | 126 | }
|
64 | 127 | }
|
65 | 128 | }
|
0 commit comments