Explorar o código

* Introduced ChannelExtendedDataEventArgs which is used to signal receive of extended data.
* Removed DataTypeCode from ChannelDataEventArgs, as this is specific to extended data.
* Large set of optimizations in receive and send of SSH messages:
- removed several buffer copies
- modified most of the SSH messages to allow the size of the message to be calculated in advance to eliminate need to resize buffer.
- added Compress(byte[] data, int offset, int length) overload to Compressor to compress part of a given buffer thereby avoiding need for buffer copy.
- added Encrypt(byte[] data, int offset, int length) overload to Cipher to encrypt part of a given buffer thereby avoiding need for buffer copy.

* SshData:
- SshData.GetBytes uses a SshDataStream which has a capacity that (in almost all cases) matches the size of the SSH message.
- Added a Load(byte[] value, int offset) overload.
- Added a LoadBytes(byte[] bytes, int offset) overload.
- Added a Write(byte[] data) overload.
- Added a Write(byte[] buffer, int offset, int count) overload.

* Added SendData(byte[] data, int offset, int size) overload to Channel to allow sending part of a given buffer.
This avoids a buffer copy in ScpClient, SftpClient, Shell, ChannelDirectTcpip, ChannelForwardedTcpip.
Fixes issue #1516.

All optimization changes above are only active when the TUNING conditional compilation symbol is defined.
By default, this symbol is defined.

Gert Driesen %!s(int64=11) %!d(string=hai) anos
pai
achega
c61633a3bc
Modificáronse 100 ficheiros con 4951 adicións e 380 borrados
  1. 1 0
      Renci.SshClient/Renci.SshNet.Tests/Classes/CipherInfoTest.cs
  2. 19 13
      Renci.SshClient/Renci.SshNet.Tests/Classes/Common/SshDataTest.cs
  3. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Dispose_PortStarted_ChannelBound.cs
  4. 1 23
      Renci.SshClient/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Started.cs
  5. 0 42
      Renci.SshClient/Renci.SshNet.Tests/Classes/Messages/Authentication/RequestMessageTest.cs
  6. 153 18
      Renci.SshClient/Renci.SshNet.Tests/Classes/Messages/Connection/ChannelDataMessageTest.cs
  7. 269 42
      Renci.SshClient/Renci.SshNet.Tests/Classes/Messages/Connection/ChannelOpen/ChannelOpenMessageTest.cs
  8. 0 12
      Renci.SshClient/Renci.SshNet.Tests/Classes/Messages/Connection/GlobalRequestMessageTest.cs
  9. 11 2
      Renci.SshClient/Renci.SshNet.Tests/Classes/ScpClientTest_Upload_FileInfoAndPath_Success.cs
  10. 121 4
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/ExtendedRequests/FStatVfsRequestTest.cs
  11. 114 4
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/ExtendedRequests/HardLinkRequestTest.cs
  12. 118 4
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/ExtendedRequests/PosixRenameRequestTest.cs
  13. 127 4
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/ExtendedRequests/StatVfsRequestTest.cs
  14. 99 3
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpBlockRequestTest.cs
  15. 84 3
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpCloseRequestTest.cs
  16. 93 3
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpFSetStatRequestTest.cs
  17. 106 3
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpFStatRequestTest.cs
  18. 112 3
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpLStatRequestTest.cs
  19. 107 3
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpLinkRequestTest.cs
  20. 99 3
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpMkDirRequestTest.cs
  21. 112 3
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpOpenDirRequestTest.cs
  22. 140 3
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpOpenRequestTest.cs
  23. 107 3
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpReadDirRequestTest.cs
  24. 125 3
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpReadLinkRequestTest.cs
  25. 132 4
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpReadRequestTest.cs
  26. 140 3
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpRealPathRequestTest.cs
  27. 90 3
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpRemoveRequestTest.cs
  28. 101 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpRenameRequestTest.cs
  29. 92 2
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpRmDirRequestTest.cs
  30. 104 3
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpSetStatRequestTest.cs
  31. 110 3
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpStatRequestTest.cs
  32. 119 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpSymLinkRequestTest.cs
  33. 93 3
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpUnblockRequestTest.cs
  34. 126 4
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpWriteRequestTest.cs
  35. 87 3
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Responses/ExtendedReplies/StatVfsReplyInfoTest.cs
  36. 70 3
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Responses/SftpAttrsResponseTest.cs
  37. 58 4
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Responses/SftpDataResponseTest.cs
  38. 104 3
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Responses/SftpExtendedReplyResponseTest.cs
  39. 58 4
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Responses/SftpHandleResponseTest.cs
  40. 0 10
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpDataMessageTest.cs
  41. 15 15
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileAttributesTest.cs
  42. 5 5
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Closed_FileAccessRead.cs
  43. 5 5
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Closed_FileAccessReadWrite.cs
  44. 5 5
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Closed_FileAccessWrite.cs
  45. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Disposed_FileAccessRead.cs
  46. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Disposed_FileAccessReadWrite.cs
  47. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Disposed_FileAccessWrite.cs
  48. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_SessionOpen_FileAccessRead.cs
  49. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_SessionOpen_FileAccessReadWrite.cs
  50. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_SessionOpen_FileAccessWrite.cs
  51. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Closed_FileAccessRead.cs
  52. 2 2
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Closed_FileAccessReadWrite.cs
  53. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Closed_FileAccessWrite.cs
  54. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Disposed_FileAccessRead.cs
  55. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Disposed_FileAccessReadWrite.cs
  56. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Disposed_FileAccessWrite.cs
  57. 2 2
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_SessionOpen_FileAccessRead.cs
  58. 2 2
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_SessionOpen_FileAccessReadWrite.cs
  59. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_SessionOpen_FileAccessWrite.cs
  60. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Close_Closed.cs
  61. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Close_Disposed.cs
  62. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Close_SessionNotOpen.cs
  63. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Close_SessionOpen.cs
  64. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Dispose_Closed.cs
  65. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Dispose_Disposed.cs
  66. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Dispose_SessionNotOpen.cs
  67. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Dispose_SessionOpen.cs
  68. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Finalize_SessionOpen.cs
  69. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_Closed.cs
  70. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_Disposed.cs
  71. 4 4
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_SessionNotOpen.cs
  72. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_SessionOpen_FIleAccessRead.cs
  73. 5 5
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_SessionOpen_FIleAccessReadWrite.cs
  74. 1 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_SessionOpen_FIleAccessWrite.cs
  75. 0 10
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest.cs
  76. 140 0
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestRead.cs
  77. 257 0
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestStatVfs.cs
  78. 53 0
      Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpVersionResponseBuilder.cs
  79. 2 2
      Renci.SshClient/Renci.SshNet.Tests/Classes/SubsystemSessionStub.cs
  80. 0 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_Connected.cs
  81. 0 1
      Renci.SshClient/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_OnDataReceived_Exception.cs
  82. 4 4
      Renci.SshClient/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj
  83. 51 2
      Renci.SshClient/Renci.SshNet/Channels/Channel.cs
  84. 4 0
      Renci.SshClient/Renci.SshNet/Channels/ChannelDirectTcpip.cs
  85. 4 0
      Renci.SshClient/Renci.SshNet/Channels/ChannelForwardedTcpip.cs
  86. 23 1
      Renci.SshClient/Renci.SshNet/Channels/IChannel.cs
  87. 4 0
      Renci.SshClient/Renci.SshNet/Common/BigInteger.cs
  88. 1 18
      Renci.SshClient/Renci.SshNet/Common/ChannelDataEventArgs.cs
  89. 24 0
      Renci.SshClient/Renci.SshNet/Common/ChannelExtendedDataEventArgs.cs
  90. 8 0
      Renci.SshClient/Renci.SshNet/Common/DerData.cs
  91. 115 0
      Renci.SshClient/Renci.SshNet/Common/Extensions.cs
  92. 1 1
      Renci.SshClient/Renci.SshNet/Common/ScpUploadEventArgs.cs
  93. 245 7
      Renci.SshClient/Renci.SshNet/Common/SshData.cs
  94. 142 0
      Renci.SshClient/Renci.SshNet/Common/SshDataStream.cs
  95. 45 5
      Renci.SshClient/Renci.SshNet/Compression/Compressor.cs
  96. 1 1
      Renci.SshClient/Renci.SshNet/KeyboardInteractiveAuthenticationMethod.NET40.cs
  97. 53 1
      Renci.SshClient/Renci.SshNet/Messages/Authentication/BannerMessage.cs
  98. 14 0
      Renci.SshClient/Renci.SshNet/Messages/Authentication/InformationResponseMessage.cs
  99. 46 0
      Renci.SshClient/Renci.SshNet/Messages/Authentication/PasswordChangeRequiredMessage.cs
  100. 41 0
      Renci.SshClient/Renci.SshNet/Messages/Authentication/PublicKeyMessage.cs

+ 1 - 0
Renci.SshClient/Renci.SshNet.Tests/Classes/CipherInfoTest.cs

@@ -1,4 +1,5 @@
 using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
 using Renci.SshNet.Security.Cryptography;
 using Renci.SshNet.Tests.Common;
 using System;

+ 19 - 13
Renci.SshClient/Renci.SshNet.Tests/Classes/Common/SshDataTest.cs

@@ -9,30 +9,35 @@ namespace Renci.SshNet.Tests.Classes.Common
         [TestMethod]
         public void Write_Boolean_False()
         {
-            var sshData = new MySshData();
-            sshData.Load(new byte[0]);
+            var sshData = new BoolSshData(false);
+            
+            var bytes = sshData.GetBytes();
 
-            sshData.Write(false);
-            Assert.AreEqual((byte) 0, sshData.ReadByte());
-            Assert.IsTrue(sshData.IsEndOfData);
+            Assert.AreEqual((byte) 0, bytes[0]);
         }
 
         [TestMethod]
         public void Write_Boolean_True()
         {
-            var sshData = new MySshData();
-            sshData.Load(new byte[0]);
+            var sshData = new BoolSshData(true);
 
-            sshData.Write(true);
-            Assert.AreEqual((byte) 1, sshData.ReadByte());
-            Assert.IsTrue(sshData.IsEndOfData);
+            var bytes = sshData.GetBytes();
+
+            Assert.AreEqual((byte) 1, bytes[0]);
         }
 
-        private class MySshData : SshData
+        private class BoolSshData : SshData
         {
-            public new void Write(bool data)
+            private readonly bool _value;
+
+            public BoolSshData(bool value)
+            {
+                _value = value;
+            }
+
+            public new bool IsEndOfData
             {
-                base.Write(data);
+                get { return base.IsEndOfData; }
             }
 
             public new byte ReadByte()
@@ -46,6 +51,7 @@ namespace Renci.SshNet.Tests.Classes.Common
 
             protected override void SaveData()
             {
+                Write(_value);
             }
         }
     }

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Dispose_PortStarted_ChannelBound.cs

@@ -100,7 +100,7 @@ namespace Renci.SshNet.Tests.Classes
                         _sessionMock.Raise(s => s.RequestSuccessReceived += null,
                             new MessageEventArgs<RequestSuccessMessage>(new RequestSuccessMessage())));
             _sessionMock.Setup(p => p.WaitOnHandle(It.IsAny<WaitHandle>()));
-            _sessionMock.Setup(p => p.SendMessage(It.Is<ChannelOpenFailureMessage>(c => c.LocalChannelNumber == _remoteChannelNumberWhileClosing && c.ReasonCode == ChannelOpenFailureMessage.AdministrativelyProhibited && c.Description == string.Empty && c.Language == null)));
+            _sessionMock.Setup(p => p.SendMessage(It.Is<ChannelOpenFailureMessage>(c => c.LocalChannelNumber == _remoteChannelNumberWhileClosing && c.ReasonCode == ChannelOpenFailureMessage.AdministrativelyProhibited && c.Description == string.Empty && c.Language == "en")));
             _sessionMock.Setup(p => p.CreateChannelForwardedTcpip(_remoteChannelNumberStarted, _remoteWindowSizeStarted, _remotePacketSizeStarted)).Returns(_channelMock.Object);
             _channelMock.Setup(
                 p =>

+ 1 - 23
Renci.SshClient/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Started.cs

@@ -179,28 +179,6 @@ namespace Renci.SshNet.Tests.Classes
             Assert.AreEqual(0, _exceptionRegister.Count);
         }
 
-        [TestMethod]
-        public void ForwardedPortShouldIgnoreChannelOpenMessageWhenChannelOpenInfoIsNull()
-        {
-            var channelNumber = (uint)new Random().Next(1001, int.MaxValue);
-            var initialWindowSize = (uint)new Random().Next(0, int.MaxValue);
-            var maximumPacketSize = (uint)new Random().Next(0, int.MaxValue);
-            var channelMock = new Mock<IChannelForwardedTcpip>(MockBehavior.Strict);
-
-            _sessionMock.Setup(
-                p =>
-                    p.CreateChannelForwardedTcpip(channelNumber, initialWindowSize, maximumPacketSize)).Returns(channelMock.Object);
-
-            _sessionMock.Raise(p => p.ChannelOpenReceived += null,
-                new MessageEventArgs<ChannelOpenMessage>(new ChannelOpenMessage(channelNumber, initialWindowSize,
-                    maximumPacketSize, null)));
-
-            _sessionMock.Verify(p => p.CreateChannelForwardedTcpip(channelNumber, initialWindowSize, maximumPacketSize), Times.Never);
-
-            Assert.AreEqual(0, _closingRegister.Count);
-            Assert.AreEqual(0, _exceptionRegister.Count);
-        }
-
         [TestMethod]
         public void ForwardedPortShouldIgnoreChannelOpenMessageWhenChannelOpenInfoIsNotForwardedTcpipChannelInfo()
         {
@@ -215,7 +193,7 @@ namespace Renci.SshNet.Tests.Classes
 
             _sessionMock.Raise(p => p.ChannelOpenReceived += null,
                 new MessageEventArgs<ChannelOpenMessage>(new ChannelOpenMessage(channelNumber, initialWindowSize,
-                    maximumPacketSize, new DirectTcpipChannelInfo())));
+                    maximumPacketSize, new DirectTcpipChannelInfo("HOST", 5, "ORIGIN", 4))));
 
             _sessionMock.Verify(p => p.CreateChannelForwardedTcpip(channelNumber, initialWindowSize, maximumPacketSize), Times.Never);
 

+ 0 - 42
Renci.SshClient/Renci.SshNet.Tests/Classes/Messages/Authentication/RequestMessageTest.cs

@@ -1,42 +0,0 @@
-using Renci.SshNet.Messages.Authentication;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using Renci.SshNet.Messages;
-using Renci.SshNet.Tests.Common;
-
-namespace Renci.SshNet.Tests.Messages.Authentication
-{
-    /// <summary>
-    ///This is a test class for RequestMessageTest and is intended
-    ///to contain all RequestMessageTest Unit Tests
-    ///</summary>
-    [TestClass()]
-    public class RequestMessageTest : TestBase
-    {
-        /// <summary>
-        ///A test for RequestMessage Constructor
-        ///</summary>
-        [TestMethod()]
-        public void RequestMessageConstructorTest()
-        {
-            ServiceName serviceName = new ServiceName(); // TODO: Initialize to an appropriate value
-            string username = string.Empty; // TODO: Initialize to an appropriate value
-            RequestMessage target = new RequestMessage(serviceName, username);
-            Assert.Inconclusive("TODO: Implement code to verify target");
-        }
-
-        /// <summary>
-        ///A test for MethodName
-        ///</summary>
-        [TestMethod()]
-        public void MethodNameTest()
-        {
-            ServiceName serviceName = new ServiceName(); // TODO: Initialize to an appropriate value
-            string username = string.Empty; // TODO: Initialize to an appropriate value
-            RequestMessage target = new RequestMessage(serviceName, username); // TODO: Initialize to an appropriate value
-            string actual;
-            actual = target.MethodName;
-            Assert.Inconclusive("Verify the correctness of this test method.");
-        }
-    }
-}

+ 153 - 18
Renci.SshClient/Renci.SshNet.Tests/Classes/Messages/Connection/ChannelDataMessageTest.cs

@@ -1,4 +1,6 @@
-using Renci.SshNet.Messages.Connection;
+using System.Linq;
+using Renci.SshNet.Common;
+using Renci.SshNet.Messages.Connection;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using System;
 using Renci.SshNet.Tests.Common;
@@ -9,29 +11,162 @@ namespace Renci.SshNet.Tests.Classes.Messages.Connection
     ///This is a test class for ChannelDataMessageTest and is intended
     ///to contain all ChannelDataMessageTest Unit Tests
     ///</summary>
-    [TestClass()]
+    [TestClass]
     public class ChannelDataMessageTest : TestBase
     {
-        /// <summary>
-        ///A test for ChannelDataMessage Constructor
-        ///</summary>
-        [TestMethod()]
-        public void ChannelDataMessageConstructorTest()
+        [TestMethod]
+        public void DefaultConstructor()
         {
-            ChannelDataMessage target = new ChannelDataMessage();
-            Assert.Inconclusive("TODO: Implement code to verify target");
+            var target = new ChannelDataMessage();
+
+            Assert.IsNull(target.Data);
+#if TUNING
+            Assert.AreEqual(0, target.Offset);
+            Assert.AreEqual(0, target.Size);
+#endif
+        }
+
+        [TestMethod]
+        public void Constructor_LocalChannelNumberAndData()
+        {
+            var random = new Random();
+
+            var localChannelNumber = (uint)random.Next(0, int.MaxValue);
+            var data = new byte[3];
+
+            var target = new ChannelDataMessage(localChannelNumber, data);
+
+            Assert.AreSame(data, target.Data);
+#if TUNING
+            Assert.AreEqual(0, target.Offset);
+            Assert.AreEqual(data.Length, target.Size);
+#endif
+        }
+
+        [TestMethod]
+        public void Constructor_LocalChannelNumberAndData_ShouldThrowArgumentNullExceptionWhenDataIsNull()
+        {
+            var localChannelNumber = (uint) new Random().Next(0, int.MaxValue);
+            byte[] data = null;
+
+            try
+            {
+                new ChannelDataMessage(localChannelNumber, data);
+                Assert.Fail();
+            }
+            catch (ArgumentNullException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("data", ex.ParamName);
+            }
+        }
+
+#if TUNING
+        [TestMethod]
+        public void Constructor_LocalChannelNumberAndDataAndOffsetAndSize()
+        {
+            var localChannelNumber = (uint) new Random().Next(0, int.MaxValue);
+            var data = new byte[4];
+            const int offset = 2;
+            const int size = 1;
+
+            var target = new ChannelDataMessage(localChannelNumber, data, offset, size);
+
+            Assert.AreSame(data, target.Data);
+            Assert.AreEqual(offset, target.Offset);
+            Assert.AreEqual(size, target.Size);
+        }
+
+        [TestMethod]
+        public void Constructor_LocalChannelNumberAndDataAndOffsetAndSize_ShouldThrowArgumentNullExceptionWhenDataIsNull()
+        {
+            var localChannelNumber = (uint) new Random().Next(0, int.MaxValue);
+            byte[] data = null;
+            const int offset = 0;
+            const int size = 0;
+
+            try
+            {
+                new ChannelDataMessage(localChannelNumber, data, offset, size);
+                Assert.Fail();
+            }
+            catch (ArgumentNullException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("data", ex.ParamName);
+            }
+        }
+#endif
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var random = new Random();
+
+            var localChannelNumber = (uint) random.Next(0, int.MaxValue);
+            var data = new byte[random.Next(10, 20)];
+            random.NextBytes(data);
+#if TUNING
+            var offset = random.Next(2, 4);
+            var size = random.Next(5, 9);
+
+            var target = new ChannelDataMessage(localChannelNumber, data, offset, size);
+#else
+            var offset = 0;
+            var size = data.Length;
+
+            var target = new ChannelDataMessage(localChannelNumber, data);
+#endif
+
+            var bytes = target.GetBytes();
+
+            var expectedBytesLength = 1; // Type
+            expectedBytesLength += 4; // LocalChannelNumber
+            expectedBytesLength += 4; // Data length
+            expectedBytesLength += size; // Data
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+            Assert.AreEqual(ChannelDataMessage.MessageNumber, sshDataStream.ReadByte());
+            Assert.AreEqual(localChannelNumber, sshDataStream.ReadUInt32());
+            Assert.AreEqual((uint) size, sshDataStream.ReadUInt32());
+
+            var actualData = new byte[size];
+            sshDataStream.Read(actualData, 0, size);
+            Assert.IsTrue(actualData.SequenceEqual(data.Take(offset, size)));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
         }
 
-        /// <summary>
-        ///A test for ChannelDataMessage Constructor
-        ///</summary>
-        [TestMethod()]
-        public void ChannelDataMessageConstructorTest1()
+        [TestMethod]
+        public void Load()
         {
-            uint localChannelNumber = 0; // TODO: Initialize to an appropriate value
-            byte[] data = null; // TODO: Initialize to an appropriate value
-            ChannelDataMessage target = new ChannelDataMessage(localChannelNumber, data);
-            Assert.Inconclusive("TODO: Implement code to verify target");
+            var random = new Random();
+
+            var localChannelNumber = (uint)random.Next(0, int.MaxValue);
+            var data = new byte[random.Next(10, 20)];
+            random.NextBytes(data);
+#if TUNING
+            var offset = random.Next(2, 4);
+            var size = random.Next(5, 9);
+            var channelDataMessage = new ChannelDataMessage(localChannelNumber, data, offset, size);
+#else
+            var offset = 0;
+            var size = data.Length;
+            var channelDataMessage = new ChannelDataMessage(localChannelNumber, data);
+#endif
+            var bytes = channelDataMessage.GetBytes();
+            var target = new ChannelDataMessage();
+
+            target.Load(bytes);
+
+            Assert.IsTrue(target.Data.SequenceEqual(data.Take(offset, size)));
+#if TUNING
+            Assert.AreEqual(0, target.Offset);
+            Assert.AreEqual(size, target.Size);
+#endif
         }
     }
 }

+ 269 - 42
Renci.SshClient/Renci.SshNet.Tests/Classes/Messages/Connection/ChannelOpen/ChannelOpenMessageTest.cs

