From fddc013fc29090578d198f457537568994647d46 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Sun, 7 Dec 2025 14:14:43 -0700 Subject: [PATCH 01/17] Opt into Microsoft Testing Platform (MTP) (#452) --- Directory.Packages.props | 5 +++ azure-pipelines/Merge-CodeCoverage.ps1 | 1 + global.json | 3 ++ test/Directory.Build.props | 1 + test/Directory.Build.targets | 6 +++ tools/artifacts/coverageResults.ps1 | 27 ++++++------- tools/artifacts/testResults.ps1 | 3 +- tools/dotnet-test-cloud.ps1 | 53 +++++++++++++++++++------- 8 files changed, 72 insertions(+), 27 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index d4cbbbb1c..56cc7c29c 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -4,12 +4,17 @@ true true + 1.9.1 + + + + diff --git a/azure-pipelines/Merge-CodeCoverage.ps1 b/azure-pipelines/Merge-CodeCoverage.ps1 index 308f57546..169bb175e 100644 --- a/azure-pipelines/Merge-CodeCoverage.ps1 +++ b/azure-pipelines/Merge-CodeCoverage.ps1 @@ -28,6 +28,7 @@ try { if ($reports) { $reports |% { $_.FullName } |% { # In addition to replacing {reporoot}, we also normalize on one kind of slash so that the report aggregates data for a file whether data was collected on Windows or not. + Write-Verbose "Processing $_" $xml = [xml](Get-Content -LiteralPath $_) $xml.coverage.packages.package.classes.class |? { $_.filename} |% { $_.filename = $_.filename.Replace('{reporoot}', $RepoRoot).Replace([IO.Path]::AltDirectorySeparatorChar, [IO.Path]::DirectorySeparatorChar) diff --git a/global.json b/global.json index 895d51bad..37a3146a2 100644 --- a/global.json +++ b/global.json @@ -3,5 +3,8 @@ "version": "10.0.100", "rollForward": "patch", "allowPrerelease": false + }, + "test": { + "runner": "Microsoft.Testing.Platform" } } diff --git a/test/Directory.Build.props b/test/Directory.Build.props index 6c7aa71dc..2b5b542d6 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -5,6 +5,7 @@ false true + true diff --git a/test/Directory.Build.targets b/test/Directory.Build.targets index 9f32cd061..8ec617e95 100644 --- a/test/Directory.Build.targets +++ b/test/Directory.Build.targets @@ -1,5 +1,11 @@ + + + + + + diff --git a/tools/artifacts/coverageResults.ps1 b/tools/artifacts/coverageResults.ps1 index 8c68216ed..1aadbb747 100644 --- a/tools/artifacts/coverageResults.ps1 +++ b/tools/artifacts/coverageResults.ps1 @@ -1,25 +1,26 @@ -$RepoRoot = [System.IO.Path]::GetFullPath("$PSScriptRoot\..\..") +$RepoRoot = Resolve-Path "$PSScriptRoot\..\.." -$coverageFiles = @(Get-ChildItem "$RepoRoot/test/*.cobertura.xml" -Recurse | Where {$_.FullName -notlike "*/In/*" -and $_.FullName -notlike "*\In\*" }) +$coverageFilesUnderRoot = @(Get-ChildItem "$RepoRoot/*.cobertura.xml" -Recurse | Where-Object {$_.FullName -notlike "*/In/*" -and $_.FullName -notlike "*\In\*" }) + +# Under MTP, coverage files are written directly to the artifacts output directory, +# so we need to look there too. +$ArtifactStagingFolder = & "$PSScriptRoot/../Get-ArtifactsStagingDirectory.ps1" +$directTestLogs = Join-Path $ArtifactStagingFolder test_logs +$coverageFilesUnderArtifacts = if (Test-Path $directTestLogs) { @(Get-ChildItem "$directTestLogs/*.cobertura.xml" -Recurse) } else { @() } # Prepare code coverage reports for merging on another machine -$repoRoot = $env:SYSTEM_DEFAULTWORKINGDIRECTORY -if (!$repoRoot) { $repoRoot = $env:GITHUB_WORKSPACE } -if ($repoRoot) { - Write-Host "Substituting $repoRoot with `"{reporoot}`"" - $coverageFiles |% { - $content = Get-Content -LiteralPath $_ |% { $_ -Replace [regex]::Escape($repoRoot), "{reporoot}" } - Set-Content -LiteralPath $_ -Value $content -Encoding UTF8 - } -} else { - Write-Warning "coverageResults: Cloud build not detected. Machine-neutral token replacement skipped." +Write-Host "Substituting $repoRoot with `"{reporoot}`"" +@($coverageFilesUnderRoot + $coverageFilesUnderArtifacts) |? { $_ }|% { + $content = Get-Content -LiteralPath $_ |% { $_ -Replace [regex]::Escape($repoRoot), "{reporoot}" } + Set-Content -LiteralPath $_ -Value $content -Encoding UTF8 } if (!((Test-Path $RepoRoot\bin) -and (Test-Path $RepoRoot\obj))) { return } @{ + $directTestLogs = $coverageFilesUnderArtifacts; $RepoRoot = ( - $coverageFiles + + $coverageFilesUnderRoot + (Get-ChildItem "$RepoRoot\obj\*.cs" -Recurse) ); } diff --git a/tools/artifacts/testResults.ps1 b/tools/artifacts/testResults.ps1 index 5310fb52a..a841967e8 100644 --- a/tools/artifacts/testResults.ps1 +++ b/tools/artifacts/testResults.ps1 @@ -4,7 +4,8 @@ Param( $result = @{} -$testRoot = Resolve-Path "$PSScriptRoot\..\..\test" +$RepoRoot = Resolve-Path "$PSScriptRoot\..\.." +$testRoot = Join-Path $RepoRoot test $result[$testRoot] = (Get-ChildItem "$testRoot\TestResults" -Recurse -Directory | Get-ChildItem -Recurse -File) $artifactStaging = & "$PSScriptRoot/../Get-ArtifactsStagingDirectory.ps1" diff --git a/tools/dotnet-test-cloud.ps1 b/tools/dotnet-test-cloud.ps1 index 02891d975..17fbe6c11 100644 --- a/tools/dotnet-test-cloud.ps1 +++ b/tools/dotnet-test-cloud.ps1 @@ -25,6 +25,7 @@ Param( $RepoRoot = (Resolve-Path "$PSScriptRoot/..").Path $ArtifactStagingFolder = & "$PSScriptRoot/Get-ArtifactsStagingDirectory.ps1" +$OnCI = ($env:CI -or $env:TF_BUILD) $dotnet = 'dotnet' if ($x86) { @@ -45,23 +46,49 @@ if ($x86) { } $testBinLog = Join-Path $ArtifactStagingFolder (Join-Path build_logs test.binlog) -$testDiagLog = Join-Path $ArtifactStagingFolder (Join-Path test_logs diag.log) +$testLogs = Join-Path $ArtifactStagingFolder test_logs -& $dotnet test $RepoRoot ` - --no-build ` - -c $Configuration ` - --filter "TestCategory!=FailsInCloudTest" ` - --collect "Code Coverage;Format=cobertura" ` - --settings "$PSScriptRoot/test.runsettings" ` - --blame-hang-timeout 60s ` - --blame-crash ` - -bl:"$testBinLog" ` - --diag "$testDiagLog;TraceLevel=info" ` - --logger trx ` +$globalJson = Get-Content $PSScriptRoot/../global.json | ConvertFrom-Json +$isMTP = $globalJson.test.runner -eq 'Microsoft.Testing.Platform' +if ($isMTP) { + $extraArgs = @() + if ($OnCI) { $extraArgs += '--no-progress' } + & $dotnet test --solution $RepoRoot ` + --no-build ` + -c $Configuration ` + -bl:"$testBinLog" ` + --filter-not-trait 'TestCategory=FailsInCloudTest' ` + --coverage ` + --coverage-output-format cobertura ` + --coverage-settings "$PSScriptRoot/test.runsettings" ` + --hangdump ` + --hangdump-timeout 60s ` + --crashdump ` + --diagnostic ` + --diagnostic-output-directory $testLogs ` + --diagnostic-verbosity Information ` + --results-directory $testLogs ` + --report-trx ` + @extraArgs +} else { + $testDiagLog = Join-Path $ArtifactStagingFolder (Join-Path test_logs diag.log) + & $dotnet test $RepoRoot ` + --no-build ` + -c $Configuration ` + --filter "TestCategory!=FailsInCloudTest" ` + --collect "Code Coverage;Format=cobertura" ` + --settings "$PSScriptRoot/test.runsettings" ` + --blame-hang-timeout 60s ` + --blame-crash ` + -bl:"$testBinLog" ` + --diag "$testDiagLog;TraceLevel=info" ` + --logger trx ` +} $unknownCounter = 0 Get-ChildItem -Recurse -Path $RepoRoot\test\*.trx |% { - Copy-Item $_ -Destination $ArtifactStagingFolder/test_logs/ + New-Item $testLogs -ItemType Directory -Force | Out-Null + Copy-Item $_ -Destination $testLogs if ($PublishResults) { $x = [xml](Get-Content -LiteralPath $_) From f761f0f7e50514cdb2b0b4b3b07fa3d298ff2eaf Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Sun, 7 Dec 2025 15:09:40 -0700 Subject: [PATCH 02/17] Push to nuget.org before pushing to github release This makes recovering a release from a nuget.org push failure easier. --- .github/workflows/release.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d2495c172..a4e4745a1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -64,6 +64,15 @@ jobs: run-id: ${{ steps.findrunid.outputs.runid }} github-token: ${{ github.token }} + - name: 🪪 Authorize NuGet package push + uses: NuGet/login@d22cc5f58ff5b88bf9bd452535b4335137e24544 # v1.1.0 + id: nuget-login + with: + user: ${{ secrets.NUGET_USER }} + + - name: 🚀 Push NuGet packages + run: dotnet nuget push ${{ runner.temp }}/deployables/*.nupkg --source https://api.nuget.org/v3/index.json -k '${{ steps.nuget-login.outputs.NUGET_API_KEY }}' + - name: 💽 Upload artifacts to release shell: pwsh if: ${{ github.event_name == 'release' && github.event.release.assets_url != '' }} @@ -74,12 +83,3 @@ jobs: Write-Host "Uploading $($_.Name) to release..." gh release -R ${{ github.repository }} upload "${{ github.ref_name }}" $_.FullName } - - - name: 🪪 Authorize NuGet package push - uses: NuGet/login@d22cc5f58ff5b88bf9bd452535b4335137e24544 # v1.1.0 - id: nuget-login - with: - user: ${{ secrets.NUGET_USER }} - - - name: 🚀 Push NuGet packages - run: dotnet nuget push ${{ runner.temp }}/deployables/*.nupkg --source https://api.nuget.org/v3/index.json -k '${{ steps.nuget-login.outputs.NUGET_API_KEY }}' From e4035601946447f2cb317003ebb600cf7df2742d Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Sun, 7 Dec 2025 15:59:57 -0700 Subject: [PATCH 03/17] Update to MTP v2 (#455) --- Directory.Packages.props | 6 +++--- test/Library.Tests/Library.Tests.csproj | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 56cc7c29c..80d105cfd 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -4,19 +4,19 @@ true true - 1.9.1 + 2.0.2 - + - + diff --git a/test/Library.Tests/Library.Tests.csproj b/test/Library.Tests/Library.Tests.csproj index 5cbc1e1f2..146335725 100644 --- a/test/Library.Tests/Library.Tests.csproj +++ b/test/Library.Tests/Library.Tests.csproj @@ -14,7 +14,7 @@ - + From a28d54057fd4e9d86d4130b3977354bdf1754fbb Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Sun, 7 Dec 2025 16:11:51 -0700 Subject: [PATCH 04/17] Update all MTP related packages at once (457) --- .github/renovate.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/renovate.json b/.github/renovate.json index c97d97791..79dba1e54 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -11,6 +11,10 @@ "matchPackageNames": ["xunit*"], "groupName": "xunit" }, + { + "matchPackageNames": ["Microsoft.Testing.Extensions.*"], + "groupName": "Microsoft Testing Platform" + }, { "matchDatasources": ["dotnet-version", "docker"], "matchDepNames": ["dotnet-sdk", "mcr.microsoft.com/dotnet/sdk"], From f355f008b2b164d1e1fa8ca120442b0bffcf06af Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Sun, 7 Dec 2025 16:15:02 -0700 Subject: [PATCH 05/17] Fix test result publishing to AzDO (458) --- tools/dotnet-test-cloud.ps1 | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tools/dotnet-test-cloud.ps1 b/tools/dotnet-test-cloud.ps1 index 17fbe6c11..9b48178c6 100644 --- a/tools/dotnet-test-cloud.ps1 +++ b/tools/dotnet-test-cloud.ps1 @@ -70,6 +70,8 @@ if ($isMTP) { --results-directory $testLogs ` --report-trx ` @extraArgs + + $trxFiles = Get-ChildItem -Recurse -Path $testLogs\*.trx } else { $testDiagLog = Join-Path $ArtifactStagingFolder (Join-Path test_logs diag.log) & $dotnet test $RepoRoot ` @@ -82,13 +84,17 @@ if ($isMTP) { --blame-crash ` -bl:"$testBinLog" ` --diag "$testDiagLog;TraceLevel=info" ` - --logger trx ` + --logger trx + + $trxFiles = Get-ChildItem -Recurse -Path $RepoRoot\test\*.trx } $unknownCounter = 0 -Get-ChildItem -Recurse -Path $RepoRoot\test\*.trx |% { +$trxFiles |% { New-Item $testLogs -ItemType Directory -Force | Out-Null - Copy-Item $_ -Destination $testLogs + if (!($_.FullName.StartsWith($testLogs))) { + Copy-Item $_ -Destination $testLogs + } if ($PublishResults) { $x = [xml](Get-Content -LiteralPath $_) From 3304d7930d87ac76dc060f80d5a89a233696e40c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Dec 2025 13:50:17 +0000 Subject: [PATCH 06/17] Update .NET SDK to v10.0.101 (#459) * Update mcr.microsoft.com/dotnet/sdk Docker tag to v10.0.101 * Bump .NET SDK --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Andrew Arnott --- .devcontainer/Dockerfile | 2 +- global.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 6637ad8ac..64f23a9eb 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # Refer to https://hub.docker.com/_/microsoft-dotnet-sdk for available versions -FROM mcr.microsoft.com/dotnet/sdk:10.0.100@sha256:c7445f141c04f1a6b454181bd098dcfa606c61ba0bd213d0a702489e5bd4cd71 +FROM mcr.microsoft.com/dotnet/sdk:10.0.101@sha256:d1823fecac3689a2eb959e02ee3bfe1c2142392808240039097ad70644566190 # Installing mono makes `dotnet test` work without errors even for net472. # But installing it takes a long time, so it's excluded by default. diff --git a/global.json b/global.json index 37a3146a2..a0ec2d8d9 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "10.0.100", + "version": "10.0.101", "rollForward": "patch", "allowPrerelease": false }, From 63de08696a81f2a8350910cd9c162e021f95a604 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 10 Dec 2025 08:48:27 -0700 Subject: [PATCH 07/17] Drop package dependencies that MTP does not require --- Directory.Packages.props | 2 -- test/Library.Tests/Library.Tests.csproj | 2 -- 2 files changed, 4 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 80d105cfd..098c7f090 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -10,12 +10,10 @@ - - diff --git a/test/Library.Tests/Library.Tests.csproj b/test/Library.Tests/Library.Tests.csproj index 146335725..e9e12e43a 100644 --- a/test/Library.Tests/Library.Tests.csproj +++ b/test/Library.Tests/Library.Tests.csproj @@ -12,8 +12,6 @@ - - From 70980c340965220736976b61c0880a1f914a3171 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Wed, 10 Dec 2025 14:22:58 -0700 Subject: [PATCH 08/17] Fix MTP test failure for MTP-incompatible projects under the test folder --- test/Directory.Build.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Directory.Build.targets b/test/Directory.Build.targets index 8ec617e95..839afb5d5 100644 --- a/test/Directory.Build.targets +++ b/test/Directory.Build.targets @@ -1,6 +1,6 @@ - + From 307d5e37fbf1fff5b2ce96d7154145d4aa80e676 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Thu, 11 Dec 2025 07:16:35 -0700 Subject: [PATCH 09/17] Fix testing regression from last commit --- test/Directory.Build.props | 1 + 1 file changed, 1 insertion(+) diff --git a/test/Directory.Build.props b/test/Directory.Build.props index 2b5b542d6..d7f919fb3 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -3,6 +3,7 @@ + true false true true From 5c9d6251b1074d83db4d18416828b2ccdba07eb9 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Thu, 11 Dec 2025 07:32:43 -0700 Subject: [PATCH 10/17] Adjust how we use IsTestProject This matches how MTP uses it internally. --- test/Directory.Build.props | 1 - test/Directory.Build.targets | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/test/Directory.Build.props b/test/Directory.Build.props index d7f919fb3..2b5b542d6 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -3,7 +3,6 @@ - true false true true diff --git a/test/Directory.Build.targets b/test/Directory.Build.targets index 839afb5d5..3758bb8c9 100644 --- a/test/Directory.Build.targets +++ b/test/Directory.Build.targets @@ -1,6 +1,6 @@ - + From c3770c5ce3215cbc649a28c19ab1905a1e092ef1 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Thu, 11 Dec 2025 09:02:49 -0700 Subject: [PATCH 11/17] All tests build 19 fail at runtime though. --- Directory.Packages.props | 8 --- .../ListOfOftenOne`1.cs | 4 -- .../WeakKeyDictionary`2.cs | 2 +- test/.editorconfig | 3 + test/Directory.Build.props | 1 - test/Directory.Packages.props | 14 +++++ test/IsolatedTestHost/App.config | 19 +------ test/IsolatedTestHost/Program.cs | 1 - .../Helpers/CSharpCodeFixVerifier`2+Test.cs | 2 +- .../VisualBasicCodeFixVerifier`2+Test.cs | 2 +- ...ualStudio.Threading.Analyzers.Tests.csproj | 3 +- ...UseSwitchToMainThreadAsyncAnalyzerTests.cs | 6 +- .../AssemblyInfo.cs | 2 - .../AsyncAutoResetEventTests.cs | 8 +-- .../AsyncBarrierTests.cs | 3 - .../AsyncCountdownEventTests.cs | 3 - .../AsyncCrossProcessMutexTests.cs | 3 - .../AsyncLazyInitializerTests.cs | 3 - .../AsyncLazyTests.cs | 9 +-- .../AsyncLocalTests.cs | 3 - .../AsyncManualResetEventTests.cs | 5 +- .../AsyncQueueTests.cs | 6 +- .../AsyncReaderWriterLockTests.cs | 21 +++---- .../AsyncReaderWriterResourceLockTests.cs | 3 - .../AsyncSemaphoreTests.cs | 3 - .../AwaitExtensionsTests.cs | 55 +++++++++---------- .../CancellationTokenExtensionsTests.cs | 3 - .../DelegatingJoinableTaskFactoryTests.cs | 7 +-- .../DispatcherExtensionsTests.cs | 2 - .../InternalUtilitiesTests.cs | 2 - ...inableTaskAndAsyncReaderWriterLockTests.cs | 3 - .../JoinableTaskCollectionTests.cs | 3 - .../JoinableTaskContextNodeTests.cs | 3 - .../JoinableTaskContextTests.cs | 3 - .../JoinableTaskFactoryTests.cs | 3 - .../JoinableTaskInternalsTests.cs | 3 - .../JoinableTaskTestBase.cs | 2 - .../JoinableTaskTests.cs | 15 ++--- .../JoinableTaskTokenTests.cs | 7 +-- .../ListOfOftenOneTests.cs | 15 ++--- ...rosoft.VisualStudio.Threading.Tests.csproj | 3 +- ...onConcurrentSynchronizationContextTests.cs | 5 -- .../ProgressWithCompletionTests.cs | 3 - .../RarelyRemoveItemSetTests.cs | 15 ++--- .../ReentrantSemaphoreJTFTests.cs | 3 - .../ReentrantSemaphoreNonJTFTests.cs | 3 - .../ReentrantSemaphoreTestBase.cs | 3 - ...ngleThreadedSynchronizationContextTests.cs | 3 - ...ingleThreadedTestSynchronizationContext.cs | 1 - .../TestBase.cs | 8 +-- .../TestBaseTests.cs | 15 ++--- .../TestUtilities.cs | 14 ++--- .../TestUtilitiesTests.cs | 2 - .../ThreadingToolsTests.cs | 5 +- .../TplExtensionsTests.cs | 5 +- .../Usings.cs | 5 ++ .../ValidityTests.cs | 2 - .../WeakKeyDictionaryTests.cs | 3 - 58 files changed, 113 insertions(+), 248 deletions(-) create mode 100644 test/Directory.Packages.props create mode 100644 test/Microsoft.VisualStudio.Threading.Tests/Usings.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index 55379f1bf..e1220977f 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -7,7 +7,6 @@ 2.0.2 2.0.208 3.11.0 - 4.13.0 1.1.2 3.11.0-beta1.25076.3 @@ -39,15 +38,8 @@ - - - - - - - diff --git a/src/Microsoft.VisualStudio.Threading/ListOfOftenOne`1.cs b/src/Microsoft.VisualStudio.Threading/ListOfOftenOne`1.cs index 6ff984ca1..2549aeb50 100644 --- a/src/Microsoft.VisualStudio.Threading/ListOfOftenOne`1.cs +++ b/src/Microsoft.VisualStudio.Threading/ListOfOftenOne`1.cs @@ -3,11 +3,7 @@ using System; using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; using System.Threading; -using System.Threading.Tasks; namespace Microsoft.VisualStudio.Threading; diff --git a/src/Microsoft.VisualStudio.Threading/WeakKeyDictionary`2.cs b/src/Microsoft.VisualStudio.Threading/WeakKeyDictionary`2.cs index 562d198aa..5f92e4cc7 100644 --- a/src/Microsoft.VisualStudio.Threading/WeakKeyDictionary`2.cs +++ b/src/Microsoft.VisualStudio.Threading/WeakKeyDictionary`2.cs @@ -214,7 +214,7 @@ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() /// internal bool Any() { - foreach (KeyValuePair.WeakReference, TValue> item in this.dictionary) + foreach (KeyValuePair, TValue> item in this.dictionary) { if (item.Key.IsAlive) { diff --git a/test/.editorconfig b/test/.editorconfig index 988129278..04701aea8 100644 --- a/test/.editorconfig +++ b/test/.editorconfig @@ -80,3 +80,6 @@ dotnet_diagnostic.SA1401.severity = silent # SA1133: Do not combine attributes dotnet_diagnostic.SA1133.severity = silent + +# xUnit1051: Use TestContext.Current.CancellationToken +dotnet_diagnostic.xUnit1051.severity = suggestion diff --git a/test/Directory.Build.props b/test/Directory.Build.props index 155b347a6..466be54e4 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -3,7 +3,6 @@ - true false true true diff --git a/test/Directory.Packages.props b/test/Directory.Packages.props new file mode 100644 index 000000000..6875d8235 --- /dev/null +++ b/test/Directory.Packages.props @@ -0,0 +1,14 @@ + + + + + + 4.13.0 + + + + + + + + diff --git a/test/IsolatedTestHost/App.config b/test/IsolatedTestHost/App.config index e5ab83a70..aed254391 100644 --- a/test/IsolatedTestHost/App.config +++ b/test/IsolatedTestHost/App.config @@ -1,29 +1,12 @@  - - - - - - + - - - - - - - - - - - - diff --git a/test/IsolatedTestHost/Program.cs b/test/IsolatedTestHost/Program.cs index 6712fa6e0..9cc72b4e0 100644 --- a/test/IsolatedTestHost/Program.cs +++ b/test/IsolatedTestHost/Program.cs @@ -7,7 +7,6 @@ using System.Reflection; using System.Threading; using System.Threading.Tasks; -using Xunit; namespace IsolatedTestHost; diff --git a/test/Microsoft.VisualStudio.Threading.Analyzers.Tests/Helpers/CSharpCodeFixVerifier`2+Test.cs b/test/Microsoft.VisualStudio.Threading.Analyzers.Tests/Helpers/CSharpCodeFixVerifier`2+Test.cs index 18ae7d018..b767fa30e 100644 --- a/test/Microsoft.VisualStudio.Threading.Analyzers.Tests/Helpers/CSharpCodeFixVerifier`2+Test.cs +++ b/test/Microsoft.VisualStudio.Threading.Analyzers.Tests/Helpers/CSharpCodeFixVerifier`2+Test.cs @@ -37,7 +37,7 @@ public Test() #if WINDOWS project = project.AddMetadataReference(MetadataReference.CreateFromFile(typeof(Dispatcher).Assembly.Location)); #else - Skip.If(true); + Assert.SkipWhen(true, "Windows only"); #endif } diff --git a/test/Microsoft.VisualStudio.Threading.Analyzers.Tests/Helpers/VisualBasicCodeFixVerifier`2+Test.cs b/test/Microsoft.VisualStudio.Threading.Analyzers.Tests/Helpers/VisualBasicCodeFixVerifier`2+Test.cs index 8793d3d8c..c3a1ef718 100644 --- a/test/Microsoft.VisualStudio.Threading.Analyzers.Tests/Helpers/VisualBasicCodeFixVerifier`2+Test.cs +++ b/test/Microsoft.VisualStudio.Threading.Analyzers.Tests/Helpers/VisualBasicCodeFixVerifier`2+Test.cs @@ -37,7 +37,7 @@ public Test() #if WINDOWS project = project.AddMetadataReference(MetadataReference.CreateFromFile(typeof(Dispatcher).Assembly.Location)); #else - Skip.If(true); + Assert.SkipWhen(true, "Windows only"); #endif } diff --git a/test/Microsoft.VisualStudio.Threading.Analyzers.Tests/Microsoft.VisualStudio.Threading.Analyzers.Tests.csproj b/test/Microsoft.VisualStudio.Threading.Analyzers.Tests/Microsoft.VisualStudio.Threading.Analyzers.Tests.csproj index 2bc4f8a7c..50bbac324 100644 --- a/test/Microsoft.VisualStudio.Threading.Analyzers.Tests/Microsoft.VisualStudio.Threading.Analyzers.Tests.csproj +++ b/test/Microsoft.VisualStudio.Threading.Analyzers.Tests/Microsoft.VisualStudio.Threading.Analyzers.Tests.csproj @@ -1,7 +1,7 @@  net8.0 - true + Exe true true $(NoWarn);NU1701 @@ -29,7 +29,6 @@ - /// Verifies that long-lived, uncanceled CancellationTokens do not result in leaking memory. /// - [SkippableFact(Skip = "It always fails after xunit 2.8 update.")] + [Fact(Skip = "It always fails after xunit 2.8 update.")] [Trait("GC", "true")] [Trait("TestCategory", "FailsInCloudTest")] public async Task WaitAsync_WithCancellationToken_DoesNotLeakWhenNotCanceled() @@ -222,7 +220,7 @@ public async Task WaitAsync_WithCancellationToken_DoesNotLeakWhenNotCanceled() /// /// Verifies that canceled CancellationTokens do not result in leaking memory. /// - [SkippableFact(Skip = "It always fails after xunit 2.8 update.")] + [Fact(Skip = "It always fails after xunit 2.8 update.")] [Trait("GC", "true")] [Trait("TestCategory", "FailsInCloudTest")] public async Task WaitAsync_WithCancellationToken_DoesNotLeakWhenCanceled() diff --git a/test/Microsoft.VisualStudio.Threading.Tests/AsyncBarrierTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/AsyncBarrierTests.cs index 5b9c48559..394cf5bee 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/AsyncBarrierTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/AsyncBarrierTests.cs @@ -6,9 +6,6 @@ using System.Threading; using System.Threading.Tasks; using Microsoft; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class AsyncBarrierTests : TestBase { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/AsyncCountdownEventTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/AsyncCountdownEventTests.cs index 7c9606aca..2ab242193 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/AsyncCountdownEventTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/AsyncCountdownEventTests.cs @@ -4,9 +4,6 @@ using System; using System.Threading; using System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class AsyncCountdownEventTests : TestBase { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/AsyncCrossProcessMutexTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/AsyncCrossProcessMutexTests.cs index 9c72d1d8a..8872ad9aa 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/AsyncCrossProcessMutexTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/AsyncCrossProcessMutexTests.cs @@ -4,9 +4,6 @@ using System; using System.Threading; using System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class AsyncCrossProcessMutexTests : TestBase, IDisposable { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/AsyncLazyInitializerTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/AsyncLazyInitializerTests.cs index 5c16ba2a6..69eb2dccd 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/AsyncLazyInitializerTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/AsyncLazyInitializerTests.cs @@ -4,9 +4,6 @@ using System; using System.Threading; using System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class AsyncLazyInitializerTests : TestBase { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/AsyncLazyTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/AsyncLazyTests.cs index 0c3e76a21..79fb5b395 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/AsyncLazyTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/AsyncLazyTests.cs @@ -8,11 +8,6 @@ using System.Threading.Tasks; using Microsoft; -using Microsoft.VisualStudio.Threading; - -using Xunit; -using Xunit.Abstractions; - using NamedSyncContext = AwaitExtensionsTests.NamedSyncContext; public class AsyncLazyTests : TestBase @@ -214,7 +209,7 @@ public async Task ValueFactoryReentersValueFactorySynchronously(bool specifyJtf) Assert.False(executed); executed = true; lazy!.GetValueAsync(); - return Task.FromResult(new object()); + return Task.FromResult(new object()); }, jtf); @@ -389,7 +384,7 @@ public void ToStringForUncreatedValue() [Fact] public async Task ToStringForCreatedValue() { - var lazy = new AsyncLazy(() => Task.FromResult(3)); + var lazy = new AsyncLazy(() => Task.FromResult(3)); int value = await lazy.GetValueAsync(); string result = lazy.ToString(); Assert.Equal(value.ToString(CultureInfo.InvariantCulture), result); diff --git a/test/Microsoft.VisualStudio.Threading.Tests/AsyncLocalTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/AsyncLocalTests.cs index eeb40ead3..0d0b63e88 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/AsyncLocalTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/AsyncLocalTests.cs @@ -7,9 +7,6 @@ using System.Reflection; using System.Threading; using System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class AsyncLocalTests : TestBase { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/AsyncManualResetEventTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/AsyncManualResetEventTests.cs index 3e774cf93..556bc7c20 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/AsyncManualResetEventTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/AsyncManualResetEventTests.cs @@ -4,9 +4,6 @@ using System; using System.Threading; using System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class AsyncManualResetEventTests : TestBase { @@ -21,7 +18,7 @@ public AsyncManualResetEventTests(ITestOutputHelper logger) [Fact] public void CtorDefaultParameter() { - Assert.False(new System.Threading.ManualResetEventSlim().IsSet); + Assert.False(new ManualResetEventSlim().IsSet); } [Fact] diff --git a/test/Microsoft.VisualStudio.Threading.Tests/AsyncQueueTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/AsyncQueueTests.cs index 65c5700df..c53a34c2c 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/AsyncQueueTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/AsyncQueueTests.cs @@ -6,14 +6,12 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; -using Xunit; public class AsyncQueueTests : TestBase { private AsyncQueue queue; - public AsyncQueueTests(Xunit.Abstractions.ITestOutputHelper logger) + public AsyncQueueTests(ITestOutputHelper logger) : base(logger) { this.queue = new AsyncQueue(); @@ -543,7 +541,7 @@ public void OnCompletedInvoked() Assert.Equal(1, invoked); } - [SkippableFact, Trait("GC", "true")] + [Fact, Trait("GC", "true")] [Trait("TestCategory", "FailsInCloudTest")] public void UnusedQueueGCPressure() { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/AsyncReaderWriterLockTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/AsyncReaderWriterLockTests.cs index 9944108c7..7cd96d1e2 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/AsyncReaderWriterLockTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/AsyncReaderWriterLockTests.cs @@ -9,9 +9,6 @@ using System.Threading; using System.Threading.Tasks; using Microsoft; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; using Xunit.Sdk; #pragma warning disable CA1416 // Validate platform compatibility @@ -230,7 +227,7 @@ public async Task CompleteMethodExecutesContinuationsAsynchronously() await continuation; } - [SkippableFact] + [Fact] [Trait("TestCategory", "FailsInCloudTest")] public async Task NoMemoryLeakForManyLocks() { @@ -3854,10 +3851,10 @@ public async Task MtaLockSharedWithMta() } /// Verifies that when an MTA holding a lock traverses (via CallContext) to an STA that the STA does not appear to hold a lock. - [SkippableFact] + [Fact] public async Task MtaLockNotSharedWithSta() { - Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + Assert.SkipUnless(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "Windows only"); using (await this.asyncLock.ReadLockAsync()) { var testComplete = new TaskCompletionSource(); @@ -3880,10 +3877,10 @@ public async Task MtaLockNotSharedWithSta() } /// Verifies that when an MTA holding a lock traverses (via CallContext) to an STA that the STA will be able to access the same lock by marshaling back to an MTA. - [SkippableFact] + [Fact] public async Task ReadLockTraversesAcrossSta() { - Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + Assert.SkipUnless(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "Windows only"); using (await this.asyncLock.ReadLockAsync()) { var testComplete = new TaskCompletionSource(); @@ -3920,10 +3917,10 @@ public async Task ReadLockTraversesAcrossSta() } /// Verifies that when an MTA holding a lock traverses (via CallContext) to an STA that the STA will be able to access the same lock by requesting it and moving back to an MTA. - [SkippableFact] + [Fact] public async Task UpgradeableReadLockTraversesAcrossSta() { - Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + Assert.SkipUnless(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "Windows only"); using (await this.asyncLock.UpgradeableReadLockAsync()) { @@ -3963,10 +3960,10 @@ public async Task UpgradeableReadLockTraversesAcrossSta() } /// Verifies that when an MTA holding a lock traverses (via CallContext) to an STA that the STA will be able to access the same lock by requesting it and moving back to an MTA. - [SkippableFact] + [Fact] public async Task WriteLockTraversesAcrossSta() { - Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + Assert.SkipUnless(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "Windows only"); using (await this.asyncLock.WriteLockAsync()) { var testComplete = new TaskCompletionSource(); diff --git a/test/Microsoft.VisualStudio.Threading.Tests/AsyncReaderWriterResourceLockTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/AsyncReaderWriterResourceLockTests.cs index 2b6fb8d15..da1e01462 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/AsyncReaderWriterResourceLockTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/AsyncReaderWriterResourceLockTests.cs @@ -7,9 +7,6 @@ using System.Threading; using System.Threading.Tasks; using Microsoft; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class AsyncReaderWriterResourceLockTests : TestBase { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/AsyncSemaphoreTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/AsyncSemaphoreTests.cs index 5265569a9..7a5ffd2b1 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/AsyncSemaphoreTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/AsyncSemaphoreTests.cs @@ -7,9 +7,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class AsyncSemaphoreTests : TestBase { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/AwaitExtensionsTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/AwaitExtensionsTests.cs index b2d5af6fb..1a8bad136 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/AwaitExtensionsTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/AwaitExtensionsTests.cs @@ -9,10 +9,7 @@ using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; using Microsoft.Win32; -using Xunit; -using Xunit.Abstractions; #pragma warning disable CA1416 // Validate platform compatibility @@ -383,10 +380,10 @@ public async Task WaitForExit_NullArgument() await Assert.ThrowsAsync(() => AwaitExtensions.WaitForExitAsync(null!)); } - [SkippableFact] + [Fact] public async Task WaitForExitAsync_ExitCode() { - Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + Assert.SkipUnless(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "Windows only"); Process p = Process.Start( new ProcessStartInfo("cmd.exe", "/c exit /b 55") { @@ -397,10 +394,10 @@ public async Task WaitForExitAsync_ExitCode() Assert.Equal(55, exitCode); } - [SkippableFact] + [Fact] public void WaitForExitAsync_AlreadyExited() { - Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + Assert.SkipUnless(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "Windows only"); Process p = Process.Start( new ProcessStartInfo("cmd.exe", "/c exit /b 55") { @@ -613,10 +610,10 @@ public async Task SyncContext_Awaiter() } } - [SkippableFact] + [Fact] public async Task AwaitRegKeyChange() { - Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + Assert.SkipUnless(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "Windows only"); using (var test = new RegKeyTest()) { Task changeWatcherTask = test.Key.WaitForChangeAsync(); @@ -626,10 +623,10 @@ public async Task AwaitRegKeyChange() } } - [SkippableFact] + [Fact] public async Task AwaitRegKeyChange_TwoAtOnce_SameKeyHandle() { - Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + Assert.SkipUnless(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "Windows only"); using (var test = new RegKeyTest()) { Task changeWatcherTask1 = test.Key.WaitForChangeAsync(); @@ -641,10 +638,10 @@ public async Task AwaitRegKeyChange_TwoAtOnce_SameKeyHandle() } } - [SkippableFact] + [Fact] public async Task AwaitRegKeyChange_NoChange() { - Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + Assert.SkipUnless(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "Windows only"); using (var test = new RegKeyTest()) { Task changeWatcherTask = test.Key.WaitForChangeAsync(cancellationToken: test.FinishedToken); @@ -656,10 +653,10 @@ public async Task AwaitRegKeyChange_NoChange() } } - [SkippableFact] + [Fact] public async Task AwaitRegKeyChange_WatchSubtree() { - Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + Assert.SkipUnless(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "Windows only"); using (var test = new RegKeyTest()) { using (RegistryKey? subKey = test.CreateSubKey()) @@ -671,10 +668,10 @@ public async Task AwaitRegKeyChange_WatchSubtree() } } - [SkippableFact] + [Fact] public async Task AwaitRegKeyChange_KeyDeleted() { - Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + Assert.SkipUnless(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "Windows only"); using (var test = new RegKeyTest()) { using (RegistryKey? subKey = test.CreateSubKey()) @@ -686,10 +683,10 @@ public async Task AwaitRegKeyChange_KeyDeleted() } } - [SkippableFact] + [Fact] public async Task AwaitRegKeyChange_NoWatchSubtree() { - Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + Assert.SkipUnless(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "Windows only"); using (var test = new RegKeyTest()) { using (RegistryKey? subKey = test.CreateSubKey()) @@ -705,10 +702,10 @@ public async Task AwaitRegKeyChange_NoWatchSubtree() } } - [SkippableFact] + [Fact] public async Task AwaitRegKeyChange_Canceled() { - Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + Assert.SkipUnless(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "Windows only"); using (var test = new RegKeyTest()) { var cts = new CancellationTokenSource(); @@ -727,10 +724,10 @@ public async Task AwaitRegKeyChange_Canceled() } } - [SkippableFact] + [Fact] public async Task AwaitRegKeyChange_KeyDisposedWhileWatching() { - Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + Assert.SkipUnless(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "Windows only"); Task watchingTask; using (var test = new RegKeyTest()) { @@ -741,10 +738,10 @@ public async Task AwaitRegKeyChange_KeyDisposedWhileWatching() await watchingTask; } - [SkippableFact] + [Fact] public async Task AwaitRegKeyChange_CanceledAndImmediatelyDisposed() { - Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + Assert.SkipUnless(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "Windows only"); Task watchingTask; CancellationToken expectedCancellationToken; using (var test = new RegKeyTest()) @@ -764,10 +761,10 @@ public async Task AwaitRegKeyChange_CanceledAndImmediatelyDisposed() } } - [SkippableFact] + [Fact] public async Task AwaitRegKeyChange_CallingThreadDestroyed() { - Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + Assert.SkipUnless(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "Windows only"); using (var test = new RegKeyTest()) { // Start watching and be certain the thread that started watching is destroyed. @@ -789,10 +786,10 @@ public async Task AwaitRegKeyChange_CallingThreadDestroyed() } } - [SkippableFact] + [Fact] public async Task AwaitRegKeyChange_DoesNotPreventAppTerminationOnWin7() { - Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + Assert.SkipUnless(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "Windows only"); string testExePath = Path.Combine( AppDomain.CurrentDomain.BaseDirectory!, "..", diff --git a/test/Microsoft.VisualStudio.Threading.Tests/CancellationTokenExtensionsTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/CancellationTokenExtensionsTests.cs index 5a957f05b..2d483b9ec 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/CancellationTokenExtensionsTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/CancellationTokenExtensionsTests.cs @@ -4,9 +4,6 @@ using System; using System.Linq; using System.Threading; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class CancellationTokenExtensionsTests : TestBase { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/DelegatingJoinableTaskFactoryTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/DelegatingJoinableTaskFactoryTests.cs index 9ca54fa96..2904d364d 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/DelegatingJoinableTaskFactoryTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/DelegatingJoinableTaskFactoryTests.cs @@ -7,9 +7,6 @@ using System.Threading; using System.Threading.Tasks; using Microsoft; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class DelegatingJoinableTaskFactoryTests : JoinableTaskTestBase { @@ -156,7 +153,7 @@ protected override void WaitSynchronously(Task task) base.WaitSynchronously(task); } - protected override void PostToUnderlyingSynchronizationContext(System.Threading.SendOrPostCallback callback, object state) + protected override void PostToUnderlyingSynchronizationContext(SendOrPostCallback callback, object state) { this.addToLog(FactoryLogEntry.InnerPostToUnderlyingSynchronizationContext); base.PostToUnderlyingSynchronizationContext(callback, state); @@ -196,7 +193,7 @@ protected override void WaitSynchronously(Task task) base.WaitSynchronously(task); } - protected override void PostToUnderlyingSynchronizationContext(System.Threading.SendOrPostCallback callback, object state) + protected override void PostToUnderlyingSynchronizationContext(SendOrPostCallback callback, object state) { this.addToLog(FactoryLogEntry.OuterPostToUnderlyingSynchronizationContext); base.PostToUnderlyingSynchronizationContext(callback, state); diff --git a/test/Microsoft.VisualStudio.Threading.Tests/DispatcherExtensionsTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/DispatcherExtensionsTests.cs index 49c05e0be..65d324840 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/DispatcherExtensionsTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/DispatcherExtensionsTests.cs @@ -9,8 +9,6 @@ using System.Windows.Threading; using Microsoft; using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class DispatcherExtensionsTests : JoinableTaskTestBase { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/InternalUtilitiesTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/InternalUtilitiesTests.cs index 5c8f3d75f..bec84f2c4 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/InternalUtilitiesTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/InternalUtilitiesTests.cs @@ -3,8 +3,6 @@ using System.Collections.Generic; using System.Linq; -using Microsoft.VisualStudio.Threading; -using Xunit; public class InternalUtilitiesTests { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskAndAsyncReaderWriterLockTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskAndAsyncReaderWriterLockTests.cs index 2c05ec10f..33a233bfc 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskAndAsyncReaderWriterLockTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskAndAsyncReaderWriterLockTests.cs @@ -3,9 +3,6 @@ using System; using System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class JoinableTaskAndAsyncReaderWriterLockTests : TestBase { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskCollectionTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskCollectionTests.cs index 02e3d8a7c..1cba90a05 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskCollectionTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskCollectionTests.cs @@ -4,9 +4,6 @@ using System; using System.Threading; using System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class JoinableTaskCollectionTests : JoinableTaskTestBase { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskContextNodeTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskContextNodeTests.cs index 156fc0aea..62393635a 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskContextNodeTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskContextNodeTests.cs @@ -5,9 +5,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class JoinableTaskContextNodeTests : JoinableTaskTestBase { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskContextTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskContextTests.cs index 2951b647c..b644fc158 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskContextTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskContextTests.cs @@ -8,9 +8,6 @@ using System.Threading.Tasks; using System.Xml.Linq; using Microsoft; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class JoinableTaskContextTests : JoinableTaskTestBase { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskFactoryTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskFactoryTests.cs index 47ba640e3..7f05a3d5b 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskFactoryTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskFactoryTests.cs @@ -3,9 +3,6 @@ using System; using System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class JoinableTaskFactoryTests : JoinableTaskTestBase { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskInternalsTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskInternalsTests.cs index 969fb62b9..d13235468 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskInternalsTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskInternalsTests.cs @@ -3,9 +3,6 @@ using System.Threading; using System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class JoinableTaskInternalsTests : JoinableTaskTestBase { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskTestBase.cs b/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskTestBase.cs index 8868d0ec6..f415f93ba 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskTestBase.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskTestBase.cs @@ -9,8 +9,6 @@ using System.Threading.Tasks; using System.Xml.Linq; using Microsoft; -using Microsoft.VisualStudio.Threading; -using Xunit.Abstractions; public abstract class JoinableTaskTestBase : TestBase { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskTests.cs index 15af17a7a..09013f9f0 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskTests.cs @@ -10,9 +10,6 @@ using System.Threading; using System.Threading.Tasks; using Microsoft; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class JoinableTaskTests : JoinableTaskTestBase { @@ -1934,7 +1931,7 @@ public void SynchronousTaskStackMaintainedCorrectly() { this.asyncPump.Run(async delegate { - this.asyncPump.Run(() => Task.FromResult(true)); + this.asyncPump.Run(() => Task.FromResult(true)); await Task.Yield(); }); } @@ -2236,7 +2233,7 @@ public void BeginAsyncWithResultOnMTAKicksOffOtherAsyncPumpWorkCanCompleteSynchr Assert.False(joinable.Task.IsCompleted); int result = joinable.Join(); - Assert.Equal(5, result); + Assert.Equal(5, result); Assert.True(taskFinished); Assert.True(joinable.Task.IsCompleted); } @@ -2268,7 +2265,7 @@ public void Join_AlreadyCompletedWithPrecanceledArgument() [Fact] public void Join_AlreadyCompletedWithPrecanceledArgument_Generic() { - JoinableTask jt = this.asyncPump.RunAsync(() => Task.FromResult(0)); + JoinableTask jt = this.asyncPump.RunAsync(() => Task.FromResult(0)); Assert.Throws(() => jt.Join(new CancellationToken(canceled: true))); } @@ -2282,7 +2279,7 @@ public async Task JoinAsync_AlreadyCompletedWithPrecanceledArgument() [Fact] public async Task JoinAsync_AlreadyCompletedWithPrecanceledArgument_Generic() { - JoinableTask jt = this.asyncPump.RunAsync(() => Task.FromResult(0)); + JoinableTask jt = this.asyncPump.RunAsync(() => Task.FromResult(0)); await Assert.ThrowsAsync(() => jt.JoinAsync(new CancellationToken(canceled: true))); } @@ -2977,7 +2974,7 @@ await loPriFactory.RunAsync(async delegate hiPriFactory.DoModalLoopTillEmptyAndTaskCompleted(outer.Task, this.TimeoutToken); } - [SkippableFact] + [Fact] public void NestedFactoriesCanBeCollected() { WeakReference weakOuterFactory = this.NestedFactoriesCanBeCollected_Helper(); @@ -4491,7 +4488,7 @@ private WeakReference NestedFactoriesCanBeCollected_Helper() }); outerFactory.DoModalLoopTillEmptyAndTaskCompleted(outer.Task, this.TimeoutToken); - Skip.IfNot(outer.IsCompleted, "this is a product defect, but this test assumes this works to test something else."); + Assert.SkipUnless(outer.IsCompleted, "this is a product defect, but this test assumes this works to test something else."); // Allow the dispatcher to drain all messages that may be holding references. SynchronizationContext.Current!.Post(s => this.testFrame.Continue = false, null); diff --git a/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskTokenTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskTokenTests.cs index 25c078496..7d2e07360 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskTokenTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskTokenTests.cs @@ -4,9 +4,6 @@ using System; using System.Threading; using System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class JoinableTaskTokenTests : JoinableTaskTestBase { @@ -171,7 +168,7 @@ public async Task RunAsyncOfT_AvoidsDeadlockWithParent(bool includeOtherContexts TaskCompletionSource tokenSource = new(); AsyncManualResetEvent releaseOuterTask = new(); - JoinableTask outerTask = this.asyncPump.RunAsync( + JoinableTask outerTask = this.asyncPump.RunAsync( async delegate { try @@ -199,7 +196,7 @@ async delegate this.Logger.WriteLine($"Token (modified): {token}"); } - JoinableTask innerTask = this.asyncPump.RunAsync( + JoinableTask innerTask = this.asyncPump.RunAsync( async delegate { await Task.Yield(); diff --git a/test/Microsoft.VisualStudio.Threading.Tests/ListOfOftenOneTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/ListOfOftenOneTests.cs index e9bf81f4b..539f88190 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/ListOfOftenOneTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/ListOfOftenOneTests.cs @@ -2,9 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Linq; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class ListOfOftenOneTests : TestBase { @@ -34,11 +31,11 @@ public void EnumerationOfOne() using (ListOfOftenOne.Enumerator enumerator = this.list.GetEnumerator()) { Assert.True(enumerator.MoveNext()); - Assert.Equal(1, enumerator.Current.Data); + Assert.Equal(1, enumerator.Current.Data); Assert.False(enumerator.MoveNext()); enumerator.Reset(); Assert.True(enumerator.MoveNext()); - Assert.Equal(1, enumerator.Current.Data); + Assert.Equal(1, enumerator.Current.Data); Assert.False(enumerator.MoveNext()); } } @@ -51,15 +48,15 @@ public void EnumerationOfTwo() using (ListOfOftenOne.Enumerator enumerator = this.list.GetEnumerator()) { Assert.True(enumerator.MoveNext()); - Assert.Equal(1, enumerator.Current.Data); + Assert.Equal(1, enumerator.Current.Data); Assert.True(enumerator.MoveNext()); - Assert.Equal(2, enumerator.Current.Data); + Assert.Equal(2, enumerator.Current.Data); Assert.False(enumerator.MoveNext()); enumerator.Reset(); Assert.True(enumerator.MoveNext()); - Assert.Equal(1, enumerator.Current.Data); + Assert.Equal(1, enumerator.Current.Data); Assert.True(enumerator.MoveNext()); - Assert.Equal(2, enumerator.Current.Data); + Assert.Equal(2, enumerator.Current.Data); Assert.False(enumerator.MoveNext()); } } diff --git a/test/Microsoft.VisualStudio.Threading.Tests/Microsoft.VisualStudio.Threading.Tests.csproj b/test/Microsoft.VisualStudio.Threading.Tests/Microsoft.VisualStudio.Threading.Tests.csproj index 31e88d642..d92df35cd 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/Microsoft.VisualStudio.Threading.Tests.csproj +++ b/test/Microsoft.VisualStudio.Threading.Tests/Microsoft.VisualStudio.Threading.Tests.csproj @@ -1,8 +1,8 @@  net8.0 + Exe true - true true true @@ -31,7 +31,6 @@ - diff --git a/test/Microsoft.VisualStudio.Threading.Tests/NonConcurrentSynchronizationContextTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/NonConcurrentSynchronizationContextTests.cs index 26afaae86..650a23f3b 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/NonConcurrentSynchronizationContextTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/NonConcurrentSynchronizationContextTests.cs @@ -2,14 +2,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using System.Collections.Generic; using System.Linq; -using System.Text; using System.Threading; using System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class NonConcurrentSynchronizationContextTests : TestBase { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/ProgressWithCompletionTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/ProgressWithCompletionTests.cs index f2dd306fc..41f1c29f3 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/ProgressWithCompletionTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/ProgressWithCompletionTests.cs @@ -5,9 +5,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class ProgressWithCompletionTests : TestBase { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/RarelyRemoveItemSetTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/RarelyRemoveItemSetTests.cs index fb4f79b14..d87d0c071 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/RarelyRemoveItemSetTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/RarelyRemoveItemSetTests.cs @@ -4,9 +4,6 @@ using System; using System.Linq; using System.Runtime.CompilerServices; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class RarelyRemoveItemSetTests : TestBase { @@ -36,11 +33,11 @@ public void EnumerationOfOne() using (RarelyRemoveItemSet.Enumerator enumerator = this.list.EnumerateAndClear().GetEnumerator()) { Assert.True(enumerator.MoveNext()); - Assert.Equal(1, enumerator.Current.Data); + Assert.Equal(1, enumerator.Current.Data); Assert.False(enumerator.MoveNext()); enumerator.Reset(); Assert.True(enumerator.MoveNext()); - Assert.Equal(1, enumerator.Current.Data); + Assert.Equal(1, enumerator.Current.Data); Assert.False(enumerator.MoveNext()); } } @@ -53,15 +50,15 @@ public void EnumerationOfTwo() using (RarelyRemoveItemSet.Enumerator enumerator = this.list.EnumerateAndClear().GetEnumerator()) { Assert.True(enumerator.MoveNext()); - Assert.Equal(1, enumerator.Current.Data); + Assert.Equal(1, enumerator.Current.Data); Assert.True(enumerator.MoveNext()); - Assert.Equal(2, enumerator.Current.Data); + Assert.Equal(2, enumerator.Current.Data); Assert.False(enumerator.MoveNext()); enumerator.Reset(); Assert.True(enumerator.MoveNext()); - Assert.Equal(1, enumerator.Current.Data); + Assert.Equal(1, enumerator.Current.Data); Assert.True(enumerator.MoveNext()); - Assert.Equal(2, enumerator.Current.Data); + Assert.Equal(2, enumerator.Current.Data); Assert.False(enumerator.MoveNext()); } } diff --git a/test/Microsoft.VisualStudio.Threading.Tests/ReentrantSemaphoreJTFTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/ReentrantSemaphoreJTFTests.cs index 7ec4ac0d8..6c001e1c2 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/ReentrantSemaphoreJTFTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/ReentrantSemaphoreJTFTests.cs @@ -6,9 +6,6 @@ using System.Threading; using System.Threading.Tasks; using Microsoft; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class ReentrantSemaphoreJTFTests : ReentrantSemaphoreTestBase { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/ReentrantSemaphoreNonJTFTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/ReentrantSemaphoreNonJTFTests.cs index 5a1ab9ebd..4935e0b64 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/ReentrantSemaphoreNonJTFTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/ReentrantSemaphoreNonJTFTests.cs @@ -2,9 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class ReentrantSemaphoreNonJTFTests : ReentrantSemaphoreTestBase { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/ReentrantSemaphoreTestBase.cs b/test/Microsoft.VisualStudio.Threading.Tests/ReentrantSemaphoreTestBase.cs index 8e58d4317..494de17d1 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/ReentrantSemaphoreTestBase.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/ReentrantSemaphoreTestBase.cs @@ -6,9 +6,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public abstract class ReentrantSemaphoreTestBase : TestBase, IDisposable { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/SingleThreadedSynchronizationContextTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/SingleThreadedSynchronizationContextTests.cs index 7cd17668d..7e9e5ec44 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/SingleThreadedSynchronizationContextTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/SingleThreadedSynchronizationContextTests.cs @@ -4,9 +4,6 @@ using System; using System.Reflection; using System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class SingleThreadedSynchronizationContextTests : TestBase { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/SingleThreadedTestSynchronizationContext.cs b/test/Microsoft.VisualStudio.Threading.Tests/SingleThreadedTestSynchronizationContext.cs index 6fd9f5646..0bd798d8a 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/SingleThreadedTestSynchronizationContext.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/SingleThreadedTestSynchronizationContext.cs @@ -8,7 +8,6 @@ using System.Diagnostics.CodeAnalysis; using System.Threading; using Microsoft; -using Microsoft.VisualStudio.Threading; #if UseWpfContext using System.Windows.Threading; #endif diff --git a/test/Microsoft.VisualStudio.Threading.Tests/TestBase.cs b/test/Microsoft.VisualStudio.Threading.Tests/TestBase.cs index 5b7b6ff4d..dd0422e78 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/TestBase.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/TestBase.cs @@ -8,9 +8,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; +using Xunit.Sdk; public abstract class TestBase { @@ -339,7 +337,7 @@ protected void ExecuteOnDispatcher(Func action) /// A task whose result is if test execution is already isolated and should therefore proceed with the body of the test, /// or after the isolated instance of the test has completed execution. /// - /// Thrown if the isolated test result is a Failure. + /// Thrown if the isolated test result is a Failure. /// Thrown if on a platform that we do not yet support test isolation on. protected Task ExecuteInIsolationAsync([CallerMemberName] string testMethodName = null!) { @@ -355,7 +353,7 @@ protected Task ExecuteInIsolationAsync([CallerMemberName] string testMetho /// if test execution is already isolated and should therefore proceed with the body of the test, /// or after the isolated instance of the test has completed execution. /// - /// Thrown if the isolated test result is a Failure. + /// Thrown if the isolated test result is a Failure. /// Thrown if on a platform that we do not yet support test isolation on. protected bool ExecuteInIsolation([CallerMemberName] string testMethodName = null!) { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/TestBaseTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/TestBaseTests.cs index 52853bcb0..26ef0eb7f 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/TestBaseTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/TestBaseTests.cs @@ -6,9 +6,6 @@ using System.Threading; using System.Threading.Tasks; using Microsoft; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; using Xunit.Sdk; public class TestBaseTests : TestBase @@ -18,10 +15,10 @@ public TestBaseTests(ITestOutputHelper logger) { } - [SkippableFact] + [Fact] public void ExecuteOnSTA_ExecutesDelegateOnSTA() { - Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + Assert.SkipUnless(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "Windows only"); bool executed = false; this.ExecuteOnSTA(delegate { @@ -32,10 +29,10 @@ public void ExecuteOnSTA_ExecutesDelegateOnSTA() Assert.True(executed); } - [SkippableFact] + [Fact] public void ExecuteOnSTA_PropagatesExceptions() { - Skip.IfNot(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); + Assert.SkipUnless(RuntimeInformation.IsOSPlatform(OSPlatform.Windows), "Windows only"); Assert.Throws(() => this.ExecuteOnSTA(() => { throw new ApplicationException(); @@ -90,7 +87,7 @@ public void ExecuteOnDispatcher_PropagatesExceptions() })); } - [SkippableFact] + [Fact] [Trait("TestCategory", "FailsInCloudTest")] public async Task ExecuteInIsolation_PassingTest() { @@ -100,7 +97,7 @@ public async Task ExecuteInIsolation_PassingTest() } } - [SkippableFact] + [Fact] public async Task ExecuteInIsolation_FailingTest() { bool executeHere; diff --git a/test/Microsoft.VisualStudio.Threading.Tests/TestUtilities.cs b/test/Microsoft.VisualStudio.Threading.Tests/TestUtilities.cs index 28844c1a1..53e7ed4ff 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/TestUtilities.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/TestUtilities.cs @@ -10,9 +10,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; +using Xunit.Sdk; internal static class TestUtilities { @@ -69,7 +67,7 @@ internal static T[] ConcurrencyTest(Func action, int concurrency = -1) concurrency = Environment.ProcessorCount; } - Skip.If(Environment.ProcessorCount < concurrency, $"The test machine does not have enough CPU cores to exercise a concurrency level of {concurrency}"); + Assert.SkipWhen(Environment.ProcessorCount < concurrency, $"The test machine does not have enough CPU cores to exercise a concurrency level of {concurrency}"); // We use a barrier to guarantee that all threads are fully ready to // execute the provided function at precisely the same time. @@ -170,7 +168,7 @@ internal static IDisposable StarveThreadpool() /// A task whose result is if test execution is already isolated and should therefore proceed with the body of the test, /// or after the isolated instance of the test has completed execution. /// - /// Thrown if the isolated test result is a Failure. + /// Thrown if the isolated test result is a Failure. /// Thrown if on a platform that we do not yet support test isolation on. internal static Task ExecuteInIsolationAsync(object testClass, string testMethodName, ITestOutputHelper logger) { @@ -189,7 +187,7 @@ internal static Task ExecuteInIsolationAsync(object testClass, string test /// A task whose result is if test execution is already isolated and should therefore proceed with the body of the test, /// or after the isolated instance of the test has completed execution. /// - /// Thrown if the isolated test result is a Failure. + /// Thrown if the isolated test result is a Failure. /// Thrown if on a platform that we do not yet support test isolation on. #pragma warning disable CA1801 // Review unused parameters internal static Task ExecuteInIsolationAsync(string testClassName, string testMethodName, ITestOutputHelper logger) @@ -248,7 +246,7 @@ internal static Task ExecuteInIsolationAsync(string testClassName, string switch (t.Result) { case IsolatedTestHost.ExitCode.TestSkipped: - throw new SkipException("Test skipped. See output of isolated task for details."); + throw SkipException.ForSkip("Test skipped. See output of isolated task for details."); case IsolatedTestHost.ExitCode.TestPassed: default: Assert.Equal(IsolatedTestHost.ExitCode.TestPassed, t.Result); @@ -259,7 +257,7 @@ internal static Task ExecuteInIsolationAsync(string testClassName, string }, TaskScheduler.Default); #else - return Task.FromException(new SkipException("Test isolation is not yet supported on this platform.")); + return Task.FromException(SkipException.ForSkip("Test isolation is not yet supported on this platform.")); #endif } diff --git a/test/Microsoft.VisualStudio.Threading.Tests/TestUtilitiesTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/TestUtilitiesTests.cs index 109fb3b6c..82a530f1d 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/TestUtilitiesTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/TestUtilitiesTests.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; -using Xunit; public class TestUtilitiesTests { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/ThreadingToolsTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/ThreadingToolsTests.cs index aec072c82..a670da2c9 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/ThreadingToolsTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/ThreadingToolsTests.cs @@ -5,9 +5,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; public class ThreadingToolsTests : TestBase { @@ -118,7 +115,7 @@ public void WithCancellationOfPrecanceledTaskOfT() Assert.Same(tcs.Task, tcs.Task.WithCancellation(cts.Token)); } - [SkippableFact] + [Fact] public void WithCancellationAndPrecancelledToken() { var tcs = new TaskCompletionSource(); diff --git a/test/Microsoft.VisualStudio.Threading.Tests/TplExtensionsTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/TplExtensionsTests.cs index aa241bd84..4d0429637 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/TplExtensionsTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/TplExtensionsTests.cs @@ -6,9 +6,6 @@ using System.Threading; using System.Threading.Tasks; using System.Threading.Tasks.Sources; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; using TplExtensions = Microsoft.VisualStudio.Threading.TplExtensions; public class TplExtensionsTests : TestBase @@ -1077,7 +1074,7 @@ public void WithTimeout_MinusOneMeansInfiniteTimeout(bool generic) { var tcs = new TaskCompletionSource(); Task? timeoutTask = generic - ? TplExtensions.WithTimeout(tcs.Task, TimeSpan.FromMilliseconds(-1)) + ? TplExtensions.WithTimeout(tcs.Task, TimeSpan.FromMilliseconds(-1)) : TplExtensions.WithTimeout((Task)tcs.Task, TimeSpan.FromMilliseconds(-1)); Assert.False(timeoutTask.IsCompleted); await Task.Delay(AsyncDelay / 2); diff --git a/test/Microsoft.VisualStudio.Threading.Tests/Usings.cs b/test/Microsoft.VisualStudio.Threading.Tests/Usings.cs new file mode 100644 index 000000000..f10604229 --- /dev/null +++ b/test/Microsoft.VisualStudio.Threading.Tests/Usings.cs @@ -0,0 +1,5 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +global using Microsoft.VisualStudio.Threading; +global using Xunit; diff --git a/test/Microsoft.VisualStudio.Threading.Tests/ValidityTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/ValidityTests.cs index 8af8ab8dc..176e1de45 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/ValidityTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/ValidityTests.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Reflection; -using Microsoft.VisualStudio.Threading; -using Xunit; public class ValidityTests { diff --git a/test/Microsoft.VisualStudio.Threading.Tests/WeakKeyDictionaryTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/WeakKeyDictionaryTests.cs index 9c8e17dcf..c533a47cd 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/WeakKeyDictionaryTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/WeakKeyDictionaryTests.cs @@ -5,9 +5,6 @@ using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; -using Microsoft.VisualStudio.Threading; -using Xunit; -using Xunit.Abstractions; /// /// Tests for the weak dictionary class. From adf181af9f7b74803b0eee39c9af47d427b803ac Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Thu, 11 Dec 2025 09:13:19 -0700 Subject: [PATCH 12/17] Fix tests that fail due to Xunit's trace assertion failure listener --- .../TestUtilities.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/Microsoft.VisualStudio.Threading.Tests/TestUtilities.cs b/test/Microsoft.VisualStudio.Threading.Tests/TestUtilities.cs index 53e7ed4ff..1c7872500 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/TestUtilities.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/TestUtilities.cs @@ -92,11 +92,10 @@ internal static T[] ConcurrencyTest(Func action, int concurrency = -1) internal static DebugAssertionRevert DisableAssertionDialog() { #if NETFRAMEWORK - DefaultTraceListener? listener = Debug.Listeners.OfType().FirstOrDefault(); - if (listener is object) - { - listener.AssertUiEnabled = false; - } + Debug.Listeners.OfType().FirstOrDefault()?.AssertUiEnabled = false; + + // Xunit v3 adds a listener that throws on assertions; remove it so we can test actual runtime functionality of the library. + Debug.Listeners.Remove("xUnit.net"); #else Trace.Listeners.Clear(); #endif From fb63f88c9f6b54cf6b042ab7a31c5b7eb0e5c536 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Thu, 11 Dec 2025 09:18:32 -0700 Subject: [PATCH 13/17] Adapt to Xunit removing its `AsyncTestContext` SynchronizationContext --- .../AsyncReaderWriterLockTests.cs | 44 ++++++++++--------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/test/Microsoft.VisualStudio.Threading.Tests/AsyncReaderWriterLockTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/AsyncReaderWriterLockTests.cs index 7cd96d1e2..c62e537ab 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/AsyncReaderWriterLockTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/AsyncReaderWriterLockTests.cs @@ -4379,30 +4379,34 @@ public async Task ReadLockAsync_OnCompleted_CapturesExecutionContext() [Fact] public async Task ReadLockAsync_UnsafeOnCompleted_DoesNotCaptureExecutionContext() { - var asyncLocal = new Microsoft.VisualStudio.Threading.AsyncLocal(); - asyncLocal.Value = "expected"; - AsyncReaderWriterLock.Awaiter? awaiter = this.asyncLock.ReadLockAsync().GetAwaiter(); - Assumes.False(awaiter.IsCompleted); - var testResultSource = new TaskCompletionSource(); - awaiter.UnsafeOnCompleted(delegate + // Apply some SynchronizationContext to ensure the issued lock will require us to yield. + using (new SynchronizationContext().Apply(checkForChangesOnRevert: false)) { - try + var asyncLocal = new Microsoft.VisualStudio.Threading.AsyncLocal(); + asyncLocal.Value = "expected"; + AsyncReaderWriterLock.Awaiter? awaiter = this.asyncLock.ReadLockAsync().GetAwaiter(); + Assumes.False(awaiter.IsCompleted); + TaskCompletionSource testResultSource = new(TaskCreationOptions.RunContinuationsAsynchronously); + awaiter.UnsafeOnCompleted(delegate { - using (awaiter.GetResult()) + try { - Assert.Null(asyncLocal.Value); - testResultSource.SetResult(null); + using (awaiter.GetResult()) + { + Assert.Null(asyncLocal.Value); + testResultSource.SetResult(null); + } } - } - catch (Exception ex) - { - testResultSource.SetException(ex); - } - finally - { - } - }); - await testResultSource.Task; + catch (Exception ex) + { + testResultSource.SetException(ex); + } + finally + { + } + }); + await testResultSource.Task; + } } [Fact(Skip = "Disabled after dependency updates introduced failures. See https://dev.azure.com/devdiv/DevDiv/_workitems/edit/1974921")] From 887c2dfea7241082f8d324900ba48ea522b592bc Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Thu, 11 Dec 2025 09:50:59 -0700 Subject: [PATCH 14/17] Adapt IsolatedTestHost to xunit.v3 --- Directory.Packages.props | 2 +- test/IsolatedTestHost/IsolatedTestHost.csproj | 3 ++- test/IsolatedTestHost/Program.cs | 3 +-- test/IsolatedTestHost/TestOutputHelper.cs | 25 +++++++++++-------- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index e1220977f..2cf97ec8a 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -36,7 +36,7 @@ - + diff --git a/test/IsolatedTestHost/IsolatedTestHost.csproj b/test/IsolatedTestHost/IsolatedTestHost.csproj index b5b95cf1e..353005b37 100644 --- a/test/IsolatedTestHost/IsolatedTestHost.csproj +++ b/test/IsolatedTestHost/IsolatedTestHost.csproj @@ -3,10 +3,11 @@ Exe net472 + false - + diff --git a/test/IsolatedTestHost/Program.cs b/test/IsolatedTestHost/Program.cs index 9cc72b4e0..a20655442 100644 --- a/test/IsolatedTestHost/Program.cs +++ b/test/IsolatedTestHost/Program.cs @@ -52,8 +52,7 @@ private static ExitCode MyMain(string assemblyFile, string testClassName, string } bool fact = testMethod.GetCustomAttributesData().Any(a => a.AttributeType.Name == "FactAttribute"); - bool skippableFact = testMethod.GetCustomAttributesData().Any(a => a.AttributeType.Name == "SkippableFactAttribute"); - if (fact || skippableFact) + if (fact) { return ExecuteTest(testClass, testMethod); } diff --git a/test/IsolatedTestHost/TestOutputHelper.cs b/test/IsolatedTestHost/TestOutputHelper.cs index b27c20f25..f91502ede 100644 --- a/test/IsolatedTestHost/TestOutputHelper.cs +++ b/test/IsolatedTestHost/TestOutputHelper.cs @@ -1,20 +1,23 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; -using Xunit.Abstractions; +using System.Globalization; +using System.Text; +using Xunit; namespace IsolatedTestHost; internal class TestOutputHelper : ITestOutputHelper { - public void WriteLine(string message) - { - Console.WriteLine(message); - } - - public void WriteLine(string format, params object[] args) - { - Console.WriteLine(format, args); - } + private readonly StringBuilder builder = new(); + + public string Output => this.builder.ToString(); + + public void Write(string message) => this.builder.Append(message); + + public void Write(string format, params object[] args) => this.builder.AppendFormat(format, args); + + public void WriteLine(string message) => this.builder.AppendLine(message); + + public void WriteLine(string format, params object[] args) => this.builder.AppendLine(string.Format(CultureInfo.CurrentCulture, format, args)); } From c9c1f37cca969adac2e17550212faa356e03f86d Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Thu, 11 Dec 2025 10:49:16 -0700 Subject: [PATCH 15/17] Improve test stability (JoinAsyncShouldCompleteWithoutUIThreadAfterCancellation) --- .../Microsoft.VisualStudio.Threading.Tests/JoinableTaskTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskTests.cs b/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskTests.cs index 09013f9f0..7264640fc 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskTests.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/JoinableTaskTests.cs @@ -3762,7 +3762,7 @@ public void JoinAsyncShouldCompleteWithoutUIThreadAfterCancellation() // We expect to be able to block on the UI thread and the Task complete. // In completing, it will throw a TaskCanceledException, wrapped by an // AggregateException. If it 'hangs', it will timeout, returning false. - Assert.Throws(() => joinTask.Wait(AsyncDelay)); + Assert.Throws(() => joinTask.Wait(UnexpectedTimeout)); } [Fact] From d29bfbe309d0cc772dec94c2ea80f3f146f63671 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Thu, 11 Dec 2025 11:11:03 -0700 Subject: [PATCH 16/17] Extend test timeout We have a test failing in 8 seconds when the timeout was set to 10. Trying 15 in an effort to give the tests enough time. --- test/Microsoft.VisualStudio.Threading.Tests/TestBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Microsoft.VisualStudio.Threading.Tests/TestBase.cs b/test/Microsoft.VisualStudio.Threading.Tests/TestBase.cs index dd0422e78..d3a837504 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests/TestBase.cs +++ b/test/Microsoft.VisualStudio.Threading.Tests/TestBase.cs @@ -20,7 +20,7 @@ public abstract class TestBase /// The maximum length of time to wait for something that we expect will happen /// within the timeout. /// - protected static readonly TimeSpan UnexpectedTimeout = Debugger.IsAttached ? Timeout.InfiniteTimeSpan : TimeSpan.FromSeconds(10); + protected static readonly TimeSpan UnexpectedTimeout = Debugger.IsAttached ? Timeout.InfiniteTimeSpan : TimeSpan.FromSeconds(15); /// /// The maximum length of time to wait for something that we do not expect will happen From f7daee0eb20ad14dfe2c5a424b883969c7992ae9 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Thu, 11 Dec 2025 11:59:22 -0700 Subject: [PATCH 17/17] Fix MTP test run error --- ...osoft.VisualStudio.Threading.Tests.Win7RegistryWatcher.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/test/Microsoft.VisualStudio.Threading.Tests.Win7RegistryWatcher/Microsoft.VisualStudio.Threading.Tests.Win7RegistryWatcher.csproj b/test/Microsoft.VisualStudio.Threading.Tests.Win7RegistryWatcher/Microsoft.VisualStudio.Threading.Tests.Win7RegistryWatcher.csproj index 849497670..6029916ee 100644 --- a/test/Microsoft.VisualStudio.Threading.Tests.Win7RegistryWatcher/Microsoft.VisualStudio.Threading.Tests.Win7RegistryWatcher.csproj +++ b/test/Microsoft.VisualStudio.Threading.Tests.Win7RegistryWatcher/Microsoft.VisualStudio.Threading.Tests.Win7RegistryWatcher.csproj @@ -2,6 +2,7 @@ net472 Exe + false