Added more tests for SftpFileStream.SetLength(long).

This commit is contained in:
Gert Driesen
2017-08-14 20:23:01 +02:00
parent 7bc67f3aca
commit 9444f21461
9 changed files with 828 additions and 4 deletions
@@ -38,11 +38,28 @@ namespace Renci.SshNet.Tests.Classes.Sftp
protected abstract void Act();
protected byte[] GenerateRandom(int length)
{
return GenerateRandom(length, new Random());
}
protected byte[] GenerateRandom(int length, Random random)
{
var buffer = new byte[length];
random.NextBytes(buffer);
return buffer;
}
protected byte[] GenerateRandom(uint length)
{
return GenerateRandom(length, new Random());
}
protected byte[] GenerateRandom(uint length, Random random)
{
var buffer = new byte[length];
random.NextBytes(buffer);
return buffer;
}
}
}
@@ -0,0 +1,170 @@
using System;
using System.Globalization;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Renci.SshNet.Sftp;
using Renci.SshNet.Tests.Common;
using System.Threading;
using Renci.SshNet.Sftp.Responses;
namespace Renci.SshNet.Tests.Classes.Sftp
{
/// <summary>
/// - In read mode
/// - Bytes in (read) buffer
/// - New length greater than client position and greater than server position
/// </summary>
[TestClass]
public class SftpFileStreamTest_SetLength_DataInReadBuffer_NewLengthGreatherThanPosition : SftpFileStreamTestBase
{
private string _path;
private SftpFileStream _sftpFileStream;
private byte[] _handle;
private uint _bufferSize;
private uint _readBufferSize;
private uint _writeBufferSize;
private MockSequence _sequence;
private long _length;
private SftpFileAttributes _fileAttributes;
private SftpFileAttributes _originalFileAttributes;
private SftpFileAttributes _newFileAttributes;
private byte[] _readBytes;
private byte[] _actualReadBytes;
protected override void SetupData()
{
var random = new Random();
_path = random.Next().ToString(CultureInfo.InvariantCulture);
_handle = GenerateRandom(random.Next(2, 6), random);
_bufferSize = (uint) random.Next(1, 1000);
_readBufferSize = (uint) random.Next(1, 1000);
_writeBufferSize = (uint) random.Next(100, 1000);
_readBytes = new byte[5];
_actualReadBytes = GenerateRandom(_readBytes.Length, random);
_length = _readBytes.Length + 2;
_fileAttributes = new SftpFileAttributesBuilder().WithExtension("X", "ABC")
.WithExtension("V", "VValue")
.WithGroupId(random.Next())
.WithLastAccessTime(DateTime.Now.AddSeconds(random.Next()))
.WithLastWriteTime(DateTime.Now.AddSeconds(random.Next()))
.WithPermissions((uint)random.Next())
.WithSize(_length + 100)
.WithUserId(random.Next())
.Build();
_originalFileAttributes = _fileAttributes.Clone();
_newFileAttributes = null;
}
protected override void SetupMocks()
{
_sequence = new MockSequence();
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Write, false))
.Returns(_handle);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.CalculateOptimalReadLength(_bufferSize))
.Returns(_readBufferSize);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.CalculateOptimalWriteLength(_bufferSize, _handle))
.Returns(_writeBufferSize);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.IsOpen)
.Returns(true);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.RequestRead(_handle, 0, _readBufferSize))
.Returns(_actualReadBytes);
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) => _newFileAttributes = attributes.Clone());
}
protected override void Arrange()
{
base.Arrange();
_sftpFileStream = new SftpFileStream(SftpSessionMock.Object, _path, FileMode.Open, FileAccess.ReadWrite, (int)_bufferSize);
_sftpFileStream.Read(_readBytes, 0, _readBytes.Length);
}
protected override void Act()
{
_sftpFileStream.SetLength(_length);
}
[TestMethod]
public void PositionShouldReturnSamePositionAsBeforeSetLength()
{
SftpSessionMock.InSequence(_sequence).Setup(p => p.IsOpen).Returns(true);
Assert.AreEqual(_readBytes.Length, _sftpFileStream.Position);
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(3));
}
[TestMethod]
public void RequestFSetStatOnSftpSessionShouldBeInvokedOnce()
{
SftpSessionMock.Verify(p => p.RequestFSetStat(_handle, _fileAttributes), Times.Once);
}
[TestMethod]
public void SizeOfSftpFileAttributesShouldBeModifiedToNewLengthBeforePassedToRequestFSetStat()
{
DictionaryAssert.AreEqual(_originalFileAttributes.Extensions, _newFileAttributes.Extensions);
Assert.AreEqual(_originalFileAttributes.GroupId, _newFileAttributes.GroupId);
Assert.AreEqual(_originalFileAttributes.LastAccessTime, _newFileAttributes.LastAccessTime);
Assert.AreEqual(_originalFileAttributes.LastWriteTime, _newFileAttributes.LastWriteTime);
Assert.AreEqual(_originalFileAttributes.Permissions, _newFileAttributes.Permissions);
Assert.AreEqual(_originalFileAttributes.UserId, _newFileAttributes.UserId);
Assert.AreEqual(_length, _newFileAttributes.Size);
}
[TestMethod]
public void ReadShouldReadStartFromSamePositionAsBeforeSetLength()
{
SftpSessionMock.InSequence(_sequence).Setup(p => p.IsOpen).Returns(true);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.RequestRead(_handle, (uint) _readBytes.Length, _readBufferSize))
.Returns(new byte[] { 0x0f });
var byteRead = _sftpFileStream.ReadByte();
Assert.AreEqual(0x0f, byteRead);
SftpSessionMock.Verify(p => p.RequestRead(_handle, (uint) _readBytes.Length, _readBufferSize), Times.Once);
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(3));
}
[TestMethod]
public void WriteShouldStartFromSamePositionAsBeforeSetLength()
{
var bytesToWrite = GenerateRandom(5);
SftpSessionMock.InSequence(_sequence).Setup(p => p.IsOpen).Returns(true);
SftpSessionMock.InSequence(_sequence).Setup(p => p.IsOpen).Returns(true);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.RequestWrite(_handle, (uint) _readBytes.Length, It.IsAny<byte[]>(), 0, bytesToWrite.Length, It.IsAny<AutoResetEvent>(), null))
.Callback<byte[], ulong, byte[], int, int, AutoResetEvent, Action<SftpStatusResponse>>((handle, serverOffset, data, offset, length, wait, writeCompleted) =>
{
wait.Set();
});
_sftpFileStream.Write(bytesToWrite, 0, bytesToWrite.Length);
_sftpFileStream.Flush();
SftpSessionMock.Verify(p => p.RequestWrite(_handle, (uint) _readBytes.Length, It.IsAny<byte[]>(), 0, bytesToWrite.Length, It.IsAny<AutoResetEvent>(), null), Times.Once);
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(4));
}
}
}
@@ -0,0 +1,171 @@
using System;
using System.Globalization;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Renci.SshNet.Sftp;
using Renci.SshNet.Tests.Common;
using System.Threading;
using Renci.SshNet.Sftp.Responses;
using Renci.SshNet.Common;
namespace Renci.SshNet.Tests.Classes.Sftp
{
/// <summary>
/// - In read mode
/// - Bytes in (read) buffer
/// - New length less than client position and greater than server position
/// </summary>
[TestClass]
public class SftpFileStreamTest_SetLength_DataInReadBuffer_NewLengthLessThanPosition : SftpFileStreamTestBase
{
private string _path;
private SftpFileStream _sftpFileStream;
private byte[] _handle;
private uint _bufferSize;
private uint _readBufferSize;
private uint _writeBufferSize;
private MockSequence _sequence;
private long _length;
private SftpFileAttributes _fileAttributes;
private SftpFileAttributes _originalFileAttributes;
private SftpFileAttributes _newFileAttributes;
private byte[] _readBytes;
private byte[] _actualReadBytes;
protected override void SetupData()
{
var random = new Random();
_path = random.Next().ToString(CultureInfo.InvariantCulture);
_handle = GenerateRandom(random.Next(2, 6), random);
_bufferSize = (uint)random.Next(1, 1000);
_readBufferSize = (uint)random.Next(1, 1000);
_writeBufferSize = (uint)random.Next(100, 1000);
_readBytes = new byte[5];
_actualReadBytes = GenerateRandom(_readBytes.Length, random);
_length = _readBytes.Length - 2;
_fileAttributes = new SftpFileAttributesBuilder().WithExtension("X", "ABC")
.WithExtension("V", "VValue")
.WithGroupId(random.Next())
.WithLastAccessTime(DateTime.Now.AddSeconds(random.Next()))
.WithLastWriteTime(DateTime.Now.AddSeconds(random.Next()))
.WithPermissions((uint)random.Next())
.WithSize(_length + 100)
.WithUserId(random.Next())
.Build();
_originalFileAttributes = _fileAttributes.Clone();
_newFileAttributes = null;
}
protected override void SetupMocks()
{
_sequence = new MockSequence();
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Write, false))
.Returns(_handle);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.CalculateOptimalReadLength(_bufferSize))
.Returns(_readBufferSize);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.CalculateOptimalWriteLength(_bufferSize, _handle))
.Returns(_writeBufferSize);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.IsOpen)
.Returns(true);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.RequestRead(_handle, 0, _readBufferSize))
.Returns(_actualReadBytes);
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) => _newFileAttributes = attributes.Clone());
}
protected override void Arrange()
{
base.Arrange();
_sftpFileStream = new SftpFileStream(SftpSessionMock.Object, _path, FileMode.Open, FileAccess.ReadWrite, (int)_bufferSize);
_sftpFileStream.Read(_readBytes, 0, _readBytes.Length);
}
protected override void Act()
{
_sftpFileStream.SetLength(_length);
}
[TestMethod]
public void PositionShouldReturnLengthOfStream()
{
SftpSessionMock.InSequence(_sequence).Setup(p => p.IsOpen).Returns(true);
Assert.AreEqual(_length, _sftpFileStream.Position);
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(3));
}
[TestMethod]
public void RequestFSetStatOnSftpSessionShouldBeInvokedOnce()
{
SftpSessionMock.Verify(p => p.RequestFSetStat(_handle, _fileAttributes), Times.Once);
}
[TestMethod]
public void SizeOfSftpFileAttributesShouldBeModifiedToNewLengthBeforePassedToRequestFSetStat()
{
DictionaryAssert.AreEqual(_originalFileAttributes.Extensions, _newFileAttributes.Extensions);
Assert.AreEqual(_originalFileAttributes.GroupId, _newFileAttributes.GroupId);
Assert.AreEqual(_originalFileAttributes.LastAccessTime, _newFileAttributes.LastAccessTime);
Assert.AreEqual(_originalFileAttributes.LastWriteTime, _newFileAttributes.LastWriteTime);
Assert.AreEqual(_originalFileAttributes.Permissions, _newFileAttributes.Permissions);
Assert.AreEqual(_originalFileAttributes.UserId, _newFileAttributes.UserId);
Assert.AreEqual(_length, _newFileAttributes.Size);
}
[TestMethod]
public void ReadShouldStartFromEndOfStream()
{
SftpSessionMock.InSequence(_sequence).Setup(p => p.IsOpen).Returns(true);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.RequestRead(_handle, (uint) _length, _readBufferSize))
.Returns(Array<byte>.Empty);
var byteRead = _sftpFileStream.ReadByte();
Assert.AreEqual(-1, byteRead);
SftpSessionMock.Verify(p => p.RequestRead(_handle, (uint) _length, _readBufferSize), Times.Once);
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(3));
}
[TestMethod]
public void WriteShouldStartFromEndOfStream()
{
var bytesToWrite = GenerateRandom(5);
SftpSessionMock.InSequence(_sequence).Setup(p => p.IsOpen).Returns(true);
SftpSessionMock.InSequence(_sequence).Setup(p => p.IsOpen).Returns(true);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.RequestWrite(_handle, (uint) _length, It.IsAny<byte[]>(), 0, bytesToWrite.Length, It.IsAny<AutoResetEvent>(), null))
.Callback<byte[], ulong, byte[], int, int, AutoResetEvent, Action<SftpStatusResponse>>((handle, serverOffset, data, offset, length, wait, writeCompleted) =>
{
wait.Set();
});
_sftpFileStream.Write(bytesToWrite, 0, bytesToWrite.Length);
_sftpFileStream.Flush();
SftpSessionMock.Verify(p => p.RequestWrite(_handle, (uint)_length, It.IsAny<byte[]>(), 0, bytesToWrite.Length, It.IsAny<AutoResetEvent>(), null), Times.Once);
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(4));
}
}
}
@@ -0,0 +1,193 @@
using System;
using System.Globalization;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Renci.SshNet.Sftp;
using Renci.SshNet.Tests.Common;
using System.Threading;
using Renci.SshNet.Sftp.Responses;
namespace Renci.SshNet.Tests.Classes.Sftp
{
/// <summary>
/// - In write mode
/// - Bytes in (write) buffer
/// - New length greater than client position and greater than server position
/// </summary>
[TestClass]
public class SftpFileStreamTest_SetLength_DataInWriteBuffer_NewLengthGreaterThanPosition : SftpFileStreamTestBase
{
private string _path;
private SftpFileStream _sftpFileStream;
private byte[] _handle;
private uint _bufferSize;
private uint _readBufferSize;
private uint _writeBufferSize;
private MockSequence _sequence;
private long _length;
private SftpFileAttributes _fileAttributes;
private SftpFileAttributes _originalFileAttributes;
private SftpFileAttributes _newFileAttributes;
private byte[] _readBytes;
private byte[] _actualReadBytes;
private byte[] _writeBytes;
private byte[] _actualWrittenBytes;
protected override void SetupData()
{
var random = new Random();
_path = random.Next().ToString(CultureInfo.InvariantCulture);
_handle = GenerateRandom(random.Next(2, 6), random);
_bufferSize = (uint) random.Next(1, 1000);
_readBufferSize = (uint) random.Next(1, 1000);
_writeBufferSize = (uint) random.Next(100, 1000);
_readBytes = new byte[5];
_actualReadBytes = GenerateRandom(_readBytes.Length, random);
_writeBytes = new byte[] { 0x01, 0x02, 0x03, 0x04 };
_length = _readBytes.Length + _writeBytes.Length + 2;
_actualWrittenBytes = null;
_fileAttributes = new SftpFileAttributesBuilder().WithExtension("X", "ABC")
.WithExtension("V", "VValue")
.WithGroupId(random.Next())
.WithLastAccessTime(DateTime.Now.AddSeconds(random.Next()))
.WithLastWriteTime(DateTime.Now.AddSeconds(random.Next()))
.WithPermissions((uint)random.Next())
.WithSize(_length + 100)
.WithUserId(random.Next())
.Build();
_originalFileAttributes = _fileAttributes.Clone();
_newFileAttributes = null;
}
protected override void SetupMocks()
{
_sequence = new MockSequence();
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Write, false))
.Returns(_handle);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.CalculateOptimalReadLength(_bufferSize))
.Returns(_readBufferSize);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.CalculateOptimalWriteLength(_bufferSize, _handle))
.Returns(_writeBufferSize);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.IsOpen)
.Returns(true);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.RequestRead(_handle, 0, _readBufferSize))
.Returns(_actualReadBytes);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.IsOpen)
.Returns(true);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.IsOpen)
.Returns(true);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.RequestWrite(_handle, (uint) _readBytes.Length, It.IsAny<byte[]>(), 0, _writeBytes.Length, It.IsAny<AutoResetEvent>(), null))
.Callback<byte[], ulong, byte[], int, int, AutoResetEvent, Action<SftpStatusResponse>>((handle, serverOffset, data, offset, length, wait, writeCompleted)
=>
{
_actualWrittenBytes = data.Take(0, _writeBytes.Length);
wait.Set();
});
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) => _newFileAttributes = attributes.Clone());
}
protected override void Arrange()
{
base.Arrange();
_sftpFileStream = new SftpFileStream(SftpSessionMock.Object, _path, FileMode.Open, FileAccess.ReadWrite, (int)_bufferSize);
_sftpFileStream.Read(_readBytes, 0, _readBytes.Length);
_sftpFileStream.Write(new byte[] { 0x01, 0x02, 0x03, 0x04 }, 0, 4);
}
protected override void Act()
{
_sftpFileStream.SetLength(_length);
}
[TestMethod]
public void PositionShouldReturnSamePositionAsBeforeSetLength()
{
SftpSessionMock.InSequence(_sequence).Setup(p => p.IsOpen).Returns(true);
Assert.AreEqual(_readBytes.Length + _writeBytes.Length, _sftpFileStream.Position);
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(4));
}
[TestMethod]
public void RequestFSetStatOnSftpSessionShouldBeInvokedOnce()
{
SftpSessionMock.Verify(p => p.RequestFSetStat(_handle, _fileAttributes), Times.Once);
}
[TestMethod]
public void SizeOfSftpFileAttributesShouldBeModifiedToNewLengthBeforePassedToRequestFSetStat()
{
DictionaryAssert.AreEqual(_originalFileAttributes.Extensions, _newFileAttributes.Extensions);
Assert.AreEqual(_originalFileAttributes.GroupId, _newFileAttributes.GroupId);
Assert.AreEqual(_originalFileAttributes.LastAccessTime, _newFileAttributes.LastAccessTime);
Assert.AreEqual(_originalFileAttributes.LastWriteTime, _newFileAttributes.LastWriteTime);
Assert.AreEqual(_originalFileAttributes.Permissions, _newFileAttributes.Permissions);
Assert.AreEqual(_originalFileAttributes.UserId, _newFileAttributes.UserId);
Assert.AreEqual(_length, _newFileAttributes.Size);
}
[TestMethod]
public void WrittenBytesShouldByFlushedToServer()
{
Assert.IsNotNull(_actualWrittenBytes);
CollectionAssert.AreEqual(_writeBytes, _actualWrittenBytes);
}
[TestMethod]
public void ReadShouldReadStartFromSamePositionAsBeforeSetLength()
{
SftpSessionMock.InSequence(_sequence).Setup(p => p.IsOpen).Returns(true);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.RequestRead(_handle, (uint) (_readBytes.Length + _writeBytes.Length), _readBufferSize))
.Returns(new byte[] { 0x0f });
var byteRead = _sftpFileStream.ReadByte();
Assert.AreEqual(0x0f, byteRead);
SftpSessionMock.Verify(p => p.RequestRead(_handle, (uint) (_readBytes.Length + _writeBytes.Length), _readBufferSize), Times.Once);
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(4));
}
[TestMethod]
public void WriteShouldStartFromSamePositionAsBeforeSetLength()
{
var bytesToWrite = GenerateRandom(5);
SftpSessionMock.InSequence(_sequence).Setup(p => p.IsOpen).Returns(true);
SftpSessionMock.InSequence(_sequence).Setup(p => p.IsOpen).Returns(true);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.RequestWrite(_handle, (uint)(_readBytes.Length + _writeBytes.Length), It.IsAny<byte[]>(), 0, bytesToWrite.Length, It.IsAny<AutoResetEvent>(), null))
.Callback<byte[], ulong, byte[], int, int, AutoResetEvent, Action<SftpStatusResponse>>((handle, serverOffset, data, offset, length, wait, writeCompleted) =>
{
wait.Set();
});
_sftpFileStream.Write(bytesToWrite, 0, bytesToWrite.Length);
_sftpFileStream.Flush();
SftpSessionMock.Verify(p => p.RequestWrite(_handle, (uint) (_readBytes.Length + _writeBytes.Length), It.IsAny<byte[]>(), 0, bytesToWrite.Length, It.IsAny<AutoResetEvent>(), null), Times.Once);
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(5));
}
}
}
@@ -0,0 +1,194 @@
using System;
using System.Globalization;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Renci.SshNet.Sftp;
using Renci.SshNet.Tests.Common;
using System.Threading;
using Renci.SshNet.Sftp.Responses;
using Renci.SshNet.Common;
namespace Renci.SshNet.Tests.Classes.Sftp
{
/// <summary>
/// - In write mode
/// - Bytes in (write) buffer
/// - New length less than client position and less than server position
/// </summary>
[TestClass]
public class SftpFileStreamTest_SetLength_DataInWriteBuffer_NewLengthLessThanPosition : SftpFileStreamTestBase
{
private string _path;
private SftpFileStream _sftpFileStream;
private byte[] _handle;
private uint _bufferSize;
private uint _readBufferSize;
private uint _writeBufferSize;
private MockSequence _sequence;
private long _length;
private SftpFileAttributes _fileAttributes;
private SftpFileAttributes _originalFileAttributes;
private SftpFileAttributes _newFileAttributes;
private byte[] _readBytes;
private byte[] _actualReadBytes;
private byte[] _writeBytes;
private byte[] _actualWrittenBytes;
protected override void SetupData()
{
var random = new Random();
_path = random.Next().ToString(CultureInfo.InvariantCulture);
_handle = GenerateRandom(random.Next(2, 6), random);
_bufferSize = (uint) random.Next(1, 1000);
_readBufferSize = (uint) random.Next(1, 1000);
_writeBufferSize = (uint) random.Next(100, 1000);
_readBytes = new byte[5];
_actualReadBytes = GenerateRandom(_readBytes.Length, random);
_writeBytes = new byte[] { 0x01, 0x02, 0x03, 0x04 };
_length = _readBytes.Length - 2;
_actualWrittenBytes = null;
_fileAttributes = new SftpFileAttributesBuilder().WithExtension("X", "ABC")
.WithExtension("V", "VValue")
.WithGroupId(random.Next())
.WithLastAccessTime(DateTime.Now.AddSeconds(random.Next()))
.WithLastWriteTime(DateTime.Now.AddSeconds(random.Next()))
.WithPermissions((uint) random.Next())
.WithSize(_length + 100)
.WithUserId(random.Next())
.Build();
_originalFileAttributes = _fileAttributes.Clone();
_newFileAttributes = null;
}
protected override void SetupMocks()
{
_sequence = new MockSequence();
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.RequestOpen(_path, Flags.Read | Flags.Write, false))
.Returns(_handle);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.CalculateOptimalReadLength(_bufferSize))
.Returns(_readBufferSize);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.CalculateOptimalWriteLength(_bufferSize, _handle))
.Returns(_writeBufferSize);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.IsOpen)
.Returns(true);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.RequestRead(_handle, 0, _readBufferSize))
.Returns(_actualReadBytes);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.IsOpen)
.Returns(true);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.IsOpen)
.Returns(true);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.RequestWrite(_handle, (uint) _readBytes.Length, It.IsAny<byte[]>(), 0, _writeBytes.Length, It.IsAny<AutoResetEvent>(), null))
.Callback<byte[], ulong, byte[], int, int, AutoResetEvent, Action<SftpStatusResponse>>((handle, serverOffset, data, offset, length, wait, writeCompleted)
=>
{
_actualWrittenBytes = data.Take(0, _writeBytes.Length);
wait.Set();
});
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) => _newFileAttributes = attributes.Clone());
}
protected override void Arrange()
{
base.Arrange();
_sftpFileStream = new SftpFileStream(SftpSessionMock.Object, _path, FileMode.Open, FileAccess.ReadWrite, (int) _bufferSize);
_sftpFileStream.Read(_readBytes, 0, _readBytes.Length);
_sftpFileStream.Write(new byte[] { 0x01, 0x02, 0x03, 0x04 }, 0, 4);
}
protected override void Act()
{
_sftpFileStream.SetLength(_length);
}
[TestMethod]
public void PositionShouldReturnLengthOfStream()
{
SftpSessionMock.InSequence(_sequence).Setup(p => p.IsOpen).Returns(true);
Assert.AreEqual(_length, _sftpFileStream.Position);
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(4));
}
[TestMethod]
public void RequestFSetStatOnSftpSessionShouldBeInvokedOnce()
{
SftpSessionMock.Verify(p => p.RequestFSetStat(_handle, _fileAttributes), Times.Once);
}
[TestMethod]
public void SizeOfSftpFileAttributesShouldBeModifiedToNewLengthBeforePassedToRequestFSetStat()
{
DictionaryAssert.AreEqual(_originalFileAttributes.Extensions, _newFileAttributes.Extensions);
Assert.AreEqual(_originalFileAttributes.GroupId, _newFileAttributes.GroupId);
Assert.AreEqual(_originalFileAttributes.LastAccessTime, _newFileAttributes.LastAccessTime);
Assert.AreEqual(_originalFileAttributes.LastWriteTime, _newFileAttributes.LastWriteTime);
Assert.AreEqual(_originalFileAttributes.Permissions, _newFileAttributes.Permissions);
Assert.AreEqual(_originalFileAttributes.UserId, _newFileAttributes.UserId);
Assert.AreEqual(_length, _newFileAttributes.Size);
}
[TestMethod]
public void WrittenBytesShouldByFlushedToServer()
{
Assert.IsNotNull(_actualWrittenBytes);
CollectionAssert.AreEqual(_writeBytes, _actualWrittenBytes);
}
[TestMethod]
public void ReadShouldStartFromEndOfStream()
{
SftpSessionMock.InSequence(_sequence).Setup(p => p.IsOpen).Returns(true);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.RequestRead(_handle, (uint) _length, _readBufferSize))
.Returns(Array<byte>.Empty);
var byteRead = _sftpFileStream.ReadByte();
Assert.AreEqual(-1, byteRead);
SftpSessionMock.Verify(p => p.RequestRead(_handle, (uint)_length, _readBufferSize), Times.Once);
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(4));
}
[TestMethod]
public void WriteShouldStartFromEndOfStream()
{
var bytesToWrite = GenerateRandom(5);
SftpSessionMock.InSequence(_sequence).Setup(p => p.IsOpen).Returns(true);
SftpSessionMock.InSequence(_sequence).Setup(p => p.IsOpen).Returns(true);
SftpSessionMock.InSequence(_sequence)
.Setup(p => p.RequestWrite(_handle, (uint) _length, It.IsAny<byte[]>(), 0, bytesToWrite.Length, It.IsAny<AutoResetEvent>(), null))
.Callback<byte[], ulong, byte[], int, int, AutoResetEvent, Action<SftpStatusResponse>>((handle, serverOffset, data, offset, length, wait, writeCompleted) =>
{
wait.Set();
});
_sftpFileStream.Write(bytesToWrite, 0, bytesToWrite.Length);
_sftpFileStream.Flush();
SftpSessionMock.Verify(p => p.RequestWrite(_handle, (uint) _length, It.IsAny<byte[]>(), 0, bytesToWrite.Length, It.IsAny<AutoResetEvent>(), null), Times.Once);
SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(5));
}
}
}
@@ -0,0 +1,38 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
namespace Renci.SshNet.Tests.Common
{
public static class DictionaryAssert
{
public static void AreEqual<TKey, TValue>(IDictionary<TKey, TValue> expected, IDictionary<TKey, TValue> actual)
{
if (ReferenceEquals(expected, actual))
return;
if (expected == null)
throw new AssertFailedException("Expected dictionary to be null, but was not null.");
if (actual == null)
throw new AssertFailedException("Expected dictionary not to be null, but was null.");
if (expected.Count != actual.Count)
throw new AssertFailedException(string.Format("Expected dictionary to contain {0} entries, but was {1}.",
expected.Count, actual.Count));
foreach (var expectedEntry in expected)
{
TValue actualValue;
if (!actual.TryGetValue(expectedEntry.Key, out actualValue))
{
throw new AssertFailedException(string.Format("Dictionary contains no entry with key '{0}'.", expectedEntry.Key));
}
if (!Equals(expectedEntry.Value, actualValue))
{
throw new AssertFailedException(string.Format("Value for key '{0}' does not match.", expectedEntry.Key));
}
}
}
}
}
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using Renci.SshNet.Common;
using System;
using Renci.SshNet.Sftp;
namespace Renci.SshNet.Tests.Common
{
@@ -24,5 +25,37 @@ namespace Renci.SshNet.Tests.Common
Buffer.BlockCopy(buffer, 0, copy, 0, buffer.Length);
return copy;
}
/// <summary>
/// Creates a deep clone of the current instance.
/// </summary>
/// <returns>
/// A deep clone of the current instance.
/// </returns>
internal static SftpFileAttributes Clone(this SftpFileAttributes value)
{
Dictionary<string, string> clonedExtensions;
if (value.Extensions != null)
{
clonedExtensions = new Dictionary<string, string>(value.Extensions.Count);
foreach (var entry in value.Extensions)
{
clonedExtensions.Add(entry.Key, entry.Value);
}
}
else
{
clonedExtensions = null;
}
return new SftpFileAttributes(value.LastAccessTime,
value.LastWriteTime,
value.Size,
value.UserId,
value.GroupId,
value.Permissions,
clonedExtensions);
}
}
}
@@ -14,6 +14,11 @@ namespace Renci.SshNet.Tests.Common
private uint? _permissions;
private IDictionary<string, string> _extensions;
public SftpFileAttributesBuilder()
{
_extensions = new Dictionary<string, string>();
}
public SftpFileAttributesBuilder WithLastAccessTime(DateTime lastAccessTime)
{
_lastAccessTime = lastAccessTime;
@@ -50,9 +55,9 @@ namespace Renci.SshNet.Tests.Common
return this;
}
public SftpFileAttributesBuilder WithExtensions(IDictionary<string, string> extensions)
public SftpFileAttributesBuilder WithExtension(string name, string value)
{
_extensions = extensions;
_extensions.Add(name, value);
return this;
}
@@ -79,7 +84,5 @@ namespace Renci.SshNet.Tests.Common
_permissions.Value,
_extensions);
}
}
}
@@ -444,6 +444,10 @@
<Compile Include="Classes\Sftp\SftpFileStreamTest_Seek_PositionedAtMiddleOfStream_OriginBeginAndOffsetZero_NoBuffering.cs" />
<Compile Include="Classes\Sftp\SftpFileStreamTest_Seek_PositionedAtMiddleOfStream_OriginBeginAndOffsetZero_ReadBuffer.cs" />
<Compile Include="Classes\Sftp\SftpFileStreamTest_SetLength_Closed.cs" />
<Compile Include="Classes\Sftp\SftpFileStreamTest_SetLength_DataInReadBuffer_NewLengthGreatherThanPosition.cs" />
<Compile Include="Classes\Sftp\SftpFileStreamTest_SetLength_DataInReadBuffer_NewLengthLessThanPosition.cs" />
<Compile Include="Classes\Sftp\SftpFileStreamTest_SetLength_DataInWriteBuffer_NewLengthGreatherThanPosition.cs" />
<Compile Include="Classes\Sftp\SftpFileStreamTest_SetLength_DataInWriteBuffer_NewLengthLessThanPosition.cs" />
<Compile Include="Classes\Sftp\SftpFileStreamTest_SetLength_Disposed.cs" />
<Compile Include="Classes\Sftp\SftpFileStreamTest_SetLength_SessionNotOpen.cs" />
<Compile Include="Classes\Sftp\SftpFileStreamTest_SetLength_SessionOpen_FIleAccessRead.cs" />
@@ -513,6 +517,7 @@
<Compile Include="Classes\SubsystemSession_SendData_Disposed.cs" />
<Compile Include="Classes\SubsystemSession_SendData_NeverConnected.cs" />
<Compile Include="Common\AsyncSocketListener.cs" />
<Compile Include="Common\DictionaryAssert.cs" />
<Compile Include="Common\Extensions.cs" />
<Compile Include="Common\HttpProxyStub.cs" />
<Compile Include="Common\HttpRequest.cs" />