@@ -1,52 +1,279 @@
-using Renci.SshNet.Messages.Connection;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using Renci.SshNet.Common;
+using Renci.SshNet.Messages.Connection;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using System;
-using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes.Messages.Connection
 {
-    /// <summary>
-    ///This is a test class for ChannelOpenMessageTest and is intended
-    ///to contain all ChannelOpenMessageTest Unit Tests
-    ///</summary>
     [TestClass]
-    [Ignore] // placeholders only
-    public class ChannelOpenMessageTest : TestBase
+    public class ChannelOpenMessageTest
     {
-        /// <summary>
-        ///A test for ChannelOpenMessage Constructor
-        ///</summary>
-        [TestMethod()]
-        public void ChannelOpenMessageConstructorTest()
-        {
-            ChannelOpenMessage target = new ChannelOpenMessage();
-            Assert.Inconclusive("TODO: Implement code to verify target");
-        }
-
-        /// <summary>
-        ///A test for ChannelOpenMessage Constructor
-        ///</summary>
-        [TestMethod()]
-        public void ChannelOpenMessageConstructorTest1()
-        {
-            uint channelNumber = 0; // TODO: Initialize to an appropriate value
-            uint initialWindowSize = 0; // TODO: Initialize to an appropriate value
-            uint maximumPacketSize = 0; // TODO: Initialize to an appropriate value
-            ChannelOpenInfo info = null; // TODO: Initialize to an appropriate value
-            ChannelOpenMessage target = new ChannelOpenMessage(channelNumber, initialWindowSize, maximumPacketSize, info);
-            Assert.Inconclusive("TODO: Implement code to verify target");
-        }
-
-        /// <summary>
-        ///A test for ChannelType
-        ///</summary>
-        [TestMethod()]
-        public void ChannelTypeTest()
-        {
-            ChannelOpenMessage target = new ChannelOpenMessage(); // TODO: Initialize to an appropriate value
-            string actual;
-            actual = target.ChannelType;
-            Assert.Inconclusive("Verify the correctness of this test method.");
+        private Random _random;
+        private Encoding _ascii;
+
+        [TestInitialize]
+        public void Init()
+        {
+            _random = new Random();
+            _ascii = Encoding.ASCII;
+        }
+
+        [TestMethod]
+        public void DefaultConstructor()
+        {
+            var target = new ChannelOpenMessage();
+
+#if TUNING
+            Assert.IsNull(target.ChannelType);
+#endif
+            Assert.IsNull(target.Info);
+            Assert.AreEqual(default(uint), target.InitialWindowSize);
+            Assert.AreEqual(default(uint), target.LocalChannelNumber);
+            Assert.AreEqual(default(uint), target.MaximumPacketSize);
+        }
+
+        [TestMethod]
+        public void Constructor_LocalChannelNumberAndInitialWindowSizeAndMaximumPacketSizeAndInfo()
+        {
+            var localChannelNumber = (uint) _random.Next(0, int.MaxValue);
+            var initialWindowSize = (uint) _random.Next(0, int.MaxValue);
+            var maximumPacketSize = (uint) _random.Next(0, int.MaxValue);
+            var info = new DirectTcpipChannelInfo("host", 22, "originator", 25);
+
+            var target = new ChannelOpenMessage(localChannelNumber, initialWindowSize, maximumPacketSize, info);
+
+#if TUNING
+            Assert.AreEqual(info.ChannelType, _ascii.GetString(target.ChannelType));
+#else
+            Assert.AreEqual(info.ChannelType, target.ChannelType);
+#endif
+            Assert.AreSame(info, target.Info);
+            Assert.AreEqual(initialWindowSize, target.InitialWindowSize);
+            Assert.AreEqual(localChannelNumber, target.LocalChannelNumber);
+            Assert.AreEqual(maximumPacketSize, target.MaximumPacketSize);
+        }
+
+        [TestMethod]
+        public void Constructor_LocalChannelNumberAndInitialWindowSizeAndMaximumPacketSizeAndInfo_ShouldThrowArgumentNullExceptionWhenInfoIsNull()
+        {
+            var localChannelNumber = (uint) _random.Next(0, int.MaxValue);
+            var initialWindowSize = (uint) _random.Next(0, int.MaxValue);
+            var maximumPacketSize = (uint) _random.Next(0, int.MaxValue);
+            ChannelOpenInfo info = null;
+
+            try
+            {
+                new ChannelOpenMessage(localChannelNumber, initialWindowSize, maximumPacketSize, info);
+                Assert.Fail();
+            }
+            catch (ArgumentNullException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("info", ex.ParamName);
+            }
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var localChannelNumber = (uint)_random.Next(0, int.MaxValue);
+            var initialWindowSize = (uint)_random.Next(0, int.MaxValue);
+            var maximumPacketSize = (uint)_random.Next(0, int.MaxValue);
+            var info = new DirectTcpipChannelInfo("host", 22, "originator", 25);
+            var infoBytes = info.GetBytes();
+            var target = new ChannelOpenMessage(localChannelNumber, initialWindowSize, maximumPacketSize, info);
+
+            var bytes = target.GetBytes();
+
+            var expectedBytesLength = 1; // Type
+            expectedBytesLength += 4; // ChannelType length
+            expectedBytesLength += target.ChannelType.Length; // ChannelType
+            expectedBytesLength += 4; // LocalChannelNumber
+            expectedBytesLength += 4; // InitialWindowSize
+            expectedBytesLength += 4; // MaximumPacketSize
+            expectedBytesLength += infoBytes.Length; // Info
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+            Assert.AreEqual(ChannelOpenMessage.MessageNumber, sshDataStream.ReadByte());
+
+            var actualChannelTypeLength = sshDataStream.ReadUInt32();
+            Assert.AreEqual((uint) target.ChannelType.Length, actualChannelTypeLength);
+
+#if TUNING
+            var actualChannelType = new byte[actualChannelTypeLength];
+            sshDataStream.Read(actualChannelType, 0, (int) actualChannelTypeLength);
+            Assert.IsTrue(target.ChannelType.SequenceEqual(actualChannelType));
+#else
+            var actualChannelType = new byte[actualChannelTypeLength];
+            sshDataStream.Read(actualChannelType, 0, (int) actualChannelTypeLength);
+            Assert.AreEqual(target.ChannelType, SshData.Ascii.GetString(actualChannelType));
+#endif
+
+            Assert.AreEqual(localChannelNumber, sshDataStream.ReadUInt32());
+            Assert.AreEqual(initialWindowSize, sshDataStream.ReadUInt32());
+            Assert.AreEqual(maximumPacketSize, sshDataStream.ReadUInt32());
+
+            var actualInfo = new byte[infoBytes.Length];
+            sshDataStream.Read(actualInfo, 0, actualInfo.Length);
+            Assert.IsTrue(infoBytes.SequenceEqual(actualInfo));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
+
+        [TestMethod]
+        public void Load_DirectTcpipChannelInfo()
+        {
+            var localChannelNumber = (uint)_random.Next(0, int.MaxValue);
+            var initialWindowSize = (uint)_random.Next(0, int.MaxValue);
+            var maximumPacketSize = (uint)_random.Next(0, int.MaxValue);
+            var info = new DirectTcpipChannelInfo("host", 22, "originator", 25);
+            var target = new ChannelOpenMessage(localChannelNumber, initialWindowSize, maximumPacketSize, info);
+            var bytes = target.GetBytes();
+
+            target.Load(bytes);
+
+#if TUNING
+            Assert.AreEqual(info.ChannelType, _ascii.GetString(target.ChannelType));
+#else
+            Assert.AreEqual(info.ChannelType, target.ChannelType);
+#endif
+            Assert.IsNotNull(target.Info);
+            Assert.AreEqual(initialWindowSize, target.InitialWindowSize);
+            Assert.AreEqual(localChannelNumber, target.LocalChannelNumber);
+            Assert.AreEqual(maximumPacketSize, target.MaximumPacketSize);
+
+            var directTcpChannelInfo = target.Info as DirectTcpipChannelInfo;
+            Assert.IsNotNull(directTcpChannelInfo);
+            Assert.AreEqual(info.ChannelType, directTcpChannelInfo.ChannelType);
+            Assert.AreEqual(info.HostToConnect, directTcpChannelInfo.HostToConnect);
+            Assert.AreEqual(info.OriginatorAddress, directTcpChannelInfo.OriginatorAddress);
+            Assert.AreEqual(info.OriginatorPort, directTcpChannelInfo.OriginatorPort);
+            Assert.AreEqual(info.PortToConnect, directTcpChannelInfo.PortToConnect);
+        }
+
+        [TestMethod]
+        public void Load_ForwardedTcpipChannelInfo()
+        {
+            var localChannelNumber = (uint)_random.Next(0, int.MaxValue);
+            var initialWindowSize = (uint)_random.Next(0, int.MaxValue);
+            var maximumPacketSize = (uint)_random.Next(0, int.MaxValue);
+            var info = new ForwardedTcpipChannelInfo("connected", 25, "originator", 21);
+            var target = new ChannelOpenMessage(localChannelNumber, initialWindowSize, maximumPacketSize, info);
+            var bytes = target.GetBytes();
+
+            target.Load(bytes);
+
+#if TUNING
+            Assert.AreEqual(info.ChannelType, _ascii.GetString(target.ChannelType));
+#else
+            Assert.AreEqual(info.ChannelType, target.ChannelType);
+#endif
+            Assert.IsNotNull(target.Info);
+            Assert.AreEqual(initialWindowSize, target.InitialWindowSize);
+            Assert.AreEqual(localChannelNumber, target.LocalChannelNumber);
+            Assert.AreEqual(maximumPacketSize, target.MaximumPacketSize);
+
+            var forwardedTcpipChannelInfo = target.Info as ForwardedTcpipChannelInfo;
+            Assert.IsNotNull(forwardedTcpipChannelInfo);
+            Assert.AreEqual(info.ChannelType, forwardedTcpipChannelInfo.ChannelType);
+            Assert.AreEqual(info.ConnectedAddress, forwardedTcpipChannelInfo.ConnectedAddress);
+            Assert.AreEqual(info.ConnectedPort, forwardedTcpipChannelInfo.ConnectedPort);
+            Assert.AreEqual(info.OriginatorAddress, forwardedTcpipChannelInfo.OriginatorAddress);
+            Assert.AreEqual(info.OriginatorPort, forwardedTcpipChannelInfo.OriginatorPort);
+        }
+
+        [TestMethod]
+        public void Load_SessionChannelOpenInfo()
+        {
+            var localChannelNumber = (uint)_random.Next(0, int.MaxValue);
+            var initialWindowSize = (uint)_random.Next(0, int.MaxValue);
+            var maximumPacketSize = (uint)_random.Next(0, int.MaxValue);
+            var info = new SessionChannelOpenInfo();
+            var target = new ChannelOpenMessage(localChannelNumber, initialWindowSize, maximumPacketSize, info);
+            var bytes = target.GetBytes();
+
+            target.Load(bytes);
+
+#if TUNING
+            Assert.AreEqual(info.ChannelType, _ascii.GetString(target.ChannelType));
+#else
+            Assert.AreEqual(info.ChannelType, target.ChannelType);
+#endif
+            Assert.IsNotNull(target.Info);
+            Assert.AreEqual(initialWindowSize, target.InitialWindowSize);
+            Assert.AreEqual(localChannelNumber, target.LocalChannelNumber);
+            Assert.AreEqual(maximumPacketSize, target.MaximumPacketSize);
+
+            var sessionChannelOpenInfo = target.Info as SessionChannelOpenInfo;
+            Assert.IsNotNull(sessionChannelOpenInfo);
+            Assert.AreEqual(info.ChannelType, sessionChannelOpenInfo.ChannelType);
+        }
+
+
+        [TestMethod]
+        public void Load_X11ChannelOpenInfo()
+        {
+            var localChannelNumber = (uint)_random.Next(0, int.MaxValue);
+            var initialWindowSize = (uint)_random.Next(0, int.MaxValue);
+            var maximumPacketSize = (uint)_random.Next(0, int.MaxValue);
+            var info = new X11ChannelOpenInfo("address", 26);
+            var target = new ChannelOpenMessage(localChannelNumber, initialWindowSize, maximumPacketSize, info);
+            var bytes = target.GetBytes();
+
+            target.Load(bytes);
+
+#if TUNING
+            Assert.AreEqual(info.ChannelType, _ascii.GetString(target.ChannelType));
+#else
+            Assert.AreEqual(info.ChannelType, target.ChannelType);
+#endif
+            Assert.IsNotNull(target.Info);
+            Assert.AreEqual(initialWindowSize, target.InitialWindowSize);
+            Assert.AreEqual(localChannelNumber, target.LocalChannelNumber);
+            Assert.AreEqual(maximumPacketSize, target.MaximumPacketSize);
+
+            var x11ChannelOpenInfo = target.Info as X11ChannelOpenInfo;
+            Assert.IsNotNull(x11ChannelOpenInfo);
+            Assert.AreEqual(info.ChannelType, x11ChannelOpenInfo.ChannelType);
+            Assert.AreEqual(info.OriginatorAddress, x11ChannelOpenInfo.OriginatorAddress);
+            Assert.AreEqual(info.OriginatorPort, x11ChannelOpenInfo.OriginatorPort);
+        }
+
+        [TestMethod]
+        public void Load_ShouldThrowNotSupportedExceptionWhenChannelTypeIsNotSupported()
+        {
+            var localChannelNumber = (uint)_random.Next(0, int.MaxValue);
+            var initialWindowSize = (uint)_random.Next(0, int.MaxValue);
+            var maximumPacketSize = (uint)_random.Next(0, int.MaxValue);
+            var channelName = "dunno_" + _random.Next().ToString(CultureInfo.InvariantCulture);
+            var channelType = _ascii.GetBytes(channelName);
+
+            var sshDataStream = new SshDataStream(1 + 4 + channelType.Length + 4 + 4 + 4);
+            sshDataStream.WriteByte(ChannelOpenMessage.MessageNumber);
+            sshDataStream.Write((uint) channelType.Length);
+            sshDataStream.Write(channelType, 0, channelType.Length);
+            sshDataStream.Write(localChannelNumber);
+            sshDataStream.Write(initialWindowSize);
+            sshDataStream.Write(maximumPacketSize);
+            var bytes = sshDataStream.ToArray();
+            var target = new ChannelOpenMessage();
+
+            try
+            {
+                target.Load(bytes);
+                Assert.Fail();
+            }
+            catch (NotSupportedException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual(string.Format("Channel type '{0}' is not supported.", channelName), ex.Message);
+            }
         }
     }
 }

+ 0 - 12
Renci.SshClient/Renci.SshNet.Tests/Classes/Messages/Connection/GlobalRequestMessageTest.cs

@@ -22,18 +22,6 @@ namespace Renci.SshNet.Tests.Classes.Messages.Connection
             Assert.Inconclusive("TODO: Implement code to verify target");
         }
 
-        /// <summary>
-        ///A test for GlobalRequestMessage Constructor
-        ///</summary>
-        [TestMethod()]
-        public void GlobalRequestMessageConstructorTest1()
-        {
-            GlobalRequestName requestName = new GlobalRequestName(); // TODO: Initialize to an appropriate value
-            bool wantReply = false; // TODO: Initialize to an appropriate value
-            GlobalRequestMessage target = new GlobalRequestMessage(requestName, wantReply);
-            Assert.Inconclusive("TODO: Implement code to verify target");
-        }
-
         /// <summary>
         ///A test for GlobalRequestMessage Constructor
         ///</summary>

+ 11 - 2
Renci.SshClient/Renci.SshNet.Tests/Classes/ScpClientTest_Upload_FileInfoAndPath_Success.cs

@@ -89,15 +89,24 @@ namespace Renci.SshNet.Tests.Classes
             for (var i = 0; i < random.Next(1, 3); i++)
                 _pipeStreamMock.InSequence(sequence).Setup(p => p.ReadByte()).Returns(-1);
             _pipeStreamMock.InSequence(sequence).Setup(p => p.ReadByte()).Returns(0);
+#if TUNING
+            _channelSessionMock.InSequence(sequence)
+                .Setup(
+                    p => p.SendData(It.Is<byte[]>(b => b.SequenceEqual(_fileContent.Take(_bufferSize))), 0, _bufferSize));
+            _channelSessionMock.InSequence(sequence)
+                .Setup(
+                    p => p.SendData(It.Is<byte[]>(b => b.Take(0, _fileContent.Length - _bufferSize).SequenceEqual(_fileContent.Take(_bufferSize, _fileContent.Length - _bufferSize))), 0, _fileContent.Length - _bufferSize));
+#else
             _channelSessionMock.InSequence(sequence)
                 .Setup(
                     p => p.SendData(It.Is<byte[]>(b => b.SequenceEqual(_fileContent.Take(_bufferSize)))));
             _channelSessionMock.InSequence(sequence)
                 .Setup(
                     p => p.SendData(It.Is<byte[]>(b => b.SequenceEqual(_fileContent.Skip(_bufferSize)))));
+#endif
             _channelSessionMock.InSequence(sequence)
                 .Setup(
-                    p => p.SendData(It.Is<byte[]>(b => b.SequenceEqual(new byte[] {0}))));
+                    p => p.SendData(It.Is<byte[]>(b => b.SequenceEqual(new byte[] { 0 }))));
             for (var i = 0; i < random.Next(1, 3); i++)
                 _pipeStreamMock.InSequence(sequence).Setup(p => p.ReadByte()).Returns(-1);
             _pipeStreamMock.InSequence(sequence).Setup(p => p.ReadByte()).Returns(0);
@@ -119,7 +128,7 @@ namespace Renci.SshNet.Tests.Classes
         }
 
         [TestMethod]
-        public void SendExecREquestOnChannelSessionShouldBeInvokedOnce()
+        public void SendExecRequestOnChannelSessionShouldBeInvokedOnce()
         {
             _channelSessionMock.Verify(p => p.SendExecRequest(string.Format("scp -t \"{0}\"", _path)), Times.Once);
         }

+ 121 - 4
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/ExtendedRequests/FStatVfsRequestTest.cs

