Files
Umbraco-CMS/src/Umbraco.Tests.Integration/RuntimeTests.cs

240 lines
9.3 KiB
C#

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Moq;
using NUnit.Framework;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Smidge;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
using Umbraco.Core.Logging;
using Umbraco.Core.Runtime;
using Umbraco.Tests.Common;
using Umbraco.Tests.Integration.Extensions;
using Umbraco.Tests.Integration.Implementations;
using Umbraco.Tests.Integration.Testing;
using Umbraco.Web.Common.AspNetCore;
using Umbraco.Extensions;
using Umbraco.Tests.Common.Builders;
using Microsoft.Extensions.Options;
namespace Umbraco.Tests.Integration
{
[TestFixture]
public class RuntimeTests
{
[TearDown]
public void TearDown()
{
MyComponent.Reset();
MyComposer.Reset();
}
[SetUp]
public void Setup()
{
MyComponent.Reset();
MyComposer.Reset();
}
/// <summary>
/// Manually configure the containers/dependencies and call Boot on Core runtime
/// </summary>
[Test]
public void Boot_Core_Runtime()
{
// LightInject / Umbraco
var container = UmbracoServiceProviderFactory.CreateServiceContainer();
var serviceProviderFactory = new UmbracoServiceProviderFactory(container, false);
var umbracoContainer = serviceProviderFactory.GetContainer();
// Special case since we are not using the Generic Host, we need to manually add an AspNetCore service to the container
umbracoContainer.Register(x => Mock.Of<IHostApplicationLifetime>());
var testHelper = new TestHelper();
var configs = testHelper.GetConfigs();
var globalSettings = new GlobalSettingsBuilder().Build();
var connectionStrings = new ConnectionStringsBuilder().Build();
// Create the core runtime
var coreRuntime = new CoreRuntime(configs, globalSettings, connectionStrings, testHelper.GetUmbracoVersion(),
testHelper.IOHelper, testHelper.Logger, testHelper.Profiler, testHelper.UmbracoBootPermissionChecker,
testHelper.GetHostingEnvironment(), testHelper.GetBackOfficeInfo(), testHelper.DbProviderFactoryCreator,
testHelper.MainDom, testHelper.GetTypeFinder(), NoAppCache.Instance);
// boot it!
var factory = coreRuntime.Configure(umbracoContainer);
Assert.IsTrue(coreRuntime.MainDom.IsMainDom);
Assert.IsNull(coreRuntime.State.BootFailedException);
Assert.AreEqual(RuntimeLevel.Install, coreRuntime.State.Level);
Assert.IsTrue(MyComposer.IsComposed);
Assert.IsFalse(MyComponent.IsInit);
Assert.IsFalse(MyComponent.IsTerminated);
// TODO: found these registration were necessary here (as we haven't called the HostBuilder?), as dependencies for ComponentCollection
// are not resolved. Need to check this if these explicit registrations are the best way to handle this.
var contentSettings = new ContentSettingsBuilder().Build();
var coreDebugSettings = new CoreDebugSettingsBuilder().Build();
var nuCacheSettings = new NuCacheSettingsBuilder().Build();
var requestHandlerSettings = new RequestHandlerSettingsBuilder().Build();
var userPasswordConfigurationSettings = new UserPasswordConfigurationSettingsBuilder().Build();
var webRoutingSettings = new WebRoutingSettingsBuilder().Build();
umbracoContainer.Register(x => Options.Create(globalSettings));
umbracoContainer.Register(x => Options.Create(contentSettings));
umbracoContainer.Register(x => Options.Create(coreDebugSettings));
umbracoContainer.Register(x => Options.Create(nuCacheSettings));
umbracoContainer.Register(x => Options.Create(requestHandlerSettings));
umbracoContainer.Register(x => Options.Create(userPasswordConfigurationSettings));
umbracoContainer.Register(x => Options.Create(webRoutingSettings));
coreRuntime.Start();
Assert.IsTrue(MyComponent.IsInit);
Assert.IsFalse(MyComponent.IsTerminated);
Assertions.AssertContainer(umbracoContainer.Container, reportOnly: true); // TODO Change that to false eventually when we clean up the container
coreRuntime.Terminate();
Assert.IsTrue(MyComponent.IsTerminated);
}
/// <summary>
/// Calling AddUmbracoCore to configure the container
/// </summary>
[Test]
public async Task AddUmbracoCore()
{
var umbracoContainer = UmbracoIntegrationTest.GetUmbracoContainer(out var serviceProviderFactory);
var testHelper = new TestHelper();
var hostBuilder = new HostBuilder()
.UseUmbraco(serviceProviderFactory)
.ConfigureServices((hostContext, services) =>
{
var webHostEnvironment = testHelper.GetWebHostEnvironment();
services.AddSingleton(testHelper.DbProviderFactoryCreator);
services.AddRequiredNetCoreServices(testHelper, webHostEnvironment);
// Add it!
services.AddUmbracoConfiguration(hostContext.Configuration);
services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly, NoAppCache.Instance, testHelper.GetLoggingConfiguration(), out _);
});
var host = await hostBuilder.StartAsync();
var app = new ApplicationBuilder(host.Services);
// assert results
var runtimeState = app.ApplicationServices.GetRequiredService<IRuntimeState>();
var mainDom = app.ApplicationServices.GetRequiredService<IMainDom>();
Assert.IsFalse(mainDom.IsMainDom); // We haven't "Started" the runtime yet
Assert.IsNull(runtimeState.BootFailedException);
Assert.AreEqual(RuntimeLevel.Install, runtimeState.Level);
Assert.IsFalse(MyComponent.IsInit); // We haven't "Started" the runtime yet
await host.StopAsync();
Assert.IsFalse(MyComponent.IsTerminated); // we didn't "Start" the runtime so nothing was registered for shutdown
}
/// <summary>
/// Calling AddUmbracoCore to configure the container and UseUmbracoCore to start the runtime
/// </summary>
/// <returns></returns>
[Test]
public async Task UseUmbracoCore()
{
var umbracoContainer = UmbracoIntegrationTest.GetUmbracoContainer(out var serviceProviderFactory);
var testHelper = new TestHelper();
var hostBuilder = new HostBuilder()
.UseUmbraco(serviceProviderFactory)
.ConfigureServices((hostContext, services) =>
{
var webHostEnvironment = testHelper.GetWebHostEnvironment();
services.AddSingleton(testHelper.DbProviderFactoryCreator);
services.AddRequiredNetCoreServices(testHelper, webHostEnvironment);
// Add it!
services.AddUmbracoConfiguration(hostContext.Configuration);
services.AddUmbracoCore(webHostEnvironment, umbracoContainer, GetType().Assembly, NoAppCache.Instance, testHelper.GetLoggingConfiguration(), out _);
});
var host = await hostBuilder.StartAsync();
var app = new ApplicationBuilder(host.Services);
app.UseUmbracoCore();
// assert results
var runtimeState = app.ApplicationServices.GetRequiredService<IRuntimeState>();
var mainDom = app.ApplicationServices.GetRequiredService<IMainDom>();
Assert.IsTrue(mainDom.IsMainDom);
Assert.IsNull(runtimeState.BootFailedException);
Assert.AreEqual(RuntimeLevel.Install, runtimeState.Level);
Assert.IsTrue(MyComponent.IsInit);
await host.StopAsync();
Assert.IsTrue(MyComponent.IsTerminated);
}
[RuntimeLevel(MinLevel = RuntimeLevel.Install)]
public class MyComposer : IUserComposer
{
public void Compose(Composition composition)
{
composition.Components().Append<MyComponent>();
IsComposed = true;
}
public static void Reset()
{
IsComposed = false;
}
public static bool IsComposed { get; private set; }
}
public class MyComponent : IComponent
{
public static bool IsInit { get; private set; }
public static bool IsTerminated { get; private set; }
private readonly ILogger _logger;
public MyComponent(ILogger logger)
{
_logger = logger;
}
public void Initialize()
{
IsInit = true;
}
public void Terminate()
{
IsTerminated = true;
}
public static void Reset()
{
IsTerminated = false;
IsInit = false;
}
}
}
}