diff --git a/src/Renci.SshNet/IServiceFactory.cs b/src/Renci.SshNet/IServiceFactory.cs
index f19110d7f..c071e8c25 100644
--- a/src/Renci.SshNet/IServiceFactory.cs
+++ b/src/Renci.SshNet/IServiceFactory.cs
@@ -114,6 +114,7 @@ internal partial interface IServiceFactory
/// The terminal height in pixels.
/// The terminal mode values.
/// Size of the buffer.
+ /// Size of the expect buffer.
///
/// The created instance.
///
@@ -135,7 +136,8 @@ ShellStream CreateShellStream(ISession session,
uint width,
uint height,
IDictionary terminalModeValues,
- int bufferSize);
+ int bufferSize,
+ int expectSize);
///
/// Creates an that encloses a path in double quotes, and escapes
diff --git a/src/Renci.SshNet/ServiceFactory.cs b/src/Renci.SshNet/ServiceFactory.cs
index ece94505b..1ef0da1fa 100644
--- a/src/Renci.SshNet/ServiceFactory.cs
+++ b/src/Renci.SshNet/ServiceFactory.cs
@@ -187,6 +187,7 @@ public ISftpResponseFactory CreateSftpResponseFactory()
/// The terminal height in pixels.
/// The terminal mode values.
/// The size of the buffer.
+ /// The size of the expect buffer.
///
/// The created instance.
///
@@ -194,16 +195,16 @@ public ISftpResponseFactory CreateSftpResponseFactory()
///
///
/// The TERM environment variable contains an identifier for the text window's capabilities.
- /// You can get a detailed list of these cababilities by using the ‘infocmp’ command.
+ /// You can get a detailed list of these capabilities by using the ‘infocmp’ command.
///
///
/// The column/row dimensions override the pixel dimensions(when non-zero). Pixel dimensions refer
/// to the drawable area of the window.
///
///
- public ShellStream CreateShellStream(ISession session, string terminalName, uint columns, uint rows, uint width, uint height, IDictionary terminalModeValues, int bufferSize)
+ public ShellStream CreateShellStream(ISession session, string terminalName, uint columns, uint rows, uint width, uint height, IDictionary terminalModeValues, int bufferSize, int expectSize)
{
- return new ShellStream(session, terminalName, columns, rows, width, height, terminalModeValues, bufferSize);
+ return new ShellStream(session, terminalName, columns, rows, width, height, terminalModeValues, bufferSize, expectSize);
}
///
diff --git a/src/Renci.SshNet/ShellStream.cs b/src/Renci.SshNet/ShellStream.cs
index e28935735..190392051 100644
--- a/src/Renci.SshNet/ShellStream.cs
+++ b/src/Renci.SshNet/ShellStream.cs
@@ -22,6 +22,8 @@ public class ShellStream : Stream
private readonly Encoding _encoding;
private readonly int _bufferSize;
private readonly Queue _incoming;
+ private readonly int _expectSize;
+ private readonly Queue _expect;
private readonly Queue _outgoing;
private IChannelSession _channel;
private AutoResetEvent _dataReceived = new AutoResetEvent(initialState: false);
@@ -76,15 +78,28 @@ internal int BufferSize
/// The terminal height in pixels.
/// The terminal mode values.
/// The size of the buffer.
+ /// The size of the expect buffer.
/// The channel could not be opened.
/// The pseudo-terminal request was not accepted by the server.
/// The request to start a shell was not accepted by the server.
- internal ShellStream(ISession session, string terminalName, uint columns, uint rows, uint width, uint height, IDictionary terminalModeValues, int bufferSize)
+ internal ShellStream(ISession session, string terminalName, uint columns, uint rows, uint width, uint height, IDictionary terminalModeValues, int bufferSize, int expectSize)
{
+ if (bufferSize <= 0)
+ {
+ throw new ArgumentException($"{nameof(bufferSize)} must be between 1 and {int.MaxValue}.");
+ }
+
+ if (expectSize <= 0)
+ {
+ throw new ArgumentException($"{nameof(expectSize)} must be between 1 and {int.MaxValue}.");
+ }
+
_encoding = session.ConnectionInfo.Encoding;
_session = session;
_bufferSize = bufferSize;
_incoming = new Queue();
+ _expectSize = expectSize;
+ _expect = new Queue(_expectSize);
_outgoing = new Queue();
_channel = _session.CreateChannelSession();
@@ -248,35 +263,40 @@ public void Expect(params ExpectAction[] expectActions)
public void Expect(TimeSpan timeout, params ExpectAction[] expectActions)
{
var expectedFound = false;
- var text = string.Empty;
+ var matchText = string.Empty;
do
{
lock (_incoming)
{
- if (_incoming.Count > 0)
+ if (_expect.Count > 0)
{
- text = _encoding.GetString(_incoming.ToArray(), 0, _incoming.Count);
+ matchText = _encoding.GetString(_expect.ToArray(), 0, _expect.Count);
}
- if (text.Length > 0)
+ if (matchText.Length > 0)
{
foreach (var expectAction in expectActions)
{
- var match = expectAction.Expect.Match(text);
+ var match = expectAction.Expect.Match(matchText);
if (match.Success)
{
- var result = text.Substring(0, match.Index + match.Length);
- var charCount = _encoding.GetByteCount(result);
+ var returnText = matchText.Substring(0, match.Index + match.Length);
+ var returnLength = _encoding.GetByteCount(returnText);
- for (var i = 0; i < charCount && _incoming.Count > 0; i++)
+ // Remove processed items from the queue
+ for (var i = 0; i < returnLength && _incoming.Count > 0; i++)
{
- // Remove processed items from the queue
+ if (_expect.Count == _incoming.Count)
+ {
+ _ = _expect.Dequeue();
+ }
+
_ = _incoming.Dequeue();
}
- expectAction.Action(result);
+ expectAction.Action(returnText);
expectedFound = true;
}
}
@@ -349,27 +369,33 @@ public string Expect(Regex regex)
///
public string Expect(Regex regex, TimeSpan timeout)
{
- var result = string.Empty;
+ var matchText = string.Empty;
+ string returnText;
while (true)
{
lock (_incoming)
{
- if (_incoming.Count > 0)
+ if (_expect.Count > 0)
{
- result = _encoding.GetString(_incoming.ToArray(), 0, _incoming.Count);
+ matchText = _encoding.GetString(_expect.ToArray(), 0, _expect.Count);
}
- var match = regex.Match(result);
+ var match = regex.Match(matchText);
if (match.Success)
{
- result = result.Substring(0, match.Index + match.Length);
- var charCount = _encoding.GetByteCount(result);
+ returnText = matchText.Substring(0, match.Index + match.Length);
+ var returnLength = _encoding.GetByteCount(returnText);
// Remove processed items from the queue
- for (var i = 0; i < charCount && _incoming.Count > 0; i++)
+ for (var i = 0; i < returnLength && _incoming.Count > 0; i++)
{
+ if (_expect.Count == _incoming.Count)
+ {
+ _ = _expect.Dequeue();
+ }
+
_ = _incoming.Dequeue();
}
@@ -390,7 +416,7 @@ public string Expect(Regex regex, TimeSpan timeout)
}
}
- return result;
+ return returnText;
}
///
@@ -446,7 +472,8 @@ public IAsyncResult BeginExpect(AsyncCallback callback, object state, params Exp
public IAsyncResult BeginExpect(TimeSpan timeout, AsyncCallback callback, object state, params ExpectAction[] expectActions)
#pragma warning restore CA1859 // Use concrete types when possible for improved performance
{
- var text = string.Empty;
+ var matchText = string.Empty;
+ string returnText;
// Create new AsyncResult object
var asyncResult = new ExpectAsyncResult(callback, state);
@@ -461,31 +488,36 @@ public IAsyncResult BeginExpect(TimeSpan timeout, AsyncCallback callback, object
{
lock (_incoming)
{
- if (_incoming.Count > 0)
+ if (_expect.Count > 0)
{
- text = _encoding.GetString(_incoming.ToArray(), 0, _incoming.Count);
+ matchText = _encoding.GetString(_expect.ToArray(), 0, _expect.Count);
}
- if (text.Length > 0)
+ if (matchText.Length > 0)
{
foreach (var expectAction in expectActions)
{
- var match = expectAction.Expect.Match(text);
+ var match = expectAction.Expect.Match(matchText);
if (match.Success)
{
- var result = text.Substring(0, match.Index + match.Length);
- var charCount = _encoding.GetByteCount(result);
+ returnText = matchText.Substring(0, match.Index + match.Length);
+ var returnLength = _encoding.GetByteCount(returnText);
- for (var i = 0; i < match.Index + match.Length && _incoming.Count > 0; i++)
+ // Remove processed items from the queue
+ for (var i = 0; i < returnLength && _incoming.Count > 0; i++)
{
- // Remove processed items from the queue
+ if (_expect.Count == _incoming.Count)
+ {
+ _ = _expect.Dequeue();
+ }
+
_ = _incoming.Dequeue();
}
- expectAction.Action(result);
+ expectAction.Action(returnText);
callback?.Invoke(asyncResult);
- expectActionResult = result;
+ expectActionResult = returnText;
}
}
}
@@ -584,6 +616,11 @@ public string ReadLine(TimeSpan timeout)
// remove processed bytes from the queue
for (var i = 0; i < bytesProcessed; i++)
{
+ if (_expect.Count == _incoming.Count)
+ {
+ _ = _expect.Dequeue();
+ }
+
_ = _incoming.Dequeue();
}
@@ -620,6 +657,7 @@ public string Read()
lock (_incoming)
{
text = _encoding.GetString(_incoming.ToArray(), 0, _incoming.Count);
+ _expect.Clear();
_incoming.Clear();
}
@@ -649,6 +687,11 @@ public override int Read(byte[] buffer, int offset, int count)
{
for (; i < count && _incoming.Count > 0; i++)
{
+ if (_expect.Count == _incoming.Count)
+ {
+ _ = _expect.Dequeue();
+ }
+
buffer[offset + i] = _incoming.Dequeue();
}
}
@@ -800,6 +843,12 @@ private void Channel_DataReceived(object sender, ChannelDataEventArgs e)
foreach (var b in e.Data)
{
_incoming.Enqueue(b);
+ if (_expect.Count == _expectSize)
+ {
+ _ = _expect.Dequeue();
+ }
+
+ _expect.Enqueue(b);
}
}
diff --git a/src/Renci.SshNet/SshClient.cs b/src/Renci.SshNet/SshClient.cs
index 2e1103553..f2bf408fb 100644
--- a/src/Renci.SshNet/SshClient.cs
+++ b/src/Renci.SshNet/SshClient.cs
@@ -407,7 +407,7 @@ public Shell CreateShell(Encoding encoding, string input, Stream output, Stream
///
///
/// The TERM environment variable contains an identifier for the text window's capabilities.
- /// You can get a detailed list of these cababilities by using the ‘infocmp’ command.
+ /// You can get a detailed list of these capabilities by using the ‘infocmp’ command.
///
///
/// The column/row dimensions override the pixel dimensions(when nonzero). Pixel dimensions refer
@@ -416,7 +416,38 @@ public Shell CreateShell(Encoding encoding, string input, Stream output, Stream
///
public ShellStream CreateShellStream(string terminalName, uint columns, uint rows, uint width, uint height, int bufferSize)
{
- return CreateShellStream(terminalName, columns, rows, width, height, bufferSize, terminalModeValues: null);
+ return CreateShellStream(terminalName, columns, rows, width, height, bufferSize, bufferSize * 2, terminalModeValues: null);
+ }
+
+ ///
+ /// Creates the shell stream.
+ ///
+ /// The TERM environment variable.
+ /// The terminal width in columns.
+ /// The terminal width in rows.
+ /// The terminal width in pixels.
+ /// The terminal height in pixels.
+ /// The size of the buffer.
+ /// The size of the expect buffer.
+ ///
+ /// The created instance.
+ ///
+ /// Client is not connected.
+ ///
+ ///
+ /// The TERM environment variable contains an identifier for the text window's capabilities.
+ /// You can get a detailed list of these capabilities by using the ‘infocmp’ command.
+ ///
+ ///
+ /// The column/row dimensions override the pixel dimensions(when non-zero). Pixel dimensions refer
+ /// to the drawable area of the window.
+ ///
+ ///
+ public ShellStream CreateShellStream(string terminalName, uint columns, uint rows, uint width, uint height, int bufferSize, int expectSize)
+ {
+ EnsureSessionIsOpen();
+
+ return CreateShellStream(terminalName, columns, rows, width, height, bufferSize, expectSize, terminalModeValues: null);
}
///
@@ -436,7 +467,7 @@ public ShellStream CreateShellStream(string terminalName, uint columns, uint row
///
///
/// The TERM environment variable contains an identifier for the text window's capabilities.
- /// You can get a detailed list of these cababilities by using the ‘infocmp’ command.
+ /// You can get a detailed list of these capabilities by using the ‘infocmp’ command.
///
///
/// The column/row dimensions override the pixel dimensions(when non-zero). Pixel dimensions refer
@@ -447,7 +478,39 @@ public ShellStream CreateShellStream(string terminalName, uint columns, uint row
{
EnsureSessionIsOpen();
- return ServiceFactory.CreateShellStream(Session, terminalName, columns, rows, width, height, terminalModeValues, bufferSize);
+ return CreateShellStream(terminalName, columns, rows, width, height, bufferSize, bufferSize * 2, terminalModeValues);
+ }
+
+ ///
+ /// Creates the shell stream.
+ ///
+ /// The TERM environment variable.
+ /// The terminal width in columns.
+ /// The terminal width in rows.
+ /// The terminal width in pixels.
+ /// The terminal height in pixels.
+ /// The size of the buffer.
+ /// The size of the expect buffer.
+ /// The terminal mode values.
+ ///
+ /// The created instance.
+ ///
+ /// Client is not connected.
+ ///
+ ///
+ /// The TERM environment variable contains an identifier for the text window's capabilities.
+ /// You can get a detailed list of these capabilities by using the ‘infocmp’ command.
+ ///
+ ///
+ /// The column/row dimensions override the pixel dimensions(when non-zero). Pixel dimensions refer
+ /// to the drawable area of the window.
+ ///
+ ///
+ public ShellStream CreateShellStream(string terminalName, uint columns, uint rows, uint width, uint height, int bufferSize, int expectSize, IDictionary terminalModeValues)
+ {
+ EnsureSessionIsOpen();
+
+ return ServiceFactory.CreateShellStream(Session, terminalName, columns, rows, width, height, terminalModeValues, bufferSize, expectSize);
}
///
diff --git a/test/Renci.SshNet.IntegrationTests/ConnectivityTests.cs b/test/Renci.SshNet.IntegrationTests/ConnectivityTests.cs
index 2f94ba7ff..61ba9e424 100644
--- a/test/Renci.SshNet.IntegrationTests/ConnectivityTests.cs
+++ b/test/Renci.SshNet.IntegrationTests/ConnectivityTests.cs
@@ -44,7 +44,7 @@ public void Common_CreateMoreChannelsThanMaxSessions()
// if the channel would not be properly closed
for (var i = 0; i < connectionInfo.MaxSessions + 1; i++)
{
- using (var stream = client.CreateShellStream("vt220", 20, 20, 20, 20, 0))
+ using (var stream = client.CreateShellStream("vt220", 20, 20, 20, 20, 20))
{
stream.WriteLine("echo test");
stream.ReadLine();
diff --git a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_ChannelOpenThrowsException.cs b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_ChannelOpenThrowsException.cs
index 651f2fbc2..423c08a82 100644
--- a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_ChannelOpenThrowsException.cs
+++ b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_ChannelOpenThrowsException.cs
@@ -22,6 +22,7 @@ public class ServiceFactoryTest_CreateShellStream_ChannelOpenThrowsException
private uint _height;
private IDictionary _terminalModeValues;
private int _bufferSize;
+ private int _expectSize;
private SshException _channelOpenException;
private SshException _actualException;
@@ -36,6 +37,7 @@ private void SetupData()
_height = (uint) random.Next();
_terminalModeValues = new Dictionary();
_bufferSize = random.Next();
+ _expectSize = _bufferSize;
_channelOpenException = new SshException();
_actualException = null;
@@ -95,7 +97,8 @@ private void Act()
_width,
_height,
_terminalModeValues,
- _bufferSize);
+ _bufferSize,
+ _expectSize);
Assert.Fail();
}
catch (SshException ex)
diff --git a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_SendPseudoTerminalRequestReturnsFalse.cs b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_SendPseudoTerminalRequestReturnsFalse.cs
index 362351a5f..e5614bb31 100644
--- a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_SendPseudoTerminalRequestReturnsFalse.cs
+++ b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_SendPseudoTerminalRequestReturnsFalse.cs
@@ -22,6 +22,7 @@ public class ServiceFactoryTest_CreateShellStream_SendPseudoTerminalRequestRetur
private uint _height;
private IDictionary _terminalModeValues;
private int _bufferSize;
+ private int _expectSize;
private SshException _actualException;
private void SetupData()
@@ -35,6 +36,7 @@ private void SetupData()
_height = (uint)random.Next();
_terminalModeValues = new Dictionary();
_bufferSize = random.Next();
+ _expectSize = _bufferSize;
_actualException = null;
}
@@ -94,7 +96,8 @@ private void Act()
_width,
_height,
_terminalModeValues,
- _bufferSize);
+ _bufferSize,
+ _expectSize);
Assert.Fail();
}
catch (SshException ex)
diff --git a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_SendPseudoTerminalRequestThrowsException.cs b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_SendPseudoTerminalRequestThrowsException.cs
index 67606992a..09caab028 100644
--- a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_SendPseudoTerminalRequestThrowsException.cs
+++ b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_SendPseudoTerminalRequestThrowsException.cs
@@ -22,6 +22,7 @@ public class ServiceFactoryTest_CreateShellStream_SendPseudoTerminalRequestThrow
private uint _height;
private IDictionary _terminalModeValues;
private int _bufferSize;
+ private int _expectSize;
private SshException _sendPseudoTerminalRequestException;
private SshException _actualException;
@@ -36,6 +37,7 @@ private void SetupData()
_height = (uint) random.Next();
_terminalModeValues = new Dictionary();
_bufferSize = random.Next();
+ _expectSize = _bufferSize;
_sendPseudoTerminalRequestException = new SshException();
_actualException = null;
@@ -97,7 +99,8 @@ private void Act()
_width,
_height,
_terminalModeValues,
- _bufferSize);
+ _bufferSize,
+ _expectSize);
Assert.Fail();
}
catch (SshException ex)
diff --git a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_SendShellRequestReturnsFalse.cs b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_SendShellRequestReturnsFalse.cs
index 5a6d43871..875faf752 100644
--- a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_SendShellRequestReturnsFalse.cs
+++ b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_SendShellRequestReturnsFalse.cs
@@ -22,6 +22,7 @@ public class ServiceFactoryTest_CreateShellStream_SendShellRequestReturnsFalse
private uint _height;
private IDictionary _terminalModeValues;
private int _bufferSize;
+ private int _expectSize;
private SshException _actualException;
private void SetupData()
@@ -35,6 +36,7 @@ private void SetupData()
_height = (uint) random.Next();
_terminalModeValues = new Dictionary();
_bufferSize = random.Next();
+ _expectSize = _bufferSize;
_actualException = null;
}
@@ -97,7 +99,8 @@ private void Act()
_width,
_height,
_terminalModeValues,
- _bufferSize);
+ _bufferSize,
+ _expectSize);
Assert.Fail();
}
catch (SshException ex)
diff --git a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_SendShellRequestThrowsException.cs b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_SendShellRequestThrowsException.cs
index da9cd6be8..240f18510 100644
--- a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_SendShellRequestThrowsException.cs
+++ b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_SendShellRequestThrowsException.cs
@@ -22,6 +22,7 @@ public class ServiceFactoryTest_CreateShellStream_SendShellRequestThrowsExceptio
private uint _height;
private IDictionary _terminalModeValues;
private int _bufferSize;
+ private int _expectSize;
private SshException _sendShellRequestException;
private SshException _actualException;
@@ -36,6 +37,7 @@ private void SetupData()
_height = (uint) random.Next();
_terminalModeValues = new Dictionary();
_bufferSize = random.Next();
+ _expectSize = _bufferSize;
_sendShellRequestException = new SshException();
_actualException = null;
}
@@ -99,7 +101,8 @@ private void Act()
_width,
_height,
_terminalModeValues,
- _bufferSize);
+ _bufferSize,
+ _expectSize);
Assert.Fail();
}
catch (SshException ex)
diff --git a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_Success.cs b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_Success.cs
index dbd8377c4..75990b608 100644
--- a/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_Success.cs
+++ b/test/Renci.SshNet.Tests/Classes/ServiceFactoryTest_CreateShellStream_Success.cs
@@ -22,6 +22,7 @@ public class ServiceFactoryTest_CreateShellStream_Success
private uint _height;
private IDictionary _terminalModeValues;
private int _bufferSize;
+ private int _expectSize;
private ShellStream _shellStream;
private void SetupData()
@@ -35,6 +36,7 @@ private void SetupData()
_height = (uint) random.Next();
_terminalModeValues = new Dictionary();
_bufferSize = random.Next();
+ _expectSize = _bufferSize;
}
private void CreateMocks()
@@ -97,7 +99,8 @@ private void Act()
_width,
_height,
_terminalModeValues,
- _bufferSize);
+ _bufferSize,
+ _expectSize);
}
[TestMethod]
diff --git a/test/Renci.SshNet.Tests/Classes/ShellStreamTest.cs b/test/Renci.SshNet.Tests/Classes/ShellStreamTest.cs
index ecec9d30e..edbef2d37 100644
--- a/test/Renci.SshNet.Tests/Classes/ShellStreamTest.cs
+++ b/test/Renci.SshNet.Tests/Classes/ShellStreamTest.cs
@@ -27,6 +27,7 @@ public class ShellStreamTest : TestBase
private uint _heightPixels;
private Dictionary _terminalModes;
private int _bufferSize;
+ private int _expectSize;
private Mock _channelSessionMock;
protected override void OnInit()
@@ -41,6 +42,7 @@ protected override void OnInit()
_heightPixels = (uint)random.Next();
_terminalModes = new Dictionary();
_bufferSize = random.Next(100, 500);
+ _expectSize = random.Next(100, _bufferSize);
_encoding = Encoding.UTF8;
_sessionMock = new Mock(MockBehavior.Strict);
@@ -120,7 +122,8 @@ private ShellStream CreateShellStream()
_widthPixels,
_heightPixels,
_terminalModes,
- _bufferSize);
+ _bufferSize,
+ _expectSize);
}
}
}
\ No newline at end of file
diff --git a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_ReadExpect.cs b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_ReadExpect.cs
index 9aa34423b..b3daf51fd 100644
--- a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_ReadExpect.cs
+++ b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_ReadExpect.cs
@@ -42,7 +42,8 @@ public void Initialize()
width: 800,
height: 600,
terminalModeValues: null,
- bufferSize: 1024);
+ bufferSize: 1024,
+ expectSize: 2048);
}
[TestMethod]
@@ -227,6 +228,22 @@ public void Expect_String_non_ASCII_characters()
Assert.AreEqual("んにちは, Bonjour", _shellStream.Read());
}
+ [TestMethod]
+ public void Expect_String_LargeExpect()
+ {
+ _channelSessionStub.Receive(Encoding.UTF8.GetBytes(new string('a', 100)));
+ for (var i = 0; i < 10; i++)
+ {
+ _channelSessionStub.Receive(Encoding.UTF8.GetBytes(new string('b', 100)));
+ }
+ _channelSessionStub.Receive(Encoding.UTF8.GetBytes("Hello, こんにちは, Bonjour"));
+ _channelSessionStub.Receive(Encoding.UTF8.GetBytes(new string('c', 100)));
+
+ Assert.AreEqual($"{new string('a', 100)}{new string('b', 1000)}Hello, こんにちは, Bonjour", _shellStream.Expect($"{new string('b', 1000)}Hello, こんにちは, Bonjour"));
+
+ Assert.AreEqual($"{new string('c', 100)}", _shellStream.Read());
+ }
+
[TestMethod]
public void Expect_Timeout()
{
diff --git a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteLessBytesThanBufferSize.cs b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteLessBytesThanBufferSize.cs
index 2f4b25921..d08a8dcc3 100644
--- a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteLessBytesThanBufferSize.cs
+++ b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteLessBytesThanBufferSize.cs
@@ -23,6 +23,7 @@ public class ShellStreamTest_Write_WriteBufferEmptyAndWriteLessBytesThanBufferSi
private Dictionary _terminalModes;
private ShellStream _shellStream;
private int _bufferSize;
+ private int _expectSize;
private byte[] _data;
private int _offset;
@@ -47,6 +48,7 @@ private void SetupData()
_heightPixels = (uint) random.Next();
_terminalModes = new Dictionary();
_bufferSize = random.Next(100, 1000);
+ _expectSize = random.Next(100, _bufferSize);
_data = CryptoAbstraction.GenerateRandom(_bufferSize - 10);
_offset = random.Next(1, 5);
@@ -101,7 +103,8 @@ private void Arrange()
_widthPixels,
_heightPixels,
_terminalModes,
- _bufferSize);
+ _bufferSize,
+ _expectSize);
}
private void Act()
diff --git a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteMoreBytesThanBufferSize.cs b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteMoreBytesThanBufferSize.cs
index 941c3f7bb..dfff5cf7f 100644
--- a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteMoreBytesThanBufferSize.cs
+++ b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteMoreBytesThanBufferSize.cs
@@ -24,6 +24,7 @@ public class ShellStreamTest_Write_WriteBufferEmptyAndWriteMoreBytesThanBufferSi
private Dictionary _terminalModes;
private ShellStream _shellStream;
private int _bufferSize;
+ private int _expectSize;
private byte[] _data;
private int _offset;
@@ -50,6 +51,7 @@ private void SetupData()
_heightPixels = (uint)random.Next();
_terminalModes = new Dictionary();
_bufferSize = random.Next(100, 1000);
+ _expectSize = random.Next(100, _bufferSize);
_data = CryptoAbstraction.GenerateRandom((_bufferSize * 2) + 10);
_offset = 0;
@@ -111,7 +113,8 @@ private void Arrange()
_widthPixels,
_heightPixels,
_terminalModes,
- _bufferSize);
+ _bufferSize,
+ _expectSize);
}
private void Act()
diff --git a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteNumberOfBytesEqualToBufferSize.cs b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteNumberOfBytesEqualToBufferSize.cs
index 42872913b..be5e80185 100644
--- a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteNumberOfBytesEqualToBufferSize.cs
+++ b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteNumberOfBytesEqualToBufferSize.cs
@@ -23,6 +23,7 @@ public class ShellStreamTest_Write_WriteBufferEmptyAndWriteNumberOfBytesEqualToB
private Dictionary _terminalModes;
private ShellStream _shellStream;
private int _bufferSize;
+ private int _expectSize;
private byte[] _data;
private int _offset;
@@ -47,6 +48,7 @@ private void SetupData()
_heightPixels = (uint)random.Next();
_terminalModes = new Dictionary();
_bufferSize = random.Next(100, 1000);
+ _expectSize = random.Next(100, _bufferSize);
_data = CryptoAbstraction.GenerateRandom(_bufferSize);
_offset = 0;
@@ -101,7 +103,8 @@ private void Arrange()
_widthPixels,
_heightPixels,
_terminalModes,
- _bufferSize);
+ _bufferSize,
+ _expectSize);
}
private void Act()
diff --git a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteZeroBytes.cs b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteZeroBytes.cs
index 94d55ca87..3bd86ded4 100644
--- a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteZeroBytes.cs
+++ b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferEmptyAndWriteZeroBytes.cs
@@ -25,6 +25,7 @@ public class ShellStreamTest_Write_WriteBufferEmptyAndWriteZeroBytes
private Dictionary _terminalModes;
private ShellStream _shellStream;
private int _bufferSize;
+ private int _expectSize;
private byte[] _data;
private int _offset;
@@ -49,6 +50,7 @@ private void SetupData()
_heightPixels = (uint)random.Next();
_terminalModes = new Dictionary();
_bufferSize = random.Next(100, 1000);
+ _expectSize = random.Next(100, _bufferSize);
_data = new byte[0];
_offset = 0;
@@ -103,7 +105,8 @@ private void Arrange()
_widthPixels,
_heightPixels,
_terminalModes,
- _bufferSize);
+ _bufferSize,
+ _expectSize);
}
private void Act()
diff --git a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferFullAndWriteLessBytesThanBufferSize.cs b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferFullAndWriteLessBytesThanBufferSize.cs
index 9fed3f4e2..2fd52d33d 100644
--- a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferFullAndWriteLessBytesThanBufferSize.cs
+++ b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferFullAndWriteLessBytesThanBufferSize.cs
@@ -23,6 +23,7 @@ public class ShellStreamTest_Write_WriteBufferFullAndWriteLessBytesThanBufferSiz
private Dictionary _terminalModes;
private ShellStream _shellStream;
private int _bufferSize;
+ private int _expectSize;
private byte[] _data;
private int _offset;
@@ -48,6 +49,7 @@ private void SetupData()
_heightPixels = (uint)random.Next();
_terminalModes = new Dictionary();
_bufferSize = random.Next(100, 1000);
+ _expectSize = random.Next(100, _bufferSize);
_bufferData = CryptoAbstraction.GenerateRandom(_bufferSize);
_data = CryptoAbstraction.GenerateRandom(_bufferSize - 10);
@@ -105,7 +107,8 @@ private void Arrange()
_widthPixels,
_heightPixels,
_terminalModes,
- _bufferSize);
+ _bufferSize,
+ _expectSize);
_shellStream.Write(_bufferData, 0, _bufferData.Length);
}
diff --git a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferFullAndWriteZeroBytes.cs b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferFullAndWriteZeroBytes.cs
index f0961ea89..7ad30c063 100644
--- a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferFullAndWriteZeroBytes.cs
+++ b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferFullAndWriteZeroBytes.cs
@@ -23,6 +23,7 @@ public class ShellStreamTest_Write_WriteBufferFullAndWriteZeroBytes
private Dictionary _terminalModes;
private ShellStream _shellStream;
private int _bufferSize;
+ private int _expectSize;
private byte[] _data;
private int _offset;
@@ -48,6 +49,7 @@ private void SetupData()
_heightPixels = (uint) random.Next();
_terminalModes = new Dictionary();
_bufferSize = random.Next(100, 1000);
+ _expectSize = random.Next(100, _bufferSize);
_bufferData = CryptoAbstraction.GenerateRandom(_bufferSize);
_data = new byte[0];
@@ -103,7 +105,8 @@ private void Arrange()
_widthPixels,
_heightPixels,
_terminalModes,
- _bufferSize);
+ _bufferSize,
+ _expectSize);
_shellStream.Write(_bufferData, 0, _bufferData.Length);
}
diff --git a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteLessBytesThanBufferCanContain.cs b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteLessBytesThanBufferCanContain.cs
index e14be3044..34f9b5299 100644
--- a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteLessBytesThanBufferCanContain.cs
+++ b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteLessBytesThanBufferCanContain.cs
@@ -23,6 +23,7 @@ public class ShellStreamTest_Write_WriteBufferNotEmptyAndWriteLessBytesThanBuffe
private Dictionary _terminalModes;
private ShellStream _shellStream;
private int _bufferSize;
+ private int _expectSize;
private byte[] _data;
private int _offset;
@@ -48,6 +49,7 @@ private void SetupData()
_heightPixels = (uint) random.Next();
_terminalModes = new Dictionary();
_bufferSize = random.Next(100, 1000);
+ _expectSize = random.Next(100, _bufferSize);
_bufferData = CryptoAbstraction.GenerateRandom(_bufferSize - 60);
_data = CryptoAbstraction.GenerateRandom(_bufferSize + 100);
@@ -103,7 +105,8 @@ private void Arrange()
_widthPixels,
_heightPixels,
_terminalModes,
- _bufferSize);
+ _bufferSize,
+ _expectSize);
_shellStream.Write(_bufferData, 0, _bufferData.Length);
}
diff --git a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteMoreBytesThanBufferCanContain.cs b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteMoreBytesThanBufferCanContain.cs
index 20436c56f..b571a084b 100644
--- a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteMoreBytesThanBufferCanContain.cs
+++ b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteMoreBytesThanBufferCanContain.cs
@@ -24,6 +24,7 @@ public class ShellStreamTest_Write_WriteBufferNotEmptyAndWriteMoreBytesThanBuffe
private Dictionary _terminalModes;
private ShellStream _shellStream;
private int _bufferSize;
+ private int _expectSize;
private byte[] _data;
private int _offset;
@@ -50,6 +51,7 @@ private void SetupData()
_heightPixels = (uint) random.Next();
_terminalModes = new Dictionary();
_bufferSize = random.Next(100, 1000);
+ _expectSize = random.Next(100, _bufferSize);
_bufferData = CryptoAbstraction.GenerateRandom(_bufferSize - 60);
_data = CryptoAbstraction.GenerateRandom(_bufferSize - _bufferData.Length + random.Next(1, 10));
@@ -111,7 +113,8 @@ private void Arrange()
_widthPixels,
_heightPixels,
_terminalModes,
- _bufferSize);
+ _bufferSize,
+ _expectSize);
_shellStream.Write(_bufferData, 0, _bufferData.Length);
}
diff --git a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteZeroBytes.cs b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteZeroBytes.cs
index 411fae02c..50305a412 100644
--- a/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteZeroBytes.cs
+++ b/test/Renci.SshNet.Tests/Classes/ShellStreamTest_Write_WriteBufferNotEmptyAndWriteZeroBytes.cs
@@ -23,6 +23,7 @@ public class ShellStreamTest_Write_WriteBufferNotEmptyAndWriteZeroBytes
private Dictionary _terminalModes;
private ShellStream _shellStream;
private int _bufferSize;
+ private int _expectSize;
private byte[] _data;
private int _offset;
@@ -48,6 +49,7 @@ private void SetupData()
_heightPixels = (uint)random.Next();
_terminalModes = new Dictionary();
_bufferSize = random.Next(100, 1000);
+ _expectSize = random.Next(100, _bufferSize);
_bufferData = CryptoAbstraction.GenerateRandom(_bufferSize - 60);
_data = new byte[0];
@@ -103,7 +105,8 @@ private void Arrange()
_widthPixels,
_heightPixels,
_terminalModes,
- _bufferSize);
+ _bufferSize,
+ _expectSize);
_shellStream.Write(_bufferData, 0, _bufferData.Length);
}
diff --git a/test/Renci.SshNet.Tests/Classes/SshClientTest_CreateShellStream_TerminalNameAndColumnsAndRowsAndWidthAndHeightAndBufferSizeAndTerminalModes_Connected.cs b/test/Renci.SshNet.Tests/Classes/SshClientTest_CreateShellStream_TerminalNameAndColumnsAndRowsAndWidthAndHeightAndBufferSizeAndTerminalModes_Connected.cs
index 4dc5a2063..b13189687 100644
--- a/test/Renci.SshNet.Tests/Classes/SshClientTest_CreateShellStream_TerminalNameAndColumnsAndRowsAndWidthAndHeightAndBufferSizeAndTerminalModes_Connected.cs
+++ b/test/Renci.SshNet.Tests/Classes/SshClientTest_CreateShellStream_TerminalNameAndColumnsAndRowsAndWidthAndHeightAndBufferSizeAndTerminalModes_Connected.cs
@@ -19,6 +19,7 @@ public class SshClientTest_CreateShellStream_TerminalNameAndColumnsAndRowsAndWid
private uint _heightPixels;
private Dictionary _terminalModes;
private int _bufferSize;
+ private int _expectSize;
private ShellStream _expected;
private ShellStream _actual;
@@ -35,6 +36,7 @@ protected override void SetupData()
_heightPixels = (uint) random.Next();
_terminalModes = new Dictionary();
_bufferSize = random.Next(100, 1000);
+ _expectSize = random.Next(100, _bufferSize);
_expected = CreateShellStream();
}
@@ -59,7 +61,8 @@ protected override void SetupMocks()
_widthPixels,
_heightPixels,
_terminalModes,
- _bufferSize))
+ _bufferSize,
+ _expectSize))
.Returns(_expected);
}
@@ -79,6 +82,7 @@ protected override void Act()
_widthPixels,
_heightPixels,
_bufferSize,
+ _expectSize,
_terminalModes);
}
@@ -92,7 +96,8 @@ public void CreateShellStreamOnServiceFactoryShouldBeInvokedOnce()
_widthPixels,
_heightPixels,
_terminalModes,
- _bufferSize),
+ _bufferSize,
+ _expectSize),
Times.Once);
}
@@ -130,6 +135,7 @@ private ShellStream CreateShellStream()
_widthPixels,
_heightPixels,
_terminalModes,
+ 1,
1);
}
}
diff --git a/test/Renci.SshNet.Tests/Classes/SshClientTest_CreateShellStream_TerminalNameAndColumnsAndRowsAndWidthAndHeightAndBufferSize_Connected.cs b/test/Renci.SshNet.Tests/Classes/SshClientTest_CreateShellStream_TerminalNameAndColumnsAndRowsAndWidthAndHeightAndBufferSize_Connected.cs
index 861c8c725..7d393b84b 100644
--- a/test/Renci.SshNet.Tests/Classes/SshClientTest_CreateShellStream_TerminalNameAndColumnsAndRowsAndWidthAndHeightAndBufferSize_Connected.cs
+++ b/test/Renci.SshNet.Tests/Classes/SshClientTest_CreateShellStream_TerminalNameAndColumnsAndRowsAndWidthAndHeightAndBufferSize_Connected.cs
@@ -19,6 +19,7 @@ public class SshClientTest_CreateShellStream_TerminalNameAndColumnsAndRowsAndWid
private uint _widthPixels;
private uint _heightPixels;
private int _bufferSize;
+ private int _expectSize;
private ShellStream _expected;
private ShellStream _actual;
@@ -34,6 +35,7 @@ protected override void SetupData()
_widthPixels = (uint)random.Next();
_heightPixels = (uint)random.Next();
_bufferSize = random.Next(100, 1000);
+ _expectSize = random.Next(100, _bufferSize);
_expected = CreateShellStream();
}
@@ -58,7 +60,8 @@ protected override void SetupMocks()
_widthPixels,
_heightPixels,
null,
- _bufferSize))
+ _bufferSize,
+ _expectSize))
.Returns(_expected);
}
@@ -77,7 +80,8 @@ protected override void Act()
_heightRows,
_widthPixels,
_heightPixels,
- _bufferSize);
+ _bufferSize,
+ _expectSize);
}
[TestMethod]
@@ -90,7 +94,8 @@ public void CreateShellStreamOnServiceFactoryShouldBeInvokedOnce()
_widthPixels,
_heightPixels,
null,
- _bufferSize),
+ _bufferSize,
+ _expectSize),
Times.Once);
}
@@ -128,6 +133,7 @@ private ShellStream CreateShellStream()
_widthPixels,
_heightPixels,
null,
+ 1,
1);
}
}