@@ -1,10 +1,127 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 
-namespace Renci.SshNet.Tests.Classes.Sftp.Requests
+namespace Renci.SshNet.Tests.Classes.Sftp.Requests.ExtendedRequests
 {
     [TestClass]
-    public class FStatVfsRequestTest : TestBase
+    public class FStatVfsRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private byte[] _handle;
+        private string _name;
+        private byte[] _nameBytes;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+            _protocolVersion = (uint)random.Next(0, int.MaxValue);
+            _requestId = (uint)random.Next(0, int.MaxValue);
+            _handle = new byte[random.Next(1, 10)];
+            random.NextBytes(_handle);
+
+            _name = "fstatvfs@openssh.com";
+            _nameBytes = Encoding.UTF8.GetBytes(_name);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new FStatVfsRequest(_protocolVersion, _requestId, _handle, null, null);
+
+            Assert.AreSame(_handle, request.Handle);
+            Assert.AreEqual(_name, request.Name);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.Extended, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            IList<SftpStatusResponse> statusActionInvocations = new List<SftpStatusResponse>();
+            IList<SftpExtendedReplyResponse> extendedReplyActionInvocations = new List<SftpExtendedReplyResponse>();
+
+            Action<SftpExtendedReplyResponse> extendedAction = extendedReplyActionInvocations.Add;
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new FStatVfsRequest(_protocolVersion, _requestId, _handle, extendedAction, statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+            Assert.AreEqual(0, extendedReplyActionInvocations.Count);
+        }
+
+        [TestMethod]
+        public void Complete_SftpExtendedReplyResponse()
+        {
+            IList<SftpStatusResponse> statusActionInvocations = new List<SftpStatusResponse>();
+            IList<SftpExtendedReplyResponse> extendedReplyActionInvocations = new List<SftpExtendedReplyResponse>();
+
+            Action<SftpExtendedReplyResponse> extendedAction = extendedReplyActionInvocations.Add;
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            var extendedReplyResponse = new SftpExtendedReplyResponse(_protocolVersion);
+
+            var request = new FStatVfsRequest(_protocolVersion, _requestId, _handle, extendedAction, statusAction);
+
+            request.Complete(extendedReplyResponse);
+
+            Assert.AreEqual(0, statusActionInvocations.Count);
+            Assert.AreEqual(1, extendedReplyActionInvocations.Count);
+            Assert.AreSame(extendedReplyResponse, extendedReplyActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var request = new FStatVfsRequest(_protocolVersion, _requestId, _handle, null, null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // Name length
+            expectedBytesLength += _nameBytes.Length; // Name
+            expectedBytesLength += 4; // Handle length
+            expectedBytesLength += _handle.Length; // Handle
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint)bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte)SftpMessageTypes.Extended, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+            Assert.AreEqual((uint) _nameBytes.Length, sshDataStream.ReadUInt32());
+
+            var actualNameBytes = new byte[_nameBytes.Length];
+            sshDataStream.Read(actualNameBytes, 0, actualNameBytes.Length);
+            Assert.IsTrue(_nameBytes.SequenceEqual(actualNameBytes));
+
+            Assert.AreEqual((uint)_handle.Length, sshDataStream.ReadUInt32());
+
+            var actualHandle = new byte[_handle.Length];
+            sshDataStream.Read(actualHandle, 0, actualHandle.Length);
+            Assert.IsTrue(_handle.SequenceEqual(actualHandle));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
 }

+ 114 - 4
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/ExtendedRequests/HardLinkRequestTest.cs

@@ -1,10 +1,120 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 
-namespace Renci.SshNet.Tests.Classes.Sftp.Requests
+namespace Renci.SshNet.Tests.Classes.Sftp.Requests.ExtendedRequests
 {
     [TestClass]
-    public class HardLinkRequestTest : TestBase
+    public class HardLinkRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private string _name;
+        private string _oldPath;
+        private byte[] _oldPathBytes;
+        private string _newPath;
+        private byte[] _newPathBytes;
+        private byte[] _nameBytes;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+            _protocolVersion = (uint)random.Next(0, int.MaxValue);
+            _requestId = (uint)random.Next(0, int.MaxValue);
+            _oldPath = random.Next().ToString(CultureInfo.InvariantCulture);
+            _oldPathBytes = Encoding.UTF8.GetBytes(_oldPath);
+            _newPath = random.Next().ToString(CultureInfo.InvariantCulture);
+            _newPathBytes = Encoding.UTF8.GetBytes(_newPath);
+
+            _name = "hardlink@openssh.com";
+            _nameBytes = Encoding.UTF8.GetBytes(_name);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new HardLinkRequest(_protocolVersion, _requestId, _oldPath, _newPath, null);
+
+            Assert.AreEqual(_name, request.Name);
+            Assert.AreEqual(_newPath, request.NewPath);
+            Assert.AreEqual(_oldPath, request.OldPath);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.Extended, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            IList<SftpStatusResponse> statusActionInvocations = new List<SftpStatusResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new HardLinkRequest(_protocolVersion, _requestId, _oldPath, _newPath, statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var request = new HardLinkRequest(_protocolVersion, _requestId, _oldPath, _newPath, null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // Name length
+            expectedBytesLength += _nameBytes.Length; // Name
+            expectedBytesLength += 4; // OldPath length
+            expectedBytesLength += _oldPathBytes.Length; // OldPath
+            expectedBytesLength += 4; // NewPath length
+            expectedBytesLength += _newPathBytes.Length; // NewPath
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint)bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte)SftpMessageTypes.Extended, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+            Assert.AreEqual((uint)_nameBytes.Length, sshDataStream.ReadUInt32());
+
+            var actualNameBytes = new byte[_nameBytes.Length];
+            sshDataStream.Read(actualNameBytes, 0, actualNameBytes.Length);
+            Assert.IsTrue(_nameBytes.SequenceEqual(actualNameBytes));
+
+            Assert.AreEqual((uint)_oldPathBytes.Length, sshDataStream.ReadUInt32());
+
+            var actualOldPath = new byte[_oldPathBytes.Length];
+            sshDataStream.Read(actualOldPath, 0, actualOldPath.Length);
+            Assert.IsTrue(_oldPathBytes.SequenceEqual(actualOldPath));
+
+            Assert.AreEqual((uint)_newPathBytes.Length, sshDataStream.ReadUInt32());
+
+            var actualNewPath = new byte[_newPathBytes.Length];
+            sshDataStream.Read(actualNewPath, 0, actualNewPath.Length);
+            Assert.IsTrue(_newPathBytes.SequenceEqual(actualNewPath));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
 }

+ 118 - 4
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/ExtendedRequests/PosixRenameRequestTest.cs

@@ -1,10 +1,124 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 
-namespace Renci.SshNet.Tests.Classes.Sftp.Requests
+namespace Renci.SshNet.Tests.Classes.Sftp.Requests.ExtendedRequests
 {
     [TestClass]
-    public class PosixRenameRequestTest : TestBase
+    public class PosixRenameRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private string _name;
+        private string _oldPath;
+        private byte[] _oldPathBytes;
+        private string _newPath;
+        private byte[] _newPathBytes;
+        private byte[] _nameBytes;
+        private Encoding _encoding;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _encoding = Encoding.Unicode;
+            _protocolVersion = (uint)random.Next(0, int.MaxValue);
+            _requestId = (uint)random.Next(0, int.MaxValue);
+            _oldPath = random.Next().ToString(CultureInfo.InvariantCulture);
+            _oldPathBytes = _encoding.GetBytes(_oldPath);
+            _newPath = random.Next().ToString(CultureInfo.InvariantCulture);
+            _newPathBytes = _encoding.GetBytes(_newPath);
+
+            _name = "posix-rename@openssh.com";
+            _nameBytes = Encoding.UTF8.GetBytes(_name);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new PosixRenameRequest(_protocolVersion, _requestId, _oldPath, _newPath, _encoding, null);
+
+            Assert.AreSame(_encoding, request.Encoding);
+            Assert.AreEqual(_name, request.Name);
+            Assert.AreEqual(_newPath, request.NewPath);
+            Assert.AreEqual(_oldPath, request.OldPath);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.Extended, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            IList<SftpStatusResponse> statusActionInvocations = new List<SftpStatusResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new PosixRenameRequest(_protocolVersion, _requestId, _oldPath, _newPath, _encoding, statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var request = new PosixRenameRequest(_protocolVersion, _requestId, _oldPath, _newPath, _encoding, null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // Name length
+            expectedBytesLength += _nameBytes.Length; // Name
+            expectedBytesLength += 4; // OldPath length
+            expectedBytesLength += _oldPathBytes.Length; // OldPath
+            expectedBytesLength += 4; // NewPath length
+            expectedBytesLength += _newPathBytes.Length; // NewPath
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint)bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte)SftpMessageTypes.Extended, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+            Assert.AreEqual((uint)_nameBytes.Length, sshDataStream.ReadUInt32());
+
+            var actualNameBytes = new byte[_nameBytes.Length];
+            sshDataStream.Read(actualNameBytes, 0, actualNameBytes.Length);
+            Assert.IsTrue(_nameBytes.SequenceEqual(actualNameBytes));
+
+            Assert.AreEqual((uint)_oldPathBytes.Length, sshDataStream.ReadUInt32());
+
+            var actualOldPath = new byte[_oldPathBytes.Length];
+            sshDataStream.Read(actualOldPath, 0, actualOldPath.Length);
+            Assert.IsTrue(_oldPathBytes.SequenceEqual(actualOldPath));
+
+            Assert.AreEqual((uint)_newPathBytes.Length, sshDataStream.ReadUInt32());
+
+            var actualNewPath = new byte[_newPathBytes.Length];
+            sshDataStream.Read(actualNewPath, 0, actualNewPath.Length);
+            Assert.IsTrue(_newPathBytes.SequenceEqual(actualNewPath));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
 }

+ 127 - 4
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/ExtendedRequests/StatVfsRequestTest.cs

@@ -1,10 +1,133 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 
-namespace Renci.SshNet.Tests.Classes.Sftp.Requests
+namespace Renci.SshNet.Tests.Classes.Sftp.Requests.ExtendedRequests
 {
     [TestClass]
-    public class StatVfsRequestTest : TestBase
+    public class StatVfsRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private string _name;
+        private string _path;
+        private byte[] _pathBytes;
+        private byte[] _nameBytes;
+        private Encoding _encoding;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _encoding = Encoding.Unicode;
+            _protocolVersion = (uint)random.Next(0, int.MaxValue);
+            _requestId = (uint)random.Next(0, int.MaxValue);
+            _path = random.Next().ToString(CultureInfo.InvariantCulture);
+            _pathBytes = _encoding.GetBytes(_path);
+
+            _name = "statvfs@openssh.com";
+            _nameBytes = Encoding.UTF8.GetBytes(_name);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new StatVfsRequest(_protocolVersion, _requestId, _path, _encoding, null, null);
+
+            Assert.AreSame(_encoding, request.Encoding);
+            Assert.AreEqual(_name, request.Name);
+            Assert.AreEqual(_path, request.Path);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.Extended, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            IList<SftpStatusResponse> statusActionInvocations = new List<SftpStatusResponse>();
+            IList<SftpExtendedReplyResponse> extendedReplyActionInvocations = new List<SftpExtendedReplyResponse>();
+
+            Action<SftpExtendedReplyResponse> extendedAction = extendedReplyActionInvocations.Add;
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new StatVfsRequest(_protocolVersion, _requestId, _path, _encoding, extendedAction, statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+            Assert.AreEqual(0, extendedReplyActionInvocations.Count);
+        }
+
+        [TestMethod]
+        public void Complete_SftpExtendedReplyResponse()
+        {
+            IList<SftpStatusResponse> statusActionInvocations = new List<SftpStatusResponse>();
+            IList<SftpExtendedReplyResponse> extendedReplyActionInvocations = new List<SftpExtendedReplyResponse>();
+
+            Action<SftpExtendedReplyResponse> extendedAction = extendedReplyActionInvocations.Add;
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            var extendedReplyResponse = new SftpExtendedReplyResponse(_protocolVersion);
+
+            var request = new StatVfsRequest(_protocolVersion, _requestId, _path, _encoding, extendedAction, statusAction);
+
+            request.Complete(extendedReplyResponse);
+
+            Assert.AreEqual(0, statusActionInvocations.Count);
+            Assert.AreEqual(1, extendedReplyActionInvocations.Count);
+            Assert.AreSame(extendedReplyResponse, extendedReplyActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var request = new StatVfsRequest(_protocolVersion, _requestId, _path, _encoding, null, null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // Name length
+            expectedBytesLength += _nameBytes.Length; // Name
+            expectedBytesLength += 4; // Path length
+            expectedBytesLength += _pathBytes.Length; // Path
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint)bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte)SftpMessageTypes.Extended, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+            Assert.AreEqual((uint)_nameBytes.Length, sshDataStream.ReadUInt32());
+
+            var actualNameBytes = new byte[_nameBytes.Length];
+            sshDataStream.Read(actualNameBytes, 0, actualNameBytes.Length);
+            Assert.IsTrue(_nameBytes.SequenceEqual(actualNameBytes));
+
+            Assert.AreEqual((uint)_pathBytes.Length, sshDataStream.ReadUInt32());
+
+            var actualPath = new byte[_pathBytes.Length];
+            sshDataStream.Read(actualPath, 0, actualPath.Length);
+            Assert.IsTrue(_pathBytes.SequenceEqual(actualPath));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
 }

+ 99 - 3
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpBlockRequestTest.cs

@@ -1,10 +1,106 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Requests
 {
     [TestClass]
-    public class SftpBlockRequestTest : TestBase
+    public class SftpBlockRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private byte[] _handle;
+        private ulong _offset;
+        private ulong _length;
+        private uint _lockMask;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _protocolVersion = (uint)random.Next(0, int.MaxValue);
+            _requestId = (uint)random.Next(0, int.MaxValue);
+            _handle = new byte[random.Next(1, 10)];
+            random.NextBytes(_handle);
+            _offset = (ulong) random.Next(0, int.MaxValue);
+            _length = (ulong) random.Next(0, int.MaxValue);
+            _lockMask = (uint) random.Next(0, int.MaxValue);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new SftpBlockRequest(_protocolVersion, _requestId, _handle, _offset, _length, _lockMask, null);
+
+            Assert.AreSame(_handle, request.Handle);
+            Assert.AreEqual(_length, request.Length);
+            Assert.AreEqual(_lockMask, request.LockMask);
+            Assert.AreEqual(_offset, request.Offset);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.Block, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            IList<SftpStatusResponse> statusActionInvocations = new List<SftpStatusResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new SftpBlockRequest(_protocolVersion, _requestId, _handle, _offset, _length, _lockMask, statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var request = new SftpBlockRequest(_protocolVersion, _requestId, _handle, _offset, _length, _lockMask, null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // Handle length
+            expectedBytesLength += _handle.Length; // Handle
+            expectedBytesLength += 8; // Offset
+            expectedBytesLength += 8; // Length
+            expectedBytesLength += 4; // LockMask
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint)bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte)SftpMessageTypes.Block, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+
+            Assert.AreEqual((uint)_handle.Length, sshDataStream.ReadUInt32());
+            var actualHandle = new byte[_handle.Length];
+            sshDataStream.Read(actualHandle, 0, actualHandle.Length);
+            Assert.IsTrue(_handle.SequenceEqual(actualHandle));
+
+            Assert.AreEqual(_offset, sshDataStream.ReadUInt64());
+            Assert.AreEqual(_length, sshDataStream.ReadUInt64());
+            Assert.AreEqual(_lockMask, sshDataStream.ReadUInt32());
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
 }

+ 84 - 3
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpCloseRequestTest.cs

@@ -1,10 +1,91 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Requests
 {
     [TestClass]
-    public class SftpCloseRequestTest : TestBase
+    public class SftpCloseRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private byte[] _handle;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _protocolVersion = (uint)random.Next(0, int.MaxValue);
+            _requestId = (uint)random.Next(0, int.MaxValue);
+            _handle = new byte[random.Next(1, 10)];
+            random.NextBytes(_handle);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new SftpCloseRequest(_protocolVersion, _requestId, _handle, null);
+
+            Assert.AreSame(_handle, request.Handle);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.Close, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            IList<SftpStatusResponse> statusActionInvocations = new List<SftpStatusResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new SftpCloseRequest(_protocolVersion, _requestId, _handle, statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var request = new SftpCloseRequest(_protocolVersion, _requestId, _handle, null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // Handle length
+            expectedBytesLength += _handle.Length; // Handle
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint)bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte)SftpMessageTypes.Close, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+
+            Assert.AreEqual((uint)_handle.Length, sshDataStream.ReadUInt32());
+            var actualHandle = new byte[_handle.Length];
+            sshDataStream.Read(actualHandle, 0, actualHandle.Length);
+            Assert.IsTrue(_handle.SequenceEqual(actualHandle));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
 }

+ 93 - 3
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpFSetStatRequestTest.cs

@@ -1,10 +1,100 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Requests
 {
     [TestClass]
-    public class SftpFSetStatRequestTest : TestBase
+    public class SftpFSetStatRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private byte[] _handle;
+        private SftpFileAttributes _attributes;
+        private byte[] _attributesBytes;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _protocolVersion = (uint)random.Next(0, int.MaxValue);
+            _requestId = (uint)random.Next(0, int.MaxValue);
+            _handle = new byte[random.Next(1, 10)];
+            random.NextBytes(_handle);
+            _attributes = SftpFileAttributes.Empty;
+            _attributesBytes = _attributes.GetBytes();
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new SftpFSetStatRequest(_protocolVersion, _requestId, _handle, _attributes, null);
+
+            Assert.AreSame(_handle, request.Handle);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.FSetStat, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            IList<SftpStatusResponse> statusActionInvocations = new List<SftpStatusResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new SftpFSetStatRequest(_protocolVersion, _requestId, _handle, _attributes, statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var request = new SftpFSetStatRequest(_protocolVersion, _requestId, _handle, _attributes, null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // Handle length
+            expectedBytesLength += _handle.Length; // Handle
+            expectedBytesLength += _attributesBytes.Length; // Attributes
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint)bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte)SftpMessageTypes.FSetStat, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+
+            Assert.AreEqual((uint)_handle.Length, sshDataStream.ReadUInt32());
+            var actualHandle = new byte[_handle.Length];
+            sshDataStream.Read(actualHandle, 0, actualHandle.Length);
+            Assert.IsTrue(_handle.SequenceEqual(actualHandle));
+
+            var actualAttributes = new byte[_attributesBytes.Length];
+            sshDataStream.Read(actualAttributes, 0, actualAttributes.Length);
+            Assert.IsTrue(_attributesBytes.SequenceEqual(actualAttributes));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
 }

+ 106 - 3
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpFStatRequestTest.cs

@@ -1,10 +1,113 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Requests
 {
     [TestClass]
-    public class SftpFStatRequestTest : TestBase
+    public class SftpFStatRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private byte[] _handle;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _protocolVersion = (uint)random.Next(0, int.MaxValue);
+            _requestId = (uint)random.Next(0, int.MaxValue);
+            _handle = new byte[random.Next(1, 10)];
+            random.NextBytes(_handle);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new SftpFStatRequest(_protocolVersion, _requestId, _handle, null, null);
+
+            Assert.AreSame(_handle, request.Handle);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.FStat, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpAttrsResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            var attrsActionInvocations = new List<SftpAttrsResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            Action<SftpAttrsResponse> attrsAction = attrsActionInvocations.Add;
+            var attrsResponse = new SftpAttrsResponse(_protocolVersion);
+
+            var request = new SftpFStatRequest(_protocolVersion, _requestId, _handle, attrsAction, statusAction);
+
+            request.Complete(attrsResponse);
+
+            Assert.AreEqual(0, statusActionInvocations.Count);
+            Assert.AreEqual(1, attrsActionInvocations.Count);
+            Assert.AreSame(attrsResponse, attrsActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            var attrsActionInvocations = new List<SftpAttrsResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            Action<SftpAttrsResponse> attrsAction = attrsActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new SftpFStatRequest(_protocolVersion, _requestId, _handle, attrsAction, statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+            Assert.AreEqual(0, attrsActionInvocations.Count);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var request = new SftpFStatRequest(_protocolVersion, _requestId, _handle, null, null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // Handle length
+            expectedBytesLength += _handle.Length; // Handle
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint)bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte)SftpMessageTypes.FStat, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+
+            Assert.AreEqual((uint)_handle.Length, sshDataStream.ReadUInt32());
+            var actualHandle = new byte[_handle.Length];
+            sshDataStream.Read(actualHandle, 0, actualHandle.Length);
+            Assert.IsTrue(_handle.SequenceEqual(actualHandle));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
 }

+ 112 - 3
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpLStatRequestTest.cs

@@ -1,10 +1,119 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Requests
 {
     [TestClass]
-    public class SftpLStatRequestTest : TestBase
+    public class SftpLStatRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private Encoding _encoding;
+        private string _path;
+        private byte[] _pathBytes;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _encoding = Encoding.Unicode;
+            _protocolVersion = (uint) random.Next(0, int.MaxValue);
+            _requestId = (uint) random.Next(0, int.MaxValue);
+            _path = random.Next().ToString(CultureInfo.InvariantCulture);
+            _pathBytes = _encoding.GetBytes(_path);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new SftpLStatRequest(_protocolVersion, _requestId, _path, _encoding, null, null);
+
+            Assert.AreSame(_encoding, request.Encoding);
+            Assert.AreEqual(_path, request.Path);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.LStat, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpAttrsResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            var attrsActionInvocations = new List<SftpAttrsResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            Action<SftpAttrsResponse> attrsAction = attrsActionInvocations.Add;
+            var attrsResponse = new SftpAttrsResponse(_protocolVersion);
+
+            var request = new SftpLStatRequest(_protocolVersion, _requestId, _path, _encoding, attrsAction, statusAction);
+
+            request.Complete(attrsResponse);
+
+            Assert.AreEqual(0, statusActionInvocations.Count);
+            Assert.AreEqual(1, attrsActionInvocations.Count);
+            Assert.AreSame(attrsResponse, attrsActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            var attrsActionInvocations = new List<SftpAttrsResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            Action<SftpAttrsResponse> attrsAction = attrsActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new SftpLStatRequest(_protocolVersion, _requestId, _path, _encoding, attrsAction, statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+            Assert.AreEqual(0, attrsActionInvocations.Count);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var request = new SftpLStatRequest(_protocolVersion, _requestId, _path, _encoding, null, null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // Pah length
+            expectedBytesLength += _pathBytes.Length; // Path
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint)bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte)SftpMessageTypes.LStat, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+
+            Assert.AreEqual((uint) _pathBytes.Length, sshDataStream.ReadUInt32());
+            var actualPath = new byte[_pathBytes.Length];
+            sshDataStream.Read(actualPath, 0, actualPath.Length);
+            Assert.IsTrue(_pathBytes.SequenceEqual(actualPath));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
 }

+ 107 - 3
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpLinkRequestTest.cs

@@ -1,10 +1,114 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Requests
 {
     [TestClass]
-    public class SftpLinkRequestTest : TestBase
+    public class SftpLinkRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private string _newLinkPath;
+        private byte[] _newLinkPathBytes;
+        private string _existingPath;
+        private byte[] _existingPathBytes;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _protocolVersion = (uint)random.Next(0, int.MaxValue);
+            _requestId = (uint)random.Next(0, int.MaxValue);
+            _newLinkPath = random.Next().ToString(CultureInfo.InvariantCulture);
+            _newLinkPathBytes = Encoding.UTF8.GetBytes(_newLinkPath);
+            _existingPath = random.Next().ToString(CultureInfo.InvariantCulture);
+            _existingPathBytes = Encoding.UTF8.GetBytes(_existingPath);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new SftpLinkRequest(_protocolVersion, _requestId, _newLinkPath, _existingPath, true, null);
+
+            Assert.AreEqual(_existingPath, request.ExistingPath);
+            Assert.IsTrue(request.IsSymLink);
+            Assert.AreEqual(_newLinkPath, request.NewLinkPath);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.Link, request.SftpMessageType);
+
+            request = new SftpLinkRequest(_protocolVersion, _requestId, _newLinkPath, _existingPath, false, null);
+
+            Assert.IsFalse(request.IsSymLink);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new SftpLinkRequest(_protocolVersion, _requestId, _newLinkPath, _existingPath, true, statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var request = new SftpLinkRequest(_protocolVersion, _requestId, _newLinkPath, _existingPath, true, null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // NewLinkPath length
+            expectedBytesLength += _newLinkPathBytes.Length; // NewLinkPath
+            expectedBytesLength += 4; // ExistingPath length
+            expectedBytesLength += _existingPathBytes.Length; // ExistingPath
+            expectedBytesLength += 1; // IsSymLink
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint)bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte)SftpMessageTypes.Link, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+
+            Assert.AreEqual((uint) _newLinkPathBytes.Length, sshDataStream.ReadUInt32());
+            var actualNewLinkPath = new byte[_newLinkPathBytes.Length];
+            sshDataStream.Read(actualNewLinkPath, 0, actualNewLinkPath.Length);
+            Assert.IsTrue(_newLinkPathBytes.SequenceEqual(actualNewLinkPath));
+
+            Assert.AreEqual((uint) _existingPathBytes.Length, sshDataStream.ReadUInt32());
+            var actualExistingPath = new byte[_existingPathBytes.Length];
+            sshDataStream.Read(actualExistingPath, 0, actualExistingPath.Length);
+            Assert.IsTrue(_existingPathBytes.SequenceEqual(actualExistingPath));
+
+            Assert.AreEqual((byte) 1, sshDataStream.ReadByte());
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
 }

+ 99 - 3
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpMkDirRequestTest.cs

@@ -1,10 +1,106 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Requests
 {
     [TestClass]
-    public class SftpMkDirRequestTest : TestBase
+    public class SftpMkDirRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private Encoding _encoding;
+        private string _path;
+        private byte[] _pathBytes;
+        private SftpFileAttributes _attributes;
+        private byte[] _attributesBytes;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _protocolVersion = (uint) random.Next(0, int.MaxValue);
+            _requestId = (uint) random.Next(0, int.MaxValue);
+            _encoding = Encoding.Unicode;
+            _path = random.Next().ToString(CultureInfo.InvariantCulture);
+            _pathBytes = _encoding.GetBytes(_path);
+            _attributes = SftpFileAttributes.Empty;
+            _attributesBytes = _attributes.GetBytes();
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new SftpMkDirRequest(_protocolVersion, _requestId, _path, _encoding, null);
+
+            Assert.AreSame(_encoding, request.Encoding);
+            Assert.AreEqual(_path, request.Path);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.MkDir, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new SftpMkDirRequest(_protocolVersion, _requestId, _path, _encoding, statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var request = new SftpMkDirRequest(_protocolVersion, _requestId, _path, _encoding, null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // Path length
+            expectedBytesLength += _pathBytes.Length; // Path
+            expectedBytesLength += _attributesBytes.Length; // Attributes
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint) bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte) SftpMessageTypes.MkDir, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+
+            Assert.AreEqual((uint) _pathBytes.Length, sshDataStream.ReadUInt32());
+            var actualPath = new byte[_pathBytes.Length];
+            sshDataStream.Read(actualPath, 0, actualPath.Length);
+            Assert.IsTrue(_pathBytes.SequenceEqual(actualPath));
+
+            var actualAttributes = new byte[_attributesBytes.Length];
+            sshDataStream.Read(actualAttributes, 0, actualAttributes.Length);
+            Assert.IsTrue(_attributesBytes.SequenceEqual(actualAttributes));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
 }

+ 112 - 3
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpOpenDirRequestTest.cs

@@ -1,10 +1,119 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Requests
 {
     [TestClass]
-    public class SftpOpenDirRequestTest : TestBase
+    public class SftpOpenDirRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private Encoding _encoding;
+        private string _path;
+        private byte[] _pathBytes;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _protocolVersion = (uint)random.Next(0, int.MaxValue);
+            _requestId = (uint)random.Next(0, int.MaxValue);
+            _encoding = Encoding.Unicode;
+            _path = random.Next().ToString(CultureInfo.InvariantCulture);
+            _pathBytes = _encoding.GetBytes(_path);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new SftpOpenDirRequest(_protocolVersion, _requestId, _path, _encoding, null, null);
+
+            Assert.AreSame(_encoding, request.Encoding);
+            Assert.AreEqual(_path, request.Path);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.OpenDir, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpHandleResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            var handleActionInvocations = new List<SftpHandleResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            Action<SftpHandleResponse> handleAction = handleActionInvocations.Add;
+            var handleResponse = new SftpHandleResponse(_protocolVersion);
+
+            var request = new SftpOpenDirRequest(_protocolVersion, _requestId, _path, _encoding, handleAction, statusAction);
+
+            request.Complete(handleResponse);
+
+            Assert.AreEqual(0, statusActionInvocations.Count);
+            Assert.AreEqual(1, handleActionInvocations.Count);
+            Assert.AreSame(handleResponse, handleActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            var handleActionInvocations = new List<SftpHandleResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            Action<SftpHandleResponse> handleAction = handleActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new SftpOpenDirRequest(_protocolVersion, _requestId, _path, _encoding, handleAction, statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+            Assert.AreEqual(0, handleActionInvocations.Count);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var request = new SftpOpenDirRequest(_protocolVersion, _requestId, _path, _encoding, null, null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // Path length
+            expectedBytesLength += _pathBytes.Length; // Path
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint)bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte)SftpMessageTypes.OpenDir, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+
+            Assert.AreEqual((uint)_pathBytes.Length, sshDataStream.ReadUInt32());
+            var actualPath = new byte[_pathBytes.Length];
+            sshDataStream.Read(actualPath, 0, actualPath.Length);
+            Assert.IsTrue(_pathBytes.SequenceEqual(actualPath));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
 }

+ 140 - 3
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpOpenRequestTest.cs

@@ -1,10 +1,147 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Requests
 {
     [TestClass]
-    public class SftpOpenRequestTest : TestBase
+    public class SftpOpenRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private Encoding _encoding;
+        private string _filename;
+        private byte[] _filenameBytes;
+        private Flags _flags;
+        private SftpFileAttributes _attributes;
+        private byte[] _attributesBytes;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _protocolVersion = (uint)random.Next(0, int.MaxValue);
+            _requestId = (uint)random.Next(0, int.MaxValue);
+            _encoding = Encoding.Unicode;
+            _filename = random.Next().ToString(CultureInfo.InvariantCulture);
+            _filenameBytes = _encoding.GetBytes(_filename);
+            _flags = Flags.Read;
+            _attributes = SftpFileAttributes.Empty;
+            _attributesBytes = _attributes.GetBytes();
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new SftpOpenRequest(_protocolVersion, _requestId, _filename, _encoding, _flags, null, null);
+
+            Assert.AreSame(_encoding, request.Encoding);
+            Assert.AreEqual(_filename, request.Filename);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.Open, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpHandleResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            var handleActionInvocations = new List<SftpHandleResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            Action<SftpHandleResponse> handleAction = handleActionInvocations.Add;
+            var handleResponse = new SftpHandleResponse(_protocolVersion);
+
+            var request = new SftpOpenRequest(
+                _protocolVersion,
+                _requestId,
+                _filename,
+                _encoding,
+                _flags,
+                handleAction,
+                statusAction);
+
+            request.Complete(handleResponse);
+
+            Assert.AreEqual(0, statusActionInvocations.Count);
+            Assert.AreEqual(1, handleActionInvocations.Count);
+            Assert.AreSame(handleResponse, handleActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            var handleActionInvocations = new List<SftpHandleResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            Action<SftpHandleResponse> handleAction = handleActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new SftpOpenRequest(
+                _protocolVersion,
+                _requestId,
+                _filename,
+                _encoding,
+                _flags,
+                handleAction,
+                statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+            Assert.AreEqual(0, handleActionInvocations.Count);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var request = new SftpOpenRequest(_protocolVersion, _requestId, _filename, _encoding, _flags, null, null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // Filename length
+            expectedBytesLength += _filenameBytes.Length; // Filename
+            expectedBytesLength += 4; // Flags
+            expectedBytesLength += _attributesBytes.Length; // Attributes
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint)bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte)SftpMessageTypes.Open, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+
+            Assert.AreEqual((uint)_filenameBytes.Length, sshDataStream.ReadUInt32());
+            var actualPath = new byte[_filenameBytes.Length];
+            sshDataStream.Read(actualPath, 0, actualPath.Length);
+            Assert.IsTrue(_filenameBytes.SequenceEqual(actualPath));
+
+            Assert.AreEqual((uint) _flags, sshDataStream.ReadUInt32());
+
+            var actualAttributes = new byte[_attributesBytes.Length];
+            sshDataStream.Read(actualAttributes, 0, actualAttributes.Length);
+            Assert.IsTrue(_attributesBytes.SequenceEqual(actualAttributes));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
 }

+ 107 - 3
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpReadDirRequestTest.cs

@@ -1,10 +1,114 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Requests
 {
     [TestClass]
-    public class SftpReadDirRequestTest : TestBase
+    public class SftpReadDirRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private byte[] _handle;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _protocolVersion = (uint) random.Next(0, int.MaxValue);
+            _requestId = (uint) random.Next(0, int.MaxValue);
+            _handle = new byte[random.Next(1, 10)];
+            random.NextBytes(_handle);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new SftpReadDirRequest(_protocolVersion, _requestId, _handle, null, null);
+
+            Assert.AreSame(_handle, request.Handle);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.ReadDir, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpAttrsResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            var nameActionInvocations = new List<SftpNameResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            Action<SftpNameResponse> nameAction = nameActionInvocations.Add;
+            var nameResponse = new SftpNameResponse(_protocolVersion, Encoding.Unicode);
+
+            var request = new SftpReadDirRequest(_protocolVersion, _requestId, _handle, nameAction, statusAction);
+
+            request.Complete(nameResponse);
+
+            Assert.AreEqual(0, statusActionInvocations.Count);
+            Assert.AreEqual(1, nameActionInvocations.Count);
+            Assert.AreSame(nameResponse, nameActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            var nameActionInvocations = new List<SftpNameResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            Action<SftpNameResponse> nameAction = nameActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new SftpReadDirRequest(_protocolVersion, _requestId, _handle, nameAction, statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+            Assert.AreEqual(0, nameActionInvocations.Count);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var request = new SftpReadDirRequest(_protocolVersion, _requestId, _handle, null, null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // Handle length
+            expectedBytesLength += _handle.Length; // Handle
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint) bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte) SftpMessageTypes.ReadDir, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+
+            Assert.AreEqual((uint) _handle.Length, sshDataStream.ReadUInt32());
+            var actualHandle = new byte[_handle.Length];
+            sshDataStream.Read(actualHandle, 0, actualHandle.Length);
+            Assert.IsTrue(_handle.SequenceEqual(actualHandle));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
 }

+ 125 - 3
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpReadLinkRequestTest.cs

@@ -1,10 +1,132 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Requests
 {
     [TestClass]
-    public class SftpReadLinkRequestTest : TestBase
+    public class SftpReadLinkRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private Encoding _encoding;
+        private string _path;
+        private byte[] _pathBytes;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _protocolVersion = (uint) random.Next(0, int.MaxValue);
+            _requestId = (uint) random.Next(0, int.MaxValue);
+            _encoding = Encoding.Unicode;
+            _path = random.Next().ToString(CultureInfo.InvariantCulture);
+            _pathBytes = _encoding.GetBytes(_path);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new SftpReadLinkRequest(_protocolVersion, _requestId, _path, _encoding, null, null);
+
+            Assert.AreSame(_encoding, request.Encoding);
+            Assert.AreEqual(_path, request.Path);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.ReadLink, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpNameResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            var nameActionInvocations = new List<SftpNameResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            Action<SftpNameResponse> nameAction = nameActionInvocations.Add;
+            var nameResponse = new SftpNameResponse(_protocolVersion, Encoding.Unicode);
+
+            var request = new SftpReadLinkRequest(
+                _protocolVersion,
+                _requestId,
+                _path,
+                _encoding,
+                nameAction,
+                statusAction);
+
+            request.Complete(nameResponse);
+
+            Assert.AreEqual(0, statusActionInvocations.Count);
+            Assert.AreEqual(1, nameActionInvocations.Count);
+            Assert.AreSame(nameResponse, nameActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            var nameActionInvocations = new List<SftpNameResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            Action<SftpNameResponse> nameAction = nameActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new SftpReadLinkRequest(
+                _protocolVersion,
+                _requestId,
+                _path,
+                _encoding,
+                nameAction,
+                statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+            Assert.AreEqual(0, nameActionInvocations.Count);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var request = new SftpReadLinkRequest(_protocolVersion, _requestId, _path, _encoding, null, null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // Path length
+            expectedBytesLength += _pathBytes.Length; // Path
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint) bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte) SftpMessageTypes.ReadLink, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+
+            Assert.AreEqual((uint) _pathBytes.Length, sshDataStream.ReadUInt32());
+            var actualPath = new byte[_pathBytes.Length];
+            sshDataStream.Read(actualPath, 0, actualPath.Length);
+            Assert.IsTrue(_pathBytes.SequenceEqual(actualPath));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
+
 }

+ 132 - 4
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpReadRequestTest.cs

@@ -1,10 +1,138 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Requests
 {
     [TestClass]
-    public class SftpReadRequestTest : TestBase
+    public class SftpReadRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private byte[] _handle;
+        private ulong _offset;
+        private uint _length;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _protocolVersion = (uint) random.Next(0, int.MaxValue);
+            _requestId = (uint) random.Next(0, int.MaxValue);
+            _handle = new byte[random.Next(1, 10)];
+            random.NextBytes(_handle);
+            _offset = (ulong) random.Next(0, int.MaxValue);
+            _length = (uint) random.Next(0, int.MaxValue);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new SftpReadRequest(_protocolVersion, _requestId, _handle, _offset, _length, null, null);
+
+            Assert.AreSame(_handle, request.Handle);
+            Assert.AreEqual(_length, request.Length);
+            Assert.AreEqual(_offset, request.Offset);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.Read, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpDataResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            var dataActionInvocations = new List<SftpDataResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            Action<SftpDataResponse> dataAction = dataActionInvocations.Add;
+            var dataResponse = new SftpDataResponse(_protocolVersion);
+
+            var request = new SftpReadRequest(
+                _protocolVersion,
+                _requestId,
+                _handle,
+                _offset,
+                _length,
+                dataAction,
+                statusAction);
+
+            request.Complete(dataResponse);
+
+            Assert.AreEqual(0, statusActionInvocations.Count);
+            Assert.AreEqual(1, dataActionInvocations.Count);
+            Assert.AreSame(dataResponse, dataActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            var dataActionInvocations = new List<SftpDataResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            Action<SftpDataResponse> dataAction = dataActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new SftpReadRequest(
+                _protocolVersion,
+                _requestId,
+                _handle,
+                _offset,
+                _length,
+                dataAction,
+                statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+            Assert.AreEqual(0, dataActionInvocations.Count);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var request = new SftpReadRequest(_protocolVersion, _requestId, _handle, _offset, _length, null, null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // Handle length
+            expectedBytesLength += _handle.Length; // Handle
+            expectedBytesLength += 8; // Offset
+            expectedBytesLength += 4; // Length
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint) bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte) SftpMessageTypes.Read, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+
+            Assert.AreEqual((uint) _handle.Length, sshDataStream.ReadUInt32());
+            var actualHandle = new byte[_handle.Length];
+            sshDataStream.Read(actualHandle, 0, actualHandle.Length);
+            Assert.IsTrue(_handle.SequenceEqual(actualHandle));
+
+            Assert.AreEqual(_offset, sshDataStream.ReadUInt64());
+            Assert.AreEqual(_length, sshDataStream.ReadUInt32());
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
-}
+}

+ 140 - 3
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpRealPathRequestTest.cs

@@ -1,10 +1,147 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Requests
 {
     [TestClass]
-    public class SftpRealPathRequestTest : TestBase
+    public class SftpRealPathRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private Encoding _encoding;
+        private string _path;
+        private byte[] _pathBytes;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _protocolVersion = (uint) random.Next(0, int.MaxValue);
+            _requestId = (uint) random.Next(0, int.MaxValue);
+            _encoding = Encoding.Unicode;
+            _path = random.Next().ToString(CultureInfo.InvariantCulture);
+            _pathBytes = _encoding.GetBytes(_path);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            var nameActionInvocations = new List<SftpNameResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            Action<SftpNameResponse> nameAction = nameActionInvocations.Add;
+
+            var request = new SftpRealPathRequest(
+                _protocolVersion,
+                _requestId,
+                _path,
+                _encoding,
+                nameAction,
+                statusAction);
+
+            Assert.AreSame(_encoding, request.Encoding);
+            Assert.AreEqual(_path, request.Path);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.RealPath, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpNameResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            var nameActionInvocations = new List<SftpNameResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            Action<SftpNameResponse> nameAction = nameActionInvocations.Add;
+            var nameResponse = new SftpNameResponse(_protocolVersion, Encoding.Unicode);
+
+            var request = new SftpRealPathRequest(_protocolVersion, _requestId, _path, _encoding, nameAction, statusAction);
+
+            request.Complete(nameResponse);
+
+            Assert.AreEqual(0, statusActionInvocations.Count);
+            Assert.AreEqual(1, nameActionInvocations.Count);
+            Assert.AreSame(nameResponse, nameActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            var nameActionInvocations = new List<SftpNameResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            Action<SftpNameResponse> nameAction = nameActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new SftpRealPathRequest(
+                _protocolVersion,
+                _requestId,
+                _path,
+                _encoding,
+                nameAction,
+                statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+            Assert.AreEqual(0, nameActionInvocations.Count);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            var nameActionInvocations = new List<SftpNameResponse>();
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            Action<SftpNameResponse> nameAction = nameActionInvocations.Add;
+            var request = new SftpRealPathRequest(
+                _protocolVersion,
+                _requestId,
+                _path,
+                _encoding,
+                nameAction,
+                statusAction);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // Path length
+            expectedBytesLength += _pathBytes.Length; // Path
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint)bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte)SftpMessageTypes.RealPath, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+
+            Assert.AreEqual((uint) _pathBytes.Length, sshDataStream.ReadUInt32());
+            var actualPath = new byte[_pathBytes.Length];
+            sshDataStream.Read(actualPath, 0, actualPath.Length);
+            Assert.IsTrue(_pathBytes.SequenceEqual(actualPath));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
 }

+ 90 - 3
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpRemoveRequestTest.cs

@@ -1,10 +1,97 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Requests
 {
     [TestClass]
-    public class SftpRemoveRequestTest : TestBase
+    public class SftpRemoveRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private Encoding _encoding;
+        private string _filename;
+        private byte[] _filenameBytes;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _protocolVersion = (uint) random.Next(0, int.MaxValue);
+            _requestId = (uint) random.Next(0, int.MaxValue);
+            _encoding = Encoding.Unicode;
+            _filename = random.Next().ToString(CultureInfo.InvariantCulture);
+            _filenameBytes = _encoding.GetBytes(_filename);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new SftpRemoveRequest(_protocolVersion, _requestId, _filename, _encoding, null);
+
+            Assert.AreSame(_encoding, request.Encoding);
+            Assert.AreEqual(_filename, request.Filename);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.Remove, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new SftpRemoveRequest(_protocolVersion, _requestId, _filename, _encoding, statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var request = new SftpRemoveRequest(_protocolVersion, _requestId, _filename, _encoding, null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // Filename length
+            expectedBytesLength += _filenameBytes.Length; // Filename
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint) bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte) SftpMessageTypes.Remove, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+
+            Assert.AreEqual((uint) _filenameBytes.Length, sshDataStream.ReadUInt32());
+            var actualFilename = new byte[_filenameBytes.Length];
+            sshDataStream.Read(actualFilename, 0, actualFilename.Length);
+            Assert.IsTrue(_filenameBytes.SequenceEqual(actualFilename));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
 }

+ 101 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpRenameRequestTest.cs

@@ -1,4 +1,13 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Requests
@@ -6,5 +15,96 @@ namespace Renci.SshNet.Tests.Classes.Sftp.Requests
     [TestClass]
     public class SftpRenameRequestTest : TestBase
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private Encoding _encoding;
+        private string _oldPath;
+        private byte[] _oldPathBytes;
+        private string _newPath;
+        private byte[] _newPathBytes;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _protocolVersion = (uint) random.Next(0, int.MaxValue);
+            _requestId = (uint) random.Next(0, int.MaxValue);
+            _encoding = Encoding.Unicode;
+            _oldPath = random.Next().ToString(CultureInfo.InvariantCulture);
+            _oldPathBytes = _encoding.GetBytes(_oldPath);
+            _newPath = random.Next().ToString(CultureInfo.InvariantCulture);
+            _newPathBytes = _encoding.GetBytes(_newPath);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new SftpRenameRequest(_protocolVersion, _requestId, _oldPath, _newPath, _encoding, null);
+
+            Assert.AreSame(_encoding, request.Encoding);
+            Assert.AreEqual(_newPath, request.NewPath);
+            Assert.AreEqual(_oldPath, request.OldPath);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.Rename, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new SftpRenameRequest(_protocolVersion, _requestId, _oldPath, _newPath, _encoding, statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var request = new SftpRenameRequest(_protocolVersion, _requestId, _oldPath, _newPath, _encoding, null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // OldPath length
+            expectedBytesLength += _oldPathBytes.Length; // OldPath
+            expectedBytesLength += 4; // NewPath length
+            expectedBytesLength += _newPathBytes.Length; // NewPath
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint) bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte) SftpMessageTypes.Rename, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+
+            Assert.AreEqual((uint) _oldPathBytes.Length, sshDataStream.ReadUInt32());
+            var actualOldPath = new byte[_oldPathBytes.Length];
+            sshDataStream.Read(actualOldPath, 0, actualOldPath.Length);
+            Assert.IsTrue(_oldPathBytes.SequenceEqual(actualOldPath));
+
+            Assert.AreEqual((uint) _newPathBytes.Length, sshDataStream.ReadUInt32());
+            var actualNewPath = new byte[_newPathBytes.Length];
+            sshDataStream.Read(actualNewPath, 0, actualNewPath.Length);
+            Assert.IsTrue(_newPathBytes.SequenceEqual(actualNewPath));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
 }

+ 92 - 2
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpRmDirRequestTest.cs

@@ -1,10 +1,100 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Requests
 {
     [TestClass]
-    public class SftpRmDirRequestTest : TestBase
+    public class SftpRmDirRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private Encoding _encoding;
+        private string _path;
+        private byte[] _pathBytes;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _protocolVersion = (uint)random.Next(0, int.MaxValue);
+            _requestId = (uint)random.Next(0, int.MaxValue);
+            _encoding = Encoding.Unicode;
+            _path = random.Next().ToString(CultureInfo.InvariantCulture);
+            _pathBytes = _encoding.GetBytes(_path);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new SftpRmDirRequest(_protocolVersion, _requestId, _path, _encoding, null);
+
+            Assert.AreSame(_encoding, request.Encoding);
+            Assert.AreEqual(_path, request.Path);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.RmDir, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new SftpRmDirRequest(_protocolVersion, _requestId, _path, _encoding, statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            var nameActionInvocations = new List<SftpNameResponse>();
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            var request = new SftpRmDirRequest(_protocolVersion, _requestId, _path, _encoding, null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // Path length
+            expectedBytesLength += _pathBytes.Length; // Path
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint) bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte) SftpMessageTypes.RmDir, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+
+            Assert.AreEqual((uint) _pathBytes.Length, sshDataStream.ReadUInt32());
+            var actualPath = new byte[_pathBytes.Length];
+            sshDataStream.Read(actualPath, 0, actualPath.Length);
+            Assert.IsTrue(_pathBytes.SequenceEqual(actualPath));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
 }

+ 104 - 3
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpSetStatRequestTest.cs

@@ -1,10 +1,111 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Requests
 {
     [TestClass]
-    public class SftpSetStatRequestTest : TestBase
+    public class SftpSetStatRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private Encoding _encoding;
+        private string _path;
+        private byte[] _pathBytes;
+        private SftpFileAttributes _attributes;
+        private byte[] _attributesBytes;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _protocolVersion = (uint)random.Next(0, int.MaxValue);
+            _requestId = (uint)random.Next(0, int.MaxValue);
+            _encoding = Encoding.Unicode;
+            _path = random.Next().ToString(CultureInfo.InvariantCulture);
+            _pathBytes = _encoding.GetBytes(_path);
+            _attributes = SftpFileAttributes.Empty;
+            _attributesBytes = _attributes.GetBytes();
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new SftpSetStatRequest(_protocolVersion, _requestId, _path, _encoding, _attributes, null);
+
+            Assert.AreSame(_encoding, request.Encoding);
+            Assert.AreEqual(_path, request.Path);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.SetStat, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new SftpSetStatRequest(
+                _protocolVersion,
+                _requestId,
+                _path,
+                _encoding,
+                _attributes,
+                statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var request = new SftpSetStatRequest(_protocolVersion, _requestId, _path, _encoding, _attributes, null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // Path length
+            expectedBytesLength += _pathBytes.Length; // Path
+            expectedBytesLength += _attributesBytes.Length; // Attributes
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint) bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte) SftpMessageTypes.SetStat, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+
+            Assert.AreEqual((uint)_pathBytes.Length, sshDataStream.ReadUInt32());
+            var actualPath = new byte[_pathBytes.Length];
+            sshDataStream.Read(actualPath, 0, actualPath.Length);
+            Assert.IsTrue(_pathBytes.SequenceEqual(actualPath));
+
+            var actualAttributes = new byte[_attributesBytes.Length];
+            sshDataStream.Read(actualAttributes, 0, actualAttributes.Length);
+            Assert.IsTrue(_attributesBytes.SequenceEqual(actualAttributes));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
 }

+ 110 - 3
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpStatRequestTest.cs

@@ -1,10 +1,117 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Requests
 {
     [TestClass]
-    public class SftpStatRequestTest : TestBase
+    public class SftpStatRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private Encoding _encoding;
+        private string _path;
+        private byte[] _pathBytes;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _protocolVersion = (uint)random.Next(0, int.MaxValue);
+            _requestId = (uint) random.Next(0, int.MaxValue);
+            _encoding = Encoding.Unicode;
+            _path = random.Next().ToString(CultureInfo.InvariantCulture);
+            _pathBytes = _encoding.GetBytes(_path);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new SftpStatRequest(_protocolVersion, _requestId, _path, _encoding, null, null);
+
+            Assert.AreSame(_encoding, request.Encoding);
+            Assert.AreEqual(_path, request.Path);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.Stat, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpAttrsResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            var attrsActionInvocations = new List<SftpAttrsResponse>();
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            Action<SftpAttrsResponse> attrsAction = attrsActionInvocations.Add;
+            var attrsResponse = new SftpAttrsResponse(_protocolVersion);
+
+            var request = new SftpStatRequest(_protocolVersion, _requestId, _path, _encoding, attrsAction, statusAction);
+
+            request.Complete(attrsResponse);
+
+            Assert.AreEqual(0, statusActionInvocations.Count);
+            Assert.AreEqual(1, attrsActionInvocations.Count);
+            Assert.AreSame(attrsResponse, attrsActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            var attrsActionInvocations = new List<SftpAttrsResponse>();
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            Action<SftpAttrsResponse> attrsAction = attrsActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new SftpStatRequest(_protocolVersion, _requestId, _path, _encoding, attrsAction, statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreEqual(0, attrsActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var request = new SftpStatRequest(_protocolVersion, _requestId, _path, _encoding, null, null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // Path length
+            expectedBytesLength += _pathBytes.Length; // Path
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint) bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte) SftpMessageTypes.Stat, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+
+            Assert.AreEqual((uint) _pathBytes.Length, sshDataStream.ReadUInt32());
+            var actualPath = new byte[_pathBytes.Length];
+            sshDataStream.Read(actualPath, 0, actualPath.Length);
+            Assert.IsTrue(_pathBytes.SequenceEqual(actualPath));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
 }

+ 119 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpSymLinkRequestTest.cs

@@ -1,4 +1,13 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Requests
@@ -6,5 +15,114 @@ namespace Renci.SshNet.Tests.Classes.Sftp.Requests
     [TestClass]
     public class SftpSymLinkRequestTest : TestBase
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private Encoding _encoding;
+        private string _newLinkPath;
+        private byte[] _newLinkPathBytes;
+        private string _existingPath;
+        private byte[] _existingPathBytes;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _protocolVersion = (uint) random.Next(0, int.MaxValue);
+            _requestId = (uint) random.Next(0, int.MaxValue);
+            _encoding = Encoding.Unicode;
+            _newLinkPath = random.Next().ToString(CultureInfo.InvariantCulture);
+            _newLinkPathBytes = _encoding.GetBytes(_newLinkPath);
+            _existingPath = random.Next().ToString(CultureInfo.InvariantCulture);
+            _existingPathBytes = _encoding.GetBytes(_existingPath);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new SftpSymLinkRequest(
+                _protocolVersion,
+                _requestId,
+                _newLinkPath,
+                _existingPath,
+                _encoding,
+                null);
+
+            Assert.AreSame(_encoding, request.Encoding);
+            Assert.AreEqual(_existingPath, request.ExistingPath);
+            Assert.AreEqual(_newLinkPath, request.NewLinkPath);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.SymLink, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new SftpSymLinkRequest(
+                _protocolVersion,
+                _requestId,
+                _newLinkPath,
+                _existingPath,
+                _encoding,
+                statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var request = new SftpSymLinkRequest(
+                _protocolVersion,
+                _requestId,
+                _newLinkPath,
+                _existingPath,
+                _encoding,
+                null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // NewLinkPath length
+            expectedBytesLength += _newLinkPathBytes.Length; // NewLinkPath
+            expectedBytesLength += 4; // ExistingPath length
+            expectedBytesLength += _existingPathBytes.Length; // ExistingPath
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint) bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte) SftpMessageTypes.SymLink, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+
+            Assert.AreEqual((uint) _newLinkPathBytes.Length, sshDataStream.ReadUInt32());
+            var actualNewLinkPath = new byte[_newLinkPathBytes.Length];
+            sshDataStream.Read(actualNewLinkPath, 0, actualNewLinkPath.Length);
+            Assert.IsTrue(_newLinkPathBytes.SequenceEqual(actualNewLinkPath));
+
+            Assert.AreEqual((uint) _existingPathBytes.Length, sshDataStream.ReadUInt32());
+            var actualExistingPath = new byte[_existingPathBytes.Length];
+            sshDataStream.Read(actualExistingPath, 0, actualExistingPath.Length);
+            Assert.IsTrue(_existingPathBytes.SequenceEqual(actualExistingPath));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
 }

+ 93 - 3
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpUnblockRequestTest.cs

@@ -1,10 +1,100 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Requests
 {
     [TestClass]
-    public class SftpUnblockRequestTest : TestBase
+    public class SftpUnblockRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private byte[] _handle;
+        private ulong _offset;
+        private ulong _length;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _protocolVersion = (uint)random.Next(0, int.MaxValue);
+            _requestId = (uint)random.Next(0, int.MaxValue);
+            _handle = new byte[random.Next(1, 10)];
+            random.NextBytes(_handle);
+            _offset = (ulong) random.Next(0, int.MaxValue);
+            _length = (ulong) random.Next(0, int.MaxValue);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var request = new SftpUnblockRequest(_protocolVersion, _requestId, _handle, _offset, _length, null);
+
+            Assert.AreSame(_handle, request.Handle);
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.Unblock, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new SftpUnblockRequest(_protocolVersion, _requestId, _handle, _offset, _length, statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+            var request = new SftpUnblockRequest(_protocolVersion, _requestId, _handle, _offset, _length, null);
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // Handle length
+            expectedBytesLength += _handle.Length; // Handle
+            expectedBytesLength += 8; // Offset
+            expectedBytesLength += 8; // Length
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint) bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte) SftpMessageTypes.Unblock, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+
+            Assert.AreEqual((uint) _handle.Length, sshDataStream.ReadUInt32());
+            var actualHandle = new byte[_handle.Length];
+            sshDataStream.Read(actualHandle, 0, actualHandle.Length);
+            Assert.IsTrue(_handle.SequenceEqual(actualHandle));
+
+            Assert.AreEqual(_offset, sshDataStream.ReadUInt64());
+            Assert.AreEqual(_length, sshDataStream.ReadUInt64());
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
-}
+}

+ 126 - 4
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Requests/SftpWriteRequestTest.cs

@@ -1,10 +1,132 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Requests;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Requests
 {
     [TestClass]
-    public class SftpWriteRequestTest : TestBase
+    public class SftpWriteRequestTest
     {
+        private uint _protocolVersion;
+        private uint _requestId;
+        private byte[] _handle;
+        private ulong _offset;
+        private byte[] _data;
+        private int _length;
+
+        [TestInitialize]
+        public void Init()
+        {
+            var random = new Random();
+
+            _protocolVersion = (uint)random.Next(0, int.MaxValue);
+            _requestId = (uint)random.Next(0, int.MaxValue);
+            _handle = new byte[random.Next(1, 10)];
+            random.NextBytes(_handle);
+            _offset = (ulong) random.Next(0, int.MaxValue);
+            _data = new byte[random.Next(5, 10)];
+            random.NextBytes(_data);
+#if TUNING
+            _length = random.Next(1, 4);
+#else
+            _length = _data.Length;
+#endif
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+#if TUNING
+            var request = new SftpWriteRequest(_protocolVersion, _requestId, _handle, _offset, _data, _length, null);
+#else
+            var request = new SftpWriteRequest(_protocolVersion, _requestId, _handle, _offset, _data, null);
+#endif
+
+            Assert.AreSame(_data, request.Data);
+            Assert.AreSame(_handle, request.Handle);
+#if TUNING
+            Assert.AreEqual(_length, request.Length);
+#endif
+            Assert.AreEqual(_protocolVersion, request.ProtocolVersion);
+            Assert.AreEqual(_requestId, request.RequestId);
+            Assert.AreEqual(SftpMessageTypes.Write, request.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Complete_SftpStatusResponse()
+        {
+            var statusActionInvocations = new List<SftpStatusResponse>();
+            Action<SftpStatusResponse> statusAction = statusActionInvocations.Add;
+            var statusResponse = new SftpStatusResponse(_protocolVersion);
+
+            var request = new SftpWriteRequest(
+                _protocolVersion,
+                _requestId,
+                _handle,
+                _offset,
+                _data,
+#if TUNING
+                _length,
+#endif
+                statusAction);
+
+            request.Complete(statusResponse);
+
+            Assert.AreEqual(1, statusActionInvocations.Count);
+            Assert.AreSame(statusResponse, statusActionInvocations[0]);
+        }
+
+        [TestMethod]
+        public void GetBytes()
+        {
+#if TUNING
+            var request = new SftpWriteRequest(_protocolVersion, _requestId, _handle, _offset, _data, _length, null);
+#else
+            var request = new SftpWriteRequest(_protocolVersion, _requestId, _handle, _offset, _data, null);
+#endif
+
+            var bytes = request.GetBytes();
+
+            var expectedBytesLength = 0;
+#if TUNING
+            expectedBytesLength += 4; // Length
+#endif
+            expectedBytesLength += 1; // Type
+            expectedBytesLength += 4; // RequestId
+            expectedBytesLength += 4; // Handle length
+            expectedBytesLength += _handle.Length; // Handle
+            expectedBytesLength += 8; // Offset
+            expectedBytesLength += 4; // Data length
+            expectedBytesLength += _length; // Data
+
+            Assert.AreEqual(expectedBytesLength, bytes.Length);
+
+            var sshDataStream = new SshDataStream(bytes);
+
+#if TUNING
+            Assert.AreEqual((uint) bytes.Length - 4, sshDataStream.ReadUInt32());
+#endif
+            Assert.AreEqual((byte) SftpMessageTypes.Write, sshDataStream.ReadByte());
+            Assert.AreEqual(_requestId, sshDataStream.ReadUInt32());
+
+            Assert.AreEqual((uint) _handle.Length, sshDataStream.ReadUInt32());
+            var actualHandle = new byte[_handle.Length];
+            sshDataStream.Read(actualHandle, 0, actualHandle.Length);
+            Assert.IsTrue(_handle.SequenceEqual(actualHandle));
+
+            Assert.AreEqual(_offset, sshDataStream.ReadUInt64());
+
+            Assert.AreEqual((uint) _length, sshDataStream.ReadUInt32());
+            var actualData = new byte[_length];
+            sshDataStream.Read(actualData, 0, actualData.Length);
+            Assert.IsTrue(_data.Take(_length).SequenceEqual(actualData));
+
+            Assert.IsTrue(sshDataStream.IsEndOfData);
+        }
     }
-}
+}

+ 87 - 3
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Responses/ExtendedReplies/StatVfsReplyInfoTest.cs

@@ -1,10 +1,94 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Responses
 {
     [TestClass]
-    public class StatVfsReplyInfoTest : TestBase
+    public class StatVfsReplyInfoTest
     {
+        private Random _random;
+        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 _namemax;
+
+        [TestInitialize]
+        public void Init()
+        {
+            _random = new Random();
+            _responseId = (uint) _random.Next(0, int.MaxValue);
+            _bsize = (ulong) _random.Next(0, int.MaxValue);
+            _frsize = (ulong)_random.Next(0, int.MaxValue);
+            _blocks = (ulong)_random.Next(0, int.MaxValue);
+            _bfree = (ulong)_random.Next(0, int.MaxValue);
+            _bavail = (ulong)_random.Next(0, int.MaxValue);
+            _files = (ulong)_random.Next(0, int.MaxValue);
+            _ffree = (ulong)_random.Next(0, int.MaxValue);
+            _favail = (ulong)_random.Next(0, int.MaxValue);
+            _sid = (ulong)_random.Next(0, int.MaxValue);
+            _namemax = (ulong)_random.Next(0, int.MaxValue);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var target = new StatVfsReplyInfo();
+
+            Assert.IsNull(target.Information);
+        }
+
+        [TestMethod]
+        public void Load()
+        {
+            var target = new StatVfsReplyInfo();
+
+#if TUNING
+            var sshDataStream = new SshDataStream(4 + 1 + 4 + 88);
+            sshDataStream.Write((uint) (sshDataStream.Capacity - 4));
+#else
+            var sshDataStream = new SshDataStream(1 + 4 + 88);
+#endif
+            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((ulong) 0x1);
+            sshDataStream.Write(_namemax);
+
+            target.Load(sshDataStream.ToArray());
+
+            Assert.IsNotNull(target.Information);
+
+            var information = target.Information;
+            Assert.AreEqual(_bavail, information.AvailableBlocks);
+            Assert.AreEqual(_favail, information.AvailableNodes);
+            Assert.AreEqual(_frsize, information.BlockSize);
+            Assert.AreEqual(_bsize, information.FileSystemBlockSize);
+            Assert.AreEqual(_bfree, information.FreeBlocks);
+            Assert.AreEqual(_ffree, information.FreeNodes);
+            Assert.IsTrue(information.IsReadOnly);
+            Assert.AreEqual(_namemax, information.MaxNameLenght);
+            Assert.AreEqual(_sid, information.Sid);
+            Assert.IsTrue(information.SupportsSetUid);
+            Assert.AreEqual(_blocks, information.TotalBlocks);
+            Assert.AreEqual(_files, information.TotalNodes);
+        }
     }
 }

+ 70 - 3
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Responses/SftpAttrsResponseTest.cs

@@ -1,10 +1,77 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Responses;
 using Renci.SshNet.Tests.Common;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Responses
 {
     [TestClass]
-    public class SftpAttrsResponseTest : TestBase
+    public class SftpAttrsResponseTest
     {
+        private Random _random;
+        private uint _protocolVersion;
+        private uint _responseId;
+
+        [TestInitialize]
+        public void Init()
+        {
+            _random = new Random();
+            _protocolVersion = (uint) _random.Next(0, int.MaxValue);
+            _responseId = (uint)_random.Next(0, int.MaxValue);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var target = new SftpAttrsResponse(_protocolVersion);
+
+            Assert.IsNull(target.Attributes);
+            Assert.AreEqual(_protocolVersion, target.ProtocolVersion);
+            Assert.AreEqual((uint) 0, target.ResponseId);
+            Assert.AreEqual(SftpMessageTypes.Attrs, target.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Load()
+        {
+            var target = new SftpAttrsResponse(_protocolVersion);
+            var attributes = CreateSftpFileAttributes();
+            var attributesBytes = attributes.GetBytes();
+
+#if TUNING
+            var sshDataStream = new SshDataStream(4 + 1 + 4 + attributesBytes.Length);
+            sshDataStream.Position = 4; // skip 4 bytes for SSH packet length
+#else
+            var sshDataStream = new SshDataStream(1 + 4 + attributesBytes.Length);
+#endif
+            sshDataStream.WriteByte((byte)SftpMessageTypes.Attrs);
+            sshDataStream.Write(_responseId);
+            sshDataStream.Write(attributesBytes, 0, attributesBytes.Length);
+
+            target.Load(sshDataStream.ToArray());
+
+            Assert.IsNotNull(target.Attributes);
+            Assert.AreEqual(_protocolVersion, target.ProtocolVersion);
+            Assert.AreEqual(_responseId, target.ResponseId);
+            Assert.AreEqual(SftpMessageTypes.Attrs, target.SftpMessageType);
+
+            // check attributes in detail
+            Assert.AreEqual(attributes.GroupId, target.Attributes.GroupId);
+            Assert.AreEqual(attributes.LastWriteTime, target.Attributes.LastWriteTime);
+            Assert.AreEqual(attributes.LastWriteTime, target.Attributes.LastWriteTime);
+            Assert.AreEqual(attributes.UserId, target.Attributes.UserId);
+        }
+
+        private SftpFileAttributes CreateSftpFileAttributes()
+        {
+            var attributes = SftpFileAttributes.Empty;
+            attributes.GroupId = _random.Next();
+            attributes.LastAccessTime = new DateTime(2014, 8, 23, 17, 43, 50, DateTimeKind.Local);
+            attributes.LastWriteTime = new DateTime(2013, 7, 22, 16, 40, 42, DateTimeKind.Local);
+            attributes.UserId = _random.Next();
+            return attributes;
+        }
     }
-}
+}

+ 58 - 4
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Responses/SftpDataResponseTest.cs

@@ -1,10 +1,64 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Responses
 {
     [TestClass]
-    public class SftpDataResponseTest : TestBase
+    public class SftpDataResponseTest
     {
+        private Random _random;
+        private uint _protocolVersion;
+        private uint _responseId;
+        private byte[] _data;
+
+        [TestInitialize]
+        public void Init()
+        {
+            _random = new Random();
+            _protocolVersion = (uint) _random.Next(0, int.MaxValue);
+            _responseId = (uint) _random.Next(0, int.MaxValue);
+            _data = new byte[_random.Next(10, 100)];
+            _random.NextBytes(_data);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var target = new SftpDataResponse(_protocolVersion);
+
+            Assert.IsNull(target.Data);
+            Assert.AreEqual(_protocolVersion, target.ProtocolVersion);
+            Assert.AreEqual((uint) 0, target.ResponseId);
+            Assert.AreEqual(SftpMessageTypes.Data, target.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Load()
+        {
+            var target = new SftpDataResponse(_protocolVersion);
+
+#if TUNING
+            var sshDataStream = new SshDataStream(4 + 1 + 4 + _data.Length);
+            sshDataStream.Position = 4; // skip 4 bytes for SSH packet length
+#else
+            var sshDataStream = new SshDataStream(1 + 4 + _data.Length);
+#endif
+            sshDataStream.WriteByte((byte)SftpMessageTypes.Attrs);
+            sshDataStream.Write(_responseId);
+            sshDataStream.Write((uint) _data.Length);
+            sshDataStream.Write(_data, 0, _data.Length);
+
+            target.Load(sshDataStream.ToArray());
+
+            Assert.IsNotNull(target.Data);
+            Assert.IsTrue(target.Data.SequenceEqual(_data));
+            Assert.AreEqual(_protocolVersion, target.ProtocolVersion);
+            Assert.AreEqual(_responseId, target.ResponseId);
+            Assert.AreEqual(SftpMessageTypes.Data, target.SftpMessageType);
+        }
     }
-}
+}

+ 104 - 3
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Responses/SftpExtendedReplyResponseTest.cs

@@ -1,10 +1,111 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Responses
 {
     [TestClass]
-    public class SftpExtendedReplyResponseTest : TestBase
+    public class SftpExtendedReplyResponseTest
     {
+        private Random _random;
+        private uint _protocolVersion;
+        private uint _responseId;
+
+        [TestInitialize]
+        public void Init()
+        {
+            _random = new Random();
+            _protocolVersion = (uint) _random.Next(0, int.MaxValue);
+            _responseId = (uint) _random.Next(0, int.MaxValue);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var target = new SftpExtendedReplyResponse(_protocolVersion);
+
+            Assert.AreEqual(_protocolVersion, target.ProtocolVersion);
+            Assert.AreEqual((uint) 0, target.ResponseId);
+            Assert.AreEqual(SftpMessageTypes.ExtendedReply, target.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Load()
+        {
+            var target = new SftpExtendedReplyResponse(_protocolVersion);
+
+#if TUNING
+            var sshDataStream = new SshDataStream(4 + 1 + 4);
+            sshDataStream.Position = 4; // skip 4 bytes for SSH packet length
+#else
+            var sshDataStream = new SshDataStream(1 + 4);
+#endif
+            sshDataStream.WriteByte((byte) SftpMessageTypes.ExtendedReply);
+            sshDataStream.Write(_responseId);
+
+            target.Load(sshDataStream.ToArray());
+
+            Assert.AreEqual(_protocolVersion, target.ProtocolVersion);
+            Assert.AreEqual(_responseId, target.ResponseId);
+            Assert.AreEqual(SftpMessageTypes.ExtendedReply, target.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void GetReply_StatVfsReplyInfo()
+        {
+            var bsize = (ulong) _random.Next(0, int.MaxValue);
+            var frsize = (ulong) _random.Next(0, int.MaxValue);
+            var blocks = (ulong) _random.Next(0, int.MaxValue);
+            var bfree = (ulong) _random.Next(0, int.MaxValue);
+            var bavail = (ulong) _random.Next(0, int.MaxValue);
+            var files = (ulong) _random.Next(0, int.MaxValue);
+            var ffree = (ulong) _random.Next(0, int.MaxValue);
+            var favail = (ulong) _random.Next(0, int.MaxValue);
+            var sid = (ulong) _random.Next(0, int.MaxValue);
+            var namemax = (ulong) _random.Next(0, int.MaxValue);
+
+#if TUNING
+            var sshDataStream = new SshDataStream(4 + 1 + 4 + 88);
+            sshDataStream.Position = 4; // skip 4 bytes for SSH packet length
+#else
+            var sshDataStream = new SshDataStream(1 + 4 + 88);
+#endif
+            sshDataStream.WriteByte((byte) SftpMessageTypes.Attrs);
+            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((ulong) 0x2);
+            sshDataStream.Write(namemax);
+
+            var target = new SftpExtendedReplyResponse(_protocolVersion);
+            target.Load(sshDataStream.ToArray());
+
+            var reply = target.GetReply<StatVfsReplyInfo>();
+            Assert.IsNotNull(reply);
+
+            var information = reply.Information;
+            Assert.IsNotNull(information);
+            Assert.AreEqual(bavail, information.AvailableBlocks);
+            Assert.AreEqual(favail, information.AvailableNodes);
+            Assert.AreEqual(frsize, information.BlockSize);
+            Assert.AreEqual(bsize, information.FileSystemBlockSize);
+            Assert.AreEqual(bfree, information.FreeBlocks);
+            Assert.AreEqual(ffree, information.FreeNodes);
+            Assert.IsFalse(information.IsReadOnly);
+            Assert.AreEqual(namemax, information.MaxNameLenght);
+            Assert.AreEqual(sid, information.Sid);
+            Assert.IsFalse(information.SupportsSetUid);
+            Assert.AreEqual(blocks, information.TotalBlocks);
+            Assert.AreEqual(files, information.TotalNodes);
+        }
     }
 }

+ 58 - 4
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/Responses/SftpHandleResponseTest.cs

@@ -1,10 +1,64 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
+using System;
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp.Responses
 {
     [TestClass]
-    public class SftpHandleResponseTest : TestBase
+    public class SftpHandleResponseTest
     {
+        private Random _random;
+        private uint _protocolVersion;
+        private uint _responseId;
+        private byte[] _handle;
+
+        [TestInitialize]
+        public void Init()
+        {
+            _random = new Random();
+            _protocolVersion = (uint) _random.Next(0, int.MaxValue);
+            _responseId = (uint) _random.Next(0, int.MaxValue);
+            _handle = new byte[_random.Next(1, 10)];
+            _random.NextBytes(_handle);
+        }
+
+        [TestMethod]
+        public void Constructor()
+        {
+            var target = new SftpHandleResponse(_protocolVersion);
+
+            Assert.IsNull(target.Handle);
+            Assert.AreEqual(_protocolVersion, target.ProtocolVersion);
+            Assert.AreEqual((uint) 0, target.ResponseId);
+            Assert.AreEqual(SftpMessageTypes.Handle, target.SftpMessageType);
+        }
+
+        [TestMethod]
+        public void Load()
+        {
+            var target = new SftpHandleResponse(_protocolVersion);
+
+#if TUNING
+            var sshDataStream = new SshDataStream(4 + 1 + 4 + _handle.Length);
+            sshDataStream.Position = 4; // skip 4 bytes for SSH packet length
+#else
+            var sshDataStream = new SshDataStream(1 + 4 + _handle.Length);
+#endif
+            sshDataStream.WriteByte((byte) SftpMessageTypes.Handle);
+            sshDataStream.Write(_responseId);
+            sshDataStream.Write((uint) _handle.Length);
+            sshDataStream.Write(_handle, 0, _handle.Length);
+
+            target.Load(sshDataStream.ToArray());
+
+            Assert.IsNotNull(target.Handle);
+            Assert.IsTrue(target.Handle.SequenceEqual(_handle));
+            Assert.AreEqual(_protocolVersion, target.ProtocolVersion);
+            Assert.AreEqual(_responseId, target.ResponseId);
+            Assert.AreEqual(SftpMessageTypes.Handle, target.SftpMessageType);
+        }
     }
-}
+}

+ 0 - 10
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpDataMessageTest.cs

@@ -1,10 +0,0 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
-
-namespace Renci.SshNet.Tests.Classes.Sftp
-{
-    [TestClass]
-    public class SftpDataMessageTest : TestBase
-    {
-    }
-}

+ 15 - 15
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileAttributesTest.cs

@@ -18,7 +18,7 @@ namespace Renci.SshNet.Tests
         [TestMethod()]
         public void SetPermissionsTest()
         {
-            SftpFileAttributes target = new SftpFileAttributes(); // TODO: Initialize to an appropriate value
+            SftpFileAttributes target = SftpFileAttributes.Empty; // TODO: Initialize to an appropriate value
             short mode = 0; // TODO: Initialize to an appropriate value
             target.SetPermissions(mode);
             Assert.Inconclusive("A method that does not return a value cannot be verified.");
@@ -30,7 +30,7 @@ namespace Renci.SshNet.Tests
         [TestMethod()]
         public void GroupCanExecuteTest()
         {
-            SftpFileAttributes target = new SftpFileAttributes(); // TODO: Initialize to an appropriate value
+            SftpFileAttributes target = SftpFileAttributes.Empty; // TODO: Initialize to an appropriate value
             bool expected = false; // TODO: Initialize to an appropriate value
             bool actual;
             target.GroupCanExecute = expected;
@@ -45,7 +45,7 @@ namespace Renci.SshNet.Tests
         [TestMethod()]
         public void GroupCanReadTest()
         {
-            SftpFileAttributes target = new SftpFileAttributes(); // TODO: Initialize to an appropriate value
+            SftpFileAttributes target = SftpFileAttributes.Empty; // TODO: Initialize to an appropriate value
             bool expected = false; // TODO: Initialize to an appropriate value
             bool actual;
             target.GroupCanRead = expected;
@@ -60,7 +60,7 @@ namespace Renci.SshNet.Tests
         [TestMethod()]
         public void GroupCanWriteTest()
         {
-            SftpFileAttributes target = new SftpFileAttributes(); // TODO: Initialize to an appropriate value
+            SftpFileAttributes target = SftpFileAttributes.Empty; // TODO: Initialize to an appropriate value
             bool expected = false; // TODO: Initialize to an appropriate value
             bool actual;
             target.GroupCanWrite = expected;
@@ -75,7 +75,7 @@ namespace Renci.SshNet.Tests
         [TestMethod()]
         public void GroupIdTest()
         {
-            SftpFileAttributes target = new SftpFileAttributes(); // TODO: Initialize to an appropriate value
+            SftpFileAttributes target = SftpFileAttributes.Empty; // TODO: Initialize to an appropriate value
             int expected = 0; // TODO: Initialize to an appropriate value
             int actual;
             target.GroupId = expected;
@@ -90,7 +90,7 @@ namespace Renci.SshNet.Tests
         [TestMethod()]
         public void LastAccessTimeTest()
         {
-            SftpFileAttributes target = new SftpFileAttributes(); // TODO: Initialize to an appropriate value
+            SftpFileAttributes target = SftpFileAttributes.Empty; // TODO: Initialize to an appropriate value
             DateTime expected = new DateTime(); // TODO: Initialize to an appropriate value
             DateTime actual;
             target.LastAccessTime = expected;
@@ -105,7 +105,7 @@ namespace Renci.SshNet.Tests
         [TestMethod()]
         public void LastWriteTimeTest()
         {
-            SftpFileAttributes target = new SftpFileAttributes(); // TODO: Initialize to an appropriate value
+            SftpFileAttributes target = SftpFileAttributes.Empty; // TODO: Initialize to an appropriate value
             DateTime expected = new DateTime(); // TODO: Initialize to an appropriate value
             DateTime actual;
             target.LastWriteTime = expected;
@@ -120,7 +120,7 @@ namespace Renci.SshNet.Tests
         [TestMethod()]
         public void OthersCanExecuteTest()
         {
-            SftpFileAttributes target = new SftpFileAttributes(); // TODO: Initialize to an appropriate value
+            SftpFileAttributes target = SftpFileAttributes.Empty; // TODO: Initialize to an appropriate value
             bool expected = false; // TODO: Initialize to an appropriate value
             bool actual;
             target.OthersCanExecute = expected;
@@ -135,7 +135,7 @@ namespace Renci.SshNet.Tests
         [TestMethod()]
         public void OthersCanReadTest()
         {
-            SftpFileAttributes target = new SftpFileAttributes(); // TODO: Initialize to an appropriate value
+            SftpFileAttributes target = SftpFileAttributes.Empty; // TODO: Initialize to an appropriate value
             bool expected = false; // TODO: Initialize to an appropriate value
             bool actual;
             target.OthersCanRead = expected;
@@ -150,7 +150,7 @@ namespace Renci.SshNet.Tests
         [TestMethod()]
         public void OthersCanWriteTest()
         {
-            SftpFileAttributes target = new SftpFileAttributes(); // TODO: Initialize to an appropriate value
+            SftpFileAttributes target = SftpFileAttributes.Empty; // TODO: Initialize to an appropriate value
             bool expected = false; // TODO: Initialize to an appropriate value
             bool actual;
             target.OthersCanWrite = expected;
@@ -165,7 +165,7 @@ namespace Renci.SshNet.Tests
         [TestMethod()]
         public void OwnerCanExecuteTest()
         {
-            SftpFileAttributes target = new SftpFileAttributes(); // TODO: Initialize to an appropriate value
+            SftpFileAttributes target = SftpFileAttributes.Empty; // TODO: Initialize to an appropriate value
             bool expected = false; // TODO: Initialize to an appropriate value
             bool actual;
             target.OwnerCanExecute = expected;
@@ -180,7 +180,7 @@ namespace Renci.SshNet.Tests
         [TestMethod()]
         public void OwnerCanReadTest()
         {
-            SftpFileAttributes target = new SftpFileAttributes(); // TODO: Initialize to an appropriate value
+            SftpFileAttributes target = SftpFileAttributes.Empty; // TODO: Initialize to an appropriate value
             bool expected = false; // TODO: Initialize to an appropriate value
             bool actual;
             target.OwnerCanRead = expected;
@@ -195,7 +195,7 @@ namespace Renci.SshNet.Tests
         [TestMethod()]
         public void OwnerCanWriteTest()
         {
-            SftpFileAttributes target = new SftpFileAttributes(); // TODO: Initialize to an appropriate value
+            SftpFileAttributes target = SftpFileAttributes.Empty; // TODO: Initialize to an appropriate value
             bool expected = false; // TODO: Initialize to an appropriate value
             bool actual;
             target.OwnerCanWrite = expected;
@@ -210,7 +210,7 @@ namespace Renci.SshNet.Tests
         [TestMethod()]
         public void SizeTest()
         {
-            SftpFileAttributes target = new SftpFileAttributes(); // TODO: Initialize to an appropriate value
+            SftpFileAttributes target = SftpFileAttributes.Empty; // TODO: Initialize to an appropriate value
             long expected = 0; // TODO: Initialize to an appropriate value
             long actual;
             target.Size = expected;
@@ -225,7 +225,7 @@ namespace Renci.SshNet.Tests
         [TestMethod()]
         public void UserIdTest()
         {
-            SftpFileAttributes target = new SftpFileAttributes(); // TODO: Initialize to an appropriate value
+            SftpFileAttributes target = SftpFileAttributes.Empty; // TODO: Initialize to an appropriate value
             int expected = 0; // TODO: Initialize to an appropriate value
             int actual;
             target.UserId = expected;

+ 5 - 5
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Closed_FileAccessRead.cs

@@ -31,11 +31,11 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         {
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
-            _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
-            _bufferSize = (uint)random.Next(0, 1000);
-            _readBufferSize = (uint)random.Next(0, 1000);
-            _writeBufferSize = (uint)random.Next(0, 1000);
+            _handle = new[] {(byte) random.Next(byte.MinValue, byte.MaxValue)};
+            _fileAttributes = SftpFileAttributes.Empty;
+            _bufferSize = (uint) random.Next(0, 1000);
+            _readBufferSize = (uint) random.Next(0, 1000);
+            _writeBufferSize = (uint) random.Next(0, 1000);
 
             _sftpSessionMock = new Mock<ISftpSession>(MockBehavior.Strict);
 

+ 5 - 5
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Closed_FileAccessReadWrite.cs

@@ -31,11 +31,11 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         {
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
-            _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
-            _bufferSize = (uint)random.Next(0, 1000);
-            _readBufferSize = (uint)random.Next(0, 1000);
-            _writeBufferSize = (uint)random.Next(0, 1000);
+            _handle = new[] {(byte) random.Next(byte.MinValue, byte.MaxValue)};
+            _fileAttributes = SftpFileAttributes.Empty;
+            _bufferSize = (uint) random.Next(0, 1000);
+            _readBufferSize = (uint) random.Next(0, 1000);
+            _writeBufferSize = (uint) random.Next(0, 1000);
 
             _sftpSessionMock = new Mock<ISftpSession>(MockBehavior.Strict);
 

+ 5 - 5
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Closed_FileAccessWrite.cs

@@ -31,11 +31,11 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         {
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
-            _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
-            _bufferSize = (uint)random.Next(0, 1000);
-            _readBufferSize = (uint)random.Next(0, 1000);
-            _writeBufferSize = (uint)random.Next(0, 1000);
+            _handle = new[] {(byte) random.Next(byte.MinValue, byte.MaxValue)};
+            _fileAttributes = SftpFileAttributes.Empty;
+            _bufferSize = (uint) random.Next(0, 1000);
+            _readBufferSize = (uint) random.Next(0, 1000);
+            _writeBufferSize = (uint) random.Next(0, 1000);
 
             _sftpSessionMock = new Mock<ISftpSession>(MockBehavior.Strict);
 

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Disposed_FileAccessRead.cs

@@ -32,7 +32,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Disposed_FileAccessReadWrite.cs

@@ -32,7 +32,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Disposed_FileAccessWrite.cs

@@ -32,7 +32,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_SessionOpen_FileAccessRead.cs

@@ -32,7 +32,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_SessionOpen_FileAccessReadWrite.cs

@@ -32,7 +32,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_SessionOpen_FileAccessWrite.cs

@@ -32,7 +32,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Closed_FileAccessRead.cs

@@ -32,7 +32,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 2 - 2
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Closed_FileAccessReadWrite.cs

@@ -31,8 +31,8 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         {
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
-            _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
+            _handle = new[] {(byte) random.Next(byte.MinValue, byte.MaxValue)};
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Closed_FileAccessWrite.cs

@@ -32,7 +32,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Disposed_FileAccessRead.cs

@@ -32,7 +32,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Disposed_FileAccessReadWrite.cs

@@ -32,7 +32,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Disposed_FileAccessWrite.cs

@@ -32,7 +32,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 2 - 2
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_SessionOpen_FileAccessRead.cs

@@ -31,8 +31,8 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         {
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
-            _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
+            _handle = new[] {(byte) random.Next(byte.MinValue, byte.MaxValue)};
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 2 - 2
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_SessionOpen_FileAccessReadWrite.cs

@@ -31,8 +31,8 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         {
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
-            _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
+            _handle = new[] {(byte) random.Next(byte.MinValue, byte.MaxValue)};
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_SessionOpen_FileAccessWrite.cs

@@ -32,7 +32,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Close_Closed.cs

@@ -31,7 +31,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(1, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Close_Disposed.cs

@@ -31,7 +31,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(1, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Close_SessionNotOpen.cs

@@ -31,7 +31,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(1, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Close_SessionOpen.cs

@@ -31,7 +31,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] {(byte) random.Next(byte.MinValue, byte.MaxValue)};
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint) random.Next(1, 1000);
             _readBufferSize = (uint) random.Next(0, 1000);
             _writeBufferSize = (uint) random.Next(0, 1000);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Dispose_Closed.cs

@@ -31,7 +31,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] {(byte) random.Next(byte.MinValue, byte.MaxValue)};
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint) random.Next(1, 1000);
             _readBufferSize = (uint) random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Dispose_Disposed.cs

@@ -31,7 +31,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] {(byte) random.Next(byte.MinValue, byte.MaxValue)};
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint) random.Next(1, 1000);
             _readBufferSize = (uint) random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Dispose_SessionNotOpen.cs

@@ -31,7 +31,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(1, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Dispose_SessionOpen.cs

@@ -31,7 +31,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] {(byte) random.Next(byte.MinValue, byte.MaxValue)};
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint) random.Next(1, 1000);
             _readBufferSize = (uint) random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Finalize_SessionOpen.cs

@@ -31,7 +31,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] {(byte) random.Next(byte.MinValue, byte.MaxValue)};
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint) random.Next(1, 1000);
             _readBufferSize = (uint) random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_Closed.cs

@@ -32,7 +32,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(1, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_Disposed.cs

@@ -32,7 +32,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(1, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);

+ 4 - 4
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_SessionNotOpen.cs

@@ -34,10 +34,10 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
-            _bufferSize = (uint)random.Next(1, 1000);
-            _readBufferSize = (uint)random.Next(0, 1000);
-            _writeBufferSize = (uint)random.Next(0, 1000);
+            _fileAttributes = SftpFileAttributes.Empty;
+            _bufferSize = (uint) random.Next(1, 1000);
+            _readBufferSize = (uint) random.Next(0, 1000);
+            _writeBufferSize = (uint) random.Next(0, 1000);
             _length = random.Next();
 
             _sftpSessionMock = new Mock<ISftpSession>(MockBehavior.Strict);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_SessionOpen_FIleAccessRead.cs

@@ -34,7 +34,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] {(byte) random.Next(byte.MinValue, byte.MaxValue)};
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint) random.Next(1, 1000);
             _readBufferSize = (uint) random.Next(0, 1000);
             _writeBufferSize = (uint) random.Next(0, 1000);

+ 5 - 5
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_SessionOpen_FIleAccessReadWrite.cs

@@ -33,11 +33,11 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         {
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
-            _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
-            _fileAttributes = new SftpFileAttributes();
-            _bufferSize = (uint)random.Next(1, 1000);
-            _readBufferSize = (uint)random.Next(0, 1000);
-            _writeBufferSize = (uint)random.Next(0, 1000);
+            _handle = new[] {(byte) random.Next(byte.MinValue, byte.MaxValue)};
+            _fileAttributes = SftpFileAttributes.Empty;
+            _bufferSize = (uint) random.Next(1, 1000);
+            _readBufferSize = (uint) random.Next(0, 1000);
+            _writeBufferSize = (uint) random.Next(0, 1000);
             _length = random.Next();
 
             _sftpSessionMock = new Mock<ISftpSession>(MockBehavior.Strict);

+ 1 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_SessionOpen_FIleAccessWrite.cs

@@ -34,7 +34,7 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             var random = new Random();
             _path = random.Next().ToString(CultureInfo.InvariantCulture);
             _handle = new[] {(byte) random.Next(byte.MinValue, byte.MaxValue)};
-            _fileAttributes = new SftpFileAttributes();
+            _fileAttributes = SftpFileAttributes.Empty;
             _bufferSize = (uint) random.Next(1, 1000);
             _readBufferSize = (uint) random.Next(0, 1000);
             _writeBufferSize = (uint) random.Next(0, 1000);

+ 0 - 10
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest.cs

@@ -1,10 +0,0 @@
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using Renci.SshNet.Tests.Common;
-
-namespace Renci.SshNet.Tests.Classes.Sftp
-{
-    [TestClass]
-    public class SftpSessionTest : TestBase
-    {
-    }
-}

+ 140 - 0
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestRead.cs

@@ -0,0 +1,140 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+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_RequestRead
+    {
+        private Mock<ISession> _sessionMock;
+        private Mock<IChannelSession> _channelSessionMock;
+        private SftpSession _sftpSession;
+        private TimeSpan _operationTimeout;
+        private byte[] _actual;
+        private byte[] _expected;
+        private Encoding _encoding;
+
+        [TestInitialize]
+        public void Setup()
+        {
+            Arrange();
+            Act();
+        }
+
+        protected void Arrange()
+        {
+            var random = new Random();
+
+            _operationTimeout = TimeSpan.FromMilliseconds(random.Next(100, 500));
+            _expected = new byte[random.Next(30, 50)];
+            _encoding = Encoding.UTF8;
+            random.NextBytes(_expected);
+
+            _sessionMock = new Mock<ISession>(MockBehavior.Strict);
+            _channelSessionMock = new Mock<IChannelSession>(MockBehavior.Strict);
+
+            var sequence = new MockSequence();
+
+            _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.IsOpen).Returns(true);
+            _channelSessionMock.InSequence(sequence).Setup(p => p.SendData(It.IsAny<byte[]>())).Callback(
+                () =>
+                    {
+                        var sftpNameResponse = CreateSftpNameResponse(1, _encoding, "ABC");
+
+                        _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(
+                () =>
+                    {
+                        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)));
+                    }
+                );
+
+            _sftpSession = new SftpSession(_sessionMock.Object, _operationTimeout, _encoding);
+            _sftpSession.Connect();
+        }
+
+        protected void Act()
+        {
+            _actual = _sftpSession.RequestRead(new byte[0], 0, 200);
+        }
+
+        [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((((uint) nameBytes.Length).GetBytes())); // filename length
+                namesAndAttributes.AddRange(nameBytes); // filename
+                namesAndAttributes.AddRange(((uint) 0).GetBytes()); // 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();
+        }
+    }
+}

+ 257 - 0
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestStatVfs.cs

@@ -0,0 +1,257 @@
+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;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpSessionTest_Connected_RequestStatVfs
+    {
+        private Mock<ISession> _sessionMock;
+        private Mock<IChannelSession> _channelSessionMock;
+        private SftpSession _sftpSession;
+        private TimeSpan _operationTimeout;
+        private SftpFileSytemInformation _actual;
+        private Encoding _encoding;
+
+        private ulong _bAvail;
+
+        [TestInitialize]
+        public void Setup()
+        {
+            Arrange();
+            Act();
+        }
+
+        protected void Arrange()
+        {
+            var random = new Random();
+
+            _operationTimeout = TimeSpan.FromMilliseconds(random.Next(100, 500));
+            _encoding = Encoding.UTF8;
+
+            _bAvail = (ulong) random.Next(0, int.MaxValue);
+
+            _sessionMock = new Mock<ISession>(MockBehavior.Strict);
+            _channelSessionMock = new Mock<IChannelSession>(MockBehavior.Strict);
+
+            var sequence = new MockSequence();
+
+            _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)
+                                                                            .AddExtension("statvfs@openssh.com", "")
+                                                                            .Build();
+                        _channelSessionMock.Raise(
+                            c => c.DataReceived += null,
+                            new ChannelDataEventArgs(0, versionInfoResponse));
+                    });
+            _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.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(
+                () =>
+                    {
+                        var statVfsReplyBuilder = StatVfsReplyBuilder.Create(2);
+                        statVfsReplyBuilder.WithBAvail(_bAvail);
+                        var statVfsReply = statVfsReplyBuilder.Build();
+
+                        _channelSessionMock.Raise(
+                            c => c.DataReceived += null,
+                            new ChannelDataEventArgs(0, statVfsReply));
+                    }
+                );
+
+            _sftpSession = new SftpSession(_sessionMock.Object, _operationTimeout, _encoding);
+            _sftpSession.Connect();
+        }
+
+        protected void Act()
+        {
+            _actual = _sftpSession.RequestStatVfs("path");
+        }
+
+        [TestMethod]
+        public void ReturnedValueShouldNotBeNull()
+        {
+            Assert.IsNotNull(_actual);
+        }
+
+        [TestMethod]
+        public void AvailableBlocksInReturnedValueShouldMatchValueInSftpResponse()
+        {
+            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((((uint) nameBytes.Length).GetBytes())); // filename length
+                namesAndAttributes.AddRange(nameBytes); // filename
+                namesAndAttributes.AddRange(((uint) 0).GetBytes()); // 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();
+            }
+        }
+    }
+}

+ 53 - 0
Renci.SshClient/Renci.SshNet.Tests/Classes/Sftp/SftpVersionResponseBuilder.cs

@@ -0,0 +1,53 @@
+using System.Collections.Generic;
+using System.Text;
+using Renci.SshNet.Common;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    public class SftpVersionResponseBuilder
+    {
+        private readonly uint _version;
+        private readonly IDictionary<string, string> _extensions;
+
+        private SftpVersionResponseBuilder(uint version)
+        {
+            _version = version;
+            _extensions = new Dictionary<string, string>();
+        }
+
+        public static SftpVersionResponseBuilder Create(uint version)
+        {
+            return new SftpVersionResponseBuilder(version);
+        }
+
+        public SftpVersionResponseBuilder AddExtension(string name, string data)
+        {
+            _extensions.Add(name, data);
+            return this;
+        }
+
+        public byte[] 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();
+        }
+    }
+}

+ 2 - 2
Renci.SshClient/Renci.SshNet.Tests/Classes/SubsystemSessionStub.cs

@@ -34,9 +34,9 @@ namespace Renci.SshNet.Tests.Classes
                 throw OnChannelOpenException;
         }
 
-        protected override void OnDataReceived(uint dataTypeCode, byte[] data)
+        protected override void OnDataReceived(byte[] data)
         {
-            OnDataReceivedInvocations.Add(new ChannelDataEventArgs(0, data, dataTypeCode));
+            OnDataReceivedInvocations.Add(new ChannelDataEventArgs(0, data));
 
             if (OnDataReceivedException != null)
                 throw OnDataReceivedException;

+ 0 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_Connected.cs

@@ -84,7 +84,6 @@ namespace Renci.SshNet.Tests.Classes
 
             var received = _subsystemSession.OnDataReceivedInvocations[0];
             Assert.AreEqual(_channelDataEventArgs.Data, received.Data);
-            Assert.AreEqual(_channelDataEventArgs.DataTypeCode, received.DataTypeCode);
         }
 
         [TestMethod]

+ 0 - 1
Renci.SshClient/Renci.SshNet.Tests/Classes/SubsystemSession_OnChannelDataReceived_OnDataReceived_Exception.cs

@@ -87,7 +87,6 @@ namespace Renci.SshNet.Tests.Classes
 
             var received = _subsystemSession.OnDataReceivedInvocations[0];
             Assert.AreEqual(_channelDataEventArgs.Data, received.Data);
-            Assert.AreEqual(_channelDataEventArgs.DataTypeCode, received.DataTypeCode);
         }
     }
 }

+ 4 - 4
Renci.SshClient/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj

@@ -24,7 +24,7 @@
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
     <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DefineConstants>TRACE;DEBUG;TUNING</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
@@ -355,7 +355,6 @@
     <Compile Include="Classes\Sftp\Responses\SftpNameResponseTest.cs" />
     <Compile Include="Classes\Sftp\Responses\SftpStatusResponseTest.cs" />
     <Compile Include="Classes\Sftp\Responses\SftpVersionResponseTest.cs" />
-    <Compile Include="Classes\Sftp\SftpDataMessageTest.cs" />
     <Compile Include="Classes\Sftp\SftpFileStreamTest_Dispose_Disposed.cs" />
     <Compile Include="Classes\Sftp\SftpFileStreamTest_Finalize_SessionOpen.cs" />
     <Compile Include="Classes\Sftp\SftpFileStreamTest_SetLength_Closed.cs" />
@@ -365,7 +364,9 @@
     <Compile Include="Classes\Sftp\SftpFileStreamTest_SetLength_SessionOpen_FIleAccessReadWrite.cs" />
     <Compile Include="Classes\Sftp\SftpFileStreamTest_SetLength_SessionOpen_FIleAccessWrite.cs" />
     <Compile Include="Classes\Sftp\SftpFileTest.cs" />
-    <Compile Include="Classes\Sftp\SftpSessionTest.cs" />
+    <Compile Include="Classes\Sftp\SftpSessionTest_Connected_RequestRead.cs" />
+    <Compile Include="Classes\Sftp\SftpSessionTest_Connected_RequestStatVfs.cs" />
+    <Compile Include="Classes\Sftp\SftpVersionResponseBuilder.cs" />
     <Compile Include="Classes\ShellTestTest.cs" />
     <Compile Include="Classes\ShellStreamTest.cs" />
     <Compile Include="Classes\SshClientTest.cs" />
@@ -467,7 +468,6 @@
     <Compile Include="Classes\Messages\Connection\RequestFailureMessageTest.cs" />
     <Compile Include="Classes\Messages\Connection\RequestInfoTest.cs" />
     <Compile Include="Classes\Messages\Authentication\RequestMessagePublicKeyTest.cs" />
-    <Compile Include="Classes\Messages\Authentication\RequestMessageTest.cs" />
     <Compile Include="Classes\Messages\Connection\RequestSuccessMessageTest.cs" />
     <Compile Include="Classes\Messages\Transport\ServiceAcceptMessageTest.cs" />
     <Compile Include="Classes\Messages\Transport\ServiceRequestMessageTest.cs" />

+ 51 - 2
Renci.SshClient/Renci.SshNet/Channels/Channel.cs

@@ -221,7 +221,7 @@ namespace Renci.SshNet.Channels
         /// <summary>
         /// Occurs when <see cref="ChannelExtendedDataMessage"/> message received
         /// </summary>
-        public event EventHandler<ChannelDataEventArgs> ExtendedDataReceived;
+        public event EventHandler<ChannelExtendedDataEventArgs> ExtendedDataReceived;
 
         /// <summary>
         /// Occurs when <see cref="ChannelEofMessage"/> message received
@@ -292,9 +292,56 @@ namespace Renci.SshNet.Channels
         /// <param name="data">The payload to send.</param>
         public void SendData(byte[] data)
         {
+#if TUNING
+            SendData(data, 0, data.Length);
+#else
             SendMessage(new ChannelDataMessage(RemoteChannelNumber, data));
+#endif
         }
 
+#if TUNING
+        /// <summary>
+        /// Sends a SSH_MSG_CHANNEL_DATA message with the specified payload.
+        /// </summary>
+        /// <param name="data">An array of <see cref="byte"/> containing the payload to send.</param>
+        /// <param name="offset">The zero-based offset in <paramref name="data"/> at which to begin taking data from.</param>
+        /// <param name="size">The number of bytes of <paramref name="data"/> to send.</param>
+        /// <remarks>
+        /// <para>
+        /// When the size of the data to send exceeds the maximum packet size or the remote window
+        /// size does not allow the full data to be sent, then this method will send the data in
+        /// multiple chunks and will wait for the remote window size to be adjusted when it's zero.
+        /// </para>
+        /// <para>
+        /// This is done to support SSH servers will a small window size that do not agressively
+        /// increase their window size. We need to take into account that there may be SSH servers
+        /// that only increase their window size when it has reached zero.
+        /// </para>
+        /// </remarks>
+        public void SendData(byte[] data, int offset, int size)
+        {
+            // send channel messages only while channel is open
+            if (!IsOpen)
+                return;
+
+            var totalBytesToSend = size;
+            while (totalBytesToSend > 0)
+            {
+                var sizeOfCurrentMessage = GetDataLengthThatCanBeSentInMessage(totalBytesToSend);
+
+                var channelDataMessage = new ChannelDataMessage(
+                    RemoteChannelNumber,
+                    data,
+                    offset,
+                    sizeOfCurrentMessage);
+                _session.SendMessage(channelDataMessage);
+
+                totalBytesToSend -= sizeOfCurrentMessage;
+                offset += sizeOfCurrentMessage;
+            }
+        }
+#endif
+
         /// <summary>
         /// Closes the channel.
         /// </summary>
@@ -342,7 +389,7 @@ namespace Renci.SshNet.Channels
 
             var extendedDataReceived = ExtendedDataReceived;
             if (extendedDataReceived != null)
-                extendedDataReceived(this, new ChannelDataEventArgs(LocalChannelNumber, data, dataTypeCode));
+                extendedDataReceived(this, new ChannelExtendedDataEventArgs(LocalChannelNumber, data, dataTypeCode));
         }
 
         /// <summary>
@@ -448,6 +495,7 @@ namespace Renci.SshNet.Channels
             _session.SendMessage(message);
         }
 
+#if !TUNING
         /// <summary>
         /// Sends channel data message to the servers.
         /// </summary>
@@ -494,6 +542,7 @@ namespace Renci.SshNet.Channels
                 totalBytesToSend -= dataThatCanBeSentInMessage;
             }
         }
+#endif
 
         /// <summary>
         /// Sends a SSH_MSG_CHANNEL_EOF message to the remote server.

+ 4 - 0
Renci.SshClient/Renci.SshNet/Channels/ChannelDirectTcpip.cs

@@ -95,7 +95,11 @@ namespace Renci.SshNet.Channels
                     InternalSocketReceive(buffer, ref read);
                     if (read > 0)
                     {
+#if TUNING
+                        SendData(buffer, 0, read);
+#else
                         SendMessage(new ChannelDataMessage(RemoteChannelNumber, buffer.Take(read).ToArray()));
+#endif
                     }
                     else
                     {

+ 4 - 0
Renci.SshClient/Renci.SshNet/Channels/ChannelForwardedTcpip.cs

@@ -89,7 +89,11 @@ namespace Renci.SshNet.Channels
 
                     if (read > 0)
                     {
+#if TUNING
+                        SendData(buffer, 0, read);
+#else
                         SendMessage(new ChannelDataMessage(RemoteChannelNumber, buffer.Take(read).ToArray()));
+#endif
                     }
                     else
                     {

+ 23 - 1
Renci.SshClient/Renci.SshNet/Channels/IChannel.cs

@@ -22,7 +22,7 @@ namespace Renci.SshNet.Channels
         /// <summary>
         /// Occurs when <see cref="ChannelExtendedDataMessage"/> message received
         /// </summary>
-        event EventHandler<ChannelDataEventArgs> ExtendedDataReceived;
+        event EventHandler<ChannelExtendedDataEventArgs> ExtendedDataReceived;
 
         /// <summary>
         /// Occurs when <see cref="ChannelRequestMessage"/> message received
@@ -79,6 +79,28 @@ namespace Renci.SshNet.Channels
         /// <param name="data">The payload to send.</param>
         void SendData(byte[] data);
 
+#if TUNING
+        /// <summary>
+        /// Sends a SSH_MSG_CHANNEL_DATA message with the specified payload.
+        /// </summary>
+        /// <param name="data">An array of <see cref="byte"/> containing the payload to send.</param>
+        /// <param name="offset">The zero-based offset in <paramref name="data"/> at which to begin taking data from.</param>
+        /// <param name="size">The number of bytes of <paramref name="data"/> to send.</param>
+        /// <remarks>
+        /// <para>
+        /// When the size of the data to send exceeds the maximum packet size or the remote window
+        /// size does not allow the full data to be sent, then this method will send the data in
+        /// multiple chunks and will wait for the remote window size to be adjusted when it's zero.
+        /// </para>
+        /// <para>
+        /// This is done to support SSH servers will a small window size that do not agressively
+        /// increase their window size. We need to take into account that there may be SSH servers
+        /// that only increase their window size when it has reached zero.
+        /// </para>
+        /// </remarks>
+        void SendData(byte[] data, int offset, int size);
+#endif
+
         /// <summary>
         /// Sends a SSH_MSG_CHANNEL_EOF message to the remote server.
         /// </summary>

+ 4 - 0
Renci.SshClient/Renci.SshNet/Common/BigInteger.cs

@@ -1969,7 +1969,11 @@ namespace Renci.SshNet.Common
             var bytesArray = new byte[bitLength / 8 + (((bitLength % 8) > 0) ? 1 : 0)];
             _randomizer.GetBytes(bytesArray);
             bytesArray[bytesArray.Length - 1] = (byte)(bytesArray[bytesArray.Length - 1] & 0x7F);   //  Ensure not a negative value
+#if TUNING
+            return new BigInteger(bytesArray);
+#else
             return new BigInteger(bytesArray.ToArray());
+#endif
         }
 
         /// <summary>

+ 1 - 18
Renci.SshClient/Renci.SshNet/Common/ChannelDataEventArgs.cs

@@ -1,7 +1,7 @@
 namespace Renci.SshNet.Common
 {
     /// <summary>
-    /// Provides data for <see cref="Renci.SshNet.Channels.Channel.DataReceived"/> event and <see cref="Renci.SshNet.Channels.Channel.ExtendedDataReceived"/> events.
+    /// Provides data for <see cref="Renci.SshNet.Channels.Channel.DataReceived"/> event.
     /// </summary>
     internal class ChannelDataEventArgs : ChannelEventArgs
     {
@@ -10,11 +10,6 @@
         /// </summary>
         public byte[] Data { get; private set; }
 
-        /// <summary>
-        /// Gets the data type code.
-        /// </summary>
-        public uint DataTypeCode { get; private set; }
-
         /// <summary>
         /// Initializes a new instance of the <see cref="ChannelDataEventArgs"/> class.
         /// </summary>
@@ -25,17 +20,5 @@
         {
             Data = data;
         }
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="ChannelDataEventArgs"/> class.
-        /// </summary>
-        /// <param name="channelNumber">Channel number.</param>
-        /// <param name="data">Channel data.</param>
-        /// <param name="dataTypeCode">Channel data type code.</param>
-        public ChannelDataEventArgs(uint channelNumber, byte[] data, uint dataTypeCode)
-            : this(channelNumber, data)
-        {
-            DataTypeCode = dataTypeCode;
-        }
     }
 }

+ 24 - 0
Renci.SshClient/Renci.SshNet/Common/ChannelExtendedDataEventArgs.cs

@@ -0,0 +1,24 @@
+namespace Renci.SshNet.Common
+{
+    /// <summary>
+    /// Provides data for <see cref="Renci.SshNet.Channels.Channel.ExtendedDataReceived"/> events.
+    /// </summary>
+    internal class ChannelExtendedDataEventArgs : ChannelDataEventArgs
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ChannelExtendedDataEventArgs"/> class.
+        /// </summary>
+        /// <param name="channelNumber">Channel number.</param>
+        /// <param name="data">Channel data.</param>
+        /// <param name="dataTypeCode">Channel data type code.</param>
+        public ChannelExtendedDataEventArgs(uint channelNumber, byte[] data, uint dataTypeCode) : base(channelNumber, data)
+        {
+            DataTypeCode = dataTypeCode;
+        }
+
+        /// <summary>
+        /// Gets the data type code.
+        /// </summary>
+        public uint DataTypeCode { get; private set; }
+    }
+}

+ 8 - 0
Renci.SshClient/Renci.SshNet/Common/DerData.cs

@@ -108,7 +108,11 @@ namespace Renci.SshNet.Common
 
             var data = ReadBytes(length);
 
+#if TUNING
+            return new BigInteger(data.Reverse());
+#else
             return new BigInteger(data.Reverse().ToArray());
+#endif
         }
 
         /// <summary>
@@ -171,7 +175,11 @@ namespace Renci.SshNet.Common
         /// <param name="data">BigInteger data to write.</param>
         public void Write(BigInteger data)
         {
+#if TUNING
             var bytes = data.ToByteArray().Reverse().ToList();
+#else
+            var bytes = data.ToByteArray().Reverse().ToList();
+#endif
             _data.Add(Integer);
             var length = GetLength(bytes.Count);
             WriteBytes(length);

+ 115 - 0
Renci.SshClient/Renci.SshNet/Common/Extensions.cs

@@ -3,6 +3,8 @@ using System.Collections.Generic;
 using System.Diagnostics;
 using System.Globalization;
 using System.Net;
+using Renci.SshNet.Messages;
+using Renci.SshNet.Messages.Connection;
 
 namespace Renci.SshNet.Common
 {
@@ -11,6 +13,82 @@ namespace Renci.SshNet.Common
     /// </summary>
     internal static partial class Extensions
     {
+        internal static byte[] ToArray(this GlobalRequestName globalRequestName)
+        {
+            switch (globalRequestName)
+            {
+                case GlobalRequestName.TcpIpForward:
+                    return SshData.Ascii.GetBytes("tcpip-forward");
+                case GlobalRequestName.CancelTcpIpForward:
+                    return SshData.Ascii.GetBytes("cancel-tcpip-forward");
+                default:
+                    throw new NotSupportedException(string.Format("Global request name '{0}' is not supported.", globalRequestName));
+            }
+        }
+
+        internal static byte[] ToArray(this ServiceName serviceName)
+        {
+            switch (serviceName)
+            {
+                case ServiceName.UserAuthentication:
+                    return SshData.Ascii.GetBytes("ssh-userauth");
+                case ServiceName.Connection:
+                    return SshData.Ascii.GetBytes("ssh-connection");
+                default:
+                    throw new NotSupportedException(string.Format("Service name '{0}' is not supported.", serviceName));
+            }
+        }
+
+        internal static ServiceName ToServiceName(this byte[] data)
+        {
+            var sshServiceName = SshData.Ascii.GetString(data);
+            switch (sshServiceName)
+            {
+                case "ssh-userauth":
+                    return ServiceName.UserAuthentication;
+                case "ssh-connection":
+                    return ServiceName.Connection;
+                default:
+                    throw new NotSupportedException(string.Format("Service name '{0}' is not supported.", sshServiceName));
+            }
+        }
+
+        internal static GlobalRequestName ToGlobalRequestName(this byte[] data)
+        {
+            var sshGlobalRequestName = SshData.Ascii.GetString(data);
+            switch (sshGlobalRequestName)
+            {
+                case "tcpip-forward":
+                    return GlobalRequestName.TcpIpForward;
+                case "cancel-tcpip-forward":
+                    return GlobalRequestName.CancelTcpIpForward;
+                default:
+                    throw new NotSupportedException(string.Format("Global request name '{0}' is not supported.", sshGlobalRequestName));
+            }
+        }
+
+#if TUNING
+        internal static BigInteger ToBigInteger(this byte[] data)
+        {
+            var reversed = new byte[data.Length];
+            Buffer.BlockCopy(data, 0, reversed, 0, data.Length);
+            return new BigInteger(reversed.Reverse());
+        }
+
+        /// <summary>
+        /// Reverses the sequence of the elements in the entire one-dimensional <see cref="Array"/>.
+        /// </summary>
+        /// <param name="array">The one-dimensional <see cref="Array"/> to reverse.</param>
+        /// <returns>
+        /// The <see cref="Array"/> with its elements reversed.
+        /// </returns>
+        internal static T[] Reverse<T>(this T[] array)
+        {
+            Array.Reverse(array);
+            return array;
+        }
+#endif
+
         /// <summary>
         /// Checks whether a collection is the same as another collection
         /// </summary>
@@ -136,7 +214,27 @@ namespace Renci.SshNet.Common
         /// <returns>An array of bytes with length 4.</returns>
         internal static byte[] GetBytes(this UInt32 value)
         {
+#if TUNING
+            var buffer = new byte[4];
+            value.Write(buffer, 0);
+            return buffer;
+#else
             return new[] {(byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) (value & 0xFF)};
+#endif
+        }
+
+        /// <summary>
+        /// Returns the specified 32-bit unsigned integer value as an array of bytes.
+        /// </summary>
+        /// <param name="value">The number to convert.</param>
+        /// <param name="buffer">The array of bytes to write <paramref name="value"/> to.</param>
+        /// <param name="offset">The zero-based offset in <paramref name="buffer"/> at which to begin writing.</param>
+        internal static void Write(this uint value, byte[] buffer, int offset)
+        {
+            buffer[offset++] = (byte) (value >> 24);
+            buffer[offset++] = (byte) (value >> 16);
+            buffer[offset++] = (byte)(value >> 8);
+            buffer[offset] = (byte) (value & 0xFF);
         }
 
         /// <summary>
@@ -187,5 +285,22 @@ namespace Renci.SshNet.Common
                     string.Format(CultureInfo.InvariantCulture, "Specified value cannot be greater than {0}.",
                         IPEndPoint.MaxPort));
         }
+
+        /// <summary>
+        /// Returns a specified number of contiguous bytes from a given offset.
+        /// </summary>
+        /// <param name="data">The array to return a number of bytes from.</param>
+        /// <param name="offset">The zero-based offset in <paramref name="data"/> at which to begin taking bytes.</param>
+        /// <param name="length">The number of bytes to take from <paramref name="data"/>.</param>
+        /// <returns>
+        /// A <see cref="byte"/> array that contains the specified number of bytes at the specified offset
+        /// of the input array.
+        /// </returns>
+        internal static byte[] Take(this byte[] data, int offset, int length)
+        {
+            var taken = new byte[length];
+            Buffer.BlockCopy(data, offset, taken, 0, length);
+            return taken;
+        }
     }
 }

+ 1 - 1
Renci.SshClient/Renci.SshNet/Common/ScpUploadEventArgs.cs

@@ -26,7 +26,7 @@ namespace Renci.SshNet.Common
         /// Initializes a new instance of the <see cref="ScpUploadEventArgs"/> class.
         /// </summary>
         /// <param name="filename">The uploaded filename.</param>
-        /// <param name="size">The the uploaded file size.</param>
+        /// <param name="size">The uploaded file size.</param>
         /// <param name="uploaded">The number of uploaded bytes so far.</param>
         public ScpUploadEventArgs(string filename, long size, long uploaded)
         {

+ 245 - 7
Renci.SshClient/Renci.SshNet/Common/SshData.cs

@@ -1,6 +1,8 @@
 using System;
 using System.Collections.Generic;
+#if !TUNING
 using System.Linq;
+#endif
 using System.Text;
 using System.Globalization;
 
@@ -11,20 +13,31 @@ namespace Renci.SshNet.Common
     /// </summary>
     public abstract class SshData
     {
-        private static readonly Encoding Ascii = new ASCIIEncoding();
+        internal const int DefaultCapacity = 64;
+
+        internal static readonly Encoding Ascii = new ASCIIEncoding();
 
 #if SILVERLIGHT
-        private static readonly Encoding Utf8 = Encoding.UTF8;
+        internal static readonly Encoding Utf8 = Encoding.UTF8;
 #else
-        private static readonly Encoding Utf8 = Encoding.Default;
+        internal static readonly Encoding Utf8 = Encoding.Default;
 #endif
 
+#if TUNING
+        private SshDataStream _stream;
+
+        protected SshDataStream DataStream
+        {
+            get { return _stream; }
+        }
+#else
         /// <summary>
         /// Data byte array that hold message unencrypted data
         /// </summary>
         private List<byte> _data;
 
         private int _readerIndex;
+#endif
 
         /// <summary>
         /// Gets a value indicating whether all data from the buffer has been read.
@@ -32,15 +45,22 @@ namespace Renci.SshNet.Common
         /// <value>
         /// 	<c>true</c> if this instance is end of data; otherwise, <c>false</c>.
         /// </value>
-        public bool IsEndOfData
+        protected bool IsEndOfData
         {
             get
             {
+#if TUNING
+                return _stream.Position >= _stream.Length;
+#else
                 return _readerIndex >= _data.Count();
+#endif
             }
         }
 
         private byte[] _loadedData;
+#if TUNING
+        private int _offset;
+#endif
 
         /// <summary>
         /// Gets the index that represents zero in current data type.
@@ -56,23 +76,64 @@ namespace Renci.SshNet.Common
             }
         }
 
+#if TUNING
+        /// <summary>
+        /// Gets the size of the message in bytes.
+        /// </summary>
+        /// <value>
+        /// The size of the messages in bytes.
+        /// </value>
+        protected virtual int BufferCapacity
+        {
+            get { return 0; }
+        }
+#endif
+
         /// <summary>
         /// Gets data bytes array
         /// </summary>
         /// <returns>Byte array representation of data structure.</returns>
-        public virtual byte[] GetBytes()
-        {
+        public
+#if !TUNING
+        virtual
+#endif
+        byte[] GetBytes()
+        {
+#if TUNING
+            var messageLength = BufferCapacity;
+            var capacity = messageLength != -1 ? messageLength : DefaultCapacity;
+            var dataStream = new SshDataStream(capacity);
+            WriteBytes(dataStream);
+            return dataStream.ToArray();
+#else
             _data = new List<byte>();
 
             SaveData();
 
             return _data.ToArray();
+#endif
         }
 
+#if TUNING
+        /// <summary>
+        /// Writes the current message to the specified <see cref="SshDataStream"/>.
+        /// </summary>
+        /// <param name="stream">The <see cref="SshDataStream"/> to write the message to.</param>
+        protected virtual void WriteBytes(SshDataStream stream)
+        {
+            _stream = stream;
+            SaveData();
+        }
+#endif
+
         internal T OfType<T>() where T : SshData, new()
         {
             var result = new T();
+#if TUNING
+            result.LoadBytes(_loadedData, _offset);
+#else
             result.LoadBytes(_loadedData);
+#endif
             result.LoadData();
             return result;
         }
@@ -84,13 +145,31 @@ namespace Renci.SshNet.Common
         /// <exception cref="ArgumentNullException"><paramref name="value"/> is null.</exception>
         public void Load(byte[] value)
         {
+#if TUNING
+            Load(value, 0);
+#else
             if (value == null)
                 throw new ArgumentNullException("value");
 
             LoadBytes(value);
             LoadData();
+#endif
         }
 
+#if TUNING
+        /// <summary>
+        /// Loads data from the specified buffer.
+        /// </summary>
+        /// <param name="value">Bytes array.</param>
+        /// <param name="offset">The zero-based offset in <paramref name="value"/> at which to begin reading SSH data.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="value"/> is null.</exception>
+        public void Load(byte[] value, int offset)
+        {
+            LoadBytes(value, offset);
+            LoadData();
+        }
+#endif
+
         /// <summary>
         /// Called when type specific data need to be loaded.
         /// </summary>
@@ -108,6 +187,9 @@ namespace Renci.SshNet.Common
         /// <exception cref="ArgumentNullException"><paramref name="bytes"/> is null.</exception>
         protected void LoadBytes(byte[] bytes)
         {
+#if TUNING
+            LoadBytes(bytes, 0);
+#else
             // Note about why I check for null here, and in Load(byte[]) in this class.
             // This method is called by several other classes, such as SshNet.Messages.Message, SshNet.Sftp.SftpMessage.
             if (bytes == null)
@@ -116,14 +198,39 @@ namespace Renci.SshNet.Common
             ResetReader();
             _loadedData = bytes;
             _data = new List<byte>(bytes);
+#endif
+        }
+
+#if TUNING
+        /// <summary>
+        /// Loads data bytes into internal buffer.
+        /// </summary>
+        /// <param name="bytes">The bytes.</param>
+        /// <param name="offset">The zero-based offset in <paramref name="bytes"/> at which to begin reading SSH data.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="bytes"/> is null.</exception>
+        protected void LoadBytes(byte[] bytes, int offset)
+        {
+            if (bytes == null)
+                throw new ArgumentNullException("bytes");
+
+            _loadedData = bytes;
+            _offset = offset;
+
+            _stream = new SshDataStream(bytes);
+            ResetReader();
         }
+#endif
 
         /// <summary>
         /// Resets internal data reader index.
         /// </summary>
         protected void ResetReader()
         {
+#if TUNING
+            _stream.Position = ZeroReaderIndex + _offset;
+#else
             _readerIndex = ZeroReaderIndex;  //  Set to 1 to skip first byte which specifies message type
+#endif
         }
 
         /// <summary>
@@ -132,9 +239,16 @@ namespace Renci.SshNet.Common
         /// <returns>An array of bytes containing the remaining data in the internal buffer.</returns>
         protected byte[] ReadBytes()
         {
+#if TUNING
+            var bytesLength = (int) (_stream.Length - _stream.Position);
+            var data = new byte[bytesLength];
+            _stream.Read(data, 0, bytesLength);
+            return data;
+#else
             var data = new byte[_data.Count - _readerIndex];
             _data.CopyTo(_readerIndex, data, 0, data.Length);
             return data;
+#endif
         }
 
         /// <summary>
@@ -148,6 +262,16 @@ namespace Renci.SshNet.Common
             // Note that this also prevents allocating non-relevant lengths, such as if length is greater than _data.Count but less than int.MaxValue.
             // For the nerds, the condition translates to: if (length > data.Count && length < int.MaxValue)
             // Which probably would cause all sorts of exception, most notably OutOfMemoryException.
+
+#if TUNING
+            var data = new byte[length];
+            var bytesRead = _stream.Read(data, 0, length);
+
+            if (bytesRead < length)
+                throw new ArgumentOutOfRangeException("length");
+
+            return data;
+#else
             if (length > _data.Count)
                 throw new ArgumentOutOfRangeException("length");
 
@@ -155,6 +279,7 @@ namespace Renci.SshNet.Common
             _data.CopyTo(_readerIndex, result, 0, length);
             _readerIndex += length;
             return result;
+#endif
         }
 
         /// <summary>
@@ -163,7 +288,14 @@ namespace Renci.SshNet.Common
         /// <returns>Byte read.</returns>
         protected byte ReadByte()
         {
+#if TUNING
+            var byteRead = _stream.ReadByte();
+            if (byteRead == -1)
+                throw new InvalidOperationException("Attempt to read past the end of the SSH data stream.");
+            return (byte) byteRead;
+#else
             return ReadBytes(1).FirstOrDefault();
+#endif
         }
 
         /// <summary>
@@ -215,6 +347,7 @@ namespace Renci.SshNet.Common
             return (int)(data[0] << 56 | data[1] << 48 | data[2] << 40 | data[3] << 32 | data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]);
         }
 
+#if !TUNING
         /// <summary>
         /// Reads next string data type from internal buffer.
         /// </summary>
@@ -229,6 +362,7 @@ namespace Renci.SshNet.Common
             }
             return Ascii.GetString(ReadBytes((int)length), 0, (int)length);
         }
+#endif
 
         /// <summary>
         /// Reads next string data type from internal buffer.
@@ -254,7 +388,25 @@ namespace Renci.SshNet.Common
             return encoding.GetString(ReadBytes((int)length), 0, (int)length);
         }
 
+#if TUNING
+        /// <summary>
+        /// Reads next data type as byte array from internal buffer.
+        /// </summary>
+        /// <returns>
+        /// The bytes read.
+        /// </returns>
+        protected byte[] ReadBinary()
+        {
+            var length = ReadUInt32();
+
+            if (length > int.MaxValue)
+            {
+                throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Data longer than {0} is not supported.", int.MaxValue));
+            }
 
+            return ReadBytes((int) length);
+        }
+#else
         /// <summary>
         /// Reads next string data type from internal buffer.
         /// </summary>
@@ -270,6 +422,7 @@ namespace Renci.SshNet.Common
 
             return ReadBytes((int)length);
         }
