From 4898ff30a775ac5eeaec149c07c0e1fd1c2532a2 Mon Sep 17 00:00:00 2001 From: Vladimir Krestov Date: Wed, 9 Feb 2022 15:54:54 +0300 Subject: [PATCH] Replace conditional test attributes with SkipOnArchitectureAttribute. It is implemented in a similar way to existing SkipOn* attributes from Microsoft.DotNet.XUnitExtensions library, allowing to set several unsupported architectures. Fixes #6653 --- .../ConditionalWinFormsFactAttribute.cs | 49 ------------------- .../ConditionalWinFormsTheoryAttribute.cs | 49 ------------------- .../SkipOnArchitectureAttribute.cs | 21 ++++++++ .../SkipOnArchitectureDiscoverer.cs | 42 ++++++++++++++++ .../tests/TestUtilities/TestArchitectures.cs | 15 ++++++ .../System/Windows/Forms/ControlTests.cs | 5 +- .../System/Windows/Forms/DataGridViewTests.cs | 36 ++++++++------ .../System/Windows/Forms/RichTextBoxTests.cs | 5 +- .../System/Windows/Forms/ToolStripTests.cs | 7 +-- 9 files changed, 109 insertions(+), 120 deletions(-) delete mode 100644 src/System.Windows.Forms/tests/TestUtilities/ConditionalWinFormsFactAttribute.cs delete mode 100644 src/System.Windows.Forms/tests/TestUtilities/ConditionalWinFormsTheoryAttribute.cs create mode 100644 src/System.Windows.Forms/tests/TestUtilities/SkipOnArchitectureAttribute.cs create mode 100644 src/System.Windows.Forms/tests/TestUtilities/SkipOnArchitectureDiscoverer.cs create mode 100644 src/System.Windows.Forms/tests/TestUtilities/TestArchitectures.cs diff --git a/src/System.Windows.Forms/tests/TestUtilities/ConditionalWinFormsFactAttribute.cs b/src/System.Windows.Forms/tests/TestUtilities/ConditionalWinFormsFactAttribute.cs deleted file mode 100644 index 8a103006600..00000000000 --- a/src/System.Windows.Forms/tests/TestUtilities/ConditionalWinFormsFactAttribute.cs +++ /dev/null @@ -1,49 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Runtime.InteropServices; -using Xunit; - -namespace System -{ - public class ConditionalWinFormsFactAttribute : WinFormsFactAttribute - { - private Architecture _unsupportedArchitecture; - private bool _isSkipRequired; - private string _skipReason; - - public override string Skip - { - get => base.Skip; - set - { - _skipReason = value; - - if (_isSkipRequired) - { - base.Skip = value; - } - - // Don't skip a test case if the skip condition is false. - } - } - - /// - /// Defines the architecture to skip the test on. This is complementary to parameter. - /// - public Architecture UnsupportedArchitecture - { - get => _unsupportedArchitecture; - set - { - _unsupportedArchitecture = value; - _isSkipRequired = RuntimeInformation.ProcessArchitecture == value; - if (_isSkipRequired && _skipReason is not null) - { - Skip = _skipReason; - } - } - } - } -} diff --git a/src/System.Windows.Forms/tests/TestUtilities/ConditionalWinFormsTheoryAttribute.cs b/src/System.Windows.Forms/tests/TestUtilities/ConditionalWinFormsTheoryAttribute.cs deleted file mode 100644 index c75175c3718..00000000000 --- a/src/System.Windows.Forms/tests/TestUtilities/ConditionalWinFormsTheoryAttribute.cs +++ /dev/null @@ -1,49 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Runtime.InteropServices; -using Xunit; - -namespace System -{ - public class ConditionalWinFormsTheoryAttribute : WinFormsTheoryAttribute - { - private Architecture _unsupportedArchitecture; - private bool _isSkipRequired; - private string _skipReason; - - public override string Skip - { - get => base.Skip; - set - { - _skipReason = value; - - if (_isSkipRequired) - { - base.Skip = value; - } - - // Don't skip a test case if the skip condition is false. - } - } - - /// - /// Defines the architecture to skip the test on. This is complementary to parameter. - /// - public Architecture UnsupportedArchitecture - { - get => _unsupportedArchitecture; - set - { - _unsupportedArchitecture = value; - _isSkipRequired = RuntimeInformation.ProcessArchitecture == value; - if (_isSkipRequired && _skipReason is not null) - { - Skip = _skipReason; - } - } - } - } -} diff --git a/src/System.Windows.Forms/tests/TestUtilities/SkipOnArchitectureAttribute.cs b/src/System.Windows.Forms/tests/TestUtilities/SkipOnArchitectureAttribute.cs new file mode 100644 index 00000000000..4544da0dbe2 --- /dev/null +++ b/src/System.Windows.Forms/tests/TestUtilities/SkipOnArchitectureAttribute.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Xunit.Sdk; + +namespace System +{ + /// + /// Apply this attribute to your test method or class to skip it on a certain architecture. + /// + /// + /// This doesn't work for . See https://github.com/dotnet/winforms/issues/7013. + /// + [TraitDiscoverer("System.SkipOnArchitectureDiscoverer", "System.Windows.Forms.TestUtilities")] + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true, Inherited = true)] + public class SkipOnArchitectureAttribute : Attribute, ITraitAttribute + { + public SkipOnArchitectureAttribute(TestArchitectures testArchitectures, string reason) { } + } +} diff --git a/src/System.Windows.Forms/tests/TestUtilities/SkipOnArchitectureDiscoverer.cs b/src/System.Windows.Forms/tests/TestUtilities/SkipOnArchitectureDiscoverer.cs new file mode 100644 index 00000000000..01b85efbf50 --- /dev/null +++ b/src/System.Windows.Forms/tests/TestUtilities/SkipOnArchitectureDiscoverer.cs @@ -0,0 +1,42 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.InteropServices; +using Microsoft.DotNet.XUnitExtensions; +using Xunit.Abstractions; +using Xunit.Sdk; + +namespace System +{ + /// + /// This class discovers all of the tests and test classes that have + /// applied the . + /// + public class SkipOnArchitectureDiscoverer : ITraitDiscoverer + { + /// + /// Gets the trait values from the Category attribute. + /// + /// The trait attribute containing the trait values. + /// The trait values. + public IEnumerable> GetTraits(IAttributeInfo traitAttribute) + { + TestArchitectures testArchitectures = 0; + + if (traitAttribute.GetConstructorArguments().FirstOrDefault() is TestArchitectures ta) + { + testArchitectures = ta; + } + + if ((testArchitectures.HasFlag(TestArchitectures.X86) && RuntimeInformation.ProcessArchitecture == Architecture.X86) || + (testArchitectures.HasFlag(TestArchitectures.X64) && RuntimeInformation.ProcessArchitecture == Architecture.X64) || + (testArchitectures.HasFlag(TestArchitectures.Arm64) && RuntimeInformation.ProcessArchitecture == Architecture.Arm64)) + { + return new[] { new KeyValuePair(XunitConstants.Category, XunitConstants.IgnoreForCI) }; + } + + return Array.Empty>(); + } + } +} diff --git a/src/System.Windows.Forms/tests/TestUtilities/TestArchitectures.cs b/src/System.Windows.Forms/tests/TestUtilities/TestArchitectures.cs new file mode 100644 index 00000000000..df21ab113ba --- /dev/null +++ b/src/System.Windows.Forms/tests/TestUtilities/TestArchitectures.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System +{ + [Flags] + public enum TestArchitectures + { + X86 = 1, + X64 = 2, + Arm64 = 4, + Any = ~0 + } +} diff --git a/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/ControlTests.cs b/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/ControlTests.cs index 0c8071caa87..aee67d35ca2 100644 --- a/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/ControlTests.cs +++ b/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/ControlTests.cs @@ -861,8 +861,9 @@ public void Control_GetNextSelectableControl_MultipleComplexControls_CycleBackwa } [ActiveIssue("https://github.com/dotnet/winforms/issues/6730")] - [ConditionalWinFormsTheory(Skip = "Flaky tests, see: https://github.com/dotnet/winforms/issues/6730", - UnsupportedArchitecture = Runtime.InteropServices.Architecture.X64)] + [WinFormsTheory] + [SkipOnArchitecture(TestArchitectures.X64, + "Flaky tests, see: https://github.com/dotnet/winforms/issues/6730")] [InlineData(RightToLeft.No)] [InlineData(RightToLeft.Yes)] public void Control_SelectNextControl_ToolStrips_CycleForwardExpected(RightToLeft rightToLeft) diff --git a/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/DataGridViewTests.cs b/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/DataGridViewTests.cs index d0524b887ba..02d40eeec0e 100644 --- a/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/DataGridViewTests.cs +++ b/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/DataGridViewTests.cs @@ -5,7 +5,6 @@ using System.ComponentModel; using System.Data; using System.Drawing; -using System.Runtime.InteropServices; using System.Windows.Forms.TestUtilities; using Xunit; @@ -171,8 +170,9 @@ public static IEnumerable ColumnHeadersHeight_SetWithHandle_TestData() } [ActiveIssue("https://github.com/dotnet/winforms/issues/6597")] - [ConditionalWinFormsTheory(UnsupportedArchitecture = Architecture.Arm64, - Skip = "Flaky tests, see: https://github.com/dotnet/winforms/issues/6597")] + [WinFormsTheory] + [SkipOnArchitecture(TestArchitectures.Arm64, + "Flaky tests, see: https://github.com/dotnet/winforms/issues/6597")] [MemberData(nameof(ColumnHeadersHeight_SetWithHandle_TestData))] public void DataGridView_ColumnHeadersHeight_SetWithHandle_GetReturnsExpected(DataGridViewColumnHeadersHeightSizeMode columnHeadersWidthSizeMode, bool columnHeadersVisible, bool autoSize, int value, int expectedValue, int expectedInvalidatedCallCount) { @@ -240,8 +240,9 @@ public static IEnumerable ColumnHeadersHeight_SetWithParentWithHandle_ } [ActiveIssue("https://github.com/dotnet/winforms/issues/6597")] - [ConditionalWinFormsTheory(UnsupportedArchitecture = Architecture.Arm64, - Skip = "Flaky tests, see: https://github.com/dotnet/winforms/issues/6597")] + [WinFormsTheory] + [SkipOnArchitecture(TestArchitectures.Arm64, + "Flaky tests, see: https://github.com/dotnet/winforms/issues/6597")] [MemberData(nameof(ColumnHeadersHeight_SetWithParentWithHandle_TestData))] public void DataGridView_ColumnHeadersHeight_SetWithParentWithHandle_GetReturnsExpected(DataGridViewColumnHeadersHeightSizeMode columnHeadersWidthSizeMode, bool columnHeadersVisible, bool autoSize, int value, int expectedValue, int expectedInvalidatedCallCount, int expectedLayoutCallCount, int expectedParentLayoutCallCount) { @@ -530,8 +531,9 @@ public static IEnumerable ColumnHeadersHeightSizeMode_SetWithHandle_Te } [ActiveIssue("https://github.com/dotnet/winforms/issues/6597")] - [ConditionalWinFormsTheory(UnsupportedArchitecture = Architecture.Arm64, - Skip = "Flaky tests, see: https://github.com/dotnet/winforms/issues/6597")] + [WinFormsTheory] + [SkipOnArchitecture(TestArchitectures.Arm64, + "Flaky tests, see: https://github.com/dotnet/winforms/issues/6597")] [MemberData(nameof(ColumnHeadersHeightSizeMode_SetWithHandle_TestData))] public void DataGridView_ColumnHeadersHeightSizeMode_SetWithHandle_GetReturnsExpected(bool columnHeadersVisible, DataGridViewColumnHeadersHeightSizeMode value, int expectedColumnHeadersHeight, int expectedInvalidatedCallCount) { @@ -566,8 +568,9 @@ public void DataGridView_ColumnHeadersHeightSizeMode_SetWithHandle_GetReturnsExp } [ActiveIssue("https://github.com/dotnet/winforms/issues/6597")] - [ConditionalWinFormsTheory(UnsupportedArchitecture = Architecture.Arm64, - Skip = "Flaky tests, see: https://github.com/dotnet/winforms/issues/6597")] + [WinFormsTheory] + [SkipOnArchitecture(TestArchitectures.Arm64, + "Flaky tests, see: https://github.com/dotnet/winforms/issues/6597")] [InlineData(DataGridViewColumnHeadersHeightSizeMode.DisableResizing, DataGridViewColumnHeadersHeightSizeMode.AutoSize)] [InlineData(DataGridViewColumnHeadersHeightSizeMode.EnableResizing, DataGridViewColumnHeadersHeightSizeMode.AutoSize)] public void DataGridView_ColumnHeadersHeightSizeMode_SetNonResizeThenResize_RestoresOldValue(DataGridViewColumnHeadersHeightSizeMode originalColumnHeadersHeightSizeMode, DataGridViewColumnHeadersHeightSizeMode value) @@ -1474,8 +1477,9 @@ public static IEnumerable RowHeadersWidthSizeMode_SetWithHandle_TestDa } [ActiveIssue("https://github.com/dotnet/winforms/issues/6597")] - [ConditionalWinFormsTheory(UnsupportedArchitecture = Architecture.Arm64, - Skip = "Flaky tests, see: https://github.com/dotnet/winforms/issues/6597")] + [WinFormsTheory] + [SkipOnArchitecture(TestArchitectures.Arm64, + "Flaky tests, see: https://github.com/dotnet/winforms/issues/6597")] [MemberData(nameof(RowHeadersWidthSizeMode_SetWithHandle_TestData))] public void DataGridView_RowHeadersWidthSizeMode_SetWithHandle_GetReturnsExpected(bool rowHeadersVisible, DataGridViewRowHeadersWidthSizeMode value, int expectedRowHeadersWidth, int expectedInvalidatedCallCount) { @@ -1510,8 +1514,9 @@ public void DataGridView_RowHeadersWidthSizeMode_SetWithHandle_GetReturnsExpecte } [ActiveIssue("https://github.com/dotnet/winforms/issues/6597")] - [ConditionalWinFormsTheory(UnsupportedArchitecture = Architecture.Arm64, - Skip = "Flaky tests, see: https://github.com/dotnet/winforms/issues/6597")] + [WinFormsTheory] + [SkipOnArchitecture(TestArchitectures.Arm64, + "Flaky tests, see: https://github.com/dotnet/winforms/issues/6597")] [InlineData(DataGridViewRowHeadersWidthSizeMode.DisableResizing, DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders)] [InlineData(DataGridViewRowHeadersWidthSizeMode.DisableResizing, DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders)] [InlineData(DataGridViewRowHeadersWidthSizeMode.DisableResizing, DataGridViewRowHeadersWidthSizeMode.AutoSizeToFirstHeader)] @@ -2446,8 +2451,9 @@ public void DataGridView_OnRowHeadersWidthChanged_Invoke_CallsRowHeadersWidthCha } [ActiveIssue("https://github.com/dotnet/winforms/issues/6597")] - [ConditionalWinFormsTheory(UnsupportedArchitecture = Architecture.Arm64, - Skip = "Flaky tests, see: https://github.com/dotnet/winforms/issues/6597")] + [WinFormsTheory] + [SkipOnArchitecture(TestArchitectures.Arm64, + "Flaky tests, see: https://github.com/dotnet/winforms/issues/6597")] [MemberData(nameof(OnRowHeadersWidthChanged_TestData))] public void DataGridView_OnRowHeadersWidthChanged_InvokeWithHandle_CallsRowHeadersWidthChanged(DataGridViewRowHeadersWidthSizeMode rowHeadersWidthSizeMode, bool rowHeadersVisible, EventArgs eventArgs) { diff --git a/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/RichTextBoxTests.cs b/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/RichTextBoxTests.cs index ffb5a25cd2c..b730d3b14d8 100644 --- a/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/RichTextBoxTests.cs +++ b/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/RichTextBoxTests.cs @@ -6876,8 +6876,9 @@ public static IEnumerable RichTextBox_Text_GetWithHandle_TestData() // NOTE: do not convert this into a theory as it will run hundreds of tests // and with that will cycle through hundreds of UI controls. [ActiveIssue("https://github.com/dotnet/winforms/issues/6609")] - [ConditionalWinFormsFact(UnsupportedArchitecture = Architecture.X86, - Skip = "Flaky tests, see: https://github.com/dotnet/winforms/issues/6609")] + [WinFormsFact] + [SkipOnArchitecture(TestArchitectures.X86, + "Flaky tests, see: https://github.com/dotnet/winforms/issues/6609")] public void RichTextBox_Text_GetWithHandle_ReturnsExpected() { using (var control = new RichTextBox()) diff --git a/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/ToolStripTests.cs b/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/ToolStripTests.cs index 0a1060943da..897e8ad60a5 100644 --- a/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/ToolStripTests.cs +++ b/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/ToolStripTests.cs @@ -6,8 +6,8 @@ using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; -using Moq; using System.Windows.Forms.TestUtilities; +using Moq; using Xunit; using static Interop; @@ -7105,8 +7105,9 @@ public void ToolStrip_SetItemLocation_ItemHasDifferentParent_ThrowsNotSupportedE } [ActiveIssue("https://github.com/dotnet/winforms/issues/6610")] - [ConditionalWinFormsFact(UnsupportedArchitecture = Architecture.X86, - Skip = "Flaky tests, see: https://github.com/dotnet/winforms/issues/6610")] + [WinFormsFact] + [SkipOnArchitecture(TestArchitectures.X86, + "Flaky tests, see: https://github.com/dotnet/winforms/issues/6610")] public void ToolStrip_WndProc_InvokeMouseActivate_Success() { using var control = new SubToolStrip();