Переглянути джерело

Added tests for issue #191, and update tests for issue #154.

Gert Driesen 8 роки тому
батько
коміт
08b2d05ed8
61 змінених файлів з 3026 додано та 128 видалено
  1. 48 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTestBase.cs
  2. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Closed_FileAccessRead.cs
  3. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Closed_FileAccessReadWrite.cs
  4. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Closed_FileAccessWrite.cs
  5. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Disposed_FileAccessRead.cs
  6. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Disposed_FileAccessReadWrite.cs
  7. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Disposed_FileAccessWrite.cs
  8. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_SessionOpen_FileAccessRead.cs
  9. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_SessionOpen_FileAccessReadWrite.cs
  10. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_SessionOpen_FileAccessWrite.cs
  11. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Closed_FileAccessRead.cs
  12. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Closed_FileAccessReadWrite.cs
  13. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Closed_FileAccessWrite.cs
  14. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Disposed_FileAccessRead.cs
  15. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Disposed_FileAccessReadWrite.cs
  16. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Disposed_FileAccessWrite.cs
  17. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_SessionOpen_FileAccessRead.cs
  18. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_SessionOpen_FileAccessReadWrite.cs
  19. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_SessionOpen_FileAccessWrite.cs
  20. 0 2
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Close_Closed.cs
  21. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Close_Disposed.cs
  22. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Close_SessionNotOpen.cs
  23. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Close_SessionOpen.cs
  24. 54 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileAccessInvalid.cs
  25. 55 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeAppend_FileAccessRead.cs
  26. 164 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeAppend_FileAccessReadWrite.cs
  27. 169 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeAppend_FileAccessWrite.cs
  28. 55 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeCreateNew_FileAccessRead.cs
  29. 147 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeCreateNew_FileAccessReadWrite.cs
  30. 151 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeCreateNew_FileAccessWrite.cs
  31. 55 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeCreate_FileAccessRead.cs
  32. 150 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeCreate_FileAccessReadWrite_FileDoesNotExist.cs
  33. 147 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeCreate_FileAccessReadWrite_FileExists.cs
  34. 155 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeCreate_FileAccessWrite_FileDoesNotExist.cs
  35. 151 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeCreate_FileAccessWrite_FileExists.cs
  36. 54 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeInvalid.cs
  37. 170 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeOpenOrCreate_FileAccessRead.cs
  38. 147 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeOpenOrCreate_FileAccessReadWrite.cs
  39. 151 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeOpenOrCreate_FileAccessWrite.cs
  40. 170 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeOpen_FileAccessRead.cs
  41. 147 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeOpen_FileAccessReadWrite.cs
  42. 151 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeOpen_FileAccessWrite.cs
  43. 55 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeTruncate_FileAccessRead.cs
  44. 147 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeTruncate_FileAccessReadWrite.cs
  45. 151 0
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeTruncate_FileAccessWrite.cs
  46. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Dispose_Closed.cs
  47. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Dispose_Disposed.cs
  48. 5 8
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Dispose_SessionNotOpen.cs
  49. 1 4
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Dispose_SessionOpen.cs
  50. 1 4
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Finalize_SessionOpen.cs
  51. 4 9
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_ReadByte_ReadMode_NoDataInWriteBufferAndNoDataInReadBuffer_Eof.cs
  52. 0 4
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_ReadByte_ReadMode_NoDataInWriteBufferAndNoDataInReadBuffer_LessDataThanReadBufferSizeAvailable.cs
  53. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_Closed.cs
  54. 5 9
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_Disposed.cs
  55. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_SessionNotOpen.cs
  56. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_SessionOpen_FIleAccessRead.cs
  57. 28 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_SessionOpen_FIleAccessReadWrite.cs
  58. 29 4
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_SessionOpen_FIleAccessWrite.cs
  59. 0 3
      src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Write_SessionOpen_CountGreatherThanTwoTimesTheWriteBufferSize.cs
  60. 85 0
      src/Renci.SshNet.Tests/Common/SftpFileAttributesBuilder.cs
  61. 24 0
      src/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj

+ 48 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTestBase.cs

@@ -0,0 +1,48 @@
+using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    public abstract class SftpFileStreamTestBase
+    {
+        internal Mock<ISftpSession> SftpSessionMock;
+        protected MockSequence MockSequence;
+
+        private void Arrange()
+        {
+            SetupData();
+            CreateMocks();
+            SetupMocks();
+        }
+
+        protected virtual void SetupData()
+        {
+            MockSequence = new MockSequence();
+        }
+
+        protected abstract void SetupMocks();
+
+        private void CreateMocks()
+        {
+            SftpSessionMock = new Mock<ISftpSession>(MockBehavior.Strict);
+        }
+
+        [TestInitialize]
+        public void SetUp()
+        {
+            Arrange();
+            Act();
+        }
+
+        protected abstract void Act();
+
+        protected byte[] GenerateRandom(int length, Random random)
+        {
+            var buffer = new byte[length];
+            random.NextBytes(buffer);
+            return buffer;
+        }
+    }
+}

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Closed_FileAccessRead.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -32,7 +31,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint) random.Next(0, 1000);
             _readBufferSize = (uint) random.Next(0, 1000);
             _writeBufferSize = (uint) random.Next(0, 1000);
@@ -43,7 +41,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Closed_FileAccessReadWrite.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -32,7 +31,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint) random.Next(0, 1000);
             _readBufferSize = (uint) random.Next(0, 1000);
             _writeBufferSize = (uint) random.Next(0, 1000);
@@ -43,7 +41,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Write | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Closed_FileAccessWrite.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -32,7 +31,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint) random.Next(0, 1000);
             _readBufferSize = (uint) random.Next(0, 1000);
             _writeBufferSize = (uint) random.Next(0, 1000);
@@ -43,7 +41,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Write | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Disposed_FileAccessRead.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -32,7 +31,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);
@@ -43,7 +41,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Disposed_FileAccessReadWrite.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -32,7 +31,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);
@@ -43,7 +41,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Write | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_Disposed_FileAccessWrite.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -32,7 +31,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);
@@ -43,7 +41,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Write | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_SessionOpen_FileAccessRead.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -32,7 +31,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);
@@ -43,7 +41,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_SessionOpen_FileAccessReadWrite.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -32,7 +31,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);
@@ -43,7 +41,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Write | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanRead_SessionOpen_FileAccessWrite.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -32,7 +31,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);
@@ -43,7 +41,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Write | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Closed_FileAccessRead.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -32,7 +31,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);
@@ -43,7 +41,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Closed_FileAccessReadWrite.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -32,7 +31,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);
@@ -43,7 +41,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Write | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Closed_FileAccessWrite.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -32,7 +31,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);
@@ -43,7 +41,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Write | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Disposed_FileAccessRead.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -32,7 +31,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);
@@ -43,7 +41,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Disposed_FileAccessReadWrite.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -32,7 +31,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);
@@ -43,7 +41,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Write | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_Disposed_FileAccessWrite.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -32,7 +31,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);
@@ -43,7 +41,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Write | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_SessionOpen_FileAccessRead.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -32,7 +31,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);
@@ -43,7 +41,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_SessionOpen_FileAccessReadWrite.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -32,7 +31,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);
@@ -43,7 +41,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Write | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_CanWrite_SessionOpen_FileAccessWrite.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -32,7 +31,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(0, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);
@@ -43,7 +41,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Write | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 2
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Close_Closed.cs

@@ -31,7 +31,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(1, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);
@@ -42,7 +41,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Close_Disposed.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -31,7 +30,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(1, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);
@@ -42,7 +40,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Close_SessionNotOpen.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -31,7 +30,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(1, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);
@@ -42,7 +40,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Close_SessionOpen.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -31,7 +30,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint) random.Next(1, 1000);
             _readBufferSize = (uint) random.Next(0, 1000);
             _writeBufferSize = (uint) random.Next(0, 1000);
@@ -42,7 +40,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 54 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileAccessInvalid.cs

@@ -0,0 +1,54 @@
+using System;
+using System.IO;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpFileStreamTest_Ctor_FileAccessInvalid : SftpFileStreamTestBase
+    {
+        private Random _random;
+        private string _path;
+        private FileMode _fileMode;
+        private FileAccess _fileAccess;
+        private int _bufferSize;
+        private ArgumentOutOfRangeException _actualException;
+
+        protected override void SetupData()
+        {
+            base.SetupData();
+
+            _random = new Random();
+            _path = _random.Next().ToString();
+            _fileMode = FileMode.Open;
+            _fileAccess = 0;
+            _bufferSize = _random.Next(5, 1000);
+        }
+
+        protected override void SetupMocks()
+        {
+        }
+
+        protected override void Act()
+        {
+            try
+            {
+                new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
+                Assert.Fail();
+            }
+            catch (ArgumentOutOfRangeException ex)
+            {
+                _actualException = ex;
+            }
+        }
+
+        [TestMethod]
+        public void CtorShouldHaveThrownArgumentException()
+        {
+            Assert.IsNotNull(_actualException);
+            Assert.IsNull(_actualException.InnerException);
+            Assert.AreEqual("access", _actualException.ParamName);
+        }
+    }
+}

+ 55 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeAppend_FileAccessRead.cs

@@ -0,0 +1,55 @@
+using System;
+using System.IO;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpFileStreamTest_Ctor_FileModeAppend_FileAccessRead : SftpFileStreamTestBase
+    {
+        private Random _random;
+        private string _path;
+        private FileMode _fileMode;
+        private FileAccess _fileAccess;
+        private int _bufferSize;
+        private ArgumentException _actualException;
+
+        protected override void SetupData()
+        {
+            base.SetupData();
+
+            _random = new Random();
+            _path = _random.Next().ToString();
+            _fileMode = FileMode.Append;
+            _fileAccess = FileAccess.Read;
+            _bufferSize = _random.Next(5, 1000);
+        }
+
+        protected override void SetupMocks()
+        {
+        }
+
+        protected override void Act()
+        {
+            try
+            {
+                new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
+                Assert.Fail();
+            }
+            catch (ArgumentException ex)
+            {
+                _actualException = ex;
+            }
+        }
+
+        [TestMethod]
+        public void CtorShouldHaveThrownArgumentException()
+        {
+            Assert.IsNotNull(_actualException);
+            Assert.IsNull(_actualException.InnerException);
+            Assert.AreEqual($"Combining {nameof(FileMode)}: {_fileMode} with {nameof(FileAccess)}: {_fileAccess} is invalid.", _actualException.Message);
+            Assert.IsNull(_actualException.ParamName);
+        }
+    }
+}

+ 164 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeAppend_FileAccessReadWrite.cs

