Skip to content

Commit

Permalink
206
Browse files Browse the repository at this point in the history
  • Loading branch information
kkgonsovsky committed Dec 12, 2024
1 parent d6bec65 commit 3110a71
Show file tree
Hide file tree
Showing 19 changed files with 310 additions and 141 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,9 @@
<AssemblyAttribute Include="Tennisi.Xunit.FullTestParallelizationAttribute">
</AssemblyAttribute>
</ItemGroup>

<ItemGroup Condition="'$(DisableTestParallelization)' == 'true'">
<AssemblyAttribute Include="Tennisi.Xunit.DisableTestParallelizationAttribute">
</AssemblyAttribute>
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ private static string GenerateBaseValue(int index)
return index.ToString("x").PadLeft(40, '0').Substring(0, 40);
}

private class DeterministicGenerator
private sealed class DeterministicGenerator
{
private readonly string _baseValue;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using Xunit;
using Xunit.Abstractions;
Expand Down
12 changes: 12 additions & 0 deletions Tennisi.Xunit.ParallelTestFramework.UI.Tests/Forms/TestWindow.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Window x:Class="Tennisi.Xunit.ParallelTestFramework.UI.Tests.Forms.TestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<TextBox x:Name="SampleTextBox" Width="200" Height="30" Margin="50"/>
<Button x:Name="SampleButton" Content="Click Me" Width="100" Height="30" Margin="50,50,0,0"/>
</Grid>
</Window>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Windows;
using System.Windows.Controls;

namespace Tennisi.Xunit.ParallelTestFramework.UI.Tests.Forms;

/// <summary>
/// Interaction logic for TestWindow.xaml
/// </summary>
public partial class TestWindow : Window
{
public string OutputText { get; private set; }

public TestWindow()
{
InitializeComponent();
SampleButton.Click += (sender, args) => OutputText = SampleTextBox.Text;
}

public new TextBox PublicTextBox { get => FindName("SampleTextBox") as TextBox; }
public new Button PublicButton { get => FindName("SampleButton") as Button; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<UseWpf>true</UseWpf>
</PropertyGroup>

<PropertyGroup>
<FullTestParallelization>true</FullTestParallelization>
</PropertyGroup>

<ImportGroup>
<Import Project="../Tennisi.Xunit.ParallelTestFramework/build/Tennisi.Xunit.ParallelTestFramework.props" />
</ImportGroup>

<ItemGroup>
<ProjectReference Include="..\Tennisi.Xunit.ParallelTestFramework.Tests\Tennisi.Xunit.ParallelTestFramework.Tests.csproj" />
<ProjectReference Include="..\Tennisi.Xunit.ParallelTestFramework.UI\Tennisi.Xunit.ParallelTestFramework.UI.csproj" />
<ProjectReference Include="..\Tennisi.Xunit.ParallelTestFramework\Tennisi.Xunit.ParallelTestFramework.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Xunit.StaFact" Version="1.1.11" />
<PackageReference Include="xunit.extensibility.execution" Version="2.9.2" />
</ItemGroup>

</Project>
19 changes: 19 additions & 0 deletions Tennisi.Xunit.ParallelTestFramework.UI.Tests/TestWindowTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Xunit;
using Tennisi.Xunit.ParallelTestFramework.UI.Tests.Forms;


namespace Tennisi.Xunit.ParallelTestFramework.UI.Tests;

public class TestWindowTests
{
[StaFact]
public void ItShouldClick()
{
var window = new TestWindow();

var button = window.PublicButton;

Assert.NotNull(button);
Assert.Equal("Click Me", button.Content);
}
}
1 change: 1 addition & 0 deletions Tennisi.Xunit.ParallelTestFramework.UI/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
UNDER CONSTRUCTION
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net7.0-windows;net8.0-windows</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Description>Run xUnit test cases in parallel</Description>
<IsPackable>True</IsPackable>
<PackageReadmeFile>README.md</PackageReadmeFile>
<RootNamespace>Tennisi.Xunit</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="xunit.extensibility.execution" Version="2.9.2" />
</ItemGroup>

<ItemGroup>
<FrameworkReference Include="Microsoft.WindowsDesktop.App" />
<ProjectReference Include="..\Tennisi.Xunit.ParallelTestFramework\Tennisi.Xunit.ParallelTestFramework.csproj" />
</ItemGroup>

</Project>
12 changes: 12 additions & 0 deletions Tennisi.Xunit.ParallelTestFramework.sln
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tennisi.Xunit.ParallelTestFramework.Tests", "Tennisi.Xunit.ParallelTestFramework.Tests\Tennisi.Xunit.ParallelTestFramework.Tests.csproj", "{25DEF5B0-7B2E-4CA7-A145-CAB9F1B68D53}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tennisi.Xunit.ParallelTestFramework.UI.Tests", "Tennisi.Xunit.ParallelTestFramework.UI.Tests\Tennisi.Xunit.ParallelTestFramework.UI.Tests.csproj", "{205A1A8F-72EB-46F1-9C2E-97B6611FA5E3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tennisi.Xunit.ParallelTestFramework.UI", "Tennisi.Xunit.ParallelTestFramework.UI\Tennisi.Xunit.ParallelTestFramework.UI.csproj", "{A1C0D3F9-9719-4756-9305-22B20CA518B6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -29,6 +33,14 @@ Global
{25DEF5B0-7B2E-4CA7-A145-CAB9F1B68D53}.Debug|Any CPU.Build.0 = Debug|Any CPU
{25DEF5B0-7B2E-4CA7-A145-CAB9F1B68D53}.Release|Any CPU.ActiveCfg = Release|Any CPU
{25DEF5B0-7B2E-4CA7-A145-CAB9F1B68D53}.Release|Any CPU.Build.0 = Release|Any CPU
{205A1A8F-72EB-46F1-9C2E-97B6611FA5E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{205A1A8F-72EB-46F1-9C2E-97B6611FA5E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{205A1A8F-72EB-46F1-9C2E-97B6611FA5E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{205A1A8F-72EB-46F1-9C2E-97B6611FA5E3}.Release|Any CPU.Build.0 = Release|Any CPU
{A1C0D3F9-9719-4756-9305-22B20CA518B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A1C0D3F9-9719-4756-9305-22B20CA518B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A1C0D3F9-9719-4756-9305-22B20CA518B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A1C0D3F9-9719-4756-9305-22B20CA518B6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace Tennisi.Xunit;

/// <summary>
/// Assembly-level attribute that disables <c>xunit.discovery.PreEnumerateTheories</c>, <c>xunit.parallelizeTestCollections</c>, <c>xunit.parallelizeAssembly</c>
/// and enables xunit.execution.DisableParallelization in the xUnit framework.
/// Alternatively, the <c>DisbaleTestParallelization</c> property can be set in the project file to achieve the same effect.
/// </summary>
/// <remarks>
/// <para>
/// When applied, it reverts the behavior of test execution to the standard xUnit execution model.
/// </para>
/// </remarks>
[AttributeUsage(AttributeTargets.Assembly)]
public sealed class DisableTestParallelizationAttribute : Attribute
{
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
namespace Tennisi.Xunit;

/// <summary>
/// An assembly-level attribute that enables <c>parallelizeTestCollections</c> and <c>preEnumerateTheories</c> in the xUnit framework.
/// Alternatively, you can set the <c>FullTestParallelization</c> property in your project file.
/// An assembly-level attribute that enables <c>xunit.discovery.PreEnumerateTheories</c>, <c>xunit.parallelizeTestCollections</c>, <c>xunit.parallelizeAssembly</c>
/// and disables xunit.execution.DisableParallelization in the xUnit framework.
/// Alternatively, the <c>FullTestParallelization</c> property can be set in the project file to achieve the same effect.
/// </summary>
/// <remarks>
/// <para>
/// Note: The use of <see cref="ParallelTag"/> is supported only when <c>FullTestParallelization</c> is enabled,
/// ensuring facts or theories received this constructor argument are executed under the parallelization strategy.
/// </para>
/// </remarks>
[AttributeUsage(AttributeTargets.Assembly)]
public sealed class FullTestParallelizationAttribute : Attribute
{
Expand Down
37 changes: 24 additions & 13 deletions Tennisi.Xunit.ParallelTestFramework/ParallelSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,40 @@ internal static class ParallelSettings
{
private class TestAsm
{
public TestAsm(bool force, ITestFrameworkOptions opts)
public TestAsm(bool disbale, bool force, ITestFrameworkOptions opts)
{
Opts = opts;
Force = force;
Disable = disbale;
}

internal bool Disable {get; set;}
internal bool Force {get; set;}
internal ITestFrameworkOptions Opts { get; set; }
}
private static readonly ConcurrentDictionary<string, TestAsm> TestCollectionsCache = new();

internal static void RefineParallelSetting(AssemblyName assemblyName, ITestFrameworkOptions opts, string setting, bool value)
internal static void RefineParallelSetting(AssemblyName assemblyName, ITestFrameworkOptions opts)
{
RefineParallelSetting(assemblyName.FullName, opts, setting, value);
RefineParallelSetting(assemblyName.FullName, opts);
}


internal static void RefineParallelSetting(string assemblyName, ITestFrameworkOptions opts, string setting, bool value)
internal static void RefineParallelSetting(string assemblyName, ITestFrameworkOptions opts)
{
if (ShouldForceParallelize(assemblyName, opts).Force)
var behaviour = DetectParallelBehaviour(assemblyName, opts);

if (behaviour.Force && !behaviour.Disable)
{
opts.SetValue("xunit.discovery.PreEnumerateTheories", true);
opts.SetValue("xunit.execution.DisableParallelization", false);
opts.SetValue("xunit.parallelizeTestCollections", true);
opts.SetValue("xunit.parallelizeAssembly", true);
}
else if (behaviour.Disable)
{
opts.SetValue(setting, value);
opts.SetValue("xunit.discovery.PreEnumerateTheories", false);
opts.SetValue("xunit.execution.DisableParallelization", true);
opts.SetValue("xunit.parallelizeTestCollections", false);
opts.SetValue("xunit.parallelizeAssembly", false);
}
}

Expand All @@ -42,16 +54,15 @@ public static bool GetSetting(string assemblyName, string setting)
return val;
}

private static TestAsm ShouldForceParallelize(string assemblyName, ITestFrameworkOptions opts)
private static TestAsm DetectParallelBehaviour(string assemblyName, ITestFrameworkOptions opts)
{
assemblyName = AssemblyInfoExtractor.ExtractNameAndVersion(assemblyName);
return TestCollectionsCache.GetOrAdd(assemblyName , name =>
{
var assembly = Assembly.Load(new AssemblyName(name));
var attributeType = typeof(FullTestParallelizationAttribute);
var attributes = assembly.GetCustomAttributes(attributeType, false);
var result = attributes.Length != 0;
return new TestAsm(force: result, opts);
var force = assembly.GetCustomAttributes(typeof(FullTestParallelizationAttribute), false).Length != 0;
var disable = assembly.GetCustomAttributes(typeof(DisableTestParallelizationAttribute), false).Length != 0;
return new TestAsm(force: force, disbale:disable, opts: opts);
});
}
}
Loading

0 comments on commit 3110a71

Please sign in to comment.