+#endif
 
         /// <summary>
         /// Reads next mpint data type from internal buffer.
@@ -281,7 +434,11 @@ namespace Renci.SshNet.Common
 
             var data = ReadBytes((int)length);
 
+#if TUNING
+            return new BigInteger(data.Reverse());
+#else
             return new BigInteger(data.Reverse().ToArray());
+#endif
         }
 
         /// <summary>
@@ -301,7 +458,7 @@ namespace Renci.SshNet.Common
         protected IDictionary<string, string> ReadExtensionPair()
         {
             var result = new Dictionary<string, string>();
-            while (_readerIndex < _data.Count)
+            while (!IsEndOfData)
             {
                 var extensionName = ReadString();
                 var extensionData = ReadString();
@@ -310,6 +467,17 @@ namespace Renci.SshNet.Common
             return result;
         }
 
+#if TUNING
+        /// <summary>
+        /// Writes bytes array data into internal buffer.
+        /// </summary>
+        /// <param name="data">Byte array data to write.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="data"/> is null.</exception>
+        protected void Write(byte[] data)
+        {
+            _stream.Write(data, 0, data.Length);
+        }
+#else
         /// <summary>
         /// Writes bytes array data into internal buffer.
         /// </summary>
@@ -319,6 +487,24 @@ namespace Renci.SshNet.Common
         {
             _data.AddRange(data);
         }
+#endif
+
+#if TUNING
+        /// <summary>
+        /// Writes a sequence of bytes to the current SSH data stream and advances the current position
+        /// within this stream by the number of bytes written.
+        /// </summary>
+        /// <param name="buffer">An array of bytes. This method write <paramref name="count"/> bytes from buffer to the current SSH data stream.</param>
+        /// <param name="offset">The zero-based offset in <paramref name="buffer"/> at which to begin writing bytes to the SSH data stream.</param>
+        /// <param name="count">The number of bytes to be written to the current SSH data stream.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
+        /// <exception cref="ArgumentException">The sum of <paramref name="offset"/> and <paramref name="count"/> is greater than the buffer length.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="offset"/> or <paramref name="count"/> is negative.</exception>
+        protected void Write(byte[] buffer, int offset, int count)
+        {
+            _stream.Write(buffer, offset, count);
+        }
+#endif
 
         /// <summary>
         /// Writes byte data into internal buffer.
@@ -326,7 +512,11 @@ namespace Renci.SshNet.Common
         /// <param name="data">Byte data to write.</param>
         protected void Write(byte data)
         {
+#if TUNING
+            _stream.WriteByte(data);
+#else
             _data.Add(data);
+#endif
         }
 
         /// <summary>
@@ -409,10 +599,50 @@ namespace Renci.SshNet.Common
                 throw new ArgumentNullException("encoding");
 
             var bytes = encoding.GetBytes(data);
+#if TUNING
+            var bytesLength = bytes.Length;
+            Write((uint) bytesLength);
+            Write(bytes, 0, bytesLength);
+#else
             Write((uint)bytes.Length);
             Write(bytes);
+#endif
         }
 
+#if TUNING
+        /// <summary>
+        /// Writes data into internal buffer.
+        /// </summary>
+        /// <param name="buffer">The data to write.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
+        protected void WriteBinaryString(byte[] buffer)
+        {
+            if (buffer == null)
+                throw new ArgumentNullException("buffer");
+
+            var bufferLength = buffer.Length;
+            Write((uint)bufferLength);
+            Write(buffer, 0, bufferLength);
+        }
+
+        /// <summary>
+        /// Writes data into internal buffer.
+        /// </summary>
+        /// <param name="buffer">An array of bytes. This method write <paramref name="count"/> bytes from buffer to the current SSH data stream.</param>
+        /// <param name="offset">The zero-based byte offset in <paramref name="buffer"/> at which to begin writing bytes to the SSH data stream.</param>
+        /// <param name="count">The number of bytes to be written to the current SSH data stream.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is null.</exception>
+        /// <exception cref="ArgumentException">The sum of <paramref name="offset"/> and <paramref name="count"/> is greater than the buffer length.</exception>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="offset"/> or <paramref name="count"/> is negative.</exception>
+        protected void WriteBinary(byte[] buffer, int offset, int count)
+        {
+            if (buffer == null)
+                throw new ArgumentNullException("buffer");
+
+            Write((uint) count);
+            Write(buffer, offset, count);
+        }
+#else
         /// <summary>
         /// Writes string data into internal buffer.
         /// </summary>
