2
0

SftpFileReaderTest_Dispose_SftpSessionIsNotOpen.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. using System;
  2. using System.Threading;
  3. using Microsoft.VisualStudio.TestTools.UnitTesting;
  4. using Moq;
  5. using Renci.SshNet.Sftp;
  6. using BufferedRead = Renci.SshNet.Sftp.SftpFileReader.BufferedRead;
  7. namespace Renci.SshNet.Tests.Classes.Sftp
  8. {
  9. [TestClass]
  10. public class SftpFileReaderTest_Dispose_SftpSessionIsNotOpen : SftpFileReaderTestBase
  11. {
  12. private const int ChunkLength = 32 * 1024;
  13. private MockSequence _seq;
  14. private byte[] _handle;
  15. private int _fileSize;
  16. private WaitHandle[] _waitHandleArray;
  17. private int _operationTimeout;
  18. private SftpFileReader _reader;
  19. private AsyncCallback _readAsyncCallback;
  20. private ManualResetEvent _beginReadInvoked;
  21. private EventWaitHandle _disposeCompleted;
  22. [TestCleanup]
  23. public void TearDown()
  24. {
  25. _beginReadInvoked?.Dispose();
  26. _disposeCompleted?.Dispose();
  27. }
  28. protected override void SetupData()
  29. {
  30. var random = new Random();
  31. _handle = CreateByteArray(random, 5);
  32. _fileSize = 5000;
  33. _waitHandleArray = new WaitHandle[2];
  34. _operationTimeout = random.Next(10000, 20000);
  35. _beginReadInvoked = new ManualResetEvent(false);
  36. _disposeCompleted = new ManualResetEvent(false);
  37. _readAsyncCallback = null;
  38. }
  39. protected override void SetupMocks()
  40. {
  41. _seq = new MockSequence();
  42. _ = SftpSessionMock.InSequence(_seq)
  43. .Setup(p => p.CreateWaitHandleArray(It.IsNotNull<WaitHandle>(), It.IsNotNull<WaitHandle>()))
  44. .Returns<WaitHandle, WaitHandle>((disposingWaitHandle, semaphoreAvailableWaitHandle) =>
  45. {
  46. _waitHandleArray[0] = disposingWaitHandle;
  47. _waitHandleArray[1] = semaphoreAvailableWaitHandle;
  48. return _waitHandleArray;
  49. });
  50. _ = SftpSessionMock.InSequence(_seq)
  51. .Setup(p => p.OperationTimeout)
  52. .Returns(_operationTimeout);
  53. _ = SftpSessionMock.InSequence(_seq)
  54. .Setup(p => p.WaitAny(_waitHandleArray, _operationTimeout))
  55. .Returns(() => WaitAny(_waitHandleArray, _operationTimeout));
  56. _ = SftpSessionMock.InSequence(_seq)
  57. .Setup(p => p.BeginRead(_handle, 0, ChunkLength, It.IsNotNull<AsyncCallback>(), It.IsAny<BufferedRead>()))
  58. .Callback(() =>
  59. {
  60. // harden test by making sure that we've invoked BeginRead before Dispose is invoked
  61. _ = _beginReadInvoked.Set();
  62. })
  63. .Returns<byte[], ulong, uint, AsyncCallback, object>((handle, offset, length, callback, state) =>
  64. {
  65. _readAsyncCallback = callback;
  66. return null;
  67. })
  68. .Callback(() =>
  69. {
  70. // wait until Dispose has been invoked on reader to allow us to harden test, and
  71. // verify whether Dispose will prevent us from entering the read-ahead loop again
  72. _ = _waitHandleArray[0].WaitOne();
  73. });
  74. _ = SftpSessionMock.InSequence(_seq)
  75. .Setup(p => p.IsOpen)
  76. .Returns(false);
  77. }
  78. protected override void Arrange()
  79. {
  80. base.Arrange();
  81. _reader = new SftpFileReader(_handle, SftpSessionMock.Object, ChunkLength, 1, _fileSize);
  82. }
  83. protected override void Act()
  84. {
  85. Assert.IsTrue(_beginReadInvoked.WaitOne(5000));
  86. _reader.Dispose();
  87. }
  88. [TestMethod]
  89. public void ReadAfterDisposeShouldThrowObjectDisposedException()
  90. {
  91. try
  92. {
  93. _ = _reader.Read();
  94. Assert.Fail();
  95. }
  96. catch (ObjectDisposedException ex)
  97. {
  98. Assert.IsNull(ex.InnerException);
  99. Assert.AreEqual(typeof(SftpFileReader).FullName, ex.ObjectName);
  100. }
  101. }
  102. [TestMethod]
  103. public void InvokeOfReadAheadCallbackShouldCompleteImmediately()
  104. {
  105. Assert.IsNotNull(_readAsyncCallback);
  106. _readAsyncCallback(new SftpReadAsyncResult(null, null));
  107. }
  108. [TestMethod]
  109. public void BeginCloseOnSftpSessionShouldNeverHaveBeenInvoked()
  110. {
  111. SftpSessionMock.Verify(p => p.BeginClose(_handle, null, null), Times.Never);
  112. }
  113. }
  114. }