Skip to content

Commit c3d43b6

Browse files
committed
Pass buffer size to ShellStream ctor.
Fixes issue #303. Added tests for issue #303 and PR #211.
1 parent 985e3f3 commit c3d43b6

19 files changed

+1822
-19
lines changed

src/Renci.SshNet.Tests.NET35/Renci.SshNet.Tests.NET35.csproj

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,9 @@
912912
<Compile Include="..\Renci.SshNet.Tests\Classes\ServiceFactoryTest_CreateSftpFileReader_FileSizeIsZero.cs">
913913
<Link>Classes\ServiceFactoryTest_CreateSftpFileReader_FileSizeIsZero.cs</Link>
914914
</Compile>
915+
<Compile Include="..\Renci.SshNet.Tests\Classes\ServiceFactoryTest_CreateShellStream.cs">
916+
<Link>Classes\ServiceFactoryTest_CreateShellStream.cs</Link>
917+
</Compile>
915918
<Compile Include="..\Renci.SshNet.Tests\Classes\SessionTest.cs">
916919
<Link>Classes\SessionTest.cs</Link>
917920
</Compile>
@@ -1425,12 +1428,45 @@
14251428
<Compile Include="..\Renci.SshNet.Tests\Classes\ShellStreamTest.cs">
14261429
<Link>Classes\ShellStreamTest.cs</Link>
14271430
</Compile>
1431+
<Compile Include="..\Renci.SshNet.Tests\Classes\ShellStreamTest_Write_WriteBufferEmptyAndWriteLessBytesThanBufferSize.cs">
1432+
<Link>Classes\ShellStreamTest_Write_WriteBufferEmptyAndWriteLessBytesThanBufferSize.cs</Link>
1433+
</Compile>
1434+
<Compile Include="..\Renci.SshNet.Tests\Classes\ShellStreamTest_Write_WriteBufferEmptyAndWriteMoreBytesThanBufferSize.cs">
1435+
<Link>Classes\ShellStreamTest_Write_WriteBufferEmptyAndWriteMoreBytesThanBufferSize.cs</Link>
1436+
</Compile>
1437+
<Compile Include="..\Renci.SshNet.Tests\Classes\ShellStreamTest_Write_WriteBufferEmptyAndWriteNumberOfBytesEqualToBufferSize.cs">
1438+
<Link>Classes\ShellStreamTest_Write_WriteBufferEmptyAndWriteNumberOfBytesEqualToBufferSize.cs</Link>
1439+
</Compile>
1440+
<Compile Include="..\Renci.SshNet.Tests\Classes\ShellStreamTest_Write_WriteBufferEmptyAndWriteZeroBytes.cs">
1441+
<Link>Classes\ShellStreamTest_Write_WriteBufferEmptyAndWriteZeroBytes.cs</Link>
1442+
</Compile>
1443+
<Compile Include="..\Renci.SshNet.Tests\Classes\ShellStreamTest_Write_WriteBufferFullAndWriteLessBytesThanBufferSize.cs">
1444+
<Link>Classes\ShellStreamTest_Write_WriteBufferFullAndWriteLessBytesThanBufferSize.cs</Link>
1445+
</Compile>
1446+
<Compile Include="..\Renci.SshNet.Tests\Classes\ShellStreamTest_Write_WriteBufferFullAndWriteZeroBytes.cs">
1447+
<Link>Classes\ShellStreamTest_Write_WriteBufferFullAndWriteZeroBytes.cs</Link>
1448+
</Compile>
1449+
<Compile Include="..\Renci.SshNet.Tests\Classes\ShellStreamTest_Write_WriteBufferNotEmptyAndWriteLessBytesThanBufferCanContain.cs">
1450+
<Link>Classes\ShellStreamTest_Write_WriteBufferNotEmptyAndWriteLessBytesThanBufferCanContain.cs</Link>
1451+
</Compile>
1452+
<Compile Include="..\Renci.SshNet.Tests\Classes\ShellStreamTest_Write_WriteBufferNotEmptyAndWriteMoreBytesThanBufferCanContain.cs">
1453+
<Link>Classes\ShellStreamTest_Write_WriteBufferNotEmptyAndWriteMoreBytesThanBufferCanContain.cs</Link>
1454+
</Compile>
1455+
<Compile Include="..\Renci.SshNet.Tests\Classes\ShellStreamTest_Write_WriteBufferNotEmptyAndWriteZeroBytes.cs">
1456+
<Link>Classes\ShellStreamTest_Write_WriteBufferNotEmptyAndWriteZeroBytes.cs</Link>
1457+
</Compile>
14281458
<Compile Include="..\Renci.SshNet.Tests\Classes\ShellTestTest.cs">
14291459
<Link>Classes\ShellTestTest.cs</Link>
14301460
</Compile>
14311461
<Compile Include="..\Renci.SshNet.Tests\Classes\SshClientTest.cs">
14321462
<Link>Classes\SshClientTest.cs</Link>
14331463
</Compile>
1464+
<Compile Include="..\Renci.SshNet.Tests\Classes\SshClientTest_CreateShellStream_TerminalNameAndColumnsAndRowsAndWidthAndHeightAndBufferSizeAndTerminalModes_Connected.cs">
1465+
<Link>Classes\SshClientTest_CreateShellStream_TerminalNameAndColumnsAndRowsAndWidthAndHeightAndBufferSizeAndTerminalModes_Connected.cs</Link>
1466+
</Compile>
1467+
<Compile Include="..\Renci.SshNet.Tests\Classes\SshClientTest_CreateShellStream_TerminalNameAndColumnsAndRowsAndWidthAndHeightAndBufferSize_Connected.cs">
1468+
<Link>Classes\SshClientTest_CreateShellStream_TerminalNameAndColumnsAndRowsAndWidthAndHeightAndBufferSize_Connected.cs</Link>
1469+
</Compile>
14341470
<Compile Include="..\Renci.SshNet.Tests\Classes\SshClientTest_Disconnect_ForwardedPortStarted.cs">
14351471
<Link>Classes\SshClientTest_Disconnect_ForwardedPortStarted.cs</Link>
14361472
</Compile>
@@ -1632,7 +1668,7 @@
16321668
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
16331669
<ProjectExtensions>
16341670
<VisualStudio>
1635-
<UserProperties ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" ProjectLinkReference="c45379b9-17b1-4e89-bc2e-6d41726413e8" />
1671+
<UserProperties ProjectLinkReference="c45379b9-17b1-4e89-bc2e-6d41726413e8" ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" />
16361672
</VisualStudio>
16371673
</ProjectExtensions>
16381674
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using Microsoft.VisualStudio.TestTools.UnitTesting;
5+
using Moq;
6+
using Renci.SshNet.Channels;
7+
using Renci.SshNet.Common;
8+
9+
namespace Renci.SshNet.Tests.Classes
10+
{
11+
[TestClass]
12+
public class ServiceFactoryTest_CreateShellStream
13+
{
14+
private Mock<ISession> _sessionMock;
15+
private Mock<IConnectionInfo> _connectionInfoMock;
16+
private Mock<IChannelSession> _channelSessionMock;
17+
private MockSequence _mockSequence;
18+
private ServiceFactory _serviceFactory;
19+
private string _terminalName;
20+
private uint _columns;
21+
private uint _rows;
22+
private uint _width;
23+
private uint _height;
24+
private IDictionary<TerminalModes, uint> _terminalModeValues;
25+
private int _bufferSize;
26+
private ShellStream _shellStream;
27+
28+
private void SetupData()
29+
{
30+
var random = new Random();
31+
32+
_terminalName = random.Next().ToString();
33+
_columns = (uint) random.Next();
34+
_rows = (uint) random.Next();
35+
_width = (uint) random.Next();
36+
_height = (uint) random.Next();
37+
_terminalModeValues = new Dictionary<TerminalModes, uint>();
38+
_bufferSize = random.Next();
39+
}
40+
41+
private void CreateMocks()
42+
{
43+
_sessionMock = new Mock<ISession>(MockBehavior.Strict);
44+
_connectionInfoMock = new Mock<IConnectionInfo>(MockBehavior.Strict);
45+
_channelSessionMock = new Mock<IChannelSession>(MockBehavior.Strict);
46+
}
47+
48+
private void SetupMocks()
49+
{
50+
_mockSequence = new MockSequence();
51+
52+
_sessionMock.InSequence(_mockSequence)
53+
.Setup(p => p.ConnectionInfo)
54+
.Returns(_connectionInfoMock.Object);
55+
_connectionInfoMock.InSequence(_mockSequence)
56+
.Setup(p => p.Encoding)
57+
.Returns(new UTF8Encoding());
58+
_sessionMock.InSequence(_mockSequence)
59+
.Setup(p => p.CreateChannelSession())
60+
.Returns(_channelSessionMock.Object);
61+
_channelSessionMock.InSequence(_mockSequence)
62+
.Setup(p => p.Open());
63+
_channelSessionMock.InSequence(_mockSequence)
64+
.Setup(p => p.SendPseudoTerminalRequest(_terminalName,
65+
_columns,
66+
_rows,
67+
_width,
68+
_height,
69+
_terminalModeValues))
70+
.Returns(true);
71+
_channelSessionMock.InSequence(_mockSequence)
72+
.Setup(p => p.SendShellRequest())
73+
.Returns(true);
74+
}
75+
76+
private void Arrange()
77+
{
78+
SetupData();
79+
CreateMocks();
80+
SetupMocks();
81+
82+
_serviceFactory = new ServiceFactory();
83+
}
84+
85+
[TestInitialize]
86+
public void Initialize()
87+
{
88+
Arrange();
89+
Act();
90+
}
91+
92+
private void Act()
93+
{
94+
_shellStream = _serviceFactory.CreateShellStream(_sessionMock.Object,
95+
_terminalName,
96+
_columns,
97+
_rows,
98+
_width,
99+
_height,
100+
_terminalModeValues,
101+
_bufferSize);
102+
}
103+
104+
[TestMethod]
105+
public void CreateShellStreamShouldNotReturnNull()
106+
{
107+
Assert.IsNotNull(_shellStream);
108+
}
109+
110+
[TestMethod]
111+
public void BufferSizeOfShellStreamShouldBeValuePassedToCreateShellStream()
112+
{
113+
Assert.AreEqual(_bufferSize, _shellStream.BufferSize);
114+
}
115+
116+
[TestMethod]
117+
public void SendPseudoTerminalRequestShouldHaveBeenInvokedOnce()
118+
{
119+
_channelSessionMock.Verify(p => p.SendPseudoTerminalRequest(_terminalName,
120+
_columns,
121+
_rows,
122+
_width,
123+
_height,
124+
_terminalModeValues),
125+
Times.Once);
126+
}
127+
128+
[TestMethod]
129+
public void SendShellRequestShouldHaveBeenInvokedOnce()
130+
{
131+
_channelSessionMock.Verify(p => p.SendShellRequest(), Times.Once);
132+
}
133+
}
134+
}