@@ -0,0 +1,164 @@
+using System;
+using System.IO;
+using System.Threading;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Tests.Common;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpFileStreamTest_Ctor_FileModeAppend_FileAccessReadWrite : SftpFileStreamTestBase
+    {
+        private Random _random;
+        private string _path;
+        private FileMode _fileMode;
+        private FileAccess _fileAccess;
+        private int _bufferSize;
+        private uint _readBufferSize;
+        private uint _writeBufferSize;
+        private byte[] _handle;
+        private SftpFileStream _target;
+        private SftpFileAttributes _fileAttributes;
+
+        protected override void SetupData()
+        {
+            base.SetupData();
+
+            _random = new Random();
+            _path = _random.Next().ToString();
+            _fileMode = FileMode.Append;
+            _fileAccess = FileAccess.ReadWrite;
+            _bufferSize = _random.Next(5, 1000);
+            _readBufferSize = (uint) _random.Next(5, 1000);
+            _writeBufferSize = (uint) _random.Next(5, 1000);
+            _handle = GenerateRandom(_random.Next(1, 10), _random);
+            _fileAttributes = new SftpFileAttributesBuilder().WithLastAccessTime(DateTime.Now.AddSeconds(_random.Next()))
+                                                             .WithLastWriteTime(DateTime.Now.AddSeconds(_random.Next()))
+                                                             .WithSize(_random.Next())
+                                                             .WithUserId(_random.Next())
+                                                             .WithGroupId(_random.Next())
+                                                             .WithPermissions((uint)_random.Next())
+                                                             .Build();
+        }
+
+        protected override void SetupMocks()
+        {
+            SftpSessionMock.InSequence(MockSequence)
+                            .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Write | Flags.Append, false))
+                            .Returns(_handle);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalReadLength((uint)_bufferSize))
+                           .Returns(_readBufferSize);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalWriteLength((uint)_bufferSize, _handle))
+                           .Returns(_writeBufferSize);
+            SftpSessionMock.InSequence(MockSequence)
+                            .Setup(p => p.RequestFStat(_handle, false))
+                            .Returns(_fileAttributes);
+        }
+
+        protected override void Act()
+        {
+            _target = new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
+        }
+
+        [TestMethod]
+        public void CanReadShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanRead);
+        }
+
+        [TestMethod]
+        public void CanSeekShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanSeek);
+        }
+
+        [TestMethod]
+        public void CanWriteShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanWrite);
+        }
+
+        [TestMethod]
+        public void CanTimeoutShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanTimeout);
+        }
+
+        [TestMethod]
+        public void PositionShouldReturnSizeOfFile()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            var actual = _target.Position;
+
+            Assert.AreEqual(_fileAttributes.Size, actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadShouldStartReadingAtEndOfFile()
+        {
+            var buffer = new byte[8];
+            var data = new byte[] {5, 4, 3, 2, 1};
+            var expected = new byte[] {0, 5, 4, 3, 2, 1, 0, 0};
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestRead(_handle, (ulong)_fileAttributes.Size, _readBufferSize)).Returns(data);
+
+            var actual = _target.Read(buffer, 1, data.Length);
+
+            Assert.AreEqual(data.Length, actual);
+            Assert.IsTrue(buffer.IsEqualTo(expected));
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestRead(_handle, (ulong)_fileAttributes.Size, _readBufferSize), Times.Once);
+        }
+
+        [TestMethod]
+        public void ReadByteShouldStartReadingAtEndOfFile()
+        {
+            var data = GenerateRandom(5, _random);
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestRead(_handle, (ulong) _fileAttributes.Size, _readBufferSize)).Returns(data);
+
+            var actual = _target.ReadByte();
+
+            Assert.AreEqual(data[0], actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestRead(_handle, (ulong) _fileAttributes.Size, _readBufferSize), Times.Once);
+        }
+
+        [TestMethod]
+        public void WriteShouldStartWritingAtEndOfFile()
+        {
+            var buffer = new byte[_writeBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestWrite(_handle, (ulong) _fileAttributes.Size, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null));
+
+            _target.Write(buffer, 0, buffer.Length);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestWrite(_handle, (ulong) _fileAttributes.Size, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null), Times.Once);
+        }
+
+        [TestMethod]
+        public void RequestOpenOnSftpSessionShouldBeInvokedOnce()
+        {
+            SftpSessionMock.Verify(p => p.RequestOpen(_path, Flags.Read | Flags.Write | Flags.Append, false), Times.Once);
+        }
+
+        [TestMethod]
+        public void RequestFStatOnSftpSessionShouldBeInvokedOnce()
+        {
+            SftpSessionMock.Verify(p => p.RequestFStat(_handle, false), Times.Once);
+        }
+    }
+}

+ 169 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeAppend_FileAccessWrite.cs

@@ -0,0 +1,169 @@
+using System;
+using System.IO;
+using System.Threading;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Sftp;
+using Renci.SshNet.Tests.Common;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpFileStreamTest_Ctor_FileModeAppend_FileAccessWrite : SftpFileStreamTestBase
+    {
+        private Random _random;
+        private string _path;
+        private FileMode _fileMode;
+        private FileAccess _fileAccess;
+        private int _bufferSize;
+        private uint _readBufferSize;
+        private uint _writeBufferSize;
+        private byte[] _handle;
+        private SftpFileStream _target;
+        private SftpFileAttributes _fileAttributes;
+
+        protected override void SetupData()
+        {
+            base.SetupData();
+
+            _random = new Random();
+            _path = _random.Next().ToString();
+            _fileMode = FileMode.Append;
+            _fileAccess = FileAccess.Write;
+            _bufferSize = _random.Next(5, 1000);
+            _readBufferSize = (uint) _random.Next(5, 1000);
+            _writeBufferSize = (uint) _random.Next(5, 1000);
+            _handle = GenerateRandom(_random.Next(1, 10), _random);
+            _fileAttributes = new SftpFileAttributesBuilder().WithLastAccessTime(DateTime.Now.AddSeconds(_random.Next()))
+                                                             .WithLastWriteTime(DateTime.Now.AddSeconds(_random.Next()))
+                                                             .WithSize(_random.Next())
+                                                             .WithUserId(_random.Next())
+                                                             .WithGroupId(_random.Next())
+                                                             .WithPermissions((uint) _random.Next())
+                                                             .Build();
+        }
+
+        protected override void SetupMocks()
+        {
+            SftpSessionMock.InSequence(MockSequence)
+                            .Setup(p => p.RequestOpen(_path, Flags.Write | Flags.Append, false))
+                            .Returns(_handle);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalReadLength((uint) _bufferSize))
+                           .Returns(_readBufferSize);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalWriteLength((uint) _bufferSize, _handle))
+                           .Returns(_writeBufferSize);
+            SftpSessionMock.InSequence(MockSequence)
+                            .Setup(p => p.RequestFStat(_handle, false))
+                            .Returns(_fileAttributes);
+        }
+
+        protected override void Act()
+        {
+            _target = new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
+        }
+
+        [TestMethod]
+        public void CanReadShouldReturnFalse()
+        {
+            Assert.IsFalse(_target.CanRead);
+        }
+
+        [TestMethod]
+        public void CanSeekShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanSeek);
+        }
+
+        [TestMethod]
+        public void CanWriteShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanWrite);
+        }
+
+        [TestMethod]
+        public void CanTimeoutShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanTimeout);
+        }
+
+        [TestMethod]
+        public void PositionShouldReturnSizeOfFile()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            var actual = _target.Position;
+
+            Assert.AreEqual(_fileAttributes.Size, actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadShouldThrowNotSupportedException()
+        {
+            var buffer = new byte[_readBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            try
+            {
+                _target.Read(buffer, 0, buffer.Length);
+                Assert.Fail();
+            }
+            catch (NotSupportedException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("Read not supported.", ex.Message);
+            }
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadByteShouldThrowNotSupportedException()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            try
+            {
+                _target.ReadByte();
+                Assert.Fail();
+            }
+            catch (NotSupportedException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("Read not supported.", ex.Message);
+            }
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void WriteShouldStartWritingAtEndOfFile()
+        {
+            var buffer = new byte[_writeBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestWrite(_handle, (ulong) _fileAttributes.Size, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null));
+
+            _target.Write(buffer, 0, buffer.Length);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestWrite(_handle, (ulong)_fileAttributes.Size, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null), Times.Once);
+        }
+
+        [TestMethod]
+        public void RequestOpenOnSftpSessionShouldBeInvokedOnce()
+        {
+            SftpSessionMock.Verify(p => p.RequestOpen(_path, Flags.Write | Flags.Append, false), Times.Once);
+        }
+
+        [TestMethod]
+        public void RequestFStatOnSftpSessionShouldBeInvokedOnce()
+        {
+            SftpSessionMock.Verify(p => p.RequestFStat(_handle, false), Times.Once);
+        }
+    }
+}

+ 55 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeCreateNew_FileAccessRead.cs

@@ -0,0 +1,55 @@
+using System;
+using System.IO;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpFileStreamTest_Ctor_FileModeCreateNew_FileAccessRead : SftpFileStreamTestBase
+    {
+        private Random _random;
+        private string _path;
+        private FileMode _fileMode;
+        private FileAccess _fileAccess;
+        private int _bufferSize;
+        private ArgumentException _actualException;
+
+        protected override void SetupData()
+        {
+            base.SetupData();
+
+            _random = new Random();
+            _path = _random.Next().ToString();
+            _fileMode = FileMode.CreateNew;
+            _fileAccess = FileAccess.Read;
+            _bufferSize = _random.Next(5, 1000);
+        }
+
+        protected override void SetupMocks()
+        {
+        }
+
+        protected override void Act()
+        {
+            try
+            {
+                new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
+                Assert.Fail();
+            }
+            catch (ArgumentException ex)
+            {
+                _actualException = ex;
+            }
+        }
+
+        [TestMethod]
+        public void CtorShouldHaveThrownArgumentException()
+        {
+            Assert.IsNotNull(_actualException);
+            Assert.IsNull(_actualException.InnerException);
+            Assert.AreEqual($"Combining {nameof(FileMode)}: {_fileMode} with {nameof(FileAccess)}: {_fileAccess} is invalid.", _actualException.Message);
+            Assert.IsNull(_actualException.ParamName);
+        }
+    }
+}

+ 147 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeCreateNew_FileAccessReadWrite.cs

@@ -0,0 +1,147 @@
+using System;
+using System.IO;
+using System.Threading;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpFileStreamTest_Ctor_FileModeCreateNew_FileAccessReadWrite : SftpFileStreamTestBase
+    {
+        private Random _random;
+        private string _path;
+        private FileMode _fileMode;
+        private FileAccess _fileAccess;
+        private int _bufferSize;
+        private uint _readBufferSize;
+        private uint _writeBufferSize;
+        private byte[] _handle;
+        private SftpFileStream _target;
+
+        protected override void SetupData()
+        {
+            base.SetupData();
+
+            _random = new Random();
+            _path = _random.Next().ToString();
+            _fileMode = FileMode.CreateNew;
+            _fileAccess = FileAccess.ReadWrite;
+            _bufferSize = _random.Next(5, 1000);
+            _readBufferSize = (uint)_random.Next(5, 1000);
+            _writeBufferSize = (uint)_random.Next(5, 1000);
+            _handle = GenerateRandom(_random.Next(1, 10), _random);
+        }
+
+        protected override void SetupMocks()
+        {
+            SftpSessionMock.InSequence(MockSequence)
+                            .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Write | Flags.CreateNew, false))
+                            .Returns(_handle);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalReadLength((uint)_bufferSize))
+                           .Returns(_readBufferSize);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalWriteLength((uint)_bufferSize, _handle))
+                           .Returns(_writeBufferSize);
+        }
+
+        protected override void Act()
+        {
+            _target = new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
+        }
+
+        [TestMethod]
+        public void CanReadShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanRead);
+        }
+
+        [TestMethod]
+        public void CanSeekShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanSeek);
+        }
+
+        [TestMethod]
+        public void CanWriteShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanWrite);
+        }
+
+        [TestMethod]
+        public void CanTimeoutShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanTimeout);
+        }
+
+        [TestMethod]
+        public void PositionShouldReturnZero()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            var actual = _target.Position;
+
+            Assert.AreEqual(0L, actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadShouldStartReadingAtBeginningOfFile()
+        {
+            var buffer = new byte[8];
+            var data = new byte[] { 5, 4, 3, 2, 1 };
+            var expected = new byte[] { 0, 5, 4, 3, 2, 1, 0, 0 };
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestRead(_handle, 0UL, _readBufferSize)).Returns(data);
+
+            var actual = _target.Read(buffer, 1, data.Length);
+
+            Assert.AreEqual(data.Length, actual);
+            Assert.IsTrue(buffer.IsEqualTo(expected));
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestRead(_handle, 0UL, _readBufferSize), Times.Once);
+        }
+
+        [TestMethod]
+        public void ReadByteShouldStartReadingAtBeginningOfFile()
+        {
+            var data = GenerateRandom(5, _random);
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestRead(_handle, 0UL, _readBufferSize))
+                .Returns(data);
+
+            var actual = _target.ReadByte();
+
+            Assert.AreEqual(data[0], actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestRead(_handle, 0UL, _readBufferSize), Times.Once);
+        }
+
+        [TestMethod]
+        public void WriteShouldStartWritingAtBeginningOfFile()
+        {
+            var buffer = new byte[_writeBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null));
+
+            _target.Write(buffer, 0, buffer.Length);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null), Times.Once);
+        }
+
+        [TestMethod]
+        public void RequestOpenOnSftpSessionShouldBeInvokedOnce()
+        {
+            SftpSessionMock.Verify(p => p.RequestOpen(_path, Flags.Read | Flags.Write | Flags.CreateNew, false), Times.Once);
+        }
+    }
+}

+ 151 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeCreateNew_FileAccessWrite.cs

@@ -0,0 +1,151 @@
+using System;
+using System.IO;
+using System.Threading;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpFileStreamTest_Ctor_FileModeCreateNew_FileAccessWrite : SftpFileStreamTestBase
+    {
+        private Random _random;
+        private string _path;
+        private FileMode _fileMode;
+        private FileAccess _fileAccess;
+        private int _bufferSize;
+        private uint _readBufferSize;
+        private uint _writeBufferSize;
+        private byte[] _handle;
+        private SftpFileStream _target;
+
+        protected override void SetupData()
+        {
+            base.SetupData();
+
+            _random = new Random();
+            _path = _random.Next().ToString();
+            _fileMode = FileMode.CreateNew;
+            _fileAccess = FileAccess.Write;
+            _bufferSize = _random.Next(5, 1000);
+            _readBufferSize = (uint) _random.Next(5, 1000);
+            _writeBufferSize = (uint) _random.Next(5, 1000);
+            _handle = GenerateRandom(_random.Next(1, 10), _random);
+        }
+
+        protected override void SetupMocks()
+        {
+            SftpSessionMock.InSequence(MockSequence)
+                            .Setup(p => p.RequestOpen(_path, Flags.Write | Flags.CreateNew, false))
+                            .Returns(_handle);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalReadLength((uint) _bufferSize))
+                           .Returns(_readBufferSize);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalWriteLength((uint) _bufferSize, _handle))
+                           .Returns(_writeBufferSize);
+        }
+
+        protected override void Act()
+        {
+            _target = new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
+        }
+
+        [TestMethod]
+        public void CanReadShouldReturnFalse()
+        {
+            Assert.IsFalse(_target.CanRead);
+        }
+
+        [TestMethod]
+        public void CanSeekShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanSeek);
+        }
+
+        [TestMethod]
+        public void CanWriteShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanWrite);
+        }
+
+        [TestMethod]
+        public void CanTimeoutShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanTimeout);
+        }
+
+        [TestMethod]
+        public void PositionShouldReturnZero()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            var actual = _target.Position;
+
+            Assert.AreEqual(0L, actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadShouldThrowNotSupportedException()
+        {
+            var buffer = new byte[_readBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            try
+            {
+                _target.Read(buffer, 0, buffer.Length);
+                Assert.Fail();
+            }
+            catch (NotSupportedException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("Read not supported.", ex.Message);
+            }
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadByteShouldThrowNotSupportedException()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            try
+            {
+                _target.ReadByte();
+                Assert.Fail();
+            }
+            catch (NotSupportedException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("Read not supported.", ex.Message);
+            }
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void WriteShouldStartWritingAtBeginningOfFile()
+        {
+            var buffer = new byte[_writeBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null));
+
+            _target.Write(buffer, 0, buffer.Length);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null), Times.Once);
+        }
+
+        [TestMethod]
+        public void RequestOpenOnSftpSessionShouldBeInvokedOnce()
+        {
+            SftpSessionMock.Verify(p => p.RequestOpen(_path, Flags.Write | Flags.CreateNew, false), Times.Once);
+        }
+    }
+}

+ 55 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeCreate_FileAccessRead.cs

@@ -0,0 +1,55 @@
+using System;
+using System.IO;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpFileStreamTest_Ctor_FileModeCreate_FileAccessRead : SftpFileStreamTestBase
+    {
+        private Random _random;
+        private string _path;
+        private FileMode _fileMode;
+        private FileAccess _fileAccess;
+        private int _bufferSize;
+        private ArgumentException _actualException;
+
+        protected override void SetupData()
+        {
+            base.SetupData();
+
+            _random = new Random();
+            _path = _random.Next().ToString();
+            _fileMode = FileMode.Create;
+            _fileAccess = FileAccess.Read;
+            _bufferSize = _random.Next(5, 1000);
+        }
+
+        protected override void SetupMocks()
+        {
+        }
+
+        protected override void Act()
+        {
+            try
+            {
+                new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
+                Assert.Fail();
+            }
+            catch (ArgumentException ex)
+            {
+                _actualException = ex;
+            }
+        }
+
+        [TestMethod]
+        public void CtorShouldHaveThrownArgumentException()
+        {
+            Assert.IsNotNull(_actualException);
+            Assert.IsNull(_actualException.InnerException);
+            Assert.AreEqual($"Combining {nameof(FileMode)}: {_fileMode} with {nameof(FileAccess)}: {_fileAccess} is invalid.", _actualException.Message);
+            Assert.IsNull(_actualException.ParamName);
+        }
+    }
+}

+ 150 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeCreate_FileAccessReadWrite_FileDoesNotExist.cs

@@ -0,0 +1,150 @@
+using System;
+using System.IO;
+using System.Threading;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpFileStreamTest_Ctor_FileModeCreate_FileAccessReadWrite_FileDoesNotExist : SftpFileStreamTestBase
+    {
+        private Random _random;
+        private string _path;
+        private FileMode _fileMode;
+        private FileAccess _fileAccess;
+        private int _bufferSize;
+        private uint _readBufferSize;
+        private uint _writeBufferSize;
+        private byte[] _handle;
+        private SftpFileStream _target;
+
+        protected override void SetupData()
+        {
+            base.SetupData();
+
+            _random = new Random();
+            _path = _random.Next().ToString();
+            _fileMode = FileMode.Create;
+            _fileAccess = FileAccess.ReadWrite;
+            _bufferSize = _random.Next(5, 1000);
+            _readBufferSize = (uint)_random.Next(5, 1000);
+            _writeBufferSize = (uint)_random.Next(5, 1000);
+            _handle = GenerateRandom(_random.Next(1, 10), _random);
+        }
+
+        protected override void SetupMocks()
+        {
+            SftpSessionMock.InSequence(MockSequence)
+                            .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Write | Flags.Truncate, true))
+                            .Returns((byte[]) null);
+            SftpSessionMock.InSequence(MockSequence)
+                            .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Write | Flags.CreateNew, false))
+                            .Returns(_handle);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalReadLength((uint)_bufferSize))
+                           .Returns(_readBufferSize);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalWriteLength((uint)_bufferSize, _handle))
+                           .Returns(_writeBufferSize);
+        }
+
+        protected override void Act()
+        {
+            _target = new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
+        }
+
+        [TestMethod]
+        public void CanReadShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanRead);
+        }
+
+        [TestMethod]
+        public void CanSeekShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanSeek);
+        }
+
+        [TestMethod]
+        public void CanWriteShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanWrite);
+        }
+
+        [TestMethod]
+        public void CanTimeoutShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanTimeout);
+        }
+
+        [TestMethod]
+        public void PositionShouldReturnZero()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            var actual = _target.Position;
+
+            Assert.AreEqual(0L, actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadShouldStartReadingAtBeginningOfFile()
+        {
+            var buffer = new byte[8];
+            var data = new byte[] { 5, 4, 3, 2, 1 };
+            var expected = new byte[] { 0, 5, 4, 3, 2, 1, 0, 0 };
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestRead(_handle, 0UL, _readBufferSize)).Returns(data);
+
+            var actual = _target.Read(buffer, 1, data.Length);
+
+            Assert.AreEqual(data.Length, actual);
+            Assert.IsTrue(buffer.IsEqualTo(expected));
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestRead(_handle, 0UL, _readBufferSize), Times.Once);
+        }
+
+        [TestMethod]
+        public void ReadByteShouldStartReadingAtBeginningOfFile()
+        {
+            var data = GenerateRandom(5, _random);
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestRead(_handle, 0UL, _readBufferSize))
+                .Returns(data);
+
+            var actual = _target.ReadByte();
+
+            Assert.AreEqual(data[0], actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestRead(_handle, 0UL, _readBufferSize), Times.Once);
+        }
+
+        [TestMethod]
+        public void WriteShouldStartWritingAtBeginningOfFile()
+        {
+            var buffer = new byte[_writeBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null));
+
+            _target.Write(buffer, 0, buffer.Length);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null), Times.Once);
+        }
+
+        [TestMethod]
+        public void RequestOpenOnSftpSessionShouldBeInvokedOnce()
+        {
+            SftpSessionMock.Verify(p => p.RequestOpen(_path, Flags.Read | Flags.Write | Flags.Truncate, true), Times.Once);
+        }
+    }
+}

+ 147 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeCreate_FileAccessReadWrite_FileExists.cs

