Skip to content

Commit

Permalink
Pass buffer size to ShellStream ctor.
Browse files Browse the repository at this point in the history
Fixes issue sshnet#303.

Added tests for issue sshnet#303 and PR sshnet#211.
  • Loading branch information
drieseng committed Sep 17, 2017
1 parent 985e3f3 commit c3d43b6
Show file tree
Hide file tree
Showing 19 changed files with 1,822 additions and 19 deletions.
38 changes: 37 additions & 1 deletion src/Renci.SshNet.Tests.NET35/Renci.SshNet.Tests.NET35.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,9 @@
<Compile Include="..\Renci.SshNet.Tests\Classes\ServiceFactoryTest_CreateSftpFileReader_FileSizeIsZero.cs">
<Link>Classes\ServiceFactoryTest_CreateSftpFileReader_FileSizeIsZero.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Tests\Classes\ServiceFactoryTest_CreateShellStream.cs">
<Link>Classes\ServiceFactoryTest_CreateShellStream.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Tests\Classes\SessionTest.cs">
<Link>Classes\SessionTest.cs</Link>
</Compile>
Expand Down Expand Up @@ -1425,12 +1428,45 @@
<Compile Include="..\Renci.SshNet.Tests\Classes\ShellStreamTest.cs">
<Link>Classes\ShellStreamTest.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Tests\Classes\ShellStreamTest_Write_WriteBufferEmptyAndWriteLessBytesThanBufferSize.cs">
<Link>Classes\ShellStreamTest_Write_WriteBufferEmptyAndWriteLessBytesThanBufferSize.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Tests\Classes\ShellStreamTest_Write_WriteBufferEmptyAndWriteMoreBytesThanBufferSize.cs">
<Link>Classes\ShellStreamTest_Write_WriteBufferEmptyAndWriteMoreBytesThanBufferSize.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Tests\Classes\ShellStreamTest_Write_WriteBufferEmptyAndWriteNumberOfBytesEqualToBufferSize.cs">
<Link>Classes\ShellStreamTest_Write_WriteBufferEmptyAndWriteNumberOfBytesEqualToBufferSize.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Tests\Classes\ShellStreamTest_Write_WriteBufferEmptyAndWriteZeroBytes.cs">
<Link>Classes\ShellStreamTest_Write_WriteBufferEmptyAndWriteZeroBytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Tests\Classes\ShellStreamTest_Write_WriteBufferFullAndWriteLessBytesThanBufferSize.cs">
<Link>Classes\ShellStreamTest_Write_WriteBufferFullAndWriteLessBytesThanBufferSize.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Tests\Classes\ShellStreamTest_Write_WriteBufferFullAndWriteZeroBytes.cs">
<Link>Classes\ShellStreamTest_Write_WriteBufferFullAndWriteZeroBytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Tests\Classes\ShellStreamTest_Write_WriteBufferNotEmptyAndWriteLessBytesThanBufferCanContain.cs">
<Link>Classes\ShellStreamTest_Write_WriteBufferNotEmptyAndWriteLessBytesThanBufferCanContain.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Tests\Classes\ShellStreamTest_Write_WriteBufferNotEmptyAndWriteMoreBytesThanBufferCanContain.cs">
<Link>Classes\ShellStreamTest_Write_WriteBufferNotEmptyAndWriteMoreBytesThanBufferCanContain.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Tests\Classes\ShellStreamTest_Write_WriteBufferNotEmptyAndWriteZeroBytes.cs">
<Link>Classes\ShellStreamTest_Write_WriteBufferNotEmptyAndWriteZeroBytes.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Tests\Classes\ShellTestTest.cs">
<Link>Classes\ShellTestTest.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Tests\Classes\SshClientTest.cs">
<Link>Classes\SshClientTest.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Tests\Classes\SshClientTest_CreateShellStream_TerminalNameAndColumnsAndRowsAndWidthAndHeightAndBufferSizeAndTerminalModes_Connected.cs">
<Link>Classes\SshClientTest_CreateShellStream_TerminalNameAndColumnsAndRowsAndWidthAndHeightAndBufferSizeAndTerminalModes_Connected.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Tests\Classes\SshClientTest_CreateShellStream_TerminalNameAndColumnsAndRowsAndWidthAndHeightAndBufferSize_Connected.cs">
<Link>Classes\SshClientTest_CreateShellStream_TerminalNameAndColumnsAndRowsAndWidthAndHeightAndBufferSize_Connected.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Tests\Classes\SshClientTest_Disconnect_ForwardedPortStarted.cs">
<Link>Classes\SshClientTest_Disconnect_ForwardedPortStarted.cs</Link>
</Compile>
Expand Down Expand Up @@ -1632,7 +1668,7 @@
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
<UserProperties ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" ProjectLinkReference="c45379b9-17b1-4e89-bc2e-6d41726413e8" />
<UserProperties ProjectLinkReference="c45379b9-17b1-4e89-bc2e-6d41726413e8" ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" />
</VisualStudio>
</ProjectExtensions>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Expand Down
134 changes: 134 additions & 0 deletions src/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Renci.SshNet.Channels;
using Renci.SshNet.Common;