src/Renci.SshNet.Tests/Classes/ShellStreamTest.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public class ShellStreamTest : TestBase
2626
private uint _widthPixels;
2727
private uint _heightPixels;
2828
private Dictionary<TerminalModes, uint> _terminalModes;
29+
private int _bufferSize;
2930
private Mock<IChannelSession> _channelSessionMock;
3031

3132
protected override void OnInit()
@@ -39,6 +40,7 @@ protected override void OnInit()
3940
_widthPixels = (uint)random.Next();
4041
_heightPixels = (uint)random.Next();
4142
_terminalModes = new Dictionary<TerminalModes, uint>();
43+
_bufferSize = random.Next(100, 500);
4244

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

114-
return new ShellStream(_sessionMock.Object, _terminalName, _widthColumns, _heightRows,
115-
_widthPixels, _heightPixels, _terminalModes);
116+
return new ShellStream(_sessionMock.Object,
117+
_terminalName,
118+
_widthColumns,
119+
_heightRows,
120+
_widthPixels,
121+
_heightPixels,
122+
_terminalModes,
123+
_bufferSize);
116124
}
117125
}
118126
}
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using Microsoft.VisualStudio.TestTools.UnitTesting;
5+
using Moq;
6+
using Renci.SshNet.Abstractions;
7+
using Renci.SshNet.Channels;
8+
using Renci.SshNet.Common;
9+
10+
namespace Renci.SshNet.Tests.Classes
11+
{
12+
[TestClass]
13+
public class ShellStreamTest_Write_WriteBufferEmptyAndWriteLessBytesThanBufferSize
14+
{
15+
private Mock<ISession> _sessionMock;
16+
private Mock<IConnectionInfo> _connectionInfoMock;
17+
private Mock<IChannelSession> _channelSessionMock;
18+
private string _terminalName;
19+
private uint _widthColumns;
20+
private uint _heightRows;
21+
private uint _widthPixels;
22+
private uint _heightPixels;
23+
private Dictionary<TerminalModes, uint> _terminalModes;
24+
private ShellStream _shellStream;
25+
private int _bufferSize;
26+
27+
private byte[] _data;
28+
private int _offset;
29+
private int _count;
30+
private MockSequence _mockSequence;
31+
32+
[TestInitialize]
33+
public void Initialize()
34+
{
35+
Arrange();
36+
Act();
37+
}
38+
39+
private void SetupData()
40+
{
41+
var random = new Random();
42+
43+
_terminalName = random.Next().ToString();
44+
_widthColumns = (uint) random.Next();
45+
_heightRows = (uint) random.Next();
46+
_widthPixels = (uint) random.Next();
47+
_heightPixels = (uint) random.Next();
48+
_terminalModes = new Dictionary<TerminalModes, uint>();
49+
_bufferSize = random.Next(100, 1000);
50+
51+
_data = CryptoAbstraction.GenerateRandom(_bufferSize - 10);
52+
_offset = random.Next(1, 5);
53+
_count = _data.Length - _offset - random.Next(1, 10);
54+
}
55+
56+
private void CreateMocks()
57+
{
58+
_sessionMock = new Mock<ISession>(MockBehavior.Strict);
59+
_connectionInfoMock = new Mock<IConnectionInfo>(MockBehavior.Strict);
60+
_channelSessionMock = new Mock<IChannelSession>(MockBehavior.Strict);
61+
}
62+
63+
private void SetupMocks()
64+
{
65+
_mockSequence = new MockSequence();
66+
67+
_sessionMock.InSequence(_mockSequence)
68+
.Setup(p => p.ConnectionInfo)
69+
.Returns(_connectionInfoMock.Object);
70+
_connectionInfoMock.InSequence(_mockSequence)
71+
.Setup(p => p.Encoding)
72+
.Returns(new UTF8Encoding());
73+
_sessionMock.InSequence(_mockSequence)
74+
.Setup(p => p.CreateChannelSession())
75+
.Returns(_channelSessionMock.Object);
76+
_channelSessionMock.InSequence(_mockSequence)
77+
.Setup(p => p.Open());
78+
_channelSessionMock.InSequence(_mockSequence)
79+
.Setup(p => p.SendPseudoTerminalRequest(_terminalName,
80+
_widthColumns,
81+
_heightRows,
82+
_widthPixels,
83+
_heightPixels,
84+
_terminalModes))
85+
.Returns(true);
86+
_channelSessionMock.InSequence(_mockSequence)
87+
.Setup(p => p.SendShellRequest())
88+
.Returns(true);
89+
}
90+
91+
private void Arrange()
92+
{
93+
SetupData();
94+
CreateMocks();
95+
SetupMocks();
96+
97+
_shellStream = new ShellStream(_sessionMock.Object,
98+
_terminalName,
99+
_widthColumns,
100+
_heightRows,
101+
_widthPixels,
102+
_heightPixels,
103+
_terminalModes,
104+
_bufferSize);
105+
}
106+
107+
private void Act()
108+
{
109+
_shellStream.Write(_data, _offset, _count);
110+
}
111+
112+
[TestMethod]
113+
public void NoDataShouldBeSentToServer()
114+
{
115+
_channelSessionMock.Verify(p => p.SendData(It.IsAny<byte[]>()), Times.Never);
116+
}
117+
118+
[TestMethod]
119+
public void FlushShouldSendWrittenBytesToServer()
120+
{
121+
byte[] bytesSent = null;
122+
123+
_channelSessionMock.InSequence(_mockSequence)
124+
.Setup(p => p.SendData(It.IsAny<byte[]>()))
125+
.Callback<byte[]>(data => bytesSent = data);
126+
127+
_shellStream.Flush();
128+
129+
Assert.IsNotNull(bytesSent);
130+
Assert.IsTrue(_data.Take(_offset, _count).IsEqualTo(bytesSent));
131+
132+
_channelSessionMock.Verify(p => p.SendData(It.IsAny<byte[]>()), Times.Once);
133+
}
134+
}
135+
}

0 commit comments

Comments
 (0)