@@ -0,0 +1,147 @@
+using System;
+using System.IO;
+using System.Threading;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpFileStreamTest_Ctor_FileModeCreate_FileAccessReadWrite_FileExists : SftpFileStreamTestBase
+    {
+        private Random _random;
+        private string _path;
+        private FileMode _fileMode;
+        private FileAccess _fileAccess;
+        private int _bufferSize;
+        private uint _readBufferSize;
+        private uint _writeBufferSize;
+        private byte[] _handle;
+        private SftpFileStream _target;
+
+        protected override void SetupData()
+        {
+            base.SetupData();
+
+            _random = new Random();
+            _path = _random.Next().ToString();
+            _fileMode = FileMode.Create;
+            _fileAccess = FileAccess.ReadWrite;
+            _bufferSize = _random.Next(5, 1000);
+            _readBufferSize = (uint)_random.Next(5, 1000);
+            _writeBufferSize = (uint)_random.Next(5, 1000);
+            _handle = GenerateRandom(_random.Next(1, 10), _random);
+        }
+
+        protected override void SetupMocks()
+        {
+            SftpSessionMock.InSequence(MockSequence)
+                            .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Write | Flags.Truncate, true))
+                            .Returns(_handle);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalReadLength((uint)_bufferSize))
+                           .Returns(_readBufferSize);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalWriteLength((uint)_bufferSize, _handle))
+                           .Returns(_writeBufferSize);
+        }
+
+        protected override void Act()
+        {
+            _target = new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
+        }
+
+        [TestMethod]
+        public void CanReadShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanRead);
+        }
+
+        [TestMethod]
+        public void CanSeekShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanSeek);
+        }
+
+        [TestMethod]
+        public void CanWriteShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanWrite);
+        }
+
+        [TestMethod]
+        public void CanTimeoutShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanTimeout);
+        }
+
+        [TestMethod]
+        public void PositionShouldReturnZero()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            var actual = _target.Position;
+
+            Assert.AreEqual(0L, actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadShouldStartReadingAtBeginningOfFile()
+        {
+            var buffer = new byte[8];
+            var data = new byte[] { 5, 4, 3, 2, 1 };
+            var expected = new byte[] { 0, 5, 4, 3, 2, 1, 0, 0 };
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestRead(_handle, 0UL, _readBufferSize)).Returns(data);
+
+            var actual = _target.Read(buffer, 1, data.Length);
+
+            Assert.AreEqual(data.Length, actual);
+            Assert.IsTrue(buffer.IsEqualTo(expected));
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestRead(_handle, 0UL, _readBufferSize), Times.Once);
+        }
+
+        [TestMethod]
+        public void ReadByteShouldStartReadingAtBeginningOfFile()
+        {
+            var data = GenerateRandom(5, _random);
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestRead(_handle, 0UL, _readBufferSize))
+                .Returns(data);
+
+            var actual = _target.ReadByte();
+
+            Assert.AreEqual(data[0], actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestRead(_handle, 0UL, _readBufferSize), Times.Once);
+        }
+
+        [TestMethod]
+        public void WriteShouldStartWritingAtBeginningOfFile()
+        {
+            var buffer = new byte[_writeBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null));
+
+            _target.Write(buffer, 0, buffer.Length);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null), Times.Once);
+        }
+
+        [TestMethod]
+        public void RequestOpenOnSftpSessionShouldBeInvokedOnce()
+        {
+            SftpSessionMock.Verify(p => p.RequestOpen(_path, Flags.Read | Flags.Write | Flags.Truncate, true), Times.Once);
+        }
+    }
+}

+ 155 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeCreate_FileAccessWrite_FileDoesNotExist.cs

@@ -0,0 +1,155 @@
+using System;
+using System.IO;
+using System.Threading;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpFileStreamTest_Ctor_FileModeCreate_FileAccessWrite_FileDoesNotExist : SftpFileStreamTestBase
+    {
+        private Random _random;
+        private string _path;
+        private FileMode _fileMode;
+        private FileAccess _fileAccess;
+        private int _bufferSize;
+        private uint _readBufferSize;
+        private uint _writeBufferSize;
+        private byte[] _handle;
+        private SftpFileStream _target;
+
+        protected override void SetupData()
+        {
+            base.SetupData();
+
+            _random = new Random();
+            _path = _random.Next().ToString();
+            _fileMode = FileMode.Create;
+            _fileAccess = FileAccess.Write;
+            _bufferSize = _random.Next(5, 1000);
+            _readBufferSize = (uint)_random.Next(5, 1000);
+            _writeBufferSize = (uint)_random.Next(5, 1000);
+            _handle = GenerateRandom(_random.Next(1, 10), _random);
+        }
+
+        protected override void SetupMocks()
+        {
+            SftpSessionMock.InSequence(MockSequence)
+                            .Setup(p => p.RequestOpen(_path, Flags.Write | Flags.Truncate, true))
+                            .Returns((byte[])null);
+            SftpSessionMock.InSequence(MockSequence)
+                            .Setup(p => p.RequestOpen(_path, Flags.Write | Flags.CreateNew, false))
+                            .Returns(_handle);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalReadLength((uint)_bufferSize))
+                           .Returns(_readBufferSize);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalWriteLength((uint)_bufferSize, _handle))
+                           .Returns(_writeBufferSize);
+        }
+
+        protected override void Act()
+        {
+            _target = new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
+        }
+
+        [TestMethod]
+        public void CanReadShouldReturnFalse()
+        {
+            Assert.IsFalse(_target.CanRead);
+        }
+
+        [TestMethod]
+        public void CanSeekShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanSeek);
+        }
+
+        [TestMethod]
+        public void CanWriteShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanWrite);
+        }
+
+        [TestMethod]
+        public void CanTimeoutShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanTimeout);
+        }
+
+        [TestMethod]
+        public void PositionShouldReturnZero()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            var actual = _target.Position;
+
+            Assert.AreEqual(0L, actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadShouldThrowNotSupportedException()
+        {
+            var buffer = new byte[_readBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            try
+            {
+                _target.Read(buffer, 0, buffer.Length);
+                Assert.Fail();
+            }
+            catch (NotSupportedException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("Read not supported.", ex.Message);
+            }
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadByteShouldThrowNotSupportedException()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            try
+            {
+                _target.ReadByte();
+                Assert.Fail();
+            }
+            catch (NotSupportedException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("Read not supported.", ex.Message);
+            }
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void WriteShouldStartWritingAtBeginningOfFile()
+        {
+            var buffer = new byte[_writeBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null));
+
+            _target.Write(buffer, 0, buffer.Length);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null), Times.Once);
+        }
+
+        [TestMethod]
+        public void RequestOpenOnSftpSessionShouldBeInvokedOnceWithTruncateAndOnceWithCreateNew()
+        {
+            SftpSessionMock.Verify(p => p.RequestOpen(_path, Flags.Write | Flags.Truncate, true), Times.Once);
+            SftpSessionMock.Verify(p => p.RequestOpen(_path, Flags.Write | Flags.CreateNew, false), Times.Once);
+        }
+    }
+}

+ 151 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeCreate_FileAccessWrite_FileExists.cs

@@ -0,0 +1,151 @@
+using System;
+using System.IO;
+using System.Threading;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpFileStreamTest_Ctor_FileModeCreate_FileAccessWrite_FileExists : SftpFileStreamTestBase
+    {
+        private Random _random;
+        private string _path;
+        private FileMode _fileMode;
+        private FileAccess _fileAccess;
+        private int _bufferSize;
+        private uint _readBufferSize;
+        private uint _writeBufferSize;
+        private byte[] _handle;
+        private SftpFileStream _target;
+
+        protected override void SetupData()
+        {
+            base.SetupData();
+
+            _random = new Random();
+            _path = _random.Next().ToString();
+            _fileMode = FileMode.Create;
+            _fileAccess = FileAccess.Write;
+            _bufferSize = _random.Next(5, 1000);
+            _readBufferSize = (uint) _random.Next(5, 1000);
+            _writeBufferSize = (uint) _random.Next(5, 1000);
+            _handle = GenerateRandom(_random.Next(1, 10), _random);
+        }
+
+        protected override void SetupMocks()
+        {
+            SftpSessionMock.InSequence(MockSequence)
+                            .Setup(p => p.RequestOpen(_path, Flags.Write | Flags.Truncate, true))
+                            .Returns(_handle);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalReadLength((uint) _bufferSize))
+                           .Returns(_readBufferSize);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalWriteLength((uint) _bufferSize, _handle))
+                           .Returns(_writeBufferSize);
+        }
+
+        protected override void Act()
+        {
+            _target = new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
+        }
+
+        [TestMethod]
+        public void CanReadShouldReturnFalse()
+        {
+            Assert.IsFalse(_target.CanRead);
+        }
+
+        [TestMethod]
+        public void CanSeekShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanSeek);
+        }
+
+        [TestMethod]
+        public void CanWriteShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanWrite);
+        }
+
+        [TestMethod]
+        public void CanTimeoutShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanTimeout);
+        }
+
+        [TestMethod]
+        public void PositionShouldReturnZero()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            var actual = _target.Position;
+
+            Assert.AreEqual(0L, actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadShouldThrowNotSupportedException()
+        {
+            var buffer = new byte[_readBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            try
+            {
+                _target.Read(buffer, 0, buffer.Length);
+                Assert.Fail();
+            }
+            catch (NotSupportedException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("Read not supported.", ex.Message);
+            }
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadByteShouldThrowNotSupportedException()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            try
+            {
+                _target.ReadByte();
+                Assert.Fail();
+            }
+            catch (NotSupportedException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("Read not supported.", ex.Message);
+            }
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void WriteShouldStartWritingAtBeginningOfFile()
+        {
+            var buffer = new byte[_writeBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null));
+
+            _target.Write(buffer, 0, buffer.Length);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null), Times.Once);
+        }
+
+        [TestMethod]
+        public void RequestOpenOnSftpSessionShouldBeInvokedOnce()
+        {
+            SftpSessionMock.Verify(p => p.RequestOpen(_path, Flags.Write | Flags.Truncate, true), Times.Once);
+        }
+    }
+}

+ 54 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeInvalid.cs

@@ -0,0 +1,54 @@
+using System;
+using System.IO;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpFileStreamTest_Ctor_FileModeInvalid : SftpFileStreamTestBase
+    {
+        private Random _random;
+        private string _path;
+        private FileMode _fileMode;
+        private FileAccess _fileAccess;
+        private int _bufferSize;
+        private ArgumentOutOfRangeException _actualException;
+
+        protected override void SetupData()
+        {
+            base.SetupData();
+
+            _random = new Random();
+            _path = _random.Next().ToString();
+            _fileMode = 0;
+            _fileAccess = FileAccess.Read;
+            _bufferSize = _random.Next(5, 1000);
+        }
+
+        protected override void SetupMocks()
+        {
+        }
+
+        protected override void Act()
+        {
+            try
+            {
+                new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
+                Assert.Fail();
+            }
+            catch (ArgumentOutOfRangeException ex)
+            {
+                _actualException = ex;
+            }
+        }
+
+        [TestMethod]
+        public void CtorShouldHaveThrownArgumentException()
+        {
+            Assert.IsNotNull(_actualException);
+            Assert.IsNull(_actualException.InnerException);
+            Assert.AreEqual("mode", _actualException.ParamName);
+        }
+    }
+}

+ 170 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeOpenOrCreate_FileAccessRead.cs

