Skip to content

Commit cf9bb86

Browse files
TIHanBruceForstall
andauthored
Enable IlasmRoundTrip tests for merged tests (#93368)
* Initial work * Tweak * Tweak * Do not generate _ilasmroundtrip.py for tests that have a generated run script * Reduce imports * Force fail to see where CI fails * Revert forcing failure. Run roundtrip on build. * Trying to fix script * Backslash tweak * Do not roundtrip the same assembly * Fixing * Remove import glob * Added is_managed_assembly * remove print * Fixed paths * Support bash. Ignore certain tests for arm. Fix poison test. * Update CLRTest.Jit.targets * Feedback. Added AssemblyChecker. * Fix paths * Update src/tests/Common/Directory.Build.targets Co-authored-by: Bruce Forstall <brucefo@microsoft.com> * Feedback * Feedback * Update AssemblyChecker.csproj * Update Program.cs * Trying to fix calling python on helix. * Remove old roundtrip script calls. Added --is-exe option for AssemblyChecker. * Tweak option: * Remove check * Remove imports * Fix build * Fix syntax errors. Fixed Popen arguments * Fixed Popen arguments * Fixing debug check * Fixing tests * Update ILVerificationTests.csproj * Fixing tests * Feedback * Feedback * Update CLRTest.Jit.targets * Added help usage flag for AssemblyChecker * Feedback on assembly-checker --------- Co-authored-by: Bruce Forstall <brucefo@microsoft.com>
1 parent 1a19c09 commit cf9bb86

File tree

12 files changed

+255
-98
lines changed

12 files changed

+255
-98
lines changed

eng/Subsets.props

+2-1
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,8 @@
336336
$(CoreClrProjectRoot)tools\r2rdump\R2RDump.csproj;
337337
$(CoreClrProjectRoot)tools\dotnet-pgo\dotnet-pgo.csproj;
338338
$(CoreClrProjectRoot)tools\aot\ILCompiler\repro\repro.csproj;
339-
$(CoreClrProjectRoot)tools\r2rtest\R2RTest.csproj" Category="clr" Condition="'$(DotNetBuildFromSource)' != 'true'"/>
339+
$(CoreClrProjectRoot)tools\r2rtest\R2RTest.csproj;
340+
$(CoreClrProjectRoot)tools\AssemblyChecker\AssemblyChecker.csproj" Category="clr" Condition="'$(DotNetBuildFromSource)' != 'true'"/>
340341
<ProjectToBuild Include="$(CoreClrProjectRoot)tools\aot\crossgen2\crossgen2.csproj" Category="clr" />
341342
<ProjectToBuild Include="$(CoreClrProjectRoot)tools\aot\ILCompiler.Build.Tasks\ILCompiler.Build.Tasks.csproj" Category="clr" Condition="'$(NativeAotSupported)' == 'true'" />
342343
<ProjectToBuild Include="$(CoreClrProjectRoot)tools\aot\ILCompiler\ILCompiler.csproj" Category="clr" Condition="'$(NativeAotSupported)' == 'true'" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<AssemblyName>AssemblyChecker</AssemblyName>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>$(NetCoreAppToolCurrent)</TargetFramework>
6+
<PlatformTarget>AnyCPU</PlatformTarget>
7+
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
8+
<AppendTargetFrameworkToOutputPath Condition="'$(BuildingInsideVisualStudio)' == 'true'">true</AppendTargetFrameworkToOutputPath>
9+
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
10+
<EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems>
11+
<ImplicitUsings>enable</ImplicitUsings>
12+
<Nullable>enable</Nullable>
13+
<OutputPath>$(RuntimeBinDir)\AssemblyChecker</OutputPath>
14+
<RunAnalyzers>false</RunAnalyzers>
15+
</PropertyGroup>
16+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Text;
5+
using System.Diagnostics;
6+
using System.Reflection;
7+
using System.Reflection.Metadata;
8+
using System.Reflection.PortableExecutable;
9+
10+
namespace AssemblyChecker
11+
{
12+
/// <summary>
13+
/// This is a simple console application that is designed to answer True or False
14+
/// questions about whether a given file is a managed assembly or not.
15+
/// You can also ask whether or not the assembly is debuggable.
16+
/// Return code of 0 indicates the file is a managed assembly.
17+
/// Return code of 1 indicates the file is not a managed assembly. No errors will be printed for this one.
18+
/// </summary>
19+
public class Program
20+
{
21+
private const string HelpText = @"
22+
Usage:
23+
<filePath>: Check if the file-path is a managed assembly.
24+
--is-debug <filePath>: Check if the file-path is a managed assembly that is built with debuggability.
25+
--is-exe <filePath>: Check if the file-path is a managed assembly that is an executable.
26+
";
27+
28+
static bool IsAssembly(string path)
29+
{
30+
using var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
31+
32+
// Try to read CLI metadata from the PE file.
33+
using var peReader = new PEReader(fs);
34+
35+
if (!peReader.HasMetadata)
36+
{
37+
return false; // File does not have CLI metadata.
38+
}
39+
40+
// Check that file has an assembly manifest.
41+
MetadataReader reader = peReader.GetMetadataReader();
42+
return reader.IsAssembly;
43+
}
44+
45+
static bool IsDebug(string path)
46+
{
47+
return
48+
Assembly.LoadFrom(path)
49+
.GetCustomAttributes(typeof(DebuggableAttribute), false)
50+
.OfType<DebuggableAttribute>().Any(x => x.IsJITOptimizerDisabled);
51+
}
52+
53+
static bool IsExe(string path)
54+
{
55+
using var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
56+
57+
// Try to read CLI metadata from the PE file.
58+
using var peReader = new PEReader(fs);
59+
60+
if (!peReader.HasMetadata)
61+
{
62+
return false; // File does not have CLI metadata.
63+
}
64+
65+
return peReader.PEHeaders.IsExe;
66+
}
67+
68+
static int Main(string[] args)
69+
{
70+
if (args.Length == 0)
71+
{
72+
Console.WriteLine(HelpText);
73+
Console.Error.WriteLine("\nExpected assembly file-path.");
74+
return 2;
75+
}
76+
77+
// Help
78+
if (args.Contains("-h"))
79+
{
80+
Console.WriteLine(HelpText);
81+
return 0;
82+
}
83+
84+
if (args.Length == 1)
85+
{
86+
return IsAssembly(args[0]) ? 0 : 1;
87+
}
88+
89+
if (args.Length == 2)
90+
{
91+
switch (args[0])
92+
{
93+
case "--is-debug":
94+
{
95+
return IsDebug(args[1]) ? 0 : 1;
96+
}
97+
98+
case "--is-exe":
99+
{
100+
return IsExe(args[1]) ? 0 : 1;
101+
}
102+
103+
default:
104+
{
105+
Console.WriteLine(HelpText);
106+
Console.Error.WriteLine("\nInvalid option.");
107+
return 2;
108+
}
109+
}
110+
}
111+
112+
Console.WriteLine(HelpText);
113+
Console.Error.WriteLine("\nToo many arguments.");
114+
return 2;
115+
}
116+
}
117+
}

src/tests/Common/CLRTest.Execute.Bash.targets

-4
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,6 @@ else
381381
LAUNCHER="$_DebuggerFullPath $_DebuggerArgsSeparator $(CLRTestRunFile)"
382382
fi
383383
384-
$(BashIlrtTestLaunchCmds)
385-
386384
if [ ! -z ${RunCrossGen2+x} ]%3B then
387385
TakeLock
388386
fi
@@ -412,8 +410,6 @@ else
412410
LAUNCHER="$_DebuggerFullPath $_DebuggerArgsSeparator $(CLRTestRunFile)"
413411
fi
414412
415-
$(BashIlrtTestLaunchCmds)
416-
417413
if [ ! -z ${RunCrossGen2+x} ]%3B then
418414
TakeLock
419415
fi

src/tests/Common/CLRTest.Execute.Batch.targets

-2
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,6 @@ IF NOT "%CLRCustomTestLauncher%"=="" (
318318
set LAUNCHER=%_DebuggerFullPath% $(CLRTestRunFile)
319319
)
320320
321-
$(BatchIlrtTestLaunchCmds)
322-
323321
if defined RunCrossGen2 (
324322
call :TakeLock
325323
)

0 commit comments

Comments
 (0)