@@ -426,6 +656,7 @@ namespace Renci.SshNet.Common
             Write((uint)data.Length);
             _data.AddRange(data);
         }
+#endif
 
         /// <summary>
         /// Writes mpint data into internal buffer.
@@ -433,9 +664,16 @@ namespace Renci.SshNet.Common
         /// <param name="data">mpint data to write.</param>
         protected void Write(BigInteger data)
         {
+#if TUNING
+            var bytes = data.ToByteArray().Reverse();
+            var bytesLength = bytes.Length;
+            Write((uint) bytesLength);
+            Write(bytes, 0, bytesLength);
+#else
             var bytes = data.ToByteArray().Reverse().ToList();
             Write((uint)bytes.Count);
             Write(bytes);
+#endif
         }
 
         /// <summary>

+ 142 - 0
Renci.SshClient/Renci.SshNet/Common/SshDataStream.cs

@@ -0,0 +1,142 @@
+using System;
+using System.Globalization;
+using System.IO;
+using System.Text;
+
+namespace Renci.SshNet.Common
+{
+    public class SshDataStream : MemoryStream
+    {
+        public SshDataStream(int capacity)
+            : base(capacity)
+        {
+        }
+
+        public SshDataStream(byte[] buffer)
+            : base(buffer)
+        {
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether all data from the SSH data stream has been read.
+        /// </summary>
+        /// <value>
+        /// <c>true</c> if this instance is end of data; otherwise, <c>false</c>.
+        /// </value>
+        public bool IsEndOfData
+        {
+            get
+            {
+                return Position >= Length;
+            }
+        }
+
+        /// <summary>
+        /// Writes <see cref="uint"/> data to the SSH data stream.
+        /// </summary>
+        /// <param name="value"><see cref="uint"/> data to write.</param>
+        public void Write(uint value)
+        {
+            var bytes = value.GetBytes();
+            Write(bytes, 0, bytes.Length);
+        }
+
+        /// <summary>
+        /// Writes <see cref="ulong"/> data to the SSH data stream.
+        /// </summary>
+        /// <param name="value"><see cref="ulong"/> data to write.</param>
+        public void Write(ulong value)
+        {
+            var bytes = value.GetBytes();
+            Write(bytes, 0, bytes.Length);
+        }
+
+        /// <summary>
+        /// Writes string data to the SSH data stream using the specified encoding.
+        /// </summary>
+        /// <param name="value">The string data to write.</param>
+        /// <param name="encoding">The character encoding to use.</param>
+        /// <exception cref="ArgumentNullException"><paramref name="value"/> is null.</exception>
+        /// <exception cref="ArgumentNullException"><paramref name="encoding"/> is null.</exception>
+        public void Write(string value, Encoding encoding)
+        {
+            if (value == null)
+                throw new ArgumentNullException("value");
+            if (encoding == null)
+                throw new ArgumentNullException("encoding");
+
+            var bytes = encoding.GetBytes(value);
+            var bytesLength = bytes.Length;
+            Write((uint) bytesLength);
+            Write(bytes, 0, bytesLength);
+        }
+
+        /// <summary>
+        /// Reads the next <see cref="uint"/> data type from the SSH data stream.
+        /// </summary>
+        /// <returns>
+        /// The <see cref="uint"/> read from the SSH data stream.
+        /// </returns>
+        public uint ReadUInt32()
+        {
+            var data = ReadBytes(4);
+            return (uint)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]);
+        }
+
+        /// <summary>
+        /// Reads the next <see cref="ulong"/> data type from the SSH data stream.
+        /// </summary>
+        /// <returns>
+        /// The <see cref="ulong"/> read from the SSH data stream.
+        /// </returns>
+        public ulong ReadUInt64()
+        {
+            var data = ReadBytes(8);
+            return ((ulong) data[0] << 56 | (ulong) data[1] << 48 | (ulong) data[2] << 40 | (ulong) data[3] << 32 |
+                    (ulong) data[4] << 24 | (ulong) data[5] << 16 | (ulong) data[6] << 8 | data[7]);
+        }
+
+        /// <summary>
+        /// Reads the next <see cref="string"/> data type from the SSH data stream.
+        /// </summary>
+        /// <returns>
+        /// The <see cref="string"/> read from the SSH data stream.
+        /// </returns>
+        public string ReadString(Encoding encoding)
+        {
+            var length = ReadUInt32();
+
+            if (length > int.MaxValue)
+            {
+                throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Strings longer than {0} is not supported.", int.MaxValue));
+            }
+            return encoding.GetString(ReadBytes((int) length), 0, (int) length);
+        }
+
+        /// <summary>
+        /// Reads next specified number of bytes data type from internal buffer.
+        /// </summary>
+        /// <param name="length">Number of bytes to read.</param>
+        /// <returns>An array of bytes that was read from the internal buffer.</returns>
+        /// <exception cref="ArgumentOutOfRangeException"><paramref name="length"/> is greater than the internal buffer size.</exception>
+        private byte[] ReadBytes(int length)
+        {
+            var data = new byte[length];
+            var bytesRead = base.Read(data, 0, length);
+
+            if (bytesRead < length)
+                throw new ArgumentOutOfRangeException("length");
+
+            return data;
+        }
+
+        public override byte[] ToArray()
+        {
+            if (Capacity == Length)
+            {
+                return GetBuffer();
+            }
+            return base.ToArray();
+        }
+    }
+}