@@ -0,0 +1,170 @@
+using System;
+using System.IO;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpFileStreamTest_Ctor_FileModeOpenOrCreate_FileAccessRead : SftpFileStreamTestBase
+    {
+        private Random _random;
+        private string _path;
+        private FileMode _fileMode;
+        private FileAccess _fileAccess;
+        private int _bufferSize;
+        private uint _readBufferSize;
+        private uint _writeBufferSize;
+        private byte[] _handle;
+        private SftpFileStream _target;
+
+        protected override void SetupData()
+        {
+            base.SetupData();
+
+            _random = new Random();
+            _path = _random.Next().ToString();
+            _fileMode = FileMode.OpenOrCreate;
+            _fileAccess = FileAccess.Read;
+            _bufferSize = _random.Next(5, 1000);
+            _readBufferSize = (uint) _random.Next(5, 1000);
+            _writeBufferSize = (uint) _random.Next(5, 1000);
+            _handle = GenerateRandom(_random.Next(1, 10), _random);
+        }
+
+        protected override void SetupMocks()
+        {
+            SftpSessionMock.InSequence(MockSequence)
+                            .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.CreateNewOrOpen, false))
+                            .Returns(_handle);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalReadLength((uint) _bufferSize))
+                           .Returns(_readBufferSize);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalWriteLength((uint) _bufferSize, _handle))
+                           .Returns(_writeBufferSize);
+        }
+
+        protected override void Act()
+        {
+            _target = new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
+        }
+
+        [TestMethod]
+        public void CanReadShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanRead);
+        }
+
+        [TestMethod]
+        public void CanSeekShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanSeek);
+        }
+
+        [TestMethod]
+        public void CanWriteShouldReturnFalse()
+        {
+            Assert.IsFalse(_target.CanWrite);
+        }
+
+        [TestMethod]
+        public void CanTimeoutShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanTimeout);
+        }
+
+        [TestMethod]
+        public void PositionShouldReturnZero()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            var actual = _target.Position;
+
+            Assert.AreEqual(0L, actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadShouldStartReadingAtBeginningOfFile()
+        {
+            var buffer = new byte[8];
+            var data = new byte[] { 5, 4, 3, 2, 1 };
+            var expected = new byte[] { 0, 5, 4, 3, 2, 1, 0, 0 };
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestRead(_handle, 0UL, _readBufferSize)).Returns(data);
+
+            var actual = _target.Read(buffer, 1, data.Length);
+
+            Assert.AreEqual(data.Length, actual);
+            Assert.IsTrue(buffer.IsEqualTo(expected));
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestRead(_handle, 0UL, _readBufferSize), Times.Once);
+        }
+
+        [TestMethod]
+        public void ReadByteShouldStartReadingAtBeginningOfFile()
+        {
+            var data = GenerateRandom(5, _random);
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestRead(_handle, 0UL, _readBufferSize))
+                .Returns(data);
+
+            var actual = _target.ReadByte();
+
+            Assert.AreEqual(data[0], actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestRead(_handle, 0UL, _readBufferSize), Times.Once);
+        }
+
+        [TestMethod]
+        public void WriteShouldThrowNotSupportedException()
+        {
+            var buffer = new byte[_writeBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            try
+            {
+                _target.Write(buffer, 0, buffer.Length);
+            }
+            catch (NotSupportedException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("Write not supported.", ex.Message);
+            }
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void WriteByteShouldThrowNotSupportedException()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            try
+            {
+                _target.WriteByte(0x0a);
+            }
+            catch (NotSupportedException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("Write not supported.", ex.Message);
+            }
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void RequestOpenOnSftpSessionShouldBeInvokedOnce()
+        {
+            SftpSessionMock.Verify(p => p.RequestOpen(_path, Flags.Read | Flags.CreateNewOrOpen, false), Times.Once);
+        }
+    }
+}

+ 147 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeOpenOrCreate_FileAccessReadWrite.cs

@@ -0,0 +1,147 @@
+using System;
+using System.IO;
+using System.Threading;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpFileStreamTest_Ctor_FileModeOpenOrCreate_FileAccessReadWrite : SftpFileStreamTestBase
+    {
+        private Random _random;
+        private string _path;
+        private FileMode _fileMode;
+        private FileAccess _fileAccess;
+        private int _bufferSize;
+        private uint _readBufferSize;
+        private uint _writeBufferSize;
+        private byte[] _handle;
+        private SftpFileStream _target;
+
+        protected override void SetupData()
+        {
+            base.SetupData();
+
+            _random = new Random();
+            _path = _random.Next().ToString();
+            _fileMode = FileMode.OpenOrCreate;
+            _fileAccess = FileAccess.ReadWrite;
+            _bufferSize = _random.Next(5, 1000);
+            _readBufferSize = (uint)_random.Next(5, 1000);
+            _writeBufferSize = (uint)_random.Next(5, 1000);
+            _handle = GenerateRandom(_random.Next(1, 10), _random);
+        }
+
+        protected override void SetupMocks()
+        {
+            SftpSessionMock.InSequence(MockSequence)
+                            .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Write | Flags.CreateNewOrOpen, false))
+                            .Returns(_handle);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalReadLength((uint) _bufferSize))
+                           .Returns(_readBufferSize);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalWriteLength((uint) _bufferSize, _handle))
+                           .Returns(_writeBufferSize);
+        }
+
+        protected override void Act()
+        {
+            _target = new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
+        }
+
+        [TestMethod]
+        public void CanReadShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanRead);
+        }
+
+        [TestMethod]
+        public void CanSeekShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanSeek);
+        }
+
+        [TestMethod]
+        public void CanWriteShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanWrite);
+        }
+
+        [TestMethod]
+        public void CanTimeoutShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanTimeout);
+        }
+
+        [TestMethod]
+        public void PositionShouldReturnZero()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            var actual = _target.Position;
+
+            Assert.AreEqual(0L, actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadShouldStartReadingAtBeginningOfFile()
+        {
+            var buffer = new byte[8];
+            var data = new byte[] { 5, 4, 3, 2, 1 };
+            var expected = new byte[] { 0, 5, 4, 3, 2, 1, 0, 0 };
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestRead(_handle, 0UL, _readBufferSize)).Returns(data);
+
+            var actual = _target.Read(buffer, 1, data.Length);
+
+            Assert.AreEqual(data.Length, actual);
+            Assert.IsTrue(buffer.IsEqualTo(expected));
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestRead(_handle, 0UL, _readBufferSize), Times.Once);
+        }
+
+        [TestMethod]
+        public void ReadByteShouldStartReadingAtBeginningOfFile()
+        {
+            var data = GenerateRandom(5, _random);
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestRead(_handle, 0UL, _readBufferSize))
+                .Returns(data);
+
+            var actual = _target.ReadByte();
+
+            Assert.AreEqual(data[0], actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestRead(_handle, 0UL, _readBufferSize), Times.Once);
+        }
+
+        [TestMethod]
+        public void WriteShouldStartWritingAtBeginningOfFile()
+        {
+            var buffer = new byte[_writeBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null));
+
+            _target.Write(buffer, 0, buffer.Length);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null), Times.Once);
+        }
+
+        [TestMethod]
+        public void RequestOpenOnSftpSessionShouldBeInvokedOnce()
+        {
+            SftpSessionMock.Verify(p => p.RequestOpen(_path, Flags.Read | Flags.Write | Flags.CreateNewOrOpen, false), Times.Once);
+        }
+    }
+}

+ 151 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeOpenOrCreate_FileAccessWrite.cs

@@ -0,0 +1,151 @@
+using System;
+using System.IO;
+using System.Threading;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpFileStreamTest_Ctor_FileModeOpenOrCreate_FileAccessWrite : SftpFileStreamTestBase
+    {
+        private Random _random;
+        private string _path;
+        private FileMode _fileMode;
+        private FileAccess _fileAccess;
+        private int _bufferSize;
+        private uint _readBufferSize;
+        private uint _writeBufferSize;
+        private byte[] _handle;
+        private SftpFileStream _target;
+
+        protected override void SetupData()
+        {
+            base.SetupData();
+
+            _random = new Random();
+            _path = _random.Next().ToString();
+            _fileMode = FileMode.OpenOrCreate;
+            _fileAccess = FileAccess.Write;
+            _bufferSize = _random.Next(5, 1000);
+            _readBufferSize = (uint) _random.Next(5, 1000);
+            _writeBufferSize = (uint) _random.Next(5, 1000);
+            _handle = GenerateRandom(_random.Next(1, 10), _random);
+        }
+
+        protected override void SetupMocks()
+        {
+            SftpSessionMock.InSequence(MockSequence)
+                            .Setup(p => p.RequestOpen(_path, Flags.Write | Flags.CreateNewOrOpen, false))
+                            .Returns(_handle);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalReadLength((uint)_bufferSize))
+                           .Returns(_readBufferSize);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalWriteLength((uint)_bufferSize, _handle))
+                           .Returns(_writeBufferSize);
+        }
+
+        protected override void Act()
+        {
+            _target = new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
+        }
+
+        [TestMethod]
+        public void CanReadShouldReturnFalse()
+        {
+            Assert.IsFalse(_target.CanRead);
+        }
+
+        [TestMethod]
+        public void CanSeekShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanSeek);
+        }
+
+        [TestMethod]
+        public void CanWriteShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanWrite);
+        }
+
+        [TestMethod]
+        public void CanTimeoutShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanTimeout);
+        }
+
+        [TestMethod]
+        public void PositionShouldReturnZero()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            var actual = _target.Position;
+
+            Assert.AreEqual(0L, actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadShouldThrowNotSupportedException()
+        {
+            var buffer = new byte[_readBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            try
+            {
+                _target.Read(buffer, 0, buffer.Length);
+                Assert.Fail();
+            }
+            catch (NotSupportedException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("Read not supported.", ex.Message);
+            }
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadByteShouldThrowNotSupportedException()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            try
+            {
+                _target.ReadByte();
+                Assert.Fail();
+            }
+            catch (NotSupportedException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("Read not supported.", ex.Message);
+            }
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void WriteShouldStartWritingAtBeginningOfFile()
+        {
+            var buffer = new byte[_writeBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null));
+
+            _target.Write(buffer, 0, buffer.Length);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null), Times.Once);
+        }
+
+        [TestMethod]
+        public void RequestOpenOnSftpSessionShouldBeInvokedOnce()
+        {
+            SftpSessionMock.Verify(p => p.RequestOpen(_path, Flags.Write | Flags.CreateNewOrOpen, false), Times.Once);
+        }
+    }
+}

+ 170 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeOpen_FileAccessRead.cs

@@ -0,0 +1,170 @@
+using System;
+using System.IO;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpFileStreamTest_Ctor_FileModeOpen_FileAccessRead : SftpFileStreamTestBase
+    {
+        private Random _random;
+        private string _path;
+        private FileMode _fileMode;
+        private FileAccess _fileAccess;
+        private int _bufferSize;
+        private uint _readBufferSize;
+        private uint _writeBufferSize;
+        private byte[] _handle;
+        private SftpFileStream _target;
+
+        protected override void SetupData()
+        {
+            base.SetupData();
+
+            _random = new Random();
+            _path = _random.Next().ToString();
+            _fileMode = FileMode.Open;
+            _fileAccess = FileAccess.Read;
+            _bufferSize = _random.Next(5, 1000);
+            _readBufferSize = (uint)_random.Next(5, 1000);
+            _writeBufferSize = (uint)_random.Next(5, 1000);
+            _handle = GenerateRandom(_random.Next(1, 10), _random);
+        }
+
+        protected override void SetupMocks()
+        {
+            SftpSessionMock.InSequence(MockSequence)
+                            .Setup(p => p.RequestOpen(_path, Flags.Read, false))
+                            .Returns(_handle);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalReadLength((uint)_bufferSize))
+                           .Returns(_readBufferSize);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalWriteLength((uint)_bufferSize, _handle))
+                           .Returns(_writeBufferSize);
+        }
+
+        protected override void Act()
+        {
+            _target = new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
+        }
+
+        [TestMethod]
+        public void CanReadShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanRead);
+        }
+
+        [TestMethod]
+        public void CanSeekShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanSeek);
+        }
+
+        [TestMethod]
+        public void CanWriteShouldReturnFalse()
+        {
+            Assert.IsFalse(_target.CanWrite);
+        }
+
+        [TestMethod]
+        public void CanTimeoutShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanTimeout);
+        }
+
+        [TestMethod]
+        public void PositionShouldReturnZero()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            var actual = _target.Position;
+
+            Assert.AreEqual(0L, actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadShouldStartReadingAtBeginningOfFile()
+        {
+            var buffer = new byte[8];
+            var data = new byte[] { 5, 4, 3, 2, 1 };
+            var expected = new byte[] { 0, 5, 4, 3, 2, 1, 0, 0 };
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestRead(_handle, 0UL, _readBufferSize)).Returns(data);
+
+            var actual = _target.Read(buffer, 1, data.Length);
+
+            Assert.AreEqual(data.Length, actual);
+            Assert.IsTrue(buffer.IsEqualTo(expected));
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestRead(_handle, 0UL, _readBufferSize), Times.Once);
+        }
+
+        [TestMethod]
+        public void ReadByteShouldStartReadingAtBeginningOfFile()
+        {
+            var data = GenerateRandom(5, _random);
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestRead(_handle, 0UL, _readBufferSize))
+                .Returns(data);
+
+            var actual = _target.ReadByte();
+
+            Assert.AreEqual(data[0], actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestRead(_handle, 0UL, _readBufferSize), Times.Once);
+        }
+
+        [TestMethod]
+        public void WriteShouldThrowNotSupportedException()
+        {
+            var buffer = new byte[_writeBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            try
+            {
+                _target.Write(buffer, 0, buffer.Length);
+            }
+            catch (NotSupportedException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("Write not supported.", ex.Message);
+            }
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void WriteByteShouldThrowNotSupportedException()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            try
+            {
+                _target.WriteByte(0x0a);
+            }
+            catch (NotSupportedException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("Write not supported.", ex.Message);
+            }
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void RequestOpenOnSftpSessionShouldBeInvokedOnce()
+        {
+            SftpSessionMock.Verify(p => p.RequestOpen(_path, Flags.Read, false), Times.Once);
+        }
+    }
+}

