From 8a01bd08e6ae72325ae438bc2edc1818417131b5 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Fri, 30 Aug 2024 11:32:51 +0200 Subject: [PATCH 01/11] Add .NET 9 target --- appveyor.yml | 12 ++++++------ src/Renci.SshNet/Renci.SshNet.csproj | 2 +- .../Renci.SshNet.AotCompatibilityTestApp.csproj | 2 +- .../Renci.SshNet.Benchmarks.csproj | 2 +- .../Renci.SshNet.IntegrationBenchmarks.csproj | 2 +- .../Renci.SshNet.IntegrationTests.csproj | 2 +- test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index ca7144ecb..896d759ee 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -19,15 +19,15 @@ for: build_script: - echo build - - dotnet build -f net8.0 -c Debug test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj - - dotnet build -f net8.0 -c Debug test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj + - dotnet build -f net9.0 -c Debug test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj + - dotnet build -f net9.0 -c Debug test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj - dotnet build -f net48 -c Debug test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj test_script: - sh: echo "Run unit tests" - - sh: dotnet test -f net8.0 -c Debug --no-restore --no-build --results-directory artifacts --logger Appveyor --logger "console;verbosity=normal" --logger "liquid.md;LogFileName=linux_unit_test_net_8_report.md" -p:CollectCoverage=true -p:CoverletOutputFormat=cobertura -p:CoverletOutput=../../artifacts/linux_unit_test_net_8_coverage.xml test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj + - sh: dotnet test -f net9.0 -c Debug --no-restore --no-build --results-directory artifacts --logger Appveyor --logger "console;verbosity=normal" --logger "liquid.md;LogFileName=linux_unit_test_net_9_report.md" -p:CollectCoverage=true -p:CoverletOutputFormat=cobertura -p:CoverletOutput=../../artifacts/linux_unit_test_net_9_coverage.xml test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj - sh: echo "Run integration tests" - - sh: dotnet test -f net8.0 -c Debug --no-restore --no-build --results-directory artifacts --logger Appveyor --logger "console;verbosity=normal" --logger "liquid.md;LogFileName=linux_integration_test_net_8_report.md" -p:CollectCoverage=true -p:CoverletOutputFormat=cobertura -p:CoverletOutput=../../artifacts/linux_integration_test_net_8_coverage.xml test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj + - sh: dotnet test -f net9.0 -c Debug --no-restore --no-build --results-directory artifacts --logger Appveyor --logger "console;verbosity=normal" --logger "liquid.md;LogFileName=linux_integration_test_net_9_report.md" -p:CollectCoverage=true -p:CoverletOutputFormat=cobertura -p:CoverletOutput=../../artifacts/linux_integration_test_net_9_coverage.xml test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj # Also run a subset of the integration tests targeting netfx using mono. This is a temporary measure to get # some coverage until a proper solution for running the .NET Framework integration tests in CI is found. # Running all the tests causes problems which are not worth solving in this rare configuration. @@ -52,8 +52,8 @@ for: - dotnet pack -c Release test_script: - - ps: echo "Run unit tests for .NET 8.0" - - ps: dotnet test -f net8.0 -c Debug --no-restore --no-build --results-directory artifacts --logger Appveyor --logger "console;verbosity=normal" --logger "liquid.md;LogFileName=windows_unit_test_net_8_report.md" -p:CollectCoverage=true -p:CoverletOutputFormat=cobertura -p:CoverletOutput=../../artifacts/windows_unit_test_net_8_coverage.xml test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj + - ps: echo "Run unit tests for .NET 9.0" + - ps: dotnet test -f net9.0 -c Debug --no-restore --no-build --results-directory artifacts --logger Appveyor --logger "console;verbosity=normal" --logger "liquid.md;LogFileName=windows_unit_test_net_9_report.md" -p:CollectCoverage=true -p:CoverletOutputFormat=cobertura -p:CoverletOutput=../../artifacts/windows_unit_test_net_9_coverage.xml test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj - ps: echo "Run unit tests for .NET Framework 4.6.2" - ps: dotnet test -f net462 -c Debug --no-restore --no-build --results-directory artifacts --logger Appveyor --logger "console;verbosity=normal" --logger "liquid.md;LogFileName=windows_unit_test_net_4_6_2_report.md" -p:CollectCoverage=true -p:CoverletOutputFormat=cobertura -p:CoverletOutput=../../artifacts/windows_unit_test_net_4_6_2_coverage.xml test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj diff --git a/src/Renci.SshNet/Renci.SshNet.csproj b/src/Renci.SshNet/Renci.SshNet.csproj index bea1b66af..df1276869 100644 --- a/src/Renci.SshNet/Renci.SshNet.csproj +++ b/src/Renci.SshNet/Renci.SshNet.csproj @@ -4,7 +4,7 @@ Renci.SshNet SSH.NET SSH.NET - net462;netstandard2.0;netstandard2.1;net6.0;net7.0;net8.0 + net462;netstandard2.0;netstandard2.1;net6.0;net7.0;net8.0;net9.0 diff --git a/test/Renci.SshNet.AotCompatibilityTestApp/Renci.SshNet.AotCompatibilityTestApp.csproj b/test/Renci.SshNet.AotCompatibilityTestApp/Renci.SshNet.AotCompatibilityTestApp.csproj index bf4fdbc82..a18321dae 100644 --- a/test/Renci.SshNet.AotCompatibilityTestApp/Renci.SshNet.AotCompatibilityTestApp.csproj +++ b/test/Renci.SshNet.AotCompatibilityTestApp/Renci.SshNet.AotCompatibilityTestApp.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net9.0 true true false diff --git a/test/Renci.SshNet.Benchmarks/Renci.SshNet.Benchmarks.csproj b/test/Renci.SshNet.Benchmarks/Renci.SshNet.Benchmarks.csproj index 1b49138db..70a0fe15a 100644 --- a/test/Renci.SshNet.Benchmarks/Renci.SshNet.Benchmarks.csproj +++ b/test/Renci.SshNet.Benchmarks/Renci.SshNet.Benchmarks.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net9.0 enable enable diff --git a/test/Renci.SshNet.IntegrationBenchmarks/Renci.SshNet.IntegrationBenchmarks.csproj b/test/Renci.SshNet.IntegrationBenchmarks/Renci.SshNet.IntegrationBenchmarks.csproj index aef8d5daa..f7ef0e3a4 100644 --- a/test/Renci.SshNet.IntegrationBenchmarks/Renci.SshNet.IntegrationBenchmarks.csproj +++ b/test/Renci.SshNet.IntegrationBenchmarks/Renci.SshNet.IntegrationBenchmarks.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net9.0 enable enable diff --git a/test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj b/test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj index 0ad9f8ce8..7e4607e89 100644 --- a/test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj +++ b/test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj @@ -1,7 +1,7 @@  - net48;net8.0 + net48;net9.0 enable true $(NoWarn);SYSLIB0021;SYSLIB1045;SYSLIB0014;IDE0220;IDE0010 diff --git a/test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj b/test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj index 08b744b39..60468355f 100644 --- a/test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj +++ b/test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj @@ -1,7 +1,7 @@  - net462;net6.0;net7.0;net8.0 + net462;net6.0;net7.0;net8.0;net9.0 From 1c4da73063131ef3f83475cf3cc7f5aa0d19c8f7 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Fri, 30 Aug 2024 11:31:02 +0200 Subject: [PATCH 02/11] Disable SonarSource S3236 This following change in the runtime now causes this analyzer to complain about some Debug.Assert calls which doesn't make sense. https://github.com/dotnet/core/blob/main/release-notes/9.0/preview/preview7/libraries.md#debugassert-now-reports-assert-condition-by-default https://rules.sonarsource.com/csharp/RSPEC-3236/ --- .editorconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.editorconfig b/.editorconfig index 20029dbf9..9cb049451 100644 --- a/.editorconfig +++ b/.editorconfig @@ -183,6 +183,9 @@ dotnet_diagnostic.S2971.severity = none # This is rather harmless. dotnet_diagnostic.S3218.severity = none +# S3236: Remove this argument from the method call; it hides the caller information. +dotnet_diagnostic.S3236.severity = none + # S3267: Loops should be simplified with "LINQ" expressions # https://rules.sonarsource.com/csharp/RSPEC-3267 # From 74d0277293b31dced069543e3b31d2ba97210e5b Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Fri, 30 Aug 2024 11:33:12 +0200 Subject: [PATCH 03/11] make use of .NET 9 Lock type see https://github.com/dotnet/runtime/issues/34812 --- src/Renci.SshNet/Channels/Channel.cs | 6 ++++++ src/Renci.SshNet/Channels/ChannelDirectTcpip.cs | 4 ++++ .../Channels/ChannelForwardedTcpip.cs | 8 ++++++++ src/Renci.SshNet/Session.cs | 16 ++++++++++++++++ src/Renci.SshNet/Sftp/SftpFileStream.cs | 5 +++++ src/Renci.SshNet/SshMessageFactory.cs | 8 ++++++++ .../Common/AsyncSocketListener.cs | 7 +++++-- 7 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/Renci.SshNet/Channels/Channel.cs b/src/Renci.SshNet/Channels/Channel.cs index e1e154ffd..56cfdc5e5 100644 --- a/src/Renci.SshNet/Channels/Channel.cs +++ b/src/Renci.SshNet/Channels/Channel.cs @@ -14,8 +14,14 @@ namespace Renci.SshNet.Channels /// internal abstract class Channel : IChannel { +#if NET9_0_OR_GREATER + private readonly Lock _serverWindowSizeLock = new Lock(); + private readonly Lock _messagingLock = new Lock(); +#else private readonly object _serverWindowSizeLock = new object(); private readonly object _messagingLock = new object(); +#endif + private readonly uint _initialWindowSize; private readonly ISession _session; private EventWaitHandle _channelClosedWaitHandle = new ManualResetEvent(initialState: false); diff --git a/src/Renci.SshNet/Channels/ChannelDirectTcpip.cs b/src/Renci.SshNet/Channels/ChannelDirectTcpip.cs index 6a07d59b0..e2e69da18 100644 --- a/src/Renci.SshNet/Channels/ChannelDirectTcpip.cs +++ b/src/Renci.SshNet/Channels/ChannelDirectTcpip.cs @@ -14,7 +14,11 @@ namespace Renci.SshNet.Channels /// internal sealed class ChannelDirectTcpip : ClientChannel, IChannelDirectTcpip { +#if NET9_0_OR_GREATER + private readonly Lock _socketLock = new Lock(); +#else private readonly object _socketLock = new object(); +#endif private EventWaitHandle _channelOpen = new AutoResetEvent(initialState: false); private EventWaitHandle _channelData = new AutoResetEvent(initialState: false); diff --git a/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs b/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs index 07271c834..160db910d 100644 --- a/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs +++ b/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs @@ -1,6 +1,9 @@ using System; using System.Net; using System.Net.Sockets; +#if NET9_0_OR_GREATER +using System.Threading; +#endif using Renci.SshNet.Abstractions; using Renci.SshNet.Common; @@ -13,7 +16,12 @@ namespace Renci.SshNet.Channels /// internal sealed class ChannelForwardedTcpip : ServerChannel, IChannelForwardedTcpip { +#if NET9_0_OR_GREATER + private readonly Lock _socketShutdownAndCloseLock = new Lock(); +#else private readonly object _socketShutdownAndCloseLock = new object(); +#endif + private Socket _socket; private IForwardedPort _forwardedPort; diff --git a/src/Renci.SshNet/Session.cs b/src/Renci.SshNet/Session.cs index 0dbd03738..330aabbda 100644 --- a/src/Renci.SshNet/Session.cs +++ b/src/Renci.SshNet/Session.cs @@ -80,7 +80,11 @@ public class Session : ISession /// Holds an object that is used to ensure only a single thread can read from /// at any given time. /// +#if NET9_0_OR_GREATER + private readonly Lock _socketReadLock = new Lock(); +#else private readonly object _socketReadLock = new object(); +#endif /// /// Holds an object that is used to ensure only a single thread can write to @@ -90,7 +94,11 @@ public class Session : ISession /// This is also used to ensure that is /// incremented atomatically. /// +#if NET9_0_OR_GREATER + private readonly Lock _socketWriteLock = new Lock(); +#else private readonly object _socketWriteLock = new object(); +#endif /// /// Holds an object that is used to ensure only a single thread can dispose @@ -1911,7 +1919,11 @@ private bool IsSocketConnected() return false; } +#if NET9_0_OR_GREATER + if (!_socketReadLock.TryEnter()) +#else if (!Monitor.TryEnter(_socketReadLock)) +#endif { return true; } @@ -1923,7 +1935,11 @@ private bool IsSocketConnected() } finally { +#if NET9_0_OR_GREATER + _socketReadLock.Exit(); +#else Monitor.Exit(_socketReadLock); +#endif } } finally diff --git a/src/Renci.SshNet/Sftp/SftpFileStream.cs b/src/Renci.SshNet/Sftp/SftpFileStream.cs index 8bf0f864a..be76b0226 100644 --- a/src/Renci.SshNet/Sftp/SftpFileStream.cs +++ b/src/Renci.SshNet/Sftp/SftpFileStream.cs @@ -18,7 +18,12 @@ namespace Renci.SshNet.Sftp #pragma warning restore IDE0079 public class SftpFileStream : Stream { +#if NET9_0_OR_GREATER + private readonly Lock _lock = new Lock(); +#else private readonly object _lock = new object(); +#endif + private readonly int _readBufferSize; private readonly int _writeBufferSize; diff --git a/src/Renci.SshNet/SshMessageFactory.cs b/src/Renci.SshNet/SshMessageFactory.cs index 630ebaad2..75bf3d96c 100644 --- a/src/Renci.SshNet/SshMessageFactory.cs +++ b/src/Renci.SshNet/SshMessageFactory.cs @@ -1,6 +1,9 @@ using System; using System.Collections.Generic; using System.Globalization; +#if NET9_0_OR_GREATER +using System.Threading; +#endif using Renci.SshNet.Common; using Renci.SshNet.Messages; @@ -14,7 +17,12 @@ internal sealed class SshMessageFactory { private readonly MessageMetadata[] _enabledMessagesByNumber; private readonly bool[] _activatedMessagesById; + +#if NET9_0_OR_GREATER + private readonly Lock _lock = new Lock(); +#else private readonly object _lock = new object(); +#endif internal static readonly MessageMetadata[] AllMessages = new MessageMetadata[] { diff --git a/test/Renci.SshNet.Tests/Common/AsyncSocketListener.cs b/test/Renci.SshNet.Tests/Common/AsyncSocketListener.cs index 9727764fa..4980eebd0 100644 --- a/test/Renci.SshNet.Tests/Common/AsyncSocketListener.cs +++ b/test/Renci.SshNet.Tests/Common/AsyncSocketListener.cs @@ -13,7 +13,11 @@ public class AsyncSocketListener : IDisposable private readonly IPEndPoint _endPoint; private readonly ManualResetEvent _acceptCallbackDone; private readonly List _connectedClients; - private readonly object _syncLock; +#if NET9_0_OR_GREATER + private readonly Lock _syncLock = new Lock(); +#else + private readonly object _syncLock = new object(); +#endif private Socket _listener; private Thread _receiveThread; private bool _started; @@ -31,7 +35,6 @@ public AsyncSocketListener(IPEndPoint endPoint) _endPoint = endPoint; _acceptCallbackDone = new ManualResetEvent(false); _connectedClients = new List(); - _syncLock = new object(); ShutdownRemoteCommunicationSocket = true; } From 137b04e3e242b49bfee4a8d94b42bf5262130a9b Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Sat, 31 Aug 2024 13:17:57 +0200 Subject: [PATCH 04/11] Define own Lock type to avoid ifdefs --- src/Renci.SshNet/Channels/Channel.cs | 5 ----- .../Channels/ChannelDirectTcpip.cs | 5 ----- .../Channels/ChannelForwardedTcpip.cs | 4 ---- src/Renci.SshNet/Common/Lock.cs | 19 +++++++++++++++++++ src/Renci.SshNet/Session.cs | 16 ---------------- src/Renci.SshNet/Sftp/SftpFileStream.cs | 4 ---- src/Renci.SshNet/SshMessageFactory.cs | 5 ----- .../Common/AsyncSocketListener.cs | 6 ++---- 8 files changed, 21 insertions(+), 43 deletions(-) create mode 100644 src/Renci.SshNet/Common/Lock.cs diff --git a/src/Renci.SshNet/Channels/Channel.cs b/src/Renci.SshNet/Channels/Channel.cs index 56cfdc5e5..de54e026c 100644 --- a/src/Renci.SshNet/Channels/Channel.cs +++ b/src/Renci.SshNet/Channels/Channel.cs @@ -14,13 +14,8 @@ namespace Renci.SshNet.Channels /// internal abstract class Channel : IChannel { -#if NET9_0_OR_GREATER private readonly Lock _serverWindowSizeLock = new Lock(); private readonly Lock _messagingLock = new Lock(); -#else - private readonly object _serverWindowSizeLock = new object(); - private readonly object _messagingLock = new object(); -#endif private readonly uint _initialWindowSize; private readonly ISession _session; diff --git a/src/Renci.SshNet/Channels/ChannelDirectTcpip.cs b/src/Renci.SshNet/Channels/ChannelDirectTcpip.cs index e2e69da18..603d0a172 100644 --- a/src/Renci.SshNet/Channels/ChannelDirectTcpip.cs +++ b/src/Renci.SshNet/Channels/ChannelDirectTcpip.cs @@ -14,12 +14,7 @@ namespace Renci.SshNet.Channels /// internal sealed class ChannelDirectTcpip : ClientChannel, IChannelDirectTcpip { -#if NET9_0_OR_GREATER private readonly Lock _socketLock = new Lock(); -#else - private readonly object _socketLock = new object(); -#endif - private EventWaitHandle _channelOpen = new AutoResetEvent(initialState: false); private EventWaitHandle _channelData = new AutoResetEvent(initialState: false); private IForwardedPort _forwardedPort; diff --git a/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs b/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs index 160db910d..90fa8744f 100644 --- a/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs +++ b/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs @@ -16,11 +16,7 @@ namespace Renci.SshNet.Channels /// internal sealed class ChannelForwardedTcpip : ServerChannel, IChannelForwardedTcpip { -#if NET9_0_OR_GREATER private readonly Lock _socketShutdownAndCloseLock = new Lock(); -#else - private readonly object _socketShutdownAndCloseLock = new object(); -#endif private Socket _socket; private IForwardedPort _forwardedPort; diff --git a/src/Renci.SshNet/Common/Lock.cs b/src/Renci.SshNet/Common/Lock.cs new file mode 100644 index 000000000..fc29776d3 --- /dev/null +++ b/src/Renci.SshNet/Common/Lock.cs @@ -0,0 +1,19 @@ +#if !NET9_0_OR_GREATER +using System.Threading; + +namespace Renci.SshNet.Common +{ + internal sealed class Lock + { + public bool TryEnter() + { + return Monitor.TryEnter(this); + } + + public void Exit() + { + Monitor.Exit(this); + } + } +} +#endif diff --git a/src/Renci.SshNet/Session.cs b/src/Renci.SshNet/Session.cs index 330aabbda..e100d7c83 100644 --- a/src/Renci.SshNet/Session.cs +++ b/src/Renci.SshNet/Session.cs @@ -80,11 +80,7 @@ public class Session : ISession /// Holds an object that is used to ensure only a single thread can read from /// at any given time. /// -#if NET9_0_OR_GREATER private readonly Lock _socketReadLock = new Lock(); -#else - private readonly object _socketReadLock = new object(); -#endif /// /// Holds an object that is used to ensure only a single thread can write to @@ -94,11 +90,7 @@ public class Session : ISession /// This is also used to ensure that is /// incremented atomatically. /// -#if NET9_0_OR_GREATER private readonly Lock _socketWriteLock = new Lock(); -#else - private readonly object _socketWriteLock = new object(); -#endif /// /// Holds an object that is used to ensure only a single thread can dispose @@ -1919,11 +1911,7 @@ private bool IsSocketConnected() return false; } -#if NET9_0_OR_GREATER if (!_socketReadLock.TryEnter()) -#else - if (!Monitor.TryEnter(_socketReadLock)) -#endif { return true; } @@ -1935,11 +1923,7 @@ private bool IsSocketConnected() } finally { -#if NET9_0_OR_GREATER _socketReadLock.Exit(); -#else - Monitor.Exit(_socketReadLock); -#endif } } finally diff --git a/src/Renci.SshNet/Sftp/SftpFileStream.cs b/src/Renci.SshNet/Sftp/SftpFileStream.cs index be76b0226..b8a8f146c 100644 --- a/src/Renci.SshNet/Sftp/SftpFileStream.cs +++ b/src/Renci.SshNet/Sftp/SftpFileStream.cs @@ -18,11 +18,7 @@ namespace Renci.SshNet.Sftp #pragma warning restore IDE0079 public class SftpFileStream : Stream { -#if NET9_0_OR_GREATER private readonly Lock _lock = new Lock(); -#else - private readonly object _lock = new object(); -#endif private readonly int _readBufferSize; private readonly int _writeBufferSize; diff --git a/src/Renci.SshNet/SshMessageFactory.cs b/src/Renci.SshNet/SshMessageFactory.cs index 75bf3d96c..b9d8b2f9b 100644 --- a/src/Renci.SshNet/SshMessageFactory.cs +++ b/src/Renci.SshNet/SshMessageFactory.cs @@ -17,12 +17,7 @@ internal sealed class SshMessageFactory { private readonly MessageMetadata[] _enabledMessagesByNumber; private readonly bool[] _activatedMessagesById; - -#if NET9_0_OR_GREATER private readonly Lock _lock = new Lock(); -#else - private readonly object _lock = new object(); -#endif internal static readonly MessageMetadata[] AllMessages = new MessageMetadata[] { diff --git a/test/Renci.SshNet.Tests/Common/AsyncSocketListener.cs b/test/Renci.SshNet.Tests/Common/AsyncSocketListener.cs index 4980eebd0..1775a1cd4 100644 --- a/test/Renci.SshNet.Tests/Common/AsyncSocketListener.cs +++ b/test/Renci.SshNet.Tests/Common/AsyncSocketListener.cs @@ -4,6 +4,8 @@ using System.Net; using System.Net.Sockets; using System.Threading; + +using Renci.SshNet.Common; #pragma warning restore IDE0005 namespace Renci.SshNet.Tests.Common @@ -13,11 +15,7 @@ public class AsyncSocketListener : IDisposable private readonly IPEndPoint _endPoint; private readonly ManualResetEvent _acceptCallbackDone; private readonly List _connectedClients; -#if NET9_0_OR_GREATER private readonly Lock _syncLock = new Lock(); -#else - private readonly object _syncLock = new object(); -#endif private Socket _listener; private Thread _receiveThread; private bool _started; From db5d7a7b2c0dcd43b68befacef4c1d274e548a82 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Thu, 5 Sep 2024 18:35:03 +0200 Subject: [PATCH 05/11] revert irrelevant style changes --- src/Renci.SshNet/Channels/Channel.cs | 1 - src/Renci.SshNet/Channels/ChannelDirectTcpip.cs | 1 + src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs | 1 - src/Renci.SshNet/Sftp/SftpFileStream.cs | 1 - test/Renci.SshNet.Tests/Common/AsyncSocketListener.cs | 3 ++- 5 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Renci.SshNet/Channels/Channel.cs b/src/Renci.SshNet/Channels/Channel.cs index 4ec001a53..ca8e910fa 100644 --- a/src/Renci.SshNet/Channels/Channel.cs +++ b/src/Renci.SshNet/Channels/Channel.cs @@ -16,7 +16,6 @@ internal abstract class Channel : IChannel { private readonly Lock _serverWindowSizeLock = new Lock(); private readonly Lock _messagingLock = new Lock(); - private readonly uint _initialWindowSize; private readonly ISession _session; private EventWaitHandle _channelClosedWaitHandle = new ManualResetEvent(initialState: false); diff --git a/src/Renci.SshNet/Channels/ChannelDirectTcpip.cs b/src/Renci.SshNet/Channels/ChannelDirectTcpip.cs index 603d0a172..7b00c3bae 100644 --- a/src/Renci.SshNet/Channels/ChannelDirectTcpip.cs +++ b/src/Renci.SshNet/Channels/ChannelDirectTcpip.cs @@ -15,6 +15,7 @@ namespace Renci.SshNet.Channels internal sealed class ChannelDirectTcpip : ClientChannel, IChannelDirectTcpip { private readonly Lock _socketLock = new Lock(); + private EventWaitHandle _channelOpen = new AutoResetEvent(initialState: false); private EventWaitHandle _channelData = new AutoResetEvent(initialState: false); private IForwardedPort _forwardedPort; diff --git a/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs b/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs index 90fa8744f..2cc0c16f8 100644 --- a/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs +++ b/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs @@ -17,7 +17,6 @@ namespace Renci.SshNet.Channels internal sealed class ChannelForwardedTcpip : ServerChannel, IChannelForwardedTcpip { private readonly Lock _socketShutdownAndCloseLock = new Lock(); - private Socket _socket; private IForwardedPort _forwardedPort; diff --git a/src/Renci.SshNet/Sftp/SftpFileStream.cs b/src/Renci.SshNet/Sftp/SftpFileStream.cs index d4d22e6c1..2ca7581c1 100644 --- a/src/Renci.SshNet/Sftp/SftpFileStream.cs +++ b/src/Renci.SshNet/Sftp/SftpFileStream.cs @@ -19,7 +19,6 @@ namespace Renci.SshNet.Sftp public class SftpFileStream : Stream { private readonly Lock _lock = new Lock(); - private readonly int _readBufferSize; private readonly int _writeBufferSize; diff --git a/test/Renci.SshNet.Tests/Common/AsyncSocketListener.cs b/test/Renci.SshNet.Tests/Common/AsyncSocketListener.cs index 1775a1cd4..a770940f4 100644 --- a/test/Renci.SshNet.Tests/Common/AsyncSocketListener.cs +++ b/test/Renci.SshNet.Tests/Common/AsyncSocketListener.cs @@ -15,7 +15,7 @@ public class AsyncSocketListener : IDisposable private readonly IPEndPoint _endPoint; private readonly ManualResetEvent _acceptCallbackDone; private readonly List _connectedClients; - private readonly Lock _syncLock = new Lock(); + private readonly Lock _syncLock; private Socket _listener; private Thread _receiveThread; private bool _started; @@ -33,6 +33,7 @@ public AsyncSocketListener(IPEndPoint endPoint) _endPoint = endPoint; _acceptCallbackDone = new ManualResetEvent(false); _connectedClients = new List(); + _syncLock = new Lock(); ShutdownRemoteCommunicationSocket = true; } From c58e5d472aa7c7797265a5556e682238d66fcd9a Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Sat, 14 Sep 2024 09:05:47 +0200 Subject: [PATCH 06/11] update global.json --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index d07970ac2..cf6e4ade2 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.100", + "version": "9.0.100-rc.1", "rollForward": "latestMajor" } } From a1fd4c3909b520cce420dcdb46a4f03e1437f50e Mon Sep 17 00:00:00 2001 From: mus65 Date: Sat, 14 Sep 2024 12:18:00 +0200 Subject: [PATCH 07/11] Keep net8.0 target in IntegrationTests Co-authored-by: Rob Hague --- .../Renci.SshNet.IntegrationTests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj b/test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj index d6566a5c5..0f1e825d5 100644 --- a/test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj +++ b/test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj @@ -1,7 +1,7 @@  - net48;net9.0 + net48;net8.0;net9.0 enable true $(NoWarn);SYSLIB0021;SYSLIB1045;SYSLIB0014;IDE0220;IDE0010 From 4f530b5426160a8452d20c5f05e204c9ccb93b2a Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Wed, 9 Oct 2024 17:24:19 +0200 Subject: [PATCH 08/11] fix Package Downgrade Warning for some reason this happens starting with .NET 9.0 RC2: /home/mus/git/SSH.NET/test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj : error NU1605: Warning As Error: Detected package downgrade: BouncyCastle.Cryptography from 2.4.0 to 2.3.1. Reference the package directly from the project to select a different version. Renci.SshNet.IntegrationTests -> SSH.NET 1.0.0 -> BouncyCastle.Cryptography (>= 2.4.0) Renci.SshNet.IntegrationTests -> Testcontainers 3.10.0 -> BouncyCastle.Cryptography (>= 2.3.1) --- .../Renci.SshNet.IntegrationTests.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj b/test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj index 0f1e825d5..6a1bc0cd4 100644 --- a/test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj +++ b/test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj @@ -13,6 +13,7 @@ + From 62a45df20c1e6b42728c31748f920817f866d097 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Wed, 9 Oct 2024 17:25:16 +0200 Subject: [PATCH 09/11] update global.json to RC2 --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index cf6e4ade2..a7afd00a8 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "9.0.100-rc.1", + "version": "9.0.100-rc.2", "rollForward": "latestMajor" } } From 4f25d256f8f215479d06784086d8e01478cc9d95 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Tue, 12 Nov 2024 21:22:24 +0100 Subject: [PATCH 10/11] update global.json to .NET 9 GA --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index a7afd00a8..f65788943 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "9.0.100-rc.2", + "version": "9.0.100", "rollForward": "latestMajor" } } From 1152c90f077b75f67c9ab68d9e01ddc008b8deb6 Mon Sep 17 00:00:00 2001 From: Marius Thesing Date: Sat, 23 Nov 2024 17:31:17 +0100 Subject: [PATCH 11/11] update GitHub Actions for .NET 9 --- .github/workflows/build.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6e4b721d2..458e018c5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,13 +17,13 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: 8.0.x + dotnet-version: 9.0.x - name: Build Unit Tests .NET - run: dotnet build -f net8.0 test/Renci.SshNet.Tests/ + run: dotnet build -f net9.0 test/Renci.SshNet.Tests/ - name: Build IntegrationTests .NET - run: dotnet build -f net8.0 test/Renci.SshNet.IntegrationTests/ + run: dotnet build -f net9.0 test/Renci.SshNet.IntegrationTests/ - name: Build IntegrationTests .NET Framework run: dotnet build -f net48 test/Renci.SshNet.IntegrationTests/ @@ -31,25 +31,25 @@ jobs: - name: Run Unit Tests .NET run: | dotnet test \ - -f net8.0 \ + -f net9.0 \ --no-build \ --logger "console;verbosity=normal" \ --logger GitHubActions \ -p:CollectCoverage=true \ -p:CoverletOutputFormat=cobertura \ - -p:CoverletOutput=../../coverlet/linux_unit_test_net_8_coverage.xml \ + -p:CoverletOutput=../../coverlet/linux_unit_test_net_9_coverage.xml \ test/Renci.SshNet.Tests/ - name: Run Integration Tests .NET run: | dotnet test \ - -f net8.0 \ + -f net9.0 \ --no-build \ --logger "console;verbosity=normal" \ --logger GitHubActions \ -p:CollectCoverage=true \ -p:CoverletOutputFormat=cobertura \ - -p:CoverletOutput=../../coverlet/linux_integration_test_net_8_coverage.xml \ + -p:CoverletOutput=../../coverlet/linux_integration_test_net_9_coverage.xml \ test/Renci.SshNet.IntegrationTests/ # Also run a subset of the integration tests targeting netfx using mono. This is a temporary measure to get @@ -111,13 +111,13 @@ jobs: - name: Run Unit Tests .NET run: | dotnet test ` - -f net8.0 ` + -f net9.0 ` --no-build ` --logger "console;verbosity=normal" ` --logger GitHubActions ` -p:CollectCoverage=true ` -p:CoverletOutputFormat=cobertura ` - -p:CoverletOutput=../../coverlet/windows_unit_test_net_8_coverage.xml ` + -p:CoverletOutput=../../coverlet/windows_unit_test_net_9_coverage.xml ` test/Renci.SshNet.Tests/ - name: Run Unit Tests .NET Framework