Skip to content

Commit 79c9a4b

Browse files
committed
SftpFileStream: Position in stream should be left untouched when clearing read buffer.
1 parent 68c1e59 commit 79c9a4b

14 files changed

+803
-44
lines changed

src/Renci.SshNet.Tests.NET35/Renci.SshNet.Tests.NET35.csproj

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1200,6 +1200,24 @@
12001200
<Compile Include="..\Renci.SshNet.Tests\Classes\Sftp\SftpFileStreamTest_Finalize_SessionOpen.cs">
12011201
<Link>Classes\Sftp\SftpFileStreamTest_Finalize_SessionOpen.cs</Link>
12021202
</Compile>
1203+
<Compile Include="..\Renci.SshNet.Tests\Classes\Sftp\SftpFileStreamTest_Flush_ReadMode_DataInBuffer_NotReadFromBuffer.cs">
1204+
<Link>Classes\Sftp\SftpFileStreamTest_Flush_ReadMode_DataInBuffer_NotReadFromBuffer.cs</Link>
1205+
</Compile>
1206+
<Compile Include="..\Renci.SshNet.Tests\Classes\Sftp\SftpFileStreamTest_Flush_ReadMode_DataInBuffer_ReadFromBuffer.cs">
1207+
<Link>Classes\Sftp\SftpFileStreamTest_Flush_ReadMode_DataInBuffer_ReadFromBuffer.cs</Link>
1208+
</Compile>
1209+
<Compile Include="..\Renci.SshNet.Tests\Classes\Sftp\SftpFileStreamTest_Flush_ReadMode_NoDataInBuffer.cs">
1210+
<Link>Classes\Sftp\SftpFileStreamTest_Flush_ReadMode_NoDataInBuffer.cs</Link>
1211+
</Compile>
1212+
<Compile Include="..\Renci.SshNet.Tests\Classes\Sftp\SftpFileStreamTest_Flush_SessionNotOpen.cs">
1213+
<Link>Classes\Sftp\SftpFileStreamTest_Flush_SessionNotOpen.cs</Link>
1214+
</Compile>
1215+
<Compile Include="..\Renci.SshNet.Tests\Classes\Sftp\SftpFileStreamTest_Flush_WriteMode_DataInBuffer.cs">
1216+
<Link>Classes\Sftp\SftpFileStreamTest_Flush_WriteMode_DataInBuffer.cs</Link>
1217+
</Compile>
1218+
<Compile Include="..\Renci.SshNet.Tests\Classes\Sftp\SftpFileStreamTest_Flush_WriteMode_NoDataInBuffer.cs">
1219+
<Link>Classes\Sftp\SftpFileStreamTest_Flush_WriteMode_NoDataInBuffer.cs</Link>
1220+
</Compile>
12031221
<Compile Include="..\Renci.SshNet.Tests\Classes\Sftp\SftpFileStreamTest_ReadByte_ReadMode_NoDataInWriteBufferAndNoDataInReadBuffer_Eof.cs">
12041222
<Link>Classes\Sftp\SftpFileStreamTest_ReadByte_ReadMode_NoDataInWriteBufferAndNoDataInReadBuffer_Eof.cs</Link>
12051223
</Compile>
@@ -1434,6 +1452,9 @@
14341452
<Compile Include="..\Renci.SshNet.Tests\Classes\SubsystemSession_SendData_NeverConnected.cs">
14351453
<Link>Classes\SubsystemSession_SendData_NeverConnected.cs</Link>
14361454
</Compile>
1455+
<Compile Include="..\Renci.SshNet.Tests\Common\ArrayBuilder.cs">
1456+
<Link>Common\ArrayBuilder.cs</Link>
1457+
</Compile>
14371458
<Compile Include="..\Renci.SshNet.Tests\Common\AsyncSocketListener.cs">
14381459
<Link>Common\AsyncSocketListener.cs</Link>
14391460
</Compile>
@@ -1527,7 +1548,7 @@
15271548
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
15281549
<ProjectExtensions>
15291550
<VisualStudio>
1530-
<UserProperties ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" ProjectLinkReference="c45379b9-17b1-4e89-bc2e-6d41726413e8" />
1551+
<UserProperties ProjectLinkReference="c45379b9-17b1-4e89-bc2e-6d41726413e8" ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" />
15311552
</VisualStudio>
15321553
</ProjectExtensions>
15331554
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
using Microsoft.VisualStudio.TestTools.UnitTesting;
2+
using Moq;
3+
using Renci.SshNet.Sftp;
4+
using Renci.SshNet.Tests.Common;
5+
using System;
6+
using System.IO;
7+
8+
namespace Renci.SshNet.Tests.Classes.Sftp
9+
{
10+
[TestClass]
11+
public class SftpFileStreamTest_Flush_ReadMode_DataInBuffer_NotReadFromBuffer : SftpFileStreamTestBase
12+
{
13+
private SftpFileStream _target;
14+
private string _path;
15+
private byte[] _handle;
16+
private uint _bufferSize;
17+
private uint _readBufferSize;
18+
private uint _writeBufferSize;
19+
private byte[] _readBytes;
20+
private byte[] _serverBytes;
21+
22+
protected override void SetupData()
23+
{
24+
base.SetupData();
25+
26+
var random = new Random();
27+
_path = random.Next().ToString();
28+
_handle = GenerateRandom(5, random);
29+
_bufferSize = (uint) random.Next(1, 1000);
30+
_readBufferSize = 100;
31+
_writeBufferSize = 500;
32+
_readBytes = new byte[random.Next(1, (int) _readBufferSize - 10)];
33+
_serverBytes = GenerateRandom(_readBytes.Length + 5); // store 5 bytes in read buffer
34+
}
35+
36+
protected override void SetupMocks()
37+
{
38+
SftpSessionMock.InSequence(MockSequence)
39+
.Setup(p => p.RequestOpen(_path, Flags.Read, false))
40+
.Returns(_handle);
41+
SftpSessionMock.InSequence(MockSequence)
42+
.Setup(p => p.CalculateOptimalReadLength(_bufferSize))
43+
.Returns(_readBufferSize);
44+
SftpSessionMock.InSequence(MockSequence)
45+
.Setup(p => p.CalculateOptimalWriteLength(_bufferSize, _handle))
46+
.Returns(_writeBufferSize);
47+
SftpSessionMock.InSequence(MockSequence)
48+
.Setup(p => p.IsOpen)
49+
.Returns(true);
50+
SftpSessionMock.InSequence(MockSequence)
51+
.Setup(p => p.RequestRead(_handle, 0UL, _readBufferSize))
52+
.Returns(_serverBytes);
53+
SftpSessionMock.InSequence(MockSequence)
54+
.Setup(p => p.IsOpen)
55+
.Returns(true);
56+
}
57+
58+
protected override void Arrange()
59+
{
60+
base.Arrange();
61+
62+
_target = new SftpFileStream(SftpSessionMock.Object,
63+
_path,
64+
FileMode.Open,
65+
FileAccess.Read,
66+
(int)_bufferSize);
67+
_target.Read(_readBytes, 0, _readBytes.Length);
68+
}
69+
70+
protected override void Act()
71+
{
72+
_target.Flush();
73+
}
74+
75+
[TestMethod]
76+
public void PositionShouldReturnSameValueAsBeforeFlush()
77+
{
78+
SftpSessionMock.InSequence(MockSequence)
79+
.Setup(p => p.IsOpen)
80+
.Returns(true);
81+
82+
Assert.AreEqual(_readBytes.Length, _target.Position);
83+
84+
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(3));
85+
}
86+
87+
[TestMethod]
88+
public void ReadShouldReadFromServer()
89+
{
90+
var serverBytes2 = GenerateRandom(5);
91+
var readBytes2 = new byte[5];
92+
var expectedReadBytes = new ArrayBuilder<byte>().Add(new byte[2])
93+
.Add(serverBytes2.Take(0, 3))
94+
.Build();
95+
96+
SftpSessionMock.InSequence(MockSequence)
97+
.Setup(p => p.IsOpen)
98+
.Returns(true);
99+
SftpSessionMock.InSequence(MockSequence)
100+
.Setup(p => p.RequestRead(_handle, (ulong)_readBytes.Length, _readBufferSize))
101+
.Returns(serverBytes2);
102+
103+
var bytesRead = _target.Read(readBytes2, 2, 3);
104+
105+
Assert.AreEqual(3, bytesRead);
106+
CollectionAssert.AreEqual(expectedReadBytes, readBytes2);
107+
108+
SftpSessionMock.Verify(p => p.RequestRead(_handle, (ulong)_readBytes.Length, _readBufferSize), Times.Once);
109+
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(3));
110+
}
111+
}
112+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
using Microsoft.VisualStudio.TestTools.UnitTesting;
2+
using Moq;
3+
using Renci.SshNet.Sftp;
4+
using Renci.SshNet.Tests.Common;
5+
using System;
6+
using System.IO;
7+
8+
namespace Renci.SshNet.Tests.Classes.Sftp
9+
{
10+
[TestClass]
11+
public class SftpFileStreamTest_Flush_ReadMode_DataInBuffer_ReadFromBuffer : SftpFileStreamTestBase
12+
{
13+
private SftpFileStream _target;
14+
private string _path;
15+
private byte[] _handle;
16+
private uint _bufferSize;
17+
private uint _readBufferSize;
18+
private uint _writeBufferSize;
19+
private byte[] _readBytes1;
20+
private byte[] _readBytes2;
21+
private byte[] _serverBytes;
22+
23+
protected override void SetupData()
24+
{
25+
base.SetupData();
26+
27+
var random = new Random();
28+
_path = random.Next().ToString();
29+
_handle = GenerateRandom(5, random);
30+
_bufferSize = (uint)random.Next(1, 1000);
31+
_readBufferSize = 100;
32+
_writeBufferSize = 500;
33+
_readBytes1 = new byte[random.Next(1, (int) _readBufferSize - 10)];
34+
_readBytes2 = new byte[random.Next(1, 3)];
35+
_serverBytes = GenerateRandom(_readBytes1.Length + 10); // store 5 bytes in read buffer
36+
}
37+
38+
protected override void SetupMocks()
39+
{
40+
SftpSessionMock.InSequence(MockSequence)
41+
.Setup(p => p.RequestOpen(_path, Flags.Read, false))
42+
.Returns(_handle);
43+
SftpSessionMock.InSequence(MockSequence)
44+
.Setup(p => p.CalculateOptimalReadLength(_bufferSize))
45+
.Returns(_readBufferSize);
46+
SftpSessionMock.InSequence(MockSequence)
47+
.Setup(p => p.CalculateOptimalWriteLength(_bufferSize, _handle))
48+
.Returns(_writeBufferSize);
49+
SftpSessionMock.InSequence(MockSequence)
50+
.Setup(p => p.IsOpen)
51+
.Returns(true);
52+
SftpSessionMock.InSequence(MockSequence)
53+
.Setup(p => p.RequestRead(_handle, 0UL, _readBufferSize))
54+
.Returns(_serverBytes);
55+
SftpSessionMock.InSequence(MockSequence)
56+
.Setup(p => p.IsOpen)
57+
.Returns(true);
58+
SftpSessionMock.InSequence(MockSequence)
59+
.Setup(p => p.IsOpen)
60+
.Returns(true);
61+
}
62+
63+
protected override void Arrange()
64+
{
65+
base.Arrange();
66+
67+
_target = new SftpFileStream(SftpSessionMock.Object,
68+
_path,
69+
FileMode.Open,
70+
FileAccess.Read,
71+
(int)_bufferSize);
72+
_target.Read(_readBytes1, 0, _readBytes1.Length);
73+
_target.Read(_readBytes2, 0, _readBytes2.Length);
74+
}
75+
76+
protected override void Act()
77+
{
78+
_target.Flush();
79+
}
80+
81+
[TestMethod]
82+
public void PositionShouldReturnSameValueAsBeforeFlush()
83+
{
84+
SftpSessionMock.InSequence(MockSequence)
85+
.Setup(p => p.IsOpen)
86+
.Returns(true);
87+
88+
Assert.AreEqual(_readBytes1.Length + _readBytes2.Length, _target.Position);
89+
90+
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(4));
91+
}
92+
93+
[TestMethod]
94+
public void ReadShouldReadFromServer()
95+
{
96+
var serverBytes3 = GenerateRandom(5);
97+
var readBytes3 = new byte[3];
98+
var expectedReadBytes = new ArrayBuilder<byte>().Add(new byte[1])
99+
.Add(serverBytes3.Take(0, 2))
100+
.Build();
101+
102+
SftpSessionMock.InSequence(MockSequence)
103+
.Setup(p => p.IsOpen)
104+
.Returns(true);
105+
SftpSessionMock.InSequence(MockSequence)
106+
.Setup(p => p.RequestRead(_handle, (ulong) (_readBytes1.Length + _readBytes2.Length), _readBufferSize))
107+
.Returns(serverBytes3);
108+
109+
var bytesRead = _target.Read(readBytes3, 1, 2);
110+
111+
Assert.AreEqual(2, bytesRead);
112+
CollectionAssert.AreEqual(expectedReadBytes, readBytes3);
113+
114+
SftpSessionMock.Verify(p => p.RequestRead(_handle, (ulong)(_readBytes1.Length + _readBytes2.Length), _readBufferSize), Times.Once);
115+
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(4));
116+
}
117+
}
118+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
using Microsoft.VisualStudio.TestTools.UnitTesting;
2+
using Moq;
3+
using Renci.SshNet.Sftp;
4+
using Renci.SshNet.Tests.Common;
5+
using System;
6+
using System.IO;
7+
8+
namespace Renci.SshNet.Tests.Classes.Sftp
9+
{
10+
[TestClass]
11+
public class SftpFileStreamTest_Flush_ReadMode_NoDataInBuffer : SftpFileStreamTestBase
12+
{
13+
private SftpFileStream _target;
14+
private string _path;
15+
private byte[] _handle;
16+
private uint _bufferSize;
17+
private uint _readBufferSize;
18+
private uint _writeBufferSize;
19+
private byte[] _readBytes;
20+
private byte[] _serverBytes;
21+
22+
protected override void SetupData()
23+
{
24+
base.SetupData();
25+
26+
var random = new Random();
27+
_path = random.Next().ToString();
28+
_handle = GenerateRandom(5, random);
29+
_bufferSize = (uint) random.Next(1, 1000);
30+
_readBufferSize = 100;
31+
_writeBufferSize = 500;
32+
_readBytes = new byte[random.Next(1, (int) _readBufferSize)];
33+
_serverBytes = GenerateRandom(_readBytes.Length);
34+
}
35+
36+
protected override void SetupMocks()
37+
{
38+
SftpSessionMock.InSequence(MockSequence)
39+
.Setup(p => p.RequestOpen(_path, Flags.Read, false))
40+
.Returns(_handle);
41+
SftpSessionMock.InSequence(MockSequence)
42+
.Setup(p => p.CalculateOptimalReadLength(_bufferSize))
43+
.Returns(_readBufferSize);
44+
SftpSessionMock.InSequence(MockSequence)
45+
.Setup(p => p.CalculateOptimalWriteLength(_bufferSize, _handle))
46+
.Returns(_writeBufferSize);
47+
SftpSessionMock.InSequence(MockSequence)
48+
.Setup(p => p.IsOpen)
49+
.Returns(true);
50+
SftpSessionMock.InSequence(MockSequence)
51+
.Setup(p => p.RequestRead(_handle, 0UL, _readBufferSize))
52+
.Returns(_serverBytes);
53+
SftpSessionMock.InSequence(MockSequence)
54+
.Setup(p => p.IsOpen)
55+
.Returns(true);
56+
}
57+
58+
protected override void Arrange()
59+
{
60+
base.Arrange();
61+
62+
_target = new SftpFileStream(SftpSessionMock.Object,
63+
_path,
64+
FileMode.Open,
65+
FileAccess.Read,
66+
(int) _bufferSize);
67+
_target.Read(_readBytes, 0, _readBytes.Length);
68+
}
69+
70+
protected override void Act()
71+
{
72+
_target.Flush();
73+
}
74+
75+
[TestMethod]
76+
public void PositionShouldReturnSameValueAsBeforeFlush()
77+
{
78+
SftpSessionMock.InSequence(MockSequence)
79+
.Setup(p => p.IsOpen)
80+
.Returns(true);
81+
82+
Assert.AreEqual(_readBytes.Length, _target.Position);
83+
84+
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(3));
85+
}
86+
87+
[TestMethod]
88+
public void ReadShouldReadFromServer()
89+
{
90+
var serverBytes2 = GenerateRandom(5);
91+
var readBytes2 = new byte[5];
92+
var expectedReadBytes = new ArrayBuilder<byte>().Add(new byte[2])
93+
.Add(serverBytes2.Take(0, 3))
94+
.Build();
95+
96+
SftpSessionMock.InSequence(MockSequence)
97+
.Setup(p => p.IsOpen)
98+
.Returns(true);
99+
SftpSessionMock.InSequence(MockSequence)
100+
.Setup(p => p.RequestRead(_handle, (ulong) _readBytes.Length, _readBufferSize))
101+
.Returns(serverBytes2);
102+
103+
var bytesRead = _target.Read(readBytes2, 2, 3);
104+
105+
Assert.AreEqual(3, bytesRead);
106+
CollectionAssert.AreEqual(expectedReadBytes, readBytes2);
107+
108+
SftpSessionMock.Verify(p => p.RequestRead(_handle, (ulong)_readBytes.Length, _readBufferSize), Times.Once);
109+
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(3));
110+
}
111+
}
112+
}

0 commit comments

Comments
 (0)