Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test integration tests #1250

Merged
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
7c6af7a
Test integration tests
WojciechNagorski Nov 21, 2023
4f37634
Update appveyor.yml
WojciechNagorski Nov 21, 2023
a504e27
Update appveyor.yml
WojciechNagorski Nov 21, 2023
2b20162
Update Dockerfile
WojciechNagorski Nov 21, 2023
547e4a6
Update appveyor.yml
WojciechNagorski Nov 21, 2023
f1e652f
test?
WojciechNagorski Nov 21, 2023
f2fe3e1
Merge branch 'develop' into integration-tests-appveyor
WojciechNagorski Nov 21, 2023
393a7a1
Test
WojciechNagorski Nov 21, 2023
e26f86b
Enable docker
WojciechNagorski Nov 22, 2023
4cd89e3
Update appveyor.yml
WojciechNagorski Nov 22, 2023
0b96523
Update appveyor.yml
WojciechNagorski Nov 22, 2023
e7611a5
Merge branch 'integration-tests-appveyor' of https://github.com/Wojci…
WojciechNagorski Nov 22, 2023
91e2ce5
Fix & Show additional information
WojciechNagorski Nov 22, 2023
83e9b20
Try to fix connection problems
WojciechNagorski Nov 23, 2023
2a891a6
Fix build
WojciechNagorski Nov 23, 2023
ceeb17c
remove artifacts
WojciechNagorski Nov 23, 2023
1d3b07e
Enable logging
WojciechNagorski Nov 23, 2023
11aac88
Log Information only
WojciechNagorski Nov 23, 2023
401600d
Update appveyor.yml
WojciechNagorski Nov 23, 2023
8b9cae2
Update appveyor.yml
WojciechNagorski Nov 23, 2023
179fa7f
Update appveyor.yml
WojciechNagorski Nov 23, 2023
c088277
Update appveyor.yml
WojciechNagorski Nov 23, 2023
fe010a4
Update appveyor.yml
WojciechNagorski Nov 23, 2023
7a4e418
Update appveyor.yml
WojciechNagorski Nov 23, 2023
89e84c1
Update appveyor.yml
WojciechNagorski Nov 23, 2023
9246e91
Update appveyor.yml
Rob-Hague Nov 23, 2023
05f4a28
Update appveyor.yml
Rob-Hague Nov 23, 2023
2b30996
Update appveyor.yml
Rob-Hague Nov 23, 2023
aeb1492
Update appveyor.yml
Rob-Hague Nov 23, 2023
d768f19
Update appveyor.yml
Rob-Hague Nov 23, 2023
fabf8c7
Update appveyor.yml
Rob-Hague Nov 23, 2023
1b6c73b
sleep after restarting
Rob-Hague Nov 23, 2023
49c730c
Update RemoteSshd.cs
WojciechNagorski Nov 23, 2023
5129976
Fix tests
WojciechNagorski Nov 24, 2023
06a52e3
Merge branch 'integration-tests-appveyor' of https://github.com/Wojci…
WojciechNagorski Nov 24, 2023
a0d6360
Dispose ports
WojciechNagorski Nov 24, 2023
914f419
Small improvements
WojciechNagorski Nov 24, 2023
5426cf1
Fix build
WojciechNagorski Nov 24, 2023
63dbf1c
Small fixes
WojciechNagorski Nov 24, 2023
82cf3bb
Revert not related changes
WojciechNagorski Nov 24, 2023
cca8ba6
Test linux and windows
WojciechNagorski Nov 25, 2023
63ef6ef
fix
WojciechNagorski Nov 25, 2023
b2b0b88
test_script
WojciechNagorski Nov 25, 2023
6d4e59f
Use real commands
WojciechNagorski Nov 25, 2023
093193c
Fixes
WojciechNagorski Nov 25, 2023
624486c
fix?
WojciechNagorski Nov 25, 2023
df3fb94
Add Appveyor TestLogger
WojciechNagorski Nov 25, 2023
24e76e4
Fix linux tests
WojciechNagorski Nov 25, 2023
ecc0fae
Fix tests
WojciechNagorski Nov 25, 2023
309ae1b
Try to fix tests
WojciechNagorski Nov 25, 2023
5bcc756
Revert
WojciechNagorski Nov 25, 2023
eee3db5
Give time before
WojciechNagorski Nov 25, 2023
70ab38d
fix
WojciechNagorski Nov 25, 2023
b9764c2
revert
WojciechNagorski Nov 25, 2023
9944991
Give some time to process all messages after connect
WojciechNagorski Nov 25, 2023
30a3620
ForwardedPortDynamicTest_Stop_PortStarted_ChannelNotBound
Rob-Hague Nov 25, 2023
19b0ac6
fix netsh
Rob-Hague Nov 25, 2023
e10fc14
trace
Rob-Hague Nov 25, 2023
cf26535
Update appveyor.yml
WojciechNagorski Nov 25, 2023
4aebfd2
Update appveyor.yml
WojciechNagorski Nov 25, 2023
9399fd9
etl2pcapng
Rob-Hague Nov 25, 2023
46cbe42
Update appveyor.yml
Rob-Hague Nov 25, 2023
850e87c
Update appveyor.yml
Rob-Hague Nov 25, 2023
0a0a473
Update appveyor.yml
Rob-Hague Nov 25, 2023
0eb40d6
Update appveyor.yml
Rob-Hague Nov 25, 2023
48ce561
Update appveyor.yml
scott-xu Nov 26, 2023
ec33d6d
Merge pull request #1 from scott-xu/patch-1
WojciechNagorski Nov 26, 2023
65e84f9
come on !!
Rob-Hague Nov 26, 2023
f850d9b
Update appveyor.yml
Rob-Hague Nov 26, 2023
68cc3a8
Fixes tests for linux
WojciechNagorski Nov 28, 2023
03df17d
Merge branch 'develop' into integration-tests-appveyor
WojciechNagorski Nov 28, 2023
4336148
Reverts
WojciechNagorski Nov 28, 2023
2210fa1
Fix build
WojciechNagorski Nov 28, 2023
64bb26b
Update TestMethodForPlatformAttribute.cs
WojciechNagorski Nov 29, 2023
e732710
Update TestMethodForPlatformAttribute.cs
WojciechNagorski Nov 29, 2023
c7c0b66
Update appveyor.yml
WojciechNagorski Nov 29, 2023
25e0aac
Issue #1253
WojciechNagorski Nov 29, 2023
0c1d4af
Install .NET SDK
WojciechNagorski Nov 29, 2023
ca4536e
next try
WojciechNagorski Nov 29, 2023
e0f9dd0
fix?
WojciechNagorski Nov 29, 2023
d96c7f7
try
WojciechNagorski Nov 29, 2023
edce619
Finishing
WojciechNagorski Nov 29, 2023
b378cf1
Fixes
WojciechNagorski Nov 29, 2023
980dbf5
apt-get install dotnet-sdk-7.0
WojciechNagorski Nov 29, 2023
81f8d03
Finish?
WojciechNagorski Nov 29, 2023
f3ca592
Add environment APPVEYOR_BAKE_IMAGE
WojciechNagorski Nov 29, 2023
cf23073
Update test/Renci.SshNet.Tests/Classes/Connection/DirectConnectorTest…
WojciechNagorski Nov 29, 2023
06a7444
Fix review
WojciechNagorski Nov 30, 2023
52d9c68
Merge branch 'integration-tests-appveyor' of https://github.com/Wojci…
WojciechNagorski Nov 30, 2023
c2143d3
Fix
WojciechNagorski Nov 30, 2023
769863f
Merge branch 'develop' into integration-tests-appveyor
WojciechNagorski Nov 30, 2023
e398e63
Update appveyor.yml
WojciechNagorski Nov 30, 2023
0251c81
Update appveyor.yml
WojciechNagorski Nov 30, 2023
502ef8a
Delete .runsettings
WojciechNagorski Nov 30, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
!**/.gitignore
!.git/HEAD
!.git/config
!.git/packed-refs
!.git/refs/heads/**
!**/Dockerfile.TestServer
23 changes: 10 additions & 13 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
os: Visual Studio 2022
os: Ubuntu2204

