HostingTests.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // Copyright (c) .NET Foundation. All rights reserved.
  2. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  3. using System;
  4. using System.Threading;
  5. using System.Threading.Tasks;
  6. using Microsoft.AspNetCore.Builder;
  7. using Microsoft.AspNetCore.DataProtection.KeyManagement.Internal;
  8. using Microsoft.AspNetCore.Hosting;
  9. using Microsoft.AspNetCore.Hosting.Server;
  10. using Microsoft.AspNetCore.Http.Features;
  11. using Microsoft.AspNetCore.Testing;
  12. using Microsoft.Extensions.DependencyInjection;
  13. using Microsoft.Extensions.DependencyInjection.Extensions;
  14. using Moq;
  15. using Xunit;
  16. namespace Microsoft.AspNetCore.DataProtection.Test
  17. {
  18. public class HostingTests
  19. {
  20. [Fact]
  21. public async Task LoadsKeyRingBeforeServerStarts()
  22. {
  23. var tcs = new TaskCompletionSource<object>();
  24. var mockKeyRing = new Mock<IKeyRingProvider>();
  25. mockKeyRing.Setup(m => m.GetCurrentKeyRing())
  26. .Returns(Mock.Of<IKeyRing>())
  27. .Callback(() => tcs.TrySetResult(null));
  28. var builder = new WebHostBuilder()
  29. .UseStartup<TestStartup>()
  30. .ConfigureServices(s =>
  31. s.AddDataProtection()
  32. .Services
  33. .Replace(ServiceDescriptor.Singleton(mockKeyRing.Object))
  34. .AddSingleton<IServer>(
  35. new FakeServer(onStart: () => tcs.TrySetException(new InvalidOperationException("Server was started before key ring was initialized")))));
  36. using (var host = builder.Build())
  37. {
  38. await host.StartAsync();
  39. }
  40. await tcs.Task.TimeoutAfter(TimeSpan.FromSeconds(10));
  41. mockKeyRing.VerifyAll();
  42. }
  43. [Fact]
  44. public async Task StartupContinuesOnFailureToLoadKey()
  45. {
  46. var mockKeyRing = new Mock<IKeyRingProvider>();
  47. mockKeyRing.Setup(m => m.GetCurrentKeyRing())
  48. .Throws(new NotSupportedException("This mock doesn't actually work, but shouldn't kill the server"))
  49. .Verifiable();
  50. var builder = new WebHostBuilder()
  51. .UseStartup<TestStartup>()
  52. .ConfigureServices(s =>
  53. s.AddDataProtection()
  54. .Services
  55. .Replace(ServiceDescriptor.Singleton(mockKeyRing.Object))
  56. .AddSingleton(Mock.Of<IServer>()));
  57. using (var host = builder.Build())
  58. {
  59. await host.StartAsync();
  60. }
  61. mockKeyRing.VerifyAll();
  62. }
  63. private class TestStartup
  64. {
  65. public void Configure(IApplicationBuilder app)
  66. {
  67. }
  68. }
  69. public class FakeServer : IServer
  70. {
  71. private readonly Action _onStart;
  72. public FakeServer(Action onStart)
  73. {
  74. _onStart = onStart;
  75. }
  76. public IFeatureCollection Features => new FeatureCollection();
  77. public Task StartAsync<TContext>(IHttpApplication<TContext> application, CancellationToken cancellationToken)
  78. {
  79. _onStart();
  80. return Task.CompletedTask;
  81. }
  82. public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
  83. public void Dispose()
  84. {
  85. }
  86. }
  87. }
  88. }