Fix random failing of tests

Fully initialize the configuration manager at the init stage

```
Failed Jellyfin.Server.Integration.Tests.Controllers.ActivityLogControllerTests.ActivityLog_GetEntries_Ok [2 s]
  Error Message:
   MediaBrowser.Common.Extensions.ResourceNotFoundException : Configuration with key metadata not found.
  Stack Trace:
     at Emby.Server.Implementations.AppBase.BaseConfigurationManager.<>c__DisplayClass43_0.<GetConfiguration>b__0(String k) in D:\a\1\s\Emby.Server.Implementations\AppBase\BaseConfigurationManager.cs:line 309
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Emby.Server.Implementations.AppBase.BaseConfigurationManager.GetConfiguration(String key) in D:\a\1\s\Emby.Server.Implementations\AppBase\BaseConfigurationManager.cs:line 300
   at MediaBrowser.Common.Configuration.ConfigurationManagerExtensions.GetConfiguration[T](IConfigurationManager manager, String key) in D:\a\1\s\MediaBrowser.Common\Configuration\IConfigurationManager.cs:line 88
   at MediaBrowser.Controller.Library.MetadataConfigurationExtensions.GetMetadataConfiguration(IConfigurationManager config) in D:\a\1\s\MediaBrowser.Controller\Library\MetadataConfigurationStore.cs:line 28
   at Emby.Server.Implementations.Library.ResolverHelper.SetDateCreated(BaseItem item, IFileSystem fileSystem, FileSystemMetadata info) in D:\a\1\s\Emby.Server.Implementations\Library\ResolverHelper.cs:line 159
   at Emby.Server.Implementations.Library.ResolverHelper.EnsureDates(IFileSystem fileSystem, BaseItem item, ItemResolveArgs args) in D:\a\1\s\Emby.Server.Implementations\Library\ResolverHelper.cs:line 153
   at Emby.Server.Implementations.Library.ResolverHelper.SetInitialItemValues(BaseItem item, ItemResolveArgs args, IFileSystem fileSystem, ILibraryManager libraryManager) in D:\a\1\s\Emby.Server.Implementations\Library\ResolverHelper.cs:line 81
   at Emby.Server.Implementations.Library.LibraryManager.ResolveItem(ItemResolveArgs args, IItemResolver[] resolvers) in D:\a\1\s\Emby.Server.Implementations\Library\LibraryManager.cs:line 480
   at Emby.Server.Implementations.Library.LibraryManager.ResolvePath(FileSystemMetadata fileInfo, IDirectoryService directoryService, IItemResolver[] resolvers, Folder parent, String collectionType, LibraryOptions libraryOptions) in D:\a\1\s\Emby.Server.Implementations\Library\LibraryManager.cs:line 618
   at Emby.Server.Implementations.Library.LibraryManager.ResolvePath(FileSystemMetadata fileInfo, Folder parent) in D:\a\1\s\Emby.Server.Implementations\Library\LibraryManager.cs:line 536
   at Emby.Server.Implementations.Library.LibraryManager.CreateRootFolder() in D:\a\1\s\Emby.Server.Implementations\Library\LibraryManager.cs:line 732
   at Emby.Server.Implementations.Library.LibraryManager.get_RootFolder() in D:\a\1\s\Emby.Server.Implementations\Library\LibraryManager.cs:line 180
   at Emby.Server.Implementations.IO.LibraryMonitor.Start() in D:\a\1\s\Emby.Server.Implementations\IO\LibraryMonitor.cs:line 135
   at Emby.Server.Implementations.IO.LibraryMonitorStartup.RunAsync() in D:\a\1\s\Emby.Server.Implementations\IO\LibraryMonitorStartup.cs:line 26
   at Emby.Server.Implementations.ApplicationHost.StartEntryPoints(IEnumerable`1 entryPoints, Boolean isBeforeStartup)+MoveNext() in D:\a\1\s\Emby.Server.Implementations\ApplicationHost.cs:line 541
   at System.Threading.Tasks.Task.WhenAll(IEnumerable`1 tasks)
   at Emby.Server.Implementations.ApplicationHost.RunStartupTasksAsync(CancellationToken cancellationToken) in D:\a\1\s\Emby.Server.Implementations\ApplicationHost.cs:line 525
   at Jellyfin.Server.Integration.Tests.JellyfinApplicationFactory.CreateServer(IWebHostBuilder builder) in D:\a\1\s\tests\Jellyfin.Server.Integration.Tests\JellyfinApplicationFactory.cs:line 101
   at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.EnsureServer()
   at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateDefaultClient(DelegatingHandler[] handlers)
   at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateDefaultClient(Uri baseAddress, DelegatingHandler[] handlers)
   at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateClient(WebApplicationFactoryClientOptions options)
   at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateClient()
   at Jellyfin.Server.Integration.Tests.Controllers.ActivityLogControllerTests.ActivityLog_GetEntries_Ok() in D:\a\1\s\tests\Jellyfin.Server.Integration.Tests\Controllers\ActivityLogControllerTests.cs:line 21
--- End of stack trace from previous location ---

```
This commit is contained in:
Bond_009 2021-04-12 00:28:17 +02:00
parent 790f7430aa
commit a4ffc7a813
5 changed files with 59 additions and 65 deletions

View File

@ -210,7 +210,7 @@ namespace Emby.Server.Implementations
/// Gets or sets the configuration manager. /// Gets or sets the configuration manager.
/// </summary> /// </summary>
/// <value>The configuration manager.</value> /// <value>The configuration manager.</value>
protected IConfigurationManager ConfigurationManager { get; set; } public ServerConfigurationManager ConfigurationManager { get; set; }
/// <summary> /// <summary>
/// Gets or sets the service provider. /// Gets or sets the service provider.
@ -232,12 +232,6 @@ namespace Emby.Server.Implementations
/// </summary> /// </summary>
public string PublishedServerUrl => _startupOptions.PublishedServerUrl ?? _startupConfig[UdpServer.AddressOverrideConfigKey]; public string PublishedServerUrl => _startupOptions.PublishedServerUrl ?? _startupConfig[UdpServer.AddressOverrideConfigKey];
/// <summary>
/// Gets the server configuration manager.
/// </summary>
/// <value>The server configuration manager.</value>
public IServerConfigurationManager ServerConfigurationManager => (IServerConfigurationManager)ConfigurationManager;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ApplicationHost"/> class. /// Initializes a new instance of the <see cref="ApplicationHost"/> class.
/// </summary> /// </summary>
@ -255,43 +249,26 @@ namespace Emby.Server.Implementations
IFileSystem fileSystem, IFileSystem fileSystem,
IServiceCollection serviceCollection) IServiceCollection serviceCollection)
{ {
_xmlSerializer = new MyXmlSerializer();
ServiceCollection = serviceCollection;
ApplicationPaths = applicationPaths; ApplicationPaths = applicationPaths;
LoggerFactory = loggerFactory; LoggerFactory = loggerFactory;
_fileSystemManager = fileSystem;
ConfigurationManager = new ServerConfigurationManager(ApplicationPaths, LoggerFactory, _xmlSerializer, _fileSystemManager);
// Have to migrate settings here as migration subsystem not yet initialised.
MigrateNetworkConfiguration();
// Have to pre-register the NetworkConfigurationFactory, as the configuration sub-system is not yet initialised.
ConfigurationManager.RegisterConfiguration<NetworkConfigurationFactory>();
NetManager = new NetworkManager((IServerConfigurationManager)ConfigurationManager, LoggerFactory.CreateLogger<NetworkManager>());
Logger = LoggerFactory.CreateLogger<ApplicationHost>();
_startupOptions = options; _startupOptions = options;
_startupConfig = startupConfig; _startupConfig = startupConfig;
_fileSystemManager = fileSystem;
ServiceCollection = serviceCollection;
// Initialize runtime stat collection Logger = LoggerFactory.CreateLogger<ApplicationHost>();
if (ServerConfigurationManager.Configuration.EnableMetrics)
{
DotNetRuntimeStatsBuilder.Default().StartCollecting();
}
fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem)); fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem));
ApplicationVersion = typeof(ApplicationHost).Assembly.GetName().Version; ApplicationVersion = typeof(ApplicationHost).Assembly.GetName().Version;
ApplicationVersionString = ApplicationVersion.ToString(3); ApplicationVersionString = ApplicationVersion.ToString(3);
ApplicationUserAgent = Name.Replace(' ', '-') + "/" + ApplicationVersionString; ApplicationUserAgent = Name.Replace(' ', '-') + "/" + ApplicationVersionString;
_xmlSerializer = new MyXmlSerializer();
ConfigurationManager = new ServerConfigurationManager(ApplicationPaths, LoggerFactory, _xmlSerializer, _fileSystemManager);
_pluginManager = new PluginManager( _pluginManager = new PluginManager(
LoggerFactory.CreateLogger<PluginManager>(), LoggerFactory.CreateLogger<PluginManager>(),
this, this,
ServerConfigurationManager.Configuration, ConfigurationManager.Configuration,
ApplicationPaths.PluginsPath, ApplicationPaths.PluginsPath,
ApplicationVersion); ApplicationVersion);
} }
@ -306,9 +283,9 @@ namespace Emby.Server.Implementations
if (!File.Exists(path)) if (!File.Exists(path))
{ {
var networkSettings = new NetworkConfiguration(); var networkSettings = new NetworkConfiguration();
ClassMigrationHelper.CopyProperties(ServerConfigurationManager.Configuration, networkSettings); ClassMigrationHelper.CopyProperties(ConfigurationManager.Configuration, networkSettings);
_xmlSerializer.SerializeToFile(networkSettings, path); _xmlSerializer.SerializeToFile(networkSettings, path);
Logger?.LogDebug("Successfully migrated network settings."); Logger.LogDebug("Successfully migrated network settings.");
} }
} }
@ -545,7 +522,21 @@ namespace Emby.Server.Implementations
/// <inheritdoc/> /// <inheritdoc/>
public void Init() public void Init()
{ {
var networkConfiguration = ServerConfigurationManager.GetNetworkConfiguration(); DiscoverTypes();
ConfigurationManager.AddParts(GetExports<IConfigurationFactory>());
// Have to migrate settings here as migration subsystem not yet initialised.
MigrateNetworkConfiguration();
NetManager = new NetworkManager(ConfigurationManager, LoggerFactory.CreateLogger<NetworkManager>());
// Initialize runtime stat collection
if (ConfigurationManager.Configuration.EnableMetrics)
{
DotNetRuntimeStatsBuilder.Default().StartCollecting();
}
var networkConfiguration = ConfigurationManager.GetNetworkConfiguration();
HttpPort = networkConfiguration.HttpServerPortNumber; HttpPort = networkConfiguration.HttpServerPortNumber;
HttpsPort = networkConfiguration.HttpsPortNumber; HttpsPort = networkConfiguration.HttpsPortNumber;
@ -563,8 +554,6 @@ namespace Emby.Server.Implementations
}; };
Certificate = GetCertificate(CertificateInfo); Certificate = GetCertificate(CertificateInfo);
DiscoverTypes();
RegisterServices(); RegisterServices();
_pluginManager.RegisterServices(ServiceCollection); _pluginManager.RegisterServices(ServiceCollection);
@ -579,7 +568,8 @@ namespace Emby.Server.Implementations
ServiceCollection.AddMemoryCache(); ServiceCollection.AddMemoryCache();
ServiceCollection.AddSingleton(ConfigurationManager); ServiceCollection.AddSingleton<IServerConfigurationManager>(ConfigurationManager);
ServiceCollection.AddSingleton<IConfigurationManager>(ConfigurationManager);
ServiceCollection.AddSingleton<IApplicationHost>(this); ServiceCollection.AddSingleton<IApplicationHost>(this);
ServiceCollection.AddSingleton<IPluginManager>(_pluginManager); ServiceCollection.AddSingleton<IPluginManager>(_pluginManager);
ServiceCollection.AddSingleton<IApplicationPaths>(ApplicationPaths); ServiceCollection.AddSingleton<IApplicationPaths>(ApplicationPaths);
@ -606,8 +596,6 @@ namespace Emby.Server.Implementations
ServiceCollection.AddSingleton<IServerApplicationHost>(this); ServiceCollection.AddSingleton<IServerApplicationHost>(this);
ServiceCollection.AddSingleton<IServerApplicationPaths>(ApplicationPaths); ServiceCollection.AddSingleton<IServerApplicationPaths>(ApplicationPaths);
ServiceCollection.AddSingleton(ServerConfigurationManager);
ServiceCollection.AddSingleton<ILocalizationManager, LocalizationManager>(); ServiceCollection.AddSingleton<ILocalizationManager, LocalizationManager>();
ServiceCollection.AddSingleton<IBlurayExaminer, BdInfoExaminer>(); ServiceCollection.AddSingleton<IBlurayExaminer, BdInfoExaminer>();
@ -796,7 +784,7 @@ namespace Emby.Server.Implementations
{ {
// For now there's no real way to inject these properly // For now there's no real way to inject these properly
BaseItem.Logger = Resolve<ILogger<BaseItem>>(); BaseItem.Logger = Resolve<ILogger<BaseItem>>();
BaseItem.ConfigurationManager = ServerConfigurationManager; BaseItem.ConfigurationManager = ConfigurationManager;
BaseItem.LibraryManager = Resolve<ILibraryManager>(); BaseItem.LibraryManager = Resolve<ILibraryManager>();
BaseItem.ProviderManager = Resolve<IProviderManager>(); BaseItem.ProviderManager = Resolve<IProviderManager>();
BaseItem.LocalizationManager = Resolve<ILocalizationManager>(); BaseItem.LocalizationManager = Resolve<ILocalizationManager>();
@ -818,13 +806,12 @@ namespace Emby.Server.Implementations
/// </summary> /// </summary>
private void FindParts() private void FindParts()
{ {
if (!ServerConfigurationManager.Configuration.IsPortAuthorized) if (!ConfigurationManager.Configuration.IsPortAuthorized)
{ {
ServerConfigurationManager.Configuration.IsPortAuthorized = true; ConfigurationManager.Configuration.IsPortAuthorized = true;
ConfigurationManager.SaveConfiguration(); ConfigurationManager.SaveConfiguration();
} }
ConfigurationManager.AddParts(GetExports<IConfigurationFactory>());
_pluginManager.CreatePlugins(); _pluginManager.CreatePlugins();
_urlPrefixes = GetUrlPrefixes().ToArray(); _urlPrefixes = GetUrlPrefixes().ToArray();
@ -928,7 +915,7 @@ namespace Emby.Server.Implementations
protected void OnConfigurationUpdated(object sender, EventArgs e) protected void OnConfigurationUpdated(object sender, EventArgs e)
{ {
var requiresRestart = false; var requiresRestart = false;
var networkConfiguration = ServerConfigurationManager.GetNetworkConfiguration(); var networkConfiguration = ConfigurationManager.GetNetworkConfiguration();
// Don't do anything if these haven't been set yet // Don't do anything if these haven't been set yet
if (HttpPort != 0 && HttpsPort != 0) if (HttpPort != 0 && HttpsPort != 0)
@ -937,10 +924,10 @@ namespace Emby.Server.Implementations
if (networkConfiguration.HttpServerPortNumber != HttpPort || if (networkConfiguration.HttpServerPortNumber != HttpPort ||
networkConfiguration.HttpsPortNumber != HttpsPort) networkConfiguration.HttpsPortNumber != HttpsPort)
{ {
if (ServerConfigurationManager.Configuration.IsPortAuthorized) if (ConfigurationManager.Configuration.IsPortAuthorized)
{ {
ServerConfigurationManager.Configuration.IsPortAuthorized = false; ConfigurationManager.Configuration.IsPortAuthorized = false;
ServerConfigurationManager.SaveConfiguration(); ConfigurationManager.SaveConfiguration();
requiresRestart = true; requiresRestart = true;
} }
@ -1156,7 +1143,7 @@ namespace Emby.Server.Implementations
} }
/// <inheritdoc/> /// <inheritdoc/>
public bool ListenWithHttps => Certificate != null && ServerConfigurationManager.GetNetworkConfiguration().EnableHttps; public bool ListenWithHttps => Certificate != null && ConfigurationManager.GetNetworkConfiguration().EnableHttps;
/// <inheritdoc/> /// <inheritdoc/>
public string GetSmartApiUrl(IPAddress ipAddress, int? port = null) public string GetSmartApiUrl(IPAddress ipAddress, int? port = null)
@ -1240,14 +1227,14 @@ namespace Emby.Server.Implementations
Scheme = scheme ?? (ListenWithHttps ? Uri.UriSchemeHttps : Uri.UriSchemeHttp), Scheme = scheme ?? (ListenWithHttps ? Uri.UriSchemeHttps : Uri.UriSchemeHttp),
Host = host, Host = host,
Port = port ?? (ListenWithHttps ? HttpsPort : HttpPort), Port = port ?? (ListenWithHttps ? HttpsPort : HttpPort),
Path = ServerConfigurationManager.GetNetworkConfiguration().BaseUrl Path = ConfigurationManager.GetNetworkConfiguration().BaseUrl
}.ToString().TrimEnd('/'); }.ToString().TrimEnd('/');
} }
public string FriendlyName => public string FriendlyName =>
string.IsNullOrEmpty(ServerConfigurationManager.Configuration.ServerName) string.IsNullOrEmpty(ConfigurationManager.Configuration.ServerName)
? Environment.MachineName ? Environment.MachineName
: ServerConfigurationManager.Configuration.ServerName; : ConfigurationManager.Configuration.ServerName;
/// <summary> /// <summary>
/// Shuts down. /// Shuts down.

View File

@ -40,15 +40,15 @@ namespace Jellyfin.Server.Migrations
.Select(m => ActivatorUtilities.CreateInstance(host.ServiceProvider, m)) .Select(m => ActivatorUtilities.CreateInstance(host.ServiceProvider, m))
.OfType<IMigrationRoutine>() .OfType<IMigrationRoutine>()
.ToArray(); .ToArray();
var migrationOptions = ((IConfigurationManager)host.ServerConfigurationManager).GetConfiguration<MigrationOptions>(MigrationsListStore.StoreKey); var migrationOptions = ((IConfigurationManager)host.ConfigurationManager).GetConfiguration<MigrationOptions>(MigrationsListStore.StoreKey);
if (!host.ServerConfigurationManager.Configuration.IsStartupWizardCompleted && migrationOptions.Applied.Count == 0) if (!host.ConfigurationManager.Configuration.IsStartupWizardCompleted && migrationOptions.Applied.Count == 0)
{ {
// If startup wizard is not finished, this is a fresh install. // If startup wizard is not finished, this is a fresh install.
// Don't run any migrations, just mark all of them as applied. // Don't run any migrations, just mark all of them as applied.
logger.LogInformation("Marking all known migrations as applied because this is a fresh install"); logger.LogInformation("Marking all known migrations as applied because this is a fresh install");
migrationOptions.Applied.AddRange(migrations.Where(m => !m.PerformOnNewInstall).Select(m => (m.Id, m.Name))); migrationOptions.Applied.AddRange(migrations.Where(m => !m.PerformOnNewInstall).Select(m => (m.Id, m.Name)));
host.ServerConfigurationManager.SaveConfiguration(MigrationsListStore.StoreKey, migrationOptions); host.ConfigurationManager.SaveConfiguration(MigrationsListStore.StoreKey, migrationOptions);
} }
var appliedMigrationIds = migrationOptions.Applied.Select(m => m.Id).ToHashSet(); var appliedMigrationIds = migrationOptions.Applied.Select(m => m.Id).ToHashSet();
@ -77,7 +77,7 @@ namespace Jellyfin.Server.Migrations
// Mark the migration as completed // Mark the migration as completed
logger.LogInformation("Migration '{Name}' applied successfully", migrationRoutine.Name); logger.LogInformation("Migration '{Name}' applied successfully", migrationRoutine.Name);
migrationOptions.Applied.Add((migrationRoutine.Id, migrationRoutine.Name)); migrationOptions.Applied.Add((migrationRoutine.Id, migrationRoutine.Name));
host.ServerConfigurationManager.SaveConfiguration(MigrationsListStore.StoreKey, migrationOptions); host.ConfigurationManager.SaveConfiguration(MigrationsListStore.StoreKey, migrationOptions);
logger.LogDebug("Migration '{Name}' marked as applied in configuration.", migrationRoutine.Name); logger.LogDebug("Migration '{Name}' marked as applied in configuration.", migrationRoutine.Name);
} }
} }