before_build:
- nuget restore Renci.SshNet.sln
services:
- docker

install:
- cinst dotnet-sdk --version=7.0.403 --limit-output

build:
project: Renci.SshNet.sln
verbosity: minimal
#for testing purposes only
build_script:
- dotnet build test/Renci.SshNet.IntegrationTests/ -c Debug

test_script:
- cmd: >-
vstest.console /logger:Appveyor test\Renci.SshNet.Tests\bin\Debug\net462\Renci.SshNet.Tests.dll /TestCaseFilter:"TestCategory!=integration" --blame
vstest.console /logger:Appveyor test\Renci.SshNet.Tests\bin\Debug\net7.0\Renci.SshNet.Tests.dll /TestCaseFilter:"TestCategory!=integration" --blame
- mkdir artifacts
WojciechNagorski marked this conversation as resolved.
Show resolved Hide resolved
- dotnet test -c Debug --no-restore --no-build --results-directory artifacts --logger "console;verbosity=detailed" --logger "liquid.md;LogFileName=TestReport.md" -p:CollectCoverage=true -p:CoverletOutputFormat=cobertura -p:CoverletOutput=artifacts/coverage.xml test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj
- ls artifacts

6 changes: 0 additions & 6 deletions global.json

This file was deleted.

9 changes: 5 additions & 4 deletions src/Renci.SshNet/Abstractions/DiagnosticAbstraction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,13 @@ public static class DiagnosticAbstraction
/// level.
/// </summary>
/// <param name="text">The message to log.</param>
/// <param name="type">The trace event type.</param>
[Conditional("DEBUG")]
public static void Log(string text)
public static void Log(string text, TraceEventType type = TraceEventType.Information)
{
Source.TraceEvent(TraceEventType.Verbose,
System.Environment.CurrentManagedThreadId,
text);
Source.TraceEvent(type,
System.Environment.CurrentManagedThreadId,
text);
}
}
}
49 changes: 35 additions & 14 deletions src/Renci.SshNet/Abstractions/SocketAbstraction.cs
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did these changes fix something?

