| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- using System;
- using System.Threading;
- using Microsoft.VisualStudio.TestTools.UnitTesting;
- using Moq;
- using Renci.SshNet.Common;
- using Renci.SshNet.Sftp;
- using BufferedRead = Renci.SshNet.Sftp.SftpFileReader.BufferedRead;
- namespace Renci.SshNet.Tests.Classes.Sftp
- {
- [TestClass]
- public class SftpFileReaderTest_Dispose_SftpSessionIsOpen_BeginCloseThrowsException : SftpFileReaderTestBase
- {
- private const int ChunkLength = 32 * 1024;
- private MockSequence _seq;
- private byte[] _handle;
- private int _fileSize;
- private WaitHandle[] _waitHandleArray;
- private int _operationTimeout;
- private SftpFileReader _reader;
- private AsyncCallback _readAsyncCallback;
- private ManualResetEvent _beginReadInvoked;
- private EventWaitHandle _disposeCompleted;
- [TestCleanup]
- public void TearDown()
- {
- _beginReadInvoked?.Dispose();
- _disposeCompleted?.Dispose();
- }
- protected override void SetupData()
- {
- var random = new Random();
- _handle = CreateByteArray(random, 5);
- _fileSize = 5000;
- _waitHandleArray = new WaitHandle[2];
- _operationTimeout = random.Next(10000, 20000);
- _beginReadInvoked = new ManualResetEvent(false);
- _disposeCompleted = new ManualResetEvent(false);
- _readAsyncCallback = null;
- }
- protected override void SetupMocks()
- {
- _seq = new MockSequence();
- _ = SftpSessionMock.InSequence(_seq)
- .Setup(p => p.CreateWaitHandleArray(It.IsNotNull<WaitHandle>(), It.IsNotNull<WaitHandle>()))
- .Returns<WaitHandle, WaitHandle>((disposingWaitHandle, semaphoreAvailableWaitHandle) =>
- {
- _waitHandleArray[0] = disposingWaitHandle;
- _waitHandleArray[1] = semaphoreAvailableWaitHandle;
- return _waitHandleArray;
- });
- _ = SftpSessionMock.InSequence(_seq)
- .Setup(p => p.OperationTimeout)
- .Returns(_operationTimeout);
- _ = SftpSessionMock.InSequence(_seq)
- .Setup(p => p.WaitAny(_waitHandleArray, _operationTimeout))
- .Returns(() => WaitAny(_waitHandleArray, _operationTimeout));
- _ = SftpSessionMock.InSequence(_seq)
- .Setup(p => p.BeginRead(_handle, 0, ChunkLength, It.IsNotNull<AsyncCallback>(), It.IsAny<BufferedRead>()))
- .Callback(() =>
- {
- // harden test by making sure that we've invoked BeginRead before Dispose is invoked
- _ = _beginReadInvoked.Set();
- })
- .Returns<byte[], ulong, uint, AsyncCallback, object>((handle, offset, length, callback, state) =>
- {
- _readAsyncCallback = callback;
- return null;
- })
- .Callback(() =>
- {
- // wait until Dispose has been invoked on reader to allow us to harden test, and
- // verify whether Dispose will prevent us from entering the read-ahead loop again
- _ = _waitHandleArray[0].WaitOne();
- });
- _ = SftpSessionMock.InSequence(_seq)
- .Setup(p => p.IsOpen)
- .Returns(true);
- _ = SftpSessionMock.InSequence(_seq)
- .Setup(p => p.BeginClose(_handle, null, null))
- .Throws(new SshException());
- }
- protected override void Arrange()
- {
- base.Arrange();
- _reader = new SftpFileReader(_handle, SftpSessionMock.Object, ChunkLength, 1, _fileSize);
- }
- protected override void Act()
- {
- Assert.IsTrue(_beginReadInvoked.WaitOne(5000));
- _reader.Dispose();
- }
- [TestMethod]
- public void ReadAfterDisposeShouldThrowObjectDisposedException()
- {
- try
- {
- _ = _reader.Read();
- Assert.Fail();
- }
- catch (ObjectDisposedException ex)
- {
- Assert.IsNull(ex.InnerException);
- Assert.AreEqual(typeof(SftpFileReader).FullName, ex.ObjectName);
- }
- }
- [TestMethod]
- public void InvokeOfReadAheadCallbackShouldCompleteImmediately()
- {
- Assert.IsNotNull(_readAsyncCallback);
- _readAsyncCallback(new SftpReadAsyncResult(null, null));
- }
- [TestMethod]
- public void BeginCloseOnSftpSessionShouldHaveBeenInvokedOnce()
- {
- SftpSessionMock.Verify(p => p.BeginClose(_handle, null, null), Times.Once);
- }
- }
- }
|