From 0e7ff1e6ec19534df8d98710e1ab4228a3cb559a Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Mon, 16 Sep 2019 13:33:09 -0700 Subject: [PATCH] Refactor xUnit extensibility Adds our own hook for before/after logic that's more usable, called `ITestMethodLifecycle`. This provides access to a context object including the information about the test and the output helper. This can be implemented by attributes or by the class itself. The goal (and result) of this, is that we have a single *test executor* extensibility point that provides all of the features we need. We should use this everywhere we need features xUnit doesn't have. Adding a new extensibility point (`ITestMethodLifecycle`) allows us to do this without turning all of these features into a giant monolith. --- Also updated our existing extensibility to use this new hook. I did as much cleanup as a could to remove duplication from logging and keep it loosly coupled. I didn't want to tease this apart completely because the scope of this PR is already pretty large. --- .../Logging.Testing/src/AssemblyTestLog.cs | 55 ++------- .../src/CollectDumpAttribute.cs | 23 +++- .../src/{Xunit => }/LogLevelAttribute.cs | 0 .../src/LoggedTest/ILoggedTest.cs | 3 +- .../src/LoggedTest/LoggedTest.cs | 5 +- .../src/LoggedTest/LoggedTestBase.cs | 41 +++++-- .../Logging.Testing/src/RepeatContext.cs | 12 -- .../src/ShortClassNameAttribute.cs | 12 -- .../src/TestFrameworkFileLoggerAttribute.cs | 13 +- .../Xunit/LoggedConditionalFactDiscoverer.cs | 28 ----- .../LoggedConditionalTheoryDiscoverer.cs | 55 --------- .../src/Xunit/LoggedFactDiscoverer.cs | 18 --- .../src/Xunit/LoggedTestAssemblyRunner.cs | 31 ----- .../src/Xunit/LoggedTestCase.cs | 37 ------ .../src/Xunit/LoggedTestCaseRunner.cs | 42 ------- .../src/Xunit/LoggedTestClassRunner.cs | 36 ------ .../src/Xunit/LoggedTestCollectionRunner.cs | 33 ----- .../src/Xunit/LoggedTestFramework.cs | 26 ---- .../Xunit/LoggedTestFrameworkDiscoverer.cs | 80 ------------ .../src/Xunit/LoggedTestFrameworkExecutor.cs | 26 ---- .../src/Xunit/LoggedTestInvoker.cs | 80 ------------ .../src/Xunit/LoggedTestMethodRunner.cs | 36 ------ .../src/Xunit/LoggedTestRunner.cs | 114 ------------------ .../src/Xunit/LoggedTheoryDiscoverer.cs | 29 ----- .../src/Xunit/LoggedTheoryTestCase.cs | 36 ------ .../src/Xunit/LoggedTheoryTestCaseRunner.cs | 41 ------- .../src/Xunit/RepeatAttribute.cs | 28 ----- ...Microsoft.Extensions.Logging.Testing.props | 4 +- .../test/AssemblyTestLogTests.cs | 8 +- .../test/LoggedTestXunitRepeatTests.cs | 43 ------- .../test/LoggedTestXunitTests.cs | 16 +-- .../test/Properties/AssemblyInfo.cs | 1 - 32 files changed, 76 insertions(+), 936 deletions(-) rename src/Logging/Logging.Testing/src/{Xunit => }/LogLevelAttribute.cs (100%) delete mode 100644 src/Logging/Logging.Testing/src/RepeatContext.cs delete mode 100644 src/Logging/Logging.Testing/src/ShortClassNameAttribute.cs delete mode 100644 src/Logging/Logging.Testing/src/Xunit/LoggedConditionalFactDiscoverer.cs delete mode 100644 src/Logging/Logging.Testing/src/Xunit/LoggedConditionalTheoryDiscoverer.cs delete mode 100644 src/Logging/Logging.Testing/src/Xunit/LoggedFactDiscoverer.cs delete mode 100644 src/Logging/Logging.Testing/src/Xunit/LoggedTestAssemblyRunner.cs delete mode 100644 src/Logging/Logging.Testing/src/Xunit/LoggedTestCase.cs delete mode 100644 src/Logging/Logging.Testing/src/Xunit/LoggedTestCaseRunner.cs delete mode 100644 src/Logging/Logging.Testing/src/Xunit/LoggedTestClassRunner.cs delete mode 100644 src/Logging/Logging.Testing/src/Xunit/LoggedTestCollectionRunner.cs delete mode 100644 src/Logging/Logging.Testing/src/Xunit/LoggedTestFramework.cs delete mode 100644 src/Logging/Logging.Testing/src/Xunit/LoggedTestFrameworkDiscoverer.cs delete mode 100644 src/Logging/Logging.Testing/src/Xunit/LoggedTestFrameworkExecutor.cs delete mode 100644 src/Logging/Logging.Testing/src/Xunit/LoggedTestInvoker.cs delete mode 100644 src/Logging/Logging.Testing/src/Xunit/LoggedTestMethodRunner.cs delete mode 100644 src/Logging/Logging.Testing/src/Xunit/LoggedTestRunner.cs delete mode 100644 src/Logging/Logging.Testing/src/Xunit/LoggedTheoryDiscoverer.cs delete mode 100644 src/Logging/Logging.Testing/src/Xunit/LoggedTheoryTestCase.cs delete mode 100644 src/Logging/Logging.Testing/src/Xunit/LoggedTheoryTestCaseRunner.cs delete mode 100644 src/Logging/Logging.Testing/src/Xunit/RepeatAttribute.cs delete mode 100644 src/Logging/Logging.Testing/test/LoggedTestXunitRepeatTests.cs diff --git a/src/Logging/Logging.Testing/src/AssemblyTestLog.cs b/src/Logging/Logging.Testing/src/AssemblyTestLog.cs index e84df52554..3c598b67d5 100644 --- a/src/Logging/Logging.Testing/src/AssemblyTestLog.cs +++ b/src/Logging/Logging.Testing/src/AssemblyTestLog.cs @@ -9,6 +9,7 @@ using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; +using Microsoft.AspNetCore.Testing; using Microsoft.Extensions.DependencyInjection; using Serilog; using Serilog.Core; @@ -23,14 +24,6 @@ namespace Microsoft.Extensions.Logging.Testing private static readonly string MaxPathLengthEnvironmentVariableName = "ASPNETCORE_TEST_LOG_MAXPATH"; private static readonly string LogFileExtension = ".log"; private static readonly int MaxPathLength = GetMaxPathLength(); - private static char[] InvalidFileChars = new char[] - { - '\"', '<', '>', '|', '\0', - (char)1, (char)2, (char)3, (char)4, (char)5, (char)6, (char)7, (char)8, (char)9, (char)10, - (char)11, (char)12, (char)13, (char)14, (char)15, (char)16, (char)17, (char)18, (char)19, (char)20, - (char)21, (char)22, (char)23, (char)24, (char)25, (char)26, (char)27, (char)28, (char)29, (char)30, - (char)31, ':', '*', '?', '\\', '/', ' ', (char)127 - }; private static readonly object _lock = new object(); private static readonly Dictionary _logs = new Dictionary(); @@ -113,8 +106,8 @@ namespace Microsoft.Extensions.Logging.Testing SerilogLoggerProvider serilogLoggerProvider = null; if (!string.IsNullOrEmpty(_baseDirectory)) { - logOutputDirectory = Path.Combine(GetAssemblyBaseDirectory(_baseDirectory, _assembly), className); - testName = RemoveIllegalFileChars(testName); + logOutputDirectory = Path.Combine(_baseDirectory, className); + testName = TestFileOutputContext.RemoveIllegalFileChars(testName); if (logOutputDirectory.Length + testName.Length + LogFileExtension.Length >= MaxPathLength) { @@ -184,10 +177,10 @@ namespace Microsoft.Extensions.Logging.Testing { var logStart = DateTimeOffset.UtcNow; SerilogLoggerProvider serilogLoggerProvider = null; - var globalLogDirectory = GetAssemblyBaseDirectory(baseDirectory, assembly); - if (!string.IsNullOrEmpty(globalLogDirectory)) + if (!string.IsNullOrEmpty(baseDirectory)) { - var globalLogFileName = Path.Combine(globalLogDirectory, "global.log"); + baseDirectory = TestFileOutputContext.GetAssemblyBaseDirectory(assembly, baseDirectory); + var globalLogFileName = Path.Combine(baseDirectory, "global.log"); serilogLoggerProvider = ConfigureFileLogging(globalLogFileName, logStart); } @@ -222,31 +215,26 @@ namespace Microsoft.Extensions.Logging.Testing { if (!_logs.TryGetValue(assembly, out var log)) { - var baseDirectory = GetFileLoggerAttribute(assembly).BaseDirectory; + var baseDirectory = TestFileOutputContext.GetOutputDirectory(assembly); log = Create(assembly, baseDirectory); _logs[assembly] = log; - // Try to clear previous logs - var assemblyBaseDirectory = GetAssemblyBaseDirectory(baseDirectory, assembly); - if (Directory.Exists(assemblyBaseDirectory)) + // Try to clear previous logs, continue if it fails. + var assemblyBaseDirectory = TestFileOutputContext.GetAssemblyBaseDirectory(assembly); + if (!string.IsNullOrEmpty(assemblyBaseDirectory)) { try { Directory.Delete(assemblyBaseDirectory, recursive: true); } - catch {} + catch { } } } return log; } } - private static string GetAssemblyBaseDirectory(string baseDirectory, Assembly assembly) - => string.IsNullOrEmpty(baseDirectory) - ? string.Empty - : Path.Combine(baseDirectory, assembly.GetName().Name, GetFileLoggerAttribute(assembly).TFM); - private static TestFrameworkFileLoggerAttribute GetFileLoggerAttribute(Assembly assembly) => assembly.GetCustomAttribute() ?? throw new InvalidOperationException($"No {nameof(TestFrameworkFileLoggerAttribute)} found on the assembly {assembly.GetName().Name}. " @@ -275,27 +263,6 @@ namespace Microsoft.Extensions.Logging.Testing return new SerilogLoggerProvider(serilogger, dispose: true); } - private static string RemoveIllegalFileChars(string s) - { - var sb = new StringBuilder(); - - foreach (var c in s) - { - if (InvalidFileChars.Contains(c)) - { - if (sb.Length > 0 && sb[sb.Length - 1] != '_') - { - sb.Append('_'); - } - } - else - { - sb.Append(c); - } - } - return sb.ToString(); - } - public void Dispose() { (_serviceProvider as IDisposable)?.Dispose(); diff --git a/src/Logging/Logging.Testing/src/CollectDumpAttribute.cs b/src/Logging/Logging.Testing/src/CollectDumpAttribute.cs index 8a6aa84bac..012a5c8fa1 100644 --- a/src/Logging/Logging.Testing/src/CollectDumpAttribute.cs +++ b/src/Logging/Logging.Testing/src/CollectDumpAttribute.cs @@ -2,6 +2,11 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Diagnostics; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Testing; namespace Microsoft.Extensions.Logging.Testing { @@ -12,7 +17,23 @@ namespace Microsoft.Extensions.Logging.Testing /// This currently only works in Windows environments /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] - public class CollectDumpAttribute : Attribute + public class CollectDumpAttribute : Attribute, ITestMethodLifecycle { + public Task OnTestStartAsync(TestContext context, CancellationToken cancellationToken) + { + return Task.CompletedTask; + } + + public Task OnTestEndAsync(TestContext context, Exception exception, CancellationToken cancellationToken) + { + if (exception != null) + { + var path = Path.Combine(context.FileOutput.TestClassOutputDirectory, context.FileOutput.GetUniqueFileName(context.FileOutput.TestName, ".dmp")); + var process = Process.GetCurrentProcess(); + DumpCollector.Collect(process, path); + } + + return Task.CompletedTask; + } } } diff --git a/src/Logging/Logging.Testing/src/Xunit/LogLevelAttribute.cs b/src/Logging/Logging.Testing/src/LogLevelAttribute.cs similarity index 100% rename from src/Logging/Logging.Testing/src/Xunit/LogLevelAttribute.cs rename to src/Logging/Logging.Testing/src/LogLevelAttribute.cs diff --git a/src/Logging/Logging.Testing/src/LoggedTest/ILoggedTest.cs b/src/Logging/Logging.Testing/src/LoggedTest/ILoggedTest.cs index a563cbdaf9..a906ae84a2 100644 --- a/src/Logging/Logging.Testing/src/LoggedTest/ILoggedTest.cs +++ b/src/Logging/Logging.Testing/src/LoggedTest/ILoggedTest.cs @@ -3,6 +3,7 @@ using System; using System.Reflection; +using Microsoft.AspNetCore.Testing; using Xunit.Abstractions; namespace Microsoft.Extensions.Logging.Testing @@ -18,6 +19,6 @@ namespace Microsoft.Extensions.Logging.Testing // For back compat IDisposable StartLog(out ILoggerFactory loggerFactory, LogLevel minLogLevel, string testName); - void Initialize(MethodInfo methodInfo, object[] testMethodArguments, ITestOutputHelper testOutputHelper); + void Initialize(TestContext context, MethodInfo methodInfo, object[] testMethodArguments, ITestOutputHelper testOutputHelper); } } diff --git a/src/Logging/Logging.Testing/src/LoggedTest/LoggedTest.cs b/src/Logging/Logging.Testing/src/LoggedTest/LoggedTest.cs index 64a9adec06..d108ffb7e8 100644 --- a/src/Logging/Logging.Testing/src/LoggedTest/LoggedTest.cs +++ b/src/Logging/Logging.Testing/src/LoggedTest/LoggedTest.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Reflection; +using Microsoft.AspNetCore.Testing; using Xunit.Abstractions; namespace Microsoft.Extensions.Logging.Testing @@ -13,9 +14,9 @@ namespace Microsoft.Extensions.Logging.Testing public ITestSink TestSink { get; set; } - public override void Initialize(MethodInfo methodInfo, object[] testMethodArguments, ITestOutputHelper testOutputHelper) + public override void Initialize(TestContext context, MethodInfo methodInfo, object[] testMethodArguments, ITestOutputHelper testOutputHelper) { - base.Initialize(methodInfo, testMethodArguments, testOutputHelper); + base.Initialize(context, methodInfo, testMethodArguments, testOutputHelper); TestSink = new TestSink(); LoggerFactory.AddProvider(new TestLoggerProvider(TestSink)); diff --git a/src/Logging/Logging.Testing/src/LoggedTest/LoggedTestBase.cs b/src/Logging/Logging.Testing/src/LoggedTest/LoggedTestBase.cs index 94cdf82257..324b855319 100644 --- a/src/Logging/Logging.Testing/src/LoggedTest/LoggedTestBase.cs +++ b/src/Logging/Logging.Testing/src/LoggedTest/LoggedTestBase.cs @@ -6,12 +6,16 @@ using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Testing; using Microsoft.Extensions.DependencyInjection; +using Serilog; using Xunit.Abstractions; namespace Microsoft.Extensions.Logging.Testing { - public class LoggedTestBase : ILoggedTest + public class LoggedTestBase : ILoggedTest, ITestMethodLifecycle { private ExceptionDispatchInfo _initializationException; @@ -23,11 +27,11 @@ namespace Microsoft.Extensions.Logging.Testing TestOutputHelper = output; } + protected TestContext Context { get; private set; } + // Internal for testing internal string ResolvedTestClassName { get; set; } - internal RepeatContext RepeatContext { get; set; } - public string ResolvedLogOutputDirectory { get; set; } public string ResolvedTestMethodName { get; set; } @@ -49,7 +53,7 @@ namespace Microsoft.Extensions.Logging.Testing return AssemblyTestLog.ForAssembly(GetType().GetTypeInfo().Assembly).StartTestLog(TestOutputHelper, GetType().FullName, out loggerFactory, minLogLevel, testName); } - public virtual void Initialize(MethodInfo methodInfo, object[] testMethodArguments, ITestOutputHelper testOutputHelper) + public virtual void Initialize(TestContext context, MethodInfo methodInfo, object[] testMethodArguments, ITestOutputHelper testOutputHelper) { try { @@ -59,25 +63,22 @@ namespace Microsoft.Extensions.Logging.Testing var logLevelAttribute = methodInfo.GetCustomAttribute() ?? methodInfo.DeclaringType.GetCustomAttribute() ?? methodInfo.DeclaringType.Assembly.GetCustomAttribute(); - var testName = testMethodArguments.Aggregate(methodInfo.Name, (a, b) => $"{a}-{(b ?? "null")}"); - var useShortClassName = methodInfo.DeclaringType.GetCustomAttribute() - ?? methodInfo.DeclaringType.Assembly.GetCustomAttribute(); // internal for testing - ResolvedTestClassName = useShortClassName == null ? classType.FullName : classType.Name; + ResolvedTestClassName = context.FileOutput.TestClassName; _testLog = AssemblyTestLog .ForAssembly(classType.GetTypeInfo().Assembly) .StartTestLog( TestOutputHelper, - ResolvedTestClassName, + context.FileOutput.TestClassName, out var loggerFactory, logLevelAttribute?.LogLevel ?? LogLevel.Debug, out var resolvedTestName, - out var logOutputDirectory, - testName); + out var logDirectory, + context.FileOutput.TestName); - ResolvedLogOutputDirectory = logOutputDirectory; + ResolvedLogOutputDirectory = logDirectory; ResolvedTestMethodName = resolvedTestName; LoggerFactory = loggerFactory; @@ -91,7 +92,7 @@ namespace Microsoft.Extensions.Logging.Testing public virtual void Dispose() { - if(_testLog == null) + if (_testLog == null) { // It seems like sometimes the MSBuild goop that adds the test framework can end up in a bad state and not actually add it // Not sure yet why that happens but the exception isn't clear so I'm adding this error so we can detect it better. @@ -102,5 +103,19 @@ namespace Microsoft.Extensions.Logging.Testing _initializationException?.Throw(); _testLog.Dispose(); } + + Task ITestMethodLifecycle.OnTestStartAsync(TestContext context, CancellationToken cancellationToken) + { + + Context = context; + + Initialize(context, context.TestMethod, context.MethodArguments, context.Output); + return Task.CompletedTask; + } + + Task ITestMethodLifecycle.OnTestEndAsync(TestContext context, Exception exception, CancellationToken cancellationToken) + { + return Task.CompletedTask; + } } } diff --git a/src/Logging/Logging.Testing/src/RepeatContext.cs b/src/Logging/Logging.Testing/src/RepeatContext.cs deleted file mode 100644 index decc7a173c..0000000000 --- a/src/Logging/Logging.Testing/src/RepeatContext.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -namespace Microsoft.Extensions.Logging.Testing -{ - public class RepeatContext - { - internal int Limit { get; set; } - - internal int CurrentIteration { get; set; } - } -} diff --git a/src/Logging/Logging.Testing/src/ShortClassNameAttribute.cs b/src/Logging/Logging.Testing/src/ShortClassNameAttribute.cs deleted file mode 100644 index bd30718814..0000000000 --- a/src/Logging/Logging.Testing/src/ShortClassNameAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright(c) .NET Foundation.All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; - -namespace Microsoft.Extensions.Logging.Testing -{ - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = false)] - public class ShortClassNameAttribute : Attribute - { - } -} diff --git a/src/Logging/Logging.Testing/src/TestFrameworkFileLoggerAttribute.cs b/src/Logging/Logging.Testing/src/TestFrameworkFileLoggerAttribute.cs index 32d8f30584..025a5a9bd8 100644 --- a/src/Logging/Logging.Testing/src/TestFrameworkFileLoggerAttribute.cs +++ b/src/Logging/Logging.Testing/src/TestFrameworkFileLoggerAttribute.cs @@ -1,20 +1,17 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using Microsoft.AspNetCore.Testing; namespace Microsoft.Extensions.Logging.Testing { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)] - public class TestFrameworkFileLoggerAttribute : Attribute + public class TestFrameworkFileLoggerAttribute : TestOutputDirectoryAttribute { public TestFrameworkFileLoggerAttribute(string tfm, string baseDirectory = null) + : base(tfm, baseDirectory) { - TFM = tfm; - BaseDirectory = baseDirectory; } - - public string TFM { get; } - public string BaseDirectory { get; } } -} \ No newline at end of file +} diff --git a/src/Logging/Logging.Testing/src/Xunit/LoggedConditionalFactDiscoverer.cs b/src/Logging/Logging.Testing/src/Xunit/LoggedConditionalFactDiscoverer.cs deleted file mode 100644 index 4d61c9592d..0000000000 --- a/src/Logging/Logging.Testing/src/Xunit/LoggedConditionalFactDiscoverer.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNetCore.Testing; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.Extensions.Logging.Testing -{ - public class LoggedConditionalFactDiscoverer : LoggedFactDiscoverer - { - private readonly IMessageSink _diagnosticMessageSink; - - public LoggedConditionalFactDiscoverer(IMessageSink diagnosticMessageSink) : base(diagnosticMessageSink) - { - _diagnosticMessageSink = diagnosticMessageSink; - } - - protected override IXunitTestCase CreateTestCase(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo factAttribute) - { - var skipReason = testMethod.EvaluateSkipConditions(); - return skipReason != null - ? new SkippedTestCase(skipReason, _diagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), TestMethodDisplayOptions.None, testMethod) - : base.CreateTestCase(discoveryOptions, testMethod, factAttribute); - } - - } -} diff --git a/src/Logging/Logging.Testing/src/Xunit/LoggedConditionalTheoryDiscoverer.cs b/src/Logging/Logging.Testing/src/Xunit/LoggedConditionalTheoryDiscoverer.cs deleted file mode 100644 index bce28051a6..0000000000 --- a/src/Logging/Logging.Testing/src/Xunit/LoggedConditionalTheoryDiscoverer.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using Microsoft.AspNetCore.Testing; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.Extensions.Logging.Testing -{ - public class LoggedConditionalTheoryDiscoverer : LoggedTheoryDiscoverer - { - public LoggedConditionalTheoryDiscoverer(IMessageSink diagnosticMessageSink) - : base(diagnosticMessageSink) - { - } - - protected override IEnumerable CreateTestCasesForTheory( - ITestFrameworkDiscoveryOptions discoveryOptions, - ITestMethod testMethod, - IAttributeInfo theoryAttribute) - { - var skipReason = testMethod.EvaluateSkipConditions(); - return skipReason != null - ? new[] { new SkippedTestCase(skipReason, DiagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), TestMethodDisplayOptions.None, testMethod) } - : base.CreateTestCasesForTheory(discoveryOptions, testMethod, theoryAttribute); - } - - protected override IEnumerable CreateTestCasesForDataRow( - ITestFrameworkDiscoveryOptions discoveryOptions, - ITestMethod testMethod, IAttributeInfo theoryAttribute, - object[] dataRow) - { - var skipReason = testMethod.EvaluateSkipConditions(); - if (skipReason == null && dataRow?.Length > 0) - { - var obj = dataRow[0]; - if (obj != null) - { - var type = obj.GetType(); - var property = type.GetProperty("Skip"); - if (property != null && property.PropertyType.Equals(typeof(string))) - { - skipReason = property.GetValue(obj) as string; - } - } - } - - return skipReason != null - ? base.CreateTestCasesForSkippedDataRow(discoveryOptions, testMethod, theoryAttribute, dataRow, skipReason) - : base.CreateTestCasesForDataRow(discoveryOptions, testMethod, theoryAttribute, dataRow); - } - - } -} diff --git a/src/Logging/Logging.Testing/src/Xunit/LoggedFactDiscoverer.cs b/src/Logging/Logging.Testing/src/Xunit/LoggedFactDiscoverer.cs deleted file mode 100644 index e2268d96cb..0000000000 --- a/src/Logging/Logging.Testing/src/Xunit/LoggedFactDiscoverer.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.Extensions.Logging.Testing -{ - public class LoggedFactDiscoverer : FactDiscoverer - { - public LoggedFactDiscoverer(IMessageSink diagnosticMessageSink) : base(diagnosticMessageSink) - { - } - - protected override IXunitTestCase CreateTestCase(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo factAttribute) - => new LoggedTestCase(DiagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), TestMethodDisplayOptions.None, testMethod); - } -} diff --git a/src/Logging/Logging.Testing/src/Xunit/LoggedTestAssemblyRunner.cs b/src/Logging/Logging.Testing/src/Xunit/LoggedTestAssemblyRunner.cs deleted file mode 100644 index 39dff8fce7..0000000000 --- a/src/Logging/Logging.Testing/src/Xunit/LoggedTestAssemblyRunner.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.Extensions.Logging.Testing -{ - public class LoggedTestAssemblyRunner : XunitTestAssemblyRunner - { - public LoggedTestAssemblyRunner( - ITestAssembly testAssembly, - IEnumerable testCases, - IMessageSink diagnosticMessageSink, - IMessageSink executionMessageSink, - ITestFrameworkExecutionOptions executionOptions) - : base(testAssembly, testCases, diagnosticMessageSink, executionMessageSink, executionOptions) - { - } - - protected override Task RunTestCollectionAsync( - IMessageBus messageBus, - ITestCollection testCollection, - IEnumerable testCases, - CancellationTokenSource cancellationTokenSource) - => new LoggedTestCollectionRunner(testCollection, testCases, DiagnosticMessageSink, messageBus, TestCaseOrderer, new ExceptionAggregator(Aggregator), cancellationTokenSource).RunAsync(); - } -} diff --git a/src/Logging/Logging.Testing/src/Xunit/LoggedTestCase.cs b/src/Logging/Logging.Testing/src/Xunit/LoggedTestCase.cs deleted file mode 100644 index c43180df89..0000000000 --- a/src/Logging/Logging.Testing/src/Xunit/LoggedTestCase.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Threading; -using System.Threading.Tasks; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.Extensions.Logging.Testing -{ - public class LoggedTestCase : XunitTestCase - { - [Obsolete("Called by the de-serializer; should only be called by deriving classes for de-serialization purposes")] - public LoggedTestCase() : base() - { - } - - public LoggedTestCase( - IMessageSink diagnosticMessageSink, - TestMethodDisplay defaultMethodDisplay, - TestMethodDisplayOptions defaultMethodDisplayOptions, - ITestMethod testMethod, - object[] testMethodArguments = null) - : base(diagnosticMessageSink, defaultMethodDisplay, defaultMethodDisplayOptions, testMethod, testMethodArguments) - { - } - - public override Task RunAsync( - IMessageSink diagnosticMessageSink, - IMessageBus messageBus, - object[] constructorArguments, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource) - => new LoggedTestCaseRunner(this, DisplayName, SkipReason, constructorArguments, TestMethodArguments, messageBus, aggregator, cancellationTokenSource).RunAsync(); - } -} diff --git a/src/Logging/Logging.Testing/src/Xunit/LoggedTestCaseRunner.cs b/src/Logging/Logging.Testing/src/Xunit/LoggedTestCaseRunner.cs deleted file mode 100644 index 20cde6144e..0000000000 --- a/src/Logging/Logging.Testing/src/Xunit/LoggedTestCaseRunner.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Threading; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.Extensions.Logging.Testing -{ - public class LoggedTestCaseRunner : XunitTestCaseRunner - { - public LoggedTestCaseRunner( - IXunitTestCase testCase, - string displayName, - string skipReason, - object[] constructorArguments, - object[] testMethodArguments, - IMessageBus messageBus, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource) - : base(testCase, displayName, skipReason, constructorArguments, testMethodArguments, messageBus, aggregator, cancellationTokenSource) - { - } - - protected override XunitTestRunner CreateTestRunner( - ITest test, - IMessageBus messageBus, - Type testClass, - object[] constructorArguments, - MethodInfo testMethod, - object[] testMethodArguments, - string skipReason, - IReadOnlyList beforeAfterAttributes, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource) - => new LoggedTestRunner(test, messageBus, testClass, constructorArguments, testMethod, testMethodArguments, - skipReason, beforeAfterAttributes, new ExceptionAggregator(aggregator), cancellationTokenSource); - } -} diff --git a/src/Logging/Logging.Testing/src/Xunit/LoggedTestClassRunner.cs b/src/Logging/Logging.Testing/src/Xunit/LoggedTestClassRunner.cs deleted file mode 100644 index e7c30264e6..0000000000 --- a/src/Logging/Logging.Testing/src/Xunit/LoggedTestClassRunner.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.Extensions.Logging.Testing -{ - public class LoggedTestClassRunner : XunitTestClassRunner - { - public LoggedTestClassRunner( - ITestClass testClass, - IReflectionTypeInfo @class, - IEnumerable testCases, - IMessageSink diagnosticMessageSink, - IMessageBus messageBus, - ITestCaseOrderer testCaseOrderer, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource, - IDictionary collectionFixtureMappings) - : base(testClass, @class, testCases, diagnosticMessageSink, messageBus, testCaseOrderer, aggregator, cancellationTokenSource, collectionFixtureMappings) - { - } - - protected override Task RunTestMethodAsync( - ITestMethod testMethod, - IReflectionMethodInfo method, - IEnumerable testCases, - object[] constructorArguments) - => new LoggedTestMethodRunner(testMethod, Class, method, testCases, DiagnosticMessageSink, MessageBus, new ExceptionAggregator(Aggregator), CancellationTokenSource, constructorArguments).RunAsync(); - } -} diff --git a/src/Logging/Logging.Testing/src/Xunit/LoggedTestCollectionRunner.cs b/src/Logging/Logging.Testing/src/Xunit/LoggedTestCollectionRunner.cs deleted file mode 100644 index c3713d4245..0000000000 --- a/src/Logging/Logging.Testing/src/Xunit/LoggedTestCollectionRunner.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.Extensions.Logging.Testing -{ - public class LoggedTestCollectionRunner : XunitTestCollectionRunner - { - private readonly IMessageSink _diagnosticMessageSink; - - public LoggedTestCollectionRunner( - ITestCollection testCollection, - IEnumerable testCases, - IMessageSink diagnosticMessageSink, - IMessageBus messageBus, - ITestCaseOrderer testCaseOrderer, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource) - : base(testCollection, testCases, diagnosticMessageSink, messageBus, testCaseOrderer, aggregator, cancellationTokenSource) - { - // Base class doesn't expose this, so capture it here. - _diagnosticMessageSink = diagnosticMessageSink; - } - - protected override Task RunTestClassAsync(ITestClass testClass, IReflectionTypeInfo @class, IEnumerable testCases) - => new LoggedTestClassRunner(testClass, @class, testCases, _diagnosticMessageSink, MessageBus, TestCaseOrderer, new ExceptionAggregator(Aggregator), CancellationTokenSource, CollectionFixtureMappings).RunAsync(); - } -} diff --git a/src/Logging/Logging.Testing/src/Xunit/LoggedTestFramework.cs b/src/Logging/Logging.Testing/src/Xunit/LoggedTestFramework.cs deleted file mode 100644 index dc5737d32b..0000000000 --- a/src/Logging/Logging.Testing/src/Xunit/LoggedTestFramework.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Reflection; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.Extensions.Logging.Testing -{ - public class LoggedTestFramework : XunitTestFramework - { - public LoggedTestFramework(IMessageSink messageSink) : base(messageSink) - { - } - - protected override ITestFrameworkDiscoverer CreateDiscoverer(IAssemblyInfo assemblyInfo) - { - return new LoggedTestFrameworkDiscoverer(assemblyInfo, SourceInformationProvider, DiagnosticMessageSink); - } - - protected override ITestFrameworkExecutor CreateExecutor(AssemblyName assemblyName) - { - return new LoggedTestFrameworkExecutor(assemblyName, SourceInformationProvider, DiagnosticMessageSink); - } - } -} diff --git a/src/Logging/Logging.Testing/src/Xunit/LoggedTestFrameworkDiscoverer.cs b/src/Logging/Logging.Testing/src/Xunit/LoggedTestFrameworkDiscoverer.cs deleted file mode 100644 index d7ff598f8e..0000000000 --- a/src/Logging/Logging.Testing/src/Xunit/LoggedTestFrameworkDiscoverer.cs +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using Microsoft.AspNetCore.Testing; -using Xunit; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.Extensions.Logging.Testing -{ - public class LoggedTestFrameworkDiscoverer : XunitTestFrameworkDiscoverer - { - private IDictionary Discoverers { get; } - - public LoggedTestFrameworkDiscoverer( - IAssemblyInfo assemblyInfo, - ISourceInformationProvider sourceProvider, - IMessageSink diagnosticMessageSink, - IXunitTestCollectionFactory collectionFactory = null) - : base(assemblyInfo, sourceProvider, diagnosticMessageSink, collectionFactory) - { - Discoverers = new Dictionary() - { - { typeof(ConditionalTheoryAttribute), new LoggedConditionalTheoryDiscoverer(diagnosticMessageSink) }, - { typeof(ConditionalFactAttribute), new LoggedConditionalFactDiscoverer(diagnosticMessageSink) }, - { typeof(TheoryAttribute), new LoggedTheoryDiscoverer(diagnosticMessageSink) }, - { typeof(FactAttribute), new LoggedFactDiscoverer(diagnosticMessageSink) } - }; - } - - protected override bool FindTestsForMethod( - ITestMethod testMethod, - bool includeSourceInformation, - IMessageBus messageBus, - ITestFrameworkDiscoveryOptions discoveryOptions) - { - if (typeof(ILoggedTest).IsAssignableFrom(testMethod.TestClass.Class.ToRuntimeType())) - { - var factAttributes = testMethod.Method.GetCustomAttributes(typeof(FactAttribute)); - if (factAttributes.Count() > 1) - { - var message = $"Test method '{testMethod.TestClass.Class.Name}.{testMethod.Method.Name}' has multiple [Fact]-derived attributes"; - var testCase = new ExecutionErrorTestCase(DiagnosticMessageSink, TestMethodDisplay.ClassAndMethod, TestMethodDisplayOptions.None, testMethod, message); - return ReportDiscoveredTestCase(testCase, includeSourceInformation, messageBus); - } - - var factAttribute = factAttributes.FirstOrDefault(); - if (factAttribute == null) - { - return true; - } - - var factAttributeType = (factAttribute as IReflectionAttributeInfo)?.Attribute.GetType(); - if (!Discoverers.TryGetValue(factAttributeType, out var discoverer)) - { - return base.FindTestsForMethod(testMethod, includeSourceInformation, messageBus, discoveryOptions); - } - else - { - foreach (var testCase in discoverer.Discover(discoveryOptions, testMethod, factAttribute)) - { - if (!ReportDiscoveredTestCase(testCase, includeSourceInformation, messageBus)) - { - return false; - } - } - - return true; - } - } - else - { - return base.FindTestsForMethod(testMethod, includeSourceInformation, messageBus, discoveryOptions); - } - } - } -} diff --git a/src/Logging/Logging.Testing/src/Xunit/LoggedTestFrameworkExecutor.cs b/src/Logging/Logging.Testing/src/Xunit/LoggedTestFrameworkExecutor.cs deleted file mode 100644 index ece623fa7a..0000000000 --- a/src/Logging/Logging.Testing/src/Xunit/LoggedTestFrameworkExecutor.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.Reflection; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.Extensions.Logging.Testing -{ - public class LoggedTestFrameworkExecutor : XunitTestFrameworkExecutor - { - public LoggedTestFrameworkExecutor(AssemblyName assemblyName, ISourceInformationProvider sourceInformationProvider, IMessageSink diagnosticMessageSink) - : base(assemblyName, sourceInformationProvider, diagnosticMessageSink) - { - } - - protected override async void RunTestCases(IEnumerable testCases, IMessageSink executionMessageSink, ITestFrameworkExecutionOptions executionOptions) - { - using (var assemblyRunner = new LoggedTestAssemblyRunner(TestAssembly, testCases, DiagnosticMessageSink, executionMessageSink, executionOptions)) - { - await assemblyRunner.RunAsync(); - } - } - } -} diff --git a/src/Logging/Logging.Testing/src/Xunit/LoggedTestInvoker.cs b/src/Logging/Logging.Testing/src/Xunit/LoggedTestInvoker.cs deleted file mode 100644 index 0e6638cb57..0000000000 --- a/src/Logging/Logging.Testing/src/Xunit/LoggedTestInvoker.cs +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Threading; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.Extensions.Logging.Testing -{ - public class LoggedTestInvoker : XunitTestInvoker - { - private readonly ITestOutputHelper _output; - private readonly RepeatContext _repeatContext; - private readonly bool _collectDumpOnFailure; - - public LoggedTestInvoker( - ITest test, - IMessageBus messageBus, - Type testClass, - object[] constructorArguments, - MethodInfo testMethod, - object[] testMethodArguments, - IReadOnlyList beforeAfterAttributes, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource, - ITestOutputHelper output, - RepeatContext repeatContext, - bool collectDumpOnFailure) - : base(test, messageBus, testClass, constructorArguments, testMethod, testMethodArguments, beforeAfterAttributes, aggregator, cancellationTokenSource) - { - _output = output; - _repeatContext = repeatContext; - _collectDumpOnFailure = collectDumpOnFailure; - } - - protected override object CreateTestClass() - { - var testClass = base.CreateTestClass(); - - (testClass as ILoggedTest).Initialize( - TestMethod, - TestMethodArguments, - _output ?? ConstructorArguments.SingleOrDefault(a => typeof(ITestOutputHelper).IsAssignableFrom(a.GetType())) as ITestOutputHelper); - - if (testClass is LoggedTestBase loggedTestBase) - { - // Used for testing - loggedTestBase.RepeatContext = _repeatContext; - } - - return testClass; - } - - protected override object CallTestMethod(object testClassInstance) - { - try - { - return base.CallTestMethod(testClassInstance); - } - catch - { - if (_collectDumpOnFailure && testClassInstance is LoggedTestBase loggedTestBase) - { - var path = Path.Combine(loggedTestBase.ResolvedLogOutputDirectory, loggedTestBase.ResolvedTestMethodName + ".dmp"); - var process = Process.GetCurrentProcess(); - - DumpCollector.Collect(process, path); - } - - throw; - } - } - } -} diff --git a/src/Logging/Logging.Testing/src/Xunit/LoggedTestMethodRunner.cs b/src/Logging/Logging.Testing/src/Xunit/LoggedTestMethodRunner.cs deleted file mode 100644 index 2ba2988257..0000000000 --- a/src/Logging/Logging.Testing/src/Xunit/LoggedTestMethodRunner.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.Extensions.Logging.Testing -{ - public class LoggedTestMethodRunner : XunitTestMethodRunner - { - private IMessageSink DiagnosticMessageSink { get; } - private object[] ConstructorArguments { get; } - - public LoggedTestMethodRunner( - ITestMethod testMethod, - IReflectionTypeInfo @class, - IReflectionMethodInfo method, - IEnumerable testCases, - IMessageSink diagnosticMessageSink, - IMessageBus messageBus, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource, - object[] constructorArguments) - : base(testMethod, @class, method, testCases, diagnosticMessageSink, messageBus, aggregator, cancellationTokenSource, constructorArguments) - { - DiagnosticMessageSink = diagnosticMessageSink; - ConstructorArguments = constructorArguments; - } - - protected override Task RunTestCaseAsync(IXunitTestCase testCase) - => testCase.RunAsync(DiagnosticMessageSink, MessageBus, ConstructorArguments, new ExceptionAggregator(Aggregator), CancellationTokenSource); - } -} diff --git a/src/Logging/Logging.Testing/src/Xunit/LoggedTestRunner.cs b/src/Logging/Logging.Testing/src/Xunit/LoggedTestRunner.cs deleted file mode 100644 index a630a4c50d..0000000000 --- a/src/Logging/Logging.Testing/src/Xunit/LoggedTestRunner.cs +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Testing; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.Extensions.Logging.Testing -{ - public class LoggedTestRunner : XunitTestRunner - { - public LoggedTestRunner( - ITest test, - IMessageBus messageBus, - Type testClass, - object[] constructorArguments, - MethodInfo testMethod, object[] - testMethodArguments, string skipReason, - IReadOnlyList beforeAfterAttributes, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource) - : base(test, messageBus, testClass, constructorArguments, testMethod, testMethodArguments, skipReason, beforeAfterAttributes, aggregator, cancellationTokenSource) - { - } - - protected async override Task> InvokeTestAsync(ExceptionAggregator aggregator) - { - var testOutputHelper = ConstructorArguments.SingleOrDefault(a => typeof(TestOutputHelper).IsAssignableFrom(a.GetType())) as TestOutputHelper - ?? new TestOutputHelper(); - testOutputHelper.Initialize(MessageBus, Test); - - var executionTime = await InvokeTestMethodAsync(aggregator, testOutputHelper); - - var output = testOutputHelper.Output; - testOutputHelper.Uninitialize(); - - return Tuple.Create(executionTime, output); - } - - protected override Task InvokeTestMethodAsync(ExceptionAggregator aggregator) - => InvokeTestMethodAsync(aggregator, null); - - private async Task InvokeTestMethodAsync(ExceptionAggregator aggregator, ITestOutputHelper output) - { - var collectDump = TestMethod.GetCustomAttribute() != null; - var repeatAttribute = GetRepeatAttribute(TestMethod); - - if (!typeof(LoggedTestBase).IsAssignableFrom(TestClass) || repeatAttribute == null) - { - return await new LoggedTestInvoker(Test, MessageBus, TestClass, ConstructorArguments, TestMethod, TestMethodArguments, BeforeAfterAttributes, aggregator, CancellationTokenSource, output, null, collectDump).RunAsync(); - } - - return await RunRepeatTestInvoker(aggregator, output, collectDump, repeatAttribute); - } - - private async Task RunRepeatTestInvoker(ExceptionAggregator aggregator, ITestOutputHelper output, bool collectDump, RepeatAttribute repeatAttribute) - { - var repeatContext = new RepeatContext - { - Limit = repeatAttribute.RunCount - }; - - var timeTaken = 0.0M; - var testLogger = new LoggedTestInvoker( - Test, - MessageBus, - TestClass, - ConstructorArguments, - TestMethod, - TestMethodArguments, - BeforeAfterAttributes, - aggregator, - CancellationTokenSource, - output, - repeatContext, - collectDump); - - for (repeatContext.CurrentIteration = 0; repeatContext.CurrentIteration < repeatContext.Limit; repeatContext.CurrentIteration++) - { - timeTaken = await testLogger.RunAsync(); - if (aggregator.HasExceptions) - { - return timeTaken; - } - } - - return timeTaken; - } - - private RepeatAttribute GetRepeatAttribute(MethodInfo methodInfo) - { - var attributeCandidate = methodInfo.GetCustomAttribute(); - if (attributeCandidate != null) - { - return attributeCandidate; - } - - attributeCandidate = methodInfo.DeclaringType.GetCustomAttribute(); - if (attributeCandidate != null) - { - return attributeCandidate; - } - - return methodInfo.DeclaringType.Assembly.GetCustomAttribute(); - } - } -} diff --git a/src/Logging/Logging.Testing/src/Xunit/LoggedTheoryDiscoverer.cs b/src/Logging/Logging.Testing/src/Xunit/LoggedTheoryDiscoverer.cs deleted file mode 100644 index 9d5402a09b..0000000000 --- a/src/Logging/Logging.Testing/src/Xunit/LoggedTheoryDiscoverer.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.Extensions.Logging.Testing -{ - public class LoggedTheoryDiscoverer : TheoryDiscoverer - { - public LoggedTheoryDiscoverer(IMessageSink diagnosticMessageSink) : base(diagnosticMessageSink) - { - } - - protected override IEnumerable CreateTestCasesForDataRow( - ITestFrameworkDiscoveryOptions discoveryOptions, - ITestMethod testMethod, - IAttributeInfo theoryAttribute, - object[] dataRow) - => new[] { new LoggedTestCase(DiagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), TestMethodDisplayOptions.None, testMethod, dataRow) }; - - protected override IEnumerable CreateTestCasesForTheory( - ITestFrameworkDiscoveryOptions discoveryOptions, - ITestMethod testMethod, - IAttributeInfo theoryAttribute) - => new[] { new LoggedTheoryTestCase(DiagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), TestMethodDisplayOptions.None, testMethod) }; - } -} diff --git a/src/Logging/Logging.Testing/src/Xunit/LoggedTheoryTestCase.cs b/src/Logging/Logging.Testing/src/Xunit/LoggedTheoryTestCase.cs deleted file mode 100644 index fa3e3a050d..0000000000 --- a/src/Logging/Logging.Testing/src/Xunit/LoggedTheoryTestCase.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Threading; -using System.Threading.Tasks; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.Extensions.Logging.Testing -{ - public class LoggedTheoryTestCase : XunitTheoryTestCase - { - [Obsolete("Called by the de-serializer; should only be called by deriving classes for de-serialization purposes")] - public LoggedTheoryTestCase() : base() - { - } - - public LoggedTheoryTestCase( - IMessageSink diagnosticMessageSink, - TestMethodDisplay defaultMethodDisplay, - TestMethodDisplayOptions defaultMethodDisplayOptions, - ITestMethod testMethod) - : base(diagnosticMessageSink, defaultMethodDisplay, defaultMethodDisplayOptions, testMethod) - { - } - - public override Task RunAsync( - IMessageSink diagnosticMessageSink, - IMessageBus messageBus, - object[] constructorArguments, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource) - => new LoggedTheoryTestCaseRunner(this, DisplayName, SkipReason, constructorArguments, diagnosticMessageSink, messageBus, aggregator, cancellationTokenSource).RunAsync(); - } -} diff --git a/src/Logging/Logging.Testing/src/Xunit/LoggedTheoryTestCaseRunner.cs b/src/Logging/Logging.Testing/src/Xunit/LoggedTheoryTestCaseRunner.cs deleted file mode 100644 index f1f92e1dcd..0000000000 --- a/src/Logging/Logging.Testing/src/Xunit/LoggedTheoryTestCaseRunner.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Threading; -using Xunit.Abstractions; -using Xunit.Sdk; - -namespace Microsoft.Extensions.Logging.Testing -{ - public class LoggedTheoryTestCaseRunner : XunitTheoryTestCaseRunner - { - public LoggedTheoryTestCaseRunner( - IXunitTestCase testCase, - string displayName, - string skipReason, - object[] constructorArguments, - IMessageSink diagnosticMessageSink, - IMessageBus messageBus, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource) - : base(testCase, displayName, skipReason, constructorArguments, diagnosticMessageSink, messageBus, aggregator, cancellationTokenSource) - { - } - - protected override XunitTestRunner CreateTestRunner( - ITest test, - IMessageBus messageBus, - Type testClass, - object[] constructorArguments, - MethodInfo testMethod, - object[] testMethodArguments, - string skipReason, - IReadOnlyList beforeAfterAttributes, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource) - => new LoggedTestRunner(test, messageBus, testClass, constructorArguments, testMethod, testMethodArguments, skipReason, beforeAfterAttributes, new ExceptionAggregator(aggregator), cancellationTokenSource); - } -} diff --git a/src/Logging/Logging.Testing/src/Xunit/RepeatAttribute.cs b/src/Logging/Logging.Testing/src/Xunit/RepeatAttribute.cs deleted file mode 100644 index ec86c0b601..0000000000 --- a/src/Logging/Logging.Testing/src/Xunit/RepeatAttribute.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.ComponentModel; - -namespace Microsoft.Extensions.Logging.Testing -{ - /// - /// Runs a test multiple times to stress flaky tests that are believed to be fixed. - /// This can be used on an assembly, class, or method name. - /// Requires using to run. - /// - [EditorBrowsable(EditorBrowsableState.Never)] - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = false)] - public class RepeatAttribute : Attribute - { - public RepeatAttribute(int runCount = 10) - { - RunCount = runCount; - } - - /// - /// The number of times to run a test. - /// - public int RunCount { get; } - } -} diff --git a/src/Logging/Logging.Testing/src/build/Microsoft.Extensions.Logging.Testing.props b/src/Logging/Logging.Testing/src/build/Microsoft.Extensions.Logging.Testing.props index c503c32d40..3895cb5471 100644 --- a/src/Logging/Logging.Testing/src/build/Microsoft.Extensions.Logging.Testing.props +++ b/src/Logging/Logging.Testing/src/build/Microsoft.Extensions.Logging.Testing.props @@ -11,8 +11,8 @@ Condition="'$(GenerateLoggingTestingAssemblyAttributes)' != 'false'"> - <_Parameter1>Microsoft.Extensions.Logging.Testing.LoggedTestFramework - <_Parameter2>Microsoft.Extensions.Logging.Testing + <_Parameter1>Microsoft.AspNetCore.Testing.AspNetTestFramework + <_Parameter2>Microsoft.AspNetCore.Testing diff --git a/src/Logging/Logging.Testing/test/AssemblyTestLogTests.cs b/src/Logging/Logging.Testing/test/AssemblyTestLogTests.cs index 20f597defc..6d7ae5139a 100644 --- a/src/Logging/Logging.Testing/test/AssemblyTestLogTests.cs +++ b/src/Logging/Logging.Testing/test/AssemblyTestLogTests.cs @@ -18,12 +18,6 @@ namespace Microsoft.Extensions.Logging.Testing.Tests private static readonly string ThisAssemblyName = ThisAssembly.GetName().Name; private static readonly string TFM = new DirectoryInfo(AppContext.BaseDirectory).Name; - [Fact] - public void FullClassNameUsedWhenShortClassNameAttributeNotSpecified() - { - Assert.Equal(GetType().FullName, ResolvedTestClassName); - } - [Fact] public void ForAssembly_ReturnsSameInstanceForSameAssembly() { @@ -57,7 +51,7 @@ namespace Microsoft.Extensions.Logging.Testing.Tests } [Fact] - private Task TestLogEscapesIllegalFileNames() => + public Task TestLogEscapesIllegalFileNames() => RunTestLogFunctionalTest((tempDir) => { var illegalTestName = "T:e/s//t"; diff --git a/src/Logging/Logging.Testing/test/LoggedTestXunitRepeatTests.cs b/src/Logging/Logging.Testing/test/LoggedTestXunitRepeatTests.cs deleted file mode 100644 index dbd1d7260a..0000000000 --- a/src/Logging/Logging.Testing/test/LoggedTestXunitRepeatTests.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Xunit; - -namespace Microsoft.Extensions.Logging.Testing.Tests -{ - [Repeat] - public class LoggedTestXunitRepeatTests : LoggedTest - { - public static int _runCount = 0; - - [Fact] - [Repeat(5)] - public void RepeatLimitIsSetCorrectly() - { - Assert.Equal(5, RepeatContext.Limit); - } - - [Fact] - [Repeat(5)] - public void RepeatRunsTestSpecifiedNumberOfTimes() - { - Assert.Equal(RepeatContext.CurrentIteration, _runCount); - _runCount++; - } - - [Fact] - public void RepeatCanBeSetOnClass() - { - Assert.Equal(10, RepeatContext.Limit); - } - } - - public class LoggedTestXunitRepeatAssemblyTests : LoggedTest - { - [Fact] - public void RepeatCanBeSetOnAssembly() - { - Assert.Equal(1, RepeatContext.Limit); - } - } -} diff --git a/src/Logging/Logging.Testing/test/LoggedTestXunitTests.cs b/src/Logging/Logging.Testing/test/LoggedTestXunitTests.cs index ab9ee746c3..d8454023a2 100644 --- a/src/Logging/Logging.Testing/test/LoggedTestXunitTests.cs +++ b/src/Logging/Logging.Testing/test/LoggedTestXunitTests.cs @@ -21,18 +21,6 @@ namespace Microsoft.Extensions.Logging.Testing.Tests _output = output; } - [Fact] - public void ShortClassNameUsedWhenShortClassNameAttributeSpecified() - { - Assert.Equal(GetType().Name, ResolvedTestClassName); - } - - [Fact] - public void LoggedTestTestOutputHelperSameInstanceAsInjectedConstructorArg() - { - Assert.Same(_output, TestOutputHelper); - } - [Fact] public void LoggedFactInitializesLoggedTestProperties() { @@ -189,9 +177,9 @@ namespace Microsoft.Extensions.Logging.Testing.Tests public bool SetupInvoked { get; private set; } = false; public bool ITestOutputHelperIsInitialized { get; private set; } = false; - public override void Initialize(MethodInfo methodInfo, object[] testMethodArguments, ITestOutputHelper testOutputHelper) + public override void Initialize(TestContext context, MethodInfo methodInfo, object[] testMethodArguments, ITestOutputHelper testOutputHelper) { - base.Initialize(methodInfo, testMethodArguments, testOutputHelper); + base.Initialize(context, methodInfo, testMethodArguments, testOutputHelper); try { diff --git a/src/Logging/Logging.Testing/test/Properties/AssemblyInfo.cs b/src/Logging/Logging.Testing/test/Properties/AssemblyInfo.cs index b104c11dfc..82616e2737 100644 --- a/src/Logging/Logging.Testing/test/Properties/AssemblyInfo.cs +++ b/src/Logging/Logging.Testing/test/Properties/AssemblyInfo.cs @@ -2,4 +2,3 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Testing; [assembly: LogLevel(LogLevel.Trace)] -[assembly: Repeat(1)]