From 677cb908ddff8bbb420ed0161fe361edfb2fa8ae Mon Sep 17 00:00:00 2001 From: Ian Griffiths Date: Tue, 4 Nov 2025 07:46:54 +0000 Subject: [PATCH 1/3] Further .NET 9.0 SDK updates * Use 9.0 on integration test CI stage * fix some additional diagnostics that have appeared recently --- .editorconfig | 8 ++++++- Rx.NET/Source/CodeCoverage.runsettings | 3 ++- Rx.NET/Source/Directory.build.props | 8 ++----- Rx.NET/Source/Directory.build.targets | 2 +- .../Benchmarks.System.Reactive/Program.cs | 4 ++++ ...ts.System.Reactive.Uwp.DeviceRunner.csproj | 12 +++++++++++ .../TestConfiguration.cs | 7 +++++++ .../Tests.System.Reactive.csproj | 7 +++++++ .../Concurrency/EventLoopSchedulerTest.cs | 1 + .../Tests/Linq/Observable/ObserveOnTest.cs | 1 + .../Tests/Linq/Observable/RefCountTest.cs | 8 +++---- .../ResetExceptionDispatchStateTest.cs | 4 ++-- .../Tests/Linq/Observable/SelectManyTest.cs | 2 ++ azure-pipelines.rx.yml | 21 +++++++++++++------ 14 files changed, 67 insertions(+), 21 deletions(-) create mode 100644 Rx.NET/Source/tests/Tests.System.Reactive/TestConfiguration.cs diff --git a/.editorconfig b/.editorconfig index 9459379a4b..386bc6c6ff 100644 --- a/.editorconfig +++ b/.editorconfig @@ -258,4 +258,10 @@ csharp_space_between_square_brackets = false dotnet_diagnostic.IDE0290.severity = none # Namespace style. -csharp_style_namespace_declarations = block_scoped \ No newline at end of file +csharp_style_namespace_declarations = block_scoped +dotnet_diagnostic.IDE0290.severity = none + +# Target-typed new expressions +# We will probably adopt these at some point, but for some reason the IDE only just started complaining about them, +# and I don't want to deal with all these while in the middle of the Slight Deunification. +dotnet_diagnostic.IDE0090.severity = none diff --git a/Rx.NET/Source/CodeCoverage.runsettings b/Rx.NET/Source/CodeCoverage.runsettings index 66e63003bc..a5298935e1 100644 --- a/Rx.NET/Source/CodeCoverage.runsettings +++ b/Rx.NET/Source/CodeCoverage.runsettings @@ -5,7 +5,8 @@ Workaround for failure to run tests on .NET FX on v3.3.1 MSTest packages --> - True + True + STA diff --git a/Rx.NET/Source/Directory.build.props b/Rx.NET/Source/Directory.build.props index 505b9863f1..99d2cba05e 100644 --- a/Rx.NET/Source/Directory.build.props +++ b/Rx.NET/Source/Directory.build.props @@ -32,11 +32,6 @@ - - $(NoWarn);CA1001;CA2213;CA1510;CA1513;IDE0028;IDE0056;IDE0057;IDE0130;IDE0290;IDE0305;IDE0306 + $(NoWarn);CA1001;CA2213;CA1510;CA1512;CA1513;IDE0028;IDE0056;IDE0057;IDE0130;IDE0290;IDE0305;IDE0306 diff --git a/Rx.NET/Source/Directory.build.targets b/Rx.NET/Source/Directory.build.targets index e68f1e5883..b3456f8d7e 100644 --- a/Rx.NET/Source/Directory.build.targets +++ b/Rx.NET/Source/Directory.build.targets @@ -5,7 +5,7 @@ $(AssemblyName) ($(TargetFramework)) - + $(DefineConstants);HAS_WINFORMS;HAS_WPF;HAS_WINRT;HAS_DISPATCHER;HAS_REMOTING;DESKTOPCLR;NO_NULLABLE_ATTRIBUTES diff --git a/Rx.NET/Source/benchmarks/Benchmarks.System.Reactive/Program.cs b/Rx.NET/Source/benchmarks/Benchmarks.System.Reactive/Program.cs index 51d1534481..ca80b785c3 100644 --- a/Rx.NET/Source/benchmarks/Benchmarks.System.Reactive/Program.cs +++ b/Rx.NET/Source/benchmarks/Benchmarks.System.Reactive/Program.cs @@ -6,6 +6,10 @@ using System.Reactive.Linq; using BenchmarkDotNet.Running; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +[assembly:DoNotParallelize] // Not really a test project, but the build tools think we are, and complain if we don't state our parallelization policy. + namespace Benchmarks.System.Reactive { internal class Program diff --git a/Rx.NET/Source/tests/Tests.System.Reactive.Uwp.DeviceRunner/Tests.System.Reactive.Uwp.DeviceRunner.csproj b/Rx.NET/Source/tests/Tests.System.Reactive.Uwp.DeviceRunner/Tests.System.Reactive.Uwp.DeviceRunner.csproj index ce955e3533..02263a1685 100644 --- a/Rx.NET/Source/tests/Tests.System.Reactive.Uwp.DeviceRunner/Tests.System.Reactive.Uwp.DeviceRunner.csproj +++ b/Rx.NET/Source/tests/Tests.System.Reactive.Uwp.DeviceRunner/Tests.System.Reactive.Uwp.DeviceRunner.csproj @@ -147,6 +147,18 @@ + + + + MSBuild:Compile diff --git a/Rx.NET/Source/tests/Tests.System.Reactive/TestConfiguration.cs b/Rx.NET/Source/tests/Tests.System.Reactive/TestConfiguration.cs new file mode 100644 index 0000000000..f1a196956b --- /dev/null +++ b/Rx.NET/Source/tests/Tests.System.Reactive/TestConfiguration.cs @@ -0,0 +1,7 @@ +// 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 Microsoft.VisualStudio.TestTools.UnitTesting; + +[assembly:Parallelize] diff --git a/Rx.NET/Source/tests/Tests.System.Reactive/Tests.System.Reactive.csproj b/Rx.NET/Source/tests/Tests.System.Reactive/Tests.System.Reactive.csproj index 47e6fbe1d9..d16de1d369 100644 --- a/Rx.NET/Source/tests/Tests.System.Reactive/Tests.System.Reactive.csproj +++ b/Rx.NET/Source/tests/Tests.System.Reactive/Tests.System.Reactive.csproj @@ -41,4 +41,11 @@ + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + \ No newline at end of file diff --git a/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Concurrency/EventLoopSchedulerTest.cs b/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Concurrency/EventLoopSchedulerTest.cs index 9b1a85209c..ccb2c7d6d8 100644 --- a/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Concurrency/EventLoopSchedulerTest.cs +++ b/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Concurrency/EventLoopSchedulerTest.cs @@ -20,6 +20,7 @@ namespace ReactiveTests.Tests { [TestClass] + [DoNotParallelize] // We've observed hangs since enabling concurrent test execution. public class EventLoopSchedulerTest { private static readonly TimeSpan MaxWaitTime = TimeSpan.FromSeconds(10); diff --git a/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Linq/Observable/ObserveOnTest.cs b/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Linq/Observable/ObserveOnTest.cs index aecd7d5a15..23b4b70b12 100644 --- a/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Linq/Observable/ObserveOnTest.cs +++ b/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Linq/Observable/ObserveOnTest.cs @@ -27,6 +27,7 @@ namespace ReactiveTests.Tests { [TestClass] + [DoNotParallelize] // We've observed hangs since enabling concurrent test execution. public class ObserveOnTest : TestBase { #region + TestBase + diff --git a/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Linq/Observable/RefCountTest.cs b/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Linq/Observable/RefCountTest.cs index 8d41ea556a..503c05203d 100644 --- a/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Linq/Observable/RefCountTest.cs +++ b/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Linq/Observable/RefCountTest.cs @@ -348,14 +348,14 @@ public void RefCount_NoDelay_SourceCompletesWithNoValuesInConnect() var connectable = new SerialSingleNotificationConnectable(Notification.CreateOnCompleted()); var refCount = connectable.RefCount(); - var s1 = refCount.Subscribe(); + _ = refCount.Subscribe(); Assert.Equal(1, connectable.Connections.Count); // Since the source immediately completed, the RefCount goes back to zero subscribers // inside the call to Connect, so we expect to be disconnected. Assert.True(connectable.Connections[0].Disposed); - var s2 = refCount.Subscribe(); + _ = refCount.Subscribe(); Assert.Equal(2, connectable.Connections.Count); Assert.True(connectable.Connections[1].Disposed); } @@ -384,10 +384,10 @@ public void RefCount_NoDelay_minObservers_SourceCompletesWithNoValuesInConnect() // We're now back in the initial disconnected state, so nothing more should // happen until we get up to minObservers. - var s3 = refCount.Subscribe(); + _ = refCount.Subscribe(); Assert.Equal(1, connectable.Connections.Count); - var s4 = refCount.Subscribe(); + _ = refCount.Subscribe(); Assert.Equal(2, connectable.Connections.Count); Assert.True(connectable.Connections[1].Disposed); } diff --git a/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Linq/Observable/ResetExceptionDispatchStateTest.cs b/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Linq/Observable/ResetExceptionDispatchStateTest.cs index 9593bcc22b..9203b6fa0a 100644 --- a/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Linq/Observable/ResetExceptionDispatchStateTest.cs +++ b/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Linq/Observable/ResetExceptionDispatchStateTest.cs @@ -22,7 +22,7 @@ public async Task ResetExceptionDispatchState_Throw_Consistent_StackTrace_On_Awa var ts = Observable.Throw(new Exception("Aaargh!")).ResetExceptionDispatchState(); string stackTrace = null; - for (int i = 0; i < 3; i++) + for (var i = 0; i < 3; i++) { try { @@ -50,7 +50,7 @@ public async Task ResetExceptionDispatchState_Replay_Consistent_StackTrace_On_Aw var ts = cts.ResetExceptionDispatchState(); string stackTrace = null; - for (int i = 0; i < 3; i++) + for (var i = 0; i < 3; i++) { try { diff --git a/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Linq/Observable/SelectManyTest.cs b/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Linq/Observable/SelectManyTest.cs index b218f53c5f..c25ddb1559 100644 --- a/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Linq/Observable/SelectManyTest.cs +++ b/Rx.NET/Source/tests/Tests.System.Reactive/Tests/Linq/Observable/SelectManyTest.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT License. // See the LICENSE file in the project root for more information. +#pragma warning disable IDE0350 // Simplify lambda - we want to keep the long form for clarity in tests. + using System; using System.Collections.Generic; using System.Linq; diff --git a/azure-pipelines.rx.yml b/azure-pipelines.rx.yml index 045bb0a523..cbf570adc8 100644 --- a/azure-pipelines.rx.yml +++ b/azure-pipelines.rx.yml @@ -132,8 +132,9 @@ stages: version: '9.0.x' - task: UseDotNet@2 + displayName: Use .NET 8.0 runtime inputs: - version: 8.0.x + version: '8.0.x' packageType: runtime - task: DotNetCoreCLI@2 @@ -164,8 +165,8 @@ stages: inputs: command: test projects: $(System.DefaultWorkingDirectory)/Rx.NET/Integration/LinuxTests/LinuxTests.csproj - arguments: -c $(BuildConfiguration) -f net8.0 --filter "TestCategory!=SkipCI" - displayName: Run 8.0 Tests on Linux + arguments: -c $(BuildConfiguration) -f net9.0 --filter "TestCategory!=SkipCI" + displayName: Run 9.0 Tests on Linux - task: DotNetCoreCLI@2 inputs: @@ -174,6 +175,13 @@ stages: arguments: -c $(BuildConfiguration) -f net9.0 --filter "TestCategory!=SkipCI" displayName: Run 9.0 Tests on Linux + - task: DotNetCoreCLI@2 + inputs: + command: test + projects: $(System.DefaultWorkingDirectory)/Rx.NET/Integration/LinuxTests/LinuxTests.csproj + arguments: -c $(BuildConfiguration) -f net8.0 --filter "TestCategory!=SkipCI" + displayName: Run 8.0 Tests on Linux + - job: WindowsDesktop pool: vmImage: windows-latest @@ -185,14 +193,15 @@ stages: steps: - task: UseDotNet@2 + displayName: Use .NET 9.0 SDK inputs: - version: 8.0.x + version: 9.0.x performMultiLevelLookup: true - task: UseDotNet@2 - displayName: Use .NET 9.0 SDK + displayName: Use .NET 8.0 SDK inputs: - version: '9.0.x' + version: '8.0.x' - task: DotNetCoreCLI@2 inputs: From 8c0e2befd443ba4c1e565869c436434315d04da8 Mon Sep 17 00:00:00 2001 From: Ian Griffiths Date: Tue, 4 Nov 2025 08:15:39 +0000 Subject: [PATCH 2/3] Update AsyncRx.NET to .NET 9.0 SDK --- azure-pipelines.asyncrx.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/azure-pipelines.asyncrx.yml b/azure-pipelines.asyncrx.yml index 5ff9cbb585..c11b784b04 100644 --- a/azure-pipelines.asyncrx.yml +++ b/azure-pipelines.asyncrx.yml @@ -34,10 +34,11 @@ stages: steps: - task: UseDotNet@2 - displayName: Use .NET Core 7.0.x SDK + displayName: Use .NET 9.0.x SDK inputs: - version: 7.0.x + version: 9.0.x performMultiLevelLookup: true + includePreviewVersions: true - task: DotNetCoreCLI@2 inputs: From a23fa1dc7dc1a1c2be51730435c9598384eea9ce Mon Sep 17 00:00:00 2001 From: Ian Griffiths Date: Tue, 4 Nov 2025 08:32:12 +0000 Subject: [PATCH 3/3] Fix bizarre errors about HttpResponse Something about the FluentAssertions library is now causing spurious errors about being unable to find a particular version of System.Net.Http, so I've replace the two lines of code that were hitting that with Xunit Assert equivalents --- .../System/Linq/AsyncEnumerableExTests.cs | 2 +- .../System.Linq.Async.Tests/System/Linq/AsyncEnumerableTests.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/AsyncEnumerableExTests.cs b/Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/AsyncEnumerableExTests.cs index dd75e9d319..37aed830d9 100644 --- a/Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/AsyncEnumerableExTests.cs +++ b/Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/AsyncEnumerableExTests.cs @@ -63,7 +63,7 @@ protected async Task SequenceIdentity(IAsyncEnumerable enumerable) var res1 = await enumerable.ToListAsync(); var res2 = await enumerable.ToListAsync(); - res1.Should().BeEquivalentTo(res2); + Assert.Equivalent(res1, res2, strict: true); } } } diff --git a/Ix.NET/Source/System.Linq.Async.Tests/System/Linq/AsyncEnumerableTests.cs b/Ix.NET/Source/System.Linq.Async.Tests/System/Linq/AsyncEnumerableTests.cs index 01dc488ef2..170f3faa79 100644 --- a/Ix.NET/Source/System.Linq.Async.Tests/System/Linq/AsyncEnumerableTests.cs +++ b/Ix.NET/Source/System.Linq.Async.Tests/System/Linq/AsyncEnumerableTests.cs @@ -62,7 +62,7 @@ protected async Task SequenceIdentity(IAsyncEnumerable enumerable) var res1 = await enumerable.ToListAsync(); var res2 = await enumerable.ToListAsync(); - res1.Should().BeEquivalentTo(res2); + Assert.Equivalent(res1, res2, strict: true); } protected static IAsyncEnumerable Throw(Exception exception)