-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Finalize implementation and add crash detection support.
- Loading branch information
Showing
20 changed files
with
272 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 0 additions & 74 deletions
74
test/EFCore.Jet.FunctionalTests/TestUtilities/Xunit/JetXunitTestCaseRunner.cs
This file was deleted.
Oops, something went wrong.
14 changes: 0 additions & 14 deletions
14
test/EFCore.Jet.FunctionalTests/TestUtilities/Xunit/JetXunitTestFramework.cs
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
test/Shared/TestUtilities/Attributes/AccessProviderTypeVariation.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using System; | ||
|
||
namespace EntityFrameworkCore.Jet.FunctionalTests.TestUtilities; | ||
|
||
[Flags] | ||
public enum AccessProviderTypeVariation | ||
{ | ||
None = 0, | ||
X86 = 1 << 0, | ||
X64 = 1 << 1, | ||
Odbc = 1 << 2, | ||
OleDb = 1 << 3, | ||
All = -1, | ||
} |
43 changes: 43 additions & 0 deletions
43
test/Shared/TestUtilities/Attributes/TestRunnerCrashAttribute.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
using System; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Microsoft.EntityFrameworkCore.TestUtilities.Xunit; | ||
|
||
namespace EntityFrameworkCore.Jet.FunctionalTests.TestUtilities; | ||
|
||
/// <summary> | ||
/// Marks a test method or class that is known to crash the test runner. | ||
/// </summary> | ||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)] | ||
public class TestRunnerCrashAttribute : Attribute, ITestCondition | ||
{ | ||
public const string DefaultSkipReason = "The test is known to crash the test runner."; | ||
|
||
protected AccessProviderTypeVariation[] AccessProviderTypeVariations { get; } | ||
|
||
public TestRunnerCrashAttribute(params AccessProviderTypeVariation[] accessProviderTypeVariations) | ||
{ | ||
AccessProviderTypeVariations = accessProviderTypeVariations.Length > 0 | ||
? accessProviderTypeVariations | ||
: new[] { AccessProviderTypeVariation.All }; | ||
} | ||
|
||
public virtual ValueTask<bool> IsMetAsync() | ||
{ | ||
// Implement and enable if we want to filter tests by specific runtime scenarios. | ||
var currentVariation = AccessProviderTypeVariation.All; // AppConfig.AccessProviderTypeVariation; | ||
var isMet = AccessProviderTypeVariations.Any(v => v.HasFlag(currentVariation)); | ||
|
||
if (!isMet && string.IsNullOrEmpty(Skip)) | ||
{ | ||
Skip = DefaultSkipReason; | ||
} | ||
|
||
return new ValueTask<bool>(isMet); | ||
} | ||
|
||
public virtual string SkipReason | ||
=> Skip; | ||
|
||
public virtual string Skip { get; set; } | ||
} |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
135 changes: 135 additions & 0 deletions
135
test/Shared/TestUtilities/Xunit/JetXunitTestCaseRunner.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Reflection; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Xunit.Abstractions; | ||
using Xunit.Sdk; | ||
|
||
namespace EntityFrameworkCore.Jet.FunctionalTests.TestUtilities.Xunit; | ||
|
||
public class JetXunitTestCaseRunner : XunitTestCaseRunner | ||
{ | ||
public const string TestRunnerCrashCacheDirectory = "TestRunnerCrashCache"; | ||
public const string AutoSkipPrefix = "[AutoSkip]"; | ||
public const string AutoSkipTestRunnerCrashingTestsEnvironmentVariableName = "EFCoreJet_AutoSkipTestRunnerCrashingTests"; | ||
|
||
public virtual bool EnableAutoSkipTestsKnownToCrashTestRunner | ||
=> (Environment.GetEnvironmentVariable(AutoSkipTestRunnerCrashingTestsEnvironmentVariableName)?.ToLowerInvariant() ?? "true") != "false"; | ||
|
||
public JetXunitTestCaseRunner(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<BeforeAfterTestAttribute> beforeAfterAttributes, | ||
ExceptionAggregator aggregator, | ||
CancellationTokenSource cancellationTokenSource) | ||
=> new JetXunitTestRunner( | ||
test, | ||
messageBus, | ||
testClass, | ||
constructorArguments, | ||
testMethod, | ||
testMethodArguments, | ||
skipReason, | ||
beforeAfterAttributes, | ||
new ExceptionAggregator(aggregator), | ||
cancellationTokenSource); | ||
|
||
/// <remarks> | ||
/// `TestRunner<TTestCase>.RunAsync()` is not virtual, so we need to override this method here to call our own | ||
/// `JetXunitTestRunner.RunAsync()` implementation. | ||
/// </remarks>> | ||
protected override async Task<RunSummary> RunTestAsync() | ||
{ | ||
if (EnableAutoSkipTestsKnownToCrashTestRunner) | ||
{ | ||
AutoSkipTestsKnownToCrashTestRunner(); | ||
} | ||
|
||
return await RunWithCrashDetection( | ||
() => ((JetXunitTestRunner)CreateTestRunner( | ||
CreateTest(TestCase, DisplayName), | ||
MessageBus, | ||
TestClass, | ||
ConstructorArguments, | ||
TestMethod, | ||
TestMethodArguments, | ||
SkipReason, | ||
BeforeAfterAttributes, | ||
Aggregator, | ||
CancellationTokenSource)) | ||
.RunAsync()); | ||
} | ||
|
||
protected virtual async Task<RunSummary> RunWithCrashDetection(Func<Task<RunSummary>> func) | ||
{ | ||
Directory.CreateDirectory(TestRunnerCrashCacheDirectory); | ||
|
||
var filePath = Path.Combine(TestRunnerCrashCacheDirectory, $"{DateTime.UtcNow:yyyyMMdd'_'HHmmss.fffffff}_{(Environment.Is64BitProcess ? "x64" : "x86")}_{Guid.NewGuid()}.txt"); | ||
var contents = $"{TestCase.TestMethod.TestClass.Class.Name}\t{TestCase.TestMethod.Method.Name}"; | ||
await File.WriteAllTextAsync(filePath, contents); | ||
|
||
var result = await func(); | ||
|
||
File.Delete(filePath); | ||
|
||
return result; | ||
} | ||
|
||
protected virtual void AutoSkipTestsKnownToCrashTestRunner() | ||
{ | ||
if (IsTestKnownToCrashTestRunner(TestCase)) | ||
{ | ||
SkipReason = $"{AutoSkipPrefix} {TestRunnerCrashAttribute.DefaultSkipReason}"; | ||
} | ||
} | ||
|
||
protected virtual bool IsTestKnownToCrashTestRunner(ITestCase testCase) | ||
{ | ||
if (File.Exists(JetXunitTestFramework.TestsKnownToCrashTestRunnerFilePath)) | ||
{ | ||
foreach (var line in File.ReadLines(JetXunitTestFramework.TestsKnownToCrashTestRunnerFilePath)) | ||
{ | ||
var parts = line.Split('\t'); | ||
if (parts.Length >= 2) | ||
{ | ||
var testClass = parts[^2]; | ||
var testMethod = parts[^1]; | ||
|
||
if (testClass == testCase.TestMethod.TestClass.Class.Name && | ||
testMethod == testCase.TestMethod.Method.Name) | ||
{ | ||
return true; | ||
} | ||
} | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
using System; | ||
using System.IO; | ||
using Xunit.Abstractions; | ||
using Xunit.Sdk; | ||
|
||
namespace EntityFrameworkCore.Jet.FunctionalTests.TestUtilities.Xunit; | ||
|
||
public class JetXunitTestFramework : XunitTestFramework | ||
{ | ||
public const string TestsKnownToCrashTestRunnerFilePath = "./../../../TestsKnownToCrashTestRunner.txt"; | ||
public const string DetectCrashesOfPreviousRunsEnvironmentVariableName = "EFCoreJet_DetectCrashesOfPreviousRuns"; | ||
|
||
public virtual bool EnableDetectCrashesOfPreviousRuns | ||
=> Environment.GetEnvironmentVariable(DetectCrashesOfPreviousRunsEnvironmentVariableName)?.ToLowerInvariant() == "true"; | ||
|
||
public JetXunitTestFramework(IMessageSink messageSink) : base(messageSink) | ||
{ | ||
} | ||
|
||
protected override ITestFrameworkDiscoverer CreateDiscoverer(IAssemblyInfo assemblyInfo) | ||
{ | ||
if (EnableDetectCrashesOfPreviousRuns) | ||
{ | ||
DetectCrashesOfPreviousRuns(); | ||
} | ||
|
||
return new JetXunitTestFrameworkDiscoverer(assemblyInfo, SourceInformationProvider, DiagnosticMessageSink); | ||
} | ||
|
||
protected virtual void DetectCrashesOfPreviousRuns() | ||
{ | ||
if (!Directory.Exists(JetXunitTestCaseRunner.TestRunnerCrashCacheDirectory)) | ||
return; | ||
|
||
foreach (var filePath in Directory.EnumerateFiles(JetXunitTestCaseRunner.TestRunnerCrashCacheDirectory, "*.txt")) | ||
{ | ||
var contents = File.ReadAllText(filePath); | ||
contents = $"{string.Join('\t', Path.GetFileNameWithoutExtension(filePath).Split('_'))}\t{contents}\n"; | ||
File.AppendAllText(TestsKnownToCrashTestRunnerFilePath, contents); | ||
|
||
File.Delete(filePath); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.