From cd6bee0f373e5f564910f58fa5a1e444e37efaca Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Fri, 19 Apr 2024 11:06:00 -0700 Subject: [PATCH 01/13] Trying out JanK's approach to override the entry assembly... --- .../CompatibilitySuppressions.xml | 22 +++++++++++++++++ .../src/CompatibilitySuppressions.xml | 24 ++++++++++++++++++- .../src/System/Reflection/Assembly.cs | 11 ++++++--- 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/CompatibilitySuppressions.xml b/src/coreclr/System.Private.CoreLib/CompatibilitySuppressions.xml index 97b65a2748409e..b2ac3a3da448b6 100644 --- a/src/coreclr/System.Private.CoreLib/CompatibilitySuppressions.xml +++ b/src/coreclr/System.Private.CoreLib/CompatibilitySuppressions.xml @@ -1,6 +1,28 @@  + + CP0001 + T:Internal.Console + + + CP0001 + T:System.Runtime.CompilerServices.ICastable + + + CP0002 + F:System.Resources.ResourceManager.BaseNameField + + + CP0002 + F:System.Resources.ResourceSet.Reader + + + CP0002 + M:System.Reflection.Assembly.SetEntryAssembly(System.Reflection.Assembly) + ref/net9.0/System.Private.CoreLib.dll + lib/net9.0/System.Private.CoreLib.dll + CP0015 M:System.Diagnostics.Tracing.EventSource.Write``1(System.String,``0):[T:System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute] diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml b/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml index 9d09ab7e105928..b667ccc2e3db8c 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml @@ -1,6 +1,10 @@  + + CP0001 + T:Internal.Console + CP0001 T:Internal.Metadata.NativeFormat.ArraySignature @@ -825,10 +829,22 @@ CP0001 T:System.Runtime.CompilerServices.ForceDictionaryLookupsAttribute + + CP0001 + T:System.Runtime.CompilerServices.ICastable + CP0001 T:System.Runtime.CompilerServices.StaticClassConstructionContext + + CP0002 + F:System.Resources.ResourceManager.BaseNameField + + + CP0002 + F:System.Resources.ResourceSet.Reader + CP0002 M:System.Reflection.MethodBase.GetParametersAsSpan @@ -837,6 +853,12 @@ CP0002 M:System.Threading.Lock.#ctor(System.Boolean) + + CP0002 + M:System.Reflection.Assembly.SetEntryAssembly(System.Reflection.Assembly) + ref/net9.0/System.Private.CoreLib.dll + lib/net9.0/System.Private.CoreLib.dll + CP0015 M:System.Diagnostics.Tracing.EventSource.Write``1(System.String,``0):[T:System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute] @@ -865,4 +887,4 @@ CP0015 M:System.Diagnostics.Tracing.EventSource.WriteEventWithRelatedActivityIdCore(System.Int32,System.Guid*,System.Int32,System.Diagnostics.Tracing.EventSource.EventData*):[T:System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute] - + \ No newline at end of file diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs index d467fd6fb08242..a48615b640de3a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs @@ -218,12 +218,17 @@ public override string ToString() } // internal test hook - private static bool s_forceNullEntryPoint; + private static Assembly? s_overriddenEntryAssembly; + + public void SetEntryAssembly(Assembly newAssembly) + { + s_overriddenEntryAssembly = newAssembly; + } public static Assembly? GetEntryAssembly() { - if (s_forceNullEntryPoint) - return null; + if (s_overriddenEntryAssembly is not null) + return s_overriddenEntryAssembly; return GetEntryAssemblyInternal(); } From 440b1a2f7973202a7f0a00189eb9bd344123a931 Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Tue, 30 Apr 2024 11:05:28 -0700 Subject: [PATCH 02/13] Fixed what was missing for this reflection scenario to work correctly. --- .../System.Private.CoreLib/CompatibilitySuppressions.xml | 6 ------ .../src/CompatibilitySuppressions.xml | 6 ------ .../src/System/Reflection/Assembly.cs | 2 +- src/libraries/System.Runtime/ref/System.Runtime.cs | 1 + 4 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/CompatibilitySuppressions.xml b/src/coreclr/System.Private.CoreLib/CompatibilitySuppressions.xml index b2ac3a3da448b6..4611de92418a03 100644 --- a/src/coreclr/System.Private.CoreLib/CompatibilitySuppressions.xml +++ b/src/coreclr/System.Private.CoreLib/CompatibilitySuppressions.xml @@ -17,12 +17,6 @@ CP0002 F:System.Resources.ResourceSet.Reader - - CP0002 - M:System.Reflection.Assembly.SetEntryAssembly(System.Reflection.Assembly) - ref/net9.0/System.Private.CoreLib.dll - lib/net9.0/System.Private.CoreLib.dll - CP0015 M:System.Diagnostics.Tracing.EventSource.Write``1(System.String,``0):[T:System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute] diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml b/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml index b667ccc2e3db8c..aa86a70c3b6592 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml @@ -853,12 +853,6 @@ CP0002 M:System.Threading.Lock.#ctor(System.Boolean) - - CP0002 - M:System.Reflection.Assembly.SetEntryAssembly(System.Reflection.Assembly) - ref/net9.0/System.Private.CoreLib.dll - lib/net9.0/System.Private.CoreLib.dll - CP0015 M:System.Diagnostics.Tracing.EventSource.Write``1(System.String,``0):[T:System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute] diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs index a48615b640de3a..7697f79c31e0fa 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs @@ -220,7 +220,7 @@ public override string ToString() // internal test hook private static Assembly? s_overriddenEntryAssembly; - public void SetEntryAssembly(Assembly newAssembly) + public static void SetEntryAssembly(Assembly newAssembly) { s_overriddenEntryAssembly = newAssembly; } diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 8b4ba90dc9b223..5d4c440555a291 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -11125,6 +11125,7 @@ public virtual void GetObjectData(System.Runtime.Serialization.SerializationInfo [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types and members the loaded assembly depends on might be removed")] [System.ObsoleteAttribute("ReflectionOnly loading is not supported and throws PlatformNotSupportedException.", DiagnosticId="SYSLIB0018", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Reflection.Assembly ReflectionOnlyLoadFrom(string assemblyFile) { throw null; } + public static void SetEntryAssembly(System.Reflection.Assembly newAssembly) { throw null; } public override string ToString() { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types and members the loaded assembly depends on might be removed")] public static System.Reflection.Assembly UnsafeLoadFrom(string assemblyFile) { throw null; } From 7fc6c77622c116a4ddc642e7f8ec944cd6b48504 Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Wed, 15 May 2024 11:40:51 -0700 Subject: [PATCH 03/13] Reverted the compatibility suppressions added by the build script. --- .../CompatibilitySuppressions.xml | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/CompatibilitySuppressions.xml b/src/coreclr/System.Private.CoreLib/CompatibilitySuppressions.xml index 4611de92418a03..97b65a2748409e 100644 --- a/src/coreclr/System.Private.CoreLib/CompatibilitySuppressions.xml +++ b/src/coreclr/System.Private.CoreLib/CompatibilitySuppressions.xml @@ -1,22 +1,6 @@  - - CP0001 - T:Internal.Console - - - CP0001 - T:System.Runtime.CompilerServices.ICastable - - - CP0002 - F:System.Resources.ResourceManager.BaseNameField - - - CP0002 - F:System.Resources.ResourceSet.Reader - CP0015 M:System.Diagnostics.Tracing.EventSource.Write``1(System.String,``0):[T:System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute] From 2caf4502c7a2160a24f4a6a2aba9a2fdd08fe3ff Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Wed, 15 May 2024 11:43:15 -0700 Subject: [PATCH 04/13] Forgot to revert also the nativeaot part of the suppressions. --- .../src/CompatibilitySuppressions.xml | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml b/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml index c716bd6935bb2a..770514a671adfc 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/CompatibilitySuppressions.xml @@ -1,10 +1,6 @@  - - CP0001 - T:Internal.Console - CP0001 T:Internal.Metadata.NativeFormat.ArraySignature @@ -829,22 +825,10 @@ CP0001 T:System.Runtime.CompilerServices.ForceDictionaryLookupsAttribute - - CP0001 - T:System.Runtime.CompilerServices.ICastable - CP0001 T:System.Runtime.CompilerServices.StaticClassConstructionContext - - CP0002 - F:System.Resources.ResourceManager.BaseNameField - - - CP0002 - F:System.Resources.ResourceSet.Reader - CP0002 M:System.Reflection.MethodBase.GetParametersAsSpan @@ -881,4 +865,4 @@ CP0015 M:System.Diagnostics.Tracing.EventSource.WriteEventWithRelatedActivityIdCore(System.Int32,System.Guid*,System.Int32,System.Diagnostics.Tracing.EventSource.EventData*):[T:System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute] - \ No newline at end of file + From a2f86a55014a43ce862dc703694e6b336e7c02b7 Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Wed, 15 May 2024 13:11:40 -0700 Subject: [PATCH 05/13] Addressed PR comments: Updated the tests to use the new "s_overriddenEntryAssembly", added an API doc to SetEntryAssembly(), added validation for it to be a Runtime Assembly, and changed the type to allow a null entry assembly. --- .../System/Configuration/CustomHostTests.cs | 2 +- .../DefaultTraceListenerClassTests.cs | 2 +- .../src/System/Reflection/Assembly.cs | 19 ++++++++++++++++--- .../System.Runtime/ref/System.Runtime.cs | 2 +- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/CustomHostTests.cs b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/CustomHostTests.cs index e8f69c198cf82d..64699f3e45d9d5 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/CustomHostTests.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/CustomHostTests.cs @@ -36,7 +36,7 @@ public void FilePathIsPopulatedCorrectly() private static void MakeAssemblyGetEntryAssemblyReturnNull() { typeof(Assembly) - .GetField("s_forceNullEntryPoint", BindingFlags.NonPublic | BindingFlags.Static) + .GetField("s_overriddenEntryAssembly", BindingFlags.NonPublic | BindingFlags.Static) .SetValue(null, true); Assert.Null(Assembly.GetEntryAssembly()); diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/DefaultTraceListenerClassTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/DefaultTraceListenerClassTests.cs index efbb26a53a7a9e..6439ce1f81bc04 100644 --- a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/DefaultTraceListenerClassTests.cs +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/DefaultTraceListenerClassTests.cs @@ -174,7 +174,7 @@ public void EntryAssemblyName_Null_NotIncludedInTrace() private static void MakeAssemblyGetEntryAssemblyReturnNull() { typeof(Assembly) - .GetField("s_forceNullEntryPoint", BindingFlags.NonPublic | BindingFlags.Static) + .GetField("s_overriddenEntryAssembly", BindingFlags.NonPublic | BindingFlags.Static) .SetValue(null, true); Assert.Null(Assembly.GetEntryAssembly()); diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs index 7697f79c31e0fa..31acb408885405 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs @@ -217,12 +217,25 @@ public override string ToString() return type.Module?.Assembly; } - // internal test hook private static Assembly? s_overriddenEntryAssembly; - public static void SetEntryAssembly(Assembly newAssembly) + /// + /// Sets the application's entry assembly to the provided assembly object + /// as argument. + /// + /// + /// Assembly object that represents the application's new entry assembly. + /// + /// + /// It is important to mention that the assembly passed to this function + /// has to be a RuntimeAssembly type. Otherwise, an exception will be thrown. + /// + public static void SetEntryAssembly(Assembly? assembly) { - s_overriddenEntryAssembly = newAssembly; + if (assembly is not RuntimeAssembly) + throw new ArgumentException(SR.Argument_MustBeRuntimeAssembly); + + s_overriddenEntryAssembly = assembly; } public static Assembly? GetEntryAssembly() diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 4d8ab69ff5cf27..eb2a12b198b716 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -11157,7 +11157,7 @@ public virtual void GetObjectData(System.Runtime.Serialization.SerializationInfo [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types and members the loaded assembly depends on might be removed")] [System.ObsoleteAttribute("ReflectionOnly loading is not supported and throws PlatformNotSupportedException.", DiagnosticId="SYSLIB0018", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public static System.Reflection.Assembly ReflectionOnlyLoadFrom(string assemblyFile) { throw null; } - public static void SetEntryAssembly(System.Reflection.Assembly newAssembly) { throw null; } + public static void SetEntryAssembly(System.Reflection.Assembly? assembly) { throw null; } public override string ToString() { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types and members the loaded assembly depends on might be removed")] public static System.Reflection.Assembly UnsafeLoadFrom(string assemblyFile) { throw null; } From cc6a5fa87fe64edb158c68d1a6ebf9069c1b7f57 Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Wed, 15 May 2024 14:38:40 -0700 Subject: [PATCH 06/13] Added tests and addressed more comments on the PR. --- .../tests/System/Configuration/CustomHostTests.cs | 8 +++----- .../DefaultTraceListenerClassTests.cs | 8 +++----- .../src/System/Reflection/Assembly.cs | 13 ++++++++++--- .../tests/System.Reflection.Tests/AssemblyTests.cs | 13 +++++++++++++ 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/CustomHostTests.cs b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/CustomHostTests.cs index 64699f3e45d9d5..73a1b97b1e0990 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/CustomHostTests.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/CustomHostTests.cs @@ -31,14 +31,12 @@ public void FilePathIsPopulatedCorrectly() } /// - /// Makes Assembly.GetEntryAssembly() return null using private reflection. + /// Makes Assembly.GetEntryAssembly() return null by passing the null literal + /// to Assembly.SetEntryAssembly(). /// private static void MakeAssemblyGetEntryAssemblyReturnNull() { - typeof(Assembly) - .GetField("s_overriddenEntryAssembly", BindingFlags.NonPublic | BindingFlags.Static) - .SetValue(null, true); - + Assembly.SetEntryAssembly(null); Assert.Null(Assembly.GetEntryAssembly()); } } diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/DefaultTraceListenerClassTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/DefaultTraceListenerClassTests.cs index 6439ce1f81bc04..3f0dae4129e394 100644 --- a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/DefaultTraceListenerClassTests.cs +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/DefaultTraceListenerClassTests.cs @@ -169,14 +169,12 @@ public void EntryAssemblyName_Null_NotIncludedInTrace() } /// - /// Makes Assembly.GetEntryAssembly() return null using private reflection. + /// Makes Assembly.GetEntryAssembly() return null by passing the null literal + /// to Assembly.SetEntryAssembly(). /// private static void MakeAssemblyGetEntryAssemblyReturnNull() { - typeof(Assembly) - .GetField("s_overriddenEntryAssembly", BindingFlags.NonPublic | BindingFlags.Static) - .SetValue(null, true); - + Assembly.SetEntryAssembly(null); Assert.Null(Assembly.GetEntryAssembly()); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs index 31acb408885405..f6465ca8652307 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs @@ -217,7 +217,7 @@ public override string ToString() return type.Module?.Assembly; } - private static Assembly? s_overriddenEntryAssembly; + private static object? s_overriddenEntryAssembly; /// /// Sets the application's entry assembly to the provided assembly object @@ -228,10 +228,17 @@ public override string ToString() /// /// /// It is important to mention that the assembly passed to this function - /// has to be a RuntimeAssembly type. Otherwise, an exception will be thrown. + /// has to be a runtime defined Assembly type object. Otherwise, an exception + /// will be thrown. /// public static void SetEntryAssembly(Assembly? assembly) { + if (assembly is null) + { + s_overriddenEntryAssembly = new object(); + return; + } + if (assembly is not RuntimeAssembly) throw new ArgumentException(SR.Argument_MustBeRuntimeAssembly); @@ -241,7 +248,7 @@ public static void SetEntryAssembly(Assembly? assembly) public static Assembly? GetEntryAssembly() { if (s_overriddenEntryAssembly is not null) - return s_overriddenEntryAssembly; + return s_overriddenEntryAssembly as Assembly; return GetEntryAssemblyInternal(); } diff --git a/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyTests.cs b/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyTests.cs index 600a4733b40c9c..aab5e1da32ab27 100644 --- a/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyTests.cs +++ b/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyTests.cs @@ -181,6 +181,19 @@ public void GetEntryAssembly() Assert.True(correct, $"Unexpected assembly name {assembly}"); } + [Fact] + public void SetEntryAssembly() + { + Assembly? originalAssembly = Assembly.GetEntryAssembly(); + Assert.NotNull(originalAssembly); + + Assembly.SetEntryAssembly(null); + Assert.Null(Assembly.GetEntryAssembly()); + + Assembly.SetEntryAssembly(originalAssembly); + Assert.Equal(Assembly.GetEntryAssembly(), originalAssembly); + } + [Fact] public void GetFile() { From 5a6813ef4f91b39d9eaba257ebc96d93ae8c80d2 Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Wed, 15 May 2024 17:03:06 -0700 Subject: [PATCH 07/13] Added exception test case for SetEntryAssembly, and wrapped all its test cases in a RemoteExecutor.Invoke() call, in order to avoid potentially interferring with the GetEntryAssembly tests. --- .../System.Reflection.Tests/AssemblyTests.cs | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyTests.cs b/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyTests.cs index aab5e1da32ab27..6392afef4244f7 100644 --- a/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyTests.cs +++ b/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyTests.cs @@ -7,10 +7,12 @@ using System.Globalization; using System.IO; using System.Linq; +using System.Reflection.Emit; using System.Reflection.Tests; using System.Runtime.CompilerServices; using System.Security; using System.Text; +using Microsoft.DotNet.RemoteExecutor; using Xunit; [assembly: @@ -184,14 +186,27 @@ public void GetEntryAssembly() [Fact] public void SetEntryAssembly() { - Assembly? originalAssembly = Assembly.GetEntryAssembly(); - Assert.NotNull(originalAssembly); + Assert.NotNull(Assembly.GetEntryAssembly()); + + RemoteExecutor.Invoke(() => + { + Assembly.SetEntryAssembly(null); + Assert.Null(Assembly.GetEntryAssembly()); + + Assembly originalAssembly = typeof(AssemblyTests).Assembly; + + Assembly.SetEntryAssembly(originalAssembly); + Assert.Equal(Assembly.GetEntryAssembly(), originalAssembly); - Assembly.SetEntryAssembly(null); - Assert.Null(Assembly.GetEntryAssembly()); + var invalidAssembly = new PersistedAssemblyBuilder( + new AssemblyName("NotaRuntimeAssemblyTest"), + typeof(object).Assembly + ); - Assembly.SetEntryAssembly(originalAssembly); - Assert.Equal(Assembly.GetEntryAssembly(), originalAssembly); + Assert.Throws( + () => Assembly.SetEntryAssembly(invalidAssembly) + ); + }).Dispose(); } [Fact] From d574dad87d94ee9bd833c8428ddb61d079102f54 Mon Sep 17 00:00:00 2001 From: Ivan Diaz Sanchez Date: Thu, 16 May 2024 09:08:18 -0700 Subject: [PATCH 08/13] Update src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs Co-authored-by: Jan Kotas --- .../System.Private.CoreLib/src/System/Reflection/Assembly.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs index f6465ca8652307..b50804f3b2d404 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs @@ -235,7 +235,7 @@ public static void SetEntryAssembly(Assembly? assembly) { if (assembly is null) { - s_overriddenEntryAssembly = new object(); + s_overriddenEntryAssembly = string.Empty; return; } From 4d02c7a26b2c18f78f9f06046e2685452cda4f56 Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Thu, 16 May 2024 14:18:05 -0700 Subject: [PATCH 09/13] Refactored further the tests that force a null entry assembly, and fixed the issue with the remote executor. --- .../tests/System/Configuration/CustomHostTests.cs | 13 ++----------- .../DefaultTraceListenerClassTests.cs | 13 ++----------- .../System.Reflection.Tests.csproj | 1 + 3 files changed, 5 insertions(+), 22 deletions(-) diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/CustomHostTests.cs b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/CustomHostTests.cs index 73a1b97b1e0990..3d32a020502a92 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/CustomHostTests.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/CustomHostTests.cs @@ -19,7 +19,8 @@ public void FilePathIsPopulatedCorrectly() { RemoteExecutor.Invoke(() => { - MakeAssemblyGetEntryAssemblyReturnNull(); + Assembly.SetEntryAssembly(null); + Assert.Null(Assembly.GetEntryAssembly()); string expectedFilePathEnding = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "dotnet.exe.config" : @@ -29,15 +30,5 @@ public void FilePathIsPopulatedCorrectly() Assert.EndsWith(expectedFilePathEnding, config.FilePath); }).Dispose(); } - - /// - /// Makes Assembly.GetEntryAssembly() return null by passing the null literal - /// to Assembly.SetEntryAssembly(). - /// - private static void MakeAssemblyGetEntryAssemblyReturnNull() - { - Assembly.SetEntryAssembly(null); - Assert.Null(Assembly.GetEntryAssembly()); - } } } diff --git a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/DefaultTraceListenerClassTests.cs b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/DefaultTraceListenerClassTests.cs index 3f0dae4129e394..ef84bec4fd2121 100644 --- a/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/DefaultTraceListenerClassTests.cs +++ b/src/libraries/System.Diagnostics.TraceSource/tests/System.Diagnostics.TraceSource.Tests/DefaultTraceListenerClassTests.cs @@ -159,7 +159,8 @@ public void EntryAssemblyName_Null_NotIncludedInTrace() { RemoteExecutor.Invoke(() => { - MakeAssemblyGetEntryAssemblyReturnNull(); + Assembly.SetEntryAssembly(null); + Assert.Null(Assembly.GetEntryAssembly()); var listener = new TestDefaultTraceListener(); Trace.Listeners.Add(listener); @@ -167,15 +168,5 @@ public void EntryAssemblyName_Null_NotIncludedInTrace() Assert.Equal("Error: 0 : hello world", listener.Output.Trim()); }).Dispose(); } - - /// - /// Makes Assembly.GetEntryAssembly() return null by passing the null literal - /// to Assembly.SetEntryAssembly(). - /// - private static void MakeAssemblyGetEntryAssemblyReturnNull() - { - Assembly.SetEntryAssembly(null); - Assert.Null(Assembly.GetEntryAssembly()); - } } } diff --git a/src/libraries/System.Runtime/tests/System.Reflection.Tests/System.Reflection.Tests.csproj b/src/libraries/System.Runtime/tests/System.Reflection.Tests/System.Reflection.Tests.csproj index 9553a7dacc4828..9c380a90bfbd23 100644 --- a/src/libraries/System.Runtime/tests/System.Reflection.Tests/System.Reflection.Tests.csproj +++ b/src/libraries/System.Runtime/tests/System.Reflection.Tests/System.Reflection.Tests.csproj @@ -2,6 +2,7 @@ $(NetCoreAppCurrent) true + true true From aac56b340fd57e6103bb4d653d4ee7b09f02ab7a Mon Sep 17 00:00:00 2001 From: Ivan Diaz Sanchez Date: Fri, 17 May 2024 09:40:23 -0700 Subject: [PATCH 10/13] Apply Jan's suggestions Co-authored-by: Jan Kotas --- .../src/System/Reflection/Assembly.cs | 8 +++----- .../tests/System.Reflection.Tests/AssemblyTests.cs | 8 ++++---- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs index b50804f3b2d404..778d5ef2a30a93 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs @@ -220,16 +220,14 @@ public override string ToString() private static object? s_overriddenEntryAssembly; /// - /// Sets the application's entry assembly to the provided assembly object - /// as argument. + /// Sets the application's entry assembly to the provided assembly object. /// /// /// Assembly object that represents the application's new entry assembly. /// /// - /// It is important to mention that the assembly passed to this function - /// has to be a runtime defined Assembly type object. Otherwise, an exception - /// will be thrown. + /// The assembly passed to this function has to be a runtime defined Assembly + /// type object. Otherwise, an exception will be thrown. /// public static void SetEntryAssembly(Assembly? assembly) { diff --git a/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyTests.cs b/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyTests.cs index 6392afef4244f7..eee55358adb8b7 100644 --- a/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyTests.cs +++ b/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyTests.cs @@ -183,7 +183,7 @@ public void GetEntryAssembly() Assert.True(correct, $"Unexpected assembly name {assembly}"); } - [Fact] + [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] public void SetEntryAssembly() { Assert.NotNull(Assembly.GetEntryAssembly()); @@ -193,10 +193,10 @@ public void SetEntryAssembly() Assembly.SetEntryAssembly(null); Assert.Null(Assembly.GetEntryAssembly()); - Assembly originalAssembly = typeof(AssemblyTests).Assembly; + Assembly testAssembly = typeof(AssemblyTests).Assembly; - Assembly.SetEntryAssembly(originalAssembly); - Assert.Equal(Assembly.GetEntryAssembly(), originalAssembly); + Assembly.SetEntryAssembly(testAssembly); + Assert.Equal(Assembly.GetEntryAssembly(), testAssembly); var invalidAssembly = new PersistedAssemblyBuilder( new AssemblyName("NotaRuntimeAssemblyTest"), From ccf2ec61bff0561ec5c843407a3aab925ed8dfcd Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Fri, 17 May 2024 10:30:01 -0700 Subject: [PATCH 11/13] Fixed a sneaky trailing whitespace that was messing up with the code analyzers. --- .../System.Private.CoreLib/src/System/Reflection/Assembly.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs index 778d5ef2a30a93..c11d07f8e0b2cd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Assembly.cs @@ -226,7 +226,7 @@ public override string ToString() /// Assembly object that represents the application's new entry assembly. /// /// - /// The assembly passed to this function has to be a runtime defined Assembly + /// The assembly passed to this function has to be a runtime defined Assembly /// type object. Otherwise, an exception will be thrown. /// public static void SetEntryAssembly(Assembly? assembly) From b06df494bf57d396810cf7608f6a44cac1586ac7 Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Fri, 17 May 2024 12:54:17 -0700 Subject: [PATCH 12/13] Changed ConditionalTheory to ConditionalFact in the tests because we're not passing parameters to it. --- .../tests/System.Reflection.Tests/AssemblyTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyTests.cs b/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyTests.cs index eee55358adb8b7..2134b65251df40 100644 --- a/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyTests.cs +++ b/src/libraries/System.Runtime/tests/System.Reflection.Tests/AssemblyTests.cs @@ -183,7 +183,7 @@ public void GetEntryAssembly() Assert.True(correct, $"Unexpected assembly name {assembly}"); } - [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] public void SetEntryAssembly() { Assert.NotNull(Assembly.GetEntryAssembly()); From 671c2f10d1dbf6b4608e84d574c1fcd46d11a5ff Mon Sep 17 00:00:00 2001 From: Ivan Diaz Date: Mon, 20 May 2024 13:31:35 -0700 Subject: [PATCH 13/13] Disabled building the CustomHostTests test file when .NET Framework --- .../System.Configuration.ConfigurationManager.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj b/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj index 0a6b23dad7e658..6880adcbf6c2ff 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj @@ -59,7 +59,7 @@ - +