+ 147 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeOpen_FileAccessReadWrite.cs

@@ -0,0 +1,147 @@
+using System;
+using System.IO;
+using System.Threading;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpFileStreamTest_Ctor_FileModeOpen_FileAccessReadWrite : SftpFileStreamTestBase
+    {
+        private Random _random;
+        private string _path;
+        private FileMode _fileMode;
+        private FileAccess _fileAccess;
+        private int _bufferSize;
+        private uint _readBufferSize;
+        private uint _writeBufferSize;
+        private byte[] _handle;
+        private SftpFileStream _target;
+
+        protected override void SetupData()
+        {
+            base.SetupData();
+
+            _random = new Random();
+            _path = _random.Next().ToString();
+            _fileMode = FileMode.Open;
+            _fileAccess = FileAccess.ReadWrite;
+            _bufferSize = _random.Next(5, 1000);
+            _readBufferSize = (uint) _random.Next(5, 1000);
+            _writeBufferSize = (uint) _random.Next(5, 1000);
+            _handle = GenerateRandom(_random.Next(1, 10), _random);
+        }
+
+        protected override void SetupMocks()
+        {
+            SftpSessionMock.InSequence(MockSequence)
+                            .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Write, false))
+                            .Returns(_handle);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalReadLength((uint) _bufferSize))
+                           .Returns(_readBufferSize);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalWriteLength((uint) _bufferSize, _handle))
+                           .Returns(_writeBufferSize);
+        }
+
+        protected override void Act()
+        {
+            _target = new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
+        }
+
+        [TestMethod]
+        public void CanReadShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanRead);
+        }
+
+        [TestMethod]
+        public void CanSeekShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanSeek);
+        }
+
+        [TestMethod]
+        public void CanWriteShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanWrite);
+        }
+
+        [TestMethod]
+        public void CanTimeoutShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanTimeout);
+        }
+
+        [TestMethod]
+        public void PositionShouldReturnZero()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            var actual = _target.Position;
+
+            Assert.AreEqual(0L, actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadShouldStartReadingAtBeginningOfFile()
+        {
+            var buffer = new byte[8];
+            var data = new byte[] { 5, 4, 3, 2, 1 };
+            var expected = new byte[] { 0, 5, 4, 3, 2, 1, 0, 0 };
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestRead(_handle, 0UL, _readBufferSize)).Returns(data);
+
+            var actual = _target.Read(buffer, 1, data.Length);
+
+            Assert.AreEqual(data.Length, actual);
+            Assert.IsTrue(buffer.IsEqualTo(expected));
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestRead(_handle, 0UL, _readBufferSize), Times.Once);
+        }
+
+        [TestMethod]
+        public void ReadByteShouldStartReadingAtBeginningOfFile()
+        {
+            var data = GenerateRandom(5, _random);
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestRead(_handle, 0UL, _readBufferSize))
+                .Returns(data);
+
+            var actual = _target.ReadByte();
+
+            Assert.AreEqual(data[0], actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestRead(_handle, 0UL, _readBufferSize), Times.Once);
+        }
+
+        [TestMethod]
+        public void WriteShouldStartWritingAtBeginningOfFile()
+        {
+            var buffer = new byte[_writeBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null));
+
+            _target.Write(buffer, 0, buffer.Length);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null), Times.Once);
+        }
+
+        [TestMethod]
+        public void RequestOpenOnSftpSessionShouldBeInvokedOnce()
+        {
+            SftpSessionMock.Verify(p => p.RequestOpen(_path, Flags.Read | Flags.Write, false), Times.Once);
+        }
+    }
+}

+ 151 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeOpen_FileAccessWrite.cs

@@ -0,0 +1,151 @@
+using System;
+using System.IO;
+using System.Threading;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpFileStreamTest_Ctor_FileModeOpen_FileAccessWrite : SftpFileStreamTestBase
+    {
+        private Random _random;
+        private string _path;
+        private FileMode _fileMode;
+        private FileAccess _fileAccess;
+        private int _bufferSize;
+        private uint _readBufferSize;
+        private uint _writeBufferSize;
+        private byte[] _handle;
+        private SftpFileStream _target;
+
+        protected override void SetupData()
+        {
+            base.SetupData();
+
+            _random = new Random();
+            _path = _random.Next().ToString();
+            _fileMode = FileMode.Open;
+            _fileAccess = FileAccess.Write;
+            _bufferSize = _random.Next(5, 1000);
+            _readBufferSize = (uint) _random.Next(5, 1000);
+            _writeBufferSize = (uint) _random.Next(5, 1000);
+            _handle = GenerateRandom(_random.Next(1, 10), _random);
+        }
+
+        protected override void SetupMocks()
+        {
+            SftpSessionMock.InSequence(MockSequence)
+                            .Setup(p => p.RequestOpen(_path, Flags.Write, false))
+                            .Returns(_handle);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalReadLength((uint) _bufferSize))
+                           .Returns(_readBufferSize);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalWriteLength((uint) _bufferSize, _handle))
+                           .Returns(_writeBufferSize);
+        }
+
+        protected override void Act()
+        {
+            _target = new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
+        }
+
+        [TestMethod]
+        public void CanReadShouldReturnFalse()
+        {
+            Assert.IsFalse(_target.CanRead);
+        }
+
+        [TestMethod]
+        public void CanSeekShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanSeek);
+        }
+
+        [TestMethod]
+        public void CanWriteShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanWrite);
+        }
+
+        [TestMethod]
+        public void CanTimeoutShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanTimeout);
+        }
+
+        [TestMethod]
+        public void PositionShouldReturnZero()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            var actual = _target.Position;
+
+            Assert.AreEqual(0L, actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadShouldThrowNotSupportedException()
+        {
+            var buffer = new byte[_readBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            try
+            {
+                _target.Read(buffer, 0, buffer.Length);
+                Assert.Fail();
+            }
+            catch (NotSupportedException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("Read not supported.", ex.Message);
+            }
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadByteShouldThrowNotSupportedException()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            try
+            {
+                _target.ReadByte();
+                Assert.Fail();
+            }
+            catch (NotSupportedException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("Read not supported.", ex.Message);
+            }
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void WriteShouldStartWritingAtBeginningOfFile()
+        {
+            var buffer = new byte[_writeBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null));
+
+            _target.Write(buffer, 0, buffer.Length);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null), Times.Once);
+        }
+
+        [TestMethod]
+        public void RequestOpenOnSftpSessionShouldBeInvokedOnce()
+        {
+            SftpSessionMock.Verify(p => p.RequestOpen(_path, Flags.Write, false), Times.Once);
+        }
+    }
+}

+ 55 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeTruncate_FileAccessRead.cs

@@ -0,0 +1,55 @@
+using System;
+using System.IO;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpFileStreamTest_Ctor_FileModeTruncate_FileAccessRead : SftpFileStreamTestBase
+    {
+        private Random _random;
+        private string _path;
+        private FileMode _fileMode;
+        private FileAccess _fileAccess;
+        private int _bufferSize;
+        private ArgumentException _actualException;
+
+        protected override void SetupData()
+        {
+            base.SetupData();
+
+            _random = new Random();
+            _path = _random.Next().ToString();
+            _fileMode = FileMode.Truncate;
+            _fileAccess = FileAccess.Read;
+            _bufferSize = _random.Next(5, 1000);
+        }
+
+        protected override void SetupMocks()
+        {
+        }
+
+        protected override void Act()
+        {
+            try
+            {
+                new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
+                Assert.Fail();
+            }
+            catch (ArgumentException ex)
+            {
+                _actualException = ex;
+            }
+        }
+
+        [TestMethod]
+        public void CtorShouldHaveThrownArgumentException()
+        {
+            Assert.IsNotNull(_actualException);
+            Assert.IsNull(_actualException.InnerException);
+            Assert.AreEqual($"Combining {nameof(FileMode)}: {_fileMode} with {nameof(FileAccess)}: {_fileAccess} is invalid.", _actualException.Message);
+            Assert.IsNull(_actualException.ParamName);
+        }
+    }
+}

+ 147 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeTruncate_FileAccessReadWrite.cs

@@ -0,0 +1,147 @@
+using System;
+using System.IO;
+using System.Threading;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpFileStreamTest_Ctor_FileModeTruncate_FileAccessReadWrite : SftpFileStreamTestBase
+    {
+        private Random _random;
+        private string _path;
+        private FileMode _fileMode;
+        private FileAccess _fileAccess;
+        private int _bufferSize;
+        private uint _readBufferSize;
+        private uint _writeBufferSize;
+        private byte[] _handle;
+        private SftpFileStream _target;
+
+        protected override void SetupData()
+        {
+            base.SetupData();
+
+            _random = new Random();
+            _path = _random.Next().ToString();
+            _fileMode = FileMode.Truncate;
+            _fileAccess = FileAccess.ReadWrite;
+            _bufferSize = _random.Next(5, 1000);
+            _readBufferSize = (uint) _random.Next(5, 1000);
+            _writeBufferSize = (uint) _random.Next(5, 1000);
+            _handle = GenerateRandom(_random.Next(1, 10), _random);
+        }
+
+        protected override void SetupMocks()
+        {
+            SftpSessionMock.InSequence(MockSequence)
+                            .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Write | Flags.Truncate, false))
+                            .Returns(_handle);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalReadLength((uint) _bufferSize))
+                           .Returns(_readBufferSize);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalWriteLength((uint) _bufferSize, _handle))
+                           .Returns(_writeBufferSize);
+        }
+
+        protected override void Act()
+        {
+            _target = new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
+        }
+
+        [TestMethod]
+        public void CanReadShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanRead);
+        }
+
+        [TestMethod]
+        public void CanSeekShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanSeek);
+        }
+
+        [TestMethod]
+        public void CanWriteShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanWrite);
+        }
+
+        [TestMethod]
+        public void CanTimeoutShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanTimeout);
+        }
+
+        [TestMethod]
+        public void PositionShouldReturnZero()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            var actual = _target.Position;
+
+            Assert.AreEqual(0L, actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadShouldStartReadingAtBeginningOfFile()
+        {
+            var buffer = new byte[8];
+            var data = new byte[] { 5, 4, 3, 2, 1 };
+            var expected = new byte[] { 0, 5, 4, 3, 2, 1, 0, 0 };
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestRead(_handle, 0UL, _readBufferSize)).Returns(data);
+
+            var actual = _target.Read(buffer, 1, data.Length);
+
+            Assert.AreEqual(data.Length, actual);
+            Assert.IsTrue(buffer.IsEqualTo(expected));
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestRead(_handle, 0UL, _readBufferSize), Times.Once);
+        }
+
+        [TestMethod]
+        public void ReadByteShouldStartReadingAtBeginningOfFile()
+        {
+            var data = GenerateRandom(5, _random);
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestRead(_handle, 0UL, _readBufferSize))
+                .Returns(data);
+
+            var actual = _target.ReadByte();
+
+            Assert.AreEqual(data[0], actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestRead(_handle, 0UL, _readBufferSize), Times.Once);
+        }
+
+        [TestMethod]
+        public void WriteShouldStartWritingAtBeginningOfFile()
+        {
+            var buffer = new byte[_writeBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null));
+
+            _target.Write(buffer, 0, buffer.Length);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null), Times.Once);
+        }
+
+        [TestMethod]
+        public void RequestOpenOnSftpSessionShouldBeInvokedOnce()
+        {
+            SftpSessionMock.Verify(p => p.RequestOpen(_path, Flags.Read | Flags.Write | Flags.Truncate, false), Times.Once);
+        }
+    }
+}

