pschelpdesk/Vendor/Prise.Tests/AssemblyLoading/DefaultAssemblyLoadContextTests/Base.cs
2024-11-04 20:45:34 +01:00

129 lines
5.8 KiB
C#

using Moq;
using Prise.AssemblyLoading;
using Prise.Tests.Plugins;
using System;
using System.IO;
using System.Reflection;
using System.Runtime.Loader;
using System.Threading.Tasks;
namespace Prise.Tests.AssemblyLoading.DefaultAssemblyLoadContextTests
{
public class AssemblyLoadContextWithLoadedPluginTestContext
{
public string PluginAssemblyPath { get; set; }
public string InitialPluginLoadDirectory { get; set; }
public string NewtonsoftAssemblyPath { get; set; }
public AssemblyName NewtonsoftAssemblyName { get; set; }
public Assembly NewtonsoftAssembly { get; set; }
public IPluginLoadContext PluginLoadContext { get; set; }
public TestContext<IAssemblyLoadContext> TestContext { get; set; }
public IAssemblyLoadContext Sut() => this.TestContext.Sut();
public Mock<M> GetMock<M>()
where M : class
{
return this.TestContext.GetMock<M>();
}
}
public class TestWithLoadedPluginBase : Base
{
protected async Task<AssemblyLoadContextWithLoadedPluginTestContext> SetupLoadedPluginTextContext(Action<PluginLoadContext> configure = null)
{
var testContext = SetupAssemblyLoadContext();
var loadContext = testContext.Sut();
var fileSystemUtility = testContext.GetMock<IFileSystemUtilities>();
var assemblyLoadStrategy = testContext.GetMock<IAssemblyLoadStrategy>();
var pluginDependencyContext = testContext.GetMock<IPluginDependencyContext>();
var pluginDependencyProvider = testContext.GetMock<IPluginDependencyContextProvider>();
var pluginAssemblyPath = Path.Combine(GetPathToAssemblies(), "Prise.Tests.dll");
var initialPluginLoadDirectory = Path.GetDirectoryName(pluginAssemblyPath);
var newtonsoftAssemblyPath = Path.Combine(GetPathToAssemblies(), "Newtonsoft.Json.dll");
var newtonsoftAssembly = Assembly.LoadFile(newtonsoftAssemblyPath);
var newtonsoftAssemblyName = AssemblyLoadContext.GetAssemblyName(newtonsoftAssemblyPath);
var assemblyStream = File.OpenRead(pluginAssemblyPath);
var pluginLoadContext = GetPluginLoadContext(pluginAssemblyPath, configure);
fileSystemUtility.Setup(f => f.EnsureFileExists(pluginAssemblyPath)).Returns(pluginAssemblyPath);
fileSystemUtility.Setup(f => f.ReadFileFromDisk(pluginAssemblyPath)).ReturnsAsync(assemblyStream);
pluginDependencyProvider.Setup(p => p.FromPluginLoadContext(pluginLoadContext)).ReturnsAsync(pluginDependencyContext.Object);
// This must be invoked before anything else can be tested
await loadContext.LoadPluginAssembly(pluginLoadContext);
return new AssemblyLoadContextWithLoadedPluginTestContext
{
TestContext = testContext,
InitialPluginLoadDirectory = initialPluginLoadDirectory,
PluginAssemblyPath = pluginAssemblyPath,
PluginLoadContext = pluginLoadContext,
NewtonsoftAssembly = newtonsoftAssembly,
NewtonsoftAssemblyName = newtonsoftAssemblyName,
NewtonsoftAssemblyPath = newtonsoftAssemblyPath,
};
}
}
public class Base : TestBase
{
protected T InvokeProtectedMethodOnLoadContextAndGetResult<T>(IAssemblyLoadContext loadContext, string methodName, params object[] args)
{
return (T)loadContext
.GetType()
.GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic)
.Invoke(loadContext, args);
}
protected IPluginLoadContext GetPluginLoadContext(string pluginAssemblyPath, Action<PluginLoadContext> configure = null)
{
var pluginLoadContext = new PluginLoadContext(pluginAssemblyPath, GetContractType(), "netcoreapp3.1");
configure?.Invoke(pluginLoadContext);
return pluginLoadContext;
}
protected Type GetContractType()
{
return TestableTypeBuilder.New()
.WithName("IMyTestType")
.WithNamespace("Test.Type")
.Build();
}
protected TestContext<IAssemblyLoadContext> SetupAssemblyLoadContext()
{
var nativeUnloader = this.mockRepository.Create<INativeAssemblyUnloader>();
var pluginDependencyResolver = this.mockRepository.Create<IPluginDependencyResolver>();
var assemblyLoadStrategy = this.mockRepository.Create<IAssemblyLoadStrategy>();
var pluginDependencyContext = this.mockRepository.Create<IPluginDependencyContext>();
var resolver = this.mockRepository.Create<IAssemblyDependencyResolver>();
var fileSystemUtility = this.mockRepository.Create<IFileSystemUtilities>();
var runtimeDefaultAssemblyLoadContext = this.mockRepository.Create<IRuntimeDefaultAssemblyContext>();
var pluginDependencyContextProvider = this.mockRepository.Create<IPluginDependencyContextProvider>();
var loadContext = new DefaultAssemblyLoadContext(
() => nativeUnloader.Object,
() => pluginDependencyResolver.Object,
() => assemblyLoadStrategy.Object,
(s) => resolver.Object,
() => fileSystemUtility.Object,
() => runtimeDefaultAssemblyLoadContext.Object,
() => pluginDependencyContextProvider.Object);
return new TestContext<IAssemblyLoadContext>(loadContext,
nativeUnloader,
pluginDependencyResolver,
assemblyLoadStrategy,
pluginDependencyContext,
resolver,
fileSystemUtility,
runtimeDefaultAssemblyLoadContext,
pluginDependencyContextProvider
);
}
}
}