namespace Renci.SshNet.Tests.Classes
{
[TestClass]
public class ServiceFactoryTest_CreateShellStream
{
private Mock<ISession> _sessionMock;
private Mock<IConnectionInfo> _connectionInfoMock;
private Mock<IChannelSession> _channelSessionMock;
private MockSequence _mockSequence;
private ServiceFactory _serviceFactory;
private string _terminalName;
private uint _columns;
private uint _rows;
private uint _width;
private uint _height;
private IDictionary<TerminalModes, uint> _terminalModeValues;
private int _bufferSize;
private ShellStream _shellStream;

private void SetupData()
{
var random = new Random();

_terminalName = random.Next().ToString();
_columns = (uint) random.Next();
_rows = (uint) random.Next();
_width = (uint) random.Next();
_height = (uint) random.Next();
_terminalModeValues = new Dictionary<TerminalModes, uint>();
_bufferSize = random.Next();
}

private void CreateMocks()
{
_sessionMock = new Mock<ISession>(MockBehavior.Strict);
_connectionInfoMock = new Mock<IConnectionInfo>(MockBehavior.Strict);
_channelSessionMock = new Mock<IChannelSession>(MockBehavior.Strict);
}

private void SetupMocks()
{
_mockSequence = new MockSequence();

_sessionMock.InSequence(_mockSequence)
.Setup(p => p.ConnectionInfo)
.Returns(_connectionInfoMock.Object);
_connectionInfoMock.InSequence(_mockSequence)
.Setup(p => p.Encoding)
.Returns(new UTF8Encoding());
_sessionMock.InSequence(_mockSequence)
.Setup(p => p.CreateChannelSession())
.Returns(_channelSessionMock.Object);
_channelSessionMock.InSequence(_mockSequence)
.Setup(p => p.Open());
_channelSessionMock.InSequence(_mockSequence)
.Setup(p => p.SendPseudoTerminalRequest(_terminalName,
_columns,
_rows,
_width,
_height,
_terminalModeValues))
.Returns(true);
_channelSessionMock.InSequence(_mockSequence)
.Setup(p => p.SendShellRequest())
.Returns(true);
}

private void Arrange()
{
SetupData();
CreateMocks();
SetupMocks();

_serviceFactory = new ServiceFactory();
}

[TestInitialize]
public void Initialize()
{
Arrange();
Act();
}

private void Act()
{
_shellStream = _serviceFactory.CreateShellStream(_sessionMock.Object,
_terminalName,
_columns,
_rows,
_width,
_height,
_terminalModeValues,
_bufferSize);
}

[TestMethod]
public void CreateShellStreamShouldNotReturnNull()
{
Assert.IsNotNull(_shellStream);
}

[TestMethod]
public void BufferSizeOfShellStreamShouldBeValuePassedToCreateShellStream()
{
Assert.AreEqual(_bufferSize, _shellStream.BufferSize);
}

[TestMethod]
public void SendPseudoTerminalRequestShouldHaveBeenInvokedOnce()
{
_channelSessionMock.Verify(p => p.SendPseudoTerminalRequest(_terminalName,
_columns,
_rows,
_width,
_height,
_terminalModeValues),
Times.Once);
}

[TestMethod]
public void SendShellRequestShouldHaveBeenInvokedOnce()
{
_channelSessionMock.Verify(p => p.SendShellRequest(), Times.Once);
}
}
}
12 changes: 10 additions & 2 deletions src/Renci.SshNet.Tests/Classes/ShellStreamTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class ShellStreamTest : TestBase
private uint _widthPixels;
private uint _heightPixels;
private Dictionary<TerminalModes, uint> _terminalModes;
private int _bufferSize;
private Mock<IChannelSession> _channelSessionMock;

protected override void OnInit()
Expand All @@ -39,6 +40,7 @@ protected override void OnInit()
_widthPixels = (uint)random.Next();
_heightPixels = (uint)random.Next();
_terminalModes = new Dictionary<TerminalModes, uint>();
_bufferSize = random.Next(100, 500);