+ 151 - 0
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Ctor_FileModeTruncate_FileAccessWrite.cs

@@ -0,0 +1,151 @@
+using System;
+using System.IO;
+using System.Threading;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Moq;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Classes.Sftp
+{
+    [TestClass]
+    public class SftpFileStreamTest_Ctor_FileModeTruncate_FileAccessWrite : SftpFileStreamTestBase
+    {
+        private Random _random;
+        private string _path;
+        private FileMode _fileMode;
+        private FileAccess _fileAccess;
+        private int _bufferSize;
+        private uint _readBufferSize;
+        private uint _writeBufferSize;
+        private byte[] _handle;
+        private SftpFileStream _target;
+
+        protected override void SetupData()
+        {
+            base.SetupData();
+
+            _random = new Random();
+            _path = _random.Next().ToString();
+            _fileMode = FileMode.Truncate;
+            _fileAccess = FileAccess.Write;
+            _bufferSize = _random.Next(5, 1000);
+            _readBufferSize = (uint) _random.Next(5, 1000);
+            _writeBufferSize = (uint) _random.Next(5, 1000);
+            _handle = GenerateRandom(_random.Next(1, 10), _random);
+        }
+
+        protected override void SetupMocks()
+        {
+            SftpSessionMock.InSequence(MockSequence)
+                            .Setup(p => p.RequestOpen(_path, Flags.Write | Flags.Truncate, false))
+                            .Returns(_handle);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalReadLength((uint) _bufferSize))
+                           .Returns(_readBufferSize);
+            SftpSessionMock.InSequence(MockSequence)
+                           .Setup(p => p.CalculateOptimalWriteLength((uint) _bufferSize, _handle))
+                           .Returns(_writeBufferSize);
+        }
+
+        protected override void Act()
+        {
+            _target = new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
+        }
+
+        [TestMethod]
+        public void CanReadShouldReturnFalse()
+        {
+            Assert.IsFalse(_target.CanRead);
+        }
+
+        [TestMethod]
+        public void CanSeekShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanSeek);
+        }
+
+        [TestMethod]
+        public void CanWriteShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanWrite);
+        }
+
+        [TestMethod]
+        public void CanTimeoutShouldReturnTrue()
+        {
+            Assert.IsTrue(_target.CanTimeout);
+        }
+
+        [TestMethod]
+        public void PositionShouldReturnZero()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            var actual = _target.Position;
+
+            Assert.AreEqual(0L, actual);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadShouldThrowNotSupportedException()
+        {
+            var buffer = new byte[_readBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            try
+            {
+                _target.Read(buffer, 0, buffer.Length);
+                Assert.Fail();
+            }
+            catch (NotSupportedException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("Read not supported.", ex.Message);
+            }
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void ReadByteShouldThrowNotSupportedException()
+        {
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+
+            try
+            {
+                _target.ReadByte();
+                Assert.Fail();
+            }
+            catch (NotSupportedException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual("Read not supported.", ex.Message);
+            }
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+        }
+
+        [TestMethod]
+        public void WriteShouldStartWritingAtBeginningOfFile()
+        {
+            var buffer = new byte[_writeBufferSize];
+
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
+            SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null));
+
+            _target.Write(buffer, 0, buffer.Length);
+
+            SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(1));
+            SftpSessionMock.Verify(p => p.RequestWrite(_handle, 0UL, buffer, 0, buffer.Length, It.IsNotNull<AutoResetEvent>(), null), Times.Once);
+        }
+
+        [TestMethod]
+        public void RequestOpenOnSftpSessionShouldBeInvokedOnce()
+        {
+            SftpSessionMock.Verify(p => p.RequestOpen(_path, Flags.Write | Flags.Truncate, false), Times.Once);
+        }
+    }
+}

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Dispose_Closed.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -31,7 +30,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint) random.Next(1, 1000);
             _readBufferSize = (uint) random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);
@@ -42,7 +40,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Dispose_Disposed.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -31,7 +30,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint) random.Next(1, 1000);
             _readBufferSize = (uint) random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);
@@ -42,7 +40,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 5 - 8
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Dispose_SessionNotOpen.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -29,12 +28,11 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         protected void Arrange()
         {
             var random = new Random();
-            _path = random.Next().ToString(CultureInfo.InvariantCulture);
-            _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);
+            _path = random.Next().ToString();
+            _handle = new[] {(byte) random.Next(byte.MinValue, byte.MaxValue)};
+            _bufferSize = (uint) random.Next(1, 1000);
+            _readBufferSize = (uint) random.Next(0, 1000);
+            _writeBufferSize = (uint) random.Next(0, 1000);
 
             _sftpSessionMock = new Mock<ISftpSession>(MockBehavior.Strict);
 
@@ -42,7 +40,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

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

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -31,10 +30,9 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint) random.Next(1, 1000);
             _readBufferSize = (uint) random.Next(0, 1000);
-            _writeBufferSize = (uint)random.Next(0, 1000);
+            _writeBufferSize = (uint) random.Next(0, 1000);
 
             _sftpSessionMock = new Mock<ISftpSession>(MockBehavior.Strict);
 
@@ -42,7 +40,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

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

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -31,10 +30,9 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint) random.Next(1, 1000);
             _readBufferSize = (uint) random.Next(0, 1000);
-            _writeBufferSize = (uint)random.Next(0, 1000);
+            _writeBufferSize = (uint) random.Next(0, 1000);
 
             _sftpSessionMock = new Mock<ISftpSession>(MockBehavior.Strict);
 
@@ -42,7 +40,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 4 - 9
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_ReadByte_ReadMode_NoDataInWriteBufferAndNoDataInReadBuffer_Eof.cs

@@ -1,5 +1,4 @@
 using System;
-using System.Globalization;
 using System.IO;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Moq;
@@ -14,7 +13,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -37,12 +35,11 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         protected void Arrange()
         {
             var random = new Random();
-            _path = random.Next().ToString(CultureInfo.InvariantCulture);
+            _path = random.Next().ToString();
             _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);
+            _bufferSize = (uint) random.Next(1, 1000);
+            _readBufferSize = (uint) random.Next(0, 1000);
+            _writeBufferSize = (uint) random.Next(0, 1000);
 
             _sftpSessionMock = new Mock<ISftpSession>(MockBehavior.Strict);
 