+ 45 - 5
Renci.SshClient/Renci.SshNet/Compression/Compressor.cs

@@ -55,15 +55,34 @@ namespace Renci.SshNet.Compression
         /// <param name="data">Data to compress.</param>
         /// <returns>Compressed data</returns>
         public virtual byte[] Compress(byte[] data)
+        {
+            return Compress(data, 0, data.Length);
+        }
+
+        /// <summary>
+        /// Compresses the specified data.
+        /// </summary>
+        /// <param name="data">Data to compress.</param>
+        /// <param name="offset">The zero-based byte offset in <paramref name="data"/> at which to begin reading the data to compress. </param>
+        /// <param name="length">The number of bytes to be compressed. </param>
+        /// <returns>
+        /// The compressed data.
+        /// </returns>
+        public virtual byte[] Compress(byte[] data, int offset, int length)
         {
             if (!IsActive)
             {
-                return data;
+                if (offset == 0 && length == data.Length)
+                    return data;
+
+                var buffer = new byte[length];
+                Buffer.BlockCopy(data, offset, buffer, 0, length);
+                return buffer;
             }
 
             _compressorStream.SetLength(0);
 
-            _compressor.Write(data, 0, data.Length);
+            _compressor.Write(data, offset, length);
 
             return _compressorStream.ToArray();
         }
