/// testsuite runs each test in sequence, loading the corresponding
/// assembly, applying an update to it and observing the results.
[Collection(nameof(ApplyUpdateUtil.NoParallelTests))]
- [ConditionalClass(typeof(ApplyUpdateUtil), nameof (ApplyUpdateUtil.IsSupported))]
public class ApplyUpdateTest
{
- [Fact]
+ [ConditionalFact(typeof(ApplyUpdateUtil), nameof (ApplyUpdateUtil.IsSupported))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/54617", typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser), nameof(PlatformDetection.IsMonoAOT))]
void StaticMethodBodyUpdate()
{
});
}
- [Fact]
+ [ConditionalFact(typeof(ApplyUpdateUtil), nameof (ApplyUpdateUtil.IsSupported))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/52993", TestRuntimes.Mono)]
void ClassWithCustomAttributes()
{
Assert.Equal(typeof(string), result.GetType());
}
- [Fact]
- [ActiveIssue("Returns true on mono", TestRuntimes.Mono)]
+ [ConditionalFact(typeof(ApplyUpdateUtil), nameof(ApplyUpdateUtil.TestUsingRemoteExecutor))]
public static void IsSupported()
{
bool result = MetadataUpdater.IsSupported;
Assert.False(result);
}
+
+ [ConditionalFact(typeof(ApplyUpdateUtil), nameof(ApplyUpdateUtil.TestUsingLaunchEnvironment))]
+ public static void IsSupported2()
+ {
+ bool result = MetadataUpdater.IsSupported;
+ Assert.True(result);
+ }
}
}
///
/// We need:
/// 1. Either DOTNET_MODIFIABLE_ASSEMBLIES=debug is set, or we can use the RemoteExecutor to run a child process with that environment; and,
- /// 2. Either Mono in a supported configuration (interpreter as the execution engine, and the hot reload feature enabled), or CoreCLR; and,
+ /// 2. Either Mono in a supported configuration (interpreter as the execution engine, and the hot reload component enabled), or CoreCLR; and,
/// 3. The test assemblies are compiled with Debug information (this is configured by setting EmitDebugInformation in ApplyUpdate\Directory.Build.props)
public static bool IsSupported => (IsModifiableAssembliesSet || IsRemoteExecutorSupported) &&
(!IsMonoRuntime || IsSupportedMonoConfiguration);
+ /// true if the current runtime was not launched with the apropriate settings for applying
+ /// updates (DOTNET_MODIFIABLE_ASSEMBLIES unset), but we can use the remote executor to
+ /// launch a child process that has the right setting.
+ public static bool TestUsingRemoteExecutor => IsRemoteExecutorSupported && !IsModifiableAssembliesSet;
+
+ /// true if the current runtime was launched with the appropriate settings for applying
+ /// updates (DOTNET_MODIFIABLE_ASSEMBLIES set, and if Mono, the interpreter is enabled).
+ public static bool TestUsingLaunchEnvironment => (!IsMonoRuntime || IsSupportedMonoConfiguration) && IsModifiableAssembliesSet;
+
public static bool IsModifiableAssembliesSet =>
String.Equals(DotNetModifiableAssembliesValue, Environment.GetEnvironmentVariable(DotNetModifiableAssembliesSwitch), StringComparison.InvariantCultureIgnoreCase);
// static cctor for RemoteExecutor throws on wasm.
public static bool IsRemoteExecutorSupported => !RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER")) && RemoteExecutor.IsSupported;
- // copied from https://github.com/dotnet/arcade/blob/6cc4c1e9e23d5e65e88a8a57216b3d91e9b3d8db/src/Microsoft.DotNet.XUnitExtensions/src/DiscovererHelpers.cs#L16-L17
- private static readonly Lazy<bool> s_isMonoRuntime = new Lazy<bool>(() => Type.GetType("Mono.RuntimeStructs") != null);
- public static bool IsMonoRuntime => s_isMonoRuntime.Value;
+ public static bool IsMonoRuntime => PlatformDetection.IsMonoRuntime;
private static readonly Lazy<bool> s_isSupportedMonoConfiguration = new Lazy<bool>(CheckSupportedMonoConfiguration);
// Not every build of Mono supports ApplyUpdate
internal static bool CheckSupportedMonoConfiguration()
{
- // check that interpreter is enabled, and the build has hot reload capabilities enabled.
+ // check that interpreter is enabled, and the build has hot reload capabilities enabled.
var isInterp = RuntimeFeature.IsDynamicCodeSupported && !RuntimeFeature.IsDynamicCodeCompiled;
return isInterp && HasApplyUpdateCapabilities();
}
string basename = assm.Location;
if (basename == "")
basename = assm.GetName().Name + ".dll";
- Console.Error.WriteLine($"Apply Delta Update for {basename}, revision {count}");
+ Console.Error.WriteLine($"Applying metadata update for {basename}, revision {count}");
string dmeta_name = $"{basename}.{count}.dmeta";
string dil_name = $"{basename}.{count}.dil";
MetadataUpdater.ApplyUpdate(assm, dmeta_data, dil_data, dpdb_data);
}
- internal static bool UseRemoteExecutor => !IsModifiableAssembliesSet;
-
internal static void AddRemoteInvokeOptions (ref RemoteInvokeOptions options)
{
options = options ?? new RemoteInvokeOptions();
public static void TestCase(Action testBody,
RemoteInvokeOptions options = null)
{
- if (UseRemoteExecutor)
+ if (TestUsingRemoteExecutor)
{
Console.Error.WriteLine ($"Running test using RemoteExecutor");
AddRemoteInvokeOptions(ref options);
string arg1,
RemoteInvokeOptions options = null)
{
- if (UseRemoteExecutor)
+ if (TestUsingRemoteExecutor)
{
AddRemoteInvokeOptions(ref options);
RemoteExecutor.Invoke(testBody, arg1, options).Dispose();
internal static string GetCapabilities() => s_ApplyUpdateCapabilities.Value;
- public static bool IsSupported { get; } = ApplyUpdateEnabled() != 0;
+ public static bool IsSupported { get; } = ApplyUpdateEnabled(justComponentCheck: 0) != 0;
private static Lazy<string> s_ApplyUpdateCapabilities = new Lazy<string>(() => InitializeApplyUpdateCapabilities());
private static string InitializeApplyUpdateCapabilities()
{
- return ApplyUpdateEnabled() != 0 ? "Baseline" : string.Empty ;
+ return ApplyUpdateEnabled(justComponentCheck: 1) != 0 ? "Baseline" : string.Empty ;
}
[MethodImpl (MethodImplOptions.InternalCall)]
- private static extern int ApplyUpdateEnabled ();
+ private static extern int ApplyUpdateEnabled (int justComponentCheck);
[MethodImpl (MethodImplOptions.InternalCall)]
private static unsafe extern void ApplyUpdate_internal (IntPtr base_assm, byte* dmeta_bytes, int dmeta_length, byte *dil_bytes, int dil_length, byte *dpdb_bytes, int dpdb_length);