Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
keithallenjackson committed Aug 30, 2018
1 parent e3540cb commit 2830ba9
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 1 deletion.
113 changes: 113 additions & 0 deletions src/Renci.SshNet.Tests/Classes/ShellStreamTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ public void WriteLine_Line_ShouldOnlyWriteLineTerminatorWhenLineIsNull()
_channelSessionMock.Setup(p => p.SendData(lineTerminator));

shellStream.WriteLine(line);
shellStream.Flush();

_channelSessionMock.Verify(p => p.SendData(lineTerminator), Times.Once);
}
Expand Down Expand Up @@ -153,6 +154,118 @@ public void Disconnection_Event_ShouldRaiseWhenIChannelDisconnected()
Assert.IsTrue(shellStream.Disposed);
}

[TestMethod]
public void Write_AlwaysUsesUnderlyingBuffer()
{
var shellStream = CreateShellStream();
var command1 = "abcd\r";
var command2 = "efgh\r";
var command1Bytes = _encoding.GetBytes(command1);
var command2Bytes = _encoding.GetBytes(command2);
var expectedBytes = command1Bytes.Concat(command2Bytes);

_channelSessionMock.Setup(p => p.SendData(It.IsAny<byte[]>()));

shellStream.Write(command1Bytes, 0, command1Bytes.Length);
shellStream.Write(command2);
shellStream.Flush();

_channelSessionMock.Verify(p => p.SendData(expectedBytes), Times.Once);
}

[TestMethod]
public void Expect_ShouldAlwaysFlushTheWriteBuffer()
{
var shellStream = CreateShellStream();
var command1 = "abcd\r";
var command2 = "efgh\r";
var command1Bytes = _encoding.GetBytes(command1);
var command2Bytes = _encoding.GetBytes(command2);
var expectedBytes = command1Bytes.Concat(command2Bytes);

_channelSessionMock.Setup(p => p.SendData(It.IsAny<byte[]>()))
.Raises(p => p.DataReceived += null, new ChannelDataEventArgs(0, expectedBytes));


shellStream.Write(command1Bytes, 0, command1Bytes.Length);
shellStream.Write(command2);
var output = shellStream.Expect("h\r", TimeSpan.FromMilliseconds(1));

_channelSessionMock.Verify(p => p.SendData(expectedBytes), Times.Once);
Assert.AreEqual(command1 + command2, output);
}

[TestMethod]
public void Read_ShouldAlwaysFlushTheWriteBuffer()
{
var shellStream = CreateShellStream();
var command1 = "abcd\r";
var command2 = "efgh\r";
var command1Bytes = _encoding.GetBytes(command1);
var command2Bytes = _encoding.GetBytes(command2);
var expectedBytes = command1Bytes.Concat(command2Bytes);

_channelSessionMock.Setup(p => p.SendData(It.IsAny<byte[]>()))
.Raises(p => p.DataReceived += null, new ChannelDataEventArgs(0, expectedBytes));


shellStream.Write(command1Bytes, 0, command1Bytes.Length);
shellStream.Write(command2);
var output = shellStream.Read();

_channelSessionMock.Verify(p => p.SendData(expectedBytes), Times.Once);
Assert.AreEqual(command1 + command2, output);
}

[TestMethod]
public void Read_Bytes_ShouldAlwaysFlushTheWriteBuffer()
{
var shellStream = CreateShellStream();
var command1 = "abcd\r";
var command2 = "efgh\r";
var command1Bytes = _encoding.GetBytes(command1);
var command2Bytes = _encoding.GetBytes(command2);
var expectedBytes = command1Bytes.Concat(command2Bytes);

_channelSessionMock.Setup(p => p.SendData(It.IsAny<byte[]>()))
.Raises(p => p.DataReceived += null, new ChannelDataEventArgs(0, expectedBytes));


shellStream.Write(command1Bytes, 0, command1Bytes.Length);
shellStream.Write(command2);
var output = new byte[expectedBytes.Length];
var count = shellStream.Read(output, 0, output.Length);

_channelSessionMock.Verify(p => p.SendData(expectedBytes), Times.Once);
CollectionAssert.AreEqual(expectedBytes, output);
Assert.AreEqual(expectedBytes.Length, count);
}

[TestMethod]
public void ReadLine_ShouldAlwaysFlushTheWriteBuffer()
{
var shellStream = CreateShellStream();
var command1 = "abcd\r\n";
var command2 = "efgh\r\n";
var command1Bytes = _encoding.GetBytes(command1);
var command2Bytes = _encoding.GetBytes(command2);
var expectedBytes = command1Bytes.Concat(command2Bytes);

_channelSessionMock.Setup(p => p.SendData(It.IsAny<byte[]>()))
.Raises(p => p.DataReceived += null, new ChannelDataEventArgs(0, expectedBytes));


shellStream.Write(command1Bytes, 0, command1Bytes.Length);
shellStream.Write(command2);

var output1 = shellStream.ReadLine(TimeSpan.FromMilliseconds(1));
var output2 = shellStream.ReadLine(TimeSpan.FromMilliseconds(1));

_channelSessionMock.Verify(p => p.SendData(expectedBytes), Times.Once);
Assert.AreEqual(command1.Substring(0, command1.Length - 2), output1);
Assert.AreEqual(command2.Substring(0, command2.Length - 2), output2);
}

private ShellStream CreateShellStream()
{
_sessionMock.Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object);
Expand Down
21 changes: 20 additions & 1 deletion src/Renci.SshNet/ShellStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,9 @@ public override long Position
/// <exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed.</exception>
public override int Read(byte[] buffer, int offset, int count)
{
// Flush the write buffer
if (!_isDisposed) Flush();

var i = 0;

lock (_incoming)
Expand Down Expand Up @@ -318,6 +321,9 @@ public void Expect(TimeSpan timeout, params ExpectAction[] expectActions)
var expectedFound = false;
var text = string.Empty;

// Flush the write buffer in case expecting output from written data
if (!_isDisposed) Flush();

do
{
lock (_incoming)
Expand Down Expand Up @@ -424,6 +430,9 @@ public IAsyncResult BeginExpect(TimeSpan timeout, AsyncCallback callback, object
// Create new AsyncResult object
var asyncResult = new ExpectAsyncResult(callback, state);

// Flush the write buffer in case expecting output from previous write
if (!_isDisposed) Flush();

// Execute callback on different thread
ThreadAbstraction.ExecuteThread(() =>
{
Expand Down Expand Up @@ -566,6 +575,9 @@ public string Expect(Regex regex, TimeSpan timeout)
{
var text = string.Empty;

// Flush the write buffer in case expecting output from previous write.
if (!_isDisposed) Flush();

while (true)
{
lock (_incoming)
Expand Down Expand Up @@ -631,6 +643,9 @@ public string ReadLine(TimeSpan timeout)
{
var text = string.Empty;

// Flush the write buffer
if(!_isDisposed) Flush();

while (true)
{
lock (_incoming)
Expand Down Expand Up @@ -683,6 +698,9 @@ public string ReadLine(TimeSpan timeout)
public string Read()
{
string text;

// Flush the write buffer
Flush();

lock (_incoming)
{
Expand Down Expand Up @@ -711,7 +729,8 @@ public void Write(string text)
}

var data = _encoding.GetBytes(text);
_channel.SendData(data);

Write(data, 0, data.Length);
}

/// <summary>
Expand Down

0 comments on commit 2830ba9

Please sign in to comment.