Copy link
Collaborator Author

@WojciechNagorski WojciechNagorski Nov 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to revert the Connect changes, for 2 reasons:

  1. I think it is better to have 1 custom logic, than 2 custom logics
  2. The new implementation will block a threadpool thread while connecting. This can lead to thread starvation and deadlocks as described in https://devblogs.microsoft.com/pfxteam/should-i-expose-synchronous-wrappers-for-asynchronous-methods/

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I am fine with removing the #elif FEATURE_SOCKET_APM and #elif FEATURE_SOCKET_TAP blocks)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will revert some changes. I did some of them because I wanted to try if something helped.

  1. What do you mean? Currently, for old and new .NET we use custom implementation from SocketExtensions because every target framework has a FEATURE_SOCKET_EAP flag. FEATURE_SOCKET_TAP and FEATURE_SOCKET_APM have not been used. I think that for the modern .NET we can propose a better sync solution. I'm open to suggestions.
  2. I've used AsyncHelper from https://github.com/aspnet/AspNetIdentity/blob/main/src/Microsoft.AspNet.Identity.Core/AsyncHelper.cs I think that this code works well. But no matter, I'll probably revert it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. I mean it's good that every TFM is using 1 implementation (under FEATURE_SOCKET_EAP), and ConnectCore doesn't use SocketExtensions
  2. It is unnecessary to dispatch this work onto the threadpool (as AsyncHelper is doing) and then wait for it on the main thread anyway. (I don't think it will block a threadpool thread as I claimed earlier, so it's not a huge problem)

Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,31 @@ public static async Task ConnectAsync(Socket socket, IPEndPoint remoteEndpoint,

private static void ConnectCore(Socket socket, IPEndPoint remoteEndpoint, TimeSpan connectTimeout, bool ownsSocket)
{
#if FEATURE_SOCKET_EAP
#if FEATURE_SOCKET_TAP
AsyncHelper.RunSync(async () =>
{
using var ctsTs = new CancellationTokenSource(connectTimeout);

try
{
await socket.ConnectAsync(remoteEndpoint, ctsTs.Token).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
throw new SshOperationTimeoutException(
string.Format(CultureInfo.InvariantCulture,
"Connection failed to establish within {0:F0} milliseconds.",
connectTimeout.TotalMilliseconds));
}
finally
{
if (!socket.Connected && ownsSocket)
{
socket.Dispose();
}
}
});
#elif FEATURE_SOCKET_EAP
var connectCompleted = new ManualResetEvent(initialState: false);
var args = new SocketAsyncEventArgs
WojciechNagorski marked this conversation as resolved.
Show resolved Hide resolved
{
Expand Down Expand Up @@ -113,18 +137,8 @@ private static void ConnectCore(Socket socket, IPEndPoint remoteEndpoint, TimeSp

// dispose SocketAsyncEventArgs
args.Dispose();
#elif FEATURE_SOCKET_APM
var connectResult = socket.BeginConnect(remoteEndpoint, null, null);
if (!connectResult.AsyncWaitHandle.WaitOne(connectTimeout, false))
throw new SshOperationTimeoutException(string.Format(CultureInfo.InvariantCulture,
"Connection failed to establish within {0:F0} milliseconds.", connectTimeout.TotalMilliseconds));
socket.EndConnect(connectResult);
#elif FEATURE_SOCKET_TAP
if (!socket.ConnectAsync(remoteEndpoint).Wait(connectTimeout))
throw new SshOperationTimeoutException(string.Format(CultureInfo.InvariantCulture,
"Connection failed to establish within {0:F0} milliseconds.", connectTimeout.TotalMilliseconds));
#else
#error Connecting to a remote endpoint is not implemented.
#error Connecting to a remote endpoint is not implemented.
#endif
}

Expand Down Expand Up @@ -325,9 +339,16 @@ public static int Read(Socket socket, byte[] buffer, int offset, int size, TimeS
return totalBytesRead;
}

public static Task<int> ReadAsync(Socket socket, byte[] buffer, int offset, int length, CancellationToken cancellationToken)
public static Task<int> ReadAsync(Socket socket, byte[] buffer, CancellationToken cancellationToken)
{
return socket.ReceiveAsync(buffer, offset, length, cancellationToken);
#if FEATURE_SOCKET_TAP
Memory<byte> memory = buffer;
return socket.ReceiveAsync(memory, SocketFlags.None, cancellationToken).AsTask();
WojciechNagorski marked this conversation as resolved.
Show resolved Hide resolved
#elif FEATURE_SOCKET_EAP
return socket.ReceiveAsync(buffer, 0, buffer.Length, cancellationToken);
#else
#error Reading from a remote endpoint is not implemented.
#endif
}

public static void Send(Socket socket, byte[] data)
Expand Down
38 changes: 20 additions & 18 deletions src/Renci.SshNet/Abstractions/SocketExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
#if FEATURE_SOCKET_EAP
using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
Expand Down Expand Up @@ -90,23 +91,23 @@ public void GetResult()
}

public static async Task ConnectAsync(this Socket socket, IPEndPoint remoteEndpoint, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();

using (var args = new AwaitableSocketAsyncEventArgs())
{
args.RemoteEndPoint = remoteEndpoint;

#if NET || NETSTANDARD2_1_OR_GREATER
await using (cancellationToken.Register(o => ((AwaitableSocketAsyncEventArgs)o).SetCancelled(), args, useSynchronizationContext: false).ConfigureAwait(continueOnCapturedContext: false))
#else
using (cancellationToken.Register(o => ((AwaitableSocketAsyncEventArgs) o).SetCancelled(), args, useSynchronizationContext: false))
#endif // NET || NETSTANDARD2_1_OR_GREATER
{
await args.ExecuteAsync(socket.ConnectAsync);
}
}
}
{
cancellationToken.ThrowIfCancellationRequested();

using (var args = new AwaitableSocketAsyncEventArgs())
{
args.RemoteEndPoint = remoteEndpoint;

#if NET || NETSTANDARD2_1_OR_GREATER
await using (cancellationToken.Register(o => ((AwaitableSocketAsyncEventArgs)o).SetCancelled(), args, useSynchronizationContext: false).ConfigureAwait(continueOnCapturedContext: false))
#else
using (cancellationToken.Register(o => ((AwaitableSocketAsyncEventArgs) o).SetCancelled(), args, useSynchronizationContext: false))
#endif // NET || NETSTANDARD2_1_OR_GREATER
{
await args.ExecuteAsync(socket.ConnectAsync);
}
}
}

public static async Task<int> ReceiveAsync(this Socket socket, byte[] buffer, int offset, int length, CancellationToken cancellationToken)
{
Expand All @@ -130,3 +131,4 @@ public static async Task<int> ReceiveAsync(this Socket socket, byte[] buffer, in
}
}
}
#endif
42 changes: 42 additions & 0 deletions src/Renci.SshNet/Common/AsyncHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;

namespace Renci.SshNet.Common
{
#pragma warning disable CA2008
internal static class AsyncHelper
{
private static readonly TaskFactory MyTaskFactory = new TaskFactory(
CancellationToken.None,
TaskCreationOptions.None,
TaskContinuationOptions.None,
TaskScheduler.Default);

public static TResult RunSync<TResult>(Func<Task<TResult>> func)
{
var cultureUi = CultureInfo.CurrentUICulture;
var culture = CultureInfo.CurrentCulture;
return MyTaskFactory.StartNew(() =>
{
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = cultureUi;
return func();
}).Unwrap().GetAwaiter().GetResult();
}

public static void RunSync(Func<Task> func)
{
var cultureUi = CultureInfo.CurrentUICulture;
var culture = CultureInfo.CurrentCulture;
MyTaskFactory.StartNew(() =>
{
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = cultureUi;
return func();
}).Unwrap().GetAwaiter().GetResult();
}
}
#pragma warning restore CA2008
}
2 changes: 1 addition & 1 deletion src/Renci.SshNet/Connection/ProtocolVersionExchange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ private static async Task<string> SocketReadLineAsync(Socket socket, List<byte>
// to be processed by subsequent invocations.
while (true)
{
var bytesRead = await SocketAbstraction.ReadAsync(socket, data, 0, data.Length, cancellationToken).ConfigureAwait(false);
var bytesRead = await SocketAbstraction.ReadAsync(socket, data, cancellationToken).ConfigureAwait(false);
if (bytesRead == 0)
{
throw new SshConnectionException("The connection was closed by the remote host.");
Expand Down
13 changes: 11 additions & 2 deletions src/Renci.SshNet/Renci.SshNet.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<PropertyGroup Condition=" '$(TargetFramework)' == 'net462' ">
<DefineConstants>$(DefineConstants);FEATURE_BINARY_SERIALIZATION;FEATURE_SOCKET_EAP;FEATURE_SOCKET_APM;FEATURE_DNS_SYNC;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_RIPEMD160</DefineConstants>
<DefineConstants>$(DefineConstants);FEATURE_BINARY_SERIALIZATION;FEATURE_DNS_SYNC;FEATURE_HASH_RIPEMD160_CREATE;FEATURE_HMAC_RIPEMD160</DefineConstants>
</PropertyGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1' or '$(TargetFramework)' == 'net6.0' or '$(TargetFramework)' == 'net7.0' ">
Expand All @@ -18,6 +18,15 @@
</ItemGroup>

<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1' or '$(TargetFramework)' == 'net6.0' or '$(TargetFramework)' == 'net7.0' ">
<DefineConstants>$(DefineConstants);FEATURE_SOCKET_TAP;FEATURE_SOCKET_APM;FEATURE_SOCKET_EAP;FEATURE_DNS_SYNC;FEATURE_DNS_APM;FEATURE_DNS_TAP</DefineConstants>
<DefineConstants>$(DefineConstants);FEATURE_DNS_SYNC;FEATURE_DNS_APM;FEATURE_DNS_TAP</DefineConstants>
</PropertyGroup>

<PropertyGroup Condition="'$(TargetFramework)' == 'net462' or '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1' ">
<DefineConstants>$(DefineConstants);FEATURE_SOCKET_EAP</DefineConstants>
</PropertyGroup>

<PropertyGroup Condition="'$(TargetFramework)' == 'net6.0' or '$(TargetFramework)' == 'net7.0' ">
<DefineConstants>$(DefineConstants);FEATURE_SOCKET_TAP</DefineConstants>
</PropertyGroup>

</Project>
5 changes: 3 additions & 2 deletions src/Renci.SshNet/Session.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Net.Sockets;
Expand Down Expand Up @@ -1052,7 +1053,7 @@ internal void SendMessage(Message message)
WaitOnHandle(_keyExchangeCompletedWaitHandle);
}

DiagnosticAbstraction.Log(string.Format("[{0}] Sending message '{1}' to server: '{2}'.", ToHex(SessionId), message.GetType().Name, message));
DiagnosticAbstraction.Log(string.Format("[{0}] Sending message '{1}' to server: '{2}'.", ToHex(SessionId), message.GetType().Name, message), message is ChannelDataMessage ? TraceEventType.Verbose : TraceEventType.Information);

var paddingMultiplier = _clientCipher is null ? (byte) 8 : Math.Max((byte) 8, _serverCipher.MinimumSize);
var packetData = message.GetPacket(paddingMultiplier, _clientCompression);
Expand Down Expand Up @@ -1711,7 +1712,7 @@ private Message LoadMessage(byte[] data, int offset, int count)
var message = _sshMessageFactory.Create(messageType);
message.Load(data, offset + 1, count - 1);

DiagnosticAbstraction.Log(string.Format("[{0}] Received message '{1}' from server: '{2}'.", ToHex(SessionId), message.GetType().Name, message));
DiagnosticAbstraction.Log(string.Format("[{0}] Received message '{1}' from server: '{2}'.", ToHex(SessionId), message.GetType().Name, message), message is ChannelDataMessage ? TraceEventType.Verbose : TraceEventType.Information);

return message;
}
Expand Down
78 changes: 28 additions & 50 deletions test/Renci.SshNet.IntegrationTests/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,50 +1,28 @@
FROM alpine:latest

COPY --chown=root:root server/ssh /etc/ssh/
COPY --chown=root:root server/script /opt/sshnet
COPY user/sshnet /home/sshnet/.ssh

RUN apk update && apk upgrade --no-cache && \
apk add --no-cache syslog-ng && \
# install and configure sshd
apk add --no-cache openssh && \
# install openssh-server-pam to allow for keyboard-interactive authentication
apk add --no-cache openssh-server-pam && \
dos2unix /etc/ssh/* && \
chmod 400 /etc/ssh/ssh*key && \
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config && \
sed -i 's/#LogLevel\s*INFO/LogLevel DEBUG3/' /etc/ssh/sshd_config && \
# Set the default RSA key
echo 'HostKey /etc/ssh/ssh_host_rsa_key' >> /etc/ssh/sshd_config && \
chmod 646 /etc/ssh/sshd_config && \
# install and configure sudo
apk add --no-cache sudo && \
addgroup sudo && \
# allow root to run any command
echo 'root ALL=(ALL) ALL' > /etc/sudoers && \
# allow everyone in the 'sudo' group to run any command without a password
echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && \
# add user to run most of the integration tests
adduser -D sshnet && \
passwd -u sshnet && \
echo 'sshnet:ssh4ever' | chpasswd && \
dos2unix /home/sshnet/.ssh/* && \
chown -R sshnet:sshnet /home/sshnet && \
chmod -R 700 /home/sshnet/.ssh && \
chmod -R 644 /home/sshnet/.ssh/authorized_keys && \
# add user to administer container (update configs, restart sshd)
adduser -D sshnetadm && \
passwd -u sshnetadm && \
echo 'sshnetadm:ssh4ever' | chpasswd && \
addgroup sshnetadm sudo && \
dos2unix /opt/sshnet/* && \
# install shadow package; we use chage command in this package to expire/unexpire password of the sshnet user
apk add --no-cache shadow && \
# allow us to use telnet command; we use this in the remote port forwarding tests
apk --no-cache add busybox-extras && \
# install full-fledged ps command
apk add --no-cache procps

EXPOSE 22 22

ENTRYPOINT ["/opt/sshnet/start.sh"]
FROM mcr.microsoft.com/dotnet/sdk:7.0.403-bullseye-slim AS build
ENV DEBIAN_FRONTEND=noninteractive
ENV DEBCONF_NOWARNINGS="yes"
ARG BUILD_CONFIGURATION=Debug

RUN curl -fsSL https://get.docker.com -o get-docker.sh \
&& sh get-docker.sh

WORKDIR /src

COPY ["test/Directory.Build.props", "test/"]
COPY ["Directory.Build.props", "."]
COPY ["test/Renci.SshNet.IntegrationTests/Dockerfile.TestServer", "test/Renci.SshNet.IntegrationTests/"]
COPY ["test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj", "test/Renci.SshNet.IntegrationTests/"]
COPY ["test/Renci.SshNet.TestTools.OpenSSH/Renci.SshNet.TestTools.OpenSSH.csproj", "test/Renci.SshNet.TestTools.OpenSSH/"]
COPY ["src/Renci.SshNet/Renci.SshNet.csproj", "src/Renci.SshNet/"]
RUN dotnet restore "./test/Renci.SshNet.IntegrationTests/./Renci.SshNet.IntegrationTests.csproj"

COPY . .

run ls test/Renci.SshNet.IntegrationTests/

WORKDIR "/src/test/Renci.SshNet.IntegrationTests"
RUN dotnet build "./Renci.SshNet.IntegrationTests.csproj" -c $BUILD_CONFIGURATION -o /app/build

WORKDIR "/src/test/Renci.SshNet.IntegrationTests"
CMD ["dotnet", "test", "--no-restore", "--no-build", "-o", "/app/build", "--results-directory", "artifacts", "--logger", "console;verbosity=detailed", "--logger", "liquid.md;LogFileName=TestReport.md", "-p:CollectCoverage=true", "-p:CoverletOutputFormat=cobertura", "-p:CoverletOutput=artifacts/coverage.xml", "Renci.SshNet.IntegrationTests.csproj"]

Loading