JellyfinApplicationFactory.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Threading.Tasks;
  7. using Emby.Server.Implementations;
  8. using Emby.Server.Implementations.IO;
  9. using Emby.Server.Implementations.Networking;
  10. using Jellyfin.Drawing.Skia;
  11. using Jellyfin.Server;
  12. using MediaBrowser.Common;
  13. using Microsoft.AspNetCore.Hosting;
  14. using Microsoft.AspNetCore.Mvc.Testing;
  15. using Microsoft.AspNetCore.TestHost;
  16. using Microsoft.Extensions.DependencyInjection;
  17. using Microsoft.Extensions.Hosting;
  18. using Microsoft.Extensions.Logging;
  19. using Serilog;
  20. using Serilog.Extensions.Logging;
  21. namespace MediaBrowser.Api.Tests
  22. {
  23. /// <summary>
  24. /// Factory for bootstrapping the Jellyfin application in memory for functional end to end tests.
  25. /// </summary>
  26. public class JellyfinApplicationFactory : WebApplicationFactory<Startup>
  27. {
  28. private static readonly string _testPathRoot = Path.Combine(Path.GetTempPath(), "jellyfin-test-data");
  29. private static readonly ConcurrentBag<ApplicationHost> _appHosts = new ConcurrentBag<ApplicationHost>();
  30. /// <summary>
  31. /// Initializes a new instance of <see cref="JellyfinApplicationFactory"/>.
  32. /// </summary>
  33. public JellyfinApplicationFactory()
  34. {
  35. // Perform static initialization that only needs to happen once per test-run
  36. Log.Logger = new LoggerConfiguration().WriteTo.Console().CreateLogger();
  37. Program.PerformStaticInitialization();
  38. }
  39. /// <inheritdoc/>
  40. protected override IWebHostBuilder CreateWebHostBuilder()
  41. {
  42. return new WebHostBuilder();
  43. }
  44. /// <inheritdoc/>
  45. protected override void ConfigureWebHost(IWebHostBuilder builder)
  46. {
  47. // Specify the startup command line options
  48. var commandLineOpts = new StartupOptions
  49. {
  50. NoWebClient = true,
  51. NoAutoRunWebApp = true
  52. };
  53. // Use a temporary directory for the application paths
  54. var webHostPathRoot = Path.Combine(_testPathRoot, "test-host-" + Path.GetFileNameWithoutExtension(Path.GetRandomFileName()));
  55. Directory.CreateDirectory(Path.Combine(webHostPathRoot, "logs"));
  56. Directory.CreateDirectory(Path.Combine(webHostPathRoot, "config"));
  57. Directory.CreateDirectory(Path.Combine(webHostPathRoot, "cache"));
  58. Directory.CreateDirectory(Path.Combine(webHostPathRoot, "jellyfin-web"));
  59. var appPaths = new ServerApplicationPaths(
  60. webHostPathRoot,
  61. Path.Combine(webHostPathRoot, "logs"),
  62. Path.Combine(webHostPathRoot, "config"),
  63. Path.Combine(webHostPathRoot, "cache"),
  64. Path.Combine(webHostPathRoot, "jellyfin-web"));
  65. // Create the logging config file
  66. // TODO: We shouldn't need to do this since we are only logging to console
  67. Program.InitLoggingConfigFile(appPaths).Wait();
  68. // Create a copy of the application configuration to use for startup
  69. var startupConfig = Program.CreateAppConfiguration(commandLineOpts, appPaths);
  70. // Create the app host and initialize it
  71. ILoggerFactory loggerFactory = new SerilogLoggerFactory();
  72. var appHost = new CoreAppHost(
  73. appPaths,
  74. loggerFactory,
  75. commandLineOpts,
  76. new ManagedFileSystem(loggerFactory.CreateLogger<ManagedFileSystem>(), appPaths),
  77. new NetworkManager(loggerFactory.CreateLogger<NetworkManager>()));
  78. _appHosts.Add(appHost);
  79. var serviceCollection = new ServiceCollection();
  80. appHost.Init(serviceCollection);
  81. // Configure the web host builder
  82. Program.ConfigureWebHostBuilder(builder, appHost, serviceCollection, commandLineOpts, startupConfig, appPaths);
  83. }
  84. /// <inheritdoc/>
  85. protected override TestServer CreateServer(IWebHostBuilder builder)
  86. {
  87. // Create the test server using the base implementation
  88. var testServer = base.CreateServer(builder);
  89. // Finish initializing the app host
  90. var appHost = (CoreAppHost)testServer.Services.GetRequiredService<IApplicationHost>();
  91. appHost.ServiceProvider = testServer.Services;
  92. appHost.InitializeServices().Wait();
  93. appHost.RunStartupTasksAsync().Wait();
  94. return testServer;
  95. }
  96. /// <inheritdoc/>
  97. protected override void Dispose(bool disposing)
  98. {
  99. foreach (var host in _appHosts)
  100. {
  101. host.Dispose();
  102. }
  103. _appHosts.Clear();
  104. base.Dispose(disposing);
  105. }
  106. }
  107. }