Skip to content

Commit 40efaa6

Browse files
committed
Move back to writing all read bytes to read buffer, not only those that exceed the user supplied buffer.
1 parent bcc8def commit 40efaa6

9 files changed

+547
-26
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
using System;
2+
using System.IO;
3+
using Microsoft.VisualStudio.TestTools.UnitTesting;
4+
using Moq;
5+
using Renci.SshNet.Common;
6+
using Renci.SshNet.Sftp;
7+
8+
namespace Renci.SshNet.Tests.Classes.Sftp
9+
{
10+
[TestClass]
11+
public class SftpFileStreamTest_Read_ReadMode_NoDataInReaderBufferAndReadLessBytesFromServerThanCount : SftpFileStreamTestBase
12+
{
13+
private string _path;
14+
private SftpFileStream _target;
15+
private byte[] _handle;
16+
private uint _bufferSize;
17+
private uint _readBufferSize;
18+
private uint _writeBufferSize;
19+
private int _actual;
20+
private byte[] _buffer;
21+
private byte[] _serverData1;
22+
private byte[] _serverData2;
23+
private int _serverData1Length;
24+
private int _serverData2Length;
25+
private int _numberOfBytesToRead;
26+
27+
protected override void SetupData()
28+
{
29+
base.SetupData();
30+
31+
var random = new Random();
32+
_path = random.Next().ToString();
33+
_handle = GenerateRandom(5, random);
34+
_bufferSize = (uint)random.Next(1, 1000);
35+
_readBufferSize = 20;
36+
_writeBufferSize = 500;
37+
38+
_numberOfBytesToRead = 20;
39+
_buffer = new byte[_numberOfBytesToRead];
40+
_serverData1Length = _numberOfBytesToRead - 5;
41+
_serverData1 = GenerateRandom(_serverData1Length, random);
42+
_serverData2Length = _numberOfBytesToRead - _serverData1Length + 3;
43+
_serverData2 = GenerateRandom(_serverData2Length, random);
44+
}
45+
46+
protected override void SetupMocks()
47+
{
48+
SftpSessionMock.InSequence(MockSequence)
49+
.Setup(p => p.RequestOpen(_path, Flags.Read, false))
50+
.Returns(_handle);
51+
SftpSessionMock.InSequence(MockSequence)
52+
.Setup(p => p.CalculateOptimalReadLength(_bufferSize))
53+
.Returns(_readBufferSize);
54+
SftpSessionMock.InSequence(MockSequence)
55+
.Setup(p => p.CalculateOptimalWriteLength(_bufferSize, _handle))
56+
.Returns(_writeBufferSize);
57+
SftpSessionMock.InSequence(MockSequence)
58+
.Setup(p => p.IsOpen)
59+
.Returns(true);
60+
SftpSessionMock.InSequence(MockSequence)
61+
.Setup(p => p.RequestRead(_handle, 0UL, _readBufferSize))
62+
.Returns(_serverData1);
63+
SftpSessionMock.InSequence(MockSequence)
64+
.Setup(p => p.RequestRead(_handle, (ulong) _serverData1.Length, _readBufferSize))
65+
.Returns(_serverData2);
66+
}
67+
68+
[TestCleanup]
69+
public void TearDown()
70+
{
71+
SftpSessionMock.InSequence(MockSequence)
72+
.Setup(p => p.RequestClose(_handle));
73+
}
74+
75+
protected override void Arrange()
76+
{
77+
base.Arrange();
78+
79+
_target = new SftpFileStream(SftpSessionMock.Object,
80+
_path,
81+
FileMode.Open,
82+
FileAccess.Read,
83+
(int)_bufferSize);
84+
}
85+
86+
protected override void Act()
87+
{
88+
_actual = _target.Read(_buffer, 0, _numberOfBytesToRead);
89+
}
90+
91+
[TestMethod]
92+
public void ReadShouldHaveReturnedTheNumberOfBytesRequested()
93+
{
94+
Assert.AreEqual(_buffer.Length, _actual);
95+
}
96+
97+
[TestMethod]
98+
public void ReadShouldHaveWrittenBytesToTheCallerSuppliedBuffer()
99+
{
100+
Assert.IsTrue(_serverData1.IsEqualTo(_buffer.Take(_serverData1Length)));
101+
102+
var bytesWrittenFromSecondRead = _numberOfBytesToRead - _serverData1Length;
103+
Assert.IsTrue(_serverData2.Take(bytesWrittenFromSecondRead).IsEqualTo(_buffer.Take(_serverData1Length, bytesWrittenFromSecondRead)));
104+
}
105+
106+
[TestMethod]
107+
public void PositionShouldReturnNumberOfBytesWrittenToBuffer()
108+
{
109+
SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
110+
111+
Assert.AreEqual(_buffer.Length, _target.Position);
112+
113+
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(2));
114+
}
115+
116+
[TestMethod]
117+
public void ReadShouldReturnAllRemaningBytesFromReadBufferWhenCountIsEqualToNumberOfRemainingBytes()
118+
{
119+
SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
120+
121+
var numberOfBytesRemainingInReadBuffer = _serverData1Length + _serverData2Length - _numberOfBytesToRead;
122+
123+
_buffer = new byte[numberOfBytesRemainingInReadBuffer];
124+
125+
var actual = _target.Read(_buffer, 0, _buffer.Length);
126+
127+
Assert.AreEqual(_buffer.Length, actual);
128+
Assert.IsTrue(_serverData2.Take(_numberOfBytesToRead - _serverData1Length, _buffer.Length).IsEqualTo(_buffer));
129+
130+
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(2));
131+
}
132+
133+
[TestMethod]
134+
public void ReadShouldReturnAllRemaningBytesFromReadBufferAndReadAgainWhenCountIsGreaterThanNumberOfRemainingBytesAndNewReadReturnsZeroBytes()
135+
{
136+
SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
137+
SftpSessionMock.InSequence(MockSequence).Setup(p => p.RequestRead(_handle, (ulong) (_serverData1Length + _serverData2Length), _readBufferSize)).Returns(Array<byte>.Empty);
138+
139+
var numberOfBytesRemainingInReadBuffer = _serverData1Length + _serverData2Length - _numberOfBytesToRead;
140+
141+
_buffer = new byte[numberOfBytesRemainingInReadBuffer + 1];
142+
143+
var actual = _target.Read(_buffer, 0, _buffer.Length);
144+
145+
Assert.AreEqual(numberOfBytesRemainingInReadBuffer, actual);
146+
Assert.IsTrue(_serverData2.Take(_numberOfBytesToRead - _serverData1Length, numberOfBytesRemainingInReadBuffer).IsEqualTo(_buffer.Take(numberOfBytesRemainingInReadBuffer)));
147+
Assert.AreEqual(0, _buffer[numberOfBytesRemainingInReadBuffer]);
148+
149+
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(2));
150+
SftpSessionMock.Verify(p => p.RequestRead(_handle, (ulong) (_serverData1Length + _serverData2Length), _readBufferSize));
151+
}
152+
}
153+
}
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
namespace Renci.SshNet.Tests.Classes.Sftp
88
{
99
[TestClass]
10-
public class SftpFileStreamTest_Read_ReadMode_NoDataInReaderBufferAndReadMoreBytesThanCount : SftpFileStreamTestBase
10+
public class SftpFileStreamTest_Read_ReadMode_NoDataInReaderBufferAndReadMoreBytesFromServerThanCount : SftpFileStreamTestBase
1111
{
1212
private string _path;
1313
private SftpFileStream _target;
@@ -18,7 +18,7 @@ public class SftpFileStreamTest_Read_ReadMode_NoDataInReaderBufferAndReadMoreByt
1818
private int _actual;
1919
private byte[] _buffer;
2020
private byte[] _serverData;
21-
private int _numberOfBytesInReadBuffer;
21+
private int _numberOfBytesToWriteToReadBuffer;
2222
private int _numberOfBytesToRead;
2323

2424
protected override void SetupData()
@@ -34,8 +34,8 @@ protected override void SetupData()
3434

3535
_numberOfBytesToRead = 20;
3636
_buffer = new byte[_numberOfBytesToRead];
37-
_numberOfBytesInReadBuffer = 10;
38-
_serverData = GenerateRandom(_buffer.Length + _numberOfBytesInReadBuffer, random);
37+
_numberOfBytesToWriteToReadBuffer = 10; // should be less than _readBufferSize
38+
_serverData = GenerateRandom(_numberOfBytesToRead + _numberOfBytesToWriteToReadBuffer, random);
3939
}
4040

4141
protected override void SetupMocks()
@@ -81,9 +81,9 @@ protected override void Act()
8181
}
8282

