Jelajahi Sumber

* 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 11 tahun lalu
induk
melakukan
c61633a3bc
100 mengubah file dengan 4951 tambahan dan 380 penghapusan
  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
         }
     }
 }

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini