未验证 提交 9962c108 编写于 作者: J Jeremy Koritzinsky 提交者: GitHub

src/tests tree test xunit-based source generated runner (#60846)

Co-authored-by: NAlexander Köplinger <alex.koeplinger@outlook.com>
Co-authored-by: NJan Kotas <jkotas@microsoft.com>
Co-authored-by: NSantiago Fernandez Madero <safern@microsoft.com>
Co-authored-by: NTomas <trylek@microsoft.com>
上级 f9e3e28a
......@@ -12,6 +12,12 @@
namespace Xunit
{
/// <summary>
/// A copy of the Xunit.FactAttribute type for assemblies that reference System.Private.CoreLib directly.
/// </summary>
public sealed class FactAttribute : Attribute
{}
/// <summary>
/// A collection of helper classes to test various conditions within
/// unit tests. If the condition being tested is not met, an exception
......
......@@ -15,6 +15,11 @@
<Compile Include="Utilities.cs" />
<Compile Include="HostPolicyMock.cs" />
<Compile Include="XPlatformUtils.cs" />
<Compile Include="CoreClrConfigurationDetection.cs" />
<Compile Include="OutOfProcessTest.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\Coreclr.TestWrapper\CoreclrTestWrapperLib.cs" Link="CoreclrTestWrapperLib.cs" />
</ItemGroup>
<ItemGroup>
......
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//
using System;
using System.Globalization;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
namespace TestLibrary;
public static class CoreClrConfigurationDetection
{
public static bool IsJitStress => !string.Equals(GetEnvironmentVariableValue("JitStress"), "0", StringComparison.InvariantCulture);
public static bool IsJitStressRegs => !string.Equals(GetEnvironmentVariableValue("JitStressRegs"), "0", StringComparison.InvariantCulture);
public static bool IsJitMinOpts => string.Equals(GetEnvironmentVariableValue("JITMinOpts"), "1", StringComparison.InvariantCulture);
public static bool IsTailCallStress => string.Equals(GetEnvironmentVariableValue("TailcallStress"), "1", StringComparison.InvariantCulture);
public static bool IsZapDisable => string.Equals(GetEnvironmentVariableValue("ZapDisable"), "1", StringComparison.InvariantCulture);
public static bool IsGCStress3 => CompareGCStressModeAsLower(GetEnvironmentVariableValue("GCStress"), "0x3", "3");
public static bool IsGCStressC => CompareGCStressModeAsLower(GetEnvironmentVariableValue("GCStress"), "0xC", "C");
public static bool IsGCStress => GetEnvironmentVariableValue("GCStress") != string.Empty;
public static bool IsCheckedRuntime => AssemblyConfigurationEquals("Checked");
public static bool IsReleaseRuntime => AssemblyConfigurationEquals("Release");
public static bool IsDebugRuntime => AssemblyConfigurationEquals("Debug");
public static bool IsStressTest =>
IsGCStress ||
IsZapDisable ||
IsTailCallStress ||
IsJitStressRegs ||
IsJitStress ||
IsJitMinOpts;
private static string GetEnvironmentVariableValue(string name) =>
Environment.GetEnvironmentVariable("DOTNET_" + name) ?? Environment.GetEnvironmentVariable("COMPlus_" + name) ?? "0";
private static bool AssemblyConfigurationEquals(string configuration)
{
AssemblyConfigurationAttribute assemblyConfigurationAttribute = typeof(string).Assembly.GetCustomAttribute<AssemblyConfigurationAttribute>();
return assemblyConfigurationAttribute != null &&
string.Equals(assemblyConfigurationAttribute.Configuration, configuration, StringComparison.InvariantCulture);
}
private static bool CompareGCStressModeAsLower(string value, string first, string second)
{
value = value.ToLowerInvariant();
return string.Equals(value, first.ToLowerInvariant(), StringComparison.InvariantCulture) ||
string.Equals(value, second.ToLowerInvariant(), StringComparison.InvariantCulture) ||
string.Equals(value, "0xf", StringComparison.InvariantCulture) ||
string.Equals(value, "f", StringComparison.InvariantCulture);
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using CoreclrTestLib;
using Xunit;
namespace TestLibrary
{
public static class OutOfProcessTest
{
internal static bool runningInWindows;
internal static string reportBase;
internal static string testBinaryBase;
internal static string helixUploadRoot;
static OutOfProcessTest()
{
reportBase = Directory.GetCurrentDirectory();
testBinaryBase = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!;
helixUploadRoot = Environment.GetEnvironmentVariable("HELIX_WORKITEM_UPLOAD_ROOT");
if (!String.IsNullOrEmpty(helixUploadRoot))
{
reportBase = Path.Combine(Path.GetFullPath(helixUploadRoot), "Reports");
}
if (String.IsNullOrEmpty(reportBase))
{
reportBase = Path.Combine(testBinaryBase, "Reports");
}
else
{
reportBase = Path.GetFullPath(reportBase);
}
}
public static void RunOutOfProcessTest(string basePath, string assemblyPath)
{
int ret = -100;
string outputFile = System.IO.Path.GetFullPath(reportBase + assemblyPath + "output.txt");
string errorFile = System.IO.Path.GetFullPath(reportBase + assemblyPath + "error.txt");
string outputDir = System.IO.Path.GetDirectoryName(outputFile)!;
string testExecutable = null;
Exception infraEx = null;
try
{
CoreclrTestWrapperLib wrapper = new CoreclrTestWrapperLib();
if (OperatingSystem.IsWindows())
{
testExecutable = Path.Combine(basePath, Path.ChangeExtension(assemblyPath, ".cmd"));
}
else
{
testExecutable = Path.Combine(basePath, Path.ChangeExtension(assemblyPath.Replace("\\", "/"), ".sh"));
}
System.IO.Directory.CreateDirectory(reportBase + Path.GetDirectoryName(assemblyPath));
ret = wrapper.RunTest(testExecutable, outputFile, errorFile, Assembly.GetEntryAssembly()!.FullName!, testBinaryBase, outputDir);
}
catch (Exception ex)
{
infraEx = ex;
}
if (infraEx != null)
{
Assert.True(false, "Test Infrastructure Failure: " + infraEx.ToString());
}
else
{
List<string> testOutput = new List<string>();
try
{
testOutput.AddRange(System.IO.File.ReadAllLines(errorFile));
}
catch (Exception ex)
{
testOutput.Add("Unable to read error file: " + errorFile);
testOutput.Add(ex.ToString());
}
testOutput.Add(string.Empty);
testOutput.Add("Return code: " + ret);
testOutput.Add("Raw output file: " + outputFile);
testOutput.Add("Raw output:");
try
{
testOutput.AddRange(System.IO.File.ReadAllLines(outputFile));
}
catch (Exception ex)
{
testOutput.Add("Unable to read output file: " + outputFile);
testOutput.Add(ex.ToString());
}
testOutput.Add("To run the test:");
testOutput.Add("Set up CORE_ROOT and run.");
testOutput.Add("> " + testExecutable);
var unicodeControlCharsRegex = new Regex("%5C%5Cp{C}+");
// Remove all characters that have no visual or spatial representation.
for (int i = 0; i < testOutput.Count; i++)
{
string line = testOutput[i];
line = unicodeControlCharsRegex.Replace(line, string.Empty);
testOutput[i] = line;
}
foreach (string line in testOutput)
{
Console.WriteLine(line);
}
Assert.True(ret == CoreclrTestWrapperLib.EXIT_SUCCESS_CODE, string.Join(Environment.NewLine, testOutput));
}
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//
#nullable disable
using System;
using System.Collections.Generic;
......@@ -196,7 +197,7 @@ public class CoreclrTestWrapperLib
{
public const int EXIT_SUCCESS_CODE = 0;
public const string TIMEOUT_ENVIRONMENT_VAR = "__TestTimeout";
// Default timeout set to 10 minutes
public const int DEFAULT_TIMEOUT_MS = 1000 * 60 * 10;
......@@ -289,7 +290,7 @@ public int RunTest(string executable, string outputFile, string errorFile, strin
Debug.Assert(outputFile != errorFile);
int exitCode = -100;
// If a timeout was given to us by an environment variable, use it instead of the default
// timeout.
string environmentVar = Environment.GetEnvironmentVariable(TIMEOUT_ENVIRONMENT_VAR);
......@@ -387,7 +388,5 @@ public int RunTest(string executable, string outputFile, string errorFile, strin
return exitCode;
}
}
}
<Project>
<PropertyGroup>
<IsTestsCommonProject>true</IsTestsCommonProject>
</PropertyGroup>
<!-- SDK Style projects auto-magically include this file. -->
<Import Project="..\Directory.Build.props" />
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsMergedTestRunnerAssembly>true</IsMergedTestRunnerAssembly>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="$(RepoRoot)/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
<ProjectReference Include="$(RepoRoot)/src/tests/Common/XUnitWrapperLibrary/XUnitWrapperLibrary.csproj" />
</ItemGroup>
<Import Project="$(RepoRoot)/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.props" />
<ItemGroup>
<ProjectReference Include="$(RepoRoot)\src\tests\JIT\IL_Conformance\Old\directed\AutoInit.ilproj" />
</ItemGroup>
</Project>
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Text;
using Microsoft.CodeAnalysis;
namespace XUnitWrapperGenerator;
interface ITestInfo
{
string TestNameExpression { get; }
string DisplayNameForFiltering { get; }
string Method { get; }
string ContainingType { get; }
string GenerateTestExecution(ITestReporterWrapper testReporterWrapper);
}
interface ITestReporterWrapper
{
string WrapTestExecutionWithReporting(string testExecution, ITestInfo test);
string GenerateSkippedTestReporting(ITestInfo skippedTest);
}
sealed class BasicTestMethod : ITestInfo
{
public BasicTestMethod(IMethodSymbol method, string externAlias, ImmutableArray<string> arguments = default, string? displayNameExpression = null)
{
var args = arguments.IsDefaultOrEmpty ? "" : string.Join(", ", arguments);
ContainingType = method.ContainingType.ToDisplayString(XUnitWrapperGenerator.FullyQualifiedWithoutGlobalNamespace);
Method = method.Name;
DisplayNameForFiltering = $"{ContainingType}.{Method}({args})";
TestNameExpression = displayNameExpression ?? $"\"{externAlias}::{ContainingType}.{Method}({args})\"";
if (method.IsStatic)
{
ExecutionStatement = $"{externAlias}::{ContainingType}.{Method}({args});";
}
else
{
ExecutionStatement = $"using ({externAlias}::{ContainingType} obj = new()) obj.{Method}({args});";
}
}
public string TestNameExpression { get; }
public string DisplayNameForFiltering { get; }
public string Method { get; }
public string ContainingType { get; }
private string ExecutionStatement { get; }
public string GenerateTestExecution(ITestReporterWrapper testReporterWrapper)
{
return testReporterWrapper.WrapTestExecutionWithReporting(ExecutionStatement, this);
}
public override bool Equals(object obj)
{
return obj is BasicTestMethod other
&& TestNameExpression == other.TestNameExpression
&& Method == other.Method
&& ContainingType == other.ContainingType
&& ExecutionStatement == other.ExecutionStatement;
}
}
sealed class LegacyStandaloneEntryPointTestMethod : ITestInfo
{
public LegacyStandaloneEntryPointTestMethod(IMethodSymbol method, string externAlias)
{
ContainingType = method.ContainingType.ToDisplayString(XUnitWrapperGenerator.FullyQualifiedWithoutGlobalNamespace);
Method = method.Name;
TestNameExpression = $"\"{externAlias}::{ContainingType}.{Method}()\"";
DisplayNameForFiltering = $"{ContainingType}.{Method}()";
ExecutionStatement = $"Xunit.Assert.Equal(100, {externAlias}::{ContainingType}.{Method}());";
}
public string TestNameExpression { get; }
public string DisplayNameForFiltering { get; }
public string Method { get; }
public string ContainingType { get; }
private string ExecutionStatement { get; }
public string GenerateTestExecution(ITestReporterWrapper testReporterWrapper)
{
return testReporterWrapper.WrapTestExecutionWithReporting(ExecutionStatement, this);
}
public override bool Equals(object obj)
{
return obj is LegacyStandaloneEntryPointTestMethod other
&& TestNameExpression == other.TestNameExpression
&& Method == other.Method
&& ContainingType == other.ContainingType; ;
}
}
sealed class ConditionalTest : ITestInfo
{
private ITestInfo _innerTest;
private string _condition;
public ConditionalTest(ITestInfo innerTest, string condition)
{
_innerTest = innerTest;
_condition = condition;
TestNameExpression = innerTest.TestNameExpression;
DisplayNameForFiltering = innerTest.DisplayNameForFiltering;
Method = innerTest.Method;
ContainingType = innerTest.ContainingType;
}
public ConditionalTest(ITestInfo innerTest, Xunit.TestPlatforms platform)
: this(innerTest, GetPlatformConditionFromTestPlatform(platform))
{
}
public string TestNameExpression { get; }
public string DisplayNameForFiltering { get; }
public string Method { get; }
public string ContainingType { get; }
public string GenerateTestExecution(ITestReporterWrapper testReporterWrapper)
{
return $"if ({_condition}) {{ {_innerTest.GenerateTestExecution(testReporterWrapper)} }} else {{ {testReporterWrapper.GenerateSkippedTestReporting(_innerTest)} }}";
}
public override bool Equals(object obj)
{
return obj is ConditionalTest other
&& TestNameExpression == other.TestNameExpression
&& Method == other.Method
&& ContainingType == other.ContainingType
&& _condition == other._condition
&& _innerTest.Equals(other._innerTest);
}
private static string GetPlatformConditionFromTestPlatform(Xunit.TestPlatforms platform)
{
List<string> platformCheckConditions = new();
if (platform.HasFlag(Xunit.TestPlatforms.Windows))
{
platformCheckConditions.Add("global::System.OperatingSystem.IsWindows()");
}
if (platform.HasFlag(Xunit.TestPlatforms.Linux))
{
platformCheckConditions.Add("global::System.OperatingSystem.IsLinux()");
}
if (platform.HasFlag(Xunit.TestPlatforms.OSX))
{
platformCheckConditions.Add("global::System.OperatingSystem.IsMacOS()");
}
if (platform.HasFlag(Xunit.TestPlatforms.illumos))
{
platformCheckConditions.Add(@"global::System.OperatingSystem.IsOSPlatform(""illumos"")");
}
if (platform.HasFlag(Xunit.TestPlatforms.Solaris))
{
platformCheckConditions.Add(@"global::System.OperatingSystem.IsOSPlatform(""Solaris"")");
}
if (platform.HasFlag(Xunit.TestPlatforms.Android))
{
platformCheckConditions.Add("global::System.OperatingSystem.IsAndroid()");
}
if (platform.HasFlag(Xunit.TestPlatforms.iOS))
{
platformCheckConditions.Add("(global::System.OperatingSystem.IsIOS() && !global::System.OperatingSystem.IsMacCatalyst())");
}
if (platform.HasFlag(Xunit.TestPlatforms.tvOS))
{
platformCheckConditions.Add("global::System.OperatingSystem.IsTvOS()");
}
if (platform.HasFlag(Xunit.TestPlatforms.MacCatalyst))
{
platformCheckConditions.Add("global::System.OperatingSystem.IsMacCatalyst()");
}
if (platform.HasFlag(Xunit.TestPlatforms.Browser))
{
platformCheckConditions.Add("global::System.OperatingSystem.IsBrowser()");
}
if (platform.HasFlag(Xunit.TestPlatforms.FreeBSD))
{
platformCheckConditions.Add(@"global::System.OperatingSystem.IsFreeBSD()");
}
if (platform.HasFlag(Xunit.TestPlatforms.NetBSD))
{
platformCheckConditions.Add(@"global::System.OperatingSystem.IsOSPlatform(""NetBSD"")");
}
return string.Join(" || ", platformCheckConditions);
}
}
sealed class MemberDataTest : ITestInfo
{
private ITestInfo _innerTest;
private string _memberInvocation;
private string _loopVarIdentifier;
public MemberDataTest(ISymbol referencedMember, ITestInfo innerTest, string externAlias, string argumentLoopVarIdentifier)
{
TestNameExpression = innerTest.TestNameExpression;
Method = innerTest.Method;
ContainingType = innerTest.ContainingType;
DisplayNameForFiltering = $"{ContainingType}.{Method}(...)";
_innerTest = innerTest;
_loopVarIdentifier = argumentLoopVarIdentifier;
string containingType = referencedMember.ContainingType.ToDisplayString(XUnitWrapperGenerator.FullyQualifiedWithoutGlobalNamespace);
_memberInvocation = referencedMember switch
{
IPropertySymbol { IsStatic: true } => $"{externAlias}::{containingType}.{referencedMember.Name}",
IMethodSymbol { IsStatic: true, Parameters: { Length: 0 } } => $"{externAlias}::{containingType}.{referencedMember.Name}()",
_ => throw new ArgumentException()
};
}
public string TestNameExpression { get; }
public string DisplayNameForFiltering { get; }
public string Method { get; }
public string ContainingType { get; }
public string GenerateTestExecution(ITestReporterWrapper testReporterWrapper)
{
return $@"
foreach (object[] {_loopVarIdentifier} in {_memberInvocation})
{{
{_innerTest.GenerateTestExecution(testReporterWrapper)}
}}
";
}
public override bool Equals(object obj)
{
return obj is MemberDataTest other
&& TestNameExpression == other.TestNameExpression
&& Method == other.Method
&& ContainingType == other.ContainingType
&& _innerTest.Equals(other._innerTest);
}
}
sealed class OutOfProcessTest : ITestInfo
{
public OutOfProcessTest(string displayName, string relativeAssemblyPath)
{
Method = displayName;
DisplayNameForFiltering = displayName;
TestNameExpression = $"@\"{displayName}\"";
ExecutionStatement = $@"TestLibrary.OutOfProcessTest.RunOutOfProcessTest(typeof(Program).Assembly.Location, @""{relativeAssemblyPath}"");";
}
public string TestNameExpression { get; }
public string DisplayNameForFiltering { get; }
public string Method { get; }
public string ContainingType => "OutOfProcessTest";
private string ExecutionStatement { get; }
public string GenerateTestExecution(ITestReporterWrapper testReporterWrapper) => testReporterWrapper.WrapTestExecutionWithReporting(ExecutionStatement, this);
}
sealed class NoTestReporting : ITestReporterWrapper
{
public string WrapTestExecutionWithReporting(string testExecution, ITestInfo test) => testExecution;
public string GenerateSkippedTestReporting(ITestInfo skippedTest) => string.Empty;
}
sealed class WrapperLibraryTestSummaryReporting : ITestReporterWrapper
{
private string _summaryLocalIdentifier;
private readonly string _filterLocalIdentifier;
public WrapperLibraryTestSummaryReporting(string summaryLocalIdentifier, string filterLocalIdentifier)
{
_summaryLocalIdentifier = summaryLocalIdentifier;
_filterLocalIdentifier = filterLocalIdentifier;
}
public string WrapTestExecutionWithReporting(string testExecutionExpression, ITestInfo test)
{
StringBuilder builder = new();
builder.AppendLine($"if ({_filterLocalIdentifier} is null || {_filterLocalIdentifier}.ShouldRunTest(@\"{test.ContainingType}.{test.Method}\", {test.TestNameExpression}))");
builder.AppendLine("{");
builder.AppendLine($"TimeSpan testStart = stopwatch.Elapsed;");
builder.AppendLine("try {");
builder.AppendLine(testExecutionExpression);
builder.AppendLine($"{_summaryLocalIdentifier}.ReportPassedTest({test.TestNameExpression}, \"{test.ContainingType}\", @\"{test.Method}\", stopwatch.Elapsed - testStart);");
builder.AppendLine("}");
builder.AppendLine("catch (System.Exception ex) {");
builder.AppendLine($"{_summaryLocalIdentifier}.ReportFailedTest({test.TestNameExpression}, \"{test.ContainingType}\", @\"{test.Method}\", stopwatch.Elapsed - testStart, ex);");
builder.AppendLine("}");
builder.AppendLine("}");
return builder.ToString();
}
public string GenerateSkippedTestReporting(ITestInfo skippedTest)
{
return $"{_summaryLocalIdentifier}.ReportSkippedTest({skippedTest.TestNameExpression}, \"{skippedTest.ContainingType}\", \"{skippedTest.Method}\", TimeSpan.Zero, string.Empty);";
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Text;
namespace XUnitWrapperGenerator;
internal class ImmutableDictionaryValueComparer<TKey, TValue> : IEqualityComparer<ImmutableDictionary<TKey, TValue>>
where TKey : notnull
{
private readonly IEqualityComparer<TValue> _valueComparer;
public ImmutableDictionaryValueComparer(IEqualityComparer<TValue> valueComparer)
{
_valueComparer = valueComparer;
}
public bool Equals(ImmutableDictionary<TKey, TValue> x, ImmutableDictionary<TKey, TValue> y)
{
if (x.Count != y.Count)
{
return false;
}
foreach (var pair in x)
{
if (!y.TryGetValue(pair.Key, out TValue? value) || !_valueComparer.Equals(value, pair.Value))
{
return false;
}
}
return true;
}
public int GetHashCode(ImmutableDictionary<TKey, TValue> obj) => throw new NotImplementedException();
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.CodeAnalysis.Diagnostics;
namespace XUnitWrapperGenerator;
public static class OptionsHelper
{
private const string ReferenceSystemPrivateCoreLibOption = "build_property.ReferenceSystemPrivateCoreLib";
private const string IsMergedTestRunnerAssemblyOption = "build_property.IsMergedTestRunnerAssembly";
private const string PriorityOption = "build_property.Priority";
private const string RuntimeFlavorOption = "build_property.RuntimeFlavor";
private const string IsOutOfProcessTestAssemblyOption = "build_metadata.AdditionalFiles.IsOutOfProcessTestAssembly";
private const string TestFilterOption = "build_metadata.AdditionalFiles.TestFilter";
private const string TestAssemblyRelativePathOption = "build_metadata.AdditionalFiles.TestAssemblyRelativePath";
private const string TestDisplayNameOption = "build_metadata.AdditionalFiles.TestDisplayName";
private static bool GetBoolOption(this AnalyzerConfigOptions options, string key)
{
return options.TryGetValue(key, out string? value)
&& bool.TryParse(value, out bool result)
&& result;
}
private static int? GetIntOption(this AnalyzerConfigOptions options, string key)
{
return options.TryGetValue(key, out string? value)
&& int.TryParse(value, out int result)
? result : 0;
}
internal static bool ReferenceSystemPrivateCoreLib(this AnalyzerConfigOptions options) => options.GetBoolOption(ReferenceSystemPrivateCoreLibOption);
internal static bool IsMergedTestRunnerAssembly(this AnalyzerConfigOptions options) => options.GetBoolOption(IsMergedTestRunnerAssemblyOption);
internal static int? Priority(this AnalyzerConfigOptions options) => options.GetIntOption(PriorityOption);
internal static string RuntimeFlavor(this AnalyzerConfigOptions options) => options.TryGetValue(RuntimeFlavorOption, out string? flavor) ? flavor : "CoreCLR";
internal static bool IsOutOfProcessTestAssembly(this AnalyzerConfigOptions options) => options.GetBoolOption(IsOutOfProcessTestAssemblyOption);
internal static string? TestFilter(this AnalyzerConfigOptions options) => options.TryGetValue(TestFilterOption, out string? filter) ? filter : null;
internal static string? TestAssemblyRelativePath(this AnalyzerConfigOptions options) => options.TryGetValue(TestAssemblyRelativePathOption, out string? flavor) ? flavor : null;
internal static string? TestDisplayName(this AnalyzerConfigOptions options) => options.TryGetValue(TestDisplayNameOption, out string? flavor) ? flavor : null;
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
namespace Xunit
{
[Flags]
public enum RuntimeConfiguration
{
Any = ~0,
Checked = 1,
Debug = 1 << 1,
Release = 1 << 2
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
namespace Xunit
{
[Flags]
public enum RuntimeTestModes
{
// Disable always when using coreclr runtime.
Any = ~0,
// We're running regular tests with no runtime stress modes
RegularRun = 1,
// JitStress, JitStressRegs, JitMinOpts and TailcallStress enable
// various modes in the JIT that cause us to exercise more code paths,
// and generate different kinds of code
JitStress = 1 << 1, // COMPlus_JitStress is set.
JitStressRegs = 1 << 2, // COMPlus_JitStressRegs is set.
JitMinOpts = 1 << 3, // COMPlus_JITMinOpts is set.
TailcallStress = 1 << 4, // COMPlus_TailcallStress is set.
// ZapDisable says to not use NGEN or ReadyToRun images.
// This means we JIT everything.
ZapDisable = 1 << 5, // COMPlus_ZapDisable is set.
// GCStress3 forces a GC at various locations, typically transitions
// to/from the VM from managed code.
GCStress3 = 1 << 6, // COMPlus_GCStress includes mode 0x3.
// GCStressC forces a GC at every JIT-generated code instruction,
// including in NGEN/ReadyToRun code.
GCStressC = 1 << 7, // COMPlus_GCStress includes mode 0xC.
AnyGCStress = GCStress3 | GCStressC // Disable when any GCStress is exercised.
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.CodeAnalysis;
namespace XUnitWrapperGenerator;
internal static class SymbolExtensions
{
public static IEnumerable<AttributeData> GetAttributesOnSelfAndContainingSymbols(this ISymbol symbol)
{
for (ISymbol? containing = symbol; containing is not null; containing = containing.ContainingSymbol)
{
foreach (var attr in containing.GetAttributes())
{
yield return attr;
}
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
namespace Xunit
{
[Flags]
public enum TargetFrameworkMonikers
{
Netcoreapp = 1,
NetFramework = 2,
Any = ~0
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
namespace Xunit
{
[Flags]
public enum TestPlatforms
{
Windows = 1,
Linux = 2,
OSX = 4,
FreeBSD = 8,
NetBSD = 16,
illumos= 32,
Solaris = 64,
iOS = 128,
tvOS = 256,
Android = 512,
Browser = 1024,
MacCatalyst = 2048,
AnyUnix = FreeBSD | Linux | NetBSD | OSX | illumos | Solaris | iOS | tvOS | MacCatalyst | Android | Browser,
Any = ~0
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
namespace Xunit
{
[Flags]
public enum TestRuntimes
{
CoreCLR = 1,
Mono = 2,
Any = ~0
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Nullable>enable</Nullable>
<EnableDefaultItems>true</EnableDefaultItems>
<IsRoslynComponent>true</IsRoslynComponent>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis" Version="$(MicrosoftCodeAnalysisVersion)" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="$(MicrosoftCodeAnalysisCSharpVersion)" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="$(MicrosoftCodeAnalysisAnalyzersVersion)" />
</ItemGroup>
<ItemGroup>
<Compile Include="../XUnitWrapperLibrary/TestFilter.cs" Link="TestFilter.cs" />
</ItemGroup>
</Project>
<Project>
<ItemGroup>
<!-- Properties used for filtering -->
<CompilerVisibleProperty Include="RuntimeFlavor" />
<CompilerVisibleProperty Include="TargetOS" />
<CompilerVisibleProperty Include="TargetArchitecture" />
<CompilerVisibleProperty Include="Priority" />
<!-- Properties that influence test harness generation -->
<CompilerVisibleProperty Include="ReferenceSystemPrivateCoreLib" />
<CompilerVisibleProperty Include="IsMergedTestRunnerAssembly" />
<CompilerVisibleProperty Include="TestFilter" />
<CompilerVisibleItemMetadata Include="AdditionalFiles" MetadataName="IsOutOfProcessTestAssembly" />
<CompilerVisibleItemMetadata Include="AdditionalFiles" MetadataName="TestAssemblyRelativePath" />
<CompilerVisibleItemMetadata Include="AdditionalFiles" MetadataName="TestDisplayName" />
</ItemGroup>
<Target Name="AddOutOfProcessTestAssembliesToCompilation" AfterTargets="ResolveProjectReferences">
<ItemGroup>
<OutOfProcessTests IsOutOfProcessTestAssembly="true" TestAssemblyRelativePath="$([MSBuild]::MakeRelative('$(OutputPath)', '%(Identity)'))" TestDisplayName="$([MSBuild]::MakeRelative('$(TestBinDir)', '%(Identity)'))" />
<!-- Change the extension to .cmd to match the existing test names for out-of-proc test runs. -->
<AdditionalFiles Include="@(OutOfProcessTests)" TestDisplayName="$([System.IO.Path]::ChangeExtension('%(TestDisplayName)', '.cmd'))" />
</ItemGroup>
</Target>
</Project>
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//
using System;
using System.Collections.Generic;
using System.Text;
namespace XUnitWrapperLibrary;
public class TestFilter
{
interface ISearchClause
{
bool IsMatch(string fullyQualifiedName, string displayName, string[] traits);
}
enum TermKind
{
FullyQualifiedName,
DisplayName
}
sealed class NameClause : ISearchClause
{
public NameClause(TermKind kind, string filter, bool substring)
{
Kind = kind;
Filter = filter;
Substring = substring;
}
public TermKind Kind { get; }
public string Filter { get; }
public bool Substring { get; }
public bool IsMatch(string fullyQualifiedName, string displayName, string[] traits)
{
string stringToSearch = Kind switch
{
TermKind.FullyQualifiedName => fullyQualifiedName,
TermKind.DisplayName => displayName,
_ => throw new InvalidOperationException()
};
if (Substring)
{
return stringToSearch.Contains(Filter);
}
return stringToSearch == Filter;
}
}
sealed class AndClause : ISearchClause
{
private ISearchClause _left;
private ISearchClause _right;
public AndClause(ISearchClause left, ISearchClause right)
{
_left = left;
_right = right;
}
public bool IsMatch(string fullyQualifiedName, string displayName, string[] traits) => _left.IsMatch(fullyQualifiedName, displayName, traits) && _right.IsMatch(fullyQualifiedName, displayName, traits);
}
sealed class OrClause : ISearchClause
{
private ISearchClause _left;
private ISearchClause _right;
public OrClause(ISearchClause left, ISearchClause right)
{
_left = left;
_right = right;
}
public bool IsMatch(string fullyQualifiedName, string displayName, string[] traits) => _left.IsMatch(fullyQualifiedName, displayName, traits) || _right.IsMatch(fullyQualifiedName, displayName, traits);
}
sealed class NotClause : ISearchClause
{
private ISearchClause _inner;
public NotClause(ISearchClause inner)
{
_inner = inner;
}
public bool IsMatch(string fullyQualifiedName, string displayName, string[] traits) => !_inner.IsMatch(fullyQualifiedName, displayName, traits);
}
private ISearchClause? _filter;
public TestFilter(string filterString)
{
if (filterString.IndexOfAny(new[] { '!', '(', ')', '~', '=' }) != -1)
{
throw new ArgumentException("Complex test filter expressions are not supported today. The only filters supported today are the simple form supported in 'dotnet test --filter' (substrings of the test's fully qualified name). If further filtering options are desired, file an issue on dotnet/runtime for support.", nameof(filterString));
}
_filter = new NameClause(TermKind.FullyQualifiedName, filterString, substring: true);
}
public bool ShouldRunTest(string fullyQualifiedName, string displayName, string[]? traits = null) => _filter is null ? true : _filter.IsMatch(fullyQualifiedName, displayName, traits ?? Array.Empty<string>());
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//
using System;
using System.Collections.Generic;
using System.Text;
namespace XUnitWrapperLibrary;
public class TestSummary
{
readonly record struct TestResult(string Name, string ContainingTypeName, string MethodName, TimeSpan Duration, Exception? Exception, string? SkipReason);
private int _numPassed = 0;
private int _numFailed = 0;
private int _numSkipped = 0;
private readonly List<TestResult> _testResults = new();
private DateTime _testRunStart = DateTime.Now;
public void ReportPassedTest(string name, string containingTypeName, string methodName, TimeSpan duration)
{
_numPassed++;
_testResults.Add(new TestResult(name, containingTypeName, methodName, duration, null, null));
}
public void ReportFailedTest(string name, string containingTypeName, string methodName, TimeSpan duration, Exception ex)
{
_numFailed++;
_testResults.Add(new TestResult(name, containingTypeName, methodName, duration, ex, null));
}
public void ReportSkippedTest(string name, string containingTypeName, string methodName, TimeSpan duration, string reason)
{
_numSkipped++;
_testResults.Add(new TestResult(name, containingTypeName, methodName, duration, null, reason));
}
public string GetTestResultOutput()
{
double totalRunSeconds = (DateTime.Now - _testRunStart).TotalSeconds;
// using StringBuilder here for simplicity of loaded IL.
StringBuilder resultsFile = new();
resultsFile.AppendLine("<assemblies>");
resultsFile.AppendLine($@"
<assembly
name=""""
test-framework=""XUnitWrapperGenerator-generated-runner""
run-date=""{_testRunStart.ToString("yyy-mm-dd")}""
run-time=""{_testRunStart.ToString("hh:mm:ss")}""
time=""{totalRunSeconds}""
total=""{_testResults.Count}""
passed=""{_numPassed}""
failed=""{_numFailed}""
skipped=""{_numSkipped}""
errors=""0"">");
resultsFile.AppendLine($@"
<collection
name=""Collection""
time=""{totalRunSeconds}""
total=""{_testResults.Count}""
passed=""{_numPassed}""
failed=""{_numFailed}""
skipped=""{_numSkipped}""
errors=""0""
>");
foreach (var test in _testResults)
{
resultsFile.Append($@"<test name=""{test.Name}"" type=""{test.ContainingTypeName}"" method=""{test.MethodName}"" time=""{test.Duration}"" ");
if (test.Exception is not null)
{
resultsFile.AppendLine($@"result=""Fail""><failure exception-type=""{test.Exception.GetType()}""><message><![CDATA[{test.Exception.Message}]]></message><stack-trace><![CDATA[{test.Exception.StackTrace}]]></stack-trace></failure></test>");
}
else if (test.SkipReason is not null)
{
resultsFile.AppendLine($@"result=""Skip""><reason><![CDATA[{test.SkipReason}]]></reason></test>");
}
else
{
resultsFile.AppendLine(@" result=""Pass"" />");
}
}
resultsFile.AppendLine("</collection>");
resultsFile.AppendLine("</assembly>");
resultsFile.AppendLine("</assemblies>");
return resultsFile.ToString();
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Library</OutputType>
<CLRTestKind>BuildOnly</CLRTestKind>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<GenerateRunScript>false</GenerateRunScript>
<TargetFramework>$(NetCoreAppToolCurrent)</TargetFramework>
<EnableDefaultItems>true</EnableDefaultItems>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Threading;
using Xunit.Runners;
namespace Xunit
{
public abstract class XunitBase
{
private static object consoleLock = new object();
private static ManualResetEvent finished = new ManualResetEvent(false);
private static int result = 100;
public int RunTests()
{
var runner = AssemblyRunner.WithoutAppDomain(GetType().Assembly.Location);
runner.OnDiscoveryComplete = OnDiscoveryComplete;
runner.OnExecutionComplete = OnExecutionComplete;
runner.OnTestFailed = OnTestFailed;
runner.OnTestSkipped = OnTestSkipped;
Console.WriteLine("Discovering...");
runner.Start();
finished.WaitOne();
finished.Dispose();
return result;
}
private static void OnDiscoveryComplete(DiscoveryCompleteInfo info)
{
lock (consoleLock)
Console.WriteLine($"Running {info.TestCasesToRun} of {info.TestCasesDiscovered} tests...");
}
private static void OnExecutionComplete(ExecutionCompleteInfo info)
{
lock (consoleLock)
Console.WriteLine($"Finished: {info.TotalTests} tests in {Math.Round(info.ExecutionTime, 3)}s ({info.TestsFailed} failed, {info.TestsSkipped} skipped)");
finished.Set();
}
private static void OnTestFailed(TestFailedInfo info)
{
lock (consoleLock)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("[FAIL] {0}: {1}", info.TestDisplayName, info.ExceptionMessage);
if (info.ExceptionStackTrace != null)
Console.WriteLine(info.ExceptionStackTrace);
Console.ResetColor();
}
result = 101;
}
private static void OnTestSkipped(TestSkippedInfo info)
{
lock (consoleLock)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("[SKIP] {0}: {1}", info.TestDisplayName, info.SkipReason);
Console.ResetColor();
}
}
}
}
......@@ -63,6 +63,7 @@
<PackageToInclude Include="Microsoft.CodeAnalysis.CSharp"/>
<PackageToInclude Include="Microsoft.CodeAnalysis.VisualBasic"/>
<PackageToInclude Include="CommandLineParser"/>
<PackageToInclude Include="Microsoft.DotNet.XUnitExtensions" />
<PackageReference Include="Microsoft.CodeAnalysis.Compilers" Version="1.1.1" />
<PackageReference Include="CommandLineParser" Version="2.1.1-beta" />
......@@ -71,6 +72,7 @@
<PackageReference Include="Newtonsoft.Json.Bson" Version="1.0.2" />
<PackageReference Include="xunit" Version="$(XUnitVersion)" />
<PackageReference Include="Microsoft.DotNet.XUnitConsoleRunner" Version="$(MicrosoftDotNetXUnitConsoleRunnerVersion)" GeneratePathProperty="True" />
<PackageReference Include="Microsoft.DotNet.XUnitExtensions" Version="$(MicrosoftDotNetXUnitExtensionsVersion)" />
<PackageReference Include="xunit.runner.utility" Version="$(XUnitVersion)" />
</ItemGroup>
......
......@@ -3,7 +3,7 @@
<PropertyGroup>
<LibrariesConfiguration>Release</LibrariesConfiguration>
</PropertyGroup>
<Import Project="$(MSBuildThisFileDirectory)\Common\dir.sdkbuild.props" Condition="'$(UsingMicrosoftNETSdk)' == 'true'" />
<Import Project="$(MSBuildThisFileDirectory)\Common\dir.common.props" Condition="'$(UsingMicrosoftNETSdk)' != 'true'" />
......@@ -179,4 +179,9 @@
<PropertyGroup Condition="'$(TargetOS)' == 'Browser'">
<CLRTestMSBuildArgs>/p:MSBuildEnableWorkloadResolver=false</CLRTestMSBuildArgs>
</PropertyGroup>
<PropertyGroup Condition="'$(IsTestsCommonProject)' != 'true'">
<BuildAsStandalone Condition="'$(BuildAsStandalone)' == ''">true</BuildAsStandalone>
<OutputType>Exe</OutputType>
</PropertyGroup>
</Project>
......@@ -408,6 +408,32 @@
</Target>
<Target Name="GetRequiresProcessIsolation" Returns="@(ProjectRequiringProcessIsolation)">
<ItemGroup Condition="'$(RequiresProcessIsolation)' == 'true'">
<ProjectRequiringProcessIsolation Include="$(MSBuildProjectFullPath)" />
</ItemGroup>
</Target>
<Target Name="DiscoverProcessIsolatedTestProjectReferences" BeforeTargets="AssignProjectConfiguration">
<MSBuild Projects="@(ProjectReference)" Targets="GetRequiresProcessIsolation" SkipNonexistentTargets="true">
<Output TaskParameter="TargetOutputs" ItemName="ReferencedProjectRequiringProcessIsolation" />
</MSBuild>
<ItemGroup>
<ProjectReference Remove="@(ReferencedProjectRequiringProcessIsolation)" />
<ProjectReference Include="@(ReferencedProjectRequiringProcessIsolation)" OutputItemType="OutOfProcessTests" BuildReference="true" ReferenceOutputAssembly="false" />
</ItemGroup>
</Target>
<PropertyGroup Condition="'$(Language)' == 'C#' and ('$(BuildAsStandalone)' == 'true' or '$(RequiresProcessIsolation)' == 'true' or '$(IsMergedTestAssembly)' == 'true')">
<ReferenceXUnitWrapperGenerator Condition="'$(ReferenceXUnitWrapperGenerator)' == ''">true</ReferenceXUnitWrapperGenerator>
</PropertyGroup>
<ItemGroup Condition="'$(ReferenceXUnitWrapperGenerator)' == 'true'">
<ProjectReference Include="$(RepoRoot)/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>
<Import Project="$(RepoRoot)/src/tests/Common/XUnitWrapperGenerator/XUnitWrapperGenerator.props" />
<Import Project="$(RepoRoot)eng/liveBuilds.targets" />
<Import Project="$(MSBuildProjectFullPath).targets" Condition="Exists('$(MSBuildProjectFullPath).targets')"/>
......
......@@ -4,9 +4,20 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using Xunit;
using Console = Internal.Console;
namespace Xunit
{
// Include an inline definition of the SkipOnMonoAttribute type as tests that reference CoreLib
// only reference CoreLib and don't reference any other assemblies.
public class SkipOnMonoAttribute : Attribute
{
public SkipOnMonoAttribute(string reason, int testPlatforms = ~0) { }
}
}
public interface IRetArg<T>
{
T ReturnArg(T t);
......@@ -114,22 +125,17 @@ public RuntimeTypeHandle GetImplType(RuntimeTypeHandle interfaceType)
return default(RuntimeTypeHandle);
}
}
public class Program
public class CastableTests
{
private static bool passed = true;
public static void Assert(bool value, string message)
{
if (!value)
{
Console.WriteLine("FAIL! " + message);
passed = false;
}
Xunit.Assert.True(value, message);
}
public static int Main()
[Fact]
[SkipOnMono("ICastable is unsupported on Mono")]
public static void Test()
{
//Console.WriteLine("Execution started. Attach debugger and press enter.");
//Console.ReadLine();
......@@ -145,7 +151,7 @@ public static int Main()
{ typeof(IExtra), null }, //we should never use it
}
);
// testing simple cases
Assert(implProxy is IRetThis, "implProxy should be castable to IRetThis via is");
Assert(!(implProxy is IUnimplemented), "implProxy should not be castable to IUnimplemented via is");
......@@ -158,7 +164,7 @@ public static int Main()
Assert(!(implProxy is IUnimplemented), "implProxy should not be castable to IUnimplemented via is");
Assert((implProxy as IUnimplemented) == null, "implProxy should not be castable to IUnimplemented via as");
// testing generics
IRetArg<string> retArgStr = (IRetArg<string>)implProxy;
Assert(retArgStr.ReturnArg("hohoho") == "hohoho", "retArgStr.ReturnArg() should return arg");
......@@ -184,7 +190,7 @@ public static int Main()
{
var _ = (IRetThis)nullCastable;
Assert(false, "Exceptions should be thrown from IsInstanceOfInterface");
}
}
catch (CastableException) {}
Assert(!(nullCastable is IRetThis), "null castable shouldn't be allowed to be casted to anything");
......@@ -198,7 +204,7 @@ public static int Main()
var r = (IRetThis)badCastable;
r.ReturnThis();
Assert(false, "Exceptions should be thrown from ReturnThis()");
}
}
catch (EntryPointNotFoundException) {}
//delegate testing
......@@ -212,17 +218,5 @@ public static int Main()
{
Assert(false, e.ToString());
}
if (passed)
{
Console.WriteLine("Test PASSED!");
return 100;
}
else
{
Console.WriteLine("Test FAILED!");
return -1;
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<!-- Internal.Console is not in the CoreLib reference assemblies. ICastable is CoreCLR-only -->
<ReferenceSystemPrivateCoreLib>true</ReferenceSystemPrivateCoreLib>
<CLRTestTargetUnsupported Condition="'$(TargetOS)' == 'Browser' Or '$(TargetOS)' == 'Android' Or '$(TargetOS)' == 'iOS' Or '$(TargetOS)' == 'iOSSimulator'">true</CLRTestTargetUnsupported>
</PropertyGroup>
<ItemGroup>
<Compile Include="Castable.cs" />
......
......@@ -9,6 +9,5 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="ICustomMarshaler.cs" />
<Compile Include="..\..\..\Common\XunitBase.cs" />
</ItemGroup>
</Project>
......@@ -10,6 +10,5 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="ICustomMarshaler.cs" />
<Compile Include="..\..\..\Common\XunitBase.cs" />
</ItemGroup>
</Project>
......@@ -10,26 +10,8 @@ public class DecimalTest
private const int StartingIntValue = 42;
private const int NewIntValue = 18;
public static int Main()
{
try
{
RunDecimalTests();
RunLPDecimalTests();
if (OperatingSystem.IsWindows())
{
RunCurrencyTests();
}
}
catch (System.Exception ex)
{
Console.WriteLine(ex.ToString());
return 101;
}
return 100;
}
private static void RunDecimalTests()
[Fact]
public static void RunDecimalTests()
{
Assert.Equal((decimal)StartingIntValue, DecimalTestNative.CreateDecimalFromInt(StartingIntValue));
......@@ -56,7 +38,8 @@ private static void RunDecimalTests()
DecimalTestNative.PassThroughDecimalToCallback((decimal)NewIntValue, d => Assert.Equal((decimal)NewIntValue, d));
}
private static void RunLPDecimalTests()
[Fact]
public static void RunLPDecimalTests()
{
Assert.Equal((decimal)StartingIntValue, DecimalTestNative.CreateLPDecimalFromInt(StartingIntValue));
......@@ -72,7 +55,9 @@ private static void RunLPDecimalTests()
DecimalTestNative.PassThroughLPDecimalToCallback((decimal)NewIntValue, d => Assert.Equal((decimal)NewIntValue, d));
}
private static void RunCurrencyTests()
[Fact]
[PlatformSpecific(TestPlatforms.Windows)]
public static void RunCurrencyTests()
{
Assert.Throws<MarshalDirectiveException>(() => DecimalTestNative.CreateCurrencyFromInt(StartingIntValue));
......
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
</PropertyGroup>
<ItemGroup>
<Compile Include="*.cs" />
</ItemGroup>
......
......@@ -11,23 +11,8 @@ public class Vector2_3_4Test
private const int StartingIntValue = 42;
private const int NewIntValue = 18;
public static int Main()
{
try
{
RunVector2Tests();
RunVector3Tests();
RunVector4Tests();
}
catch (System.Exception ex)
{
Console.WriteLine(ex);
return 101;
}
return 100;
}
private static void RunVector2Tests()
[Fact]
public static void RunVector2Tests()
{
Console.WriteLine($"Running {nameof(RunVector2Tests)}... ");
float X = StartingIntValue;
......@@ -69,7 +54,8 @@ private static void RunVector2Tests()
}));
}
private static void RunVector3Tests()
[Fact]
public static void RunVector3Tests()
{
Console.WriteLine($"Running {nameof(RunVector3Tests)}... ");
float X = StartingIntValue;
......@@ -111,7 +97,8 @@ private static void RunVector3Tests()
}));
}
private static void RunVector4Tests()
[Fact]
public static void RunVector4Tests()
{
Console.WriteLine($"Running {nameof(RunVector4Tests)}... ");
float X = StartingIntValue;
......
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
</PropertyGroup>
<ItemGroup>
<Compile Include="*.cs" />
</ItemGroup>
......
......@@ -3,11 +3,21 @@
.assembly extern legacy library mscorlib {}
.assembly autoinit{}
.assembly AutoInit {}
.assembly extern xunit.core
{
.publickeytoken = (
8d 05 b1 bb 7a 6f db 6c
)
.ver 2:4:2:0
}
.class public auto_init {
.method public static int32 main(class [mscorlib]System.String[]) {
.method public static int32 main() {
.custom instance void [xunit.core]Xunit.FactAttribute::.ctor() = (
01 00 00 00
)
.zeroinit
.entrypoint
.locals (int32,int32,int32,int32,int32,int32,int32,int32,int32,int32,int32,int32,int32,int32,int32,int32)
......
......@@ -3,10 +3,9 @@
using System;
using System.Runtime.CompilerServices;
using Xunit;
// This test represent deep execution tree that could case C stack overflow
// This test represent deep execution tree that could case C stack overflow
// in recursive tree walkers. It should work if the compiler spills deep tree periodically or
// recursive walkers are replaced with non-recursive versions.
class GitHub_10215
......@@ -461,6 +460,10 @@ private static int CalcBigExpressionWithoutStores()
}
// Use the [Fact] attribute directly on Main like an IL test since we can't run the generator on this project.
// The above expression creates a deep enough syntax tree that running a tree traversal of the syntax causes a stack overflow.
// As a result, running any generator on this project causes the compilation to crash.
[Fact]
public static int Main()
{
if (CalcBigExpressionWithoutStores() == 100)
......
......@@ -2,6 +2,8 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<CLRTestPriority>1</CLRTestPriority>
<!-- Explicitly don't reference the generator here as the source here blows the stack whenever a SyntaxVisitor traverses it (which happens as part of the generator execution). -->
<ReferenceXUnitWrapperGenerator>false</ReferenceXUnitWrapperGenerator>
</PropertyGroup>
<PropertyGroup>
<DebugType />
......
......@@ -25,17 +25,14 @@
<ItemGroup>
<_SpmiTestProjects Include="..\Performance\CodeQuality\Bytemark\Bytemark.csproj" />
<_SpmiTestProjects Include="..\Methodical\fp\exgen\10w5d_cs_do.csproj" />
<_SpmiTestProjects Update="@(_SpmiTestProjects)">
<Properties>OutputPath=$(OutputPath)\%(FileName)</Properties>
</_SpmiTestProjects>
<ProjectReference Include="@(_SpmiTestProjects)">
<Targets>Build</Targets>
<OutputItemType>_SpmiTest</OutputItemType>
<TargetPath>%(FileName)</TargetPath>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<!-- This target builds the executables and test running scripts for the _SpmiTestProjects
to the output directory of the current project. -->
<Target Name="_BuildSpmiTestProjects" BeforeTargets="Build">
<MSBuild Projects="@(_SpmiTestProjects)" />
</Target>
<!-- _SpmiTestNamesFile contains the file names of the _SpmiTestProjects. -->
<PropertyGroup>
<_SpmiTestNamesFile>$(IntermediateOutputPath)\SpmiTestNames.txt</_SpmiTestNamesFile>
......@@ -55,4 +52,14 @@
<LogicalName>SpmiTestNames</LogicalName>
</EmbeddedResource>
</ItemGroup>
<Target Name="_CopySpmiTestsToOutput" DependsOnTargets="ResolveProjectReferences" BeforeTargets="AssignTargetPaths">
<Copy SourceFiles="@(_SpmiTest)" DestinationFolder="$([System.IO.Path]::GetDirectoryName('$(OutputPath)'))/$([System.IO.Path]::GetFileName('%(FileName)'))" SkipUnchangedFiles="True" />
</Target>
<!-- This target builds the executables and test running scripts for the _SpmiTestProjects
to the output directory of the current project. -->
<Target Name="_BuildSpmiTestProjectScripts" BeforeTargets="CreateExecuteScript">
<MSBuild Projects="@(_SpmiTestProjects)" Targets="CreateExecuteScript" Properties="OutputPath=$(OutputPath)\%(FileName)" />
</Target>
</Project>
<Project>
<!-- This target builds the executables and test running scripts for the _SpmiTestProjects
to the output directory of the current project. -->
<Target Name="_BuildSpmiTestProjectScripts" BeforeTargets="CreateExecuteScript">
<MSBuild Projects="@(_SpmiTestProjects)" Targets="CreateExecuteScript" />
</Target>
</Project>
......@@ -25,6 +25,8 @@
<RestoreProjects Include="Common\test_dependencies_fs\test_dependencies.fsproj" />
<RestoreProjects Include="Common\test_dependencies\test_dependencies.csproj" />
<RestoreProjects Include="Common\CoreCLRTestLibrary\CoreCLRTestLibrary.csproj" />
<RestoreProjects Include="Common\XUnitWrapperGenerator\XUnitWrapperGenerator.csproj" />
<RestoreProjects Include="Common\XUnitWrapperLibrary\XUnitWrapperLibrary.csproj" />
<RestoreProjects Include="Common\external\external.csproj" />
<RestoreProjects Include="Common\ilasm\ilasm.ilproj" />
</ItemGroup>
......
......@@ -9,7 +9,7 @@
namespace IlasmPortablePdbTests
{
public class IlasmPortablePdbTester : XunitBase
public class IlasmPortablePdbTester : IDisposable
{
private const string CoreRoot = "CORE_ROOT";
private const string IlasmFileName = "ilasm";
......@@ -36,7 +36,7 @@ public void TestPortablePdbDebugDirectory(string ilSource)
{
var ilasm = IlasmPortablePdbTesterCommon.GetIlasmFullPath(CoreRootVar, IlasmFile);
IlasmPortablePdbTesterCommon.Assemble(ilasm, ilSource, TestDir, out string dll, out string pdb);
using (var peStream = new FileStream(dll, FileMode.Open, FileAccess.Read))
{
using (var peReader = new PEReader(peStream))
......@@ -102,7 +102,7 @@ public void TestPortablePdbDocuments()
var portablePdbMdReader = pdbReaderProvider.GetMetadataReader();
Assert.NotNull(portablePdbMdReader);
Assert.Equal(expected.Count, portablePdbMdReader.Documents.Count);
int i = 0;
foreach (var documentHandle in portablePdbMdReader.Documents)
{
......@@ -246,7 +246,7 @@ public void TestPortablePdbLocalScope(string ilSource)
Assert.Equal(expected[i].Length, localScope.Length);
var variableHandles = localScope.GetLocalVariables();
Assert.Equal(expected[i].Variables.Count, variableHandles.Count);
int j = 0;
foreach (var variableHandle in localScope.GetLocalVariables())
{
......@@ -255,7 +255,7 @@ public void TestPortablePdbLocalScope(string ilSource)
var variableName = portablePdbMdReader.GetString(variable.Name);
Assert.Equal(expected[i].Variables[j].Name, variableName);
Assert.Equal(expected[i].Variables[j].Index, variable.Index);
Assert.Equal(expected[i].Variables[j].IsDebuggerHidden,
Assert.Equal(expected[i].Variables[j].IsDebuggerHidden,
variable.Attributes == LocalVariableAttributes.DebuggerHidden);
j++;
}
......@@ -268,10 +268,7 @@ public void TestPortablePdbLocalScope(string ilSource)
}
}
}
public static int Main(string[] args)
{
return new IlasmPortablePdbTester().RunTests();
}
public void Dispose() {}
}
}
......@@ -6,7 +6,6 @@
<Compile Include="IlasmPortablePdbTester.cs" />
<Compile Include="IlasmPortablePdbTesterCommon.cs" />
<Compile Include="IlasmPortablePdbTesterTypes.cs" />
<Compile Include="..\..\Common\XunitBase.cs" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Resources\**" />
......
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata;
......@@ -16,7 +17,7 @@ public class ILMethodTester
[Theory(DisplayName = "")]
[MemberData(nameof(TestDataLoader.GetMethodsWithValidIL), MemberType = typeof(TestDataLoader))]
[Trait("", "Valid IL Tests")]
void TestMethodsWithValidIL(ValidILTestCase validIL)
public static void TestMethodsWithValidIL(ValidILTestCase validIL)
{
var results = Verify(validIL);
Assert.Empty(results);
......@@ -25,7 +26,7 @@ void TestMethodsWithValidIL(ValidILTestCase validIL)
[Theory(DisplayName = "")]
[MemberData(nameof(TestDataLoader.GetMethodsWithInvalidIL), MemberType = typeof(TestDataLoader))]
[Trait("", "Invalid IL Tests")]
void TestMethodsWithInvalidIL(InvalidILTestCase invalidIL)
public static void TestMethodsWithInvalidIL(InvalidILTestCase invalidIL)
{
IEnumerable<VerificationResult> results = null;
......
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata;
......@@ -11,12 +12,12 @@
namespace ILVerification.Tests
{
public class ILTypeVerificationTester : XunitBase
public class ILTypeVerificationTester
{
[Theory(DisplayName = "")]
[MemberData(nameof(TestDataLoader.GetTypesWithValidType), MemberType = typeof(TestDataLoader))]
[Trait("", "Valid type implementation tests")]
private void TestValidTypes(ValidTypeTestCase validType)
public static void TestValidTypes(ValidTypeTestCase validType)
{
IEnumerable<VerificationResult> results = Verify(validType);
Assert.Empty(results);
......@@ -25,7 +26,7 @@ private void TestValidTypes(ValidTypeTestCase validType)
[Theory(DisplayName = "")]
[MemberData(nameof(TestDataLoader.GetTypesWithInvalidType), MemberType = typeof(TestDataLoader))]
[Trait("", "Invalid type implementation tests")]
private void TestInvalidTypes(InvalidTypeTestCase invalidType)
public static void TestInvalidTypes(InvalidTypeTestCase invalidType)
{
IEnumerable<VerificationResult> results = null;
......@@ -65,10 +66,5 @@ private static IEnumerable<VerificationResult> Verify(TestCase testCase)
});
return verifier.Verify(module.PEReader, typeHandle);
}
public static int Main(string[] args)
{
return new ILTypeVerificationTester().RunTests();
}
}
}
......@@ -12,13 +12,11 @@
<Compile Include="ILMethodTester.cs" />
<Compile Include="ILTypeVerificationTester.cs" />
<Compile Include="TestDataLoader.cs" />
<Compile Include="..\Common\XunitBase.cs" />
</ItemGroup>
<Import Project="..\..\coreclr\tools\ILVerification\ILVerification.projitems" />
<ItemGroup>
<PackageReference Include="xunit" Version="$(XUnitVersion)" />
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
</ItemGroup>
......
......@@ -289,7 +289,7 @@ protected override PEReader ResolveCore(string simpleName)
}
}
abstract class TestCase : IXunitSerializable
public abstract class TestCase : IXunitSerializable
{
public string TestName { get; set; }
public string TypeName { get; set; }
......@@ -324,12 +324,12 @@ public override string ToString()
/// <summary>
/// Describes a test case with a method that contains valid IL
/// </summary>
class ValidILTestCase : TestCase { }
public class ValidILTestCase : TestCase { }
/// <summary>
/// Describes a test case with a method that contains invalid IL with the expected VerifierErrors
/// </summary>
class InvalidILTestCase : TestCase
public class InvalidILTestCase : TestCase
{
public List<VerifierError> ExpectedVerifierErrors { get; set; }
......@@ -369,9 +369,9 @@ private static string GetErrorsString(List<VerifierError> errors)
}
}
class ValidTypeTestCase : TestCase { }
public class ValidTypeTestCase : TestCase { }
class InvalidTypeTestCase : TestCase
public class InvalidTypeTestCase : TestCase
{
public List<VerifierError> ExpectedVerifierErrors { get; set; }
......
......@@ -6,13 +6,13 @@
namespace R2RDumpTests
{
public class R2RDumpTester : XunitBase
public class R2RDumpTester
{
private const string CoreRoot = "CORE_ROOT";
private const string R2RDumpRelativePath = "R2RDump";
private const string R2RDumpFile = "R2RDump.dll";
private const string CoreRunFileName = "corerun";
public static string FindExePath(string exe)
{
if (OperatingSystem.IsWindows())
......@@ -37,7 +37,8 @@ public static string FindExePath(string exe)
}
[Fact]
public void DumpCoreLib()
[SkipOnMono("Ready-To-Run is a CoreCLR-only feature", TestPlatforms.Any)]
public static void DumpCoreLib()
{
string CoreRootVar = Environment.GetEnvironmentVariable(CoreRoot);
bool IsUnix = !OperatingSystem.IsWindows();
......@@ -73,10 +74,5 @@ public void DumpCoreLib()
Assert.True(!failed);
}
}
public static int Main(string[] args)
{
return new R2RDumpTester().RunTests();
}
}
}
\ No newline at end of file
}
......@@ -9,14 +9,10 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="R2RDumpTester.cs" />
<Compile Include="..\..\..\Common\XunitBase.cs" />
</ItemGroup>
<ItemGroup>
<Compile Remove="Resources\**" />
<EmbeddedResource Remove="Resources\**" />
<None Remove="Resources\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="xunit" Version="$(XUnitVersion)" />
</ItemGroup>
</Project>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册