View File

@ -173,7 +173,7 @@ namespace Jellyfin.Server
// If hosting the web client, validate the client content path // If hosting the web client, validate the client content path
if (startupConfig.HostWebClient()) if (startupConfig.HostWebClient())
{ {
string? webContentPath = appHost.ServerConfigurationManager.ApplicationPaths.WebPath; string? webContentPath = appHost.ConfigurationManager.ApplicationPaths.WebPath;
if (!Directory.Exists(webContentPath) || Directory.GetFiles(webContentPath).Length == 0) if (!Directory.Exists(webContentPath) || Directory.GetFiles(webContentPath).Length == 0)
{ {
throw new InvalidOperationException( throw new InvalidOperationException(

View File

@ -0,0 +1,15 @@
#pragma warning disable CS1591
using MediaBrowser.Common.Configuration;
using MediaBrowser.Model.Configuration;
namespace MediaBrowser.Controller.Library
{
public static class MetadataConfigurationExtensions
{
public static MetadataConfiguration GetMetadataConfiguration(this IConfigurationManager config)
{
return config.GetConfiguration<MetadataConfiguration>("metadata");
}
}
}

View File

@ -14,18 +14,10 @@ namespace MediaBrowser.Controller.Library
{ {
new ConfigurationStore new ConfigurationStore
{ {
Key = "metadata", Key = "metadata",
ConfigurationType = typeof(MetadataConfiguration) ConfigurationType = typeof(MetadataConfiguration)
} }
}; };
} }
} }
public static class MetadataConfigurationExtensions
{
public static MetadataConfiguration GetMetadataConfiguration(this IConfigurationManager config)
{
return config.GetConfiguration<MetadataConfiguration>("metadata");
}
}
} }