@@ -51,8 +48,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(_sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(_sequence).Setup(p => p.RequestFStat(_handle, false))
-                            .Returns(_fileAttributes);
             _sftpSessionMock.InSequence(_sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 4
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_ReadByte_ReadMode_NoDataInWriteBufferAndNoDataInReadBuffer_LessDataThanReadBufferSizeAvailable.cs

@@ -18,7 +18,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -44,7 +43,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint) random.Next(5, 1000);
             _readBufferSize = (uint) random.Next(10, 100);
             _writeBufferSize = (uint) random.Next(10, 100);
@@ -58,8 +56,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(_sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(_sequence).Setup(p => p.RequestFStat(_handle, false))
-                            .Returns(_fileAttributes);
             _sftpSessionMock.InSequence(_sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_Closed.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -32,7 +31,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint)random.Next(1, 1000);
             _readBufferSize = (uint)random.Next(0, 1000);
             _writeBufferSize = (uint)random.Next(0, 1000);
@@ -43,7 +41,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Write | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 5 - 9
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_Disposed.cs

@@ -1,5 +1,4 @@
 using System;
-using System.Globalization;
 using System.IO;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Moq;
@@ -14,7 +13,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -30,12 +28,11 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         protected void Arrange()
         {
             var random = new Random();
-            _path = random.Next().ToString(CultureInfo.InvariantCulture);
-            _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);
+            _path = random.Next().ToString();
+            _handle = new[] {(byte) random.Next(byte.MinValue, byte.MaxValue)};
+            _bufferSize = (uint) random.Next(1, 1000);
+            _readBufferSize = (uint) random.Next(0, 1000);
+            _writeBufferSize = (uint) random.Next(0, 1000);
 
             _sftpSessionMock = new Mock<ISftpSession>(MockBehavior.Strict);
 
@@ -43,7 +40,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Write | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_SessionNotOpen.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -34,7 +33,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint) random.Next(1, 1000);
             _readBufferSize = (uint) random.Next(0, 1000);
             _writeBufferSize = (uint) random.Next(0, 1000);
@@ -46,7 +44,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(_sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(_sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(_sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_SessionOpen_FIleAccessRead.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -34,7 +33,6 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint) random.Next(1, 1000);
             _readBufferSize = (uint) random.Next(0, 1000);
             _writeBufferSize = (uint) random.Next(0, 1000);
@@ -46,7 +44,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(_sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(_sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(_sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 28 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_SessionOpen_FIleAccessReadWrite.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -14,7 +15,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -22,6 +22,15 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private long _length;
         private long _lengthPassedToRequestFSetStat;
 
+        private DateTime _fileAttributesLastAccessTime;
+        private DateTime _fileAttributesLastWriteTime;
+        private long _fileAttributesSize;
+        private int _fileAttributesUserId;
+        private int _fileAttributesGroupId;
+        private uint _fileAttributesPermissions;
+        private IDictionary<string, string> _fileAttributesExtensions;
+        private SftpFileAttributes _fileAttributes;
+
         [TestInitialize]
         public void Setup()
         {
@@ -34,19 +43,32 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint) random.Next(1, 1000);
             _readBufferSize = (uint) random.Next(0, 1000);
             _writeBufferSize = (uint) random.Next(0, 1000);
             _length = random.Next();
 
+            _fileAttributesLastAccessTime = DateTime.Now.AddSeconds(random.Next());
+            _fileAttributesLastWriteTime = DateTime.Now.AddSeconds(random.Next());
+            _fileAttributesSize = random.Next();
+            _fileAttributesUserId = random.Next();
+            _fileAttributesGroupId = random.Next();
+            _fileAttributesPermissions = (uint) random.Next();
+            _fileAttributesExtensions = new Dictionary<string, string>();
+            _fileAttributes = new SftpFileAttributes(_fileAttributesLastAccessTime,
+                                                     _fileAttributesLastWriteTime,
+                                                     _fileAttributesSize,
+                                                     _fileAttributesUserId,
+                                                     _fileAttributesGroupId,
+                                                     _fileAttributesPermissions,
+                                                     _fileAttributesExtensions);
+
             _sftpSessionMock = new Mock<ISftpSession>(MockBehavior.Strict);
 
             _sequence = new MockSequence();
             _sftpSessionMock.InSequence(_sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Write | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(_sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(_sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);
@@ -56,6 +78,9 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(_sequence)
                 .Setup(p => p.IsOpen)
                 .Returns(true);
+            _sftpSessionMock.InSequence(_sequence)
+                .Setup(p => p.RequestFStat(_handle, false))
+                .Returns(_fileAttributes);
             _sftpSessionMock.InSequence(_sequence)
                 .Setup(p => p.RequestFSetStat(_handle, _fileAttributes))
                 .Callback<byte[], SftpFileAttributes>((bytes, attributes) => _lengthPassedToRequestFSetStat = attributes.Size);

+ 29 - 4
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_SetLength_SessionOpen_FIleAccessWrite.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -14,7 +15,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -22,6 +22,15 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private long _length;
         private long _lengthPassedToRequestFSetStat;
 
+        private DateTime _fileAttributesLastAccessTime;
+        private DateTime _fileAttributesLastWriteTime;
+        private long _fileAttributesSize;
+        private int _fileAttributesUserId;
+        private int _fileAttributesGroupId;
+        private uint _fileAttributesPermissions;
+        private IDictionary<string, string> _fileAttributesExtensions;
+        private SftpFileAttributes _fileAttributes;
+
         [TestInitialize]
         public void Setup()
         {
@@ -34,19 +43,32 @@ 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 = SftpFileAttributes.Empty;
             _bufferSize = (uint) random.Next(1, 1000);
             _readBufferSize = (uint) random.Next(0, 1000);
             _writeBufferSize = (uint) random.Next(0, 1000);
             _length = random.Next();
 
+            _fileAttributesLastAccessTime = DateTime.Now.AddSeconds(random.Next());
+            _fileAttributesLastWriteTime = DateTime.Now.AddSeconds(random.Next());
+            _fileAttributesSize = random.Next();
+            _fileAttributesUserId = random.Next();
+            _fileAttributesGroupId = random.Next();
+            _fileAttributesPermissions = (uint)random.Next();
+            _fileAttributesExtensions = new Dictionary<string, string>();
+            _fileAttributes = new SftpFileAttributes(_fileAttributesLastAccessTime,
+                                                     _fileAttributesLastWriteTime,
+                                                     _fileAttributesSize,
+                                                     _fileAttributesUserId,
+                                                     _fileAttributesGroupId,
+                                                     _fileAttributesPermissions,
+                                                     _fileAttributesExtensions);
+
             _sftpSessionMock = new Mock<ISftpSession>(MockBehavior.Strict);
 
             _sequence = new MockSequence();
             _sftpSessionMock.InSequence(_sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Write | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(_sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(_sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);
@@ -56,11 +78,14 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(_sequence)
                 .Setup(p => p.IsOpen)
                 .Returns(true);
+            _sftpSessionMock.InSequence(_sequence)
+                .Setup(p => p.RequestFStat(_handle, false))
+                .Returns(_fileAttributes);
             _sftpSessionMock.InSequence(_sequence)
                 .Setup(p => p.RequestFSetStat(_handle, _fileAttributes))
                 .Callback<byte[], SftpFileAttributes>((bytes, attributes) => _lengthPassedToRequestFSetStat = attributes.Size);
 
-            _sftpFileStream = new SftpFileStream(_sftpSessionMock.Object, _path, FileMode.Create, FileAccess.Write, (int)_bufferSize);
+            _sftpFileStream = new SftpFileStream(_sftpSessionMock.Object, _path, FileMode.Create, FileAccess.Write, (int) _bufferSize);
         }
 
         protected void Act()

+ 0 - 3
src/Renci.SshNet.Tests/Classes/Sftp/SftpFileStreamTest_Write_SessionOpen_CountGreatherThanTwoTimesTheWriteBufferSize.cs

@@ -16,7 +16,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
         private string _path;
         private SftpFileStream _sftpFileStream;
         private byte[] _handle;
-        private SftpFileAttributes _fileAttributes;
         private uint _bufferSize;
         private uint _readBufferSize;
         private uint _writeBufferSize;
@@ -57,7 +56,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _random = new Random();
             _path = _random.Next().ToString(CultureInfo.InvariantCulture);
             _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(500, 1000);
@@ -80,7 +78,6 @@ namespace Renci.SshNet.Tests.Classes.Sftp
             _sftpSessionMock.InSequence(_sequence)
                 .Setup(p => p.RequestOpen(_path, Flags.Write | Flags.Truncate, true))
                 .Returns(_handle);
-            _sftpSessionMock.InSequence(_sequence).Setup(p => p.RequestFStat(_handle, false)).Returns(_fileAttributes);
             _sftpSessionMock.InSequence(_sequence)
                 .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                 .Returns(_readBufferSize);

+ 85 - 0
src/Renci.SshNet.Tests/Common/SftpFileAttributesBuilder.cs

@@ -0,0 +1,85 @@
+using System;
+using System.Collections.Generic;
+using Renci.SshNet.Sftp;
+
+namespace Renci.SshNet.Tests.Common
+{
+    public class SftpFileAttributesBuilder
+    {
+        private DateTime? _lastAccessTime;
+        private DateTime? _lastWriteTime;
+        private long? _size;
+        private int? _userId;
+        private int? _groupId;
+        private uint? _permissions;
+        private IDictionary<string, string> _extensions;
+
+        public SftpFileAttributesBuilder WithLastAccessTime(DateTime lastAccessTime)
+        {
+            _lastAccessTime = lastAccessTime;
+            return this;
+        }
+
+        public SftpFileAttributesBuilder WithLastWriteTime(DateTime lastWriteTime)
+        {
+            _lastWriteTime = lastWriteTime;
+            return this;
+        }
+
+        public SftpFileAttributesBuilder WithSize(long size)
+        {
+            _size = size;
+            return this;
+        }
+
+        public SftpFileAttributesBuilder WithUserId(int userId)
+        {
+            _userId = userId;
+            return this;
+        }
+
+        public SftpFileAttributesBuilder WithGroupId(int groupId)
+        {
+            _groupId = groupId;
+            return this;
+        }
+
+        public SftpFileAttributesBuilder WithPermissions(uint permissions)
+        {
+            _permissions = permissions;
+            return this;
+        }
+
+        public SftpFileAttributesBuilder WithExtensions(IDictionary<string, string> extensions)
+        {
+            _extensions = extensions;
+            return this;
+        }
+
+        public SftpFileAttributes Build()
+        {
+            if (_lastAccessTime == null)
+                throw new ArgumentException();
+            if (_lastWriteTime == null)
+                throw new ArgumentException();
+            if (_size == null)
+                throw new ArgumentException();
+            if (_userId == null)
+                throw new ArgumentException();
+            if (_groupId == null)
+                throw new ArgumentException();
+            if (_permissions == null)
+                throw new ArgumentException();
+
+            return new SftpFileAttributes(_lastAccessTime.Value,
+                                          _lastWriteTime.Value,
+                                          _size.Value,
+                                          _userId.Value,
+                                          _groupId.Value,
+                                          _permissions.Value,
+                                          _extensions);
+        }
+
+
+    }
+}

+ 24 - 0
src/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj

@@ -356,6 +356,7 @@
     <Compile Include="Classes\Sftp\SftpFileReaderTest_Read_ReahAheadExceptionInBeginRead.cs" />
     <Compile Include="Classes\Sftp\SftpFileReaderTest_Read_ReadAheadExceptionInWaitOnHandle_ChunkAvailable.cs" />
     <Compile Include="Classes\Sftp\SftpFileReaderTest_Read_ReadAheadExceptionInWaitOnHandle_NoChunkAvailable.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTestBase.cs" />
     <Compile Include="Classes\Sftp\SftpFileStreamTest_CanRead_Closed_FileAccessRead.cs" />
     <Compile Include="Classes\Sftp\SftpFileStreamTest_CanRead_Closed_FileAccessReadWrite.cs" />
     <Compile Include="Classes\Sftp\SftpFileStreamTest_CanRead_Closed_FileAccessWrite.cs" />
@@ -378,6 +379,26 @@
     <Compile Include="Classes\Sftp\SftpFileStreamTest_Close_Disposed.cs" />
     <Compile Include="Classes\Sftp\SftpFileStreamTest_Close_SessionNotOpen.cs" />
     <Compile Include="Classes\Sftp\SftpFileStreamTest_Close_SessionOpen.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileAccessInvalid.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeAppend_FileAccessRead.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeCreateNew_FileAccessRead.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeCreateNew_FileAccessReadWrite.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeCreateNew_FileAccessWrite.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeCreate_FileAccessRead.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeCreate_FileAccessReadWrite_FileDoesNotExist.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeCreate_FileAccessReadWrite_FileExists.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeCreate_FileAccessWrite_FileDoesNotExist.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeCreate_FileAccessWrite_FileExists.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeOpenOrCreate_FileAccessRead.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeOpenOrCreate_FileAccessReadWrite.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeOpenOrCreate_FileAccessWrite.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeOpen_FileAccessRead.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeOpen_FileAccessReadWrite.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeOpen_FileAccessWrite.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeTruncate_FileAccessRead.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeTruncate_FileAccessReadWrite.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeTruncate_FileAccessWrite.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeInvalid.cs" />
     <Compile Include="Classes\Sftp\SftpFileStreamTest_Dispose_Closed.cs" />
     <Compile Include="Classes\Sftp\SftpFileStreamTest_Dispose_SessionNotOpen.cs" />
     <Compile Include="Classes\Sftp\SftpFileStreamTest_Dispose_SessionOpen.cs" />
@@ -426,6 +447,8 @@
     <Compile Include="Classes\Sftp\SftpFileStreamTest_SetLength_SessionOpen_FIleAccessWrite.cs" />
     <Compile Include="Classes\Sftp\SftpFileStreamTest_Write_SessionOpen_CountGreatherThanTwoTimesTheWriteBufferSize.cs" />
     <Compile Include="Classes\Sftp\SftpFileStreamTest_ReadByte_ReadMode_NoDataInWriteBufferAndNoDataInReadBuffer_Eof.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeAppend_FileAccessReadWrite.cs" />
+    <Compile Include="Classes\Sftp\SftpFileStreamTest_Ctor_FileModeAppend_FileAccessWrite.cs" />
     <Compile Include="Classes\Sftp\SftpFileTest.cs" />
     <Compile Include="Classes\Sftp\SftpSessionTest_Connected_RequestRead.cs" />
     <Compile Include="Classes\Sftp\SftpSessionTest_Connected_RequestStatVfs.cs" />
@@ -482,6 +505,7 @@
     <Compile Include="Classes\Common\PipeStream_Close_BlockingWrite.cs" />
     <Compile Include="Classes\Common\PipeStream_Flush_BytesRemainingAfterRead.cs" />
     <Compile Include="Classes\Common\PipeStream_Flush_NoBytesRemainingAfterRead.cs" />
+    <Compile Include="Common\SftpFileAttributesBuilder.cs" />
     <Compile Include="Common\TestBase.cs" />
     <Compile Include="Classes\Compression\CompressorTest.cs" />
     <Compile Include="Classes\Common\DerDataTest.cs" />