diff --git a/mono-no-runtime-async/Program.cs b/mono-no-runtime-async/Program.cs new file mode 100644 index 0000000..07479b4 --- /dev/null +++ b/mono-no-runtime-async/Program.cs @@ -0,0 +1,49 @@ +// Mono does not support runtime async. +// This test is ran against Mono builds to verify no assemblies require runtime async. + +using System.Reflection; +using System.Reflection.Metadata; +using System.Reflection.PortableExecutable; + +// Find the root of the .NET installation. +// /shared/Microsoft.NETCore.App//System.Private.CoreLib.dll +string corelib = typeof(object).Assembly.Location; +string dotnetRoot = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(corelib)!, "..", "..", "..")); +if (!File.Exists(Path.Combine(dotnetRoot, "dotnet"))) + throw new Exception($"Expected to find 'dotnet' in {dotnetRoot}"); +Console.WriteLine($"Searching for assemblies in {dotnetRoot}"); + +var assemblies = Directory.EnumerateFiles(dotnetRoot, "*.dll", SearchOption.AllDirectories); +int failureCount = 0; +foreach (var assembly in assemblies) +{ + using var file = File.Open(assembly, FileMode.Open, FileAccess.Read); + using var reader = new PEReader(file); + + if (!reader.HasMetadata) + continue; + + var metadataReader = reader.GetMetadataReader(); + + foreach (var methodHandle in metadataReader.MethodDefinitions) + { + var method = metadataReader.GetMethodDefinition(methodHandle); + + // Detect the use of runtime async through MethodImplAttributes.Async. + if ((method.ImplAttributes & MethodImplAttributes.Async) != 0) + { + Console.WriteLine($"FAIL: {assembly} has methods with MethodImplAttributes.Async"); + failureCount++; + break; + } + } +} + +if (failureCount > 0) +{ + Console.WriteLine($"FAIL: assemblies use runtime async. Mono does not support runtime async."); + return 1; +} + +Console.WriteLine("PASS: no assemblies use runtime async."); +return 0; diff --git a/mono-no-runtime-async/mono-no-runtime-async.csproj b/mono-no-runtime-async/mono-no-runtime-async.csproj new file mode 100644 index 0000000..305d8ad --- /dev/null +++ b/mono-no-runtime-async/mono-no-runtime-async.csproj @@ -0,0 +1,10 @@ + + + + Exe + $(TestTargetFramework) + enable + enable + + + diff --git a/mono-no-runtime-async/test.json b/mono-no-runtime-async/test.json new file mode 100644 index 0000000..d070aa0 --- /dev/null +++ b/mono-no-runtime-async/test.json @@ -0,0 +1,14 @@ +{ + "name": "mono-no-runtime-async", + "enabled": true, + "requiresSdk": true, + "version": "11.0", + "versionSpecific": false, + "type": "bash", + "cleanup": true, + "skipWhen": [ + "runtime=coreclr" + ], + "ignoredRIDs":[ + ] +} diff --git a/mono-no-runtime-async/test.sh b/mono-no-runtime-async/test.sh new file mode 100644 index 0000000..7369d68 --- /dev/null +++ b/mono-no-runtime-async/test.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +set -euo pipefail +IFS=$'\n\t' + +dotnet run