_encoding = Encoding.UTF8;
_sessionMock = new Mock<ISession>(MockBehavior.Strict);
Expand Down Expand Up @@ -111,8 +113,14 @@ private ShellStream CreateShellStream()
_widthPixels, _heightPixels, _terminalModes)).Returns(true);
_channelSessionMock.Setup(p => p.SendShellRequest()).Returns(true);

return new ShellStream(_sessionMock.Object, _terminalName, _widthColumns, _heightRows,
_widthPixels, _heightPixels, _terminalModes);
return new ShellStream(_sessionMock.Object,
_terminalName,
_widthColumns,
_heightRows,
_widthPixels,
_heightPixels,
_terminalModes,
_bufferSize);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Renci.SshNet.Abstractions;
using Renci.SshNet.Channels;
using Renci.SshNet.Common;

namespace Renci.SshNet.Tests.Classes
{
[TestClass]
public class ShellStreamTest_Write_WriteBufferEmptyAndWriteLessBytesThanBufferSize
{
private Mock<ISession> _sessionMock;
private Mock<IConnectionInfo> _connectionInfoMock;
private Mock<IChannelSession> _channelSessionMock;
private string _terminalName;
private uint _widthColumns;
private uint _heightRows;
private uint _widthPixels;
private uint _heightPixels;
private Dictionary<TerminalModes, uint> _terminalModes;
private ShellStream _shellStream;
private int _bufferSize;

private byte[] _data;
private int _offset;
private int _count;
private MockSequence _mockSequence;

[TestInitialize]
public void Initialize()
{
Arrange();
Act();
}

private void SetupData()
{
var random = new Random();

_terminalName = random.Next().ToString();
_widthColumns = (uint) random.Next();
_heightRows = (uint) random.Next();
_widthPixels = (uint) random.Next();
_heightPixels = (uint) random.Next();
_terminalModes = new Dictionary<TerminalModes, uint>();
_bufferSize = random.Next(100, 1000);

_data = CryptoAbstraction.GenerateRandom(_bufferSize - 10);
_offset = random.Next(1, 5);
_count = _data.Length - _offset - random.Next(1, 10);
}

private void CreateMocks()
{
_sessionMock = new Mock<ISession>(MockBehavior.Strict);
_connectionInfoMock = new Mock<IConnectionInfo>(MockBehavior.Strict);
_channelSessionMock = new Mock<IChannelSession>(MockBehavior.Strict);
}

private void SetupMocks()
{
_mockSequence = new MockSequence();

_sessionMock.InSequence(_mockSequence)
.Setup(p => p.ConnectionInfo)
.Returns(_connectionInfoMock.Object);
_connectionInfoMock.InSequence(_mockSequence)
.Setup(p => p.Encoding)
.Returns(new UTF8Encoding());
_sessionMock.InSequence(_mockSequence)
.Setup(p => p.CreateChannelSession())
.Returns(_channelSessionMock.Object);
_channelSessionMock.InSequence(_mockSequence)
.Setup(p => p.Open());
_channelSessionMock.InSequence(_mockSequence)
.Setup(p => p.SendPseudoTerminalRequest(_terminalName,
_widthColumns,
_heightRows,
_widthPixels,
_heightPixels,
_terminalModes))
.Returns(true);
_channelSessionMock.InSequence(_mockSequence)
.Setup(p => p.SendShellRequest())
.Returns(true);
}

private void Arrange()
{
SetupData();
CreateMocks();
SetupMocks();

_shellStream = new ShellStream(_sessionMock.Object,
_terminalName,
_widthColumns,
_heightRows,
_widthPixels,
_heightPixels,
_terminalModes,
_bufferSize);
}

private void Act()
{
_shellStream.Write(_data, _offset, _count);
}

[TestMethod]
public void NoDataShouldBeSentToServer()
{
_channelSessionMock.Verify(p => p.SendData(It.IsAny<byte[]>()), Times.Never);
}

[TestMethod]
public void FlushShouldSendWrittenBytesToServer()
{
byte[] bytesSent = null;

_channelSessionMock.InSequence(_mockSequence)
.Setup(p => p.SendData(It.IsAny<byte[]>()))
.Callback<byte[]>(data => bytesSent = data);

_shellStream.Flush();

Assert.IsNotNull(bytesSent);
Assert.IsTrue(_data.Take(_offset, _count).IsEqualTo(bytesSent));

_channelSessionMock.Verify(p => p.SendData(It.IsAny<byte[]>()), Times.Once);
}
}
}
Loading

0 comments on commit c3d43b6

Please sign in to comment.