Hot Reload: test on WebAssembly (#53050)
authorAleksey Kliger (λgeek) <alklig@microsoft.com>
Tue, 25 May 2021 00:25:17 +0000 (20:25 -0400)
committerGitHub <noreply@github.com>
Tue, 25 May 2021 00:25:17 +0000 (20:25 -0400)
* Hot Reload: test on WebAssembly

   1. Always build the assemblies in the ApplyUpdate/ subdirectory without optimization, with debug info.  Hot reload depends on it.
   2. Pass the required environment variable to the runtime via xharness to enable support for applying updates.

* Add ApplyUpdate test assemblies to test project linker descriptor

* Fix wasm EnableAggressiveTrimming lane

src/libraries/System.Runtime.Loader/tests/ApplyUpdate/Directory.Build.props
src/libraries/System.Runtime.Loader/tests/ApplyUpdateUtil.cs
src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj
src/mono/mono/metadata/metadata-update.c

index e2d777b..765d890 100644 (file)
     <PackageReference Include="Microsoft.DotNet.HotReload.Utils.Generator.BuildTool" Version="$(MicrosoftDotNetHotReloadUtilsGeneratorBuildToolVersion)" />
   </ItemGroup>
   
+  <PropertyGroup>
+    <!-- to call AsssemblyExtensions.ApplyUpdate we need Optimize=false, EmitDebugInformation=true in all configurations -->
+    <Optimize>false</Optimize>
+    <EmitDebugInformation>true</EmitDebugInformation>
+  </PropertyGroup>
+
 </Project>
index baa5ac2..51873c0 100644 (file)
@@ -20,10 +20,9 @@ namespace System.Reflection.Metadata
         /// 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,
-        /// 3. The test assemblies are compiled in the Debug configuration.
+        /// 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) &&
-            IsSupportedTestConfiguration();
+            (!IsMonoRuntime || IsSupportedMonoConfiguration);
 
         public static bool IsModifiableAssembliesSet =>
             String.Equals(DotNetModifiableAssembliesValue, Environment.GetEnvironmentVariable(DotNetModifiableAssembliesSwitch), StringComparison.InvariantCultureIgnoreCase);
@@ -61,16 +60,6 @@ namespace System.Reflection.Metadata
             return caps is string {Length: > 0};
         }
 
-        // Only Debug assemblies are editable
-        internal static bool IsSupportedTestConfiguration()
-        {
-#if DEBUG
-            return true;
-#else
-            return false;
-#endif
-        }
-
         private static System.Collections.Generic.Dictionary<Assembly, int> assembly_count = new();
 
         internal static void ApplyUpdate (System.Reflection.Assembly assm)
index 3e8e0bc..a69b4fe 100644 (file)
@@ -6,6 +6,8 @@
     <IncludeRemoteExecutor>true</IncludeRemoteExecutor>
     <!-- Some tests rely on no deps.json file being present. -->
     <GenerateDependencyFile>false</GenerateDependencyFile>
+    <!-- EnC tests on targets without a remote executor need the environment variable set before launching the test -->
+    <WasmXHarnessMonoArgs>--setenv=DOTNET_MODIFIABLE_ASSEMBLIES=debug</WasmXHarnessMonoArgs>
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="ApplyUpdateTest.cs" />
 
     <TrimmerRootDescriptor Include="$(MSBuildThisFileDirectory)ILLink.Descriptors.xml" />
   </ItemGroup>
+
+  <Target Name="PreserveEnCAssembliesFromLinking"
+         Condition="'$(TargetOS)' == 'Browser' and '$(EnableAggressiveTrimming)' == 'true'"
+         BeforeTargets="ConfigureTrimming">
+    <ItemGroup>
+      <!-- Don't modify EnC test assemblies -->
+      <TrimmerRootAssembly
+          Condition="$([System.String]::Copy('%(ResolvedFileToPublish.FileName)%(ResolvedFileToPublish.Extension)').EndsWith('System.Reflection.Metadata.ApplyUpdate.Test.MethodBody1.dll'))"
+          Include="%(ResolvedFileToPublish.FullPath)" />
+    </ItemGroup>
+  </Target>
+
+  <Target Name="IncludeDeltasInWasmBundle"
+         BeforeTargets="PrepareForWasmBuildApp"
+         Condition="'$(TargetOS)' == 'Browser'">
+    <ItemGroup>
+      <!-- FIXME: this belongs in eng/testing/tests.wasm.targets -->
+      <!-- FIXME: Can we do something on the Content items in the referenced projects themselves to get this for free? -->
+      <WasmFilesToIncludeInFileSystem Include="@(PublishItemsOutputGroupOutputs)"
+                                     Condition="$([System.String]::new('%(PublishItemsOutputGroupOutputs.Identity)').EndsWith('.dmeta'))" />
+      <WasmFilesToIncludeInFileSystem Include="@(PublishItemsOutputGroupOutputs)"
+                                     Condition="$([System.String]::new('%(PublishItemsOutputGroupOutputs.Identity)').EndsWith('.dil'))" />
+      <WasmFilesToIncludeInFileSystem Include="@(PublishItemsOutputGroupOutputs)"
+                                     Condition="$([System.String]::new('%(PublishItemsOutputGroupOutputs.Identity)').EndsWith('.dpdb'))" />
+    </ItemGroup>
+  </Target>
 </Project>
index d5e9fc7..21797da 100644 (file)
@@ -85,8 +85,10 @@ mono_metadata_update_enabled (int *modifiable_assemblies_out)
 
        if (!inited) {
                char *val = g_getenv (DOTNET_MODIFIABLE_ASSEMBLIES);
-               if (val && !g_strcasecmp (val, "debug"))
+               if (val && !g_strcasecmp (val, "debug")) {
+                       mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_METADATA_UPDATE, "Metadata update enabled for debuggable assemblies");
                        modifiable = MONO_MODIFIABLE_ASSM_DEBUG;
+               }
                g_free (val);
                inited = TRUE;
        }