diff --git a/src/Renci.SshNet.NETCore/Renci.SshNet.NETCore.csproj b/src/Renci.SshNet.NETCore/Renci.SshNet.NETCore.csproj
index 6f217844..f68f35c6 100644
--- a/src/Renci.SshNet.NETCore/Renci.SshNet.NETCore.csproj
+++ b/src/Renci.SshNet.NETCore/Renci.SshNet.NETCore.csproj
@@ -97,6 +97,10 @@
4.0.1
+
+
+
+
TRACE;DEBUG;FEATURE_ENCODING_ASCII;FEATURE_DIAGNOSTICS_TRACESOURCE;FEATURE_DIRECTORYINFO_ENUMERATEFILES;FEATURE_MEMORYSTREAM_TRYGETBUFFER;FEATURE_REFLECTION_TYPEINFO;FEATURE_RNG_CREATE;FEATURE_SOCKET_TAP;FEATURE_SOCKET_EAP;FEATURE_SOCKET_SYNC;FEATURE_SOCKET_SETSOCKETOPTION;FEATURE_SOCKET_SELECT;FEATURE_SOCKET_POLL;FEATURE_DNS_TAP;FEATURE_STREAM_TAP;FEATURE_THREAD_COUNTDOWNEVENT;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1_CREATE;FEATURE_HASH_SHA256_CREATE;FEATURE_HASH_SHA384_CREATE;FEATURE_HASH_SHA512_CREATE;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512
diff --git a/src/Renci.SshNet.Tests/Classes/Sftp/SftpDataResponseBuilder.cs b/src/Renci.SshNet.Tests/Classes/Sftp/SftpDataResponseBuilder.cs
new file mode 100644
index 00000000..71cfbb67
--- /dev/null
+++ b/src/Renci.SshNet.Tests/Classes/Sftp/SftpDataResponseBuilder.cs
@@ -0,0 +1,38 @@
+using Renci.SshNet.Sftp.Responses;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+ internal class SftpDataResponseBuilder
+ {
+ private uint _protocolVersion;
+ private uint _responseId;
+ private byte[] _data;
+
+ public SftpDataResponseBuilder WithProtocolVersion(uint protocolVersion)
+ {
+ _protocolVersion = protocolVersion;
+ return this;
+ }
+
+ public SftpDataResponseBuilder WithResponseId(uint responseId)
+ {
+ _responseId = responseId;
+ return this;
+ }
+
+ public SftpDataResponseBuilder WithData(byte[] data)
+ {
+ _data = data;
+ return this;
+ }
+
+ public SftpDataResponse Build()
+ {
+ return new SftpDataResponse(_protocolVersion)
+ {
+ ResponseId = _responseId,
+ Data = _data
+ };
+ }
+ }
+}
diff --git a/src/Renci.SshNet.Tests/Classes/Sftp/SftpHandleResponseBuilder.cs b/src/Renci.SshNet.Tests/Classes/Sftp/SftpHandleResponseBuilder.cs
new file mode 100644
index 00000000..4477e2fb
--- /dev/null
+++ b/src/Renci.SshNet.Tests/Classes/Sftp/SftpHandleResponseBuilder.cs
@@ -0,0 +1,42 @@
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Responses;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+ internal class SftpHandleResponseBuilder
+ {
+ private uint _protocolVersion;
+ private uint _responseId;
+ private byte[] _handle;
+
+ public SftpHandleResponseBuilder WithProtocolVersion(uint protocolVersion)
+ {
+ _protocolVersion = protocolVersion;
+ return this;
+ }
+
+ public SftpHandleResponseBuilder WithResponseId(uint responseId)
+ {
+ _responseId = responseId;
+ return this;
+ }
+
+ public SftpHandleResponseBuilder WithHandle(byte[] handle)
+ {
+ _handle = handle;
+ return this;
+ }
+
+ public SftpHandleResponse Build()
+ {
+ var sftpHandleResponse = new SftpHandleResponse(_protocolVersion)
+ {
+ ResponseId = _responseId,
+ Handle = _handle
+ };
+ return sftpHandleResponse;
+ }
+ }
+}
diff --git a/src/Renci.SshNet.Tests/Classes/Sftp/SftpInitRequestBuilder.cs b/src/Renci.SshNet.Tests/Classes/Sftp/SftpInitRequestBuilder.cs
new file mode 100644
index 00000000..f0f5f6c6
--- /dev/null
+++ b/src/Renci.SshNet.Tests/Classes/Sftp/SftpInitRequestBuilder.cs
@@ -0,0 +1,20 @@
+using Renci.SshNet.Sftp.Requests;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+ internal class SftpInitRequestBuilder
+ {
+ private uint _version;
+
+ public SftpInitRequestBuilder WithVersion(uint version)
+ {
+ _version = version;
+ return this;
+ }
+
+ public SftpInitRequest Build()
+ {
+ return new SftpInitRequest(_version);
+ }
+ }
+}
diff --git a/src/Renci.SshNet.Tests/Classes/Sftp/SftpNameResponseBuilder.cs b/src/Renci.SshNet.Tests/Classes/Sftp/SftpNameResponseBuilder.cs
new file mode 100644
index 00000000..e0dc9ae5
--- /dev/null
+++ b/src/Renci.SshNet.Tests/Classes/Sftp/SftpNameResponseBuilder.cs
@@ -0,0 +1,61 @@
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Responses;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+ internal class SftpNameResponseBuilder
+ {
+ private uint _responseId;
+ private uint _protocolVersion;
+ private Encoding _encoding;
+ private List> _files;
+
+ public SftpNameResponseBuilder()
+ {
+ _files = new List>();
+ }
+
+ public SftpNameResponseBuilder WithProtocolVersion(uint protocolVersion)
+ {
+ _protocolVersion = protocolVersion;
+ return this;
+ }
+
+ public SftpNameResponseBuilder WithResponseId(uint responseId)
+ {
+ _responseId = responseId;
+ return this;
+ }
+
+ public SftpNameResponseBuilder WithFiles(params KeyValuePair[] files)
+ {
+ for (var i = 0; i < files.Length; i++)
+ _files.Add(files[i]);
+ return this;
+ }
+
+ public SftpNameResponseBuilder WithFile(string filename, SftpFileAttributes attributes)
+ {
+ _files.Add(new KeyValuePair(filename, attributes));
+ return this;
+ }
+
+ public SftpNameResponseBuilder WithEncoding(Encoding encoding)
+ {
+ _encoding = encoding;
+ return this;
+ }
+
+ public SftpNameResponse Build()
+ {
+ var sftpNameResponse = new SftpNameResponse(_protocolVersion, _encoding)
+ {
+ ResponseId = _responseId,
+ Files = _files.ToArray()
+ };
+ return sftpNameResponse;
+ }
+ }
+}
diff --git a/src/Renci.SshNet.Tests/Classes/Sftp/SftpOpenRequestBuilder.cs b/src/Renci.SshNet.Tests/Classes/Sftp/SftpOpenRequestBuilder.cs
new file mode 100644
index 00000000..00c0efa3
--- /dev/null
+++ b/src/Renci.SshNet.Tests/Classes/Sftp/SftpOpenRequestBuilder.cs
@@ -0,0 +1,71 @@
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+ internal class SftpOpenRequestBuilder
+ {
+ private uint _protocolVersion;
+ private uint _requestId;
+ private string _fileName;
+ private Encoding _encoding;
+ private Flags _flags;
+ private Action _handleAction;
+ private Action _statusAction;
+
+ public SftpOpenRequestBuilder WithProtocolVersion(uint protocolVersion)
+ {
+ _protocolVersion = protocolVersion;
+ return this;
+ }
+
+ public SftpOpenRequestBuilder WithRequestId(uint requestId)
+ {
+ _requestId = requestId;
+ return this;
+ }
+
+ public SftpOpenRequestBuilder WithFileName(string fileName)
+ {
+ _fileName = fileName;
+ return this;
+ }
+
+ public SftpOpenRequestBuilder WithEncoding(Encoding encoding)
+ {
+ _encoding = encoding;
+ return this;
+ }
+
+ public SftpOpenRequestBuilder WithFlags(Flags flags)
+ {
+ _flags = flags;
+ return this;
+ }
+
+ public SftpOpenRequestBuilder WithDataAction(Action handleAction)
+ {
+ _handleAction = handleAction;
+ return this;
+ }
+
+ public SftpOpenRequestBuilder WithStatusAction(Action statusAction)
+ {
+ _statusAction = statusAction;
+ return this;
+ }
+
+ public SftpOpenRequest Build()
+ {
+ var handleAction = _handleAction ?? ((handleResponse) => { });
+ var statusAction = _statusAction ?? ((statusResponse) => { });
+
+ return new SftpOpenRequest(_protocolVersion, _requestId, _fileName, _encoding, _flags, handleAction, statusAction);
+ }
+ }
+}
diff --git a/src/Renci.SshNet.Tests/Classes/Sftp/SftpReadRequestBuilder.cs b/src/Renci.SshNet.Tests/Classes/Sftp/SftpReadRequestBuilder.cs
new file mode 100644
index 00000000..2dc995c0
--- /dev/null
+++ b/src/Renci.SshNet.Tests/Classes/Sftp/SftpReadRequestBuilder.cs
@@ -0,0 +1,67 @@
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
+using System;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+ internal class SftpReadRequestBuilder
+ {
+ private uint _protocolVersion;
+ private uint _requestId;
+ private byte[] _handle;
+ private uint _offset;
+ private uint _length;
+ private Action _dataAction;
+ private Action _statusAction;
+
+ public SftpReadRequestBuilder WithProtocolVersion(uint protocolVersion)
+ {
+ _protocolVersion = protocolVersion;
+ return this;
+ }
+
+ public SftpReadRequestBuilder WithRequestId(uint requestId)
+ {
+ _requestId = requestId;
+ return this;
+ }
+
+ public SftpReadRequestBuilder WithHandle(byte[] handle)
+ {
+ _handle = handle;
+ return this;
+ }
+
+ public SftpReadRequestBuilder WithOffset(uint offset)
+ {
+ _offset = offset;
+ return this;
+ }
+
+ public SftpReadRequestBuilder WithLength(uint length)
+ {
+ _length = length;
+ return this;
+ }
+
+ public SftpReadRequestBuilder WithDataAction(Action dataAction)
+ {
+ _dataAction = dataAction;
+ return this;
+ }
+
+ public SftpReadRequestBuilder WithStatusAction(Action statusAction)
+ {
+ _statusAction = statusAction;
+ return this;
+ }
+
+ public SftpReadRequest Build()
+ {
+ var dataAction = _dataAction ?? ((dataResponse) => { });
+ var statusAction = _statusAction ?? ((statusResponse) => { });
+
+ return new SftpReadRequest(_protocolVersion, _requestId, _handle, _offset, _length, dataAction, statusAction);
+ }
+ }
+}
diff --git a/src/Renci.SshNet.Tests/Classes/Sftp/SftpRealPathRequestBuilder.cs b/src/Renci.SshNet.Tests/Classes/Sftp/SftpRealPathRequestBuilder.cs
new file mode 100644
index 00000000..536e07e2
--- /dev/null
+++ b/src/Renci.SshNet.Tests/Classes/Sftp/SftpRealPathRequestBuilder.cs
@@ -0,0 +1,61 @@
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
+using System;
+using System.Text;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+ internal class SftpRealPathRequestBuilder
+ {
+ private uint _protocolVersion;
+ private uint _requestId;
+ private string _path;
+ private Encoding _encoding;
+ private Action _nameAction;
+ private Action _statusAction;
+
+ public SftpRealPathRequestBuilder WithProtocolVersion(uint protocolVersion)
+ {
+ _protocolVersion = protocolVersion;
+ return this;
+ }
+
+ public SftpRealPathRequestBuilder WithRequestId(uint requestId)
+ {
+ _requestId = requestId;
+ return this;
+ }
+
+ public SftpRealPathRequestBuilder WithPath(string path)
+ {
+ _path = path;
+ return this;
+ }
+
+ public SftpRealPathRequestBuilder WithEncoding(Encoding encoding)
+ {
+ _encoding = encoding;
+ return this;
+ }
+
+ public SftpRealPathRequestBuilder WithNameAction(Action nameAction)
+ {
+ _nameAction = nameAction;
+ return this;
+ }
+
+ public SftpRealPathRequestBuilder WithStatusAction(Action statusAction)
+ {
+ _statusAction = statusAction;
+ return this;
+ }
+
+ public SftpRealPathRequest Build()
+ {
+ var nameAction = _nameAction ?? ((nameResponse) => { });
+ var statusAction = _statusAction ?? ((statusResponse) => { });
+
+ return new SftpRealPathRequest(_protocolVersion, _requestId, _path, _encoding, nameAction, statusAction);
+ }
+ }
+}
diff --git a/src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestRead.cs b/src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestRead.cs
index ef2a428c..4aec5217 100644
--- a/src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestRead.cs
+++ b/src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestRead.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -7,19 +6,37 @@ using Moq;
using Renci.SshNet.Channels;
using Renci.SshNet.Common;
using Renci.SshNet.Sftp;
+using Renci.SshNet.Abstractions;
+using Renci.SshNet.Sftp.Responses;
namespace Renci.SshNet.Tests.Classes.Sftp
{
[TestClass]
public class SftpSessionTest_Connected_RequestRead
{
+ #region SftpSession.Connect()
+
private Mock _sessionMock;
private Mock _channelSessionMock;
+ private ISftpResponseFactory _sftpMessageFactory;
private SftpSession _sftpSession;
private int _operationTimeout;
- private byte[] _actual;
- private byte[] _expected;
private Encoding _encoding;
+ private uint _protocolVersion;
+ private byte[] _sftpInitRequestBytes;
+ private SftpVersionResponse _sftpVersionResponse;
+ private byte[] _sftpRealPathRequestBytes;
+ private SftpNameResponse _sftpNameResponse;
+
+ #endregion SftpSession.Connect()
+
+ private byte[] _sftpReadRequestBytes;
+ private byte[] _sftpDataResponseBytes;
+ private byte[] _handle;
+ private uint _offset;
+ private uint _length;
+ private byte[] _data;
+ private byte[] _actual;
[TestInitialize]
public void Setup()
@@ -28,111 +45,119 @@ namespace Renci.SshNet.Tests.Classes.Sftp
Act();
}
- protected void Arrange()
+ private void SetupData()
{
var random = new Random();
- _operationTimeout = random.Next(100, 500);
- _expected = new byte[random.Next(30, 50)];
- _encoding = Encoding.UTF8;
- random.NextBytes(_expected);
+ #region SftpSession.Connect()
+ _operationTimeout = random.Next(100, 500);
+ _protocolVersion = (uint) random.Next(0, 3);
+ _encoding = Encoding.UTF8;
+ _sftpMessageFactory = new SftpResponseFactory();
+ _sftpInitRequestBytes = new SftpInitRequestBuilder().WithVersion(SftpSession.MaximumSupportedVersion)
+ .Build()
+ .GetBytes();
+ _sftpVersionResponse = new SftpVersionResponseBuilder().WithVersion(_protocolVersion)
+ .Build();
+ _sftpRealPathRequestBytes = new SftpRealPathRequestBuilder().WithProtocolVersion(_protocolVersion)
+ .WithRequestId(1)
+ .WithPath(".")
+ .WithEncoding(_encoding)
+ .Build()
+ .GetBytes();
+ _sftpNameResponse = new SftpNameResponseBuilder().WithProtocolVersion(_protocolVersion)
+ .WithResponseId(1)
+ .WithEncoding(_encoding)
+ .WithFile("XYZ", SftpFileAttributes.Empty)
+ .Build();
+
+ #endregion SftpSession.Connect()
+
+ _handle = CryptoAbstraction.GenerateRandom(random.Next(1, 10));
+ _offset = (uint) random.Next(1, 5);
+ _length = (uint) random.Next(30, 50);
+ _data = CryptoAbstraction.GenerateRandom((int) _length);
+ _sftpReadRequestBytes = new SftpReadRequestBuilder().WithProtocolVersion(_protocolVersion)
+ .WithRequestId(2)
+ .WithHandle(_handle)
+ .WithOffset(_offset)
+ .WithLength(_length)
+ .Build()
+ .GetBytes();
+ _sftpDataResponseBytes = new SftpDataResponseBuilder().WithProtocolVersion(_protocolVersion)
+ .WithResponseId(2)
+ .WithData(_data)
+ .Build()
+ .GetBytes();
+ }
+
+ private void CreateMocks()
+ {
_sessionMock = new Mock(MockBehavior.Strict);
_channelSessionMock = new Mock(MockBehavior.Strict);
+ }
+ private void SetupMocks()
+ {
var sequence = new MockSequence();
+ #region SftpSession.Connect()
+
_sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelSessionMock.Object);
_channelSessionMock.InSequence(sequence).Setup(p => p.Open());
_channelSessionMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest("sftp")).Returns(true);
_channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
- _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny())).Callback(
- () =>
- {
- // generate response for SftpInitRequest
- var versionInfoResponse = SftpVersionResponseBuilder.Create(3)
- .Build();
- _channelSessionMock.Raise(
- c => c.DataReceived += null,
- new ChannelDataEventArgs(0, versionInfoResponse));
- });
+ _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpInitRequestBytes))
+ .Callback(() =>
+ {
+ _channelSessionMock.Raise(c => c.DataReceived += null,
+ new ChannelDataEventArgs(0, _sftpVersionResponse.GetBytes()));
+ });
_channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
- _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny())).Callback(
- () =>
- {
- var sftpNameResponse = CreateSftpNameResponse(1, _encoding, "ABC");
+ _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpRealPathRequestBytes))
+ .Callback(() =>
+ {
+ _channelSessionMock.Raise(c => c.DataReceived += null,
+ new ChannelDataEventArgs(0, _sftpNameResponse.GetBytes()));
+ });
+ #endregion SftpSession.Connect()
+
+ _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+ _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpReadRequestBytes))
+ .Callback(() =>
+ {
_channelSessionMock.Raise(
c => c.DataReceived += null,
- new ChannelDataEventArgs(0, sftpNameResponse));
+ new ChannelDataEventArgs(0, _sftpDataResponseBytes.Take(0, 20)));
+ _channelSessionMock.Raise(
+ c => c.DataReceived += null,
+ new ChannelDataEventArgs(0, _sftpDataResponseBytes.Take(20, _sftpDataResponseBytes.Length - 20)));
}
);
- _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
- _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny())).Callback(
- () =>
- {
- var sftpDataResponse = CreateSftpDataResponse(2, _expected);
+ }
- _channelSessionMock.Raise(
- c => c.DataReceived += null,
- new ChannelDataEventArgs(0, sftpDataResponse.Take(0, 20)));
- _channelSessionMock.Raise(
- c => c.DataReceived += null,
- new ChannelDataEventArgs(0, sftpDataResponse.Take(20, sftpDataResponse.Length - 20)));
- }
- );
+ private void Arrange()
+ {
+ SetupData();
+ CreateMocks();
+ SetupMocks();
- _sftpSession = new SftpSession(_sessionMock.Object, _operationTimeout, _encoding);
+ _sftpSession = new SftpSession(_sessionMock.Object, _operationTimeout, _encoding, _sftpMessageFactory);
_sftpSession.Connect();
}
protected void Act()
{
- _actual = _sftpSession.RequestRead(new byte[0], 0, 200);
+ _actual = _sftpSession.RequestRead(_handle, _offset, _length);
}
[TestMethod]
public void ReturnedValueShouldBeDataOfSftpDataResponse()
{
Assert.IsNotNull(_actual);
- Assert.IsTrue(_expected.SequenceEqual(_actual));
- }
-
- private static byte[] CreateSftpDataResponse(uint responseId, byte[] data)
- {
- var sshDataStream = new SshDataStream(4 + 1 + 4 + 4 + data.Length + 1);
- sshDataStream.Write((uint) sshDataStream.Capacity - 4);
- sshDataStream.WriteByte((byte) SftpMessageTypes.Data);
- sshDataStream.Write(responseId);
- sshDataStream.Write((uint) data.Length);
- sshDataStream.Write(data, 0, data.Length);
- sshDataStream.WriteByte(1); // EOF
- return sshDataStream.ToArray();
- }
-
- private static byte[] CreateSftpNameResponse(uint responseId, Encoding encoding, params string[] names)
- {
- var namesAndAttributes = new List();
- foreach (var name in names)
- {
- var nameBytes = encoding.GetBytes(name);
- var attributesBytes = SftpFileAttributes.Empty.GetBytes();
-
- namesAndAttributes.AddRange(Pack.UInt32ToBigEndian((uint) nameBytes.Length)); // filename length
- namesAndAttributes.AddRange(nameBytes); // filename
- namesAndAttributes.AddRange(Pack.UInt32ToBigEndian(0U)); // longname length
- namesAndAttributes.AddRange(attributesBytes); // attributes
- }
-
- var namesAndAttributesBytes = namesAndAttributes.ToArray();
-
- var sshDataStream = new SshDataStream(4 + 1 + 4 + 4 + namesAndAttributesBytes.Length);
- sshDataStream.Write((uint) sshDataStream.Capacity - 4);
- sshDataStream.WriteByte((byte) SftpMessageTypes.Name);
- sshDataStream.Write(responseId);
- sshDataStream.Write((uint) names.Length);
- sshDataStream.Write(namesAndAttributesBytes, 0, namesAndAttributesBytes.Length);
- return sshDataStream.ToArray();
+ Assert.IsTrue(_data.SequenceEqual(_actual));
}
}
}
\ No newline at end of file
diff --git a/src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestStatVfs.cs b/src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestStatVfs.cs
index a88fee21..ca6d225b 100644
--- a/src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestStatVfs.cs
+++ b/src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestStatVfs.cs
@@ -1,25 +1,38 @@
using System;
-using System.Collections.Generic;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Renci.SshNet.Channels;
using Renci.SshNet.Common;
using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Responses;
namespace Renci.SshNet.Tests.Classes.Sftp
{
[TestClass]
public class SftpSessionTest_Connected_RequestStatVfs
{
+ #region SftpSession.Connect()
+
private Mock _sessionMock;
private Mock _channelSessionMock;
+ private ISftpResponseFactory _sftpMessageFactory;
private SftpSession _sftpSession;
private int _operationTimeout;
- private SftpFileSytemInformation _actual;
private Encoding _encoding;
+ private uint _protocolVersion;
+ private SftpVersionResponse _sftpVersionResponse;
+ private SftpNameResponse _sftpNameResponse;
+ private byte[] _sftpInitRequestBytes;
+ private byte[] _sftpRealPathRequestBytes;
+ #endregion SftpSession.Connect()
+
+ private byte[] _sftpStatVfsRequestBytes;
+ private StatVfsResponse _sftpStatVfsResponse;
private ulong _bAvail;
+ private string _path;
+ private SftpFileSytemInformation _actual;
[TestInitialize]
public void Setup()
@@ -28,67 +41,104 @@ namespace Renci.SshNet.Tests.Classes.Sftp
Act();
}
- protected void Arrange()
+ private void SetupData()
{
var random = new Random();
+ #region SftpSession.Connect()
+
_operationTimeout = random.Next(100, 500);
_encoding = Encoding.UTF8;
+ _protocolVersion = 3;
+ _sftpMessageFactory = new SftpResponseFactory();
+ _sftpInitRequestBytes = new SftpInitRequestBuilder().WithVersion(SftpSession.MaximumSupportedVersion)
+ .Build()
+ .GetBytes();
+ _sftpVersionResponse = new SftpVersionResponseBuilder().WithVersion(_protocolVersion)
+ .WithExtension("statvfs@openssh.com", "")
+ .Build();
+ _sftpRealPathRequestBytes = new SftpRealPathRequestBuilder().WithProtocolVersion(_protocolVersion)
+ .WithRequestId(1)
+ .WithPath(".")
+ .WithEncoding(_encoding)
+ .Build()
+ .GetBytes();
+ _sftpNameResponse = new SftpNameResponseBuilder().WithProtocolVersion(_protocolVersion)
+ .WithResponseId(1U)
+ .WithEncoding(_encoding)
+ .WithFile("ABC", SftpFileAttributes.Empty)
+ .Build();
+ #endregion SftpSession.Connect()
+
+ _path = random.Next().ToString();
_bAvail = (ulong) random.Next(0, int.MaxValue);
+ _sftpStatVfsRequestBytes = new SftpStatVfsRequestBuilder().WithProtocolVersion(_protocolVersion)
+ .WithRequestId(2)
+ .WithPath(_path)
+ .WithEncoding(_encoding)
+ .Build()
+ .GetBytes();
+ _sftpStatVfsResponse = new SftpStatVfsResponseBuilder().WithProtocolVersion(_protocolVersion)
+ .WithResponseId(2U)
+ .WithBAvail(_bAvail)
+ .Build();
+ }
+ private void CreateMocks()
+ {
_sessionMock = new Mock(MockBehavior.Strict);
_channelSessionMock = new Mock(MockBehavior.Strict);
+ }
+ private void SetupMocks()
+ {
var sequence = new MockSequence();
+ #region SftpSession.Connect()
+
_sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelSessionMock.Object);
_channelSessionMock.InSequence(sequence).Setup(p => p.Open());
_channelSessionMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest("sftp")).Returns(true);
_channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
- _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny())).Callback(
+ _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpInitRequestBytes)).Callback(
() =>
- {
- // generate response for SftpInitRequest
- var versionInfoResponse = SftpVersionResponseBuilder.Create(3)
- .AddExtension("statvfs@openssh.com", "")
- .Build();
- _channelSessionMock.Raise(
- c => c.DataReceived += null,
- new ChannelDataEventArgs(0, versionInfoResponse));
- });
+ {
+ _channelSessionMock.Raise(c => c.DataReceived += null,
+ new ChannelDataEventArgs(0, _sftpVersionResponse.GetBytes()));
+ });
_channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
- _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny())).Callback(
+ _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpRealPathRequestBytes)).Callback(
() =>
- {
- var sftpNameResponse = CreateSftpNameResponse(1, _encoding, "ABC");
+ {
+ _channelSessionMock.Raise(c => c.DataReceived += null,
+ new ChannelDataEventArgs(0, _sftpNameResponse.GetBytes()));
+ });
+
+ #endregion SftpSession.Connect()
- _channelSessionMock.Raise(
- c => c.DataReceived += null,
- new ChannelDataEventArgs(0, sftpNameResponse));
- }
- );
_channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
- _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny())).Callback(
+ _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpStatVfsRequestBytes)).Callback(
() =>
- {
- var statVfsReplyBuilder = StatVfsReplyBuilder.Create(2);
- statVfsReplyBuilder.WithBAvail(_bAvail);
- var statVfsReply = statVfsReplyBuilder.Build();
+ {
+ _channelSessionMock.Raise(c => c.DataReceived += null,
+ new ChannelDataEventArgs(0, _sftpStatVfsResponse.GetBytes()));
+ });
+ }
- _channelSessionMock.Raise(
- c => c.DataReceived += null,
- new ChannelDataEventArgs(0, statVfsReply));
- }
- );
+ protected void Arrange()
+ {
+ SetupData();
+ CreateMocks();
+ SetupMocks();
- _sftpSession = new SftpSession(_sessionMock.Object, _operationTimeout, _encoding);
+ _sftpSession = new SftpSession(_sessionMock.Object, _operationTimeout, _encoding, _sftpMessageFactory);
_sftpSession.Connect();
}
protected void Act()
{
- _actual = _sftpSession.RequestStatVfs("path");
+ _actual = _sftpSession.RequestStatVfs(_path);
}
[TestMethod]
@@ -102,156 +152,5 @@ namespace Renci.SshNet.Tests.Classes.Sftp
{
Assert.AreEqual(_bAvail, _actual.AvailableBlocks);
}
-
- private static byte[] CreateSftpNameResponse(uint responseId, Encoding encoding, params string[] names)
- {
- var namesAndAttributes = new List();
- foreach (var name in names)
- {
- var nameBytes = encoding.GetBytes(name);
- var attributesBytes = SftpFileAttributes.Empty.GetBytes();
-
- namesAndAttributes.AddRange(Pack.UInt32ToBigEndian((uint) nameBytes.Length)); // filename length
- namesAndAttributes.AddRange(nameBytes); // filename
- namesAndAttributes.AddRange(Pack.UInt32ToBigEndian(0U)); // longname length
- namesAndAttributes.AddRange(attributesBytes); // attributes
- }
-
- var namesAndAttributesBytes = namesAndAttributes.ToArray();
-
- var sshDataStream = new SshDataStream(4 + 1 + 4 + 4 + namesAndAttributesBytes.Length);
- sshDataStream.Write((uint) sshDataStream.Capacity - 4);
- sshDataStream.WriteByte((byte) SftpMessageTypes.Name);
- sshDataStream.Write(responseId);
- sshDataStream.Write((uint) names.Length);
- sshDataStream.Write(namesAndAttributesBytes, 0, namesAndAttributesBytes.Length);
- return sshDataStream.ToArray();
- }
-
- public class StatVfsReplyBuilder
- {
- private readonly uint _responseId;
- private ulong _bsize;
- private ulong _frsize;
- private ulong _blocks;
- private ulong _bfree;
- private ulong _bavail;
- private ulong _files;
- private ulong _ffree;
- private ulong _favail;
- private ulong _sid;
- private ulong _flag;
- private ulong _namemax;
-
- private StatVfsReplyBuilder(uint responseId)
- {
- _responseId = responseId;
- }
-
- public static StatVfsReplyBuilder Create(uint responseId)
- {
- return new StatVfsReplyBuilder(responseId);
- }
-
- public StatVfsReplyBuilder WithBSize(ulong bsize)
- {
- _bsize = bsize;
- return this;
- }
-
- public StatVfsReplyBuilder WithFrSize(ulong frsize)
- {
- _frsize = frsize;
- return this;
- }
-
- public StatVfsReplyBuilder WithBlocks(ulong blocks)
- {
- _blocks = blocks;
- return this;
- }
-
- public StatVfsReplyBuilder WithBFree(ulong bfree)
- {
- _bfree = bfree;
- return this;
- }
-
- public StatVfsReplyBuilder WithBAvail(ulong bavail)
- {
- _bavail = bavail;
- return this;
- }
-
- public StatVfsReplyBuilder WithFiles(ulong files)
- {
- _files = files;
- return this;
- }
-
- public StatVfsReplyBuilder WithFFree(ulong ffree)
- {
- _ffree = ffree;
- return this;
- }
-
- public StatVfsReplyBuilder WithFAvail(ulong favail)
- {
- _favail = favail;
- return this;
- }
-
- public StatVfsReplyBuilder WithSid(ulong sid)
- {
- _sid = sid;
- return this;
- }
-
- public StatVfsReplyBuilder WithIsReadOnly(bool isReadOnly)
- {
- if (isReadOnly)
- _flag &= SftpFileSytemInformation.SSH_FXE_STATVFS_ST_RDONLY;
- else
- _flag |= SftpFileSytemInformation.SSH_FXE_STATVFS_ST_RDONLY;
-
- return this;
- }
-
- public StatVfsReplyBuilder WithSupportsSetUid(bool supportsSetUid)
- {
- if (supportsSetUid)
- _flag |= SftpFileSytemInformation.SSH_FXE_STATVFS_ST_NOSUID;
- else
- _flag &= SftpFileSytemInformation.SSH_FXE_STATVFS_ST_NOSUID;
-
- return this;
- }
-
- public StatVfsReplyBuilder WithNameMax(ulong nameMax)
- {
- _namemax = nameMax;
- return this;
- }
-
- public byte[] Build()
- {
- var sshDataStream = new SshDataStream(4 + 1 + 4 + 88);
- sshDataStream.Write((uint) sshDataStream.Capacity - 4);
- sshDataStream.WriteByte((byte) SftpMessageTypes.ExtendedReply);
- sshDataStream.Write(_responseId);
- sshDataStream.Write(_bsize);
- sshDataStream.Write(_frsize);
- sshDataStream.Write(_blocks);
- sshDataStream.Write(_bfree);
- sshDataStream.Write(_bavail);
- sshDataStream.Write(_files);
- sshDataStream.Write(_ffree);
- sshDataStream.Write(_favail);
- sshDataStream.Write(_sid);
- sshDataStream.Write(_flag);
- sshDataStream.Write(_namemax);
- return sshDataStream.ToArray();
- }
- }
- }
+ }
}
\ No newline at end of file
diff --git a/src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_MultipleSftpMessagesInSingleSshDataMessage.cs b/src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_MultipleSftpMessagesInSingleSshDataMessage.cs
new file mode 100644
index 00000000..4119fcf2
--- /dev/null
+++ b/src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_MultipleSftpMessagesInSingleSshDataMessage.cs
@@ -0,0 +1,200 @@
+using System;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Channels;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Responses;
+using Renci.SshNet.Abstractions;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+ [TestClass]
+ public class SftpSessionTest_DataReceived_MultipleSftpMessagesInSingleSshDataMessage
+ {
+ #region SftpSession.Connect()
+
+ private Mock _sessionMock;
+ private Mock _channelSessionMock;
+ private Mock _sftpMessageFactoryMock;
+ private SftpSession _sftpSession;
+ private int _operationTimeout;
+ private Encoding _encoding;
+ private uint _protocolVersion;
+ private byte[] _sftpInitRequestBytes;
+ private SftpVersionResponse _sftpVersionResponse;
+ private byte[] _sftpRealPathRequestBytes;
+ private SftpNameResponse _sftpNameResponse;
+ private byte[] _sftpOpenRequestBytes;
+ private byte[] _sftpHandleResponseBytes;
+ private byte[] _sftpReadRequestBytes;
+ private byte[] _sftpDataResponseBytes;
+ private byte[] _handle;
+ private uint _offset;
+ private uint _length;
+ private byte[] _data;
+ private string _path;
+ private byte[] _actualHandle;
+ private byte[] _actualData;
+
+ #endregion SftpSession.Connect()
+
+ [TestInitialize]
+ public void Setup()
+ {
+ Arrange();
+ Act();
+ }
+
+ private void SetupData()
+ {
+ var random = new Random();
+
+ #region SftpSession.Connect()
+
+ _operationTimeout = random.Next(100, 500);
+ _protocolVersion = (uint)random.Next(0, 3);
+ _encoding = Encoding.UTF8;
+
+ _sftpInitRequestBytes = new SftpInitRequestBuilder().WithVersion(SftpSession.MaximumSupportedVersion)
+ .Build()
+ .GetBytes();
+ _sftpVersionResponse = new SftpVersionResponseBuilder().WithVersion(_protocolVersion)
+ .Build();
+ _sftpRealPathRequestBytes = new SftpRealPathRequestBuilder().WithProtocolVersion(_protocolVersion)
+ .WithRequestId(1)
+ .WithPath(".")
+ .WithEncoding(_encoding)
+ .Build()
+ .GetBytes();
+ _sftpNameResponse = new SftpNameResponseBuilder().WithProtocolVersion(_protocolVersion)
+ .WithResponseId(1)
+ .WithEncoding(_encoding)
+ .WithFile("/ABC", SftpFileAttributes.Empty)
+ .Build();
+
+ #endregion SftpSession.Connect()
+
+ _path = random.Next().ToString();
+ _handle = CryptoAbstraction.GenerateRandom(4);
+ _offset = (uint) random.Next(1, 5);
+ _length = (uint) random.Next(30, 50);
+ _data = CryptoAbstraction.GenerateRandom(200);
+ _sftpOpenRequestBytes = new SftpOpenRequestBuilder().WithProtocolVersion(_protocolVersion)
+ .WithRequestId(2)
+ .WithFileName(_path)
+ .WithFlags(Flags.Read)
+ .WithEncoding(_encoding)
+ .Build()
+ .GetBytes();
+ _sftpHandleResponseBytes = new SftpHandleResponseBuilder().WithProtocolVersion(_protocolVersion)
+ .WithResponseId(2)
+ .WithHandle(_handle)
+ .Build()
+ .GetBytes();
+ _sftpReadRequestBytes = new SftpReadRequestBuilder().WithProtocolVersion(_protocolVersion)
+ .WithRequestId(3)
+ .WithHandle(_handle)
+ .WithOffset(_offset)
+ .WithLength(_length)
+ .Build()
+ .GetBytes();
+ _sftpDataResponseBytes = new SftpDataResponseBuilder().WithProtocolVersion(_protocolVersion)
+ .WithResponseId(3)
+ .WithData(_data)
+ .Build()
+ .GetBytes();
+ }
+
+ private void CreateMocks()
+ {
+ _sessionMock = new Mock(MockBehavior.Strict);
+ _channelSessionMock = new Mock(MockBehavior.Strict);
+ _sftpMessageFactoryMock = new Mock(MockBehavior.Strict);
+ }
+
+ private void SetupMocks()
+ {
+ var sequence = new MockSequence();
+
+ #region SftpSession.Connect()
+
+ _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelSessionMock.Object);
+ _channelSessionMock.InSequence(sequence).Setup(p => p.Open());
+ _channelSessionMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest("sftp")).Returns(true);
+ _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+ _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpInitRequestBytes))
+ .Callback(() =>
+ {
+ _channelSessionMock.Raise(c => c.DataReceived += null,
+ new ChannelDataEventArgs(0, _sftpVersionResponse.GetBytes()));
+ });
+ _sftpMessageFactoryMock.InSequence(sequence)
+ .Setup(p => p.Create(0U, (byte)SftpMessageTypes.Version, _encoding))
+ .Returns(_sftpVersionResponse);
+ _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+ _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpRealPathRequestBytes))
+ .Callback(() =>
+ {
+ _channelSessionMock.Raise(c => c.DataReceived += null,
+ new ChannelDataEventArgs(0, _sftpNameResponse.GetBytes()));
+ });
+ _sftpMessageFactoryMock.InSequence(sequence)
+ .Setup(p => p.Create(_protocolVersion, (byte)SftpMessageTypes.Name, _encoding))
+ .Returns(_sftpNameResponse);
+
+ #endregion SftpSession.Connect()
+
+ _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+ _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpOpenRequestBytes));
+ _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+ _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpReadRequestBytes)).Callback(() =>
+ {
+ var sshMessagePayload = new byte[_sftpHandleResponseBytes.Length + _sftpDataResponseBytes.Length];
+ Buffer.BlockCopy(_sftpHandleResponseBytes, 0, sshMessagePayload, 0, _sftpHandleResponseBytes.Length);
+ Buffer.BlockCopy(_sftpDataResponseBytes, 0, sshMessagePayload, _sftpHandleResponseBytes.Length, _sftpDataResponseBytes.Length);
+
+ _channelSessionMock.Raise(c => c.DataReceived += null,
+ new ChannelDataEventArgs(0, sshMessagePayload));
+ });
+ _sftpMessageFactoryMock.InSequence(sequence)
+ .Setup(p => p.Create(_protocolVersion, (byte) SftpMessageTypes.Handle, _encoding))
+ .Returns(new SftpHandleResponse(_protocolVersion));
+ _sftpMessageFactoryMock.InSequence(sequence)
+ .Setup(p => p.Create(_protocolVersion, (byte) SftpMessageTypes.Data, _encoding))
+ .Returns(new SftpDataResponse(_protocolVersion));
+ }
+
+ protected void Arrange()
+ {
+ SetupData();
+ CreateMocks();
+ SetupMocks();
+
+ _sftpSession = new SftpSession(_sessionMock.Object, _operationTimeout, _encoding, _sftpMessageFactoryMock.Object);
+ _sftpSession.Connect();
+ }
+
+ protected void Act()
+ {
+ var openAsyncResult = _sftpSession.BeginOpen(_path, Flags.Read, null, null);
+ var readAsyncResult = _sftpSession.BeginRead(_handle, _offset, _length, null, null);
+
+ _actualHandle = _sftpSession.EndOpen(openAsyncResult);
+ _actualData = _sftpSession.EndRead(readAsyncResult);
+ }
+
+ [TestMethod]
+ public void ReturnedValueShouldBeDataOfSftpDataResponse()
+ {
+ Assert.IsTrue(_data.IsEqualTo(_actualData));
+ }
+
+ [TestMethod]
+ public void ReturnedHandleShouldBeHandleOfSftpHandleResponse()
+ {
+ Assert.IsTrue(_handle.IsEqualTo(_actualHandle));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_MultipleSftpMessagesSplitOverMultipleSshDataMessages.cs b/src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_MultipleSftpMessagesSplitOverMultipleSshDataMessages.cs
new file mode 100644
index 00000000..3eb2c949
--- /dev/null
+++ b/src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_MultipleSftpMessagesSplitOverMultipleSshDataMessages.cs
@@ -0,0 +1,207 @@
+using System;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Channels;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Responses;
+using Renci.SshNet.Abstractions;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+ [TestClass]
+ public class SftpSessionTest_DataReceived_MultipleSftpMessagesSplitOverMultipleSshDataMessages
+ {
+ #region SftpSession.Connect()
+
+ private Mock _sessionMock;
+ private Mock _channelSessionMock;
+ private Mock _sftpMessageFactoryMock;
+ private SftpSession _sftpSession;
+ private int _operationTimeout;
+ private Encoding _encoding;
+ private uint _protocolVersion;
+ private byte[] _sftpInitRequestBytes;
+ private SftpVersionResponse _sftpVersionResponse;
+ private byte[] _sftpRealPathRequestBytes;
+ private SftpNameResponse _sftpNameResponse;
+ private byte[] _sftpOpenRequestBytes;
+ private byte[] _sftpHandleResponseBytes;
+ private byte[] _sftpReadRequestBytes;
+ private byte[] _sftpDataResponseBytes;
+ private byte[] _handle;
+ private uint _offset;
+ private uint _length;
+ private byte[] _data;
+ private string _path;
+ private byte[] _actualHandle;
+ private byte[] _actualData;
+
+ #endregion SftpSession.Connect()
+
+ [TestInitialize]
+ public void Setup()
+ {
+ Arrange();
+ Act();
+ }
+
+ private void SetupData()
+ {
+ var random = new Random();
+
+ #region SftpSession.Connect()
+
+ _operationTimeout = random.Next(100, 500);
+ _protocolVersion = (uint)random.Next(0, 3);
+ _encoding = Encoding.UTF8;
+
+ _sftpInitRequestBytes = new SftpInitRequestBuilder().WithVersion(SftpSession.MaximumSupportedVersion)
+ .Build()
+ .GetBytes();
+ _sftpVersionResponse = new SftpVersionResponseBuilder().WithVersion(_protocolVersion)
+ .Build();
+ _sftpRealPathRequestBytes = new SftpRealPathRequestBuilder().WithProtocolVersion(_protocolVersion)
+ .WithRequestId(1)
+ .WithPath(".")
+ .WithEncoding(_encoding)
+ .Build()
+ .GetBytes();
+ _sftpNameResponse = new SftpNameResponseBuilder().WithProtocolVersion(_protocolVersion)
+ .WithResponseId(1)
+ .WithEncoding(_encoding)
+ .WithFile("/ABC", SftpFileAttributes.Empty)
+ .Build();
+
+ #endregion SftpSession.Connect()
+
+ _path = random.Next().ToString();
+ _handle = CryptoAbstraction.GenerateRandom(4);
+ _offset = (uint) random.Next(1, 5);
+ _length = (uint) random.Next(30, 50);
+ _data = CryptoAbstraction.GenerateRandom(200);
+ _sftpOpenRequestBytes = new SftpOpenRequestBuilder().WithProtocolVersion(_protocolVersion)
+ .WithRequestId(2)
+ .WithFileName(_path)
+ .WithFlags(Flags.Read)
+ .WithEncoding(_encoding)
+ .Build()
+ .GetBytes();
+ _sftpHandleResponseBytes = new SftpHandleResponseBuilder().WithProtocolVersion(_protocolVersion)
+ .WithResponseId(2)
+ .WithHandle(_handle)
+ .Build()
+ .GetBytes();
+ _sftpReadRequestBytes = new SftpReadRequestBuilder().WithProtocolVersion(_protocolVersion)
+ .WithRequestId(3)
+ .WithHandle(_handle)
+ .WithOffset(_offset)
+ .WithLength(_length)
+ .Build()
+ .GetBytes();
+ _sftpDataResponseBytes = new SftpDataResponseBuilder().WithProtocolVersion(_protocolVersion)
+ .WithResponseId(3)
+ .WithData(_data)
+ .Build()
+ .GetBytes();
+ }
+
+ private void CreateMocks()
+ {
+ _sessionMock = new Mock(MockBehavior.Strict);
+ _channelSessionMock = new Mock(MockBehavior.Strict);
+ _sftpMessageFactoryMock = new Mock(MockBehavior.Strict);
+ }
+
+ private void SetupMocks()
+ {
+ var sequence = new MockSequence();
+
+ #region SftpSession.Connect()
+
+ _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelSessionMock.Object);
+ _channelSessionMock.InSequence(sequence).Setup(p => p.Open());
+ _channelSessionMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest("sftp")).Returns(true);
+ _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+ _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpInitRequestBytes))
+ .Callback(() =>
+ {
+ _channelSessionMock.Raise(c => c.DataReceived += null,
+ new ChannelDataEventArgs(0, _sftpVersionResponse.GetBytes()));
+ });
+ _sftpMessageFactoryMock.InSequence(sequence)
+ .Setup(p => p.Create(0U, (byte)SftpMessageTypes.Version, _encoding))
+ .Returns(_sftpVersionResponse);
+ _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+ _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpRealPathRequestBytes))
+ .Callback(() =>
+ {
+ _channelSessionMock.Raise(c => c.DataReceived += null,
+ new ChannelDataEventArgs(0, _sftpNameResponse.GetBytes()));
+ });
+ _sftpMessageFactoryMock.InSequence(sequence)
+ .Setup(p => p.Create(_protocolVersion, (byte)SftpMessageTypes.Name, _encoding))
+ .Returns(_sftpNameResponse);
+
+ #endregion SftpSession.Connect()
+
+ _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+ _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpOpenRequestBytes)).Callback(() =>
+ {
+ var sshMessagePayload = new byte[_sftpHandleResponseBytes.Length + 40];
+ Buffer.BlockCopy(_sftpHandleResponseBytes, 0, sshMessagePayload, 0, _sftpHandleResponseBytes.Length);
+ Buffer.BlockCopy(_sftpDataResponseBytes, 0, sshMessagePayload, _sftpHandleResponseBytes.Length, 40);
+
+ _channelSessionMock.Raise(c => c.DataReceived += null,
+ new ChannelDataEventArgs(0, sshMessagePayload));
+ });
+ _sftpMessageFactoryMock.InSequence(sequence)
+ .Setup(p => p.Create(_protocolVersion, (byte) SftpMessageTypes.Handle, _encoding))
+ .Returns(new SftpHandleResponse(_protocolVersion));
+ _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+ _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpReadRequestBytes)).Callback(() =>
+ {
+ var sshMessagePayload = new byte[_sftpDataResponseBytes.Length - 40];
+ Buffer.BlockCopy(_sftpDataResponseBytes, 40, sshMessagePayload, 0, _sftpDataResponseBytes.Length - 40);
+
+ _channelSessionMock.Raise(c => c.DataReceived += null,
+ new ChannelDataEventArgs(0, sshMessagePayload));
+ });
+ _sftpMessageFactoryMock.InSequence(sequence)
+ .Setup(p => p.Create(_protocolVersion, (byte) SftpMessageTypes.Data, _encoding))
+ .Returns(new SftpDataResponse(_protocolVersion));
+ }
+
+ protected void Arrange()
+ {
+ SetupData();
+ CreateMocks();
+ SetupMocks();
+
+ _sftpSession = new SftpSession(_sessionMock.Object, _operationTimeout, _encoding, _sftpMessageFactoryMock.Object);
+ _sftpSession.Connect();
+ }
+
+ protected void Act()
+ {
+ var openAsyncResult = _sftpSession.BeginOpen(_path, Flags.Read, null, null);
+ var readAsyncResult = _sftpSession.BeginRead(_handle, _offset, _length, null, null);
+
+ _actualHandle = _sftpSession.EndOpen(openAsyncResult);
+ _actualData = _sftpSession.EndRead(readAsyncResult);
+ }
+
+ [TestMethod]
+ public void ReturnedValueShouldBeDataOfSftpDataResponse()
+ {
+ Assert.IsTrue(_data.IsEqualTo(_actualData));
+ }
+
+ [TestMethod]
+ public void ReturnedHandleShouldBeHandleOfSftpHandleResponse()
+ {
+ Assert.IsTrue(_handle.IsEqualTo(_actualHandle));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_SingleSftpMessageInSshDataMessage.cs b/src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_SingleSftpMessageInSshDataMessage.cs
new file mode 100644
index 00000000..75f1d2b8
--- /dev/null
+++ b/src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_DataReceived_SingleSftpMessageInSshDataMessage.cs
@@ -0,0 +1,165 @@
+using System;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Channels;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Responses;
+using Renci.SshNet.Abstractions;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+ [TestClass]
+ public class SftpSessionTest_DataReceived_SingleSftpMessageInSshDataMessage
+ {
+ #region SftpSession.Connect()
+
+ private Mock _sessionMock;
+ private Mock _channelSessionMock;
+ private Mock _sftpMessageFactoryMock;
+ private SftpSession _sftpSession;
+ private int _operationTimeout;
+ private Encoding _encoding;
+ private uint _protocolVersion;
+ private byte[] _sftpInitRequestBytes;
+ private SftpVersionResponse _sftpVersionResponse;
+ private byte[] _sftpRealPathRequestBytes;
+ private SftpNameResponse _sftpNameResponse;
+ private byte[] _sftpReadRequestBytes;
+ private byte[] _sftpDataResponseBytes;
+ private byte[] _handle;
+ private uint _offset;
+ private uint _length;
+ private byte[] _data;
+ private byte[] _actual;
+
+ #endregion SftpSession.Connect()
+
+ [TestInitialize]
+ public void Setup()
+ {
+ Arrange();
+ Act();
+ }
+
+ private void SetupData()
+ {
+ var random = new Random();
+
+ #region SftpSession.Connect()
+
+ _operationTimeout = random.Next(100, 500);
+ _protocolVersion = (uint) random.Next(0, 3);
+ _encoding = Encoding.UTF8;
+
+ _sftpInitRequestBytes = new SftpInitRequestBuilder().WithVersion(SftpSession.MaximumSupportedVersion)
+ .Build()
+ .GetBytes();
+ _sftpVersionResponse = new SftpVersionResponseBuilder().WithVersion(_protocolVersion)
+ .Build();
+ _sftpRealPathRequestBytes = new SftpRealPathRequestBuilder().WithProtocolVersion(_protocolVersion)
+ .WithRequestId(1)
+ .WithPath(".")
+ .WithEncoding(_encoding)
+ .Build()
+ .GetBytes();
+ _sftpNameResponse = new SftpNameResponseBuilder().WithProtocolVersion(_protocolVersion)
+ .WithResponseId(1)
+ .WithEncoding(_encoding)
+ .WithFile("/ABC", SftpFileAttributes.Empty)
+ .Build();
+
+ #endregion SftpSession.Connect()
+
+ _handle = CryptoAbstraction.GenerateRandom(4);
+ _offset = (uint) random.Next(1, 5);
+ _length = (uint) random.Next(30, 50);
+ _data = CryptoAbstraction.GenerateRandom(200);
+ _sftpReadRequestBytes = new SftpReadRequestBuilder().WithProtocolVersion(_protocolVersion)
+ .WithRequestId(2)
+ .WithHandle(_handle)
+ .WithOffset(_offset)
+ .WithLength(_length)
+ .Build()
+ .GetBytes();
+ _sftpDataResponseBytes = new SftpDataResponseBuilder().WithProtocolVersion(_protocolVersion)
+ .WithResponseId(2)
+ .WithData(_data)
+ .Build()
+ .GetBytes();
+ }
+
+ private void CreateMocks()
+ {
+ _sessionMock = new Mock(MockBehavior.Strict);
+ _channelSessionMock = new Mock(MockBehavior.Strict);
+ _sftpMessageFactoryMock = new Mock(MockBehavior.Strict);
+ }
+
+ private void SetupMocks()
+ {
+ var sequence = new MockSequence();
+
+ #region SftpSession.Connect()
+
+ _sessionMock.InSequence(sequence).Setup(p => p.CreateChannelSession()).Returns(_channelSessionMock.Object);
+ _channelSessionMock.InSequence(sequence).Setup(p => p.Open());
+ _channelSessionMock.InSequence(sequence).Setup(p => p.SendSubsystemRequest("sftp")).Returns(true);
+ _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+ _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpInitRequestBytes))
+ .Callback(() =>
+ {
+ _channelSessionMock.Raise(c => c.DataReceived += null,
+ new ChannelDataEventArgs(0, _sftpVersionResponse.GetBytes()));
+ });
+ _sftpMessageFactoryMock.InSequence(sequence)
+ .Setup(p => p.Create(0U, (byte) SftpMessageTypes.Version, _encoding))
+ .Returns(_sftpVersionResponse);
+ _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+ _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpRealPathRequestBytes))
+ .Callback(() =>
+ {
+ _channelSessionMock.Raise(c => c.DataReceived += null,
+ new ChannelDataEventArgs(0, _sftpNameResponse.GetBytes()));
+ });
+ _sftpMessageFactoryMock.InSequence(sequence)
+ .Setup(p => p.Create(_protocolVersion, (byte) SftpMessageTypes.Name, _encoding))
+ .Returns(_sftpNameResponse);
+
+ #endregion SftpSession.Connect()
+
+ _channelSessionMock.InSequence(sequence).Setup(p => p.IsOpen).Returns(true);
+ _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(_sftpReadRequestBytes))
+ .Callback(() =>
+ {
+ _channelSessionMock.Raise(c => c.DataReceived += null,
+ new ChannelDataEventArgs(0, _sftpDataResponseBytes));
+ });
+ _sftpMessageFactoryMock.InSequence(sequence)
+ .Setup(p => p.Create(_protocolVersion, (byte) SftpMessageTypes.Data, _encoding))
+ .Returns(new SftpDataResponse(_protocolVersion));
+ }
+
+ protected void Arrange()
+ {
+ SetupData();
+ CreateMocks();
+ SetupMocks();
+
+ _sftpSession = new SftpSession(_sessionMock.Object, _operationTimeout, _encoding, _sftpMessageFactoryMock.Object);
+ _sftpSession.Connect();
+ }
+
+ protected void Act()
+ {
+ _actual = _sftpSession.RequestRead(_handle, _offset, _length);
+ }
+
+ [TestMethod]
+ public void ReturnedValueShouldBeDataOfSftpDataResponse()
+ {
+ Assert.IsTrue(_data.IsEqualTo(_actual));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Renci.SshNet.Tests/Classes/Sftp/SftpStatVfsRequestBuilder.cs b/src/Renci.SshNet.Tests/Classes/Sftp/SftpStatVfsRequestBuilder.cs
new file mode 100644
index 00000000..71e37bd1
--- /dev/null
+++ b/src/Renci.SshNet.Tests/Classes/Sftp/SftpStatVfsRequestBuilder.cs
@@ -0,0 +1,61 @@
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
+using System;
+using System.Text;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+ internal class SftpStatVfsRequestBuilder
+ {
+ private uint _protocolVersion;
+ private uint _requestId;
+ private string _path;
+ private Encoding _encoding;
+ private Action _extendedAction;
+ private Action _statusAction;
+
+ public SftpStatVfsRequestBuilder WithProtocolVersion(uint protocolVersion)
+ {
+ _protocolVersion = protocolVersion;
+ return this;
+ }
+
+ public SftpStatVfsRequestBuilder WithRequestId(uint requestId)
+ {
+ _requestId = requestId;
+ return this;
+ }
+
+ public SftpStatVfsRequestBuilder WithPath(string path)
+ {
+ _path = path;
+ return this;
+ }
+
+ public SftpStatVfsRequestBuilder WithEncoding(Encoding encoding)
+ {
+ _encoding = encoding;
+ return this;
+ }
+
+ public SftpStatVfsRequestBuilder WithExtendedAction(Action extendedAction)
+ {
+ _extendedAction = extendedAction;
+ return this;
+ }
+
+ public SftpStatVfsRequestBuilder WithStatusAction(Action statusAction)
+ {
+ _statusAction = statusAction;
+ return this;
+ }
+
+ public StatVfsRequest Build()
+ {
+ var extendedAction = _extendedAction ?? ((extendedReplyResponse) => { });
+ var statusAction = _statusAction ?? ((statusResponse) => { });
+
+ return new StatVfsRequest(_protocolVersion, _requestId, _path, _encoding, extendedAction, statusAction);
+ }
+ }
+}
diff --git a/src/Renci.SshNet.Tests/Classes/Sftp/SftpStatVfsResponseBuilder.cs b/src/Renci.SshNet.Tests/Classes/Sftp/SftpStatVfsResponseBuilder.cs
new file mode 100644
index 00000000..2d6be526
--- /dev/null
+++ b/src/Renci.SshNet.Tests/Classes/Sftp/SftpStatVfsResponseBuilder.cs
@@ -0,0 +1,135 @@
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Responses;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+ internal class SftpStatVfsResponseBuilder
+ {
+ private uint _protocolVersion;
+ private uint _responseId;
+ private ulong _bsize;
+ private ulong _frsize;
+ private ulong _blocks;
+ private ulong _bfree;
+ private ulong _bavail;
+ private ulong _files;
+ private ulong _ffree;
+ private ulong _favail;
+ private ulong _sid;
+ private ulong _flag;
+ private ulong _namemax;
+
+ public SftpStatVfsResponseBuilder WithProtocolVersion(uint protocolVersion)
+ {
+ _protocolVersion = protocolVersion;
+ return this;
+ }
+
+ public SftpStatVfsResponseBuilder WithResponseId(uint responseId)
+ {
+ _responseId = responseId;
+ return this;
+ }
+
+ public SftpStatVfsResponseBuilder WithBSize(ulong bsize)
+ {
+ _bsize = bsize;
+ return this;
+ }
+
+ public SftpStatVfsResponseBuilder WithFrSize(ulong frsize)
+ {
+ _frsize = frsize;
+ return this;
+ }
+
+ public SftpStatVfsResponseBuilder WithBlocks(ulong blocks)
+ {
+ _blocks = blocks;
+ return this;
+ }
+
+ public SftpStatVfsResponseBuilder WithBFree(ulong bfree)
+ {
+ _bfree = bfree;
+ return this;
+ }
+
+ public SftpStatVfsResponseBuilder WithBAvail(ulong bavail)
+ {
+ _bavail = bavail;
+ return this;
+ }
+
+ public SftpStatVfsResponseBuilder WithFiles(ulong files)
+ {
+ _files = files;
+ return this;
+ }
+
+ public SftpStatVfsResponseBuilder WithFFree(ulong ffree)
+ {
+ _ffree = ffree;
+ return this;
+ }
+
+ public SftpStatVfsResponseBuilder WithFAvail(ulong favail)
+ {
+ _favail = favail;
+ return this;
+ }
+
+ public SftpStatVfsResponseBuilder WithSid(ulong sid)
+ {
+ _sid = sid;
+ return this;
+ }
+
+ public SftpStatVfsResponseBuilder WithIsReadOnly(bool isReadOnly)
+ {
+ if (isReadOnly)
+ _flag &= SftpFileSytemInformation.SSH_FXE_STATVFS_ST_RDONLY;
+ else
+ _flag |= SftpFileSytemInformation.SSH_FXE_STATVFS_ST_RDONLY;
+
+ return this;
+ }
+
+ public SftpStatVfsResponseBuilder WithSupportsSetUid(bool supportsSetUid)
+ {
+ if (supportsSetUid)
+ _flag |= SftpFileSytemInformation.SSH_FXE_STATVFS_ST_NOSUID;
+ else
+ _flag &= SftpFileSytemInformation.SSH_FXE_STATVFS_ST_NOSUID;
+
+ return this;
+ }
+
+ public SftpStatVfsResponseBuilder WithNameMax(ulong nameMax)
+ {
+ _namemax = nameMax;
+ return this;
+ }
+
+ public StatVfsResponse Build()
+ {
+ var fileSystemInfo = new SftpFileSytemInformation(_bsize,
+ _frsize,
+ _blocks,
+ _bfree,
+ _bavail,
+ _files,
+ _ffree,
+ _favail,
+ _sid,
+ _flag,
+ _namemax);
+
+ return new StatVfsResponse(_protocolVersion)
+ {
+ ResponseId = _responseId,
+ Information = fileSystemInfo
+ };
+ }
+ }
+}
diff --git a/src/Renci.SshNet.Tests/Classes/Sftp/SftpVersionResponseBuilder.cs b/src/Renci.SshNet.Tests/Classes/Sftp/SftpVersionResponseBuilder.cs
index e5e1f670..85f33cc1 100644
--- a/src/Renci.SshNet.Tests/Classes/Sftp/SftpVersionResponseBuilder.cs
+++ b/src/Renci.SshNet.Tests/Classes/Sftp/SftpVersionResponseBuilder.cs
@@ -1,53 +1,38 @@
using System.Collections.Generic;
-using System.Text;
-using Renci.SshNet.Common;
-using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Responses;
namespace Renci.SshNet.Tests.Classes.Sftp
{
- public class SftpVersionResponseBuilder
+ internal class SftpVersionResponseBuilder
{
- private readonly uint _version;
- private readonly IDictionary _extensions;
+ private uint _version;
+ private IDictionary _extensions;
- private SftpVersionResponseBuilder(uint version)
+ public SftpVersionResponseBuilder()
{
- _version = version;
_extensions = new Dictionary();
}
- public static SftpVersionResponseBuilder Create(uint version)
+ public SftpVersionResponseBuilder WithVersion(uint version)
{
- return new SftpVersionResponseBuilder(version);
+ _version = version;
+ return this;
}
- public SftpVersionResponseBuilder AddExtension(string name, string data)
+ public SftpVersionResponseBuilder WithExtension(string name, string data)
{
_extensions.Add(name, data);
return this;
}
- public byte[] Build()
+ public SftpVersionResponse Build()
{
- var extensions = BuildExtensions();
-
- var sshDataStream = new SshDataStream(4 + 1 + 4 + extensions.Length);
- sshDataStream.Write((uint)sshDataStream.Capacity - 4);
- sshDataStream.WriteByte((byte)SftpMessageTypes.Version);
- sshDataStream.Write(_version);
- sshDataStream.Write(extensions, 0, extensions.Length);
- return sshDataStream.ToArray();
- }
-
- private byte[] BuildExtensions()
- {
- var sshDataStream = new SshDataStream(0);
- foreach (var extensionPair in _extensions)
- {
- sshDataStream.Write(extensionPair.Key, Encoding.ASCII);
- sshDataStream.Write(extensionPair.Value, Encoding.ASCII);
- }
- return sshDataStream.ToArray();
+ var sftpVersionResponse = new SftpVersionResponse()
+ {
+ Version = _version,
+ Extentions = _extensions
+ };
+ return sftpVersionResponse;
}
}
}
diff --git a/src/Renci.SshNet.Tests/Classes/SftpClientTest_Dispose_Connected.cs b/src/Renci.SshNet.Tests/Classes/SftpClientTest_Dispose_Connected.cs
index f633a0b5..05f504f2 100644
--- a/src/Renci.SshNet.Tests/Classes/SftpClientTest_Dispose_Connected.cs
+++ b/src/Renci.SshNet.Tests/Classes/SftpClientTest_Dispose_Connected.cs
@@ -10,9 +10,10 @@ namespace Renci.SshNet.Tests.Classes
{
private Mock _serviceFactoryMock;
private Mock _sessionMock;
+ private Mock _sftpMessageFactoryMock;
+ private Mock _sftpSessionMock;
private SftpClient _sftpClient;
private ConnectionInfo _connectionInfo;
- private Mock _sftpSessionMock;
private int _operationTimeout;
[TestInitialize]
@@ -31,6 +32,7 @@ namespace Renci.SshNet.Tests.Classes
{
_serviceFactoryMock = new Mock(MockBehavior.Strict);
_sessionMock = new Mock(MockBehavior.Strict);
+ _sftpMessageFactoryMock = new Mock(MockBehavior.Strict);
_sftpSessionMock = new Mock(MockBehavior.Strict);
_connectionInfo = new ConnectionInfo("host", "user", new NoneAuthenticationMethod("userauth"));
@@ -44,8 +46,11 @@ namespace Renci.SshNet.Tests.Classes
.Returns(_sessionMock.Object);
_sessionMock.InSequence(sequence).Setup(p => p.Connect());
_serviceFactoryMock.InSequence(sequence)
- .Setup(p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding))
- .Returns(_sftpSessionMock.Object);
+ .Setup(p => p.CreateSftpMessageFactory())
+ .Returns(_sftpMessageFactoryMock.Object);
+ _serviceFactoryMock.InSequence(sequence)
+ .Setup(p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding, _sftpMessageFactoryMock.Object))
+ .Returns(_sftpSessionMock.Object);
_sftpSessionMock.InSequence(sequence).Setup(p => p.Connect());
_sessionMock.InSequence(sequence).Setup(p => p.OnDisconnecting());
_sftpSessionMock.InSequence(sequence).Setup(p => p.Dispose());
@@ -59,11 +64,17 @@ namespace Renci.SshNet.Tests.Classes
_sftpClient.Dispose();
}
+ [TestMethod]
+ public void CreateSftpMessageFactoryOnServiceFactoryShouldBeInvokedOnce()
+ {
+ _serviceFactoryMock.Verify(p => p.CreateSftpMessageFactory(), Times.Once);
+ }
+
[TestMethod]
public void CreateSftpSessionOnServiceFactoryShouldBeInvokedOnce()
{
_serviceFactoryMock.Verify(
- p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding),
+ p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding, _sftpMessageFactoryMock.Object),
Times.Once);
}
diff --git a/src/Renci.SshNet.Tests/Classes/SftpClientTest_Dispose_Disconnected.cs b/src/Renci.SshNet.Tests/Classes/SftpClientTest_Dispose_Disconnected.cs
index c29fdc16..cdf8bef6 100644
--- a/src/Renci.SshNet.Tests/Classes/SftpClientTest_Dispose_Disconnected.cs
+++ b/src/Renci.SshNet.Tests/Classes/SftpClientTest_Dispose_Disconnected.cs
@@ -10,9 +10,11 @@ namespace Renci.SshNet.Tests.Classes
{
private Mock _serviceFactoryMock;
private Mock _sessionMock;
+ private Mock _sftpMessageFactoryMock;
+ private Mock _sftpSessionMock;
private SftpClient _sftpClient;
private ConnectionInfo _connectionInfo;
- private Mock _sftpSessionMock;
+
private int _operationTimeout;
[TestInitialize]
@@ -22,15 +24,11 @@ namespace Renci.SshNet.Tests.Classes
Act();
}
- [TestCleanup]
- public void Cleanup()
- {
- }
-
protected void Arrange()
{
_serviceFactoryMock = new Mock(MockBehavior.Strict);
_sessionMock = new Mock(MockBehavior.Strict);
+ _sftpMessageFactoryMock = new Mock(MockBehavior.Strict);
_sftpSessionMock = new Mock(MockBehavior.Strict);
_connectionInfo = new ConnectionInfo("host", "user", new NoneAuthenticationMethod("userauth"));
@@ -44,7 +42,10 @@ namespace Renci.SshNet.Tests.Classes
.Returns(_sessionMock.Object);
_sessionMock.InSequence(sequence).Setup(p => p.Connect());
_serviceFactoryMock.InSequence(sequence)
- .Setup(p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding))
+ .Setup(p => p.CreateSftpMessageFactory())
+ .Returns(_sftpMessageFactoryMock.Object);
+ _serviceFactoryMock.InSequence(sequence)
+ .Setup(p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding, _sftpMessageFactoryMock.Object))
.Returns(_sftpSessionMock.Object);
_sftpSessionMock.InSequence(sequence).Setup(p => p.Connect());
_sessionMock.InSequence(sequence).Setup(p => p.OnDisconnecting());
@@ -60,11 +61,17 @@ namespace Renci.SshNet.Tests.Classes
_sftpClient.Dispose();
}
+ [TestMethod]
+ public void CreateSftpMessageFactoryOnServiceFactoryShouldBeInvokedOnce()
+ {
+ _serviceFactoryMock.Verify(p => p.CreateSftpMessageFactory(), Times.Once);
+ }
+
[TestMethod]
public void CreateSftpSessionOnServiceFactoryShouldBeInvokedOnce()
{
_serviceFactoryMock.Verify(
- p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding),
+ p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding, _sftpMessageFactoryMock.Object),
Times.Once);
}
diff --git a/src/Renci.SshNet.Tests/Classes/SftpClientTest_Dispose_Disposed.cs b/src/Renci.SshNet.Tests/Classes/SftpClientTest_Dispose_Disposed.cs
index 1d9b8b4d..227e78f5 100644
--- a/src/Renci.SshNet.Tests/Classes/SftpClientTest_Dispose_Disposed.cs
+++ b/src/Renci.SshNet.Tests/Classes/SftpClientTest_Dispose_Disposed.cs
@@ -10,9 +10,10 @@ namespace Renci.SshNet.Tests.Classes
{
private Mock _serviceFactoryMock;
private Mock _sessionMock;
+ private Mock _sftpMessageFactoryMock;
+ private Mock _sftpSessionMock;
private SftpClient _sftpClient;
private ConnectionInfo _connectionInfo;
- private Mock _sftpSessionMock;
private int _operationTimeout;
[TestInitialize]
@@ -31,6 +32,7 @@ namespace Renci.SshNet.Tests.Classes
{
_serviceFactoryMock = new Mock(MockBehavior.Strict);
_sessionMock = new Mock(MockBehavior.Strict);
+ _sftpMessageFactoryMock = new Mock(MockBehavior.Strict);
_sftpSessionMock = new Mock(MockBehavior.Strict);
_connectionInfo = new ConnectionInfo("host", "user", new NoneAuthenticationMethod("userauth"));
@@ -44,7 +46,10 @@ namespace Renci.SshNet.Tests.Classes
.Returns(_sessionMock.Object);
_sessionMock.InSequence(sequence).Setup(p => p.Connect());
_serviceFactoryMock.InSequence(sequence)
- .Setup(p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding))
+ .Setup(p => p.CreateSftpMessageFactory())
+ .Returns(_sftpMessageFactoryMock.Object);
+ _serviceFactoryMock.InSequence(sequence)
+ .Setup(p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding, _sftpMessageFactoryMock.Object))
.Returns(_sftpSessionMock.Object);
_sftpSessionMock.InSequence(sequence).Setup(p => p.Connect());
_sessionMock.InSequence(sequence).Setup(p => p.OnDisconnecting());
@@ -60,11 +65,17 @@ namespace Renci.SshNet.Tests.Classes
_sftpClient.Dispose();
}
+ [TestMethod]
+ public void CreateSftpMessageFactoryOnServiceFactoryShouldBeInvokedOnce()
+ {
+ _serviceFactoryMock.Verify(p => p.CreateSftpMessageFactory(), Times.Once);
+ }
+
[TestMethod]
public void CreateSftpSessionOnServiceFactoryShouldBeInvokedOnce()
{
_serviceFactoryMock.Verify(
- p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding),
+ p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding, _sftpMessageFactoryMock.Object),
Times.Once);
}
diff --git a/src/Renci.SshNet.Tests/Classes/SftpClientTest_Finalize_Connected.cs b/src/Renci.SshNet.Tests/Classes/SftpClientTest_Finalize_Connected.cs
index 27b9b9ee..828de9e2 100644
--- a/src/Renci.SshNet.Tests/Classes/SftpClientTest_Finalize_Connected.cs
+++ b/src/Renci.SshNet.Tests/Classes/SftpClientTest_Finalize_Connected.cs
@@ -1,5 +1,4 @@
using System;
-using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Renci.SshNet.Sftp;
@@ -11,9 +10,10 @@ namespace Renci.SshNet.Tests.Classes
{
private Mock _serviceFactoryMock;
private Mock _sessionMock;
+ private Mock _sftpMessageFactoryMock;
+ private Mock _sftpSessionMock;
private SftpClient _sftpClient;
private ConnectionInfo _connectionInfo;
- private Mock _sftpSessionMock;
private int _operationTimeout;
[TestInitialize]
@@ -27,6 +27,7 @@ namespace Renci.SshNet.Tests.Classes
{
_serviceFactoryMock = new Mock(MockBehavior.Loose);
_sessionMock = new Mock(MockBehavior.Strict);
+ _sftpMessageFactoryMock = new Mock(MockBehavior.Strict);
_sftpSessionMock = new Mock(MockBehavior.Strict);
_connectionInfo = new ConnectionInfo("host", "user", new NoneAuthenticationMethod("userauth"));
@@ -37,17 +38,15 @@ namespace Renci.SshNet.Tests.Classes
_serviceFactoryMock.Setup(p => p.CreateSession(_connectionInfo))
.Returns(_sessionMock.Object);
_sessionMock.Setup(p => p.Connect());
- _serviceFactoryMock.Setup(p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding))
- .Returns(_sftpSessionMock.Object);
+ _serviceFactoryMock.Setup(p => p.CreateSftpMessageFactory())
+ .Returns(_sftpMessageFactoryMock.Object);
+ _serviceFactoryMock.Setup(p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding, _sftpMessageFactoryMock.Object))
+ .Returns(_sftpSessionMock.Object);
_sftpSessionMock.Setup(p => p.Connect());
_sftpClient.Connect();
_sftpClient = null;
- _serviceFactoryMock.Setup(p => p.CreateSftpSession(_sessionMock.Object, _operationTimeout, _connectionInfo.Encoding))
- .Returns((ISftpSession) null);
- _serviceFactoryMock.ResetCalls();
-
// we need to dereference all other mocks as they might otherwise hold the target alive
_sessionMock = null;
_connectionInfo = null;
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSessionStub.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSessionStub.cs
index ca47f09e..241b4910 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSessionStub.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSessionStub.cs
@@ -10,8 +10,8 @@ namespace Renci.SshNet.Tests.Classes
{
private int _onChannelOpenInvocationCount;
- public SubsystemSessionStub(ISession session, string subsystemName, int operationTimeout, Encoding encoding)
- : base(session, subsystemName, operationTimeout, encoding)
+ public SubsystemSessionStub(ISession session, string subsystemName, int operationTimeout)
+ : base(session, subsystemName, operationTimeout)
{
OnDataReceivedInvocations = new List();
}
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSession_Connect_Connected.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSession_Connect_Connected.cs
index fa90ba56..24e868cb 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSession_Connect_Connected.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSession_Connect_Connected.cs
@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
- private Encoding _encoding;
private IList _disconnectedRegister;
private IList _errorOccurredRegister;
private InvalidOperationException _actualException;
@@ -35,7 +34,6 @@ namespace Renci.SshNet.Tests.Classes
var random = new Random();
_subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
_operationTimeout = 30000;
- _encoding = Encoding.UTF8;
_disconnectedRegister = new List();
_errorOccurredRegister = new List();
@@ -51,8 +49,7 @@ namespace Renci.SshNet.Tests.Classes
_subsystemSession = new SubsystemSessionStub(
_sessionMock.Object,
_subsystemName,
- _operationTimeout,
- _encoding);
+ _operationTimeout);
_subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
_subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
_subsystemSession.Connect();
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSession_Connect_Disconnected.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSession_Connect_Disconnected.cs
index 065fed11..1d15dd6e 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSession_Connect_Disconnected.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSession_Connect_Disconnected.cs
@@ -18,7 +18,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
- private Encoding _encoding;
private IList _disconnectedRegister;
private IList _errorOccurredRegister;
private MockSequence _sequence;
@@ -35,7 +34,6 @@ namespace Renci.SshNet.Tests.Classes
var random = new Random();
_subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
_operationTimeout = 30000;
- _encoding = Encoding.UTF8;
_disconnectedRegister = new List();
_errorOccurredRegister = new List();
@@ -55,8 +53,7 @@ namespace Renci.SshNet.Tests.Classes
_subsystemSession = new SubsystemSessionStub(
_sessionMock.Object,
_subsystemName,
- _operationTimeout,
- _encoding);
+ _operationTimeout);
_subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
_subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
_subsystemSession.Connect();
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSession_Connect_Disposed.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSession_Connect_Disposed.cs
index b500dd35..11e6b0c6 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSession_Connect_Disposed.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSession_Connect_Disposed.cs
@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
- private Encoding _encoding;
private IList _disconnectedRegister;
private IList _errorOccurredRegister;
private ObjectDisposedException _actualException;
@@ -34,7 +33,6 @@ namespace Renci.SshNet.Tests.Classes
var random = new Random();
_subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
_operationTimeout = 30000;
- _encoding = Encoding.UTF8;
_disconnectedRegister = new List();
_errorOccurredRegister = new List();
@@ -49,8 +47,7 @@ namespace Renci.SshNet.Tests.Classes
_subsystemSession = new SubsystemSessionStub(
_sessionMock.Object,
_subsystemName,
- _operationTimeout,
- _encoding);
+ _operationTimeout);
_subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
_subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
_subsystemSession.Dispose();
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSession_Disconnect_Connected.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSession_Disconnect_Connected.cs
index 43b28985..f5d07813 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSession_Disconnect_Connected.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSession_Disconnect_Connected.cs
@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
- private Encoding _encoding;
private IList _disconnectedRegister;
private IList _errorOccurredRegister;
private MockSequence _sequence;
@@ -34,7 +33,6 @@ namespace Renci.SshNet.Tests.Classes
var random = new Random();
_subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
_operationTimeout = 30000;
- _encoding = Encoding.UTF8;
_disconnectedRegister = new List();
_errorOccurredRegister = new List();
@@ -50,8 +48,7 @@ namespace Renci.SshNet.Tests.Classes
_subsystemSession = new SubsystemSessionStub(
_sessionMock.Object,
_subsystemName,
- _operationTimeout,
- _encoding);
+ _operationTimeout);
_subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
_subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
_subsystemSession.Connect();
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSession_Disconnect_Disposed.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSession_Disconnect_Disposed.cs
index f3e2312a..21116a78 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSession_Disconnect_Disposed.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSession_Disconnect_Disposed.cs
@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
- private Encoding _encoding;
private IList _disconnectedRegister;
private IList _errorOccurredRegister;
@@ -33,7 +32,6 @@ namespace Renci.SshNet.Tests.Classes
var random = new Random();
_subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
_operationTimeout = 30000;
- _encoding = Encoding.UTF8;
_disconnectedRegister = new List();
_errorOccurredRegister = new List();
@@ -49,8 +47,7 @@ namespace Renci.SshNet.Tests.Classes
_subsystemSession = new SubsystemSessionStub(
_sessionMock.Object,
_subsystemName,
- _operationTimeout,
- _encoding);
+ _operationTimeout);
_subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
_subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
_subsystemSession.Connect();
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSession_Disconnect_NeverConnected.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSession_Disconnect_NeverConnected.cs
index 8804f6aa..71b161a5 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSession_Disconnect_NeverConnected.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSession_Disconnect_NeverConnected.cs
@@ -15,7 +15,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
- private Encoding _encoding;
private IList _disconnectedRegister;
private IList _errorOccurredRegister;
@@ -31,7 +30,6 @@ namespace Renci.SshNet.Tests.Classes
var random = new Random();
_subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
_operationTimeout = 30000;
- _encoding = Encoding.UTF8;
_disconnectedRegister = new List();
_errorOccurredRegister = new List();
@@ -40,8 +38,7 @@ namespace Renci.SshNet.Tests.Classes
_subsystemSession = new SubsystemSessionStub(
_sessionMock.Object,
_subsystemName,
- _operationTimeout,
- _encoding);
+ _operationTimeout);
_subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
_subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
}
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Connected.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Connected.cs
index dfe98c1c..f89da65c 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Connected.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Connected.cs
@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
- private Encoding _encoding;
private IList _disconnectedRegister;
private IList _errorOccurredRegister;
@@ -33,7 +32,6 @@ namespace Renci.SshNet.Tests.Classes
var random = new Random();
_subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
_operationTimeout = 30000;
- _encoding = Encoding.UTF8;
_disconnectedRegister = new List();
_errorOccurredRegister = new List();
@@ -49,8 +47,7 @@ namespace Renci.SshNet.Tests.Classes
_subsystemSession = new SubsystemSessionStub(
_sessionMock.Object,
_subsystemName,
- _operationTimeout,
- _encoding);
+ _operationTimeout);
_subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
_subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
_subsystemSession.Connect();
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Disconnected.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Disconnected.cs
index 2111db3b..c304ed43 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Disconnected.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Disconnected.cs
@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
- private Encoding _encoding;
private IList _disconnectedRegister;
private IList _errorOccurredRegister;
@@ -33,7 +32,6 @@ namespace Renci.SshNet.Tests.Classes
var random = new Random();
_subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
_operationTimeout = 30000;
- _encoding = Encoding.UTF8;
_disconnectedRegister = new List();
_errorOccurredRegister = new List();
@@ -49,8 +47,7 @@ namespace Renci.SshNet.Tests.Classes
_subsystemSession = new SubsystemSessionStub(
_sessionMock.Object,
_subsystemName,
- _operationTimeout,
- _encoding);
+ _operationTimeout);
_subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
_subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
_subsystemSession.Connect();
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Disposed.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Disposed.cs
index eb2e1d46..d2f93dec 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Disposed.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_Disposed.cs
@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
- private Encoding _encoding;
private IList _disconnectedRegister;
private IList _errorOccurredRegister;
@@ -33,7 +32,6 @@ namespace Renci.SshNet.Tests.Classes
var random = new Random();
_subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
_operationTimeout = 30000;
- _encoding = Encoding.UTF8;
_disconnectedRegister = new List();
_errorOccurredRegister = new List();
@@ -49,8 +47,7 @@ namespace Renci.SshNet.Tests.Classes
_subsystemSession = new SubsystemSessionStub(
_sessionMock.Object,
_subsystemName,
- _operationTimeout,
- _encoding);
+ _operationTimeout);
_subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
_subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
_subsystemSession.Connect();
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_NeverConnected.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_NeverConnected.cs
index 6c83b499..83fab899 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_NeverConnected.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSession_Dispose_NeverConnected.cs
@@ -16,7 +16,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
- private Encoding _encoding;
private IList _disconnectedRegister;
private IList _errorOccurredRegister;
@@ -32,7 +31,6 @@ namespace Renci.SshNet.Tests.Classes
var random = new Random();
_subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
_operationTimeout = 30000;
- _encoding = Encoding.UTF8;
_disconnectedRegister = new List();
_errorOccurredRegister = new List();
@@ -41,8 +39,7 @@ namespace Renci.SshNet.Tests.Classes
_subsystemSession = new SubsystemSessionStub(
_sessionMock.Object,
_subsystemName,
- _operationTimeout,
- _encoding);
+ _operationTimeout);
_subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
_subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
}
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_Connected.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_Connected.cs
index bdd03248..f8187a90 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_Connected.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_Connected.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
-using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Renci.SshNet.Channels;
@@ -17,7 +16,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
- private Encoding _encoding;
private IList _disconnectedRegister;
private IList _errorOccurredRegister;
private ChannelDataEventArgs _channelDataEventArgs;
@@ -35,7 +33,6 @@ namespace Renci.SshNet.Tests.Classes
var random = new Random();
_subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
_operationTimeout = 30000;
- _encoding = Encoding.UTF8;
_disconnectedRegister = new List();
_errorOccurredRegister = new List();
_channelDataEventArgs = new ChannelDataEventArgs(
@@ -53,8 +50,7 @@ namespace Renci.SshNet.Tests.Classes
_subsystemSession = new SubsystemSessionStub(
_sessionMock.Object,
_subsystemName,
- _operationTimeout,
- _encoding);
+ _operationTimeout);
_subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
_subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
_subsystemSession.Connect();
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_Disposed.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_Disposed.cs
index ec925926..33dfac88 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_Disposed.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_Disposed.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
-using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Renci.SshNet.Channels;
@@ -17,7 +16,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
- private Encoding _encoding;
private IList _disconnectedRegister;
private IList _errorOccurredRegister;
private ChannelDataEventArgs _channelDataEventArgs;
@@ -34,7 +32,6 @@ namespace Renci.SshNet.Tests.Classes
var random = new Random();
_subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
_operationTimeout = 30000;
- _encoding = Encoding.UTF8;
_disconnectedRegister = new List();
_errorOccurredRegister = new List();
_channelDataEventArgs = new ChannelDataEventArgs(
@@ -53,8 +50,7 @@ namespace Renci.SshNet.Tests.Classes
_subsystemSession = new SubsystemSessionStub(
_sessionMock.Object,
_subsystemName,
- _operationTimeout,
- _encoding);
+ _operationTimeout);
_subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
_subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
_subsystemSession.Connect();
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_OnDataReceived_Exception.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_OnDataReceived_Exception.cs
index a1e01413..43b9bbe3 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_OnDataReceived_Exception.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_OnDataReceived_Exception.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
-using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Renci.SshNet.Channels;
@@ -18,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
- private Encoding _encoding;
private IList _disconnectedRegister;
private IList _errorOccurredRegister;
private ChannelDataEventArgs _channelDataEventArgs;
@@ -36,7 +34,6 @@ namespace Renci.SshNet.Tests.Classes
var random = new Random();
_subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
_operationTimeout = 30000;
- _encoding = Encoding.UTF8;
_disconnectedRegister = new List();
_errorOccurredRegister = new List();
_channelDataEventArgs = new ChannelDataEventArgs(
@@ -55,8 +52,7 @@ namespace Renci.SshNet.Tests.Classes
_subsystemSession = new SubsystemSessionStub(
_sessionMock.Object,
_subsystemName,
- _operationTimeout,
- _encoding);
+ _operationTimeout);
_subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
_subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
_subsystemSession.OnDataReceivedException = _onDataReceivedException;
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelException_Connected.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelException_Connected.cs
index 774c2e91..e283c322 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelException_Connected.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelException_Connected.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
-using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Renci.SshNet.Channels;
@@ -18,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
- private Encoding _encoding;
private IList _disconnectedRegister;
private IList _errorOccurredRegister;
private ExceptionEventArgs _channelExceptionEventArgs;
@@ -36,7 +34,6 @@ namespace Renci.SshNet.Tests.Classes
var random = new Random();
_subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
_operationTimeout = 30000;
- _encoding = Encoding.UTF8;
_disconnectedRegister = new List();
_errorOccurredRegister = new List();
_channelExceptionEventArgs = new ExceptionEventArgs(new SystemException());
@@ -52,8 +49,7 @@ namespace Renci.SshNet.Tests.Classes
_subsystemSession = new SubsystemSessionStub(
_sessionMock.Object,
_subsystemName,
- _operationTimeout,
- _encoding);
+ _operationTimeout);
_subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
_subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
_subsystemSession.Connect();
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelException_Disposed.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelException_Disposed.cs
index 50a644e6..d9b3a162 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelException_Disposed.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelException_Disposed.cs
@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
- private Encoding _encoding;
private IList _disconnectedRegister;
private IList _errorOccurredRegister;
private ExceptionEventArgs _channelExceptionEventArgs;
@@ -34,7 +33,6 @@ namespace Renci.SshNet.Tests.Classes
var random = new Random();
_subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
_operationTimeout = 30000;
- _encoding = Encoding.UTF8;
_disconnectedRegister = new List();
_errorOccurredRegister = new List();
_channelExceptionEventArgs = new ExceptionEventArgs(new SystemException());
@@ -51,8 +49,7 @@ namespace Renci.SshNet.Tests.Classes
_subsystemSession = new SubsystemSessionStub(
_sessionMock.Object,
_subsystemName,
- _operationTimeout,
- _encoding);
+ _operationTimeout);
_subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
_subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
_subsystemSession.Connect();
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionDisconnected_Connected.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionDisconnected_Connected.cs
index 49d915a4..b6851cfc 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionDisconnected_Connected.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionDisconnected_Connected.cs
@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
- private Encoding _encoding;
private IList _disconnectedRegister;
private IList _errorOccurredRegister;
private MockSequence _sequence;
@@ -34,7 +33,6 @@ namespace Renci.SshNet.Tests.Classes
var random = new Random();
_subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
_operationTimeout = 30000;
- _encoding = Encoding.UTF8;
_disconnectedRegister = new List();
_errorOccurredRegister = new List();
@@ -49,8 +47,7 @@ namespace Renci.SshNet.Tests.Classes
_subsystemSession = new SubsystemSessionStub(
_sessionMock.Object,
_subsystemName,
- _operationTimeout,
- _encoding);
+ _operationTimeout);
_subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
_subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
_subsystemSession.Connect();
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionDisconnected_Disposed.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionDisconnected_Disposed.cs
index 094424d1..7a90eba4 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionDisconnected_Disposed.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionDisconnected_Disposed.cs
@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
- private Encoding _encoding;
private IList _disconnectedRegister;
private IList _errorOccurredRegister;
@@ -33,7 +32,6 @@ namespace Renci.SshNet.Tests.Classes
var random = new Random();
_subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
_operationTimeout = 30000;
- _encoding = Encoding.UTF8;
_disconnectedRegister = new List();
_errorOccurredRegister = new List();
@@ -49,8 +47,7 @@ namespace Renci.SshNet.Tests.Classes
_subsystemSession = new SubsystemSessionStub(
_sessionMock.Object,
_subsystemName,
- _operationTimeout,
- _encoding);
+ _operationTimeout);
_subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
_subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
_subsystemSession.Connect();
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionErrorOccurred_Connected.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionErrorOccurred_Connected.cs
index 66cd4173..32151eb9 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionErrorOccurred_Connected.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionErrorOccurred_Connected.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
-using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Renci.SshNet.Channels;
@@ -18,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
- private Encoding _encoding;
private IList _disconnectedRegister;
private IList _errorOccurredRegister;
private ExceptionEventArgs _errorOccurredEventArgs;
@@ -36,7 +34,6 @@ namespace Renci.SshNet.Tests.Classes
var random = new Random();
_subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
_operationTimeout = 30000;
- _encoding = Encoding.UTF8;
_disconnectedRegister = new List();
_errorOccurredRegister = new List();
_errorOccurredEventArgs = new ExceptionEventArgs(new SystemException());
@@ -52,8 +49,7 @@ namespace Renci.SshNet.Tests.Classes
_subsystemSession = new SubsystemSessionStub(
_sessionMock.Object,
_subsystemName,
- _operationTimeout,
- _encoding);
+ _operationTimeout);
_subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
_subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
_subsystemSession.Connect();
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionErrorOccurred_Disposed.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionErrorOccurred_Disposed.cs
index e3bd8bd9..df18c042 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionErrorOccurred_Disposed.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSession_OnSessionErrorOccurred_Disposed.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
-using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Renci.SshNet.Channels;
@@ -17,7 +16,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
- private Encoding _encoding;
private IList _disconnectedRegister;
private IList _errorOccurredRegister;
private ExceptionEventArgs _errorOccurredEventArgs;
@@ -34,7 +32,6 @@ namespace Renci.SshNet.Tests.Classes
var random = new Random();
_subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
_operationTimeout = 30000;
- _encoding = Encoding.UTF8;
_disconnectedRegister = new List();
_errorOccurredRegister = new List();
_errorOccurredEventArgs = new ExceptionEventArgs(new SystemException());
@@ -51,8 +48,7 @@ namespace Renci.SshNet.Tests.Classes
_subsystemSession = new SubsystemSessionStub(
_sessionMock.Object,
_subsystemName,
- _operationTimeout,
- _encoding);
+ _operationTimeout);
_subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
_subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
_subsystemSession.Connect();
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSession_SendData_Connected.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSession_SendData_Connected.cs
index ce2c6850..11a455c7 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSession_SendData_Connected.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSession_SendData_Connected.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
-using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Renci.SshNet.Channels;
@@ -17,7 +16,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
- private Encoding _encoding;
private IList _disconnectedRegister;
private IList _errorOccurredRegister;
private byte[] _data;
@@ -35,7 +33,6 @@ namespace Renci.SshNet.Tests.Classes
var random = new Random();
_subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
_operationTimeout = 30000;
- _encoding = Encoding.UTF8;
_disconnectedRegister = new List();
_errorOccurredRegister = new List();
_data = new[] {(byte) random.Next(byte.MinValue, byte.MaxValue)};
@@ -53,8 +50,7 @@ namespace Renci.SshNet.Tests.Classes
_subsystemSession = new SubsystemSessionStub(
_sessionMock.Object,
_subsystemName,
- _operationTimeout,
- _encoding);
+ _operationTimeout);
_subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
_subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
_subsystemSession.Connect();
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSession_SendData_Disposed.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSession_SendData_Disposed.cs
index 8935fc8e..b8ebc7fa 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSession_SendData_Disposed.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSession_SendData_Disposed.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
-using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Renci.SshNet.Channels;
@@ -17,7 +16,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
- private Encoding _encoding;
private IList _disconnectedRegister;
private IList _errorOccurredRegister;
private ObjectDisposedException _actualException;
@@ -34,7 +32,6 @@ namespace Renci.SshNet.Tests.Classes
var random = new Random();
_subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
_operationTimeout = 30000;
- _encoding = Encoding.UTF8;
_disconnectedRegister = new List();
_errorOccurredRegister = new List();
@@ -50,8 +47,7 @@ namespace Renci.SshNet.Tests.Classes
_subsystemSession = new SubsystemSessionStub(
_sessionMock.Object,
_subsystemName,
- _operationTimeout,
- _encoding);
+ _operationTimeout);
_subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
_subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
_subsystemSession.Connect();
diff --git a/src/Renci.SshNet.Tests/Classes/SubsystemSession_SendData_NeverConnected.cs b/src/Renci.SshNet.Tests/Classes/SubsystemSession_SendData_NeverConnected.cs
index 8d36e19c..3dd9f5cc 100644
--- a/src/Renci.SshNet.Tests/Classes/SubsystemSession_SendData_NeverConnected.cs
+++ b/src/Renci.SshNet.Tests/Classes/SubsystemSession_SendData_NeverConnected.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
-using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Renci.SshNet.Channels;
@@ -17,7 +16,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
- private Encoding _encoding;
private IList _disconnectedRegister;
private IList _errorOccurredRegister;
private InvalidOperationException _actualException;
@@ -36,7 +34,6 @@ namespace Renci.SshNet.Tests.Classes
var random = new Random();
_subsystemName = random.Next().ToString(CultureInfo.InvariantCulture);
_operationTimeout = 30000;
- _encoding = Encoding.UTF8;
_disconnectedRegister = new List();
_errorOccurredRegister = new List();
_data = new[] {(byte) random.Next(byte.MinValue, byte.MaxValue)};
@@ -53,8 +50,7 @@ namespace Renci.SshNet.Tests.Classes
_subsystemSession = new SubsystemSessionStub(
_sessionMock.Object,
_subsystemName,
- _operationTimeout,
- _encoding);
+ _operationTimeout);
_subsystemSession.Disconnected += (sender, args) => _disconnectedRegister.Add(args);
_subsystemSession.ErrorOccurred += (sender, args) => _errorOccurredRegister.Add(args);
}
diff --git a/src/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj b/src/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj
index 9bf0c4cd..9fc8daef 100644
--- a/src/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj
+++ b/src/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj
@@ -343,6 +343,7 @@
+
@@ -453,8 +454,19 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Renci.SshNet/IServiceFactory.cs b/src/Renci.SshNet/IServiceFactory.cs
index 7a2c35c0..dafc09c5 100644
--- a/src/Renci.SshNet/IServiceFactory.cs
+++ b/src/Renci.SshNet/IServiceFactory.cs
@@ -31,10 +31,11 @@ namespace Renci.SshNet
/// The to create the in.
/// The number of milliseconds to wait for an operation to complete, or -1 to wait indefinitely.
/// The encoding.
+ /// The factory to use for creating SFTP messages.
///
/// An .
///
- ISftpSession CreateSftpSession(ISession session, int operationTimeout, Encoding encoding);
+ ISftpSession CreateSftpSession(ISession session, int operationTimeout, Encoding encoding, ISftpResponseFactory sftpMessageFactory);
///
/// Create a new .
@@ -59,5 +60,7 @@ namespace Renci.SshNet
IKeyExchange CreateKeyExchange(IDictionary clientAlgorithms, string[] serverAlgorithms);
ISftpFileReader CreateSftpFileReader(string fileName, ISftpSession sftpSession, uint bufferSize);
+
+ ISftpResponseFactory CreateSftpMessageFactory();
}
}
diff --git a/src/Renci.SshNet/Netconf/NetConfSession.cs b/src/Renci.SshNet/Netconf/NetConfSession.cs
index d2c7b35d..14ba00a6 100644
--- a/src/Renci.SshNet/Netconf/NetConfSession.cs
+++ b/src/Renci.SshNet/Netconf/NetConfSession.cs
@@ -35,7 +35,7 @@ namespace Renci.SshNet.NetConf
/// The session.
/// The number of milliseconds to wait for an operation to complete, or -1 to wait indefinitely.
public NetConfSession(ISession session, int operationTimeout)
- : base(session, "netconf", operationTimeout, Encoding.UTF8)
+ : base(session, "netconf", operationTimeout)
{
ClientCapabilities = new XmlDocument();
ClientCapabilities.LoadXml("" +
diff --git a/src/Renci.SshNet/Renci.SshNet.csproj b/src/Renci.SshNet/Renci.SshNet.csproj
index 7b7a2631..28bca009 100644
--- a/src/Renci.SshNet/Renci.SshNet.csproj
+++ b/src/Renci.SshNet/Renci.SshNet.csproj
@@ -172,6 +172,7 @@
+
@@ -416,6 +417,7 @@
+
@@ -427,6 +429,7 @@
+
Code
diff --git a/src/Renci.SshNet/ServiceFactory.cs b/src/Renci.SshNet/ServiceFactory.cs
index b9ad0e95..f9cd7fc6 100644
--- a/src/Renci.SshNet/ServiceFactory.cs
+++ b/src/Renci.SshNet/ServiceFactory.cs
@@ -46,12 +46,13 @@ namespace Renci.SshNet
/// The to create the in.
/// The number of milliseconds to wait for an operation to complete, or -1 to wait indefinitely.
/// The encoding.
+ /// The factory to use for creating SFTP messages.
///
/// An .
///
- public ISftpSession CreateSftpSession(ISession session, int operationTimeout, Encoding encoding)
+ public ISftpSession CreateSftpSession(ISession session, int operationTimeout, Encoding encoding, ISftpResponseFactory sftpMessageFactory)
{
- return new SftpSession(session, operationTimeout, encoding);
+ return new SftpSession(session, operationTimeout, encoding, sftpMessageFactory);
}
///
@@ -130,5 +131,10 @@ namespace Renci.SshNet
return sftpSession.CreateFileReader(handle, sftpSession, chunkSize, maxPendingReads, fileSize);
}
+
+ public ISftpResponseFactory CreateSftpMessageFactory()
+ {
+ return new SftpResponseFactory();
+ }
}
}
diff --git a/src/Renci.SshNet/Sftp/ISftpMessageFactory.cs b/src/Renci.SshNet/Sftp/ISftpMessageFactory.cs
new file mode 100644
index 00000000..afb440c1
--- /dev/null
+++ b/src/Renci.SshNet/Sftp/ISftpMessageFactory.cs
@@ -0,0 +1,9 @@
+using System.Text;
+
+namespace Renci.SshNet.Sftp
+{
+ internal interface ISftpResponseFactory
+ {
+ SftpMessage Create(uint protocolVersion, byte messageType, Encoding encoding);
+ }
+}
diff --git a/src/Renci.SshNet/Sftp/Responses/SftpDataResponse.cs b/src/Renci.SshNet/Sftp/Responses/SftpDataResponse.cs
index 610f90b3..f15a8dcc 100644
--- a/src/Renci.SshNet/Sftp/Responses/SftpDataResponse.cs
+++ b/src/Renci.SshNet/Sftp/Responses/SftpDataResponse.cs
@@ -7,7 +7,7 @@
get { return SftpMessageTypes.Data; }
}
- public byte[] Data { get; private set; }
+ public byte[] Data { get; set; }
public SftpDataResponse(uint protocolVersion)
: base(protocolVersion)
@@ -20,5 +20,12 @@
Data = ReadBinary();
}
+
+ protected override void SaveData()
+ {
+ base.SaveData();
+
+ WriteBinary(Data, 0, Data.Length);
+ }
}
}
diff --git a/src/Renci.SshNet/Sftp/Responses/SftpHandleResponse.cs b/src/Renci.SshNet/Sftp/Responses/SftpHandleResponse.cs
index 2a856139..233e3e37 100644
--- a/src/Renci.SshNet/Sftp/Responses/SftpHandleResponse.cs
+++ b/src/Renci.SshNet/Sftp/Responses/SftpHandleResponse.cs
@@ -7,7 +7,7 @@
get { return SftpMessageTypes.Handle; }
}
- public byte[] Handle { get; private set; }
+ public byte[] Handle { get; set; }
public SftpHandleResponse(uint protocolVersion)
: base(protocolVersion)
@@ -20,5 +20,12 @@
Handle = ReadBinary();
}
+
+ protected override void SaveData()
+ {
+ base.SaveData();
+
+ WriteBinary(Handle, 0, Handle.Length);
+ }
}
}
diff --git a/src/Renci.SshNet/Sftp/Responses/SftpNameResponse.cs b/src/Renci.SshNet/Sftp/Responses/SftpNameResponse.cs
index ca5166b3..3750119d 100644
--- a/src/Renci.SshNet/Sftp/Responses/SftpNameResponse.cs
+++ b/src/Renci.SshNet/Sftp/Responses/SftpNameResponse.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using Renci.SshNet.Common;
+using System.Collections.Generic;
using System.Text;
namespace Renci.SshNet.Sftp.Responses
@@ -14,12 +15,12 @@ namespace Renci.SshNet.Sftp.Responses
public Encoding Encoding { get; private set; }
- public KeyValuePair[] Files { get; private set; }
+ public KeyValuePair[] Files { get; set; }
public SftpNameResponse(uint protocolVersion, Encoding encoding)
: base(protocolVersion)
{
- Files = new KeyValuePair[0];
+ Files = Array>.Empty;
Encoding = encoding;
}
@@ -29,14 +30,42 @@ namespace Renci.SshNet.Sftp.Responses
Count = ReadUInt32();
Files = new KeyValuePair[Count];
-
+
for (var i = 0; i < Count; i++)
{
var fileName = ReadString(Encoding);
- ReadString(Encoding); // skip longname
- var attributes = ReadAttributes();
- Files[i] = new KeyValuePair(fileName, attributes);
+ if (SupportsLongName(ProtocolVersion))
+ {
+ ReadString(Encoding); // skip longname
+ }
+ Files[i] = new KeyValuePair(fileName, ReadAttributes());
}
}
+
+ protected override void SaveData()
+ {
+ base.SaveData();
+
+ Write((uint) Files.Length); // count
+
+ for (var i = 0; i < Files.Length; i++)
+ {
+ var file = Files[i];
+
+ Write(file.Key, Encoding); // filename
+
+ if (SupportsLongName(ProtocolVersion))
+ {
+ Write(0U); // longname
+ }
+
+ Write(file.Value.GetBytes()); // attrs
+ }
+ }
+
+ private static bool SupportsLongName(uint protocolVersion)
+ {
+ return protocolVersion <= 3U;
+ }
}
}
diff --git a/src/Renci.SshNet/Sftp/Responses/SftpResponse.cs b/src/Renci.SshNet/Sftp/Responses/SftpResponse.cs
index 44fafef1..3b784bf0 100644
--- a/src/Renci.SshNet/Sftp/Responses/SftpResponse.cs
+++ b/src/Renci.SshNet/Sftp/Responses/SftpResponse.cs
@@ -1,10 +1,8 @@
-using System;
-
-namespace Renci.SshNet.Sftp.Responses
+namespace Renci.SshNet.Sftp.Responses
{
internal abstract class SftpResponse : SftpMessage
{
- public uint ResponseId { get; private set; }
+ public uint ResponseId { get; set; }
public uint ProtocolVersion { get; private set; }
@@ -22,7 +20,9 @@ namespace Renci.SshNet.Sftp.Responses
protected override void SaveData()
{
- throw new InvalidOperationException("Response cannot be saved.");
+ base.SaveData();
+
+ Write(ResponseId);
}
}
}
diff --git a/src/Renci.SshNet/Sftp/Responses/SftpVersionResponse.cs b/src/Renci.SshNet/Sftp/Responses/SftpVersionResponse.cs
index 642bd806..87c9f13f 100644
--- a/src/Renci.SshNet/Sftp/Responses/SftpVersionResponse.cs
+++ b/src/Renci.SshNet/Sftp/Responses/SftpVersionResponse.cs
@@ -9,9 +9,9 @@ namespace Renci.SshNet.Sftp.Responses
get { return SftpMessageTypes.Version; }
}
- public uint Version { get; private set; }
+ public uint Version { get; set; }
- public IDictionary Extentions { get; private set; }
+ public IDictionary Extentions { get; set; }
protected override void LoadData()
{
diff --git a/src/Renci.SshNet/Sftp/Responses/StatVfsResponse.cs b/src/Renci.SshNet/Sftp/Responses/StatVfsResponse.cs
index 6a6d36a9..e7b6c2ed 100644
--- a/src/Renci.SshNet/Sftp/Responses/StatVfsResponse.cs
+++ b/src/Renci.SshNet/Sftp/Responses/StatVfsResponse.cs
@@ -2,10 +2,10 @@
{
internal class StatVfsResponse : SftpExtendedReplyResponse
{
- public SftpFileSytemInformation Information { get; private set; }
+ public SftpFileSytemInformation Information { get; set; }
- public StatVfsResponse()
- : base(0)
+ public StatVfsResponse(uint protocolVersion)
+ : base(protocolVersion)
{
}
@@ -13,12 +13,25 @@
{
base.LoadData();
- this.Information = new SftpFileSytemInformation(this.ReadUInt64(), this.ReadUInt64(),
- this.ReadUInt64(), this.ReadUInt64(),
- this.ReadUInt64(), this.ReadUInt64(),
- this.ReadUInt64(), this.ReadUInt64(),
- this.ReadUInt64(), this.ReadUInt64(),
- this.ReadUInt64());
+ Information = new SftpFileSytemInformation(ReadUInt64(), // FileSystemBlockSize
+ ReadUInt64(), // BlockSize
+ ReadUInt64(), // TotalBlocks
+ ReadUInt64(), // FreeBlocks
+ ReadUInt64(), // AvailableBlocks
+ ReadUInt64(), // TotalNodes
+ ReadUInt64(), // FreeNodes
+ ReadUInt64(), // AvailableNodes
+ ReadUInt64(), // Sid
+ ReadUInt64(), // Flags
+ ReadUInt64() // MaxNameLenght
+ );
+ }
+
+ protected override void SaveData()
+ {
+ base.SaveData();
+
+ Information.SaveData(DataStream);
}
}
}
\ No newline at end of file
diff --git a/src/Renci.SshNet/Sftp/SftpFileSystemInformation.cs b/src/Renci.SshNet/Sftp/SftpFileSystemInformation.cs
index a8b73107..bff9295b 100644
--- a/src/Renci.SshNet/Sftp/SftpFileSystemInformation.cs
+++ b/src/Renci.SshNet/Sftp/SftpFileSystemInformation.cs
@@ -1,4 +1,6 @@
-namespace Renci.SshNet.Sftp
+using Renci.SshNet.Common;
+
+namespace Renci.SshNet.Sftp
{
///
/// Contains File system information exposed by statvfs@openssh.com request.
@@ -140,5 +142,20 @@
_flag = flag;
MaxNameLenght = namemax;
}
+
+ internal void SaveData(SshDataStream stream)
+ {
+ stream.Write(FileSystemBlockSize);
+ stream.Write(BlockSize);
+ stream.Write(TotalBlocks);
+ stream.Write(FreeBlocks);
+ stream.Write(AvailableBlocks);
+ stream.Write(TotalNodes);
+ stream.Write(FreeNodes);
+ stream.Write(AvailableNodes);
+ stream.Write(Sid);
+ stream.Write(_flag);
+ stream.Write(MaxNameLenght);
+ }
}
}
\ No newline at end of file
diff --git a/src/Renci.SshNet/Sftp/SftpMessage.cs b/src/Renci.SshNet/Sftp/SftpMessage.cs
index d6161497..8f131fa7 100644
--- a/src/Renci.SshNet/Sftp/SftpMessage.cs
+++ b/src/Renci.SshNet/Sftp/SftpMessage.cs
@@ -1,21 +1,11 @@
-using System;
-using System.IO;
+using System.IO;
using Renci.SshNet.Common;
using System.Globalization;
-using Renci.SshNet.Sftp.Responses;
-using System.Text;
namespace Renci.SshNet.Sftp
{
internal abstract class SftpMessage : SshData
{
- public static SftpMessage Load(uint protocolVersion, byte[] data, int offset, int count, Encoding encoding)
- {
- var messageType = (SftpMessageTypes) data[offset];
-
- return Load(protocolVersion, messageType, data, offset + 1, count - 1, encoding);
- }
-
///
/// Gets the size of the message in bytes.
///
@@ -79,42 +69,6 @@ namespace Renci.SshNet.Sftp
return SftpFileAttributes.FromBytes(DataStream);
}
- private static SftpMessage Load(uint protocolVersion, SftpMessageTypes messageType, byte[] data, int offset, int count, Encoding encoding)
- {
- SftpMessage message;
-
- switch (messageType)
- {
- case SftpMessageTypes.Version:
- message = new SftpVersionResponse();
- break;
- case SftpMessageTypes.Status:
- message = new SftpStatusResponse(protocolVersion);
- break;
- case SftpMessageTypes.Data:
- message = new SftpDataResponse(protocolVersion);
- break;
- case SftpMessageTypes.Handle:
- message = new SftpHandleResponse(protocolVersion);
- break;
- case SftpMessageTypes.Name:
- message = new SftpNameResponse(protocolVersion, encoding);
- break;
- case SftpMessageTypes.Attrs:
- message = new SftpAttrsResponse(protocolVersion);
- break;
- case SftpMessageTypes.ExtendedReply:
- message = new SftpExtendedReplyResponse(protocolVersion);
- break;
- default:
- throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Message type '{0}' is not supported.", messageType));
- }
-
- message.Load(data, offset, count);
-
- return message;
- }
-
public override string ToString()
{
return string.Format(CultureInfo.CurrentCulture, "SFTP Message : {0}", SftpMessageType);
diff --git a/src/Renci.SshNet/Sftp/SftpMessageFactory.cs b/src/Renci.SshNet/Sftp/SftpMessageFactory.cs
new file mode 100644
index 00000000..4fcbec1e
--- /dev/null
+++ b/src/Renci.SshNet/Sftp/SftpMessageFactory.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Text;
+using Renci.SshNet.Sftp.Responses;
+using System.Globalization;
+
+namespace Renci.SshNet.Sftp
+{
+ internal sealed class SftpResponseFactory : ISftpResponseFactory
+ {
+ public SftpMessage Create(uint protocolVersion, byte messageType, Encoding encoding)
+ {
+ var sftpMessageType = (SftpMessageTypes) messageType;
+
+ SftpMessage message;
+
+ switch (sftpMessageType)
+ {
+ case SftpMessageTypes.Version:
+ message = new SftpVersionResponse();
+ break;
+ case SftpMessageTypes.Status:
+ message = new SftpStatusResponse(protocolVersion);
+ break;
+ case SftpMessageTypes.Data:
+ message = new SftpDataResponse(protocolVersion);
+ break;
+ case SftpMessageTypes.Handle:
+ message = new SftpHandleResponse(protocolVersion);
+ break;
+ case SftpMessageTypes.Name:
+ message = new SftpNameResponse(protocolVersion, encoding);
+ break;
+ case SftpMessageTypes.Attrs:
+ message = new SftpAttrsResponse(protocolVersion);
+ break;
+ case SftpMessageTypes.ExtendedReply:
+ message = new SftpExtendedReplyResponse(protocolVersion);
+ break;
+ default:
+ throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Message type '{0}' is not supported.", sftpMessageType));
+ }
+
+ return message;
+ }
+
+ public
+ }
+}
diff --git a/src/Renci.SshNet/Sftp/SftpSession.cs b/src/Renci.SshNet/Sftp/SftpSession.cs
index 4f74f884..71846bdb 100644
--- a/src/Renci.SshNet/Sftp/SftpSession.cs
+++ b/src/Renci.SshNet/Sftp/SftpSession.cs
@@ -11,15 +11,21 @@ namespace Renci.SshNet.Sftp
{
internal class SftpSession : SubsystemSession, ISftpSession
{
- private const int MaximumSupportedVersion = 3;
+ internal const int MaximumSupportedVersion = 3;
private const int MinimumSupportedVersion = 0;
private readonly Dictionary _requests = new Dictionary();
+ private readonly ISftpResponseFactory _sftpMessageFactory;
//FIXME: obtain from SftpClient!
private readonly List _data = new List(32 * 1024);
private EventWaitHandle _sftpVersionConfirmed = new AutoResetEvent(false);
private IDictionary _supportedExtensions;
+ ///
+ /// Gets the character encoding to use.
+ ///
+ protected Encoding Encoding { get; private set; }
+
///
/// Gets the remote working directory.
///
@@ -49,9 +55,11 @@ namespace Renci.SshNet.Sftp
}
}
- public SftpSession(ISession session, int operationTimeout, Encoding encoding)
- : base(session, "sftp", operationTimeout, encoding)
+ public SftpSession(ISession session, int operationTimeout, Encoding encoding, ISftpResponseFactory sftpMessageFactory)
+ : base(session, "sftp", operationTimeout)
{
+ Encoding = encoding;
+ _sftpMessageFactory = sftpMessageFactory;
}
///
@@ -263,7 +271,7 @@ namespace Renci.SshNet.Sftp
// remove loaded data and bytes for length from _data holder
if (_data.Count == packetTotalLength)
{
- // the only buffered data is the data we're processing
+ // the only buffered data is the data we're processing
_data.Clear();
}
else
@@ -282,8 +290,10 @@ namespace Renci.SshNet.Sftp
private bool TryLoadSftpMessage(byte[] packetData, int offset, int count)
{
- // Load SFTP Message and handle it
- var response = SftpMessage.Load(ProtocolVersion, packetData, offset, count, Encoding);
+ // Create SFTP message
+ var response = _sftpMessageFactory.Create(ProtocolVersion, packetData[offset], Encoding);
+ // Load message data into it
+ response.Load(packetData, offset + 1, count - 1);
try
{
@@ -1513,6 +1523,8 @@ namespace Renci.SshNet.Sftp
// bytes 6 to 9: response id
// bytes 10 to 13: length of payload
//
+ // WinSCP uses a payload length of 32755 bytes
+ //
// most ssh servers limit the size of the payload of a SSH_MSG_CHANNEL_DATA
// response to 16 KB; if we requested 16 KB of data, then the SSH_FXP_DATA
// payload of the SSH_MSG_CHANNEL_DATA message would be too big (16 KB + 13 bytes), and
@@ -1544,6 +1556,10 @@ namespace Renci.SshNet.Sftp
//
// 14-21: offset
// 22-25: data length
+
+ // Putty uses data length of 4096 bytes
+ // WinSCP uses data length of 32739 bytes (total 32768 bytes; 32739 + 25 + 4 bytes for handle)
+
var lengthOfNonDataProtocolFields = 25u + (uint)handle.Length;
var maximumPacketSize = Channel.RemotePacketSize;
return Math.Min(bufferSize, maximumPacketSize) - lengthOfNonDataProtocolFields;
diff --git a/src/Renci.SshNet/SftpClient.cs b/src/Renci.SshNet/SftpClient.cs
index d6b83aa2..2de6cbfe 100644
--- a/src/Renci.SshNet/SftpClient.cs
+++ b/src/Renci.SshNet/SftpClient.cs
@@ -240,7 +240,7 @@ namespace Renci.SshNet
: base(connectionInfo, ownsConnectionInfo, serviceFactory)
{
_operationTimeout = SshNet.Session.Infinite;
- BufferSize = 1024 * 32;
+ _bufferSize = 1024 * 32;
}
#endregion Constructors
@@ -1375,8 +1375,7 @@ namespace Renci.SshNet
{
CheckDisposed();
- return new SftpFileStream(_sftpSession, path, FileMode.OpenOrCreate, FileAccess.Write,
- (int) _bufferSize);
+ return new SftpFileStream(_sftpSession, path, FileMode.OpenOrCreate, FileAccess.Write, (int) _bufferSize);
}
///
@@ -2123,7 +2122,7 @@ namespace Renci.SshNet
{
base.OnConnected();
- _sftpSession = ServiceFactory.CreateSftpSession(Session, _operationTimeout, ConnectionInfo.Encoding);
+ _sftpSession = ServiceFactory.CreateSftpSession(Session, _operationTimeout, ConnectionInfo.Encoding, ServiceFactory.CreateSftpMessageFactory());
_sftpSession.Connect();
}
diff --git a/src/Renci.SshNet/SubsystemSession.cs b/src/Renci.SshNet/SubsystemSession.cs
index d8a64305..4aa52d5c 100644
--- a/src/Renci.SshNet/SubsystemSession.cs
+++ b/src/Renci.SshNet/SubsystemSession.cs
@@ -1,6 +1,5 @@
using System;
using System.Globalization;
-using System.Text;
using System.Threading;
using Renci.SshNet.Abstractions;
using Renci.SshNet.Channels;
@@ -72,32 +71,23 @@ namespace Renci.SshNet
get { return _channel != null && _channel.IsOpen; }
}
- ///
- /// Gets the character encoding to use.
- ///
- protected Encoding Encoding { get; private set; }
-
///
/// Initializes a new instance of the SubsystemSession class.
///
/// The session.
/// Name of the subsystem.
/// The number of milliseconds to wait for a given operation to complete, or -1 to wait indefinitely.
- /// The character encoding to use.
- /// or or is null.
- protected SubsystemSession(ISession session, string subsystemName, int operationTimeout, Encoding encoding)
+ /// or is null.
+ protected SubsystemSession(ISession session, string subsystemName, int operationTimeout)
{
if (session == null)
throw new ArgumentNullException("session");
if (subsystemName == null)
throw new ArgumentNullException("subsystemName");
- if (encoding == null)
- throw new ArgumentNullException("encoding");
_session = session;
_subsystemName = subsystemName;
OperationTimeout = operationTimeout;
- Encoding = encoding;
}
///