Пример #1
0
        public void DisposeWhileHandlingFileEvent_DisposedWatcherIsNotCalled()
        {
            // Timing issue - event notifications happen on a different thread so we could
            // be in the middle of handling an event when the monitor is disposed. This
            // shouldn't cause an error.

            // Arrange
            var timeout    = System.Diagnostics.Debugger.IsAttached ? 1000 * 60 * 5 : 1000;
            var testLogger = new TestLogger();

            var fileSystemMock = new Mock <IFileSystem>();

            fileSystemMock.Setup(x => x.Directory.Exists(It.IsAny <string>())).Returns(true);

            var watcherFactoryMock = CreateFactoryAndWatcherMocks(out var watcherMock);
            var fileMonitor        = new SingleFileMonitor(watcherFactoryMock.Object, fileSystemMock.Object, "c:\\dummy\\file.txt", testLogger);

            var eventHandlerStartedEvent = new ManualResetEvent(false);
            var disposeCalledEvent       = new ManualResetEvent(false);


            // Stage 1: listen to events from the monitor
            var disposedEventSignalled = false;

            fileMonitor.FileChanged += (s, args) =>
            {
                //*******************************
                // Do not assert in this callback
                //*******************************
                // We're on a background thread so assertions won't cause a test failure

                // Signal that we are in the event handler, and block until dispose is called
                eventHandlerStartedEvent.Set();
                disposedEventSignalled = disposeCalledEvent.WaitOne(timeout);
            };


            // Stage 2: raise the file system event then block until we are in the event handler
            var eventHandlerMethodTask = System.Threading.Tasks.Task.Run(() =>
                                                                         watcherMock.Raise(x => x.Created += null, new FileSystemEventArgs(WatcherChangeTypes.Created, "", "")));

            eventHandlerStartedEvent.WaitOne(timeout).Should().BeTrue();


            // Stage 3: dispose the monitor, unblock the background thread and wait until it has finished
            watcherMock.Reset(); // reset the counts of calls to the watcher

            fileMonitor.Dispose();
            disposeCalledEvent.Set();

            eventHandlerMethodTask.Wait(timeout).Should().BeTrue();
            disposedEventSignalled.Should().BeTrue();

            // Expect a single call to watcher.Dispose(), and no other calls
            watcherMock.Verify(x => x.Dispose(), Times.Once);
            watcherMock.VerifyNoOtherCalls();
        }
Пример #2
0
        public void AfterDispose_EventsAreIgnored()
        {
            Action <Mock <IFileSystemWatcher> > op = (watcherMock) => watcherMock.Raise(x => x.Created += null, new FileSystemEventArgs(WatcherChangeTypes.Created, "", ""));

            DoRaise_Dispose_RaiseAgain(op);

            op = (watcherMock) => watcherMock.Raise(x => x.Deleted += null, new FileSystemEventArgs(WatcherChangeTypes.Created, "", ""));
            DoRaise_Dispose_RaiseAgain(op);

            op = (watcherMock) => watcherMock.Raise(x => x.Changed += null, new FileSystemEventArgs(WatcherChangeTypes.Created, "", ""));
            DoRaise_Dispose_RaiseAgain(op);

            op = (watcherMock) => watcherMock.Raise(x => x.Renamed += null, new RenamedEventArgs(WatcherChangeTypes.Created, "", "", ""));
            DoRaise_Dispose_RaiseAgain(op);


            void DoRaise_Dispose_RaiseAgain(Action <Mock <IFileSystemWatcher> > raiseEvent)
            {
                // Arrange
                var fileSystemMock = new Mock <IFileSystem>();

                fileSystemMock.Setup(x => x.Directory.Exists(It.IsAny <string>())).Returns(true);

                var watcherFactoryMock = CreateFactoryAndWatcherMocks(out var watcherMock);
                var testLogger         = new TestLogger();

                var fileMonitor = new SingleFileMonitor(watcherFactoryMock.Object, fileSystemMock.Object, "c:\\dummy\\file.txt", testLogger);

                var eventCount = 0;

                fileMonitor.FileChanged += (s, args) => eventCount++;

                // 1. First event is handled
                raiseEvent(watcherMock);
                eventCount.Should().Be(1);

                // 2. Dispose then re-raise
                fileMonitor.Dispose();
                raiseEvent(watcherMock);
                eventCount.Should().Be(1);
            }
        }