8383
[TestMethod]
84-
public void ReadShouldHaveReturnedTheNumberOfBytesWrittenToBuffer()
84+
public void ReadShouldHaveReturnedTheNumberOfBytesRequested()
8585
{
86-
Assert.AreEqual(_buffer.Length, _actual);
86+
Assert.AreEqual(_numberOfBytesToRead, _actual);
8787
}
8888

8989
[TestMethod]
@@ -107,12 +107,12 @@ public void ReadShouldReturnAllRemaningBytesFromReadBufferWhenCountIsEqualToNumb
107107
{
108108
SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
109109

110-
_buffer = new byte[_numberOfBytesInReadBuffer];
110+
_buffer = new byte[_numberOfBytesToWriteToReadBuffer];
111111

112-
var actual = _target.Read(_buffer, 0, _numberOfBytesInReadBuffer);
112+
var actual = _target.Read(_buffer, 0, _numberOfBytesToWriteToReadBuffer);
113113

114-
Assert.AreEqual(_numberOfBytesInReadBuffer, actual);
115-
Assert.IsTrue(_serverData.Take(_numberOfBytesToRead, _numberOfBytesInReadBuffer).IsEqualTo(_buffer));
114+
Assert.AreEqual(_numberOfBytesToWriteToReadBuffer, actual);
115+
Assert.IsTrue(_serverData.Take(_numberOfBytesToRead, _numberOfBytesToWriteToReadBuffer).IsEqualTo(_buffer));
116116

117117
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(2));
118118
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
using System;
2+
using System.IO;
3+
using Microsoft.VisualStudio.TestTools.UnitTesting;
4+
using Moq;
5+
using Renci.SshNet.Sftp;
6+
7+
namespace Renci.SshNet.Tests.Classes.Sftp
8+
{
9+
[TestClass]
10+
public class SftpFileStreamTest_Seek_PositionedAtBeginningOfStream_OriginBeginAndOffsetNegative : SftpFileStreamTestBase
11+
{
12+
private Random _random;
13+
private string _path;
14+
private FileMode _fileMode;
15+
private FileAccess _fileAccess;
16+
private int _bufferSize;
17+
private uint _readBufferSize;
18+
private uint _writeBufferSize;
19+
private byte[] _handle;
20+
private SftpFileStream _target;
21+
private int _offset;
22+
private EndOfStreamException _actualException;
23+
24+
protected override void SetupData()
25+
{
26+
base.SetupData();
27+
28+
_random = new Random();
29+
_path = _random.Next().ToString();
30+
_fileMode = FileMode.OpenOrCreate;
31+
_fileAccess = FileAccess.Read;
32+
_bufferSize = _random.Next(5, 1000);
33+
_readBufferSize = (uint)_random.Next(5, 1000);
34+
_writeBufferSize = (uint)_random.Next(5, 1000);
35+
_handle = GenerateRandom(_random.Next(1, 10), _random);
36+
_offset = _random.Next(int.MinValue, -1);
37+
}
38+
39+
protected override void SetupMocks()
40+
{
41+
SftpSessionMock.InSequence(MockSequence)
42+
.Setup(p => p.RequestOpen(_path, Flags.Read | Flags.CreateNewOrOpen, false))
43+
.Returns(_handle);
44+
SftpSessionMock.InSequence(MockSequence)
45+
.Setup(p => p.CalculateOptimalReadLength((uint)_bufferSize))
46+
.Returns(_readBufferSize);
47+
SftpSessionMock.InSequence(MockSequence)
48+
.Setup(p => p.CalculateOptimalWriteLength((uint)_bufferSize, _handle))
49+
.Returns(_writeBufferSize);
50+
SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
51+
}
52+
53+
protected override void Arrange()
54+
{
55+
base.Arrange();
56+
57+
_target = new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
58+
}
59+
60+
protected override void Act()
61+
{
62+
try
63+
{
64+
_target.Seek(_offset, SeekOrigin.Begin);
65+
Assert.Fail();
66+
}
67+
catch (EndOfStreamException ex)
68+
{
69+
_actualException = ex;
70+
}
71+
}
72+
73+
[TestMethod]
74+
public void SeekShouldHaveThrownEndOfStreamException()
75+
{
76+
Assert.IsNotNull(_actualException);
77+
Assert.IsNull(_actualException.InnerException);
78+
Assert.AreEqual("Attempted to read past the end of the stream.", _actualException.Message);
79+
}
80+
81+
[TestMethod]
82+
public void IsOpenOnSftpSessionShouldHaveBeenInvokedOnce()
83+
{
84+
SftpSessionMock.Verify(p => p.IsOpen, Times.Once);
85+
}
86+
87+
[TestMethod]
88+
public void PositionShouldReturnZero()
89+
{
90+
SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
91+
92+
Assert.AreEqual(0L, _target.Position);
93+
94+
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(2));
95+
}
96+
}
97+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using System;
2+
using System.IO;
3+
using Microsoft.VisualStudio.TestTools.UnitTesting;
4+
using Moq;
5+
using Renci.SshNet.Sftp;
6+
7+
namespace Renci.SshNet.Tests.Classes.Sftp
8+
{
9+
[TestClass]
10+
public class SftpFileStreamTest_Seek_PositionedAtBeginningOfStream_OriginBeginAndOffsetPositive : SftpFileStreamTestBase
11+
{
12+
private Random _random;
13+
private string _path;
14+
private FileMode _fileMode;
15+
private FileAccess _fileAccess;
16+
private int _bufferSize;
17+
private uint _readBufferSize;
18+
private uint _writeBufferSize;
19+
private byte[] _handle;
20+
private SftpFileStream _target;
21+
private int _offset;
22+
private EndOfStreamException _actualException;
23+
private long _actual;
24+
25+
protected override void SetupData()
26+
{
27+
base.SetupData();
28+
29+
_random = new Random();
30+
_path = _random.Next().ToString();
31+
_fileMode = FileMode.OpenOrCreate;
32+
_fileAccess = FileAccess.Read;
33+
_bufferSize = _random.Next(5, 1000);
34+
_readBufferSize = (uint)_random.Next(5, 1000);
35+
_writeBufferSize = (uint)_random.Next(5, 1000);
36+
_handle = GenerateRandom(_random.Next(1, 10), _random);
37+
_offset = _random.Next(1, int.MaxValue);
38+
}
39+
40+
protected override void SetupMocks()
41+
{
42+
SftpSessionMock.InSequence(MockSequence)
43+
.Setup(p => p.RequestOpen(_path, Flags.Read | Flags.CreateNewOrOpen, false))
44+
.Returns(_handle);
45+
SftpSessionMock.InSequence(MockSequence)
46+
.Setup(p => p.CalculateOptimalReadLength((uint)_bufferSize))
47+
.Returns(_readBufferSize);
48+
SftpSessionMock.InSequence(MockSequence)
49+
.Setup(p => p.CalculateOptimalWriteLength((uint)_bufferSize, _handle))
50+
.Returns(_writeBufferSize);
51+
SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
52+
}
53+
54+
protected override void Arrange()
55+
{
56+
base.Arrange();
57+
58+
_target = new SftpFileStream(SftpSessionMock.Object, _path, _fileMode, _fileAccess, _bufferSize);
59+
}
60+
61+
protected override void Act()
62+
{
63+
_actual = _target.Seek(_offset, SeekOrigin.Begin);
64+
}
65+
66+
[TestMethod]
67+
public void SeekShouldHaveReturnedOffset()
68+
{
69+
Assert.AreEqual(_offset, _actual);
70+
}
71+
72+
[TestMethod]
73+
public void IsOpenOnSftpSessionShouldHaveBeenInvokedOnce()
74+
{
75+
SftpSessionMock.Verify(p => p.IsOpen, Times.Once);
76+
}
77+
78+
[TestMethod]
79+
public void PositionShouldReturnOffset()
80+
{
81+
SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
82+
83+
Assert.AreEqual(_offset, _target.Position);
84+
85+
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(2));
86+
}
87+
}
88+
}

0 commit comments

Comments
 (0)