public void RealFile_RenameFromTrackedFileName_IsTracked()
        {
            // Arrange
            var testLogger        = new TestLogger(logToConsole: true, logThreadId: true);
            var testDir           = CreateTestSpecificDirectory();
            var filePathToMonitor = Path.Combine(testDir, "settingsFile.txt");

            File.WriteAllText(filePathToMonitor, "contents");

            using (var singleFileMonitor = new SingleFileMonitor(filePathToMonitor, testLogger))
            {
                var testWrapper = new WaitableFileMonitor(singleFileMonitor);
                testWrapper.EventCount.Should().Be(0);

                // Act: rename the file from the tracked name
                var renamedFile = Path.ChangeExtension(filePathToMonitor, "moved");
                File.Move(filePathToMonitor, renamedFile);

                testWrapper.WaitForEventAndThrowIfMissing();
                testWrapper.EventCount.Should().Be(1);
            }
        }
Пример #2
0
        public void CriticalExceptions_AreNotSuppressed()
        {
            // Arrange
            var directoryMock = new Mock<IDirectory>();
            directoryMock.Setup(x => x.Exists(It.IsAny<string>())).Returns(true);

            var watcherFactoryMock = CreateFactoryAndWatcherMocks(out var watcherMock);
            Action act = () =>
            {
                watcherMock.Raise(x => x.Changed += null, new FileSystemEventArgs(WatcherChangeTypes.Changed, "", ""));
            };

            var testLogger = new TestLogger();

            using (var fileMonitor = new SingleFileMonitor(watcherFactoryMock.Object, directoryMock.Object, "c:\\dummy\\file.txt", testLogger))
            {
                fileMonitor.FileChanged += (s, args) => throw new StackOverflowException("YYY critical exception");

                // Act and assert
                act.Should().ThrowExactly<StackOverflowException>().And.Message.Should().Be("YYY critical exception");
            }
        }
Пример #3
0
        public void NonCriticalExceptions_AreSuppressed()
        {
            // Arrange
            var directoryMock = new Mock<IDirectory>();
            directoryMock.Setup(x => x.Exists(It.IsAny<string>())).Returns(true);

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

            using (var fileMonitor = new SingleFileMonitor(watcherFactoryMock.Object, directoryMock.Object, "c:\\dummy\\file.txt", testLogger))
            {
                fileMonitor.FileChanged += (s, args) => throw new InvalidOperationException("XXX non-critical exception");

                // Act
                watcherMock
                    .Raise(x => x.Changed += null, new FileSystemEventArgs(WatcherChangeTypes.Changed, "", ""));

                // Assert
                testLogger.AssertPartialOutputStringExists("XXX non-critical exception");
                fileMonitor.MonitoredFilePath.Should().Be("c:\\dummy\\file.txt");
            }
        }
Пример #4
0
        public void OnlyRaisesEventsIfHasListeners()
        {
            // Arrange
            var testDir = CreateTestSpecificDirectory();
            var filePathToMonitor = Path.Combine(testDir, "settingsFile.txt");

            EventHandler dummyHandler = (sender, args) => { };

            using (var singleFileMonitor = new SingleFileMonitor(filePathToMonitor, new TestLogger()))
            {
                singleFileMonitor.MonitoredFilePath.Should().Be(filePathToMonitor);

                // 1. Nothing registered -> underlying wrapper should not be raising events
                singleFileMonitor.FileWatcherIsRaisingEvents.Should().BeFalse();

                // 2. Register a listener -> start monitoring
                singleFileMonitor.FileChanged += dummyHandler;
                singleFileMonitor.FileWatcherIsRaisingEvents.Should().BeTrue();

                // 3. Unregister the listener -> stop monitoring
                singleFileMonitor.FileChanged -= dummyHandler;
                singleFileMonitor.FileWatcherIsRaisingEvents.Should().BeFalse();
            }
        }
Пример #5
0
 public WaitableFileMonitor(SingleFileMonitor singleFileMonitor)
 {
     this.singleFileMonitor              = singleFileMonitor;
     this.singleFileMonitor.FileChanged += OnFileChanged;
 }
Пример #6
0
        public void RealFile_MultipleOperations_NoDuplicates()
        {
            // Repeated file operations will raise lots of events.
            // We don't want duplicates.

            // Arrange
            var testLogger        = new TestLogger(logToConsole: true, logThreadId: true);
            var testDir           = CreateTestSpecificDirectory();
            var filePathToMonitor = Path.Combine(testDir, "settingsFile.txt");

            int totalEventCount = 0;

            for (int i = 0; i < 100; i++)
            {
                TestContext.WriteLine($"Iteration: {i}");

                // Cleanup
                if (File.Exists(filePathToMonitor))
                {
                    File.Delete(filePathToMonitor);
                }
                testBody();
            }

            // We might lose some events if they happen too close together, but we should never
            // have more events than there are logical file operations.
            // There are 5 operations per iteration -> expecting close to 500.

            TestContext.WriteLine($"Number of recorded events: {totalEventCount}");
            totalEventCount.Should().BeInRange(340, 500);

            void testBody()
            {
                const int pauseBetweenOpsInMs = 125;

                using (var singleFileMonitor = new SingleFileMonitor(filePathToMonitor, testLogger))
                {
                    var testWrapper = new WaitableFileMonitor(singleFileMonitor);
                    testWrapper.EventCount.Should().Be(0);

                    // 1. Create the file
                    File.WriteAllText(filePathToMonitor, "initial text");
                    testWrapper.PauseForEvent(pauseBetweenOpsInMs);

                    // 2. Amend the file
                    File.AppendAllText(filePathToMonitor, " more text");
                    testWrapper.PauseForEvent(pauseBetweenOpsInMs);

                    // 3. Rename from the tracked name
                    var renamedFile = Path.ChangeExtension(filePathToMonitor, "moved");
                    File.Move(filePathToMonitor, renamedFile);
                    testWrapper.PauseForEvent(pauseBetweenOpsInMs);

                    // 4. Rename back to the tracked name
                    File.Move(renamedFile, filePathToMonitor);
                    testWrapper.PauseForEvent(pauseBetweenOpsInMs);

                    // 5. Delete
                    File.Delete(filePathToMonitor);
                    testWrapper.PauseForEvent(pauseBetweenOpsInMs);

                    totalEventCount += testWrapper.EventCount;
                }
            };
        }