@@ -72,17 +91,38 @@ namespace Renci.SshNet.Compression
         /// Decompresses the specified data.
         /// </summary>
         /// <param name="data">Compressed data.</param>
-        /// <returns>Decompressed data.</returns>
+        /// <returns>
+        /// The decompressed data.
+        /// </returns>
         public virtual byte[] Decompress(byte[] data)
+        {
+            return Decompress(data, 0, data.Length);
+        }
+
+        /// <summary>
+        /// Decompresses the specified data.
+        /// </summary>
+        /// <param name="data">Compressed data.</param>
+        /// <param name="offset">The zero-based byte offset in <paramref name="data"/> at which to begin reading the data to decompress. </param>
+        /// <param name="length">The number of bytes to be read from the compressed data. </param>
+        /// <returns>
+        /// The decompressed data.
+        /// </returns>
+        public virtual byte[] Decompress(byte[] data, int offset, int length)
         {
             if (!IsActive)
             {
-                return data;
+                if (offset == 0 && length == data.Length)
+                    return data;
+
+                var buffer = new byte[length];
+                Buffer.BlockCopy(data, offset, buffer, 0, length);
+                return buffer;
             }
 
             _decompressorStream.SetLength(0);
 
-            _decompressor.Write(data, 0, data.Length);
+            _decompressor.Write(data, offset, length);
 
             return _decompressorStream.ToArray();
         }

+ 1 - 1
Renci.SshClient/Renci.SshNet/KeyboardInteractiveAuthenticationMethod.NET40.cs

@@ -3,7 +3,7 @@ using System.Threading;
 
 namespace Renci.SshNet
 {
-    public partial  class KeyboardInteractiveAuthenticationMethod : AuthenticationMethod
+    public partial  class KeyboardInteractiveAuthenticationMethod
     {
         /// <summary>
         /// Executes the specified action in a separate thread.

+ 53 - 1
Renci.SshClient/Renci.SshNet/Messages/Authentication/BannerMessage.cs

@@ -1,4 +1,6 @@
-namespace Renci.SshNet.Messages.Authentication
+using System;
+
+namespace Renci.SshNet.Messages.Authentication
 {
     /// <summary>
     /// Represents SSH_MSG_USERAUTH_BANNER message.
@@ -6,23 +8,68 @@
     [Message("SSH_MSG_USERAUTH_BANNER", 53)]
     public class BannerMessage : Message
     {
+#if TUNING
+        private byte[] _message;
+        private byte[] _language;
+#endif
+
         /// <summary>
         /// Gets banner message.
         /// </summary>
+#if TUNING
+        public string Message
+        {
+            get { return Utf8.GetString(_message); }
+        }
+#else
         public string Message { get; private set; }
+#endif
 
         /// <summary>
         /// Gets banner language.
         /// </summary>
+#if TUNING
+        public string Language
+        {
+            get { return Utf8.GetString(_language); }
+        }
+#else
         public string Language { get; private set; }
+#endif
+
+#if TUNING
+        /// <summary>
+        /// Gets the size of the message in bytes.
+        /// </summary>
+        /// <value>
+        /// The size of the messages in bytes.
+        /// </value>
+        protected override int BufferCapacity
+        {
+            get
+            {
+                var capacity = base.BufferCapacity;
+                capacity += 4; // Message length
+                capacity += _message.Length; // Message
+                capacity += 4; // Language length
+                capacity += _language.Length; // Language
+                return capacity;
+            }
+        }
+#endif
 
         /// <summary>
         /// Called when type specific data need to be loaded.
         /// </summary>
         protected override void LoadData()
         {
+#if TUNING
+            _message = ReadBinary();
+            _language = ReadBinary();
+#else
             Message = ReadString();
             Language = ReadString();
+#endif
         }
 
         /// <summary>
@@ -30,8 +77,13 @@
         /// </summary>
         protected override void SaveData()
         {
+#if TUNING
+            WriteBinaryString(_message);
+            WriteBinaryString(_language);
+#else
             Write(Message);
             Write(Language);
+#endif
         }
     }
 }

+ 14 - 0
Renci.SshClient/Renci.SshNet/Messages/Authentication/InformationResponseMessage.cs

@@ -14,6 +14,20 @@ namespace Renci.SshNet.Messages.Authentication
         /// </summary>
         public IList<string> Responses { get; private set; }
 
+#if TUNING
+        /// <summary>
+        /// Gets the size of the message in bytes.
+        /// </summary>
+        /// <value>
+        /// <c>-1</c> to indicate that the size of the message cannot be determined,
+        /// or is too costly to calculate.
+        /// </value>
+        protected override int BufferCapacity
+        {
+            get { return -1; }
+        }
+#endif
+
         /// <summary>
         /// Initializes a new instance of the <see cref="InformationResponseMessage"/> class.
         /// </summary>

+ 46 - 0
Renci.SshClient/Renci.SshNet/Messages/Authentication/PasswordChangeRequiredMessage.cs

@@ -6,23 +6,64 @@
     [Message("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ", 60)]
     internal class PasswordChangeRequiredMessage : Message
     {
+#if TUNING
+        /// <summary>
+        /// Gets password change request message as UTF-8 encoded byte array.
+        /// </summary>
+        public byte[] Message { get; private set; }
+#else
         /// <summary>
         /// Gets password change request message.
         /// </summary>
         public string Message { get; private set; }
+#endif
+
 
+#if TUNING
+        /// <summary>
+        /// Gets message language as UTF-8 encoded byte array.
+        /// </summary>
+        public byte[] Language { get; private set; }
+#else
         /// <summary>
         /// Gets message language.
         /// </summary>
         public string Language { get; private set; }
+#endif
+
+#if TUNING
+        /// <summary>
+        /// Gets the size of the message in bytes.
+        /// </summary>
+        /// <value>
+        /// The size of the messages in bytes.
+        /// </value>
+        protected override int BufferCapacity
+        {
+            get
+            {
+                var capacity = base.BufferCapacity;
+                capacity += 4; // Message length
+                capacity += Message.Length; // Message
+                capacity += 4; // Language length
+                capacity += Language.Length; // Language
+                return capacity;
+            }
+        }
+#endif
 
         /// <summary>
         /// Called when type specific data need to be loaded.
         /// </summary>
         protected override void LoadData()
         {
+#if TUNING
+            Message = ReadBinary();
+            Language = ReadBinary();
+#else
             Message = ReadString();
             Language = ReadString();
+#endif
         }
 
         /// <summary>
@@ -30,8 +71,13 @@
         /// </summary>
         protected override void SaveData()
         {
+#if TUNING
+            WriteBinaryString(Message);
+            WriteBinaryString(Language);
+#else
             Write(Message);
             Write(Language);
+#endif
         }
     }
 }

+ 41 - 0
Renci.SshClient/Renci.SshNet/Messages/Authentication/PublicKeyMessage.cs

@@ -6,6 +6,15 @@
     [Message("SSH_MSG_USERAUTH_PK_OK", 60)]
     internal class PublicKeyMessage : Message
     {
+#if TUNING
+        /// <summary>
+        /// Gets the name of the public key algorithm as ASCII encoded byte array.
+        /// </summary>
+        /// <value>
+        /// The name of the public key algorithm.
+        /// </value>
+        public byte[] PublicKeyAlgorithmName { get; private set; }
+#else
         /// <summary>
         /// Gets the name of the public key algorithm.
         /// </summary>
@@ -13,19 +22,46 @@
         /// The name of the public key algorithm.
         /// </value>
         public string PublicKeyAlgorithmName { get; private set; }
+#endif
 
         /// <summary>
         /// Gets the public key data.
         /// </summary>
         public byte[] PublicKeyData { get; private set; }
 
+#if TUNING
+        /// <summary>
+        /// Gets the size of the message in bytes.
+        /// </summary>
+        /// <value>
+        /// The size of the messages in bytes.
+        /// </value>
+        protected override int BufferCapacity
+        {
+            get
+            {
+                var capacity = base.BufferCapacity;
+                capacity += 4; // PublicKeyAlgorithmName length
+                capacity += PublicKeyAlgorithmName.Length; // PublicKeyAlgorithmName
+                capacity += 4; // PublicKeyData length
+                capacity += PublicKeyData.Length; // PublicKeyData
+                return capacity;
+            }
+        }
+#endif
+
         /// <summary>
         /// Called when type specific data need to be loaded.
         /// </summary>
         protected override void LoadData()
         {
+#if TUNING
+            PublicKeyAlgorithmName = ReadBinary();
+            PublicKeyData = ReadBinary();
+#else
             PublicKeyAlgorithmName = ReadAsciiString();
             PublicKeyData = ReadBinaryString();
+#endif
         }
 
         /// <summary>
@@ -33,8 +69,13 @@
         /// </summary>
         protected override void SaveData()
         {
+#if TUNING
+            WriteBinaryString(PublicKeyAlgorithmName);
+            WriteBinaryString(PublicKeyData);
+#else
             WriteAscii(PublicKeyAlgorithmName);
             WriteBinaryString(PublicKeyData);
+#endif
         }
     }
 }

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio