Ejemplo n.º 1
0
        public void TestDeadlockWhenRemovingAnActiveDataSource()
        {
            var logFile    = new Mock <ILogSource>();
            var dataSource = new Mock <IDataSource>();

            dataSource.Setup(x => x.UnfilteredLogSource).Returns(logFile.Object);

            var collection = new BookmarkCollection(_bookmarks.Object, TimeSpan.Zero);

            logFile.Setup(x => x.RemoveListener(It.IsAny <ILogSourceListener>()))
            .Callback((ILogSourceListener unused) =>
            {
                // In order to produce the deadlock, we have to simulate what's happening in reality.
                // Any ILogFile implementation will hold a lock both while invoking listeners and while
                // Removing them. Waiting on the OnLogFileModified() call simulates exactly that...
                var task = new Task(() =>
                {
                    collection.OnLogFileModified(logFile.Object, LogSourceModification.Removed(0, 10));
                }, TaskCreationOptions.LongRunning);

                task.Start();
                task.Wait();
            });

            collection.AddDataSource(dataSource.Object);

            var removeTask = Task.Factory.StartNew(() => collection.RemoveDataSource(dataSource.Object));

            removeTask.Wait(TimeSpan.FromSeconds(1)).Should().BeTrue("because RemoveDataSource should not block at all");

            logFile.Verify(x => x.RemoveListener(collection), Times.Once);
        }