Remove Encoding from SubsystemSession and NetConfSession, and move it to SftpSession (as it is only used there).

Refactor creation of SFTP response messages to a SftpResponseFactory.
Implement SaveData for a few SFTP response messages.
This commit is contained in:
Gert Driesen
2017-08-06 18:33:28 +02:00
parent 9ecfa0d38c
commit e2cf28a28d
61 changed files with 1620 additions and 513 deletions
@@ -97,6 +97,10 @@
<Version>4.0.1</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Compile Update="..\Renci.SshNet\Sftp\ISftpMessageFactory.cs" Link="Sftp\ISftpResponseFactory.cs" />
<Compile Update="..\Renci.SshNet\Sftp\SftpMessageFactory.cs" Link="Sftp\SftpResponseFactory.cs" />
</ItemGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
<DefineConstants>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</DefineConstants>
</PropertyGroup>
@@ -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
};
}
}
}
@@ -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;
}
}
}
@@ -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);
}
}
}
@@ -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<KeyValuePair<string, SftpFileAttributes>> _files;
public SftpNameResponseBuilder()
{
_files = new List<KeyValuePair<string, SftpFileAttributes>>();
}
public SftpNameResponseBuilder WithProtocolVersion(uint protocolVersion)
{
_protocolVersion = protocolVersion;
return this;
}
public SftpNameResponseBuilder WithResponseId(uint responseId)
{
_responseId = responseId;
return this;
}
public SftpNameResponseBuilder WithFiles(params KeyValuePair<string, SftpFileAttributes>[] 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<string, SftpFileAttributes>(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;
}
}
}
@@ -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<SftpHandleResponse> _handleAction;
private Action<SftpStatusResponse> _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<SftpHandleResponse> handleAction)
{
_handleAction = handleAction;
return this;
}
public SftpOpenRequestBuilder WithStatusAction(Action<SftpStatusResponse> 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);
}
}
}
@@ -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<SftpDataResponse> _dataAction;
private Action<SftpStatusResponse> _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<SftpDataResponse> dataAction)
{
_dataAction = dataAction;
return this;
}
public SftpReadRequestBuilder WithStatusAction(Action<SftpStatusResponse> 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);
}
}
}
@@ -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<SftpNameResponse> _nameAction;
private Action<SftpStatusResponse> _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<SftpNameResponse> nameAction)
{
_nameAction = nameAction;
return this;
}
public SftpRealPathRequestBuilder WithStatusAction(Action<SftpStatusResponse> 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);
}
}
}
@@ -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<ISession> _sessionMock;
private Mock<IChannelSession> _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<ISession>(MockBehavior.Strict);
_channelSessionMock = new Mock<IChannelSession>(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<byte[]>())).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<byte[]>())).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<byte[]>())).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<byte>();
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));
}
}
}
@@ -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<ISession> _sessionMock;
private Mock<IChannelSession> _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<ISession>(MockBehavior.Strict);
_channelSessionMock = new Mock<IChannelSession>(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<byte[]>())).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<byte[]>())).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<byte[]>())).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<byte>();
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();
}
}
}
}
}
@@ -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<ISession> _sessionMock;
private Mock<IChannelSession> _channelSessionMock;
private Mock<ISftpResponseFactory> _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<ISession>(MockBehavior.Strict);
_channelSessionMock = new Mock<IChannelSession>(MockBehavior.Strict);
_sftpMessageFactoryMock = new Mock<ISftpResponseFactory>(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));
}
}
}
@@ -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<ISession> _sessionMock;
private Mock<IChannelSession> _channelSessionMock;
private Mock<ISftpResponseFactory> _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<ISession>(MockBehavior.Strict);
_channelSessionMock = new Mock<IChannelSession>(MockBehavior.Strict);
_sftpMessageFactoryMock = new Mock<ISftpResponseFactory>(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));
}
}
}
@@ -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<ISession> _sessionMock;
private Mock<IChannelSession> _channelSessionMock;
private Mock<ISftpResponseFactory> _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<ISession>(MockBehavior.Strict);
_channelSessionMock = new Mock<IChannelSession>(MockBehavior.Strict);
_sftpMessageFactoryMock = new Mock<ISftpResponseFactory>(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));
}
}
}
@@ -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<SftpExtendedReplyResponse> _extendedAction;
private Action<SftpStatusResponse> _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<SftpExtendedReplyResponse> extendedAction)
{
_extendedAction = extendedAction;
return this;
}
public SftpStatVfsRequestBuilder WithStatusAction(Action<SftpStatusResponse> 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);
}
}
}
@@ -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
};
}
}
}
@@ -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<string, string> _extensions;
private uint _version;
private IDictionary<string, string> _extensions;
private SftpVersionResponseBuilder(uint version)
public SftpVersionResponseBuilder()
{
_version = version;
_extensions = new Dictionary<string, string>();
}
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;
}
}
}
@@ -10,9 +10,10 @@ namespace Renci.SshNet.Tests.Classes
{
private Mock<IServiceFactory> _serviceFactoryMock;
private Mock<ISession> _sessionMock;
private Mock<ISftpResponseFactory> _sftpMessageFactoryMock;
private Mock<ISftpSession> _sftpSessionMock;
private SftpClient _sftpClient;
private ConnectionInfo _connectionInfo;
private Mock<ISftpSession> _sftpSessionMock;
private int _operationTimeout;
[TestInitialize]
@@ -31,6 +32,7 @@ namespace Renci.SshNet.Tests.Classes
{
_serviceFactoryMock = new Mock<IServiceFactory>(MockBehavior.Strict);
_sessionMock = new Mock<ISession>(MockBehavior.Strict);
_sftpMessageFactoryMock = new Mock<ISftpResponseFactory>(MockBehavior.Strict);
_sftpSessionMock = new Mock<ISftpSession>(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);
}
@@ -10,9 +10,11 @@ namespace Renci.SshNet.Tests.Classes
{
private Mock<IServiceFactory> _serviceFactoryMock;
private Mock<ISession> _sessionMock;
private Mock<ISftpResponseFactory> _sftpMessageFactoryMock;
private Mock<ISftpSession> _sftpSessionMock;
private SftpClient _sftpClient;
private ConnectionInfo _connectionInfo;
private Mock<ISftpSession> _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<IServiceFactory>(MockBehavior.Strict);
_sessionMock = new Mock<ISession>(MockBehavior.Strict);
_sftpMessageFactoryMock = new Mock<ISftpResponseFactory>(MockBehavior.Strict);
_sftpSessionMock = new Mock<ISftpSession>(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);
}
@@ -10,9 +10,10 @@ namespace Renci.SshNet.Tests.Classes
{
private Mock<IServiceFactory> _serviceFactoryMock;
private Mock<ISession> _sessionMock;
private Mock<ISftpResponseFactory> _sftpMessageFactoryMock;
private Mock<ISftpSession> _sftpSessionMock;
private SftpClient _sftpClient;
private ConnectionInfo _connectionInfo;
private Mock<ISftpSession> _sftpSessionMock;
private int _operationTimeout;
[TestInitialize]
@@ -31,6 +32,7 @@ namespace Renci.SshNet.Tests.Classes
{
_serviceFactoryMock = new Mock<IServiceFactory>(MockBehavior.Strict);
_sessionMock = new Mock<ISession>(MockBehavior.Strict);
_sftpMessageFactoryMock = new Mock<ISftpResponseFactory>(MockBehavior.Strict);
_sftpSessionMock = new Mock<ISftpSession>(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);
}
@@ -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<IServiceFactory> _serviceFactoryMock;
private Mock<ISession> _sessionMock;
private Mock<ISftpResponseFactory> _sftpMessageFactoryMock;
private Mock<ISftpSession> _sftpSessionMock;
private SftpClient _sftpClient;
private ConnectionInfo _connectionInfo;
private Mock<ISftpSession> _sftpSessionMock;
private int _operationTimeout;
[TestInitialize]
@@ -27,6 +27,7 @@ namespace Renci.SshNet.Tests.Classes
{
_serviceFactoryMock = new Mock<IServiceFactory>(MockBehavior.Loose);
_sessionMock = new Mock<ISession>(MockBehavior.Strict);
_sftpMessageFactoryMock = new Mock<ISftpResponseFactory>(MockBehavior.Strict);
_sftpSessionMock = new Mock<ISftpSession>(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;
@@ -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<ChannelDataEventArgs>();
}
@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
private Encoding _encoding;
private IList<EventArgs> _disconnectedRegister;
private IList<ExceptionEventArgs> _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<EventArgs>();
_errorOccurredRegister = new List<ExceptionEventArgs>();
@@ -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();
@@ -18,7 +18,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
private Encoding _encoding;
private IList<EventArgs> _disconnectedRegister;
private IList<ExceptionEventArgs> _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<EventArgs>();
_errorOccurredRegister = new List<ExceptionEventArgs>();
@@ -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();
@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
private Encoding _encoding;
private IList<EventArgs> _disconnectedRegister;
private IList<ExceptionEventArgs> _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<EventArgs>();
_errorOccurredRegister = new List<ExceptionEventArgs>();
@@ -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();
@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
private Encoding _encoding;
private IList<EventArgs> _disconnectedRegister;
private IList<ExceptionEventArgs> _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<EventArgs>();
_errorOccurredRegister = new List<ExceptionEventArgs>();
@@ -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();
@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
private Encoding _encoding;
private IList<EventArgs> _disconnectedRegister;
private IList<ExceptionEventArgs> _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<EventArgs>();
_errorOccurredRegister = new List<ExceptionEventArgs>();
@@ -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();
@@ -15,7 +15,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
private Encoding _encoding;
private IList<EventArgs> _disconnectedRegister;
private IList<ExceptionEventArgs> _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<EventArgs>();
_errorOccurredRegister = new List<ExceptionEventArgs>();
@@ -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);
}
@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
private Encoding _encoding;
private IList<EventArgs> _disconnectedRegister;
private IList<ExceptionEventArgs> _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<EventArgs>();
_errorOccurredRegister = new List<ExceptionEventArgs>();
@@ -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();
@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
private Encoding _encoding;
private IList<EventArgs> _disconnectedRegister;
private IList<ExceptionEventArgs> _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<EventArgs>();
_errorOccurredRegister = new List<ExceptionEventArgs>();
@@ -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();
@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
private Encoding _encoding;
private IList<EventArgs> _disconnectedRegister;
private IList<ExceptionEventArgs> _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<EventArgs>();
_errorOccurredRegister = new List<ExceptionEventArgs>();
@@ -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();
@@ -16,7 +16,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
private Encoding _encoding;
private IList<EventArgs> _disconnectedRegister;
private IList<ExceptionEventArgs> _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<EventArgs>();
_errorOccurredRegister = new List<ExceptionEventArgs>();
@@ -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);
}
@@ -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<EventArgs> _disconnectedRegister;
private IList<ExceptionEventArgs> _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<EventArgs>();
_errorOccurredRegister = new List<ExceptionEventArgs>();
_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();
@@ -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<EventArgs> _disconnectedRegister;
private IList<ExceptionEventArgs> _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<EventArgs>();
_errorOccurredRegister = new List<ExceptionEventArgs>();
_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();
@@ -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<EventArgs> _disconnectedRegister;
private IList<ExceptionEventArgs> _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<EventArgs>();
_errorOccurredRegister = new List<ExceptionEventArgs>();
_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;
@@ -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<EventArgs> _disconnectedRegister;
private IList<ExceptionEventArgs> _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<EventArgs>();
_errorOccurredRegister = new List<ExceptionEventArgs>();
_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();
@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
private Encoding _encoding;
private IList<EventArgs> _disconnectedRegister;
private IList<ExceptionEventArgs> _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<EventArgs>();
_errorOccurredRegister = new List<ExceptionEventArgs>();
_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();
@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
private Encoding _encoding;
private IList<EventArgs> _disconnectedRegister;
private IList<ExceptionEventArgs> _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<EventArgs>();
_errorOccurredRegister = new List<ExceptionEventArgs>();
@@ -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();
@@ -17,7 +17,6 @@ namespace Renci.SshNet.Tests.Classes
private string _subsystemName;
private SubsystemSessionStub _subsystemSession;
private int _operationTimeout;
private Encoding _encoding;
private IList<EventArgs> _disconnectedRegister;
private IList<ExceptionEventArgs> _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<EventArgs>();
_errorOccurredRegister = new List<ExceptionEventArgs>();
@@ -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();
@@ -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<EventArgs> _disconnectedRegister;
private IList<ExceptionEventArgs> _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<EventArgs>();
_errorOccurredRegister = new List<ExceptionEventArgs>();
_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();
@@ -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<EventArgs> _disconnectedRegister;
private IList<ExceptionEventArgs> _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<EventArgs>();
_errorOccurredRegister = new List<ExceptionEventArgs>();
_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();
@@ -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<EventArgs> _disconnectedRegister;
private IList<ExceptionEventArgs> _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<EventArgs>();
_errorOccurredRegister = new List<ExceptionEventArgs>();
_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();
@@ -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<EventArgs> _disconnectedRegister;
private IList<ExceptionEventArgs> _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<EventArgs>();
_errorOccurredRegister = new List<ExceptionEventArgs>();
@@ -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();
@@ -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<EventArgs> _disconnectedRegister;
private IList<ExceptionEventArgs> _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<EventArgs>();
_errorOccurredRegister = new List<ExceptionEventArgs>();
_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);
}
@@ -343,6 +343,7 @@
<Compile Include="Classes\SftpClientTest_Dispose_Disconnected.cs" />
<Compile Include="Classes\SftpClientTest_Dispose_Disposed.cs" />
<Compile Include="Classes\SftpClientTest_Finalize_Connected.cs" />
<Compile Include="Classes\Sftp\SftpDataResponseBuilder.cs" />
<Compile Include="Classes\Sftp\SftpFileReaderTestBase.cs" />
<Compile Include="Classes\Sftp\SftpFileReaderTest_DisposeShouldUnblockReadAndReadAhead.cs" />
<Compile Include="Classes\Sftp\SftpFileReaderTest_LastChunkBeforeEofIsComplete.cs" />
@@ -453,8 +454,19 @@
<Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeAppend_FileAccessReadWrite.cs" />
<Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeAppend_FileAccessWrite.cs" />
<Compile Include="Classes\Sftp\SftpFileTest.cs" />
<Compile Include="Classes\Sftp\SftpHandleResponseBuilder.cs" />
<Compile Include="Classes\Sftp\SftpInitRequestBuilder.cs" />
<Compile Include="Classes\Sftp\SftpNameResponseBuilder.cs" />
<Compile Include="Classes\Sftp\SftpOpenRequestBuilder.cs" />
<Compile Include="Classes\Sftp\SftpReadRequestBuilder.cs" />
<Compile Include="Classes\Sftp\SftpRealPathRequestBuilder.cs" />
<Compile Include="Classes\Sftp\SftpSessionTest_Connected_RequestRead.cs" />
<Compile Include="Classes\Sftp\SftpSessionTest_Connected_RequestStatVfs.cs" />
<Compile Include="Classes\Sftp\SftpSessionTest_DataReceived_MultipleSftpMessagesInSingleSshDataMessage.cs" />
<Compile Include="Classes\Sftp\SftpSessionTest_DataReceived_MultipleSftpMessagesSplitOverMultipleSshDataMessages.cs" />
<Compile Include="Classes\Sftp\SftpSessionTest_DataReceived_SingleSftpMessageInSshDataMessage.cs" />
<Compile Include="Classes\Sftp\SftpStatVfsRequestBuilder.cs" />
<Compile Include="Classes\Sftp\SftpStatVfsResponseBuilder.cs" />
<Compile Include="Classes\Sftp\SftpVersionResponseBuilder.cs" />
<Compile Include="Classes\ShellTestTest.cs" />
<Compile Include="Classes\ShellStreamTest.cs" />
+4 -1
View File
@@ -31,10 +31,11 @@ namespace Renci.SshNet
/// <param name="session">The <see cref="ISession"/> to create the <see cref="ISftpSession"/> in.</param>
/// <param name="operationTimeout">The number of milliseconds to wait for an operation to complete, or -1 to wait indefinitely.</param>
/// <param name="encoding">The encoding.</param>
/// <param name="sftpMessageFactory">The factory to use for creating SFTP messages.</param>
/// <returns>
/// An <see cref="ISftpSession"/>.
/// </returns>
ISftpSession CreateSftpSession(ISession session, int operationTimeout, Encoding encoding);
ISftpSession CreateSftpSession(ISession session, int operationTimeout, Encoding encoding, ISftpResponseFactory sftpMessageFactory);
/// <summary>
/// Create a new <see cref="PipeStream"/>.
@@ -59,5 +60,7 @@ namespace Renci.SshNet
IKeyExchange CreateKeyExchange(IDictionary<string, Type> clientAlgorithms, string[] serverAlgorithms);
ISftpFileReader CreateSftpFileReader(string fileName, ISftpSession sftpSession, uint bufferSize);
ISftpResponseFactory CreateSftpMessageFactory();
}
}
+1 -1
View File
@@ -35,7 +35,7 @@ namespace Renci.SshNet.NetConf
/// <param name="session">The session.</param>
/// <param name="operationTimeout">The number of milliseconds to wait for an operation to complete, or -1 to wait indefinitely.</param>
public NetConfSession(ISession session, int operationTimeout)
: base(session, "netconf", operationTimeout, Encoding.UTF8)
: base(session, "netconf", operationTimeout)
{
ClientCapabilities = new XmlDocument();
ClientCapabilities.LoadXml("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
+3
View File
@@ -172,6 +172,7 @@
<Compile Include="ServiceFactory.cs" />
<Compile Include="ServiceFactory.NET.cs" />
<Compile Include="Sftp\ISftpFileReader.cs" />
<Compile Include="Sftp\ISftpMessageFactory.cs" />
<Compile Include="Sftp\ISftpSession.cs" />
<Compile Include="Common\SshDataStream.cs" />
<Compile Include="ExpectAsyncResult.cs" />
@@ -416,6 +417,7 @@
<Compile Include="Sftp\Responses\SftpResponse.cs" />
<Compile Include="Sftp\Responses\SftpStatusResponse.cs" />
<Compile Include="Sftp\Responses\SftpVersionResponse.cs" />
<Compile Include="Sftp\Responses\StatVfsResponse.cs" />
<Compile Include="Sftp\SftpCloseAsyncResult.cs" />
<Compile Include="Sftp\SftpDownloadAsyncResult.cs" />
<Compile Include="Sftp\SftpFile.cs" />
@@ -427,6 +429,7 @@
</Compile>
<Compile Include="Sftp\SftpListDirectoryAsyncResult.cs" />
<Compile Include="Sftp\SftpMessage.cs" />
<Compile Include="Sftp\SftpMessageFactory.cs" />
<Compile Include="Sftp\SftpMessageTypes.cs">
<SubType>Code</SubType>
</Compile>
+8 -2
View File
@@ -46,12 +46,13 @@ namespace Renci.SshNet
/// <param name="session">The <see cref="ISession"/> to create the <see cref="ISftpSession"/> in.</param>
/// <param name="operationTimeout">The number of milliseconds to wait for an operation to complete, or -1 to wait indefinitely.</param>
/// <param name="encoding">The encoding.</param>
/// <param name="sftpMessageFactory">The factory to use for creating SFTP messages.</param>
/// <returns>
/// An <see cref="ISftpSession"/>.
/// </returns>
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);
}
/// <summary>
@@ -130,5 +131,10 @@ namespace Renci.SshNet
return sftpSession.CreateFileReader(handle, sftpSession, chunkSize, maxPendingReads, fileSize);
}
public ISftpResponseFactory CreateSftpMessageFactory()
{
return new SftpResponseFactory();
}
}
}
@@ -0,0 +1,9 @@
using System.Text;
namespace Renci.SshNet.Sftp
{
internal interface ISftpResponseFactory
{
SftpMessage Create(uint protocolVersion, byte messageType, Encoding encoding);
}
}
@@ -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);
}
}
}
@@ -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);
}
}
}
@@ -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<string, SftpFileAttributes>[] Files { get; private set; }
public KeyValuePair<string, SftpFileAttributes>[] Files { get; set; }
public SftpNameResponse(uint protocolVersion, Encoding encoding)
: base(protocolVersion)
{
Files = new KeyValuePair<string, SftpFileAttributes>[0];
Files = Array<KeyValuePair<string, SftpFileAttributes>>.Empty;
Encoding = encoding;
}
@@ -29,14 +30,42 @@ namespace Renci.SshNet.Sftp.Responses
Count = ReadUInt32();
Files = new KeyValuePair<string, SftpFileAttributes>[Count];
for (var i = 0; i < Count; i++)
{
var fileName = ReadString(Encoding);
ReadString(Encoding); // skip longname
var attributes = ReadAttributes();
Files[i] = new KeyValuePair<string, SftpFileAttributes>(fileName, attributes);
if (SupportsLongName(ProtocolVersion))
{
ReadString(Encoding); // skip longname
}
Files[i] = new KeyValuePair<string, SftpFileAttributes>(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;
}
}
}
@@ -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);
}
}
}
@@ -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<string, string> Extentions { get; private set; }
public IDictionary<string, string> Extentions { get; set; }
protected override void LoadData()
{
@@ -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);
}
}
}
@@ -1,4 +1,6 @@
namespace Renci.SshNet.Sftp
using Renci.SshNet.Common;
namespace Renci.SshNet.Sftp
{
/// <summary>
/// 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);
}
}
}
+1 -47
View File
@@ -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);
}
/// <summary>
/// Gets the size of the message in bytes.
/// </summary>
@@ -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);
@@ -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
}
}
+22 -6
View File
@@ -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<uint, SftpRequest> _requests = new Dictionary<uint, SftpRequest>();
private readonly ISftpResponseFactory _sftpMessageFactory;
//FIXME: obtain from SftpClient!
private readonly List<byte> _data = new List<byte>(32 * 1024);
private EventWaitHandle _sftpVersionConfirmed = new AutoResetEvent(false);
private IDictionary<string, string> _supportedExtensions;
/// <summary>
/// Gets the character encoding to use.
/// </summary>
protected Encoding Encoding { get; private set; }
/// <summary>
/// Gets the remote working directory.
/// </summary>
@@ -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;
}
/// <summary>
@@ -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
// <handle>
// 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;
+3 -4
View File
@@ -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);
}
/// <summary>
@@ -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();
}
+2 -12
View File
@@ -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; }
}
/// <summary>
/// Gets the character encoding to use.
/// </summary>
protected Encoding Encoding { get; private set; }
/// <summary>
/// Initializes a new instance of the SubsystemSession class.
/// </summary>
/// <param name="session">The session.</param>
/// <param name="subsystemName">Name of the subsystem.</param>
/// <param name="operationTimeout">The number of milliseconds to wait for a given operation to complete, or -1 to wait indefinitely.</param>
/// <param name="encoding">The character encoding to use.</param>
/// <exception cref="ArgumentNullException"><paramref name="session" /> or <paramref name="subsystemName" /> or <paramref name="encoding"/> is <c>null</c>.</exception>
protected SubsystemSession(ISession session, string subsystemName, int operationTimeout, Encoding encoding)
/// <exception cref="ArgumentNullException"><paramref name="session" /> or <paramref name="subsystemName" /> is <c>null</c>.</exception>
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;
}
/// <summary>