SftpFileStreamTest_ReadAsync_ReadMode_NoDataInReaderBufferAndReadLessBytesFromServerThanCountAndLessThanBufferSize.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. using System;
  2. using System.IO;
  3. using System.Threading.Tasks;
  4. using Microsoft.VisualStudio.TestTools.UnitTesting;
  5. using Moq;
  6. using Renci.SshNet.Common;
  7. using Renci.SshNet.Sftp;
  8. using Renci.SshNet.Tests.Common;
  9. namespace Renci.SshNet.Tests.Classes.Sftp
  10. {
  11. [TestClass]
  12. public class SftpFileStreamTest_ReadAsync_ReadMode_NoDataInReaderBufferAndReadLessBytesFromServerThanCountAndLessThanBufferSize : SftpFileStreamAsyncTestBase
  13. {
  14. private string _path;
  15. private SftpFileStream _target;
  16. private byte[] _handle;
  17. private uint _bufferSize;
  18. private uint _readBufferSize;
  19. private uint _writeBufferSize;
  20. private int _actual;
  21. private byte[] _buffer;
  22. private byte[] _serverData;
  23. private int _serverDataLength;
  24. private int _numberOfBytesToRead;
  25. private byte[] _originalBuffer;
  26. protected override void SetupData()
  27. {
  28. base.SetupData();
  29. var random = new Random();
  30. _path = random.Next().ToString();
  31. _handle = GenerateRandom(5, random);
  32. _bufferSize = (uint)random.Next(1, 1000);
  33. _readBufferSize = 20;
  34. _writeBufferSize = 500;
  35. _numberOfBytesToRead = (int)_readBufferSize + 2; // greater than read buffer size
  36. _originalBuffer = GenerateRandom(_numberOfBytesToRead, random);
  37. _buffer = _originalBuffer.Copy();
  38. _serverDataLength = (int)_readBufferSize - 1; // less than read buffer size
  39. _serverData = GenerateRandom(_serverDataLength, random);
  40. Assert.IsTrue(_serverDataLength < _numberOfBytesToRead && _serverDataLength < _readBufferSize);
  41. }
  42. protected override void SetupMocks()
  43. {
  44. SftpSessionMock.InSequence(MockSequence)
  45. .Setup(p => p.RequestOpenAsync(_path, Flags.Read, default))
  46. .ReturnsAsync(_handle);
  47. SftpSessionMock.InSequence(MockSequence)
  48. .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
  49. .Returns(_readBufferSize);
  50. SftpSessionMock.InSequence(MockSequence)
  51. .Setup(p => p.CalculateOptimalWriteLength(_bufferSize, _handle))
  52. .Returns(_writeBufferSize);
  53. SftpSessionMock.InSequence(MockSequence)
  54. .Setup(p => p.IsOpen)
  55. .Returns(true);
  56. SftpSessionMock.InSequence(MockSequence)
  57. .Setup(p => p.RequestReadAsync(_handle, 0UL, _readBufferSize, default))
  58. .ReturnsAsync(_serverData);
  59. }
  60. [TestCleanup]
  61. public void TearDown()
  62. {
  63. SftpSessionMock.InSequence(MockSequence)
  64. .Setup(p => p.RequestClose(_handle));
  65. }
  66. protected override async Task ArrangeAsync()
  67. {
  68. await base.ArrangeAsync();
  69. _target = await SftpFileStream.OpenAsync(SftpSessionMock.Object,
  70. _path,
  71. FileMode.Open,
  72. FileAccess.Read,
  73. (int)_bufferSize,
  74. default);
  75. }
  76. protected override async Task ActAsync()
  77. {
  78. _actual = await _target.ReadAsync(_buffer, 0, _numberOfBytesToRead, default);
  79. }
  80. [TestMethod]
  81. public void ReadShouldHaveReturnedTheNumberOfBytesReturnedByTheReadFromTheServer()
  82. {
  83. Assert.AreEqual(_serverDataLength, _actual);
  84. }
  85. [TestMethod]
  86. public void ReadShouldHaveWrittenBytesToTheCallerSuppliedBufferAndRemainingBytesShouldRemainUntouched()
  87. {
  88. Assert.IsTrue(_serverData.IsEqualTo(_buffer.Take(_serverDataLength)));
  89. Assert.IsTrue(_originalBuffer.Take(_serverDataLength, _originalBuffer.Length - _serverDataLength).IsEqualTo(_buffer.Take(_serverDataLength, _buffer.Length - _serverDataLength)));
  90. }
  91. [TestMethod]
  92. public void PositionShouldReturnNumberOfBytesWrittenToCallerProvidedBuffer()
  93. {
  94. SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
  95. Assert.AreEqual(_actual, _target.Position);
  96. SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(2));
  97. }
  98. [TestMethod]
  99. public async Task SubsequentReadShouldReadAgainFromCurrentPositionFromServerAndReturnZeroWhenServerReturnsZeroBytes()
  100. {
  101. SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
  102. SftpSessionMock.InSequence(MockSequence)
  103. .Setup(p => p.RequestReadAsync(_handle, (ulong)_actual, _readBufferSize, default))
  104. .ReturnsAsync(Array.Empty<byte>());
  105. var buffer = _originalBuffer.Copy();
  106. var actual = await _target.ReadAsync(buffer, 0, buffer.Length);
  107. Assert.AreEqual(0, actual);
  108. Assert.IsTrue(_originalBuffer.IsEqualTo(buffer));
  109. SftpSessionMock.Verify(p => p.RequestReadAsync(_handle, (ulong)_actual, _readBufferSize, default), Times.Once);
  110. SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(2));
  111. }
  112. [TestMethod]
  113. public async Task SubsequentReadShouldReadAgainFromCurrentPositionFromServerAndNotUpdatePositionWhenServerReturnsZeroBytes()
  114. {
  115. SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
  116. SftpSessionMock.InSequence(MockSequence)
  117. .Setup(p => p.RequestReadAsync(_handle, (ulong)_actual, _readBufferSize, default))
  118. .ReturnsAsync(Array.Empty<byte>());
  119. SftpSessionMock.InSequence(MockSequence).Setup(p => p.IsOpen).Returns(true);
  120. _ = await _target.ReadAsync(new byte[10], 0, 10);
  121. Assert.AreEqual(_actual, _target.Position);
  122. SftpSessionMock.Verify(p => p.RequestReadAsync(_handle, (ulong)_actual, _readBufferSize, default), Times.Once);
  123. SftpSessionMock.Verify(p => p.IsOpen, Times.Exactly(3));
  124. }
  125. }
  126. }