diff options
author | Levi Broderick <levib@microsoft.com> | 2019-04-10 22:56:33 -0700 |
---|---|---|
committer | Levi Broderick <levib@microsoft.com> | 2019-04-10 22:56:33 -0700 |
commit | eda0c04f28b9d0ecf3d29fc2c860eac1606d9e6d (patch) | |
tree | 0cadf7e159302d9fc6e193420f17f2e4f707dc98 /tests | |
parent | bae40fa2c2d8f9acb9b8148b7d6a6b91ace55058 (diff) | |
parent | 232ba42911f8266a96f73a77bc1e18f431d96862 (diff) | |
download | coreclr-eda0c04f28b9d0ecf3d29fc2c860eac1606d9e6d.tar.gz coreclr-eda0c04f28b9d0ecf3d29fc2c860eac1606d9e6d.tar.bz2 coreclr-eda0c04f28b9d0ecf3d29fc2c860eac1606d9e6d.zip |
Merge remote-tracking branch 'origin/master' into utf8_validation_apis_3
Diffstat (limited to 'tests')
21 files changed, 1218 insertions, 17 deletions
diff --git a/tests/issues.targets b/tests/issues.targets index 79e559838d..c540e01dde 100644 --- a/tests/issues.targets +++ b/tests/issues.targets @@ -329,6 +329,9 @@ <ExcludeList Include="$(XunitTestBinBase)/Interop/COM/NETClients/Events/NETClientEvents/*"> <Issue>22784</Issue> </ExcludeList> + <ExcludeList Include="$(XunitTestBinBase)/Interop/COM/NETClients/ConsumeNETServer/ConsumeNETServer/*"> + <Issue>20682</Issue> + </ExcludeList> </ItemGroup> <!-- Windows arm64 specific excludes --> diff --git a/tests/src/Interop/COM/NETClients/Aggregation/NETClientAggregation.csproj b/tests/src/Interop/COM/NETClients/Aggregation/NETClientAggregation.csproj index 182ba923c9..63df657451 100644 --- a/tests/src/Interop/COM/NETClients/Aggregation/NETClientAggregation.csproj +++ b/tests/src/Interop/COM/NETClients/Aggregation/NETClientAggregation.csproj @@ -30,7 +30,7 @@ </PropertyGroup> <ItemGroup> <Compile Include="Program.cs" /> - <Compile Include="../../ServerContracts/NativeServers.cs" /> + <Compile Include="../../ServerContracts/Server.CoClasses.cs" /> <Compile Include="../../ServerContracts/Server.Contracts.cs" /> <Compile Include="../../ServerContracts/ServerGuids.cs" /> </ItemGroup> diff --git a/tests/src/Interop/COM/NETClients/ConsumeNETServer/App.manifest b/tests/src/Interop/COM/NETClients/ConsumeNETServer/App.manifest new file mode 100644 index 0000000000..58fc0a2781 --- /dev/null +++ b/tests/src/Interop/COM/NETClients/ConsumeNETServer/App.manifest @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"> + <assemblyIdentity + type="win32" + name="ConsumeNETServer" + version="1.0.0.0" /> + + <dependency> + <dependentAssembly> + <!-- RegFree COM to activate Managed Server --> + <assemblyIdentity + type="win32" + name="CoreShim.X" + version="1.0.0.0"/> + </dependentAssembly> + </dependency> + +</assembly> diff --git a/tests/src/Interop/COM/NETClients/ConsumeNETServer/ConsumeNETServer.csproj b/tests/src/Interop/COM/NETClients/ConsumeNETServer/ConsumeNETServer.csproj new file mode 100644 index 0000000000..9202a9757a --- /dev/null +++ b/tests/src/Interop/COM/NETClients/ConsumeNETServer/ConsumeNETServer.csproj @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <AssemblyName>ConsumeNETServer</AssemblyName> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{4BDB75BD-30D8-4603-98DB-C6CFDC5F6F0E}</ProjectGuid> + <OutputType>Exe</OutputType> + <ProjectTypeGuids>{209912F9-0DA1-4184-9CC1-8D583BAF4A28};{87799F5D-CEBD-499D-BDBA-B2C6105CD766}</ProjectTypeGuids> + <ApplicationManifest>App.manifest</ApplicationManifest> + <CLRTestScriptLocalCoreShim>true</CLRTestScriptLocalCoreShim> + <RequiresMockHostPolicy>true</RequiresMockHostPolicy> + + <!-- Blocked on ILAsm supporting embedding resources. See https://github.com/dotnet/coreclr/issues/20819 --> + <IlrtTestKind>BuildOnly</IlrtTestKind> + + <!-- Blocked on CrossGen.exe supporting embedding resources. See https://github.com/dotnet/coreclr/issues/21006 --> + <CrossGenTest>false</CrossGenTest> + + <!-- Test unsupported outside of windows --> + <TestUnsupportedOutsideWindows>true</TestUnsupportedOutsideWindows> + <DisableProjectBuild Condition="'$(TargetsUnix)' == 'true'">true</DisableProjectBuild> + <!-- This test would require the runincontext.exe to include App.manifest describing the COM interfaces --> + <UnloadabilityIncompatible>true</UnloadabilityIncompatible> + + <!-- Suppress warning about conflicting type names. This occurs because of the reference to NETServer. + The reference is only to ensure the project is built and properly copied. The test itself uses + COM to activate the server rather than typical class activation via 'new' --> + <NoWarn>$(NoWarn),0436</NoWarn> + </PropertyGroup> + <!-- Default configurations to help VS understand the configurations --> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"> + </PropertyGroup> + <ItemGroup> + <Compile Include="Program.cs" /> + <Compile Include="../../ServerContracts/Server.CoClasses.cs" /> + <Compile Include="../../ServerContracts/Server.Contracts.cs" /> + <Compile Include="../../ServerContracts/ServerGuids.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="../../NETServer/NETServer.csproj" /> + <ProjectReference Include="../../../../Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj" /> + </ItemGroup> + <ItemGroup> + <None Include="CoreShim.X.manifest"> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Interop/COM/NETClients/ConsumeNETServer/CoreShim.X.manifest b/tests/src/Interop/COM/NETClients/ConsumeNETServer/CoreShim.X.manifest new file mode 100644 index 0000000000..abb39fbb21 --- /dev/null +++ b/tests/src/Interop/COM/NETClients/ConsumeNETServer/CoreShim.X.manifest @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + +<assemblyIdentity + type="win32" + name="CoreShim.X" + version="1.0.0.0" /> + +<file name="CoreShim.dll"> + <!-- ConsumeNETServerTesting --> + <comClass + clsid="{DE4ACF53-5957-4D31-8BE2-EA6C80683246}" + threadingModel="Both" /> +</file> + +</assembly> diff --git a/tests/src/Interop/COM/NETClients/ConsumeNETServer/Program.cs b/tests/src/Interop/COM/NETClients/ConsumeNETServer/Program.cs new file mode 100644 index 0000000000..1a2aa68d99 --- /dev/null +++ b/tests/src/Interop/COM/NETClients/ConsumeNETServer/Program.cs @@ -0,0 +1,117 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace NetClient +{ + using System; + using System.Collections.Generic; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + using TestLibrary; + using Server.Contract; + + using CoClass = Server.Contract.Servers; + + class Program + { + static void Validate_Activation() + { + Console.WriteLine($"{nameof(Validate_Activation)}..."); + + var test = new CoClass.ConsumeNETServerTesting(); + test.ReleaseResources(); + + // The CoClass should be the activated type, _not_ the activation interface. + Assert.AreEqual(test.GetType(), typeof(CoClass.ConsumeNETServerTestingClass)); + } + + static void Validate_CCW_Wasnt_Unwrapped() + { + Console.WriteLine($"{nameof(Validate_CCW_Wasnt_Unwrapped)}..."); + + var test = new CoClass.ConsumeNETServerTesting(); + test.ReleaseResources(); + + // The CoClass should be the activated type, _not_ the implementation class. + // This indicates the real implementation class is wrapped in its CCW and exposed + // to the runtime as an RCW. + Assert.AreNotEqual(test.GetType(), typeof(ConsumeNETServerTesting)); + } + + static void Validate_Client_CCW_RCW() + { + Console.WriteLine($"{nameof(Validate_Client_CCW_RCW)}..."); + + IntPtr ccw = IntPtr.Zero; + + // Validate the client side view is consistent + var test = new CoClass.ConsumeNETServerTesting(); + try + { + ccw = test.GetCCW(); + object rcw = Marshal.GetObjectForIUnknown(ccw); + object inst = test.GetRCW(); + Assert.AreEqual(rcw, inst); + } + finally + { + test.ReleaseResources(); + } + } + + static void Validate_Server_CCW_RCW() + { + Console.WriteLine($"{nameof(Validate_Server_CCW_RCW)}..."); + + // Validate the server side view is consistent + var test = new CoClass.ConsumeNETServerTesting(); + try + { + Assert.IsTrue(test.EqualByCCW(test)); + Assert.IsTrue(test.NotEqualByRCW(test)); + } + finally + { + test.ReleaseResources(); + } + } + + static int Main(string[] doNotUse) + { + // RegFree COM is not supported on Windows Nano + if (Utilities.IsWindowsNanoServer) + { + return 100; + } + + // Initialize CoreShim and hostpolicymock + HostPolicyMock.Initialize(Environment.CurrentDirectory, null); + Environment.SetEnvironmentVariable("CORESHIM_COMACT_ASSEMBLYNAME", "NETServer"); + Environment.SetEnvironmentVariable("CORESHIM_COMACT_TYPENAME", "ConsumeNETServerTesting"); + + try + { + using (HostPolicyMock.Mock_corehost_resolve_component_dependencies( + 0, + string.Empty, + string.Empty, + string.Empty)) + { + Validate_Activation(); + Validate_CCW_Wasnt_Unwrapped(); + Validate_Client_CCW_RCW(); + Validate_Server_CCW_RCW(); + } + } + catch (Exception e) + { + Console.WriteLine($"Test Failure: {e}"); + return 101; + } + + return 100; + } + } +} diff --git a/tests/src/Interop/COM/NETClients/Events/NETClientEvents.csproj b/tests/src/Interop/COM/NETClients/Events/NETClientEvents.csproj index fccbee9258..f346a0227e 100644 --- a/tests/src/Interop/COM/NETClients/Events/NETClientEvents.csproj +++ b/tests/src/Interop/COM/NETClients/Events/NETClientEvents.csproj @@ -30,7 +30,7 @@ </PropertyGroup> <ItemGroup> <Compile Include="Program.cs" /> - <Compile Include="../../ServerContracts/NativeServers.cs" /> + <Compile Include="../../ServerContracts/Server.CoClasses.cs" /> <Compile Include="../../ServerContracts/Server.Contracts.cs" /> <Compile Include="../../ServerContracts/Server.Events.cs" /> <Compile Include="../../ServerContracts/ServerGuids.cs" /> diff --git a/tests/src/Interop/COM/NETClients/IDispatch/NETClientIDispatch.csproj b/tests/src/Interop/COM/NETClients/IDispatch/NETClientIDispatch.csproj index 4fd95f6694..a99416ba28 100644 --- a/tests/src/Interop/COM/NETClients/IDispatch/NETClientIDispatch.csproj +++ b/tests/src/Interop/COM/NETClients/IDispatch/NETClientIDispatch.csproj @@ -30,7 +30,7 @@ </PropertyGroup> <ItemGroup> <Compile Include="Program.cs" /> - <Compile Include="../../ServerContracts/NativeServers.cs" /> + <Compile Include="../../ServerContracts/Server.CoClasses.cs" /> <Compile Include="../../ServerContracts/Server.Contracts.cs" /> <Compile Include="../../ServerContracts/ServerGuids.cs" /> </ItemGroup> diff --git a/tests/src/Interop/COM/NETClients/Licensing/NETClientLicense.csproj b/tests/src/Interop/COM/NETClients/Licensing/NETClientLicense.csproj index 52154225c4..a46a2a2619 100644 --- a/tests/src/Interop/COM/NETClients/Licensing/NETClientLicense.csproj +++ b/tests/src/Interop/COM/NETClients/Licensing/NETClientLicense.csproj @@ -30,7 +30,7 @@ </PropertyGroup> <ItemGroup> <Compile Include="Program.cs" /> - <Compile Include="../../ServerContracts/NativeServers.cs" /> + <Compile Include="../../ServerContracts/Server.CoClasses.cs" /> <Compile Include="../../ServerContracts/Server.Contracts.cs" /> <Compile Include="../../ServerContracts/ServerGuids.cs" /> </ItemGroup> diff --git a/tests/src/Interop/COM/NETClients/Primitives/NETClientPrimitives.csproj b/tests/src/Interop/COM/NETClients/Primitives/NETClientPrimitives.csproj index 81c06a3f3c..c1f38576e3 100644 --- a/tests/src/Interop/COM/NETClients/Primitives/NETClientPrimitives.csproj +++ b/tests/src/Interop/COM/NETClients/Primitives/NETClientPrimitives.csproj @@ -35,7 +35,7 @@ <Compile Include="NumericTests.cs" /> <Compile Include="StringTests.cs" /> <Compile Include="ColorTests.cs" /> - <Compile Include="../../ServerContracts/NativeServers.cs" /> + <Compile Include="../../ServerContracts/Server.CoClasses.cs" /> <Compile Include="../../ServerContracts/Server.Contracts.cs" /> <Compile Include="../../ServerContracts/ServerGuids.cs" /> </ItemGroup> diff --git a/tests/src/Interop/COM/NETServer/ConsumeNETServerTesting.cs b/tests/src/Interop/COM/NETServer/ConsumeNETServerTesting.cs new file mode 100644 index 0000000000..d8dba73982 --- /dev/null +++ b/tests/src/Interop/COM/NETServer/ConsumeNETServerTesting.cs @@ -0,0 +1,51 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +[ComVisible(true)] +[Guid(Server.Contract.Guids.ConsumeNETServerTesting)] +public class ConsumeNETServerTesting : Server.Contract.IConsumeNETServer +{ + private IntPtr _ccw; + private object _rcwUnwrapped; + + public ConsumeNETServerTesting() + { + _ccw = Marshal.GetIUnknownForObject(this); + _rcwUnwrapped = Marshal.GetObjectForIUnknown(_ccw); + } + + public IntPtr GetCCW() + { + return _ccw; + } + + public object GetRCW() + { + return _rcwUnwrapped; + } + + public void ReleaseResources() + { + Marshal.Release(_ccw); + _ccw = IntPtr.Zero; + _rcwUnwrapped = null; + } + + public bool EqualByCCW(object obj) + { + IntPtr ccwMaybe = Marshal.GetIUnknownForObject(obj); + bool areEqual = ccwMaybe == _ccw; + Marshal.Release(ccwMaybe); + + return areEqual; + } + + public bool NotEqualByRCW(object obj) + { + return _rcwUnwrapped != obj; + } +} diff --git a/tests/src/Interop/COM/NETServer/NETServer.csproj b/tests/src/Interop/COM/NETServer/NETServer.csproj index aa4e791a6c..e820c0c63f 100644 --- a/tests/src/Interop/COM/NETServer/NETServer.csproj +++ b/tests/src/Interop/COM/NETServer/NETServer.csproj @@ -17,13 +17,7 @@ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"> </PropertyGroup> <ItemGroup> - <Compile Include="ImportedTypes.cs" /> - <Compile Include="NumericTesting.cs" /> - <Compile Include="ArrayTesting.cs" /> - <Compile Include="StringTesting.cs" /> - <Compile Include="ErrorMarshalTesting.cs" /> - <Compile Include="ColorTesting.cs" /> - <Compile Include="LicenseTesting.cs" /> + <Compile Include="*.cs" /> <Compile Include="../ServerContracts/Server.Contracts.cs" /> <Compile Include="../ServerContracts/ServerGuids.cs" /> </ItemGroup> diff --git a/tests/src/Interop/COM/ServerContracts/NativeServers.cs b/tests/src/Interop/COM/ServerContracts/Server.CoClasses.cs index 724f7e2bcc..25432a27db 100644 --- a/tests/src/Interop/COM/ServerContracts/NativeServers.cs +++ b/tests/src/Interop/COM/ServerContracts/Server.CoClasses.cs @@ -183,6 +183,31 @@ namespace Server.Contract.Servers { } */ + + /// <summary> + /// Managed definition of CoClass + /// </summary> + /// <remarks> + /// This interface is used to test consumption of the NET server from a NET client only. + /// </remarks> + [ComImport] + [CoClass(typeof(ConsumeNETServerTestingClass))] + [Guid("CCBC1915-3252-4F6B-98AA-411CE6213D94")] + internal interface ConsumeNETServerTesting : Server.Contract.IConsumeNETServer + { + } + + /// <summary> + /// Managed activation for CoClass + /// </summary> + /// <remarks> + /// This interface is used to test consumption of the NET server from a NET client only. + /// </remarks> + [ComImport] + [Guid(Server.Contract.Guids.ConsumeNETServerTesting)] + internal class ConsumeNETServerTestingClass + { + } } #pragma warning restore 618 // Must test deprecated features diff --git a/tests/src/Interop/COM/ServerContracts/Server.Contracts.cs b/tests/src/Interop/COM/ServerContracts/Server.Contracts.cs index 7c198c7138..f32518485c 100644 --- a/tests/src/Interop/COM/ServerContracts/Server.Contracts.cs +++ b/tests/src/Interop/COM/ServerContracts/Server.Contracts.cs @@ -306,6 +306,22 @@ namespace Server.Contract void SetNextLicense([MarshalAs(UnmanagedType.LPWStr)] string lic); } + + /// <remarks> + /// This interface is used to test consumption of the NET server from a NET client only. + /// </remarks> + [ComVisible(true)] + [Guid("CCBC1915-3252-4F6B-98AA-411CE6213D94")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IConsumeNETServer + { + IntPtr GetCCW(); + object GetRCW(); + void ReleaseResources(); + + bool EqualByCCW(object obj); + bool NotEqualByRCW(object obj); + } } #pragma warning restore 618 // Must test deprecated features diff --git a/tests/src/Interop/COM/ServerContracts/ServerGuids.cs b/tests/src/Interop/COM/ServerContracts/ServerGuids.cs index 98ed0aed85..d03eacf708 100644 --- a/tests/src/Interop/COM/ServerContracts/ServerGuids.cs +++ b/tests/src/Interop/COM/ServerContracts/ServerGuids.cs @@ -19,5 +19,6 @@ namespace Server.Contract public const string ColorTesting = "C222F472-DA5A-4FC6-9321-92F4F7053A65"; public const string LicenseTesting = "66DB7882-E2B0-471D-92C7-B2B52A0EA535"; public const string DefaultInterfaceTesting = "FAEF42AE-C1A4-419F-A912-B768AC2679EA"; + public const string ConsumeNETServerTesting = "DE4ACF53-5957-4D31-8BE2-EA6C80683246"; } } diff --git a/tests/src/Loader/ContextualReflection/ContextualReflection.cs b/tests/src/Loader/ContextualReflection/ContextualReflection.cs new file mode 100644 index 0000000000..3356e3df4b --- /dev/null +++ b/tests/src/Loader/ContextualReflection/ContextualReflection.cs @@ -0,0 +1,748 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.Loader; +using System.Runtime.Remoting; +using System.Threading.Tasks; +using TestLibrary; + +namespace ContextualReflectionTest +{ + class AGenericClass<T> + { + } + + class Program : IProgram + { + public AssemblyLoadContext alc { get; set; } + public Assembly alcAssembly { get; set; } + public Type alcProgramType { get; set; } + public IProgram alcProgramInstance { get; set; } + public Assembly defaultAssembly { get; set; } + + public static int Main() + { + Program program = new Program(isolated:false); + + program.RunTests(); + + Console.WriteLine("Success"); + + return 100; + } + + public Program() + { + InitializeIsolation(true); + } + + public Program(bool isolated) + { + InitializeIsolation(isolated); + } + + public void InitializeIsolation(bool isolated) + { + if (isolated == false) + { + alc = new AssemblyLoadContext("Isolated", isCollectible: true); + defaultAssembly = Assembly.GetExecutingAssembly(); + alcAssembly = alc.LoadFromAssemblyPath(defaultAssembly.Location); + + Assert.AreEqual(alcAssembly, alc.LoadFromAssemblyName(alcAssembly.GetName())); + + alcProgramType = alcAssembly.GetType("ContextualReflectionTest.Program"); + + AssemblyLoadContext.Default.Resolving += TestResolve.ResolvingTestDefault; + alc.Resolving += TestResolve.ResolvingTestIsolated; + + alcProgramInstance = (IProgram) Activator.CreateInstance(alcProgramType); + } + else + { + alcAssembly = Assembly.GetExecutingAssembly(); + alc = AssemblyLoadContext.GetLoadContext(alcAssembly); + alcProgramType = typeof(Program); + alcProgramInstance = this; + defaultAssembly = AssemblyLoadContext.Default.LoadFromAssemblyName(alcAssembly.GetName()); + } + } + + void VerifyIsolationDefault() + { + VerifyIsolation(); + Assert.AreEqual(defaultAssembly, Assembly.GetExecutingAssembly()); + Assert.AreEqual(AssemblyLoadContext.Default, AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly())); + Assert.AreNotEqual(alcProgramType, typeof(Program)); + Assert.AreNotEqual((object)alcProgramInstance, (object)this); + } + + void VerifyIsolationAlc() + { + VerifyIsolation(); + Assert.AreEqual(alcAssembly, Assembly.GetExecutingAssembly()); + Assert.AreEqual(alc, AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly())); + Assert.AreEqual(alcProgramType, typeof(Program)); + Assert.AreEqual((object)alcProgramInstance, (object)this); + } + + void VerifyIsolation() + { + Assert.AreEqual("Default", AssemblyLoadContext.Default.Name); + + Assert.IsNotNull(alc); + Assert.IsNotNull(alcAssembly); + Assert.IsNotNull(alcProgramType); + Assert.IsNotNull(alcProgramInstance); + + Assert.AreEqual("Isolated", alc.Name); + + Assert.AreNotEqual(defaultAssembly, alcAssembly); + Assert.AreNotEqual(alc, AssemblyLoadContext.Default); + + Assert.AreEqual(alc, AssemblyLoadContext.GetLoadContext(alcProgramInstance.alcAssembly)); + Assert.AreEqual(alcAssembly, alcProgramInstance.alcAssembly); + Assert.AreEqual(alcProgramType, alcProgramInstance.alcProgramType); + Assert.AreEqual(alcProgramInstance, alcProgramInstance.alcProgramInstance); + } + + void VerifyTestResolve() + { + TestResolve.Assert(ResolveEvents.ExpectedEvent, () => AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName("TestDefaultLoad"))); + TestResolve.Assert(ResolveEvents.NoEvent, () => AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName("TestIsolatedLoad"))); + TestResolve.Assert(ResolveEvents.ExpectedEvent, () => alc.LoadFromAssemblyName(new AssemblyName("TestIsolatedLoad"))); + TestResolve.Assert(ResolveEvents.ExpectedEvent, () => alc.LoadFromAssemblyName(new AssemblyName("TestDefaultLoad"))); + + // Make sure failure is not cached + TestResolve.Assert(ResolveEvents.ExpectedEvent, () => AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName("TestDefaultLoad"))); + TestResolve.Assert(ResolveEvents.NoEvent, () => AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName("TestIsolatedLoad"))); + TestResolve.Assert(ResolveEvents.ExpectedEvent, () => alc.LoadFromAssemblyName(new AssemblyName("TestIsolatedLoad"))); + TestResolve.Assert(ResolveEvents.ExpectedEvent, () => alc.LoadFromAssemblyName(new AssemblyName("TestDefaultLoad"))); + } + + void VerifyContextualReflectionProxy() + { + Assert.IsNull(ConntextualReflectionProxy.CurrentContextualReflectionContext); + + using (ConntextualReflectionProxy.EnterContextualReflection(alc)) + { + Assert.AreEqual(alc, ConntextualReflectionProxy.CurrentContextualReflectionContext); + using (ConntextualReflectionProxy.EnterContextualReflection(AssemblyLoadContext.Default)) + { + Assert.AreEqual(AssemblyLoadContext.Default, ConntextualReflectionProxy.CurrentContextualReflectionContext); + using (ConntextualReflectionProxy.EnterContextualReflection((Assembly)null)) + { + Assert.IsNull(ConntextualReflectionProxy.CurrentContextualReflectionContext); + using (ConntextualReflectionProxy.EnterContextualReflection(alcAssembly)) + { + Assert.AreEqual(alc, ConntextualReflectionProxy.CurrentContextualReflectionContext); + } + Assert.IsNull(ConntextualReflectionProxy.CurrentContextualReflectionContext); + } + Assert.AreEqual(AssemblyLoadContext.Default, ConntextualReflectionProxy.CurrentContextualReflectionContext); + } + Assert.AreEqual(alc, ConntextualReflectionProxy.CurrentContextualReflectionContext); + } + Assert.IsNull(ConntextualReflectionProxy.CurrentContextualReflectionContext); + } + + void VerifyUsingStatementContextualReflectionUsage() + { + Assert.IsNull(ConntextualReflectionProxy.CurrentContextualReflectionContext); + + { + using IDisposable alcScope = ConntextualReflectionProxy.EnterContextualReflection(alc); + Assert.AreEqual(alc, ConntextualReflectionProxy.CurrentContextualReflectionContext); + } + + Assert.IsNull(ConntextualReflectionProxy.CurrentContextualReflectionContext); + + { + using IDisposable alcScope = ConntextualReflectionProxy.EnterContextualReflection(alc); + Assert.AreEqual(alc, ConntextualReflectionProxy.CurrentContextualReflectionContext); + alcScope.Dispose(); + Assert.IsNull(ConntextualReflectionProxy.CurrentContextualReflectionContext); + } + + Assert.IsNull(ConntextualReflectionProxy.CurrentContextualReflectionContext); + + { + using IDisposable alcScope = ConntextualReflectionProxy.EnterContextualReflection(alc); + Assert.AreEqual(alc, ConntextualReflectionProxy.CurrentContextualReflectionContext); + alcScope.Dispose(); + Assert.IsNull(ConntextualReflectionProxy.CurrentContextualReflectionContext); + alcScope.Dispose(); + } + + Assert.IsNull(ConntextualReflectionProxy.CurrentContextualReflectionContext); + + { + using IDisposable alcScope = ConntextualReflectionProxy.EnterContextualReflection(alc); + Assert.AreEqual(alc, ConntextualReflectionProxy.CurrentContextualReflectionContext); + { + using IDisposable defaultScope = ConntextualReflectionProxy.EnterContextualReflection(AssemblyLoadContext.Default); + Assert.AreEqual(AssemblyLoadContext.Default, ConntextualReflectionProxy.CurrentContextualReflectionContext); + + } + Assert.AreEqual(alc, ConntextualReflectionProxy.CurrentContextualReflectionContext); + } + + Assert.IsNull(ConntextualReflectionProxy.CurrentContextualReflectionContext); + + { + using IDisposable alcScope = ConntextualReflectionProxy.EnterContextualReflection(alc); + Assert.AreEqual(alc, ConntextualReflectionProxy.CurrentContextualReflectionContext); + try + { + using IDisposable defaultScope = ConntextualReflectionProxy.EnterContextualReflection(AssemblyLoadContext.Default); + Assert.AreEqual(AssemblyLoadContext.Default, ConntextualReflectionProxy.CurrentContextualReflectionContext); + + throw new InvalidOperationException(); + } + catch + { + } + Assert.AreEqual(alc, ConntextualReflectionProxy.CurrentContextualReflectionContext); + } + + Assert.IsNull(ConntextualReflectionProxy.CurrentContextualReflectionContext); + + { + using IDisposable alcScope = ConntextualReflectionProxy.EnterContextualReflection(alc); + Assert.AreEqual(alc, ConntextualReflectionProxy.CurrentContextualReflectionContext); + using IDisposable defaultScope = ConntextualReflectionProxy.EnterContextualReflection(AssemblyLoadContext.Default); + Assert.AreEqual(AssemblyLoadContext.Default, ConntextualReflectionProxy.CurrentContextualReflectionContext); + defaultScope.Dispose(); + Assert.AreEqual(alc, ConntextualReflectionProxy.CurrentContextualReflectionContext); + alcScope.Dispose(); + } + + Assert.IsNull(ConntextualReflectionProxy.CurrentContextualReflectionContext); + } + + void VerifyBadContextualReflectionUsage() + { + Assert.IsNull(ConntextualReflectionProxy.CurrentContextualReflectionContext); + + { + IDisposable alcScope = ConntextualReflectionProxy.EnterContextualReflection(alc); + Assert.AreEqual(alc, ConntextualReflectionProxy.CurrentContextualReflectionContext); + alcScope.Dispose(); + } + + Assert.IsNull(ConntextualReflectionProxy.CurrentContextualReflectionContext); + + { + IDisposable alcScope = ConntextualReflectionProxy.EnterContextualReflection(alc); + Assert.AreEqual(alc, ConntextualReflectionProxy.CurrentContextualReflectionContext); + alcScope.Dispose(); + alcScope.Dispose(); + } + + Assert.IsNull(ConntextualReflectionProxy.CurrentContextualReflectionContext); + + { + IDisposable alcScope = ConntextualReflectionProxy.EnterContextualReflection(alc); + Assert.AreEqual(alc, ConntextualReflectionProxy.CurrentContextualReflectionContext); + IDisposable defaultScope = ConntextualReflectionProxy.EnterContextualReflection(AssemblyLoadContext.Default); + Assert.AreEqual(AssemblyLoadContext.Default, ConntextualReflectionProxy.CurrentContextualReflectionContext); + defaultScope.Dispose(); + Assert.AreEqual(alc, ConntextualReflectionProxy.CurrentContextualReflectionContext); + alcScope.Dispose(); + } + + Assert.IsNull(ConntextualReflectionProxy.CurrentContextualReflectionContext); + + { + IDisposable alcScope = ConntextualReflectionProxy.EnterContextualReflection(alc); + Assert.AreEqual(alc, ConntextualReflectionProxy.CurrentContextualReflectionContext); + IDisposable defaultScope = ConntextualReflectionProxy.EnterContextualReflection(AssemblyLoadContext.Default); + Assert.AreEqual(AssemblyLoadContext.Default, ConntextualReflectionProxy.CurrentContextualReflectionContext); + + alcScope.Dispose(); + Assert.IsNull(ConntextualReflectionProxy.CurrentContextualReflectionContext); + + defaultScope.Dispose(); + Assert.AreEqual(alc, ConntextualReflectionProxy.CurrentContextualReflectionContext); + alcScope.Dispose(); + } + + Assert.IsNull(ConntextualReflectionProxy.CurrentContextualReflectionContext); + + { + IDisposable alcScope = ConntextualReflectionProxy.EnterContextualReflection(alc); + Assert.AreEqual(alc, ConntextualReflectionProxy.CurrentContextualReflectionContext); + try + { + IDisposable defaultScope = ConntextualReflectionProxy.EnterContextualReflection((Assembly)null); + Assert.AreEqual(null, ConntextualReflectionProxy.CurrentContextualReflectionContext); + + throw new InvalidOperationException(); + } + catch + { + } + } + + Assert.IsNull(ConntextualReflectionProxy.CurrentContextualReflectionContext); + } + + void TestResolveMissingAssembly(bool isolated, Action<string> action, bool skipNullIsolated = false) + { + using (ConntextualReflectionProxy.EnterContextualReflection((Assembly)null)) + { + TestResolve.Assert(ResolveEvents.ExpectedEvent, () => action("TestDefaultLoad")); + if (!skipNullIsolated) + TestResolve.Assert(isolated ? ResolveEvents.ExpectedEvent : ResolveEvents.NoEvent, () => action("TestIsolatedLoad")); + } + using (ConntextualReflectionProxy.EnterContextualReflection(AssemblyLoadContext.Default)) + { + TestResolve.Assert(ResolveEvents.ExpectedEvent, () => action("TestDefaultLoad")); + TestResolve.Assert(ResolveEvents.NoEvent, () => action("TestIsolatedLoad")); + } + using (ConntextualReflectionProxy.EnterContextualReflection(alc)) + { + TestResolve.Assert(ResolveEvents.ExpectedEvent, () => action("TestDefaultLoad")); + TestResolve.Assert(ResolveEvents.ExpectedEvent, () => action("TestIsolatedLoad")); + } + } + + void TestAssemblyLoad(bool isolated) + { + TestAssemblyLoad(isolated, (string assemblyName) => Assembly.Load(assemblyName)); + TestAssemblyLoad(isolated, (string assemblyName) => Assembly.Load(new AssemblyName(assemblyName))); + } + + void TestAssemblyLoad(bool isolated, Func<string, Assembly> assemblyLoad) + { + TestResolveMissingAssembly(isolated, (string assemblyName) => assemblyLoad(assemblyName)); + + using (ConntextualReflectionProxy.EnterContextualReflection((Assembly)null)) + { + Assembly assembly = assemblyLoad("ContextualReflection"); + + Assert.AreEqual(isolated ? alc : AssemblyLoadContext.Default, AssemblyLoadContext.GetLoadContext(assembly)); + + Assembly depends = assemblyLoad("ContextualReflectionDependency"); + + Assert.AreEqual(AssemblyLoadContext.Default, AssemblyLoadContext.GetLoadContext(depends)); + } + using (ConntextualReflectionProxy.EnterContextualReflection(AssemblyLoadContext.Default)) + { + Assembly assembly = assemblyLoad("ContextualReflection"); + + Assert.AreEqual(AssemblyLoadContext.Default, AssemblyLoadContext.GetLoadContext(assembly)); + + Assembly depends = assemblyLoad("ContextualReflectionDependency"); + + Assert.AreEqual(AssemblyLoadContext.Default, AssemblyLoadContext.GetLoadContext(depends)); + } + using (ConntextualReflectionProxy.EnterContextualReflection(alc)) + { + Assembly assembly = assemblyLoad("ContextualReflection"); + + Assert.AreEqual(alc, AssemblyLoadContext.GetLoadContext(assembly)); + + Assembly depends = assemblyLoad("ContextualReflectionDependency"); + + Assert.AreEqual(AssemblyLoadContext.Default, AssemblyLoadContext.GetLoadContext(depends)); + } + } + + void TestTypeGetType(bool isolated) + { + TestTypeGetType(isolated, (string typeName) => Type.GetType(typeName)); + TestTypeGetType(isolated, (string typeName) => Type.GetType(typeName, throwOnError : false)); + TestTypeGetType(isolated, (string typeName) => Type.GetType(typeName, throwOnError : false, ignoreCase : false)); + TestTypeGetType(isolated, (string typeName) => Type.GetType(typeName, assemblyResolver : null, typeResolver : null)); + TestTypeGetType(isolated, (string typeName) => Type.GetType(typeName, assemblyResolver : null, typeResolver : null, throwOnError : false)); + TestTypeGetType(isolated, (string typeName) => Type.GetType(typeName, assemblyResolver : null, typeResolver : null, throwOnError : false, ignoreCase : false)); + } + + void TestTypeGetType(bool isolated, Func<string, System.Type> typeGetType) + { + TestResolveMissingAssembly(isolated, (string assemblyName) => typeGetType(string.Format("MyType, {0}", assemblyName))); + + using (ConntextualReflectionProxy.EnterContextualReflection((Assembly)null)) + { + { + Type p = typeGetType("ContextualReflectionTest.Program"); + + Assembly expectedAssembly = Assembly.GetExecutingAssembly(); + + Assert.IsNotNull(p); + Assert.AreEqual(expectedAssembly, p.Assembly); + Assert.AreEqual(typeof (Program), p); + } + { + Type p = typeGetType("ContextualReflectionTest.Program, ContextualReflection"); + + Assembly expectedAssembly = Assembly.GetExecutingAssembly(); + + Assert.IsNotNull(p); + Assert.AreEqual(expectedAssembly, p.Assembly); + Assert.AreEqual(typeof (Program), p); + } + { + Type g = typeGetType("ContextualReflectionTest.AGenericClass`1[[ContextualReflectionTest.Program, ContextualReflection]], ContextualReflection"); + + Assembly expectedAssembly = Assembly.GetExecutingAssembly(); + + Assert.IsNotNull(g); + Assert.AreEqual(expectedAssembly, g.Assembly); + Assert.AreEqual(expectedAssembly, g.GenericTypeArguments[0].Assembly); + Assert.AreEqual(typeof (Program), g.GenericTypeArguments[0]); + Assert.AreEqual(isolated ? alc : AssemblyLoadContext.Default, AssemblyLoadContext.GetLoadContext(g.GenericTypeArguments[0].Assembly)); + } + } + using (ConntextualReflectionProxy.EnterContextualReflection(AssemblyLoadContext.Default)) + { + { + Type p = typeGetType("ContextualReflectionTest.Program"); + + Assembly expectedAssembly = Assembly.GetExecutingAssembly(); + + Assert.IsNotNull(p); + Assert.AreEqual(expectedAssembly, p.Assembly); + Assert.AreEqual(typeof (Program), p); + } + { + Type p = typeGetType("ContextualReflectionTest.Program, ContextualReflection"); + + Assembly expectedAssembly = defaultAssembly; + + Assert.IsNotNull(p); + Assert.AreEqual(expectedAssembly, p.Assembly); + Assert.AreEqual(AssemblyLoadContext.Default, AssemblyLoadContext.GetLoadContext(p.Assembly)); + } + { + Type g = typeGetType("ContextualReflectionTest.AGenericClass`1[[ContextualReflectionTest.Program, ContextualReflection]], ContextualReflection"); + + Assembly expectedAssembly = defaultAssembly; + + Assert.IsNotNull(g); + Assert.AreEqual(expectedAssembly, g.Assembly); + Assert.AreEqual(expectedAssembly, g.GenericTypeArguments[0].Assembly); + Assert.AreEqual(AssemblyLoadContext.Default, AssemblyLoadContext.GetLoadContext(g.Assembly)); + Assert.AreEqual(AssemblyLoadContext.Default, AssemblyLoadContext.GetLoadContext(g.GenericTypeArguments[0].Assembly)); + } + } + using (ConntextualReflectionProxy.EnterContextualReflection(alc)) + { + { + Type p = typeGetType("ContextualReflectionTest.Program"); + + Assembly expectedAssembly = Assembly.GetExecutingAssembly(); + + Assert.IsNotNull(p); + Assert.AreEqual(expectedAssembly, p.Assembly); + Assert.AreEqual(typeof (Program), p); + } + { + Type p = typeGetType("ContextualReflectionTest.Program, ContextualReflection"); + + Assembly expectedAssembly = alcAssembly; + + Assert.IsNotNull(p); + Assert.AreEqual(expectedAssembly, p.Assembly); + Assert.AreEqual(alc, AssemblyLoadContext.GetLoadContext(p.Assembly)); + } + { + Type g = typeGetType("ContextualReflectionTest.AGenericClass`1[[ContextualReflectionTest.Program, ContextualReflection]], ContextualReflection"); + + Assembly expectedAssembly = alcAssembly; + + Assert.IsNotNull(g); + Assert.AreEqual(expectedAssembly, g.Assembly); + Assert.AreEqual(expectedAssembly, g.GenericTypeArguments[0].Assembly); + Assert.AreEqual(alc, AssemblyLoadContext.GetLoadContext(g.Assembly)); + Assert.AreEqual(alc, AssemblyLoadContext.GetLoadContext(g.GenericTypeArguments[0].Assembly)); + } + } + } + + void TestAssemblyGetType(bool isolated) + { + Assembly assembly = Assembly.GetExecutingAssembly(); + TestResolveMissingAssembly(isolated, + (string assemblyName) => assembly.GetType(string.Format("ContextualReflectionTest.AGenericClass`1[[MyType, {0}]]", assemblyName))); + + using (ConntextualReflectionProxy.EnterContextualReflection((Assembly)null)) + { + { + Type g = assembly.GetType("ContextualReflectionTest.AGenericClass`1[[ContextualReflectionTest.Program]]", throwOnError : false); + + Assert.IsNotNull(g); + Assert.AreEqual(assembly, g.Assembly); + Assert.AreEqual(assembly, g.GenericTypeArguments[0].Assembly); + Assert.AreEqual(Assembly.GetExecutingAssembly(), g.GenericTypeArguments[0].Assembly); + Assert.AreEqual(typeof (Program), g.GenericTypeArguments[0]); + } + { + Type g = assembly.GetType("ContextualReflectionTest.AGenericClass`1[[ContextualReflectionTest.Program, ContextualReflection]]", throwOnError : false); + + Assert.IsNotNull(g); + Assert.AreEqual(assembly, g.Assembly); + Assert.AreEqual(assembly, g.GenericTypeArguments[0].Assembly); + Assert.AreEqual(Assembly.GetExecutingAssembly(), g.GenericTypeArguments[0].Assembly); + Assert.AreEqual(typeof (Program), g.GenericTypeArguments[0]); + } + { + Assembly mscorlib = typeof (System.Collections.Generic.List<string>).Assembly; + + Type m = mscorlib.GetType("System.Collections.Generic.List`1[[ContextualReflectionTest.Program, ContextualReflection]]", throwOnError : false); + + Assembly expectedAssembly = mscorlib; + + Assert.IsNotNull(m); + Assert.AreEqual(expectedAssembly, m.Assembly); + Assert.AreEqual(AssemblyLoadContext.Default, AssemblyLoadContext.GetLoadContext(m.GenericTypeArguments[0].Assembly)); + } + } + using (ConntextualReflectionProxy.EnterContextualReflection(AssemblyLoadContext.Default)) + { + { + Type g = assembly.GetType("ContextualReflectionTest.AGenericClass`1[[ContextualReflectionTest.Program]]", throwOnError : false); + + Assert.IsNotNull(g); + Assert.AreEqual(assembly, g.Assembly); + Assert.AreEqual(assembly, g.GenericTypeArguments[0].Assembly); + Assert.AreEqual(Assembly.GetExecutingAssembly(), g.GenericTypeArguments[0].Assembly); + Assert.AreEqual(typeof (Program), g.GenericTypeArguments[0]); + } + { + Type g = assembly.GetType("ContextualReflectionTest.AGenericClass`1[[ContextualReflectionTest.Program, ContextualReflection]]", throwOnError : false); + + Assembly expectedAssembly = defaultAssembly; + + Assert.IsNotNull(g); + Assert.AreEqual(assembly, g.Assembly); + Assert.AreEqual(expectedAssembly, g.GenericTypeArguments[0].Assembly); + } + { + Assembly mscorlib = typeof (System.Collections.Generic.List<string>).Assembly; + + Type m = mscorlib.GetType("System.Collections.Generic.List`1[[ContextualReflectionTest.Program, ContextualReflection]]", throwOnError : false); + + Assembly expectedAssembly = mscorlib; + + Assert.IsNotNull(m); + Assert.AreEqual(expectedAssembly, m.Assembly); + Assert.AreEqual(AssemblyLoadContext.Default, AssemblyLoadContext.GetLoadContext(m.GenericTypeArguments[0].Assembly)); + } + } + using (ConntextualReflectionProxy.EnterContextualReflection(alc)) + { + { + Type g = assembly.GetType("ContextualReflectionTest.AGenericClass`1[[ContextualReflectionTest.Program]]", throwOnError : false); + + Assert.IsNotNull(g); + Assert.AreEqual(assembly, g.Assembly); + Assert.AreEqual(assembly, g.GenericTypeArguments[0].Assembly); + Assert.AreEqual(Assembly.GetExecutingAssembly(), g.GenericTypeArguments[0].Assembly); + Assert.AreEqual(typeof (Program), g.GenericTypeArguments[0]); + } + { + Type g = assembly.GetType("ContextualReflectionTest.AGenericClass`1[[ContextualReflectionTest.Program, ContextualReflection]]", throwOnError : false); + + Assembly expectedAssembly = alcAssembly; + + Assert.IsNotNull(g); + Assert.AreEqual(assembly, g.Assembly); + Assert.AreEqual(expectedAssembly, g.GenericTypeArguments[0].Assembly); + } + { + Assembly mscorlib = typeof (System.Collections.Generic.List<string>).Assembly; + + Type m = mscorlib.GetType("System.Collections.Generic.List`1[[ContextualReflectionTest.Program, ContextualReflection]]", throwOnError : false); + + Assembly expectedAssembly = mscorlib; + + Assert.IsNotNull(m); + Assert.AreEqual(expectedAssembly, m.Assembly); + Assert.AreEqual(alc, AssemblyLoadContext.GetLoadContext(m.GenericTypeArguments[0].Assembly)); + } + } + } + + void TestActivatorCreateInstance(bool isolated) + { + TestResolveMissingAssembly(isolated, (string assemblyName) => Activator.CreateInstance(assemblyName, "MyType")); + TestResolveMissingAssembly(isolated, + (string assemblyName) => Activator.CreateInstance("System.Private.CoreLib", string.Format("System.Collections.Generic.List`1[[MyType, {0}]]", assemblyName)), + skipNullIsolated : true); + + TestResolveMissingAssembly(isolated, + (string assemblyName) => Activator.CreateInstance("ContextualReflection", string.Format("ContextualReflectionTest.AGenericClass`1[[MyType, {0}]]", assemblyName))); + + Assembly assembly = Assembly.GetExecutingAssembly(); + + using (ConntextualReflectionProxy.EnterContextualReflection((Assembly)null)) + { + { + ObjectHandle objectHandle = Activator.CreateInstance(null, "ContextualReflectionTest.AGenericClass`1[[ContextualReflectionTest.Program]]"); + Type g = objectHandle.Unwrap().GetType(); + + Assert.IsNotNull(g); + Assert.AreEqual(assembly, g.Assembly); + Assert.AreEqual(assembly, g.GenericTypeArguments[0].Assembly); + Assert.AreEqual(Assembly.GetExecutingAssembly(), g.GenericTypeArguments[0].Assembly); + Assert.AreEqual(typeof (Program), g.GenericTypeArguments[0]); + } + { + ObjectHandle objectHandle = Activator.CreateInstance(null, "ContextualReflectionTest.AGenericClass`1[[ContextualReflectionTest.Program, ContextualReflection]]"); + Type g = objectHandle.Unwrap().GetType(); + + Assert.IsNotNull(g); + Assert.AreEqual(assembly, g.Assembly); + Assert.AreEqual(assembly, g.GenericTypeArguments[0].Assembly); + Assert.AreEqual(Assembly.GetExecutingAssembly(), g.GenericTypeArguments[0].Assembly); + Assert.AreEqual(typeof (Program), g.GenericTypeArguments[0]); + } + { + ObjectHandle objectHandle = Activator.CreateInstance("ContextualReflection" , "ContextualReflectionTest.AGenericClass`1[[ContextualReflectionTest.Program, ContextualReflection]]"); + Type g = objectHandle.Unwrap().GetType(); + + Assembly expectedAssembly = assembly; + + Assert.IsNotNull(g); + Assert.AreEqual(expectedAssembly, g.Assembly); + Assert.AreEqual(expectedAssembly, g.GenericTypeArguments[0].Assembly); + } + { + Assembly expectedAssembly = alcAssembly; + + Assembly mscorlib = typeof (System.Collections.Generic.List<string>).Assembly; + + ObjectHandle objectHandle = Activator.CreateInstance(mscorlib.GetName().Name, "System.Collections.Generic.List`1[[ContextualReflectionTest.Program, ContextualReflection]]"); + Type m = objectHandle.Unwrap().GetType(); + + Assert.IsNotNull(m); + Assert.AreEqual(mscorlib, m.Assembly); + Assert.AreEqual(AssemblyLoadContext.Default, AssemblyLoadContext.GetLoadContext(m.GenericTypeArguments[0].Assembly)); + } + } + using (ConntextualReflectionProxy.EnterContextualReflection(AssemblyLoadContext.Default)) + { + { + ObjectHandle objectHandle = Activator.CreateInstance(null, "ContextualReflectionTest.AGenericClass`1[[ContextualReflectionTest.Program]]"); + Type g = objectHandle.Unwrap().GetType(); + + Assert.IsNotNull(g); + Assert.AreEqual(assembly, g.Assembly); + Assert.AreEqual(assembly, g.GenericTypeArguments[0].Assembly); + Assert.AreEqual(Assembly.GetExecutingAssembly(), g.GenericTypeArguments[0].Assembly); + Assert.AreEqual(typeof (Program), g.GenericTypeArguments[0]); + } + { + ObjectHandle objectHandle = Activator.CreateInstance(null, "ContextualReflectionTest.AGenericClass`1[[ContextualReflectionTest.Program, ContextualReflection]]"); + Type g = objectHandle.Unwrap().GetType(); + + Assembly expectedAssembly = defaultAssembly; + + Assert.IsNotNull(g); + Assert.AreEqual(assembly, g.Assembly); + Assert.AreEqual(expectedAssembly, g.GenericTypeArguments[0].Assembly); + } + { + ObjectHandle objectHandle = Activator.CreateInstance("ContextualReflection" , "ContextualReflectionTest.AGenericClass`1[[ContextualReflectionTest.Program, ContextualReflection]]"); + Type g = objectHandle.Unwrap().GetType(); + + Assembly expectedAssembly = defaultAssembly; + + Assert.IsNotNull(g); + Assert.AreEqual(expectedAssembly, g.Assembly); + Assert.AreEqual(expectedAssembly, g.GenericTypeArguments[0].Assembly); + } + { + Assembly mscorlib = typeof (System.Collections.Generic.List<string>).Assembly; + + ObjectHandle objectHandle = Activator.CreateInstance(mscorlib.GetName().Name, "System.Collections.Generic.List`1[[ContextualReflectionTest.Program, ContextualReflection]]"); + Type m = objectHandle.Unwrap().GetType(); + + Assembly expectedAssembly = mscorlib; + + Assert.IsNotNull(m); + Assert.AreEqual(expectedAssembly, m.Assembly); + Assert.AreEqual(AssemblyLoadContext.Default, AssemblyLoadContext.GetLoadContext(m.GenericTypeArguments[0].Assembly)); + } + } + using (ConntextualReflectionProxy.EnterContextualReflection(alc)) + { + { + ObjectHandle objectHandle = Activator.CreateInstance(null, "ContextualReflectionTest.AGenericClass`1[[ContextualReflectionTest.Program]]"); + Type g = objectHandle.Unwrap().GetType(); + + Assert.IsNotNull(g); + Assert.AreEqual(assembly, g.Assembly); + Assert.AreEqual(assembly, g.GenericTypeArguments[0].Assembly); + Assert.AreEqual(Assembly.GetExecutingAssembly(), g.GenericTypeArguments[0].Assembly); + Assert.AreEqual(typeof (Program), g.GenericTypeArguments[0]); + } + { + ObjectHandle objectHandle = Activator.CreateInstance(null, "ContextualReflectionTest.AGenericClass`1[[ContextualReflectionTest.Program, ContextualReflection]]"); + Type g = objectHandle.Unwrap().GetType(); + + Assembly expectedAssembly = alcAssembly; + + Assert.IsNotNull(g); + Assert.AreEqual(assembly, g.Assembly); + Assert.AreEqual(expectedAssembly, g.GenericTypeArguments[0].Assembly); + } + { + ObjectHandle objectHandle = Activator.CreateInstance("ContextualReflection" , "ContextualReflectionTest.AGenericClass`1[[ContextualReflectionTest.Program, ContextualReflection]]"); + Type g = objectHandle.Unwrap().GetType(); + + Assembly expectedAssembly = alcAssembly; + + Assert.IsNotNull(g); + Assert.AreEqual(expectedAssembly, g.Assembly); + Assert.AreEqual(expectedAssembly, g.GenericTypeArguments[0].Assembly); + } + { + Assembly mscorlib = typeof (System.Collections.Generic.List<string>).Assembly; + + ObjectHandle objectHandle = Activator.CreateInstance(mscorlib.GetName().Name, "System.Collections.Generic.List`1[[ContextualReflectionTest.Program, ContextualReflection]]"); + Type m = objectHandle.Unwrap().GetType(); + + Assert.IsNotNull(m); + Assert.AreEqual(mscorlib, m.Assembly); + Assert.AreEqual(alc, AssemblyLoadContext.GetLoadContext(m.GenericTypeArguments[0].Assembly)); + } + } + } + + public void RunTests() + { + VerifyIsolationDefault(); + VerifyTestResolve(); + VerifyContextualReflectionProxy(); + VerifyUsingStatementContextualReflectionUsage(); + VerifyBadContextualReflectionUsage(); + + RunTests(isolated : false); + alcProgramInstance.RunTestsIsolated(); + } + + public void RunTests(bool isolated) + { + TestAssemblyLoad(isolated); + TestTypeGetType(isolated); + TestAssemblyGetType(isolated); + TestActivatorCreateInstance(isolated); + } + + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public void RunTestsIsolated() + { + VerifyIsolationAlc(); + RunTests(isolated : true); + } + } +} + diff --git a/tests/src/Loader/ContextualReflection/ContextualReflection.csproj b/tests/src/Loader/ContextualReflection/ContextualReflection.csproj new file mode 100644 index 0000000000..6f88de3877 --- /dev/null +++ b/tests/src/Loader/ContextualReflection/ContextualReflection.csproj @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <OutputType>Exe</OutputType> + <CLRTestKind>BuildAndRun</CLRTestKind> + <ProjectGuid>{78030DC5-F1A6-4B98-A130-A66F5047FF29}</ProjectGuid> + </PropertyGroup> + <ItemGroup> + <Compile Include="ContextualReflection.cs" /> + <ProjectReference Include="ContextualReflectionDependency.csproj" /> + <ProjectReference Include="../../Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/Loader/ContextualReflection/ContextualReflectionDependency.cs b/tests/src/Loader/ContextualReflection/ContextualReflectionDependency.cs new file mode 100644 index 0000000000..d8fc8ef014 --- /dev/null +++ b/tests/src/Loader/ContextualReflection/ContextualReflectionDependency.cs @@ -0,0 +1,123 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +using System; +using System.IO; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.Loader; + +namespace ContextualReflectionTest +{ + public interface IProgram + { + AssemblyLoadContext alc { get; } + Assembly alcAssembly { get; } + Type alcProgramType { get; } + IProgram alcProgramInstance { get; } + [MethodImplAttribute(MethodImplOptions.NoInlining)] + void RunTestsIsolated(); + } + + public class ConntextualReflectionProxy + { + public static AssemblyLoadContext CurrentContextualReflectionContext + { + get + { +#if AssemblyLoadContextContextualReflectionFacade + return AssemblyLoadContext.CurrentContextualReflectionContext; +#else + Type t = typeof (AssemblyLoadContext); + + object result = t.InvokeMember("CurrentContextualReflectionContext", + BindingFlags.Public | BindingFlags.Static | BindingFlags.GetProperty, + null, + null, + new object [] {}); + + return (AssemblyLoadContext) result; +#endif + } + } + + static public IDisposable EnterContextualReflection(AssemblyLoadContext alc) + { +#if AssemblyLoadContextContextualReflectionFacade + return alc.EnterContextualReflection(); +#else + Type t = typeof (AssemblyLoadContext); + + object result = t.InvokeMember("EnterContextualReflection", + BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, + null, + alc, + new object [] {}); + + return (IDisposable) result; +#endif + } + + static public IDisposable EnterContextualReflection(Assembly activating) + { +#if AssemblyLoadContextContextualReflectionFacade + return AssemblyLoadContext.EnterContextualReflection(activating); +#else + Type t = typeof (AssemblyLoadContext); + + object result = t.InvokeMember("EnterContextualReflection", + BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, + null, + null, + new object [] {activating}); + + return (IDisposable) result; +#endif + } + } + + public enum ResolveEvents + { + NoEvent, + ExpectedEvent, + }; + + public class TestResolve + { + static public ResolveEvents ResolveEvent { get; set;} + + static public Assembly ResolvingTestDefault(AssemblyLoadContext alc, AssemblyName assemblyName) + { + if (assemblyName.Name.Contains("TestDefaultLoad") && (ResolveEvent == ResolveEvents.NoEvent)) + { + ResolveEvent = ResolveEvents.ExpectedEvent; + } + return null; + } + + static public Assembly ResolvingTestIsolated(AssemblyLoadContext alc, AssemblyName assemblyName) + { + if (assemblyName.Name.Contains("TestIsolatedLoad") && (ResolveEvent == ResolveEvents.NoEvent)) + { + ResolveEvent = ResolveEvents.ExpectedEvent; + } + return null; + } + + static public void Assert(ResolveEvents expected, Action action) + { + ResolveEvent = ResolveEvents.NoEvent; + try + { + action(); + } + catch + { + } + finally + { + TestLibrary.Assert.AreEqual(expected, ResolveEvent); + } + } + } +} diff --git a/tests/src/Loader/ContextualReflection/ContextualReflectionDependency.csproj b/tests/src/Loader/ContextualReflection/ContextualReflectionDependency.csproj new file mode 100644 index 0000000000..1d8fb64087 --- /dev/null +++ b/tests/src/Loader/ContextualReflection/ContextualReflectionDependency.csproj @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <OutputType>Library</OutputType> + <CLRTestKind>BuildOnly</CLRTestKind> + <ProjectGuid>{95DBE3B0-AA86-4366-BB8A-E04B534365F3}</ProjectGuid> + </PropertyGroup> + <ItemGroup> + <Compile Include="ContextualReflectionDependency.cs" /> + <ProjectReference Include="../../Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj" /> + </ItemGroup> + <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> +</Project> diff --git a/tests/src/tracing/eventcounter/incrementingpollingcounter.cs b/tests/src/tracing/eventcounter/incrementingpollingcounter.cs index f215460741..2b21ebbf68 100644 --- a/tests/src/tracing/eventcounter/incrementingpollingcounter.cs +++ b/tests/src/tracing/eventcounter/incrementingpollingcounter.cs @@ -21,7 +21,7 @@ namespace BasicEventSourceTests { private object _failureCounter; - public SimpleEventSource(Func<float> getFailureCount, Type IncrementingPollingCounterType) + public SimpleEventSource(Func<double> getFailureCount, Type IncrementingPollingCounterType) { _failureCounter = Activator.CreateInstance(IncrementingPollingCounterType, "failureCount", this, getFailureCount); } @@ -93,7 +93,7 @@ namespace BasicEventSourceTests public static int failureCountCalled = 0; - public static float getFailureCount() + public static double getFailureCount() { failureCountCalled++; return failureCountCalled; diff --git a/tests/src/tracing/eventcounter/pollingcounter.cs b/tests/src/tracing/eventcounter/pollingcounter.cs index ba2369d639..9e8dff2ef4 100644 --- a/tests/src/tracing/eventcounter/pollingcounter.cs +++ b/tests/src/tracing/eventcounter/pollingcounter.cs @@ -22,7 +22,7 @@ namespace BasicEventSourceTests private object _failureCounter; private object _successCounter; - public SimpleEventSource(Func<float> getFailureCount, Func<float> getSuccessCount, Type PollingCounterType) + public SimpleEventSource(Func<double> getFailureCount, Func<double> getSuccessCount, Type PollingCounterType) { _failureCounter = Activator.CreateInstance(PollingCounterType, "failureCount", this, getSuccessCount); _successCounter = Activator.CreateInstance(PollingCounterType, "successCount", this, getFailureCount); @@ -140,13 +140,13 @@ namespace BasicEventSourceTests public static int failureCountCalled = 0; public static int successCountCalled = 0; - public static float getFailureCount() + public static double getFailureCount() { failureCountCalled++; return failureCountCalled; } - public static float getSuccessCount() + public static double getSuccessCount() { successCountCalled++; return successCountCalled; |